2 @package vdigit.toolbars
4 @brief wxGUI vector digitizer toolbars
7 - toolbars::VDigitToolbar
9 (C) 2007-2011 by the GRASS Development Team
11 This program is free software under the GNU General Public License
12 (>=v2). Read the file COPYING that comes with GRASS for details.
14 @author Martin Landa <landa.martin gmail.com>
27 from icons.icon
import MetaIcon
30 """!Toolbar for digitization
32 def __init__(self, parent, mapcontent, layerTree = None, log = None):
36 BaseToolbar.__init__(self, parent)
51 self.Bind(wx.EVT_TOOL, self.
OnTool)
68 self.EnableTool(self.undo,
False)
70 self.RemoveTool(self.undo)
77 def _toolbarData(self):
83 'addPoint' : MetaIcon(img =
'point-create',
84 label = _(
'Digitize new point'),
85 desc = _(
'Left: new point')),
86 'addLine' : MetaIcon(img =
'line-create',
87 label = _(
'Digitize new line'),
88 desc = _(
'Left: new point; Ctrl+Left: undo last point; Right: close line')),
89 'addBoundary' : MetaIcon(img =
'boundary-create',
90 label = _(
'Digitize new boundary'),
91 desc = _(
'Left: new point; Ctrl+Left: undo last point; Right: close line')),
92 'addCentroid' : MetaIcon(img =
'centroid-create',
93 label = _(
'Digitize new centroid'),
94 desc = _(
'Left: new point')),
95 'addArea' : MetaIcon(img =
'polygon-create',
96 label = _(
'Digitize new area (composition of boundaries without category and one centroid with category)'),
97 desc = _(
'Left: new point')),
98 'addVertex' : MetaIcon(img =
'vertex-create',
99 label = _(
'Add new vertex'),
100 desc = _(
'Left: Select; Ctrl+Left: Unselect; Right: Confirm')),
101 'deleteLine' : MetaIcon(img =
'line-delete',
102 label = _(
'Delete feature(s)'),
103 desc = _(
'Left: Select; Ctrl+Left: Unselect; Right: Confirm')),
104 'displayAttr' : MetaIcon(img =
'attributes-display',
105 label = _(
'Display/update attributes'),
106 desc = _(
'Left: Select')),
107 'displayCats' : MetaIcon(img =
'cats-display',
108 label = _(
'Display/update categories'),
109 desc = _(
'Left: Select')),
110 'editLine' : MetaIcon(img =
'line-edit',
111 label = _(
'Edit line/boundary'),
112 desc = _(
'Left: new point; Ctrl+Left: undo last point; Right: close line')),
113 'moveLine' : MetaIcon(img =
'line-move',
114 label = _(
'Move feature(s)'),
115 desc = _(
'Left: Select; Ctrl+Left: Unselect; Right: Confirm')),
116 'moveVertex' : MetaIcon(img =
'vertex-move',
117 label = _(
'Move vertex'),
118 desc = _(
'Left: Select; Ctrl+Left: Unselect; Right: Confirm')),
119 'removeVertex' : MetaIcon(img =
'vertex-delete',
120 label = _(
'Remove vertex'),
121 desc = _(
'Left: Select; Ctrl+Left: Unselect; Right: Confirm')),
122 'settings' : BaseIcons[
'settings'].SetLabel(_(
'Digitization settings')),
123 'quit' : BaseIcons[
'quit'].SetLabel(label = _(
'Quit digitizer'),
124 desc = _(
'Quit digitizer and save changes')),
125 'help' : BaseIcons[
'help'].SetLabel(label = _(
'Vector Digitizer manual'),
126 desc = _(
'Show Vector Digitizer manual')),
127 'additionalTools' : MetaIcon(img =
'tools',
128 label = _(
'Additional tools '
129 '(copy, flip, connect, etc.)'),
130 desc = _(
'Left: Select; Ctrl+Left: Unselect; Right: Confirm')),
131 'undo' : MetaIcon(img =
'undo',
133 desc = _(
'Undo previous changes')),
137 (
"addPoint", icons[
"addPoint"],
140 (
"addLine", icons[
"addLine"],
143 (
"addBoundary", icons[
"addBoundary"],
146 (
"addCentroid", icons[
"addCentroid"],
149 (
"addArea", icons[
"addArea"],
152 (
"moveVertex", icons[
"moveVertex"],
155 (
"addVertex", icons[
"addVertex"],
158 (
"removeVertex", icons[
"removeVertex"],
161 (
"editLine", icons[
"editLine"],
164 (
"moveLine", icons[
"moveLine"],
167 (
"deleteLine", icons[
"deleteLine"],
170 (
"displayCats", icons[
"displayCats"],
173 (
"displayAttr", icons[
"displayAttr"],
176 (
"additionalTools", icons[
"additionalTools"],
180 (
"undo", icons[
"undo"],
182 (
"settings", icons[
"settings"],
184 (
"help", icons[
"help"],
186 (
"quit", icons[
"quit"],
191 """!Tool selected -> disable selected tool in map toolbar"""
192 aId = self.parent.toolbars[
'map'].
GetAction(type =
'id')
193 self.parent.toolbars[
'map'].ToggleTool(aId,
False)
196 cursor = self.parent.cursors[
"cross"]
197 self.parent.MapWindow.SetCursor(cursor)
200 self.parent.OnPointer(
None)
204 aId = self.action.get(
'id', -1)
205 if aId != event.GetId()
and \
207 self.ToggleTool(self.
action[
'id'],
False)
209 self.ToggleTool(self.
action[
'id'],
True)
211 self.
action[
'id'] = event.GetId()
215 if self.
action[
'id'] != -1:
216 self.ToggleTool(self.
action[
'id'],
True)
219 if self.
action[
'id'] != aId:
220 self.parent.MapWindow.ClearLines(pdc = self.parent.MapWindow.pdcTmp)
222 len(self.parent.MapWindow.digit.GetDisplay().GetSelected()) > 0:
224 self.parent.MapWindow.OnMiddleDown(
None)
227 self.parent.MapWindow.SetFocus()
230 """!Add point to the vector map Laier"""
231 Debug.msg (2,
"VDigitToolbar.OnAddPoint()")
232 self.
action = {
'desc' :
"addLine",
234 'id' : self.addPoint }
235 self.parent.MapWindow.mouse[
'box'] =
'point'
238 """!Add line to the vector map layer"""
239 Debug.msg (2,
"VDigitToolbar.OnAddLine()")
240 self.
action = {
'desc' :
"addLine",
242 'id' : self.addLine }
243 self.parent.MapWindow.mouse[
'box'] =
'line'
247 """!Add boundary to the vector map layer"""
248 Debug.msg (2,
"VDigitToolbar.OnAddBoundary()")
249 if self.
action[
'desc'] !=
'addLine' or \
250 self.
action[
'type'] !=
'boundary':
251 self.parent.MapWindow.polycoords = []
252 self.
action = {
'desc' :
"addLine",
254 'id' : self.addBoundary }
255 self.parent.MapWindow.mouse[
'box'] =
'line'
258 """!Add centroid to the vector map layer"""
259 Debug.msg (2,
"VDigitToolbar.OnAddCentroid()")
260 self.
action = {
'desc' :
"addLine",
262 'id' : self.addCentroid }
263 self.parent.MapWindow.mouse[
'box'] =
'point'
266 """!Add area to the vector map layer"""
267 Debug.msg (2,
"VDigitToolbar.OnAddCentroid()")
268 self.
action = {
'desc' :
"addLine",
270 'id' : self.addArea }
271 self.parent.MapWindow.mouse[
'box'] =
'line'
274 """!Quit digitization tool"""
281 self.settingsDialog.OnCancel(
None)
284 self.parent.MapWindow.mouse[
'use'] =
"pointer"
285 self.parent.MapWindow.mouse[
'box'] =
"point"
286 self.parent.MapWindow.polycoords = []
289 self.parent.RemoveToolbar(
"vdigit")
292 """!Move line vertex"""
293 Debug.msg(2,
"Digittoolbar.OnMoveVertex():")
294 self.
action = {
'desc' :
"moveVertex",
295 'id' : self.moveVertex }
296 self.parent.MapWindow.mouse[
'box'] =
'point'
299 """!Add line vertex"""
300 Debug.msg(2,
"Digittoolbar.OnAddVertex():")
301 self.
action = {
'desc' :
"addVertex",
302 'id' : self.addVertex }
303 self.parent.MapWindow.mouse[
'box'] =
'point'
306 """!Remove line vertex"""
307 Debug.msg(2,
"Digittoolbar.OnRemoveVertex():")
308 self.
action = {
'desc' :
"removeVertex",
309 'id' : self.removeVertex }
310 self.parent.MapWindow.mouse[
'box'] =
'point'
314 Debug.msg(2,
"Digittoolbar.OnEditLine():")
315 self.
action = {
'desc' :
"editLine",
316 'id' : self.editLine }
317 self.parent.MapWindow.mouse[
'box'] =
'line'
321 Debug.msg(2,
"Digittoolbar.OnMoveLine():")
322 self.
action = {
'desc' :
"moveLine",
323 'id' : self.moveLine }
324 self.parent.MapWindow.mouse[
'box'] =
'box'
328 Debug.msg(2,
"Digittoolbar.OnDeleteLine():")
329 self.
action = {
'desc' :
"deleteLine",
330 'id' : self.deleteLine }
331 self.parent.MapWindow.mouse[
'box'] =
'box'
334 """!Display/update categories"""
335 Debug.msg(2,
"Digittoolbar.OnDisplayCats():")
336 self.
action = {
'desc' :
"displayCats",
337 'id' : self.displayCats }
338 self.parent.MapWindow.mouse[
'box'] =
'point'
341 """!Display/update attributes"""
342 Debug.msg(2,
"Digittoolbar.OnDisplayAttr():")
343 self.
action = {
'desc' :
"displayAttrs",
344 'id' : self.displayAttr }
345 self.parent.MapWindow.mouse[
'box'] =
'point'
348 """!Undo previous changes"""
354 """!Enable 'Undo' in toolbar
356 @param enable False for disable
358 if not self.FindById(self.undo):
362 if self.GetToolEnabled(self.undo)
is False:
363 self.EnableTool(self.undo,
True)
365 if self.GetToolEnabled(self.undo)
is True:
366 self.EnableTool(self.undo,
False)
369 """!Show settings dialog"""
370 if self.
digit is None:
372 self.
digit = self.parent.MapWindow.digit = VDigit(mapwindow = self.parent.MapWindow)
374 self.
digit = self.parent.MapWindow.digit =
None
377 self.
settingsDialog = VDigitSettingsDialog(parent = self.
parent, title = _(
"Digitization settings"),
378 style = wx.DEFAULT_DIALOG_STYLE)
379 self.settingsDialog.Show()
382 """!Show digitizer help page in web browser"""
383 log = self.parent.GetLayerManager().GetLogWindow()
384 log.RunCmd([
'g.manual',
385 'entry=wxGUI.Vector_Digitizer'])
388 """!Menu for additional tools"""
389 point = wx.GetMousePosition()
392 for label, itype, handler, desc
in (
393 (_(
'Break selected lines/boundaries at intersection'),
394 wx.ITEM_CHECK, self.
OnBreak,
"breakLine"),
395 (_(
'Connect selected lines/boundaries'),
396 wx.ITEM_CHECK, self.
OnConnect,
"connectLine"),
397 (_(
'Copy categories'),
399 (_(
'Copy features from (background) vector map'),
400 wx.ITEM_CHECK, self.
OnCopy,
"copyLine"),
401 (_(
'Copy attributes'),
403 (_(
'Feature type conversion'),
405 (_(
'Flip selected lines/boundaries'),
406 wx.ITEM_CHECK, self.
OnFlip,
"flipLine"),
407 (_(
'Merge selected lines/boundaries'),
408 wx.ITEM_CHECK, self.
OnMerge,
"mergeLine"),
409 (_(
'Snap selected lines/boundaries (only to nodes)'),
410 wx.ITEM_CHECK, self.
OnSnap,
"snapLine"),
411 (_(
'Split line/boundary'),
413 (_(
'Query features'),
414 wx.ITEM_CHECK, self.
OnQuery,
"queryLine"),
415 (_(
'Z bulk-labeling of 3D lines'),
416 wx.ITEM_CHECK, self.
OnZBulk,
"zbulkLine")):
418 item = wx.MenuItem(parentMenu = toolMenu, id = wx.ID_ANY,
421 toolMenu.AppendItem(item)
422 self.parent.MapWindow.Bind(wx.EVT_MENU, handler, item)
423 if self.
action[
'desc'] == desc:
428 self.parent.MapWindow.PopupMenu(toolMenu)
431 if self.
action[
'desc'] ==
'addPoint':
432 self.ToggleTool(self.additionalTools,
False)
435 """!Copy selected features from (background) vector map"""
436 if self.
action[
'desc'] ==
'copyLine':
437 self.ToggleTool(self.addPoint,
True)
438 self.ToggleTool(self.additionalTools,
False)
442 Debug.msg(2,
"Digittoolbar.OnCopy():")
443 self.
action = {
'desc' :
"copyLine",
444 'id' : self.additionalTools }
445 self.parent.MapWindow.mouse[
'box'] =
'box'
449 if self.
action[
'desc'] ==
'splitLine':
450 self.ToggleTool(self.addPoint,
True)
451 self.ToggleTool(self.additionalTools,
False)
455 Debug.msg(2,
"Digittoolbar.OnSplitLine():")
456 self.
action = {
'desc' :
"splitLine",
457 'id' : self.additionalTools }
458 self.parent.MapWindow.mouse[
'box'] =
'point'
462 """!Copy categories"""
463 if self.
action[
'desc'] ==
'copyCats':
464 self.ToggleTool(self.addPoint,
True)
465 self.ToggleTool(self.copyCats,
False)
469 Debug.msg(2,
"Digittoolbar.OnCopyCats():")
470 self.
action = {
'desc' :
"copyCats",
471 'id' : self.additionalTools }
472 self.parent.MapWindow.mouse[
'box'] =
'point'
475 """!Copy attributes"""
476 if self.
action[
'desc'] ==
'copyAttrs':
477 self.ToggleTool(self.addPoint,
True)
478 self.ToggleTool(self.copyCats,
False)
482 Debug.msg(2,
"Digittoolbar.OnCopyAttrb():")
483 self.
action = {
'desc' :
"copyAttrs",
484 'id' : self.additionalTools }
485 self.parent.MapWindow.mouse[
'box'] =
'point'
489 """!Flip selected lines/boundaries"""
490 if self.
action[
'desc'] ==
'flipLine':
491 self.ToggleTool(self.addPoint,
True)
492 self.ToggleTool(self.additionalTools,
False)
496 Debug.msg(2,
"Digittoolbar.OnFlip():")
497 self.
action = {
'desc' :
"flipLine",
498 'id' : self.additionalTools }
499 self.parent.MapWindow.mouse[
'box'] =
'box'
502 """!Merge selected lines/boundaries"""
503 if self.
action[
'desc'] ==
'mergeLine':
504 self.ToggleTool(self.addPoint,
True)
505 self.ToggleTool(self.additionalTools,
False)
509 Debug.msg(2,
"Digittoolbar.OnMerge():")
510 self.
action = {
'desc' :
"mergeLine",
511 'id' : self.additionalTools }
512 self.parent.MapWindow.mouse[
'box'] =
'box'
515 """!Break selected lines/boundaries"""
516 if self.
action[
'desc'] ==
'breakLine':
517 self.ToggleTool(self.addPoint,
True)
518 self.ToggleTool(self.additionalTools,
False)
522 Debug.msg(2,
"Digittoolbar.OnBreak():")
523 self.
action = {
'desc' :
"breakLine",
524 'id' : self.additionalTools }
525 self.parent.MapWindow.mouse[
'box'] =
'box'
528 """!Snap selected features"""
529 if self.
action[
'desc'] ==
'snapLine':
530 self.ToggleTool(self.addPoint,
True)
531 self.ToggleTool(self.additionalTools,
False)
535 Debug.msg(2,
"Digittoolbar.OnSnap():")
536 self.
action = {
'desc' :
"snapLine",
537 'id' : self.additionalTools }
538 self.parent.MapWindow.mouse[
'box'] =
'box'
541 """!Connect selected lines/boundaries"""
542 if self.
action[
'desc'] ==
'connectLine':
543 self.ToggleTool(self.addPoint,
True)
544 self.ToggleTool(self.additionalTools,
False)
548 Debug.msg(2,
"Digittoolbar.OnConnect():")
549 self.
action = {
'desc' :
"connectLine",
550 'id' : self.additionalTools }
551 self.parent.MapWindow.mouse[
'box'] =
'box'
554 """!Query selected lines/boundaries"""
555 if self.
action[
'desc'] ==
'queryLine':
556 self.ToggleTool(self.addPoint,
True)
557 self.ToggleTool(self.additionalTools,
False)
561 Debug.msg(2,
"Digittoolbar.OnQuery(): %s" % \
562 UserSettings.Get(group =
'vdigit', key =
'query', subkey =
'selection'))
563 self.
action = {
'desc' :
"queryLine",
564 'id' : self.additionalTools }
565 self.parent.MapWindow.mouse[
'box'] =
'box'
568 """!Z bulk-labeling selected lines/boundaries"""
569 if not self.digit.IsVector3D():
570 GError(parent = self.
parent,
571 message = _(
"Vector map is not 3D. Operation canceled."))
574 if self.
action[
'desc'] ==
'zbulkLine':
575 self.ToggleTool(self.addPoint,
True)
576 self.ToggleTool(self.additionalTools,
False)
580 Debug.msg(2,
"Digittoolbar.OnZBulk():")
581 self.
action = {
'desc' :
"zbulkLine",
582 'id' : self.additionalTools }
583 self.parent.MapWindow.mouse[
'box'] =
'line'
586 """!Feature type conversion
588 Supported conversions:
592 if self.
action[
'desc'] ==
'typeConv':
593 self.ToggleTool(self.addPoint,
True)
594 self.ToggleTool(self.additionalTools,
False)
598 Debug.msg(2,
"Digittoolbar.OnTypeConversion():")
599 self.
action = {
'desc' :
"typeConv",
600 'id' : self.additionalTools }
601 self.parent.MapWindow.mouse[
'box'] =
'box'
604 """!Select vector map layer for editing
606 If there is a vector map layer already edited, this action is
607 firstly terminated. The map layer is closed. After this the
608 selected map layer activated for editing.
610 if event.GetSelection() == 0:
612 openVectorMap = self.mapLayer.GetName(fullyQualified =
False)[
'name']
616 exceptMap = openVectorMap, log = self.
log,
618 {
'tool' :
'create' },
622 if dlg
and dlg.GetName():
625 mapName = dlg.GetName() +
'@' + grass.gisenv()[
'MAPSET']
626 self.layerTree.AddLayer(ltype =
'vector',
628 lcmd = [
'd.vect',
'map=%s' % mapName])
631 selection = vectLayers.index(mapName)
634 if dlg.IsChecked(
'table'):
635 lmgr = self.parent.GetLayerManager()
637 lmgr.OnShowAttributeTable(
None, selection =
'table')
640 self.combo.SetValue(_(
'Select vector map'))
645 selection = event.GetSelection() - 1
661 """!Start editing selected vector map layer.
663 @param mapLayer MapLayer to be edited
666 self.mapcontent.ChangeLayerActive(mapLayer,
False)
669 self.parent.MapWindow.EraseMap()
673 if UserSettings.Get(group =
'vdigit', key =
'bgmap',
674 subkey =
'value', internal =
True) == mapLayer.GetName():
675 UserSettings.Set(group =
'vdigit', key =
'bgmap',
676 subkey =
'value', value =
'', internal =
True)
678 self.parent.SetStatusText(_(
"Please wait, "
679 "opening vector map <%s> for editing...") % mapLayer.GetName(),
682 self.parent.MapWindow.pdcVector = wx.PseudoDC()
683 self.
digit = self.parent.MapWindow.digit = VDigit(mapwindow = self.parent.MapWindow)
688 if self.digit.OpenMap(mapLayer.GetName())
is None:
694 self.combo.SetValue(mapLayer.GetName())
695 self.parent.toolbars[
'map'].combo.SetValue (_(
'Digitize'))
696 lmgr = self.parent.GetLayerManager()
700 Debug.msg (4,
"VDigitToolbar.StartEditing(): layer=%s" % mapLayer.GetName())
703 if self.parent.MapWindow.mouse[
'use'] ==
'pointer':
704 self.parent.MapWindow.SetCursor(self.parent.cursors[
"cross"])
706 if not self.parent.MapWindow.resize:
707 self.parent.MapWindow.UpdateMap(render =
True)
710 opacity = mapLayer.GetOpacity(float =
True)
712 alpha = int(opacity * 255)
718 """!Stop editing of selected vector map layer.
720 @return True on success
721 @return False on failure
723 self.combo.SetValue (_(
'Select vector map'))
727 Debug.msg (4,
"VDigitToolbar.StopEditing(): layer=%s" % self.mapLayer.GetName())
728 if UserSettings.Get(group =
'vdigit', key =
'saveOnExit', subkey =
'enabled')
is False:
729 if self.digit.GetUndoLevel() > -1:
730 dlg = wx.MessageDialog(parent = self.
parent,
731 message = _(
"Do you want to save changes "
732 "in vector map <%s>?") % self.mapLayer.GetName(),
733 caption = _(
"Save changes?"),
734 style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
735 if dlg.ShowModal() == wx.ID_NO:
740 self.parent.SetStatusText(_(
"Please wait, "
741 "closing and rebuilding topology of "
742 "vector map <%s>...") % self.mapLayer.GetName(),
744 self.digit.CloseMap()
746 lmgr = self.parent.GetLayerManager()
749 lmgr.GetLogWindow().GetProgressBar().
SetValue(0)
750 lmgr.GetLogWindow().WriteCmdLog(_(
"Editing of vector map <%s> successfully finished") % \
751 self.mapLayer.GetName(),
754 item = self.parent.tree.FindItemByData(
'maplayer', self.
mapLayer)
755 if item
and self.parent.tree.IsItemChecked(item):
756 self.mapcontent.ChangeLayerActive(self.
mapLayer,
True)
759 self.parent.MapWindow.SetCursor(self.parent.cursors[
"default"])
760 self.parent.MapWindow.pdcVector =
None
763 for dialog
in (
'attributes',
'category'):
764 if self.parent.dialogs[dialog]:
765 self.parent.dialogs[dialog].Close()
766 self.parent.dialogs[dialog] =
None
769 del self.parent.MapWindow.digit
773 self.parent.MapWindow.redrawAll =
True
778 """!Update list of available vector map layers.
779 This list consists only editable layers (in the current mapset)
781 @param updateTool True to update also toolbar
783 Debug.msg (4,
"VDigitToolbar.UpdateListOfLayers(): updateTool=%d" % \
786 layerNameSelected =
None
789 layerNameSelected = self.mapLayer.GetName()
793 self.
layers = self.mapcontent.GetListOfLayers(l_type =
"vector",
794 l_mapset = grass.gisenv()[
'MAPSET'])
797 if not layer.name
in layerNameList:
798 layerNameList.append (layer.GetName())
802 value = _(
'Select vector map')
804 value = layerNameSelected
807 self.
combo = wx.ComboBox(self, id = wx.ID_ANY, value = value,
808 choices = [_(
'New vector map'), ] + layerNameList, size = (80, -1),
809 style = wx.CB_READONLY)
813 self.combo.SetItems([_(
'New vector map'), ] + layerNameList)
820 """!Get selected layer for editing -- MapLayer instance"""
Various dialogs used in wxGUI.
def CreateNewVector
Create new vector map layer.
wxGUI vector digitizer preferences dialogs