52
56
label = _('Import raster data')),
53
57
'rastLink' : MetaIcon(img = 'layer-import',
54
58
label = _('Link external raster data')),
59
'rastUnpack' : MetaIcon(img = 'layer-import',
60
label = _('Unpack raster map')),
55
61
'rastOut' : MetaIcon(img = 'layer-export',
56
62
label = _('Set raster output format')),
57
63
'vectImport' : MetaIcon(img = 'layer-import',
58
64
label = _('Import vector data')),
59
65
'vectLink' : MetaIcon(img = 'layer-import',
60
66
label = _('Link external vector data')),
67
'vectUnpack' : MetaIcon(img = 'layer-import',
68
label = _('Unpack vector map')),
61
69
'vectOut' : MetaIcon(img = 'layer-export',
62
70
label = _('Set vector output format')),
63
'addCmd' : MetaIcon(img = 'layer-command-add',
71
'wmsImport' : MetaIcon(img = 'layer-wms-add',
72
label = _('Import data from WMS server')),
73
'layerCmd' : MetaIcon(img = 'layer-command-add',
64
74
label = _('Add command layer')),
65
75
'quit' : MetaIcon(img = 'quit',
66
76
label = _('Quit')),
67
'addRgb' : MetaIcon(img = 'layer-rgb-add',
77
'layerRaster' : MetaIcon(img = 'raster',
78
label = _('Add raster map layer')),
79
'layerRgb' : MetaIcon(img = 'rgb',
68
80
label = _('Add RGB map layer')),
69
'addHis' : MetaIcon(img = 'layer-his-add',
81
'layerHis' : MetaIcon(img = 'his',
70
82
label = _('Add HIS map layer')),
71
'addShaded' : MetaIcon(img = 'layer-shaded-relief-add',
72
label = _('Add shaded relief map layer')),
73
'addRArrow' : MetaIcon(img = 'layer-aspect-arrow-add',
83
'layerShaded' : MetaIcon(img = 'shaded-relief',
84
label = _('Add shaded relief map layer')),
85
'layerRastarrow' : MetaIcon(img = 'aspect-arrow',
74
86
label = _('Add raster flow arrows')),
75
'addRNum' : MetaIcon(img = 'layer-cell-cats-add',
87
'layerRastnum' : MetaIcon(img = 'cell-cats',
76
88
label = _('Add raster cell numbers')),
77
'addThematic': MetaIcon(img = 'layer-vector-thematic-add',
89
'layerVector' : MetaIcon(img = 'vector',
90
label = _('Add vector map layer')),
91
'layerThememap': MetaIcon(img = 'vector-thematic',
78
92
label = _('Add thematic area (choropleth) map layer')),
79
'addChart' : MetaIcon(img = 'layer-vector-chart-add',
93
'layerThemechart' : MetaIcon(img = 'vector-chart',
80
94
label = _('Add thematic chart layer')),
81
'addGrid' : MetaIcon(img = 'layer-grid-add',
95
'layerGrid' : MetaIcon(img = 'layer-grid-add',
82
96
label = _('Add grid layer')),
83
'addGeodesic': MetaIcon(img = 'shortest-distance',
97
'layerGeodesic': MetaIcon(img = 'shortest-distance',
84
98
label = _('Add geodesic line layer')),
85
'addRhumb' : MetaIcon(img = 'shortest-distance',
99
'layerRhumb' : MetaIcon(img = 'shortest-distance',
86
100
label = _('Add rhumbline layer')),
87
'addLabels' : MetaIcon(img = 'layer-label-add',
101
'layerLabels' : MetaIcon(img = 'label',
88
102
label = _('Add labels')),
89
'addRast3d' : MetaIcon(img = 'layer-raster3d-add',
103
'layer3d-raster' : MetaIcon(img = 'raster3d',
90
104
label = _('Add 3D raster map layer'),
91
105
desc = _('Note that 3D raster data are rendered only in 3D view mode')),
106
'layerWms' : MetaIcon(img = 'wms',
107
label = _('Add WMS layer.')),
92
108
'layerOptions' : MetaIcon(img = 'options',
93
109
label = _('Set options')),
110
'layerEdited' : MetaIcon(img = 'layer-edit',
111
label = _("Editing mode")),
112
'layerBgmap' : MetaIcon(img = 'layer-bottom',
113
label = _("Background vector map"))
96
116
class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
97
"""!Creates layer tree structure
117
"""Creates layer tree structure
99
def __init__(self, parent,
119
def __init__(self, parent, giface,
100
120
id = wx.ID_ANY, style = wx.SUNKEN_BORDER,
101
121
ctstyle = CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
102
122
CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT |
325
403
if not hasattr (self, "popupID"):
326
404
self.popupID = dict()
327
405
for key in ('remove', 'rename', 'opacity', 'nviz', 'zoom',
328
'region', 'export', 'attr', 'edit0', 'edit1',
406
'region', 'export', 'attr', 'edit', 'save_ws',
329
407
'bgmap', 'topo', 'meta', 'null', 'zoom1', 'region1',
330
'color', 'hist', 'univar', 'prof', 'properties'):
408
'color', 'hist', 'univar', 'prof', 'properties', 'sql', 'copy',
409
'report', 'export-pg', 'pack'):
331
410
self.popupID[key] = wx.NewId()
413
currentMapset = grass.gisenv()['MAPSET']
333
415
self.popupMenu = wx.Menu()
335
417
numSelected = len(self.GetSelections())
337
self.popupMenu.Append(self.popupID['remove'], text = _("Remove"))
419
item = wx.MenuItem(self.popupMenu, id = self.popupID['remove'], text = _("Remove"))
420
item.SetBitmap(MetaIcon(img = 'layer-remove').GetBitmap(self.bmpsize))
421
self.popupMenu.AppendItem(item)
338
422
self.Bind(wx.EVT_MENU, self.lmgr.OnDeleteLayer, id = self.popupID['remove'])
340
if ltype != "command":
424
if ltype != "command" and numSelected == 1:
341
425
self.popupMenu.Append(self.popupID['rename'], text = _("Rename"))
342
426
self.Bind(wx.EVT_MENU, self.OnRenameLayer, id = self.popupID['rename'])
344
self.popupMenu.Enable(self.popupID['rename'], False)
428
# when multiple maps are selected of different types
429
# we cannot zoom or change region
430
# because g.region can handle only the same type
432
selected = self.GetSelectedLayers()
433
for layer in selected:
434
if self.GetLayerInfo(layer, key='type') != ltype:
346
438
# map layer items
347
439
if ltype not in ("group", "command"):
348
self.popupMenu.AppendSeparator()
349
self.popupMenu.Append(self.popupID['opacity'], text = _("Change opacity level"))
350
self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, id = self.popupID['opacity'])
351
self.popupMenu.Append(self.popupID['properties'], text = _("Properties"))
352
self.Bind(wx.EVT_MENU, self.OnPopupProperties, id = self.popupID['properties'])
355
self.popupMenu.Enable(self.popupID['opacity'], False)
356
self.popupMenu.Enable(self.popupID['properties'], False)
358
if ltype in ('raster', 'vector', '3d-raster') and self.lmgr.IsPaneShown('toolbarNviz'):
359
self.popupMenu.Append(self.popupID['nviz'], _("3D view properties"))
360
self.Bind (wx.EVT_MENU, self.OnNvizProperties, id = self.popupID['nviz'])
362
if ltype in ('raster', 'vector', 'rgb'):
363
self.popupMenu.Append(self.popupID['zoom'], text = _("Zoom to selected map(s)"))
441
self.popupMenu.AppendSeparator()
442
if ltype != '3d-raster':
443
item = wx.MenuItem(self.popupMenu, id = self.popupID['opacity'], text=_("Change opacity level"))
444
item.SetBitmap(MetaIcon(img = 'layer-opacity').GetBitmap(self.bmpsize))
445
self.popupMenu.AppendItem(item)
446
self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, id=self.popupID['opacity'])
447
item = wx.MenuItem(self.popupMenu, id = self.popupID['properties'], text = _("Properties"))
448
item.SetBitmap(MetaIcon(img = 'options').GetBitmap(self.bmpsize))
449
self.popupMenu.AppendItem(item)
450
self.Bind(wx.EVT_MENU, self.OnPopupProperties, id = self.popupID['properties'])
452
if ltype in ('raster', 'vector', '3d-raster') and self.mapdisplay.IsPaneShown('3d'):
453
self.popupMenu.Append(self.popupID['nviz'], _("3D view properties"))
454
self.Bind (wx.EVT_MENU, self.OnNvizProperties, id = self.popupID['nviz'])
456
if same and ltype in ('raster', 'vector', 'rgb', '3d-raster'):
457
self.popupMenu.AppendSeparator()
458
item = wx.MenuItem(self.popupMenu, id = self.popupID['zoom'], text = _("Zoom to selected map(s)"))
459
item.SetBitmap(MetaIcon(img = 'zoom-layer').GetBitmap(self.bmpsize))
460
self.popupMenu.AppendItem(item)
364
461
self.Bind(wx.EVT_MENU, self.mapdisplay.OnZoomToMap, id = self.popupID['zoom'])
365
self.popupMenu.Append(self.popupID['region'], text = _("Set computational region from selected map(s)"))
463
item = wx.MenuItem(self.popupMenu, id = self.popupID['region'], text = _("Set computational region from selected map(s)"))
464
item.SetBitmap(MetaIcon(img = 'region').GetBitmap(self.bmpsize))
465
self.popupMenu.AppendItem(item)
366
466
self.Bind(wx.EVT_MENU, self.OnSetCompRegFromMap, id = self.popupID['region'])
370
mltype = self.GetPyData(self.layer_selected)[0]['type']
470
mltype = self.GetLayerInfo(self.layer_selected, key = 'type')
374
474
# vector layers (specific items)
375
if mltype and mltype == "vector":
475
if mltype and mltype == "vector" and numSelected == 1:
376
476
self.popupMenu.AppendSeparator()
377
self.popupMenu.Append(self.popupID['export'], text = _("Export"))
477
item = wx.MenuItem(self.popupMenu, id = self.popupID['export'], text = _("Export common formats"))
478
item.SetBitmap(MetaIcon(img = 'layer-export').GetBitmap(self.bmpsize))
479
self.popupMenu.AppendItem(item)
378
480
self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['v.out.ogr',
379
481
'input=%s' % mapLayer.GetName()]),
380
482
id = self.popupID['export'])
483
if 'v.out.ogr' not in globalvar.grassCmd:
484
self.popupMenu.Enable(self.popupID['export'], False)
486
self.popupMenu.Append(self.popupID['export-pg'], text = _("Export PostGIS"))
487
self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['v.out.postgis',
488
'input=%s' % mapLayer.GetName()]),
489
id = self.popupID['export-pg'])
490
if 'v.out.postgis' not in globalvar.grassCmd:
491
self.popupMenu.Enable(self.popupID['export-pg'], False)
493
item = wx.MenuItem(self.popupMenu, id = self.popupID['pack'], text = _("Create pack"))
494
self.popupMenu.AppendItem(item)
495
self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['v.pack',
496
'input=%s' % mapLayer.GetName()]),
497
id = self.popupID['pack'])
499
lmapset = self.GetLayerInfo(self.layer_selected, key = 'maplayer').GetMapset()
500
if lmapset != currentMapset:
501
self.popupMenu.Append(self.popupID['copy'], text = _("Make a copy in the current mapset"))
502
self.Bind(wx.EVT_MENU, self.OnCopyMap, id = self.popupID['copy'])
382
504
self.popupMenu.AppendSeparator()
384
506
self.popupMenu.Append(self.popupID['color'], _("Set color table"))
385
507
self.Bind (wx.EVT_MENU, self.OnVectorColorTable, id = self.popupID['color'])
387
self.popupMenu.Append(self.popupID['attr'], text = _("Show attribute data"))
509
item = wx.MenuItem(self.popupMenu, id = self.popupID['attr'], text = _("Show attribute data"))
510
item.SetBitmap(MetaIcon(img = 'table').GetBitmap(self.bmpsize))
511
self.popupMenu.AppendItem(item)
388
512
self.Bind(wx.EVT_MENU, self.lmgr.OnShowAttributeTable, id = self.popupID['attr'])
390
self.popupMenu.Append(self.popupID['edit0'], text = _("Start editing"))
391
self.popupMenu.Append(self.popupID['edit1'], text = _("Stop editing"))
392
self.popupMenu.Enable(self.popupID['edit1'], False)
393
self.Bind (wx.EVT_MENU, self.OnStartEditing, id = self.popupID['edit0'])
394
self.Bind (wx.EVT_MENU, self.OnStopEditing, id = self.popupID['edit1'])
396
layer = self.GetPyData(self.layer_selected)[0]['maplayer']
397
# enable editing only for vector map layers available in the current mapset
398
514
digitToolbar = self.mapdisplay.GetToolbar('vdigit')
516
vdigitLayer = digitToolbar.GetLayer()
519
layer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
520
if vdigitLayer is not layer:
521
item = wx.MenuItem(self.popupMenu, id = self.popupID['edit'], text = _("Start editing"))
522
self.Bind (wx.EVT_MENU, self.OnStartEditing, id = self.popupID['edit'])
524
item = wx.MenuItem(self.popupMenu, id = self.popupID['edit'], text = _("Stop editing"))
525
self.Bind (wx.EVT_MENU, self.OnStopEditing, id = self.popupID['edit'])
526
item.SetBitmap(MetaIcon(img = 'edit').GetBitmap(self.bmpsize))
527
self.popupMenu.AppendItem(item)
529
### removed from layer tree
400
531
# background vector map
401
self.popupMenu.Append(self.popupID['bgmap'],
402
text = _("Use as background vector map for digitizer"),
403
kind = wx.ITEM_CHECK)
404
self.Bind(wx.EVT_MENU, self.OnSetBgMap, id = self.popupID['bgmap'])
405
if UserSettings.Get(group = 'vdigit', key = 'bgmap', subkey = 'value',
406
internal = True) == layer.GetName():
407
self.popupMenu.Check(self.popupID['bgmap'], True)
532
# self.popupMenu.Append(self.popupID['bgmap'],
533
# text = _("Use as background vector map for digitizer"),
534
# kind = wx.ITEM_CHECK)
535
# self.Bind(wx.EVT_MENU, self.OnSetBgMap, id = self.popupID['bgmap'])
536
# if UserSettings.Get(group = 'vdigit', key = 'bgmap', subkey = 'value',
537
# internal = True) == layer.GetName():
538
# self.popupMenu.Check(self.popupID['bgmap'], True)
409
540
self.popupMenu.Append(self.popupID['topo'], text = _("Rebuild topology"))
410
541
self.Bind(wx.EVT_MENU, self.OnTopology, id = self.popupID['topo'])
544
# if layer and layer.GetType() == 'vector':
545
# if 'info' not in self.GetLayerInfo(self.layer_selected):
546
# info = grass.parse_command('v.info',
548
# map = layer.GetName())
549
# self.SetLayerInfo(self.layer_selected, key = 'info', value = info)
550
# info = self.GetLayerInfo(self.layer_selected, key = 'info')
551
# if info and info['format'] != 'native' and \
552
# info['format'].split(',')[1] == 'PostgreSQL':
553
# self.popupMenu.Append(self.popupID['sql'], text = _("SQL Spatial Query"))
554
# self.Bind(wx.EVT_MENU, self.OnSqlQuery, id = self.popupID['sql'])
412
if layer.GetMapset() != grass.gisenv()['MAPSET']:
556
if layer.GetMapset() != currentMapset:
413
557
# only vector map in current mapset can be edited
414
self.popupMenu.Enable (self.popupID['edit0'], False)
415
self.popupMenu.Enable (self.popupID['edit1'], False)
558
self.popupMenu.Enable (self.popupID['edit'], False)
416
559
self.popupMenu.Enable (self.popupID['topo'], False)
417
560
elif digitToolbar and digitToolbar.GetLayer():
418
561
# vector map already edited
419
562
vdigitLayer = digitToolbar.GetLayer()
420
563
if vdigitLayer is layer:
421
self.popupMenu.Enable(self.popupID['edit0'], False)
422
self.popupMenu.Enable(self.popupID['edit1'], True)
423
564
self.popupMenu.Enable(self.popupID['remove'], False)
424
565
self.popupMenu.Enable(self.popupID['bgmap'], False)
425
566
self.popupMenu.Enable(self.popupID['topo'], False)
427
self.popupMenu.Enable(self.popupID['edit0'], False)
428
self.popupMenu.Enable(self.popupID['edit1'], False)
429
568
self.popupMenu.Enable(self.popupID['bgmap'], True)
431
self.popupMenu.Append(self.popupID['meta'], _("Metadata"))
570
item = wx.MenuItem(self.popupMenu, id = self.popupID['meta'], text = _("Metadata"))
571
item.SetBitmap(MetaIcon(img = 'layer-info').GetBitmap(self.bmpsize))
572
self.popupMenu.AppendItem(item)
432
573
self.Bind (wx.EVT_MENU, self.OnMetadata, id = self.popupID['meta'])
434
self.popupMenu.Enable(self.popupID['attr'], False)
435
self.popupMenu.Enable(self.popupID['edit0'], False)
436
self.popupMenu.Enable(self.popupID['edit1'], False)
437
self.popupMenu.Enable(self.popupID['meta'], False)
438
self.popupMenu.Enable(self.popupID['bgmap'], False)
439
self.popupMenu.Enable(self.popupID['topo'], False)
440
self.popupMenu.Enable(self.popupID['export'], False)
442
575
# raster layers (specific items)
443
576
elif mltype and mltype == "raster":
444
self.popupMenu.Append(self.popupID['zoom1'], text = _("Zoom to selected map(s) (ignore NULLs)"))
445
self.Bind(wx.EVT_MENU, self.mapdisplay.OnZoomToRaster, id = self.popupID['zoom1'])
446
self.popupMenu.Append(self.popupID['region1'], text = _("Set computational region from selected map(s) (ignore NULLs)"))
447
self.Bind(wx.EVT_MENU, self.OnSetCompRegFromRaster, id = self.popupID['region1'])
449
self.popupMenu.AppendSeparator()
450
self.popupMenu.Append(self.popupID['export'], text = _("Export"))
451
self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['r.out.gdal',
452
'input=%s' % mapLayer.GetName()]),
453
id = self.popupID['export'])
455
self.popupMenu.AppendSeparator()
578
self.popupMenu.Append(self.popupID['zoom1'], text=_("Zoom to selected map(s) (ignore NULLs)"))
579
self.Bind(wx.EVT_MENU, self.mapdisplay.OnZoomToRaster, id=self.popupID['zoom1'])
580
self.popupMenu.Append(self.popupID['region1'], text=_("Set computational region from selected map(s) (ignore NULLs)"))
581
self.Bind(wx.EVT_MENU, self.OnSetCompRegFromRaster, id=self.popupID['region1'])
583
self.popupMenu.AppendSeparator()
586
item = wx.MenuItem(self.popupMenu, id = self.popupID['export'], text = _("Export"))
587
item.SetBitmap(MetaIcon(img = 'layer-export').GetBitmap(self.bmpsize))
588
self.popupMenu.AppendItem(item)
589
self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['r.out.gdal',
590
'input=%s' % mapLayer.GetName()]),
591
id = self.popupID['export'])
593
item = wx.MenuItem(self.popupMenu, id = self.popupID['pack'], text = _("Create pack"))
594
self.popupMenu.AppendItem(item)
595
self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['r.pack',
596
'input=%s' % mapLayer.GetName()]),
597
id = self.popupID['pack'])
599
lmapset = self.GetLayerInfo(self.layer_selected, key = 'maplayer').GetMapset()
600
if lmapset != currentMapset:
601
self.popupMenu.Append(self.popupID['copy'], text = _("Make a copy in the current mapset"))
602
self.Bind(wx.EVT_MENU, self.OnCopyMap, id = self.popupID['copy'])
604
self.popupMenu.AppendSeparator()
456
606
self.popupMenu.Append(self.popupID['color'], _("Set color table"))
457
607
self.Bind (wx.EVT_MENU, self.OnRasterColorTable, id = self.popupID['color'])
458
self.popupMenu.Append(self.popupID['hist'], _("Histogram"))
609
item = wx.MenuItem(self.popupMenu, id = self.popupID['hist'], text = _("Histogram"))
610
item.SetBitmap(MetaIcon(img = 'layer-raster-histogram').GetBitmap(self.bmpsize))
611
self.popupMenu.AppendItem(item)
459
612
self.Bind (wx.EVT_MENU, self.OnHistogram, id = self.popupID['hist'])
460
self.popupMenu.Append(self.popupID['univar'], _("Univariate raster statistics"))
614
item = wx.MenuItem(self.popupMenu, id = self.popupID['univar'], text = _("Univariate raster statistics"))
615
item.SetBitmap(MetaIcon(img = 'raster-stats').GetBitmap(self.bmpsize))
616
self.popupMenu.AppendItem(item)
461
617
self.Bind (wx.EVT_MENU, self.OnUnivariateStats, id = self.popupID['univar'])
462
self.popupMenu.Append(self.popupID['prof'], _("Profile"))
463
self.Bind (wx.EVT_MENU, self.OnProfile, id = self.popupID['prof'])
464
self.popupMenu.Append(self.popupID['meta'], _("Metadata"))
465
self.Bind (wx.EVT_MENU, self.OnMetadata, id = self.popupID['meta'])
468
self.popupMenu.Enable(self.popupID['zoom1'], False)
469
self.popupMenu.Enable(self.popupID['region1'], False)
470
self.popupMenu.Enable(self.popupID['color'], False)
471
self.popupMenu.Enable(self.popupID['hist'], False)
472
self.popupMenu.Enable(self.popupID['univar'], False)
473
self.popupMenu.Enable(self.popupID['prof'], False)
474
self.popupMenu.Enable(self.popupID['meta'], False)
475
self.popupMenu.Enable(self.popupID['export'], False)
476
if self.lmgr.IsPaneShown('toolbarNviz'):
477
self.popupMenu.Enable(self.popupID['nviz'], False)
619
item = wx.MenuItem(self.popupMenu, id = self.popupID['report'], text = _("Report raster statistics"))
620
item.SetBitmap(MetaIcon(img = 'stats').GetBitmap(self.bmpsize))
621
self.popupMenu.AppendItem(item)
622
self.Bind(wx.EVT_MENU, self.OnReportStats, id = self.popupID['report'])
625
item = wx.MenuItem(self.popupMenu, id = self.popupID['prof'], text = _("Profile"))
626
item.SetBitmap(MetaIcon(img = 'layer-raster-profile').GetBitmap(self.bmpsize))
627
self.popupMenu.AppendItem(item)
628
self.Bind (wx.EVT_MENU, self.OnProfile, id = self.popupID['prof'])
630
item = wx.MenuItem(self.popupMenu, id = self.popupID['meta'], text = _("Metadata"))
631
item.SetBitmap(MetaIcon(img = 'layer-info').GetBitmap(self.bmpsize))
632
self.popupMenu.AppendItem(item)
633
self.Bind (wx.EVT_MENU, self.OnMetadata, id = self.popupID['meta'])
635
elif mltype and mltype == '3d-raster':
637
self.popupMenu.AppendSeparator()
638
self.popupMenu.Append(self.popupID['color'], _("Set color table"))
639
self.Bind(wx.EVT_MENU, self.OnRasterColorTable, id=self.popupID['color'])
641
item = wx.MenuItem(self.popupMenu, id = self.popupID['univar'], text = _("Univariate raster statistics"))
642
item.SetBitmap(MetaIcon(img = 'stats').GetBitmap(self.bmpsize))
643
self.popupMenu.AppendItem(item)
644
self.Bind (wx.EVT_MENU, self.OnUnivariateStats, id = self.popupID['univar'])
646
item = wx.MenuItem(self.popupMenu, id = self.popupID['meta'], text = _("Metadata"))
647
item.SetBitmap(MetaIcon(img = 'layer-info').GetBitmap(self.bmpsize))
648
self.popupMenu.AppendItem(item)
649
self.Bind (wx.EVT_MENU, self.OnMetadata, id = self.popupID['meta'])
651
# web service layers (specific item)
652
elif mltype and mltype == "wms":
653
self.popupMenu.Append(self.popupID['save_ws'], text = _("Save web service layer"))
654
self.Bind(wx.EVT_MENU, self.OnSaveWs, id = self.popupID['save_ws'])
479
656
self.PopupMenu(self.popupMenu)
480
657
self.popupMenu.Destroy()
659
def OnSaveWs(self, event):
660
"""Show dialog for saving web service layer into GRASS vector/raster layer"""
661
mapLayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
662
dlg = SaveWMSLayerDialog(parent=self, layer=mapLayer,
663
giface=self._gifaceForDisplay)
482
667
def OnTopology(self, event):
483
"""!Rebuild topology of selected vector map"""
484
mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
668
"""Rebuild topology of selected vector map"""
669
mapLayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
485
670
cmd = ['v.build',
486
671
'map=%s' % mapLayer.GetName()]
487
self.lmgr.goutput.RunCmd(cmd, switchPage = True)
672
self._giface.RunCmd(cmd)
674
def OnSqlQuery(self, event):
675
"""Show SQL query window for PostGIS layers
677
dlg = SqlQueryFrame(parent = self)
489
681
def OnMetadata(self, event):
490
"""!Print metadata of raster/vector map layer
491
TODO: Dialog to modify metadata
682
"""Print metadata of raster/vector map layer
685
Dialog to modify metadata
493
mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
494
mltype = self.GetPyData(self.layer_selected)[0]['type']
687
mapLayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
688
mltype = self.GetLayerInfo(self.layer_selected,key = 'type')
496
690
if mltype == 'raster':
498
692
elif mltype == 'vector':
694
elif mltype == '3d-raster':
500
696
cmd.append('map=%s' % mapLayer.GetName())
502
698
# print output to command log area
503
self.lmgr.goutput.RunCmd(cmd, switchPage = True)
699
self._giface.RunCmd(cmd)
505
701
def OnSetCompRegFromRaster(self, event):
506
"""!Set computational region from selected raster map (ignore NULLs)"""
507
mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
702
"""Set computational region from selected raster map (ignore NULLs)"""
703
mapLayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
509
705
cmd = ['g.region',
511
706
'zoom=%s' % mapLayer.GetName()]
513
708
# print output to command log area
514
self.lmgr.goutput.RunCmd(cmd)
709
self._giface.RunCmd(cmd, notification=Notification.NO_NOTIFICATION)
711
# re-render map display
712
self._giface.GetMapWindow().UpdateMap(render=True)
516
714
def OnSetCompRegFromMap(self, event):
517
"""!Set computational region from selected raster/vector map
715
"""Set computational region from selected raster/vector map
522
720
for layer in self.GetSelections():
523
mapLayer = self.GetPyData(layer)[0]['maplayer']
524
mltype = self.GetPyData(layer)[0]['type']
721
mapLayer = self.GetLayerInfo(layer, key = 'maplayer')
722
mltype = self.GetLayerInfo(layer, key = 'type')
526
724
if mltype == 'raster':
527
725
rast.append(mapLayer.GetName())
536
734
cmd = ['g.region']
538
cmd.append('rast=%s' % ','.join(rast))
736
cmd.append('raster=%s' % ','.join(rast))
540
cmd.append('vect=%s' % ','.join(vect))
738
cmd.append('vector=%s' % ','.join(vect))
542
cmd.append('rast3d=%s' % ','.join(rast3d))
740
cmd.append('raster_3d=%s' % ','.join(rast3d))
544
742
# print output to command log area
547
self.lmgr.goutput.RunCmd(cmd, compReg = False)
744
if mltype == '3d-raster':
746
self._giface.RunCmd(cmd, compReg = False,
747
notification=Notification.NO_NOTIFICATION)
749
# re-render map display
750
self._giface.GetMapWindow().UpdateMap(render=True)
549
752
def OnProfile(self, event):
550
"""!Plot profile of given raster map layer"""
551
mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
753
"""Plot profile of given raster map layer"""
754
mapLayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
552
755
if not mapLayer.GetName():
553
756
wx.MessageBox(parent = self,
554
757
message = _("Unable to create profile of "
556
759
caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
559
if not hasattr (self, "profileFrame"):
560
self.profileFrame = None
562
if hasattr (self.mapdisplay, "profile") and self.mapdisplay.profile:
563
self.profileFrame = self.mapdisplay.profile
565
if not self.profileFrame:
566
self.profileFrame = ProfileFrame(self.mapdisplay,
567
id = wx.ID_ANY, pos = wx.DefaultPosition, size = (700,300),
568
style = wx.DEFAULT_FRAME_STYLE, rasterList = [mapLayer.GetName()])
570
self.profileFrame.Show()
761
self.mapdisplay.Profile(rasters=[mapLayer.GetName()])
572
763
def OnRasterColorTable(self, event):
573
"""!Set color table for raster map"""
574
name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
575
GUI(parent = self).ParseCommand(['r.colors',
764
"""Set color table for 2D/3D raster map"""
767
for layer in self.GetSelectedLayers():
768
if self.GetLayerInfo(layer, key='type') == '3d-raster':
769
raster3d.append(self.GetLayerInfo(layer, key = 'maplayer').GetName())
771
raster2d.append(self.GetLayerInfo(layer, key = 'maplayer').GetName())
774
GUI(parent = self, giface = self._giface).ParseCommand(['r.colors',
775
'map=%s' % ','.join(raster2d)])
777
GUI(parent = self, giface = self._giface).ParseCommand(['r3.colors',
778
'map=%s' % ','.join(raster3d)])
578
780
def OnVectorColorTable(self, event):
579
"""!Set color table for vector map"""
580
name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
781
"""Set color table for vector map"""
782
name = self.GetLayerInfo(self.layer_selected, key = 'maplayer').GetName()
581
783
GUI(parent = self, centreOnParent = False).ParseCommand(['v.colors',
582
784
'map=%s' % name])
786
def _mapNameValidationFailed(self, ctrl):
787
message = _("Name <%(name)s> is not a valid name for GRASS map. "
788
"Please use only ASCII characters excluding %(chars)s "
789
"and space.") % {'name': ctrl.GetValue(), 'chars': '/"\'@,=*~'}
790
GError(parent=self, message=message, caption=_("Invalid name"))
792
def OnCopyMap(self, event):
793
"""Copy selected map into current mapset"""
794
layer = self.GetSelectedLayer()
795
ltype = self.GetLayerInfo(layer, key='type')
796
lnameSrc = self.GetLayerInfo(layer, key = 'maplayer').GetName()
798
if ltype == 'raster':
801
label = _('Raster map')
802
elif ltype == 'vector':
805
label = _('Vector map')
806
elif ltype == '3d-raster':
809
label = _('3D raster map')
811
GError(_("Unsupported map type <%s>") % ltype, parent = self)
814
# TODO: replace by New[Raster|Vector]Dialog
815
dlg = TextEntryDialog(parent = self,
816
message = _('Enter name for the new %s in the current mapset:') % label.lower(),
817
caption = _('Make a copy of %s <%s>') % (label.lower(), lnameSrc),
818
defaultValue = lnameSrc.split('@')[0],
819
validator = GenericValidator(grass.legal_name, self._mapNameValidationFailed),
821
if dlg.ShowModal() == wx.ID_OK:
822
lnameDst = dlg.GetValue()
828
currentMapset = grass.gisenv()['MAPSET']
829
# check if map already exists
830
if lnameDst in grass.list_grouped(key)[currentMapset]:
831
dlgOw = wx.MessageDialog(parent = self, message = _("%s <%s> already exists "
832
"in the current mapset. "
833
"Do you want to overwrite it?") % (label, lnameDst),
834
caption = _("Overwrite?"),
835
style = wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
836
if dlgOw.ShowModal() != wx.ID_YES:
839
kwargs = {key : '%s,%s' % (lnameSrc, lnameDst)}
840
if 0 != RunCommand('g.copy', overwrite = True, **kwargs):
841
GError(_("Unable to make copy of <%s>") % lnameSrc,
846
mapsetDst = lnameDst.split('@')[1]
847
if mapsetDst != currentMapset:
848
GError(_("Unable to make copy of <%s>. Mapset <%s> is not current mapset.") % \
849
(lnameSrc, mapsetDst))
852
lnameDst += '@' + currentMapset
853
# add copied map to the layer tree
854
self.AddLayer(ltype, lname = lnameDst, lcmd = ['d.%s' % module, 'map=%s' % lnameDst])
584
856
def OnHistogram(self, event):
585
"""!Plot histogram for given raster map layer
857
"""Plot histogram for given raster map layer
587
mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
588
if not mapLayer.GetName():
860
for layer in self.GetSelectedLayers():
861
rasterList.append(self.GetLayerInfo(layer, key = 'maplayer').GetName())
589
864
GError(parent = self,
590
865
message = _("Unable to display histogram of "
591
866
"raster map. No map name defined."))
594
win = HistogramFrame(parent = self)
869
win = HistogramPlotFrame(parent = self, rasterList = rasterList)
596
870
win.CentreOnScreen()
598
win.SetHistLayer(mapLayer.GetName())
599
win.HistWindow.UpdateHist()
603
873
def OnUnivariateStats(self, event):
604
"""!Univariate raster statistics"""
605
name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
606
self.lmgr.goutput.RunCmd(['r.univar', 'map=%s' % name], switchPage = True)
874
"""Univariate 2D/3D raster statistics"""
877
for layer in self.GetSelectedLayers():
878
if self.GetLayerInfo(layer, key='type') == '3d-raster':
879
raster3d.append(self.GetLayerInfo(layer, key = 'maplayer').GetName())
881
raster2d.append(self.GetLayerInfo(layer, key = 'maplayer').GetName())
884
self._giface.RunCmd(['r.univar', 'map=%s' % ','.join(raster2d)])
887
self._giface.RunCmd(['r3.univar', 'map=%s' % ','.join(raster3d)])
889
def OnReportStats(self, event):
890
"""Print 2D statistics"""
892
# TODO: Implement self.GetSelectedLayers(ltype='raster')
893
for layer in self.GetSelectedLayers():
894
if self.GetLayerInfo(layer, key='type') == 'raster':
895
rasters.append(self.GetLayerInfo(layer, key = 'maplayer').GetName())
898
self._giface.RunCmd(['r.report', 'map=%s' % ','.join(rasters), 'units=h,c,p'])
608
900
def OnStartEditing(self, event):
609
"""!Start editing vector map layer requested by the user
901
"""Start editing vector map layer requested by the user
612
maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
903
mapLayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
905
from vdigit import errorMsg
907
self.mapdisplay.toolbars['map'].combo.SetValue (_("2D view"))
909
GError(_("Unable to start wxGUI vector digitizer.\n"
910
"Details: %s") % errorMsg, parent = self)
617
913
if not self.mapdisplay.GetToolbar('vdigit'): # enable tool
618
914
self.mapdisplay.AddToolbar('vdigit')
620
if not self.mapdisplay.toolbars['vdigit']:
623
self.mapdisplay.toolbars['vdigit'].StartEditing(maplayer)
916
else: # tool already enabled
919
# mark layer as 'edited'
920
self.mapdisplay.toolbars['vdigit'].StartEditing(mapLayer)
922
def StartEditing(self, layerItem):
625
923
self._setGradient('vdigit')
626
self.RefreshLine(self.layer_selected)
925
self.SetItemIcon(layerItem, 'edited')
926
self.RefreshLine(layerItem)
628
928
def OnStopEditing(self, event):
629
"""!Stop editing the current vector map layer
929
"""Stop editing the current vector map layer
631
maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
633
931
self.mapdisplay.toolbars['vdigit'].OnExit()
635
self.lmgr.toolbars['tools'].Enable('vdigit', enable = True)
933
def StopEditing(self, layerItem):
637
934
self._setGradient()
638
self.RefreshLine(self.layer_selected)
935
self.SetItemIcon(layerItem)
936
self.RefreshLine(layerItem)
938
def SetBgMapForEditing(self, mapName, unset=False):
940
layerItem = self.FindItemByData('name', mapName)[0]
640
def OnSetBgMap(self, event):
641
"""!Set background vector map for editing sesstion"""
642
digit = self.mapdisplay.GetWindow().digit
643
if event.IsChecked():
644
mapName = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
645
UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
646
value = str(mapName), internal = True)
647
digit.OpenBackgroundMap(mapName)
648
945
self._setGradient('bgmap')
946
self.SetItemIcon(layerItem, 'bgmap')
650
UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
651
value = '', internal = True)
652
digit.CloseBackgroundMap()
653
948
self._setGradient()
949
self.SetItemIcon(layerItem)
655
self.RefreshLine(self.layer_selected)
951
self.RefreshLine(layerItem)
657
953
def OnPopupProperties (self, event):
658
"""!Popup properties dialog"""
954
"""Popup properties dialog"""
659
955
self.PropertiesDialog(self.layer_selected)
661
957
def OnPopupOpacityLevel(self, event):
662
"""!Popup opacity level indicator"""
663
if not self.GetPyData(self.layer_selected)[0]['ctrl']:
958
"""Popup opacity level indicator"""
959
if not self.GetLayerInfo(self.layer_selected, key = 'ctrl'):
666
maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
962
maplayer = self.GetLayerInfo(self.layer_selected, key = 'maplayer')
667
963
current_opacity = maplayer.GetOpacity()
669
965
dlg = SetOpacityDialog(self, opacity = current_opacity,
670
966
title = _("Set opacity of <%s>") % maplayer.GetName())
967
dlg.applyOpacity.connect(lambda value:
968
self.ChangeLayerOpacity(layer=self.layer_selected, value=value))
671
969
dlg.CentreOnParent()
672
dlg.Bind(EVT_APPLY_OPACITY, self.OnApplyLayerOpacity)
674
971
if dlg.ShowModal() == wx.ID_OK:
675
972
self.ChangeLayerOpacity(layer = self.layer_selected, value = dlg.GetOpacity())
678
def OnApplyLayerOpacity(self, event):
679
"""!Handles EVT_APPLY_OPACITY event."""
680
self.ChangeLayerOpacity(layer = self.layer_selected, value = event.value)
682
975
def ChangeLayerOpacity(self, layer, value):
683
"""!Change opacity value of layer
684
@param layer layer for which to change (item in layertree)
685
@param value opacity value (float between 0 and 1)
976
"""Change opacity value of layer
978
:param layer: layer for which to change (item in layertree)
979
:param value: opacity value (float between 0 and 1)
687
maplayer = self.GetPyData(layer)[0]['maplayer']
981
maplayer = self.GetLayerInfo(layer, key = 'maplayer')
688
982
self.Map.ChangeOpacity(maplayer, value)
689
983
maplayer.SetOpacity(value)
690
984
self.SetItemText(layer,