Changeset 65205
- Timestamp:
- May 10, 2015, 2:01:38 AM (9 years ago)
- Location:
- grass/trunk/gui/wxpython
- Files:
-
- 6 edited
-
core/render.py (modified) (18 diffs)
-
core/ws.py (modified) (5 diffs)
-
lmgr/layertree.py (modified) (13 diffs)
-
mapdisp/frame.py (modified) (1 diff)
-
mapdisp/main.py (modified) (7 diffs)
-
mapwin/buffered.py (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
-
grass/trunk/gui/wxpython/core/render.py
r65158 r65205 3 3 4 4 @brief Rendering map layers and overlays into map composition image. 5 6 .. todo::7 Implement RenderManager also for other layers (see WMS8 implementation for details)9 10 .. todo::11 Render classes should not care about updating statusbar (change12 emiting events).13 5 14 6 Classes: … … 17 9 - render::Overlay 18 10 - render::Map 11 - render::RenderLayerMgr 12 - render::RenderMapMgr 19 13 20 14 (C) 2006-2015 by the GRASS Development Team … … 41 35 from grass.script import core as grass 42 36 from grass.script.utils import try_remove 43 from grass.script.task import cmdlist_to_tuple 37 from grass.script.task import cmdlist_to_tuple, cmdtuple_to_list 44 38 from grass.pydispatch.signal import Signal 45 39 … … 50 44 from core.debug import Debug 51 45 from core.settings import UserSettings 46 from core.gconsole import CmdThread, GStderr, EVT_CMD_DONE 52 47 53 48 class Layer(object): … … 123 118 124 119 def __str__(self): 125 return self. name120 return self.GetCmd(string=True) 126 121 127 122 def __repr__(self): … … 151 146 {'type' : self.type, 'name' : self.name}) 152 147 148 # render layers 153 149 env.update(self.render_env) 154 # execute command155 150 try: 156 151 if self.type == 'command': 157 read = False152 first = True 158 153 for c in self.cmd: 159 ret, msg = self._runCommand(c, env) 160 if ret != 0: 161 break 162 if not read: 154 self.renderMgr.Render(c, env) 155 if first: 163 156 env["GRASS_RENDER_FILE_READ"] = "TRUE" 164 165 env["GRASS_RENDER_FILE_READ"] = "FALSE" 157 first = False 166 158 else: 167 ret, msg = self._runCommand(self.cmd, env) 168 if ret != 0: 169 sys.stderr.write(_("Command '%s' failed\n") % self.GetCmd(string = True)) 170 if msg: 171 sys.stderr.write(_("Details: %s\n") % msg) 172 raise GException() 173 159 self.renderMgr.Render(self.cmd, env) 174 160 except GException: 161 sys.stderr.write(_("Command '%s' failed\n") % self.GetCmd(string = True)) 162 sys.stderr.write(_("Details: %s\n") % e) 163 175 164 # clean up after problems 176 165 for f in [self.mapfile, self.maskfile]: … … 179 168 try_remove(f) 180 169 f = None 181 182 self.forceRender = False 183 170 184 171 return self.mapfile 185 186 def _runCommand(self, cmd, env): 187 """Run command to render data 188 """ 189 if self.type == 'wms': 190 ret = 0 191 msg = '' 192 self.renderMgr.Render(cmd, env=env) 193 else: 194 ret, msg = RunCommand(cmd[0], 195 getErrorMsg = True, 196 quiet = True, 197 env=env, 198 **cmd[1]) 199 200 return ret, msg 201 172 202 173 def GetCmd(self, string = False): 203 174 """Get GRASS command as list of string. … … 276 247 raise GException(_("Unsupported map layer type '%s'") % ltype) 277 248 278 if ltype == 'wms' and not isinstance(self.renderMgr, RenderWMSMgr):279 self.renderMgr = RenderWMSMgr(layer=self,280 mapfile=self.mapfile,281 maskfile=self.maskfile)282 elif self.type == 'wms' and ltype != 'wms':283 self.renderMgr = None284 249 if not self.renderMgr: 250 if ltype == 'wms': 251 renderMgr = RenderWMSMgr 252 else: 253 renderMgr = RenderLayerMgr 254 self.renderMgr = renderMgr(self) 255 285 256 self.type = ltype 286 257 … … 321 292 def IsDownloading(self): 322 293 """Is data downloading from web server e. g. wms""" 323 if self.renderMgr is None: 324 return False 325 else: 326 return self.renderMgr.IsDownloading() 294 return self.renderMgr.IsDownloading() 327 295 328 296 def AbortThread(self): 329 297 """Abort running thread e. g. downloading data""" 330 if self.renderMgr is None: 331 return 332 else: 333 self.renderMgr.Abort() 298 self.renderMgr.Abort() 334 299 335 300 def GetRenderMgr(self): … … 368 333 self.render_env["GRASS_RENDER_TRANSPARENT"] = "TRUE" 369 334 335 class RenderLayerMgr(wx.EvtHandler): 336 def __init__(self, layer): 337 """Render layer into image 338 339 :param layer: Layer to be rendered 340 """ 341 self.layer = layer 342 343 wx.EvtHandler.__init__(self) 344 self.thread = CmdThread(self) 345 self.cmdStdErr = GStderr(self) 346 347 self.updateProgress = Signal('RenderLayerMgr.updateProgress') 348 self.Bind(EVT_CMD_DONE, self.OnRenderDone) 349 350 self._startTime = None 351 352 def Render(self, cmd, env): 353 """Render layer 354 355 :param cmd: display command given as tuple 356 :param env: environmental variables used for rendering 357 """ 358 Debug.msg(1, "RenderLayerMgr.Render(%s): force=%d img=%s" % \ 359 (self.layer, self.layer.forceRender, self.layer.mapfile)) 360 361 env_cmd = env.copy() 362 env_cmd['GRASS_RENDER_FILE'] = self.layer.mapfile 363 364 cmd[1]['quiet'] = True # be quiet 365 cmd_tuple = cmdtuple_to_list(cmd) 366 367 self._startTime = time.time() 368 self.thread.RunCmd(cmd_tuple, env=env_cmd, stderr=self.cmdStdErr) 369 self.layer.forceRender = False 370 371 def Abort(self): 372 """Abort rendering process""" 373 self.thread.abort(abortall = True) 374 375 def IsDownloading(self): 376 """Is downloading 377 378 :return: always False 379 """ 380 return False 381 382 def OnRenderDone(self, event): 383 """Rendering done 384 385 Emits updateProcess 386 """ 387 stop = time.time() 388 Debug.msg(1, "RenderLayerMgr.OnRenderDone(%s): ret=%d time=%f" % \ 389 (self.layer, event.returncode, stop - self._startTime)) 390 self.updateProgress.emit(layer=self.layer) 391 392 class RenderMapMgr(wx.EvtHandler): 393 def __init__(self, Map): 394 """Render map layers as image composition 395 396 :param Map: Map object to be rendered 397 """ 398 wx.EvtHandler.__init__(self) 399 400 self.Map = Map 401 self.thread = CmdThread(self) 402 self.cmdStdErr = GStderr(self) 403 404 self.updateMap = Signal('RenderMapMgr.updateMap') 405 self.updateProgress = Signal('RenderMapMgr.updateProgress') 406 self.renderDone = Signal('RenderMapMgr.renderDone') 407 self.renderDone.connect(self.OnRenderDone) 408 409 # GRASS environment variable (for rendering) 410 self._render_env = {"GRASS_RENDER_BACKGROUNDCOLOR" : "000000", 411 "GRASS_RENDER_FILE_COMPRESSION" : "0", 412 "GRASS_RENDER_TRUECOLOR" : "TRUE", 413 "GRASS_RENDER_TRANSPARENT" : "TRUE" } 414 415 self._init() 416 self._rendering = False 417 418 def _init(self, env=None): 419 """Init render manager 420 421 :param env: environmental variables or None 422 """ 423 self._startTime = time.time() 424 self.progressInfo = None 425 self._env = env 426 self.layers = [] 427 428 # re-render from scratch 429 if os.path.exists(self.Map.mapfile): 430 os.remove(self.Map.mapfile) 431 432 def _renderLayers(self, env, force = False, overlaysOnly = False): 433 """Render all map layers into files 434 435 :param dict env: environmental variables to be used for rendering process 436 :param bool force: True to force rendering 437 :param bool overlaysOnly: True to render only overlays 438 439 :return: number of layers to be rendered 440 """ 441 if overlaysOnly: 442 self.layers = self.Map.GetListOfLayers(ltype='overlay', active=True) 443 else: 444 self.layers = self.Map.GetListOfLayers(active=True) 445 446 # reset progress 447 self.ReportProgress() 448 449 # render map layers if forced 450 nlayers = 0 451 for layer in self.layers: 452 if force or layer.forceRender: 453 nlayers += 1 454 layer.Render(env) 455 else: 456 layer.GetRenderMgr().updateProgress.emit(layer=layer) 457 458 Debug.msg(1, "RenderMapMgr.Render(): %d layers to be rendered " 459 "(force=%d, all active layers -> %d)" % (nlayers, force, 460 len(self.layers))) 461 462 return nlayers 463 464 def Render(self, force = False, windres = False): 465 """Render map composition 466 467 :param bool force: force rendering all map layers in the composition 468 :param windres: True for region resolution instead for map resolution 469 """ 470 if self._rendering: 471 Debug.msg(1, "RenderMapMgr().Render(): cancelled (already rendering)") 472 return 473 474 wx.BeginBusyCursor() 475 self._rendering = True 476 477 env = os.environ.copy() 478 env.update(self._render_env) 479 # use external gisrc if defined 480 if self.Map.gisrc: 481 env['GISRC'] = self.Map.gisrc 482 env['GRASS_REGION'] = self.Map.SetRegion(windres) 483 env['GRASS_RENDER_WIDTH'] = str(self.Map.width) 484 env['GRASS_RENDER_HEIGHT'] = str(self.Map.height) 485 driver = UserSettings.Get(group = 'display', key = 'driver', subkey = 'type') 486 if driver == 'png': 487 env['GRASS_RENDER_IMMEDIATE'] = 'png' 488 else: 489 env['GRASS_RENDER_IMMEDIATE'] = 'cairo' 490 491 self._init(env) 492 if self._renderLayers(env, force, windres) == 0: 493 self.renderDone.emit() 494 495 def OnRenderDone(self): 496 """Rendering process done 497 498 Make image composiotion, emits updateMap event. 499 """ 500 stopTime = time.time() 501 502 maps = list() 503 masks = list() 504 opacities = list() 505 506 for layer in self.layers: 507 maps.append(layer.mapfile) 508 masks.append(layer.maskfile) 509 opacities.append(str(layer.opacity)) 510 511 # run g.pngcomp to get composite image 512 bgcolor = ':'.join(map(str, UserSettings.Get(group = 'display', key = 'bgcolor', 513 subkey = 'color'))) 514 startCompTime = time.time() 515 if maps: 516 ret, msg = RunCommand('g.pnmcomp', 517 getErrorMsg = True, 518 overwrite = True, 519 input = '%s' % ",".join(maps), 520 mask = '%s' % ",".join(masks), 521 opacity = '%s' % ",".join(opacities), 522 bgcolor = bgcolor, 523 width = self.Map.width, 524 height = self.Map.height, 525 output = self.Map.mapfile, 526 env=self._env) 527 if ret != 0: 528 raise GException(_("Rendering failed: %s" % msg)) 529 530 stop = time.time() 531 Debug.msg (1, "RenderMapMgr.OnRenderDone() time=%f sec (comp: %f)" % \ 532 (stop - self._startTime, stop - startCompTime)) 533 534 self._rendering = False 535 wx.EndBusyCursor() 536 537 self.updateMap.emit() 538 539 def Abort(self): 540 """Abort all rendering processes""" 541 for layer in self.layers: 542 layer.GetRenderMgr().Abort() 543 544 def ReportProgress(self, layer=None): 545 """Calculates progress in rendering/downloading 546 and emits signal to inform progress bar about progress. 547 548 Emits renderDone event when progressVal is equal to range. 549 550 :param layer: Layer to be processed or None to reset 551 """ 552 if self.progressInfo is None or layer is None: 553 self.progressInfo = {'progresVal' : 0, # current progress value 554 'downloading' : [], # layers, which are downloading data 555 'rendered' : [], # already rendered layers 556 'range' : len(self.layers)} 557 else: 558 if layer not in self.progressInfo['rendered']: 559 self.progressInfo['rendered'].append(layer) 560 if layer.IsDownloading() and \ 561 layer not in self.progressInfo['downloading']: 562 self.progressInfo['downloading'].append(layer) 563 else: 564 self.progressInfo['progresVal'] += 1 565 if layer in self.progressInfo['downloading']: 566 self.progressInfo['downloading'].remove(layer) 567 568 # for updating statusbar text 569 stText = '' 570 first = True 571 for layer in self.progressInfo['downloading']: 572 if first: 573 stText += _("Downloading data ") 574 first = False 575 else: 576 stText += ', ' 577 stText += '<%s>' % layer.GetName() 578 if stText: 579 stText += '...' 580 581 if self.progressInfo['range'] != len(self.progressInfo['rendered']): 582 if stText: 583 stText = _('Rendering & ') + stText 584 else: 585 stText = _('Rendering...') 586 587 self.updateProgress.emit(range=self.progressInfo['range'], 588 value=self.progressInfo['progresVal'], 589 text=stText) 590 591 if layer and self.progressInfo['progresVal'] == self.progressInfo['range']: 592 self.renderDone.emit() 593 370 594 class Map(object): 371 595 def __init__(self, gisrc = None): … … 374 598 :param gisrc: alternative gisrc (used eg. by georectifier) 375 599 """ 376 Debug.msg (1, "Map.__init__(): %s" % gisrc)600 Debug.msg (1, "Map.__init__(): gisrc=%s" % gisrc) 377 601 # region/extent settigns 378 602 self.wind = dict() # WIND settings (wind file) … … 389 613 # path to external gisrc 390 614 self.gisrc = gisrc 391 615 392 616 # generated file for g.pnmcomp output for rendering the map 393 617 self.mapfile = grass.tempfile(create = False) + '.ppm' … … 398 622 RunCommand('g.region', flags='d') 399 623 400 # info to report progress401 self.progressInfo = None402 403 # GRASS environment variable (for rendering)404 self.render_env = {"GRASS_RENDER_BACKGROUNDCOLOR" : "000000",405 "GRASS_RENDER_FILE_COMPRESSION" : "0",406 "GRASS_RENDER_TRUECOLOR" : "TRUE",407 "GRASS_RENDER_TRANSPARENT" : "TRUE",408 }409 410 624 # projection info 411 625 self.projinfo = self._projInfo() 412 626 413 # is some layer being downloaded?414 self.downloading = False415 416 627 self.layerChanged = Signal('Map.layerChanged') 417 self.updateProgress = Signal('Map.updateProgress')418 628 self.layerRemoved = Signal('Map:layerRemoved') 419 629 self.layerAdded = Signal('Map:layerAdded') 420 630 631 self.renderMgr = RenderMapMgr(self) 632 633 def GetRenderMgr(self): 634 """Get render manager """ 635 return self.renderMgr 636 421 637 def GetProjInfo(self): 422 638 """Get projection info""" … … 845 1061 return selected 846 1062 847 def _renderLayers(self, env, force = False, overlaysOnly = False):848 """Render all map layers into files849 850 :param bool force: True to force rendering851 :param bool overlaysOnly: True to render only overlays852 853 :return: list of maps, masks and opacities854 """855 maps = list()856 masks = list()857 opacities = list()858 # render map layers859 if overlaysOnly:860 layers = self.overlays861 else:862 layers = self.layers + self.overlays863 864 self.downloading = False865 866 self.ReportProgress(layer=None)867 868 for layer in layers:869 # skip non-active map layers870 if not layer or not layer.active:871 continue872 873 # render874 if force or layer.forceRender:875 if not layer.Render(env):876 continue877 878 if layer.IsDownloading():879 self.downloading = True880 881 self.ReportProgress(layer=layer)882 883 # skip map layers when rendering fails884 if not os.path.exists(layer.mapfile):885 continue886 887 # add image to compositing list888 if layer.type != "overlay":889 maps.append(layer.mapfile)890 masks.append(layer.maskfile)891 opacities.append(str(layer.opacity))892 893 return maps, masks, opacities894 895 def GetMapsMasksAndOpacities(self, force, windres, env):896 """897 Used by Render function.898 899 :return: maps, masks, opacities900 """901 return self._renderLayers(force=force, env=env)902 903 1063 def Render(self, force = False, windres = False): 904 1064 """Creates final image composite … … 910 1070 :param windres: use region resolution (True) otherwise display 911 1071 resolution 912 913 :return: name of file with rendered image or None 914 """ 915 wx.BeginBusyCursor() 916 env = os.environ.copy() 917 env.update(self.render_env) 918 # use external gisrc if defined 919 if self.gisrc: 920 env['GISRC'] = self.gisrc 921 env['GRASS_REGION'] = self.SetRegion(windres) 922 env['GRASS_RENDER_WIDTH'] = str(self.width) 923 env['GRASS_RENDER_HEIGHT'] = str(self.height) 924 driver = UserSettings.Get(group = 'display', key = 'driver', subkey = 'type') 925 if driver == 'png': 926 env['GRASS_RENDER_IMMEDIATE'] = 'png' 927 else: 928 env['GRASS_RENDER_IMMEDIATE'] = 'cairo' 929 930 start = time.time() 931 maps, masks, opacities = self.GetMapsMasksAndOpacities(force, windres, env) 932 933 # ugly hack for MSYS 934 if sys.platform != 'win32': 935 mapstr = ",".join(maps) 936 maskstr = ",".join(masks) 937 else: 938 mapstr = "" 939 for item in maps: 940 mapstr += item.replace('\\', '/') 941 mapstr = mapstr.rstrip(',') 942 maskstr = "" 943 for item in masks: 944 maskstr += item.replace('\\', '/') 945 maskstr = maskstr.rstrip(',') 946 947 # run g.pngcomp to get composite image 948 bgcolor = ':'.join(map(str, UserSettings.Get(group = 'display', key = 'bgcolor', 949 subkey = 'color'))) 950 startComp = time.time() 951 if maps: 952 ret, msg = RunCommand('g.pnmcomp', 953 getErrorMsg = True, 954 overwrite = True, 955 input = '%s' % ",".join(maps), 956 mask = '%s' % ",".join(masks), 957 opacity = '%s' % ",".join(opacities), 958 bgcolor = bgcolor, 959 width = self.width, 960 height = self.height, 961 output = self.mapfile, 962 env=env) 963 964 if ret != 0: 965 print >> sys.stderr, _("ERROR: Rendering failed. Details: %s") % msg 966 wx.EndBusyCursor() 967 return None 968 969 stop = time.time() 970 Debug.msg (1, "Map.Render() force=%s -> time=%f (comp: %f)" % \ 971 (force, stop - start, stop - startComp)) 972 973 wx.EndBusyCursor() 974 if not maps: 975 return None 976 977 return self.mapfile 978 1072 """ 1073 self.renderMgr.Render(force, windres) 1074 979 1075 def _addLayer(self, layer, render=False, pos=-1): 980 1076 if layer.type == 'overlay': … … 1024 1120 renderMgr = layer.GetRenderMgr() 1025 1121 if renderMgr: 1026 renderMgr.dataFetched.connect(self.layerChanged) 1027 renderMgr.updateProgress.connect(self.ReportProgress) 1122 if layer.type == 'wms': 1123 renderMgr.dataFetched.connect(self.layerChanged) 1124 renderMgr.updateProgress.connect(self.renderMgr.ReportProgress) 1028 1125 1029 1126 self.layerAdded.emit(layer=layer) … … 1108 1205 layer.SetOpacity(kargs['opacity']) 1109 1206 1207 1110 1208 if render and not layer.Render(): 1111 1209 raise GException(_("Unable to render map layer <%s>.") % 1112 1210 layer.GetName()) 1113 1211 1114 1212 self.layerChanged(layer=layer) 1213 1115 1214 return layer 1116 1215 … … 1322 1421 for l in self.layers + self.overlays: 1323 1422 l.AbortThread() 1324 1325 def ReportProgress(self, layer):1326 """Calculates progress in rendering/downloading1327 and emits signal to inform progress bar about progress.1328 """1329 if self.progressInfo is None or layer is None:1330 self.progressInfo = {'progresVal' : 0, # current progress value1331 'downloading' : [], # layers, which are downloading data1332 'rendered' : [], # already rendered layers1333 'range' : len(self.GetListOfLayers(active = True)) +1334 len(self.GetListOfLayers(active = True, ltype = 'overlay')) -1335 len(self.GetListOfLayers(active = True, ltype = '3d-raster'))}1336 else:1337 if layer not in self.progressInfo['rendered']:1338 self.progressInfo['rendered'].append(layer)1339 if layer.IsDownloading() and \1340 layer not in self.progressInfo['downloading']:1341 self.progressInfo['downloading'].append(layer)1342 else:1343 self.progressInfo['progresVal'] += 11344 if layer in self.progressInfo['downloading']:1345 self.progressInfo['downloading'].remove(layer)1346 1347 # for updating statusbar text1348 stText = ''1349 first = True1350 for layer in self.progressInfo['downloading']:1351 if first:1352 stText += _("Downloading data ")1353 first = False1354 else:1355 stText += ', '1356 stText += '<%s>' % layer.GetName()1357 if stText:1358 stText += '...'1359 1360 if self.progressInfo['range'] != len(self.progressInfo['rendered']):1361 if stText:1362 stText = _('Rendering & ') + stText1363 else:1364 stText = _('Rendering...')1365 1366 self.updateProgress.emit(range=self.progressInfo['range'],1367 value=self.progressInfo['progresVal'],1368 text=stText) -
grass/trunk/gui/wxpython/core/ws.py
r64406 r65205 46 46 """Fetch and prepare WMS data for rendering. 47 47 """ 48 def __init__(self, layer , mapfile, maskfile):48 def __init__(self, layer): 49 49 if not haveGdal: 50 50 sys.stderr.write(_("Unable to load GDAL Python bindings.\n"\ … … 52 52 53 53 self.layer = layer 54 54 55 55 wx.EvtHandler.__init__(self) 56 56 … … 66 66 self.cmdStdErr = GStderr(self) 67 67 68 self.mapfile = mapfile69 self.maskfile = maskfile70 68 self.tempMap = grass.tempfile() 71 69 self.dstSize = {} … … 120 118 self.renderedRegion = region 121 119 122 try_remove(self. mapfile)120 try_remove(self.layer.mapfile) 123 121 try_remove(self.tempMap) 124 122 … … 160 158 return 161 159 162 self.mapMerger = GDALRasterMerger(targetFile = self.mapfile, region = self.renderedRegion, 160 self.mapMerger = GDALRasterMerger(targetFile = self.layer.mapfile, 161 region = self.renderedRegion, 163 162 bandsNum = 3, gdalDriver = 'PNM', fillValue = 0) 164 163 self.mapMerger.AddRasterBands(self.tempMap, {1 : 1, 2 : 2, 3 : 3}) 165 164 del self.mapMerger 166 165 167 self.maskMerger = GDALRasterMerger(targetFile = self. maskfile, region = self.renderedRegion,166 self.maskMerger = GDALRasterMerger(targetFile = self.layer.maskfile, region = self.renderedRegion, 168 167 bandsNum = 1, gdalDriver = 'PNM', fillValue = 0) 169 168 #{4 : 1} alpha channel (4) to first and only channel (1) in mask -
grass/trunk/gui/wxpython/lmgr/layertree.py
r64876 r65205 371 371 self.rerender = False 372 372 if self.mapdisplay.IsAutoRendered(): 373 self.mapdisplay.GetMapWindow().UpdateMap(render= True)373 self.mapdisplay.GetMapWindow().UpdateMap(render=False) 374 374 375 375 event.Skip() … … 1104 1104 checked = lchecked 1105 1105 else: 1106 checked = True1106 checked = False 1107 1107 1108 1108 self.forceCheck = True … … 1144 1144 ctrlId = None 1145 1145 1146 # add a data object to hold the layer's command (does not apply to generic command layers) 1146 # add a data object to hold the layer's command (does not 1147 # apply to generic command layers) 1147 1148 self.SetPyData(layer, ({'cmd' : cmd, 1148 1149 'type' : ltype, … … 1154 1155 'propwin' : None}, 1155 1156 None)) 1157 1156 1158 # must be after SetPyData because it calls OnLayerChecked 1157 1159 # which calls GetVisibleLayers which requires already set PyData … … 1184 1186 else: 1185 1187 self.first = False 1186 1187 1188 else: # group 1188 1189 self.SetPyData(layer, ({'cmd' : None, … … 1210 1211 self.OnRenameLayer(None) 1211 1212 1212 1213 1213 return layer 1214 1214 … … 1224 1224 else: 1225 1225 win.Show() 1226 1227 1226 return 1228 1227 … … 1231 1230 Debug.msg (3, "LayerTree.PropertiesDialog(): ltype=%s" % \ 1232 1231 ltype) 1233 1232 1234 1233 cmd = None 1235 1234 if self.GetLayerInfo(layer, key = 'cmd'): 1236 1237 1235 module = GUI(parent = self, show = show, centreOnParent = False) 1238 1236 module.ParseCommand(self.GetLayerInfo(layer, key = 'cmd'), 1239 completed = (self.GetOptData,layer,params)) 1240 1237 completed = (self.GetOptData, layer, params)) 1241 1238 self.SetLayerInfo(layer, key = 'cmd', value = module.GetCmd()) 1242 1239 elif self.GetLayerInfo(layer, key = 'type') != 'command': 1243 1240 cmd = [ltype2command[ltype]] 1244 if ltype == 'raster': 1245 if UserSettings.Get(group = 'rasterLayer', key = 'opaque', subkey = 'enabled'): 1246 cmd.append('-n') 1247 elif ltype == 'rgb': 1241 if ltype in ('raster', 'rgb'): 1248 1242 if UserSettings.Get(group = 'rasterLayer', key = 'opaque', subkey = 'enabled'): 1249 1243 cmd.append('-n') 1250 1244 elif ltype == 'vector': 1251 1245 cmd += GetDisplayVectSettings() 1252 1246 1253 1247 if cmd: 1254 GUI(parent = self, centreOnParent = False).ParseCommand(cmd, 1255 completed = (self.GetOptData,layer,params)) 1256 1248 module = GUI(parent = self, centreOnParent = False) 1249 module.ParseCommand(cmd, 1250 completed = (self.GetOptData,layer,params)) 1251 1257 1252 def OnActivateLayer(self, event): 1258 1253 """Double click on the layer item. … … 1667 1662 message = _("Map <%s> not found.") % mapName) 1668 1663 return 1669 1664 1665 if not mapLayer.IsActive(): 1666 self.forceCheck = True 1667 self.CheckItem(layer, True) 1668 mapLayer.SetActive(True) 1669 1670 1670 # update layer data 1671 1671 if params: … … 1674 1674 1675 1675 # change parameters for item in layers list in render.Map 1676 self.ChangeLayer(layer) 1677 1676 if params: 1677 self.ChangeLayer(layer) 1678 1678 1679 # set region if auto-zooming is enabled or layer tree contains 1679 1680 # only one map layer 1680 1681 if dcmd: 1681 if not self.mapdisplay.IsPaneShown('3d') and (self.first or 1682 UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled')): 1682 if not self.mapdisplay.IsPaneShown('3d') and \ 1683 (self.first or \ 1684 UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled')): 1683 1685 mapLayer = self.GetLayerInfo(layer, key = 'maplayer') 1684 1686 if mapLayer.GetType() in ('raster', 'vector'): 1685 1687 self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,], 1686 1688 render = False) 1687 1689 1688 1690 self.first = False # first layer has been already added to 1689 1691 # the layer tree … … 1717 1719 if nlayers < 2: 1718 1720 mapWin.ResetView() 1719 1721 1720 1722 def GetVisibleLayers(self, skipDigitized=False): 1721 1723 # make a list of visible layers … … 1776 1778 if not found: 1777 1779 layerName = self.GetItemText(item) 1778 1779 maplayer = self.Map.ChangeLayer(layer = self.GetLayerInfo(item, key = 'maplayer'), type = type,1780 command = cmdlist, name = layerName,1781 active = chk, hidden = hidden, opacity = opac , render = False)1780 1781 maplayer = self.Map.ChangeLayer(layer = self.GetLayerInfo(item, key = 'maplayer'), 1782 type = type, command = cmdlist, name = layerName, 1783 active = chk, hidden = hidden, opacity = opac) 1782 1784 1783 1785 self.SetLayerInfo(item, key = 'maplayer', value = maplayer) … … 1786 1788 if self.mapdisplay.GetToolbar('vdigit'): 1787 1789 self.mapdisplay.GetToolbar('vdigit').UpdateListOfLayers(updateTool = True) 1788 1790 1789 1791 self.Map.SetLayers(self.GetVisibleLayers()) 1792 1790 1793 # redraw map if auto-rendering is enabled 1791 1794 self.rerender = True -
grass/trunk/gui/wxpython/mapdisp/frame.py
r64610 r65205 248 248 249 249 # 250 self.Map. updateProgress.connect(self.statusbarManager.SetProgress)250 self.Map.GetRenderMgr().updateProgress.connect(self.statusbarManager.SetProgress) 251 251 252 252 def GetMapWindow(self): -
grass/trunk/gui/wxpython/mapdisp/main.py
r65158 r65205 6 6 Classes: 7 7 - mapdisp::DMonMap 8 - mapdisp::DMonMapDirect9 8 - mapdisp::Layer 10 9 - mapdisp::LayerList … … 39 38 from core.giface import StandaloneGrassInterface 40 39 from core.gcmd import RunCommand 41 from core.render import Map, MapLayer, Overlay 40 from core.render import Map, MapLayer, Overlay, RenderMapMgr 42 41 from core.utils import _ 43 42 from mapdisp.frame import MapFrame … … 67 66 """ 68 67 Map.__init__(self) 69 68 70 69 self._giface = giface 71 70 … … 94 93 self.query = Signal('DMonMap.query') 95 94 96 def GetLayersFromCmdFile(self, mapfile=None): 95 self.renderMgr = RenderMapMgr(self) 96 97 def GetLayersFromCmdFile(self): 97 98 """Get list of map layers from cmdfile 98 99 """ … … 156 157 else: 157 158 classLayer = MapLayer 158 args['mapfile'] = mapfile159 159 args['ltype'] = ltype 160 160 161 161 mapLayer = classLayer(name = name, cmd = cmd, Map = None, 162 162 hidden = True, **args) 163 163 mapLayer.GetRenderMgr().updateProgress.connect(self.GetRenderMgr().ReportProgress) 164 164 165 exists = False 165 166 for i, layer in enumerate(existingLayers): … … 246 247 #return layer 247 248 248 class DMonMapDirect(DMonMap):249 def __init__(self, giface, cmdfile=None, mapfile=None):250 """Map composition (stack of map layers and overlays)251 252 :param cmdline: full path to the cmd file (defined by d.mon)253 :param mapfile: full path to the map file (defined by d.mon)254 """255 DMonMap.__init__(self, giface, cmdfile, mapfile)256 257 self.render_env['GRASS_RENDER_BACKGROUNDCOLOR'] = 'FFFFFF'258 self.render_env['GRASS_RENDER_TRANSPARENT'] = 'FALSE'259 self.render_env['GRASS_RENDER_FILE_READ'] = 'TRUE'260 261 def Render(self, *args, **kwargs):262 """Render layer to image.263 264 For input params and returned data see overridden method in Map class.265 """266 wx.BeginBusyCursor()267 env = os.environ.copy()268 env.update(self.render_env)269 # use external gisrc if defined270 if self.gisrc:271 env['GISRC'] = self.gisrc272 env['GRASS_REGION'] = self.SetRegion(kwargs.get('windres', False))273 env['GRASS_RENDER_WIDTH'] = str(self.width)274 env['GRASS_RENDER_HEIGHT'] = str(self.height)275 driver = UserSettings.Get(group = 'display', key = 'driver', subkey = 'type')276 if driver == 'png':277 env['GRASS_RENDER_IMMEDIATE'] = 'png'278 else:279 env['GRASS_RENDER_IMMEDIATE'] = 'cairo'280 281 if os.path.exists(self.mapfile):282 os.remove(self.mapfile)283 284 self.GetMapsMasksAndOpacities(kwargs['force'], kwargs.get('windres', False), env)285 wx.EndBusyCursor()286 287 return self.mapfile288 289 def GetLayersFromCmdFile(self):290 super(self.__class__, self).GetLayersFromCmdFile(self.mapfile)291 292 249 class Layer(object): 293 250 """@implements core::giface::Layer""" … … 445 402 446 403 if __name__ == "__main__": 447 dmonMap = DMonMapDirect448 # if decorations:449 # dmonMap = DMonMap450 404 self.cmdTimeStamp = os.path.getmtime(monFile['cmd']) 451 self.Map = dmonMap(giface=self._giface, cmdfile=monFile['cmd'],405 self.Map = DMonMap(giface=self._giface, cmdfile=monFile['cmd'], 452 406 mapfile = monFile['map']) 453 407 -
grass/trunk/gui/wxpython/mapwin/buffered.py
r64627 r65205 150 150 151 151 # render output objects 152 self.mapfile = None # image file to be rendered153 152 self.img = None # wx.Image object (self.mapfile) 154 153 # decoration overlays … … 182 181 183 182 # rerender when Map reports change 184 self.Map.layerChanged.connect(self.OnUpdateMap) 185 183 ### self.Map.layerChanged.connect(self.OnUpdateMap) 184 self.Map.GetRenderMgr().renderDone.connect(self._updateMFinished) 185 186 186 # vars for handling mouse clicks 187 187 self.dragid = -1 … … 705 705 """ 706 706 imgId = 99 707 if self. mapfile and self.Map.mapfile and os.path.isfile(self.Map.mapfile) and \707 if self.Map.mapfile and os.path.isfile(self.Map.mapfile) and \ 708 708 os.path.getsize(self.Map.mapfile): 709 709 img = wx.Image(self.Map.mapfile, wx.BITMAP_TYPE_ANY) … … 809 809 :func:`UpdateMap` for arguments description. 810 810 """ 811 Debug.msg (1, "BufferedWindow.UpdateMap(): started " 812 "(render=%s, renderVector=%s)" % (render, renderVector)) 813 811 814 self.resize = False 812 815 … … 814 817 if self.IsAlwaysRenderEnabled() and self.img is None: 815 818 render = True 816 817 818 # 819 # render background image if needed 820 # 821 822 # here was the change of the layertree rerender variable 823 # but it is fully the problem of layertree 824 # and so it is handled there 825 # remove this comment when it is old enough 826 819 827 820 try: 828 821 if render: 829 822 # update display size 830 823 self.Map.ChangeMapSize(self.GetClientSize()) 831 if self._properties.resolution: 832 # use computation region resolution for rendering 833 windres = True 834 else: 835 windres = False 836 837 self.mapfile = self.Map.Render(force = True, 838 windres = windres) 839 else: 840 self.mapfile = self.Map.Render(force = False) 841 824 825 self.Map.Render(force=render, 826 windres=self._properties.resolution) 842 827 except GException as e: 843 GError(message = e.value) 844 self.mapfile = None 845 828 GError(message=e.value) 829 830 def _updateMFinished(self, renderVector=True): 831 Debug.msg (1, "BufferedWindow.UpdateMap(): finished") 846 832 self.img = self.GetImage() # id=99 847 833 848 834 # 849 835 # clear pseudoDcs … … 854 840 pdc.Clear() 855 841 pdc.RemoveAll() 856 842 857 843 # 858 844 # draw background map image to PseudoDC … … 863 849 try: 864 850 id = self.imagedict[self.img]['id'] 865 except: 851 except Exception as e: 852 Debug.mgs(1, "UpdateMap() failed: %s", e) 866 853 return False 867 868 854 self.Draw(self.pdc, self.img, drawid = id) 869 855 … … 873 859 if renderVector and hasattr(self, "digit"): 874 860 self._updateMap() 861 875 862 # 876 863 # render overlays … … 881 868 id = self.imagedict[img]['id'] 882 869 self.Draw(self.pdc, img = img, drawid = id, 883 pdctype = self.overlays[id].pdcType, coords = self.overlays[id].coords) 884 870 pdctype = self.overlays[id].pdcType, 871 coords = self.overlays[id].coords) 872 885 873 for id in self.textdict.keys(): 886 874 self.Draw(self.pdc, img = self.textdict[id], drawid = id, 887 875 pdctype = 'text', coords = [10, 10, 10, 10]) 888 876 889 877 # optionally draw computational extent box 890 878 self.DrawCompRegionExtent() 891 879 892 880 # 893 881 # redraw pdcTmp if needed 894 882 # 895 883 896 884 # draw registered graphics 897 885 if len(self.graphicsSetList) > 0: … … 913 901 if len(self.polycoords) > 0: 914 902 self.DrawLines(self.pdcTmp) 915 916 Debug.msg (1, "BufferedWindow.UpdateMap(): render=%s, renderVector=%s" % \ 917 (render, renderVector)) 918 903 919 904 return True 920 905 921 906 def DrawCompRegionExtent(self): 922 907 """Draw computational region extent in the display
Note:
See TracChangeset
for help on using the changeset viewer.
