123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- """
- @package mapwin.graphics
- @brief Map display canvas - buffered window.
- Classes:
- - graphics::GraphicsSet
- - graphics::GraphicsSetItem
- (C) 2006-2013 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 Stepan Turek <stepan.turek seznam.cz> (handlers support, GraphicsSet)
- """
- from copy import copy
- import wx
- from gui_core.wrap import NewId
- class GraphicsSet:
- def __init__(
- self,
- parentMapWin,
- graphicsType,
- pdc,
- setStatusFunc=None,
- drawFunc=None,
- mapCoords=True,
- ):
- """Class, which contains instances of GraphicsSetItem and
- draws them For description of parameters look at method
- RegisterGraphicsToDraw in BufferedWindow class.
- """
- self.pens = {
- "default": wx.Pen(colour=wx.BLACK, width=2, style=wx.SOLID),
- "selected": wx.Pen(colour=wx.GREEN, width=2, style=wx.SOLID),
- "unused": wx.Pen(colour=wx.LIGHT_GREY, width=2, style=wx.SOLID),
- "highest": wx.Pen(colour=wx.RED, width=2, style=wx.SOLID),
- }
- self.brushes = {"default": wx.TRANSPARENT_BRUSH}
- # list contains instances of GraphicsSetItem
- self.itemsList = []
- self.properties = {}
- self.graphicsType = graphicsType
- self.parentMapWin = parentMapWin
- self.setStatusFunc = setStatusFunc
- self.mapCoords = mapCoords
- self.pdc = pdc
- if drawFunc:
- self.drawFunc = drawFunc
- elif self.graphicsType == "point":
- self.properties["size"] = 5
- self.properties["text"] = {}
- self.properties["text"]["font"] = wx.Font(
- pointSize=self.properties["size"],
- family=wx.FONTFAMILY_DEFAULT,
- style=wx.FONTSTYLE_NORMAL,
- weight=wx.FONTWEIGHT_NORMAL,
- )
- self.properties["text"]["active"] = True
- self.drawFunc = self.parentMapWin.DrawCross
- elif self.graphicsType == "line":
- self.drawFunc = self.parentMapWin.DrawPolylines
- elif self.graphicsType == "rectangle":
- self.drawFunc = self.parentMapWin.DrawRectangle
- elif self.graphicsType == "polygon":
- self.drawFunc = self.parentMapWin.DrawPolygon
- def Draw(self):
- """Draws all containing items."""
- itemOrderNum = 0
- for item in self.itemsList:
- self._clearId(item.GetId())
- if self.setStatusFunc is not None:
- self.setStatusFunc(item, itemOrderNum)
- if item.GetPropertyVal("hide") is True:
- itemOrderNum += 1
- continue
- if self.graphicsType == "point":
- if item.GetPropertyVal("penName"):
- self.parentMapWin.pen = self.pens[item.GetPropertyVal("penName")]
- else:
- self.parentMapWin.pen = self.pens["default"]
- if self.mapCoords:
- coords = self.parentMapWin.Cell2Pixel(item.GetCoords())
- else:
- coords = item.GetCoords()
- size = self.properties["size"]
- label = item.GetPropertyVal("label")
- if label is None:
- self.properties["text"] = None
- else:
- self.properties["text"]["coords"] = [
- coords[0] + size,
- coords[1] + size,
- size,
- size,
- ]
- self.properties["text"]["color"] = self.parentMapWin.pen.GetColour()
- self.properties["text"]["text"] = label
- self.drawFunc(
- pdc=self.pdc,
- drawid=item.GetId(),
- coords=coords,
- text=self.properties["text"],
- size=self.properties["size"],
- )
- elif self.graphicsType == "line":
- if item.GetPropertyVal("penName"):
- pen = self.pens[item.GetPropertyVal("penName")]
- else:
- pen = self.pens["default"]
- if self.mapCoords:
- coords = [
- self.parentMapWin.Cell2Pixel(coords)
- for coords in item.GetCoords()
- ]
- else:
- coords = item.GetCoords()
- self.drawFunc(pdc=self.pdc, pen=pen, coords=coords, drawid=item.GetId())
- elif self.graphicsType == "rectangle":
- if item.GetPropertyVal("penName"):
- pen = self.pens[item.GetPropertyVal("penName")]
- else:
- pen = self.pens["default"]
- if item.GetPropertyVal("brushName"):
- brush = self.brushes[item.GetPropertyVal("brushName")]
- else:
- brush = self.brushes["default"]
- if self.mapCoords:
- coords = [
- self.parentMapWin.Cell2Pixel(coords)
- for coords in item.GetCoords()
- ]
- else:
- coords = item.GetCoords()
- self.drawFunc(
- pdc=self.pdc,
- pen=pen,
- brush=brush,
- drawid=item.GetId(),
- point1=coords[0],
- point2=coords[1],
- )
- elif self.graphicsType == "polygon":
- if item.GetPropertyVal("penName"):
- pen = self.pens[item.GetPropertyVal("penName")]
- else:
- pen = self.pens["default"]
- if item.GetPropertyVal("brushName"):
- brush = self.brushes[item.GetPropertyVal("brushName")]
- else:
- brush = self.brushes["default"]
- if self.mapCoords:
- coords = [
- self.parentMapWin.Cell2Pixel(coords)
- for coords in item.GetCoords()
- ]
- else:
- coords = item.GetCoords()
- self.drawFunc(
- pdc=self.pdc,
- pen=pen,
- brush=brush,
- coords=coords,
- drawid=item.GetId(),
- )
- itemOrderNum += 1
- def AddItem(self, coords, penName=None, label=None, hide=False):
- """Append item to the list.
- Added item is put to the last place in drawing order.
- Could be 'point' or 'line' according to graphicsType.
- :param coords: list of east, north coordinates (double) of item.
- Example:
- * point: [1023, 122]
- * line: [[10, 12],[20,40],[23, 2334]]
- * rectangle: [[10, 12], [33, 45]]
- :param penName: the 'default' pen is used if is not defined
- :type penName: str
- :param label: label, which will be drawn with point. It is
- relavant just for 'point' type.
- :type label: str
- :param hide: if it is True, the item is not drawn when self.Draw
- is called. Hidden items are also counted in drawing
- order.
- :type hide: bool
- :return: (GraphicsSetItem) - added item reference
- """
- item = GraphicsSetItem(coords=coords, penName=penName, label=label, hide=hide)
- self.itemsList.append(item)
- return item
- def DeleteItem(self, item):
- """Deletes item
- :param item: (GraphicsSetItem) - item to remove
- :return: True if item was removed
- :return: False if item was not found
- """
- try:
- self.itemsList.remove(item)
- except ValueError:
- return False
- return True
- def GetAllItems(self):
- """Returns list of all containing instances of GraphicsSetItem,
- in order as they are drawn. If you want to change order of
- drawing use: SetItemDrawOrder method.
- """
- # user can edit objects but not order in list, that is reason,
- # why is returned shallow copy of data list it should be used
- # SetItemDrawOrder for changing order
- return copy(self.itemsList)
- def GetItem(self, drawNum):
- """Get given item from the list.
- :param drawNum: drawing order (index) number of item
- :type drawNum: int
- :return: instance of GraphicsSetItem which is drawn in drawNum order
- :return: False if drawNum was out of range
- """
- return self.itemsList[drawNum]
- def SetPropertyVal(self, propName, propVal):
- """Set property value
- :param propName: - property name: "size", "text"
- - both properties are relevant for "point" type
- :type propName: str
- :param propVal: property value to be set
- :return: True if value was set
- :return: False if propName is not "size" or "text" or type is "line"
- """
- if propName in self.properties:
- self.properties[propName] = propVal
- return True
- return False
- def GetPropertyVal(self, propName):
- """Get property value
- Raises KeyError if propName is not "size" or "text" or type is
- "line"
- :param propName: property name: "size", "text" both properties
- are relevant for "point" type
- :type propName: str
- :return: value of property
- """
- if propName in self.properties:
- return self.properties[propName]
- raise KeyError(_("Property does not exist: %s") % (propName))
- def AddPen(self, penName, pen):
- """Add pen
- :param penName: name of added pen
- :type penName: str
- :param pen: added pen
- :type pen: Wx.Pen
- :return: True - if pen was added
- :return: False - if pen already exists
- """
- if penName in self.pens:
- return False
- self.pens[penName] = pen
- return True
- def GetPen(self, penName):
- """Get existing pen
- :param penName: name of pen
- :type penName: str
- :return: wx.Pen reference if is found
- :return: None if penName was not found
- """
- if penName in self.pens:
- return self.pens[penName]
- return None
- def AddBrush(self, brushName, brush):
- """Add brush
- :param brushName: name of added brush
- :type brushName: str
- :param brush: added brush
- :type brush: wx.Brush
- :return: True - if brush was added
- :return: False - if brush already exists
- """
- if brushName in self.brushes:
- return False
- self.brushes[brushName] = brush
- return True
- def GetBrush(self, brushName):
- """Get existing brush
- :param brushName: name of brush
- :type brushName: str
- :return: wx.Brush reference if is found
- :return: None if brushName was not found
- """
- if brushName in self.brushes:
- return self.brushes[brushName]
- return None
- def SetItemDrawOrder(self, item, drawNum):
- """Set draw order for item
- :param item: (GraphicsSetItem)
- :param drawNum: drawing order of item to be set
- :type drawNum: int
- :return: True if order was changed
- :return: False if drawNum is out of range or item was not found
- """
- if drawNum < len(self.itemsList) and drawNum >= 0 and item in self.itemsList:
- self.itemsList.insert(
- drawNum, self.itemsList.pop(self.itemsList.index(item))
- )
- return True
- return False
- def GetItemDrawOrder(self, item):
- """Get draw order for given item
- :param item: (GraphicsSetItem)
- :return: (int) - drawing order of item
- :return: None - if item was not found
- """
- try:
- return self.itemsList.index(item)
- except ValueError:
- return None
- def _clearId(self, drawid):
- """Clears old object before drawing new object."""
- try:
- self.pdc.ClearId(drawid)
- except:
- pass
- class GraphicsSetItem:
- def __init__(self, coords, penName=None, brushName=None, label=None, hide=False):
- """Could be point or line according to graphicsType in
- GraphicsSet class
- :param coords: list of coordinates (double) of item
- Example: point: [1023, 122]
- line: [[10, 12],[20,40],[23, 2334]]
- rectangle: [[10, 12], [33, 45]]
- :param penName: if it is not defined 'default' pen is used
- :type penName: str
- :param brushName: if it is not defined 'default' brush is used
- :type brushName: str
- :param label: label, which will be drawn with point. It is
- relevant just for 'point' type
- :type label: str
- :param hide: if it is True, item is not drawn Hidden items are
- also counted in drawing order in GraphicsSet class.
- :type hide: bool
- """
- self.coords = coords
- self.properties = {
- "penName": penName,
- "brushName": brushName,
- "hide": hide,
- "label": label,
- }
- self.id = NewId()
- def AddProperty(self, propName):
- """Adds new property, to set it, call SetPropertyVal afterwards.
- :param propName - name of the newly defined property
- :type propName: str
- """
- if propName not in self.properties:
- self.properties[propName] = None
- def SetPropertyVal(self, propName, propVal):
- """Set property value
- :param propName: - property name: "penName", "hide" or "label"
- - property "label" is relevant just for 'point' type
- - or newly defined property name
- :type propName: str
- :param propVal: property value to be set
- :return: True if value was set
- :return: False if propName is not "penName", "hide" or "label"
- """
- if propName in self.properties:
- self.properties[propName] = propVal
- return True
- return False
- def GetPropertyVal(self, propName):
- """Get property value
- Raises KeyError if propName is not "penName", "hide" or
- "label".
- :param propName: - property name: "penName", "hide" or "label"
- - property "label" is relevant just for 'point' type
- :type propName: str
- :return: value of property
- """
- if propName in self.properties:
- return self.properties[propName]
- raise KeyError(_("Property does not exist: %s") % (propName))
- def SetCoords(self, coords):
- """Set coordinates of item
- :param coords: list of east, north coordinates (double) of item
- Example:
- * point: [1023, 122]
- * line: [[10, 12],[20,40],[23, 2334]]
- * rectangle: [[10, 12], [33, 45]]
- """
- self.coords = coords
- def GetCoords(self):
- """Get item coordinates
- :return: coordinates
- """
- return self.coords
- def GetId(self):
- """Get item id (drawing id)."""
- return self.id
|