123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- """
- @package iclass.digit
- @brief wxIClass digitizer classes
- Classes:
- - digit::IClassVDigit
- - digit::IClassVDigitWindow
- (C) 2006-2012 by the GRASS Development Team
- This program is free software under the GNU General Public
- License (>=v2). Read the file COPYING that comes with GRASS
- for details.
- @author Vaclav Petras <wenzeslaus gmail.com>
- @author Anna Kratochvilova <kratochanna gmail.com>
- """
- import wx
- from vdigit.mapwindow import VDigitWindow
- from vdigit.wxdigit import IVDigit
- from vdigit.wxdisplay import DisplayDriver, TYPE_AREA
- from core.gcmd import GWarning
- from core.utils import _
- try:
- from grass.lib.gis import G_verbose, G_set_verbose
- from grass.lib.vector import *
- from grass.lib.vedit import *
- except ImportError:
- pass
- import grass.script as grass
- class IClassVDigitWindow(VDigitWindow):
- """Class similar to VDigitWindow but specialized for wxIClass."""
- def __init__(self, parent, giface, map, properties):
- """
-
- @a parent should has toolbar providing current class (category).
-
- :param parent: gui parent
- :param map: map renderer instance
- """
- VDigitWindow.__init__(self, parent=parent, giface=giface,
- Map=map, properties=properties)
- def _onLeftDown(self, event):
- action = self.toolbar.GetAction()
- if not action:
- return
- region = grass.region()
- e, n = self.Pixel2Cell(event.GetPositionTuple())
- if not ((region['s'] <= n <= region['n']) and (region['w'] <= e <= region['e'])):
- GWarning(parent = self.parent,
- message = _("You are trying to create a training area "
- "outside the computational region. "
- "Please, use g.region to set the appropriate region first."))
- return
- cat = self.GetCurrentCategory()
-
- if cat is None and action == "addLine":
- dlg = wx.MessageDialog(parent = self.parent,
- message = _("In order to create a training area, "
- "you have to select class first.\n\n"
- "There is no class yet, "
- "do you want to create one?"),
- caption = _("No class selected"),
- style = wx.YES_NO)
- if dlg.ShowModal() == wx.ID_YES:
- self.parent.OnCategoryManager(None)
-
- dlg.Destroy()
- event.Skip()
- return
-
- super(IClassVDigitWindow, self)._onLeftDown(event)
-
- def _addRecord(self):
- return False
-
- def _updateATM(self):
- pass
-
- def _onRightUp(self, event):
- super(IClassVDigitWindow, self)._onRightUp(event)
- self.parent.UpdateChangeState(changes = True)
-
- def GetCurrentCategory(self):
- """Returns current category (class).
-
- Category should be assigned to new features (areas).
- It is taken from parent's toolbar.
- """
- return self.parent.GetToolbar("iClass").GetSelectedCategoryIdx()
- def GetCategoryColor(self, cat):
- """Get color associated with given category"""
- r, g, b = map(int, self.parent.GetClassColor(cat).split(':'))
- return wx.Colour(r, g, b)
-
- class IClassVDigit(IVDigit):
- """Class similar to IVDigit but specialized for wxIClass."""
- def __init__(self, mapwindow):
- IVDigit.__init__(self, mapwindow, driver = IClassDisplayDriver)
- self._settings['closeBoundary'] = True # snap to the first node
-
- def _getNewFeaturesLayer(self):
- return 1
-
- def _getNewFeaturesCat(self):
- cat = self.mapWindow.GetCurrentCategory()
- return cat
-
- def DeleteAreasByCat(self, cats):
- """Delete areas (centroid+boundaries) by categories
- :param cats: list of categories
- """
- for cat in cats:
- Vedit_delete_areas_cat(self.poMapInfo, 1, cat)
-
- def CopyMap(self, name, tmp = False):
- """Make a copy of open vector map
- Note: Attributes are not copied
-
- :param name: name for a copy
- :param tmp: True for temporary map
- :return: number of copied features
- :return: -1 on error
- """
- if not self.poMapInfo:
- # nothing to copy
- return -1
-
- poMapInfoNew = pointer(Map_info())
-
- if not tmp:
- open_fn = Vect_open_new
- else:
- open_fn = Vect_open_tmp_new
- is3D = bool(Vect_is_3d(self.poMapInfo))
- if open_fn(poMapInfoNew, name, is3D) == -1:
- return -1
- verbose = G_verbose()
- G_set_verbose(-1) # be silent
-
- if Vect_copy_map_lines(self.poMapInfo, poMapInfoNew) == 1:
- G_set_verbose(verbose)
- return -1
-
- Vect_build(poMapInfoNew)
- G_set_verbose(verbose)
-
- ret = Vect_get_num_lines(poMapInfoNew)
- Vect_close(poMapInfoNew)
-
- return ret
- def GetMapInfo(self):
- """Returns Map_info() struct of open vector map"""
- return self.poMapInfo
- class IClassDisplayDriver(DisplayDriver):
- """Class similar to DisplayDriver but specialized for wxIClass
- .. todo::
- needs refactoring (glog, gprogress)
- """
- def __init__(self, device, deviceTmp, mapObj, window, glog, gprogress):
- DisplayDriver.__init__(self, device, deviceTmp, mapObj, window, glog, gprogress)
- self._cat = -1
-
- def _drawObject(self, robj):
- """Draw given object to the device
- :param robj: object to draw
- """
- if robj.type == TYPE_AREA:
- self._cat = Vect_get_area_cat(self.poMapInfo, robj.fid, 1)
- elif robj.type == TYPE_CENTROIDIN:
- return # skip centroids
- DisplayDriver._drawObject(self, robj)
-
- def _definePen(self, rtype):
- """Define pen/brush based on rendered object)
- :param rtype: type of the object
- :return: pen, brush
- """
- pen, brush = DisplayDriver._definePen(self, rtype)
- if self._cat > 0 and rtype == TYPE_AREA:
- brush = wx.Brush(self.window.GetCategoryColor(self._cat), wx.SOLID)
-
- return pen, brush
- def CloseMap(self):
- """Close training areas map - be quiet"""
- verbosity = G_verbose()
- G_set_verbose(0)
- DisplayDriver.CloseMap(self)
- G_set_verbose(verbosity)
|