def EvaluateInput(self, animationData): stds = 0 maps = 0 mapCount = set() tempManager = None windowIndex = [] for anim in animationData: for layer in anim.layerList: if layer.active and hasattr(layer, 'maps'): if layer.mapType in ('strds', 'stvds', 'str3ds'): stds += 1 else: maps += 1 mapCount.add(len(layer.maps)) windowIndex.append(anim.windowIndex) if maps and stds: temporalMode = TemporalMode.NONTEMPORAL elif maps: temporalMode = TemporalMode.NONTEMPORAL elif stds: temporalMode = TemporalMode.TEMPORAL else: temporalMode = None if temporalMode == TemporalMode.NONTEMPORAL: if len(mapCount) > 1: raise GException( _("Inconsistent number of maps, please check input data.")) elif temporalMode == TemporalMode.TEMPORAL: tempManager = TemporalManager() # these raise GException: for anim in animationData: tempManager.AddTimeSeries(*anim.firstStdsNameType) message = tempManager.EvaluateInputData() if message: GMessage(parent=self.frame, message=message) return temporalMode, tempManager
def ChangeLayer(self, layer, render = False, **kargs): """!Change map layer properties @param layer map layer instance @param ltype layer type ('raster', 'vector', etc.) @param command GRASS command given as list @param name layer name @param active layer render only if True @param hidden layer not displayed in layer tree if True @param opacity opacity level range from 0(transparent) - 1(not transparent) @param render render an image if True """ Debug.msg (3, "Map.ChangeLayer(): layer=%s" % layer.name) if 'ltype' in kargs: layer.SetType(kargs['ltype']) # check type print kargs['command'] print "yyy" if 'command' in kargs: layer.SetCmd(kargs['command']) if 'name' in kargs: layer.SetName(kargs['name']) if 'active' in kargs: layer.SetActive(kargs['active']) if 'hidden' in kargs: layer.SetHidden(kargs['hidden']) if 'opacity' in kargs: layer.SetOpacity(kargs['opacity']) if render and not layer.Render(): raise GException(_("Unable to render map layer <%s>.") % layer.GetName()) return layer
def AddMapLayer(self, mlayer, render=False, pos=-1): wx.BeginBusyCursor() # opacity must be <0;1> if mlayer.opacity < 0: opacity = 0 elif mlayer.opacity > 1: opacity = 1 # add maplayer to the list of layers if pos > -1: self.layers.insert(pos, mlayer) else: self.layers.append(mlayer) Debug.msg(3, "Map.AddLayer(): layer=%s" % mlayer.name) if render: if not mlayer.Render(): raise GException(_("Unable to render map layer <%s>.") % mlayer.name) wx.EndBusyCursor() return mlayer
def _gatherInformation(self, timeseries, etype, timeseriesList, infoDict): """Get info about timeseries and check topology (raises GException)""" id = validateTimeseriesName(timeseries, etype) sp = tgis.dataset_factory(etype, id) # Insert content from db sp.select() # Get ordered map list maps = sp.get_registered_maps_as_objects() if not sp.check_temporal_topology(maps): raise GException( _("Topology of Space time dataset %s is invalid." % id)) timeseriesList.append(id) infoDict[id] = {} infoDict[id]['etype'] = etype infoDict[id]['temporal_type'] = sp.get_temporal_type() if sp.is_time_relative(): infoDict[id]['unit'] = sp.get_relative_time_unit() infoDict[id]['granularity'] = sp.get_granularity() infoDict[id]['map_time'] = sp.get_map_time() infoDict[id]['maps'] = maps
def UpdateCategoryWithPolygons(self, cat_id, scatts_pols, value): start_time = time.clock() if cat_id not in self.scatts_dt.GetCategories(): raise GException(_("Select category for editing.")) for scatt_id, coords in six.iteritems(scatts_pols): if self.scatt_conds_dt.AddScattPlot(cat_id, scatt_id) < 0: return False b1, b2 = idScattToidBands(scatt_id, len(self.an_data.GetBands())) b = self.scatts_dt.GetBandsInfo(scatt_id) region = {} region['s'] = b['b2']['min'] - 0.5 region['n'] = b['b2']['max'] + 0.5 region['w'] = b['b1']['min'] - 0.5 region['e'] = b['b1']['max'] + 0.5 arr = self.scatt_conds_dt.GetValuesArr(cat_id, scatt_id) arr = Rasterize(polygon=coords, rast=arr, region=region, value=value) # previous way of rasterization / used scipy # raster_pol = RasterizePolygon(coords, b['b1']['range'], b['b1']['min'], # b['b2']['range'], b['b2']['min']) #raster_ind = np.where(raster_pol > 0) #arr = self.scatt_conds_dt.GetValuesArr(cat_id, scatt_id) #arr[raster_ind] = value # arr.flush() self.ComputeCatsScatts([cat_id]) return cat_id
def ChangeOverlay(self, id, render = False, **kargs): """Change overlay properities Add new overlay if overlay with 'id' doesn't exist. :param id: overlay id (PseudoDC) :param ltype: overlay ltype (barscale, legend) :param command: GRASS command to render overlay :param active: overlay activated (True) or disabled (False) :param hidden: overlay is not shown in layer tree (if True) :param render: render an image (if True) :return: new layer on success """ overlay = self.GetOverlay(id, list = False) if overlay is None: overlay = Overlay(id, ltype = None, cmd = None) if 'ltype' in kargs: overlay.SetName(kargs['ltype']) # ltype -> overlay if 'command' in kargs: overlay.SetCmd(kargs['command']) if 'active' in kargs: overlay.SetActive(kargs['active']) if 'hidden' in kargs: overlay.SetHidden(kargs['hidden']) if 'opacity' in kargs: overlay.SetOpacity(kargs['opacity']) if render and overlay.GetCmd() != [] and not overlay.Render(): raise GException(_("Unable to render overlay <%s>.") % overlay.GetType()) return overlay
def AddOverlay(self, id, type, command, l_active=True, l_hidden=True, l_opacity=1.0, l_render=False): """!Adds overlay (grid, barscale, legend, etc.) to list of overlays @param id overlay id (PseudoDC) @param type overlay type (barscale, legend) @param command GRASS command to render overlay @param l_active overlay activated (True) or disabled (False) @param l_hidden overlay is not shown in layer tree (if True) @param l_render render an image (if True) @return new layer on success @retutn None on failure """ Debug.msg(2, "Map.AddOverlay(): cmd=%s, render=%d" % (command, l_render)) overlay = Overlay(id=id, type=type, cmd=command, active=l_active, hidden=l_hidden, opacity=l_opacity) # add maplayer to the list of layers self.overlays.append(overlay) if l_render and command != '' and not overlay.Render(): raise GException(_("Unable to render overlay <%s>.") % name) return self.overlays[-1]
def ChangeOverlay(self, id, render=False, **kargs): """!Change overlay properities Add new overlay if overlay with 'id' doesn't exist. @param id overlay id (PseudoDC) @param ltype overlay ltype (barscale, legend) @param command GRASS command to render overlay @param active overlay activated (True) or disabled (False) @param hidden overlay is not shown in layer tree (if True) @param render render an image (if True) @return new layer on success """ overlay = self.GetOverlay(id, list=False) if overlay is None: overlay = Overlay(id, ltype=None, cmd=None) if "ltype" in kargs: overlay.SetName(kargs["ltype"]) # ltype -> overlay if "command" in kargs: overlay.SetCmd(kargs["command"]) if "active" in kargs: overlay.SetActive(kargs["active"]) if "hidden" in kargs: overlay.SetHidden(kargs["hidden"]) if "opacity" in kargs: overlay.SetOpacity(kargs["opacity"]) if render and overlay.GetCmd() != [] and not overlay.Render(): raise GException(_("Unable to render overlay <%s>.") % overlay.GetType()) return overlay
def LoadOverlay(self, cmd): """Creates raster legend with d.legend :param cmd: d.legend command as a list :return: bitmap with legend """ Debug.msg(5, "BitmapProvider.LoadOverlay: cmd={c}".format(c=cmd)) fileHandler, filename = tempfile.mkstemp(suffix=".png") os.close(fileHandler) # Set the environment variables for this process _setEnvironment(self.imageWidth, self.imageHeight, filename, transparent=True, bgcolor=(0, 0, 0)) Debug.msg(1, "Render raster legend " + str(filename)) cmdTuple = CmdToTuple(cmd) returncode, stdout, messages = read2_command(cmdTuple[0], **cmdTuple[1]) if returncode == 0: return wx.BitmapFromImage(autoCropImageFromFile(filename)) else: os.remove(filename) raise GException(messages)
def ComputeCatsScatts(self, cats_ids): requested_dt = {} requested_dt_conds = {} for c in cats_ids: requested_dt_conds[c] = self.scatt_conds_dt.GetCatScatts(c) requested_dt[c] = self.scatts_dt.GetCatScatts(c) scatt_conds = self.scatt_conds_dt.GetData(requested_dt_conds) scatts = self.scatts_dt.GetData(requested_dt) bands = self.an_data.GetBands() cats_rasts = self.scatts_dt.GetCatsRasts() cats_rasts_conds = self.scatts_dt.GetCatsRastsConds() returncode, scatts = ComputeScatts(self.an_data.GetRegion(), scatt_conds, bands, len(self.GetBands()), scatts, cats_rasts_conds, cats_rasts) if returncode < 0: GException(_("Computing of scatter plots failed."))
def Set(self, group, value, key=None, subkey=None, settings_type="user"): """Set value of key/subkey Raise KeyError if group/key is not found :param group: settings group :param key: key (value, None) :param subkey: subkey (value, list or None) :param value: value :param settings_type: 'user', 'internal', 'default' """ if settings_type == "user": settings = self.userSettings elif settings_type == "internal": settings = self.internalSettings else: settings = self.defaultSettings try: if subkey is None: if key is None: settings[group] = value else: settings[group][key] = value else: if isinstance(subkey, type(tuple())) or isinstance( subkey, type(list()) ): settings[group][key][subkey[0]][subkey[1]] = value else: settings[group][key][subkey] = value except KeyError: raise GException( "%s '%s:%s:%s'" % (_("Unable to set "), group, key, subkey) )
def Render(self): """!Render layer to image @return rendered image filename @return None on error """ if not self.cmd: return None # ignore in 2D if self.type == '3d-raster': return None Debug.msg (3, "Layer.Render(): type=%s, name=%s" % \ (self.type, self.name)) # prepare command for each layer layertypes = ('raster', 'rgb', 'his', 'shaded', 'rastarrow', 'rastnum', 'vector', 'thememap', 'themechart', 'grid', 'geodesic', 'rhumb', 'labels', 'command', 'rastleg', 'overlay') if self.type not in layertypes: raise GException(_("<%(name)s>: layer type <%(type)s> is not supported") % \ {'type' : self.type, 'name' : self.name}) # start monitor if not self.mapfile: if self.type == 'overlay': tempfile_sfx = ".png" else: tempfile_sfx = ".ppm" mapfile = tempfile.NamedTemporaryFile(suffix=tempfile_sfx, delete=False) # we don't want it open, we just need the name self.mapfile = mapfile.name mapfile.close() self.maskfile = self.mapfile.rsplit(".", 1)[0] + ".pgm" if UserSettings.Get(group='display', key='driver', subkey='type') == 'cairo': if self.mapfile: os.environ["GRASS_CAIROFILE"] = self.mapfile # FIXME: the second RunCommand() here locks up the GUI, need to use 'xkill' to recover. # the first one works as expected. # if 'cairo' not in RunCommand('d.mon', flags='p', read = True): # RunCommand('d.mon', start = 'cairo', select = 'cairo') else: if self.mapfile: os.environ["GRASS_PNGFILE"] = self.mapfile # execute command try: if self.type == 'command': read = False for c in self.cmd: ret, msg = RunCommand(c[0], getErrorMsg=True, quiet=True, **c[1]) if ret != 0: break if not read: os.environ["GRASS_PNG_READ"] = "TRUE" os.environ["GRASS_PNG_READ"] = "FALSE" else: ret, msg = RunCommand(self.cmd[0], getErrorMsg=True, quiet=True, **self.cmd[1]) if ret != 0: sys.stderr.write( _("Command '%s' failed\n") % self.GetCmd(string=True)) if msg: sys.stderr.write(_("Details: %s\n") % msg) raise GException() except GException: # clean up after problems try: os.remove(self.mapfile) os.remove(self.maskfile) os.remove(self.gtemp) except (OSError, TypeError): pass self.mapfile = None self.maskfile = None # stop monitor if UserSettings.Get(group='display', key='driver', subkey='type') == 'cairo': # FIXME: # ret, msg = RunCommand('d.mon', stop = 'cairo', getErrorMsg = True) # if ret != 0: # sys.stderr.write(_("Closing Cairo driver failed\n")) # if msg: # sys.stderr.write(_("Details: %s\n") % msg) del os.environ["GRASS_CAIROFILE"] elif "GRASS_PNGFILE" in os.environ: del os.environ["GRASS_PNGFILE"] self.force_render = False return self.mapfile
def SaveToFile(self, settings=None): """Save settings to the file""" if settings is None: settings = self.userSettings dirPath = GetSettingsPath() if not os.path.exists(dirPath): try: os.mkdir(dirPath) except: GError(_('Unable to create settings directory')) return try: file = open(self.filePath, "w") for group in list(settings.keys()): for key in list(settings[group].keys()): subkeys = list(settings[group][key].keys()) file.write('%s%s%s%s' % (group, self.sep, key, self.sep)) for idx in range(len(subkeys)): value = settings[group][key][subkeys[idx]] if isinstance(value, dict): if idx > 0: file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep)) file.write('%s%s' % (subkeys[idx], self.sep)) kvalues = list( settings[group][key][subkeys[idx]].keys()) srange = range(len(kvalues)) for sidx in srange: svalue = self._parseValue(settings[group][key][ subkeys[idx]][kvalues[sidx]]) file.write('%s%s%s' % (kvalues[sidx], self.sep, svalue)) if sidx < len(kvalues) - 1: file.write('%s' % self.sep) else: if idx > 0 and isinstance( settings[group][key][subkeys[idx - 1]], dict): file.write('%s%s%s%s%s' % (os.linesep, group, self.sep, key, self.sep)) value = self._parseValue( settings[group][key][subkeys[idx]]) file.write('%s%s%s' % (subkeys[idx], self.sep, value)) if idx < len(subkeys) - 1 and not isinstance( settings[group][key][subkeys[idx + 1]], dict): file.write('%s' % self.sep) file.write(os.linesep) except IOError as e: raise GException(e) except Exception as e: raise GException( _('Writing settings to file <%(file)s> failed.' '\n\nDetails: %(detail)s') % { 'file': self.filePath, 'detail': e }) file.close() return self.filePath
def _getLabelsAndMaps(self, timeseries): """Returns time labels and map names (done by sampling) for both interval and point data. """ sp = tgis.dataset_factory(self.timeseriesInfo[timeseries]['etype'], timeseries) if sp.is_in_db() is False: raise GException( _("Space time dataset <%s> not found.") % timeseries) sp.select() listOfMaps = [] timeLabels = [] granNum, unit = self.GetGranularity() if self.temporalType == TemporalType.ABSOLUTE: if self.granularityMode == GranularityMode.ONE_UNIT: gran = '%(one)d %(unit)s' % {'one': 1, 'unit': unit} else: gran = '%(num)d %(unit)s' % {'num': granNum, 'unit': unit} elif self.temporalType == TemporalType.RELATIVE: unit = self.timeseriesInfo[timeseries]['unit'] if self.granularityMode == GranularityMode.ONE_UNIT: gran = 1 else: gran = granNum # start sampling - now it can be used for both interval and point data # after instance, there can be a gap or an interval # if it is a gap we remove it and put there the previous instance instead # however the first gap must be removed to avoid duplication maps = sp.get_registered_maps_as_objects_by_granularity(gran=gran) if maps and len(maps) > 0: lastTimeseries = None followsPoint = False # indicates that we are just after finding a point afterPoint = False # indicates that we are after finding a point for mymap in maps: if isinstance(mymap, list): if len(mymap) > 0: map = mymap[0] else: map = mymap series = map.get_id() start, end = map.get_temporal_extent_as_tuple() if self.timeseriesInfo[timeseries]['map_time'] == 'point': # point data listOfMaps.append(series) afterPoint = True followsPoint = True lastTimeseries = series end = None else: end = end # interval data if series: # map exists, stop point mode listOfMaps.append(series) afterPoint = False else: # check point mode if afterPoint: if followsPoint: # skip this one, already there followsPoint = False continue else: # append the last one (of point time) listOfMaps.append(lastTimeseries) end = None else: # append series which is None listOfMaps.append(series) timeLabels.append((start, end, unit)) return timeLabels, listOfMaps
(os.linesep, group, self.sep, key, self.sep)) value = self._parseValue( settings[group][key][subkeys[idx]]) file.write('%s%s%s' % (subkeys[idx], self.sep, value)) if idx < len(subkeys) - 1 and \ type(settings[group][key][subkeys[idx + 1]]) != types.DictType: file.write('%s' % self.sep) file.write(os.linesep) except IOError, e: raise GException(e) except StandardError, e: raise GException( _('Writing settings to file <%(file)s> failed.' '\n\nDetails: %(detail)s') % { 'file': self.filePath, 'detail': e }) file.close() def _parseValue(self, value, read=False): """!Parse value to be store in settings file""" if read: # -> read settings (cast values) if value == 'True': value = True elif value == 'False': value = False elif value == 'None': value = None elif ':' in value: # -> color
def checkSeriesCompatibility(mapSeriesList=None, timeseriesList=None): """Checks whether time series (map series and stds) are compatible, which means they have equal number of maps ad times (in case of stds). This is needed within layer list, not within the entire animation tool. Throws GException if these are incompatible. :return: number of maps for animation """ timeseriesInfo = { 'count': set(), 'temporalType': set(), 'mapType': set(), 'mapTimes': set() } if timeseriesList: for stds, etype in timeseriesList: sp = tgis.open_old_stds(stds, etype) mapType = sp.get_map_time() # interval, ... tempType = sp.get_initial_values()[0] # absolute timeseriesInfo['mapType'].add(mapType) timeseriesInfo['temporalType'].add(tempType) rows = sp.get_registered_maps_as_objects(where=None, order="start_time") if rows: times = [] timeseriesInfo['count'].add(len(rows)) for row in rows: if tempType == 'absolute': time = row.get_absolute_time() else: time = row.get_relative_time() times.append(time) timeseriesInfo['mapTimes'].add(tuple(times)) else: timeseriesInfo['mapTimes'].add(None) timeseriesInfo['count'].add(None) if len(timeseriesInfo['count']) > 1: raise GException( _("The number of maps in space-time datasets " "has to be the same.")) if len(timeseriesInfo['temporalType']) > 1: raise GException( _("The temporal type (absolute/relative) of space-time datasets " "has to be the same.")) if len(timeseriesInfo['mapType']) > 1: raise GException( _("The map type (point/interval) of space-time datasets " "has to be the same.")) if len(timeseriesInfo['mapTimes']) > 1: raise GException( _("The temporal extents of maps in space-time datasets " "have to be the same.")) if mapSeriesList: count = set() for mapSeries in mapSeriesList: count.add(len(mapSeries)) if len(count) > 1: raise GException( _("The number of maps to animate has to be " "the same for each map series.")) if timeseriesList and list(count)[0] != list( timeseriesInfo['count'])[0]: raise GException( _("The number of maps to animate has to be " "the same as the number of maps in temporal dataset.")) if mapSeriesList: return list(count)[0] if timeseriesList: return list(timeseriesInfo['count'])[0]
def _checkDatasets(self, datasets): """Checks and validates datasets. Reports also type of dataset (e.g. 'strds'). :return: (mapName, mapset, type) """ validated = [] tDict = tgis.tlist_grouped('stds', group_type=True, dbif=self.dbif) # nested list with '(map, mapset, etype)' items allDatasets = [[[(map, mapset, etype) for map in maps] for etype, maps in etypesDict.iteritems()] for mapset, etypesDict in tDict.iteritems()] # flatten this list if allDatasets: allDatasets = reduce( lambda x, y: x + y, reduce( lambda x, y: x + y, allDatasets)) mapsets = tgis.get_tgis_c_library_interface().available_mapsets() allDatasets = [ i for i in sorted( allDatasets, key=lambda l: mapsets.index(l[1]))] for dataset in datasets: errorMsg = _("Space time dataset <%s> not found.") % dataset if dataset.find("@") >= 0: nameShort, mapset = dataset.split('@', 1) indices = [n for n, (mapName, mapsetName, etype) in enumerate( allDatasets) if nameShort == mapName and mapsetName == mapset] else: indices = [n for n, (mapName, mapset, etype) in enumerate( allDatasets) if dataset == mapName] if len(indices) == 0: raise GException(errorMsg) elif len(indices) >= 2: dlg = wx.SingleChoiceDialog( self, message=_( "Please specify the space time dataset <%s>." % dataset), caption=_("Ambiguous dataset name"), choices=[("%(map)s@%(mapset)s: %(etype)s" % {'map': allDatasets[i][0], 'mapset': allDatasets[i][1], 'etype': allDatasets[i][2]}) for i in indices], style=wx.CHOICEDLG_STYLE | wx.OK) if dlg.ShowModal() == wx.ID_OK: index = dlg.GetSelection() validated.append(allDatasets[indices[index]]) else: continue else: validated.append(allDatasets[indices[0]]) return validated
def Render(self): """!Render layer to image @return rendered image filename @return None on error or if cmdfile is defined """ if not self.cmd: return None # ignore in 2D if self.type == "3d-raster": return None Debug.msg(3, "Layer.Render(): type=%s, name=%s" % (self.type, self.name)) # prepare command for each layer layertypes = utils.command2ltype.values() + ["overlay", "command"] if self.type not in layertypes: raise GException( _("<%(name)s>: layer type <%(type)s> is not supported") % {"type": self.type, "name": self.name} ) if self.mapfile: os.environ["GRASS_RENDER_FILE"] = self.mapfile # execute command try: if self.type == "command": read = False for c in self.cmd: ret, msg = self._runCommand(c) if ret != 0: break if not read: os.environ["GRASS_RENDER_FILE_READ"] = "TRUE" os.environ["GRASS_RENDER_FILE_READ"] = "FALSE" else: ret, msg = self._runCommand(self.cmd) if ret != 0: sys.stderr.write(_("Command '%s' failed\n") % self.GetCmd(string=True)) if msg: sys.stderr.write(_("Details: %s\n") % msg) raise GException() except GException: # clean up after problems for f in [self.mapfile, self.maskfile]: if not f: continue grass.try_remove(f) f = None # stop monitor if self.mapfile and "GRASS_RENDER_FILE" in os.environ: del os.environ["GRASS_RENDER_FILE"] self.forceRender = False return self.mapfile