diff --git a/display/d.vect.chart/plot.c b/display/d.vect.chart/plot.c
index 68ef37dcea1..73dcaf08c78 100644
--- a/display/d.vect.chart/plot.c
+++ b/display/d.vect.chart/plot.c
@@ -27,8 +27,6 @@ int plot(int ctype, struct Map_info *Map, int type, int field, char *columns,
dbTable *table;
dbColumn *column;
- Points = Vect_new_line_struct();
- Cats = Vect_new_cats_struct();
db_init_string(&sql);
Fi = Vect_get_field(Map, field);
@@ -40,8 +38,11 @@ int plot(int ctype, struct Map_info *Map, int type, int field, char *columns,
if (driver == NULL) {
G_warning(_("Unable to open database <%s> by driver <%s>"),
Fi->database, Fi->driver);
+ Vect_destroy_field_info(Fi);
return 1;
}
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
db_set_error_handler_driver(driver);
val =
@@ -134,6 +135,8 @@ int plot(int ctype, struct Map_info *Map, int type, int field, char *columns,
db_close_database_shutdown_driver(driver);
Vect_destroy_line_struct(Points);
Vect_destroy_cats_struct(Cats);
+ Vect_destroy_field_info(Fi);
+ G_free(val);
return 0;
}
diff --git a/general/g.setproj/g.setproj.html b/general/g.setproj/g.setproj.html
index eb39ccb4010..8db06bc6880 100644
--- a/general/g.setproj/g.setproj.html
+++ b/general/g.setproj/g.setproj.html
@@ -1,32 +1,8 @@
-
-
-
-g.setproj - GRASS GIS manual
-
-
-
-
-
-
-
-
-
-
NAME
+
DESCRIPTION
-g.setproj allows the user to create the PROJ_INFO and the
+g.setproj allows the user to create the PROJ_INFO and the
PROJ_UNITS files to record the coordinate reference system (CRS) information
associated with a current project (previously called location).
-
-
-
SYNOPSIS
-
-g.setproj
-
-
DESCRIPTION
-
-Allows a user to create a PROJ_INFO file in the PERMANENT mapset of the
-current project. PROJ_INFO file is used to record the CRS information
-associated with the specified project.
NOTES
@@ -82,11 +58,6 @@
SEE ALSO
AUTHORS
-Irina Kosinovsky,
-U.S. Army Construction Engineering
-Research Laboratory
+Irina Kosinovsky, U.S. Army Construction Engineering Research Laboratory
Morten Hulden, morten at untamo.net - rewrote module and added 121 projections
Andreas Lange, andreas.lange at rhein-main.de - added prelimnary map datum support
-
-
-
diff --git a/gui/wxpython/animation/data.py b/gui/wxpython/animation/data.py
index ec33ce082d2..a627ce00865 100644
--- a/gui/wxpython/animation/data.py
+++ b/gui/wxpython/animation/data.py
@@ -21,6 +21,7 @@
from grass.script.utils import parse_key_val
from grass.script import core as gcore
+from grass.exceptions import ScriptError
from core.gcmd import GException
from animation.nviztask import NvizTask
@@ -299,7 +300,7 @@ def SetName(self, name):
try:
name = validateTimeseriesName(name, self._mapType)
self._maps = getRegisteredMaps(name, self._mapType)
- except (GException, gcore.ScriptError) as e:
+ except (GException, ScriptError) as e:
raise ValueError(str(e))
else:
self._maps = validateMapNames(name.split(","), self._mapType)
diff --git a/gui/wxpython/animation/dialogs.py b/gui/wxpython/animation/dialogs.py
index 5a634b3bb16..1ee8d01c174 100644
--- a/gui/wxpython/animation/dialogs.py
+++ b/gui/wxpython/animation/dialogs.py
@@ -37,6 +37,7 @@
from wx import HyperlinkCtrl
from core.gcmd import GMessage, GError, GException
+from grass.exceptions import ScriptError
from core import globalvar
from gui_core.dialogs import MapLayersDialog, GetImageHandlers
from gui_core.preferences import PreferencesBaseDialog
@@ -727,10 +728,9 @@ def _update(self):
if isStart:
self.animationData.startRegion = isStart
else:
- if isStart:
- self.animationData.startRegion = isStart
- else:
+ if not isStart:
raise GException(_("Region information is not complete"))
+ self.animationData.startRegion = isStart
if isEnd:
self.animationData.endRegion = self.endRegion.GetValue()
self.animationData.zoomRegionValue = None
@@ -1785,7 +1785,7 @@ def _createDefaultCommand(self):
if maps:
mapName, mapLayer = getNameAndLayer(maps[0])
cmd.append("map={name}".format(name=mapName))
- except gcore.ScriptError as e:
+ except ScriptError as e:
GError(parent=self, message=str(e), showTraceback=False)
return None
return cmd
@@ -1838,7 +1838,7 @@ def _onOK(self, event):
self.layer.name = self._name
self.layer.cmd = self._cmd
event.Skip()
- except (GException, gcore.ScriptError) as e:
+ except (GException, ScriptError) as e:
GError(parent=self, message=str(e))
def GetLayer(self):
diff --git a/gui/wxpython/animation/nviztask.py b/gui/wxpython/animation/nviztask.py
index 5dbb1d3e982..caa02553db4 100644
--- a/gui/wxpython/animation/nviztask.py
+++ b/gui/wxpython/animation/nviztask.py
@@ -299,12 +299,10 @@ def GetCommandSeries(self, layerList, paramName):
if len(layerList) > 1:
raise GException(_("Please add only one layer in the list."))
- return
layer = layerList[0]
- if hasattr(layer, "maps"):
- series = layer.maps
- else:
+ if not hasattr(layer, "maps"):
raise GException(_("No map series nor space-time dataset is added."))
+ series = layer.maps
for value in series:
self.task.set_param(paramName, value)
diff --git a/gui/wxpython/animation/provider.py b/gui/wxpython/animation/provider.py
index 08d1c083cb8..0be21a2ed94 100644
--- a/gui/wxpython/animation/provider.py
+++ b/gui/wxpython/animation/provider.py
@@ -758,14 +758,15 @@ def Clear(self):
Debug.msg(4, "MapFilesPool.Clear")
for key in list(self.dictionary.keys()):
- if self.referenceCount[key] <= 0:
- name, ext = os.path.splitext(self.dictionary[key])
- os.remove(self.dictionary[key])
- if ext == ".ppm":
- os.remove(name + ".pgm")
- del self.dictionary[key]
- del self.referenceCount[key]
- del self.size[key]
+ if self.referenceCount[key] > 0:
+ continue
+ name, ext = os.path.splitext(self.dictionary[key])
+ os.remove(self.dictionary[key])
+ if ext == ".ppm":
+ os.remove(name + ".pgm")
+ del self.dictionary[key]
+ del self.referenceCount[key]
+ del self.size[key]
class BitmapPool(DictRefCounter):
diff --git a/gui/wxpython/animation/utils.py b/gui/wxpython/animation/utils.py
index 54aafa3532f..cf49e3fd974 100644
--- a/gui/wxpython/animation/utils.py
+++ b/gui/wxpython/animation/utils.py
@@ -92,18 +92,18 @@ def validateMapNames(names, etype):
for name in names:
if name.find("@") >= 0:
nameShort, mapset = name.split("@", 1)
- if nameShort in mapDict[mapset]:
- newNames.append(name)
- else:
- raise GException(_("Map <%s> not found.") % name)
- else:
- found = False
- for mapset, mapNames in mapDict.items():
- if name in mapNames:
- found = True
- newNames.append(name + "@" + mapset)
- if not found:
+ if nameShort not in mapDict[mapset]:
raise GException(_("Map <%s> not found.") % name)
+ newNames.append(name)
+
+ continue
+ found = False
+ for mapset, mapNames in mapDict.items():
+ if name in mapNames:
+ found = True
+ newNames.append(name + "@" + mapset)
+ if not found:
+ raise GException(_("Map <%s> not found.") % name)
return newNames
@@ -331,21 +331,22 @@ def layerListToCmdsMatrix(layerList):
continue
if hasattr(layer, "maps"):
for i, part in enumerate(layer.cmd):
- if part.startswith("map="):
- cmd = layer.cmd[:]
- cmds = []
- for map_ in layer.maps:
- # check if dataset uses layers instead of maps
- mapName, mapLayer = getNameAndLayer(map_)
- cmd[i] = "map={name}".format(name=mapName)
- if mapLayer:
- try:
- idx = cmd.index("layer")
- cmd[idx] = "layer={layer}".format(layer=mapLayer)
- except ValueError:
- cmd.append("layer={layer}".format(layer=mapLayer))
- cmds.append(cmd[:])
- cmdsForComposition.append(cmds)
+ if not part.startswith("map="):
+ continue
+ cmd = layer.cmd[:]
+ cmds = []
+ for map_ in layer.maps:
+ # check if dataset uses layers instead of maps
+ mapName, mapLayer = getNameAndLayer(map_)
+ cmd[i] = "map={name}".format(name=mapName)
+ if mapLayer:
+ try:
+ idx = cmd.index("layer")
+ cmd[idx] = "layer={layer}".format(layer=mapLayer)
+ except ValueError:
+ cmd.append("layer={layer}".format(layer=mapLayer))
+ cmds.append(cmd[:])
+ cmdsForComposition.append(cmds)
else:
cmdsForComposition.append([layer.cmd] * count)
diff --git a/gui/wxpython/core/gcmd.py b/gui/wxpython/core/gcmd.py
index 0b8d57fe2fe..08a95c0aa7e 100644
--- a/gui/wxpython/core/gcmd.py
+++ b/gui/wxpython/core/gcmd.py
@@ -180,25 +180,25 @@ def __init__(self, args, **kwargs):
# "^" must be the first character in the list to avoid double
# escaping.
for c in ("^", "|", "&", "<", ">"):
- if c in args[i]:
- if "=" in args[i]:
- a = args[i].split("=")
- k = a[0] + "="
- v = "=".join(a[1 : len(a)])
- else:
- k = ""
- v = args[i]
-
- # If there are spaces, the argument was already
- # esscaped with double quotes, so don't escape it
- # again.
- if c in v and " " not in v:
- # Here, we escape each ^ in ^^^ with ^^ and a
- # with ^ + ,
- # so we need 7 carets.
-
- v = v.replace(c, "^^^^^^^" + c)
- args[i] = k + v
+ if c not in args[i]:
+ continue
+ if "=" in args[i]:
+ a = args[i].split("=")
+ k = a[0] + "="
+ v = "=".join(a[1 : len(a)])
+ else:
+ k = ""
+ v = args[i]
+
+ # If there are spaces, the argument was already
+ # escaped with double quotes, so don't escape it
+ # again.
+ if c in v and " " not in v:
+ # Here, we escape each ^ in ^^^ with ^^ and a
+ # with ^ + ,
+ # so we need 7 carets.
+ v = v.replace(c, "^^^^^^^" + c)
+ args[i] = k + v
subprocess.Popen.__init__(self, args, **kwargs)
diff --git a/gui/wxpython/core/globalvar.py b/gui/wxpython/core/globalvar.py
index a5ce362f8c8..a3c8b50de79 100644
--- a/gui/wxpython/core/globalvar.py
+++ b/gui/wxpython/core/globalvar.py
@@ -23,6 +23,7 @@
from grass.script.core import get_commands
from core.debug import Debug
+from pathlib import Path
# path to python scripts
ETCDIR = os.path.join(os.getenv("GISBASE"), "etc")
@@ -206,7 +207,8 @@ def UpdateGRASSAddOnCommands(eList=None):
if pathList and path not in pathList:
os.environ["PATH"] = path + os.pathsep + os.environ["PATH"]
- for fname in os.listdir(path):
+ for file_path in Path(path).iterdir():
+ fname = file_path.name
if fname in {"docs", "modules.xml"}:
continue
if grassScripts: # win32
diff --git a/gui/wxpython/core/render.py b/gui/wxpython/core/render.py
index 67e7561c4e7..631298afa1a 100644
--- a/gui/wxpython/core/render.py
+++ b/gui/wxpython/core/render.py
@@ -217,15 +217,12 @@ def GetCmd(self, string=False):
:return: command list/string
"""
- if string:
- if self.type == "command":
- scmd = []
- for c in self.cmd:
- scmd.append(utils.GetCmdString(c))
-
- return ";".join(scmd)
- return utils.GetCmdString(self.cmd)
- return self.cmd
+ if not string:
+ return self.cmd
+ if self.type == "command":
+ scmd = [utils.GetCmdString(c) for c in self.cmd]
+ return ";".join(scmd)
+ return utils.GetCmdString(self.cmd)
def GetType(self):
"""Get map layer type"""
@@ -883,25 +880,24 @@ def GetWindow(self):
env["GISDBASE"], env["LOCATION_NAME"], env["MAPSET"], "WIND"
)
try:
- windfile = open(filename)
+ with open(filename) as windfile:
+ for line in windfile:
+ line = line.strip()
+ try:
+ key, value = line.split(":", 1)
+ except ValueError as e:
+ sys.stderr.write(
+ _("\nERROR: Unable to read WIND file: %s\n") % e
+ )
+ return None
+
+ self.wind[key.strip()] = value.strip()
except OSError as e:
sys.exit(
_("Error: Unable to open '%(file)s'. Reason: %(ret)s. wxGUI exited.\n")
% {"file": filename, "ret": e}
)
- for line in windfile:
- line = line.strip()
- try:
- key, value = line.split(":", 1)
- except ValueError as e:
- sys.stderr.write(_("\nERROR: Unable to read WIND file: %s\n") % e)
- return None
-
- self.wind[key.strip()] = value.strip()
-
- windfile.close()
-
return self.wind
def AdjustRegion(self):
@@ -1406,29 +1402,28 @@ def DeleteLayer(self, layer, overlay=False):
list_ = self.overlays if overlay else self.layers
- if layer in list_:
- if layer.mapfile:
- base, mapfile = os.path.split(layer.mapfile)
- tempbase = mapfile.split(".")[0]
- if base == "" or tempbase == "":
- return None
- basefile = os.path.join(base, tempbase) + r".*"
- # this comes all the way from r28605, so leaving
- # it as it is, although it does not really fit with the
- # new system (but probably works well enough)
- for f in glob.glob(basefile):
- os.remove(f)
-
- if layer.GetType() in {"vector", "thememap"}:
- if os.path.isfile(layer._legrow):
- os.remove(layer._legrow)
-
- list_.remove(layer)
-
- self.layerRemoved.emit(layer=layer)
- return layer
+ if layer not in list_:
+ return None
+ if layer.mapfile:
+ base, mapfile = os.path.split(layer.mapfile)
+ tempbase = mapfile.split(".")[0]
+ if base == "" or tempbase == "":
+ return None
+ basefile = os.path.join(base, tempbase) + r".*"
+ # this comes all the way from r28605, so leaving
+ # it as it is, although it does not really fit with the
+ # new system (but probably works well enough)
+ for f in glob.glob(basefile):
+ os.remove(f)
- return None
+ if layer.GetType() in {"vector", "thememap"}:
+ if os.path.isfile(layer._legrow):
+ os.remove(layer._legrow)
+
+ list_.remove(layer)
+
+ self.layerRemoved.emit(layer=layer)
+ return layer
def SetLayers(self, layers):
self.layers = layers
@@ -1653,12 +1648,11 @@ def GetOverlay(self, id, list=False):
"""
ovl = [overlay for overlay in self.overlays if overlay.id == id]
- if not list:
- if len(ovl) != 1:
- return None
- return ovl[0]
-
- return ovl
+ if list:
+ return ovl
+ if len(ovl) != 1:
+ return None
+ return ovl[0]
def DeleteOverlay(self, overlay):
"""Delete overlay
diff --git a/gui/wxpython/core/settings.py b/gui/wxpython/core/settings.py
index f65664a5e9b..783464ac99f 100644
--- a/gui/wxpython/core/settings.py
+++ b/gui/wxpython/core/settings.py
@@ -29,6 +29,7 @@
from core import globalvar
from core.gcmd import GException, GError
from core.utils import GetSettingsPath, PathJoin, rgb2str
+from pathlib import Path
class SettingsJSONEncoder(json.JSONEncoder):
@@ -104,7 +105,8 @@ def __init__(self):
def _generateLocale(self):
"""Generate locales"""
try:
- self.locs = os.listdir(os.path.join(os.environ["GISBASE"], "locale"))
+ locale_path = Path(os.environ["GISBASE"]) / "locale"
+ self.locs = [p.name for p in locale_path.iterdir() if p.is_dir()]
self.locs.append("en") # GRASS doesn't ship EN po files
self.locs.sort()
# Add a default choice to not override system locale
@@ -941,30 +943,28 @@ def _readLegacyFile(self, settings=None):
settings = self.userSettings
try:
- fd = open(self.legacyFilePath)
+ with open(self.legacyFilePath) as fd:
+ line = ""
+ for line in fd:
+ line = line.rstrip("%s" % os.linesep)
+ group, key = line.split(self.sep)[0:2]
+ kv = line.split(self.sep)[2:]
+ subkeyMaster = None
+ if len(kv) % 2 != 0: # multiple (e.g. nviz)
+ subkeyMaster = kv[0]
+ del kv[0]
+ idx = 0
+ while idx < len(kv):
+ subkey = [subkeyMaster, kv[idx]] if subkeyMaster else kv[idx]
+ value = kv[idx + 1]
+ value = self._parseValue(value, read=True)
+ self.Append(settings, group, key, subkey, value)
+ idx += 2
except OSError:
sys.stderr.write(
_("Unable to read settings file <%s>\n") % self.legacyFilePath
)
return
-
- try:
- line = ""
- for line in fd:
- line = line.rstrip("%s" % os.linesep)
- group, key = line.split(self.sep)[0:2]
- kv = line.split(self.sep)[2:]
- subkeyMaster = None
- if len(kv) % 2 != 0: # multiple (e.g. nviz)
- subkeyMaster = kv[0]
- del kv[0]
- idx = 0
- while idx < len(kv):
- subkey = [subkeyMaster, kv[idx]] if subkeyMaster else kv[idx]
- value = kv[idx + 1]
- value = self._parseValue(value, read=True)
- self.Append(settings, group, key, subkey, value)
- idx += 2
except ValueError as e:
print(
_(
@@ -975,9 +975,6 @@ def _readLegacyFile(self, settings=None):
% {"file": self.legacyFilePath, "detail": e, "line": line},
file=sys.stderr,
)
- fd.close()
-
- fd.close()
def SaveToFile(self, settings=None):
"""Save settings to the file"""
diff --git a/gui/wxpython/core/toolboxes.py b/gui/wxpython/core/toolboxes.py
index da4a516e83c..0bfac9d6b9f 100644
--- a/gui/wxpython/core/toolboxes.py
+++ b/gui/wxpython/core/toolboxes.py
@@ -124,101 +124,94 @@ def getMenudataFile(userRootFile, newFile, fallback):
# always create toolboxes directory if does not exist yet
tbDir = _setupToolboxes()
- if tbDir:
- menudataFile = os.path.join(tbDir, newFile)
- generateNew = False
- # when any of main_menu.xml or toolboxes.xml are changed,
- # generate new menudata.xml
-
- if os.path.exists(menudataFile):
- # remove menu file when there is no main_menu and toolboxes
- if not _getUserToolboxesFile() and not userRootFile:
- os.remove(menudataFile)
- _debug(
- 2,
- (
- "toolboxes.getMenudataFile: no user defined files, "
- "menudata deleted"
- ),
- )
- return fallback
-
- if bool(_getUserToolboxesFile()) != bool(userRootFile):
- # always generate new because we don't know if there has been
- # any change
- generateNew = True
- _debug(
- 2,
- ("toolboxes.getMenudataFile: only one of the user defined files"),
- )
- else:
- # if newer files -> generate new
- menudataTime = os.path.getmtime(menudataFile)
- if _getUserToolboxesFile():
- if os.path.getmtime(_getUserToolboxesFile()) > menudataTime:
- _debug(
- 2,
- (
- "toolboxes.getMenudataFile: user toolboxes is newer "
- "than menudata"
- ),
- )
- generateNew = True
- if userRootFile:
- if os.path.getmtime(userRootFile) > menudataTime:
- _debug(
- 2,
- (
- "toolboxes.getMenudataFile: user root file is "
- "newer than menudata"
- ),
- )
- generateNew = True
- elif _getUserToolboxesFile() or userRootFile:
- _debug(2, "toolboxes.getMenudataFile: no menudata")
- generateNew = True
- else:
- _debug(2, "toolboxes.getMenudataFile: no user defined files")
+ if not tbDir:
+ _debug(2, "toolboxes.getMenudataFile: returning menudata fallback file")
+ return fallback
+
+ menudataFile = os.path.join(tbDir, newFile)
+ generateNew = False
+ # when any of main_menu.xml or toolboxes.xml are changed,
+ # generate new menudata.xml
+
+ if os.path.exists(menudataFile):
+ # remove menu file when there is no main_menu and toolboxes
+ if not _getUserToolboxesFile() and (not userRootFile):
+ os.remove(menudataFile)
+ _debug(
+ 2,
+ ("toolboxes.getMenudataFile: no user defined files, menudata deleted"),
+ )
return fallback
- if generateNew:
- try:
- # The case when user does not have custom root
- # file but has toolboxes requires regeneration.
- # Unfortunately, this is the case can be often: defined
- # toolboxes but undefined module tree file.
- _debug(2, "toolboxes.getMenudataFile: creating a tree")
- tree = createTree(
- distributionRootFile=distributionRootFile, userRootFile=userRootFile
- )
- except ETREE_EXCEPTIONS:
- _warning(
- _(
- "Unable to parse user toolboxes XML files. "
- "Default files will be loaded."
- )
- )
- return fallback
-
- try:
- xml = _getXMLString(tree.getroot())
- Path(menudataFile).write_text(xml)
- return menudataFile
- except Exception:
- _debug(
- 2,
- (
- "toolboxes.getMenudataFile: writing menudata failed, "
- "returning fallback file"
- ),
- )
- return fallback
+ if bool(_getUserToolboxesFile()) != bool(userRootFile):
+ # always generate new because we don't know if there has been
+ # any change
+ generateNew = True
+ _debug(
+ 2,
+ ("toolboxes.getMenudataFile: only one of the user defined files"),
+ )
else:
- return menudataFile
+ # if newer files -> generate new
+ menudataTime = os.path.getmtime(menudataFile)
+ if _getUserToolboxesFile():
+ if os.path.getmtime(_getUserToolboxesFile()) > menudataTime:
+ _debug(
+ 2,
+ (
+ "toolboxes.getMenudataFile: user toolboxes is newer "
+ "than menudata"
+ ),
+ )
+ generateNew = True
+ if userRootFile:
+ if os.path.getmtime(userRootFile) > menudataTime:
+ _debug(
+ 2,
+ (
+ "toolboxes.getMenudataFile: user root file is "
+ "newer than menudata"
+ ),
+ )
+ generateNew = True
+ elif _getUserToolboxesFile() or userRootFile:
+ _debug(2, "toolboxes.getMenudataFile: no menudata")
+ generateNew = True
else:
- _debug(2, "toolboxes.getMenudataFile: returning menudata fallback file")
+ _debug(2, "toolboxes.getMenudataFile: no user defined files")
return fallback
+ if not generateNew:
+ return menudataFile
+ try:
+ # The case when user does not have custom root
+ # file but has toolboxes requires regeneration.
+ # Unfortunately, this is the case can be often: defined
+ # toolboxes but undefined module tree file.
+ _debug(2, "toolboxes.getMenudataFile: creating a tree")
+ tree = createTree(
+ distributionRootFile=distributionRootFile, userRootFile=userRootFile
+ )
+ except ETREE_EXCEPTIONS:
+ _warning(
+ _("Unable to parse user toolboxes XML files. Default files will be loaded.")
+ )
+ return fallback
+
+ try:
+ xml = _getXMLString(tree.getroot())
+ Path(menudataFile).write_text(xml)
+ return menudataFile
+ except Exception:
+ _debug(
+ 2,
+ (
+ "toolboxes.getMenudataFile: writing menudata failed, "
+ "returning fallback file"
+ ),
+ )
+ return fallback
+
def _setupToolboxes():
"""Create 'toolboxes' directory if doesn't exist."""
@@ -611,21 +604,23 @@ def _expandRuntimeModules(node, loadMetadata=True):
n = ET.SubElement(module, "module")
n.text = name
- if module.find("description") is None:
- if loadMetadata:
- # not all modules are always compiled (e.g., r.in.lidar)
- if shutil.which(name):
- desc, keywords = _loadMetadata(name)
- if not desc:
- hasErrors = True
- else:
- desc, keywords = _("Module not installed"), ""
+ if module.find("description") is not None:
+ continue
+
+ if loadMetadata:
+ # not all modules are always compiled (e.g., r.in.lidar)
+ if shutil.which(name):
+ desc, keywords = _loadMetadata(name)
+ if not desc:
+ hasErrors = True
else:
- desc, keywords = "", ""
- n = ET.SubElement(module, "description")
- n.text = _escapeXML(desc)
- n = ET.SubElement(module, "keywords")
- n.text = _escapeXML(",".join(keywords))
+ desc, keywords = (_("Module not installed"), "")
+ else:
+ desc, keywords = ("", "")
+ n = ET.SubElement(module, "description")
+ n.text = _escapeXML(desc)
+ n = ET.SubElement(module, "keywords")
+ n.text = _escapeXML(",".join(keywords))
if hasErrors:
# not translatable until toolboxes compilation on Mac is fixed
diff --git a/gui/wxpython/core/utils.py b/gui/wxpython/core/utils.py
index a1722fec64b..72423756460 100644
--- a/gui/wxpython/core/utils.py
+++ b/gui/wxpython/core/utils.py
@@ -146,18 +146,18 @@ def GetLayerNameFromCmd(dcmd, fullyQualified=False, param=None, layerType=None):
params.append((idx, p, v))
if len(params) < 1:
- if len(dcmd) > 1:
- i = 1
- while i < len(dcmd):
- if "=" not in dcmd[i] and not dcmd[i].startswith("-"):
- task = gtask.parse_interface(dcmd[0])
- # this expects the first parameter to be the right one
- p = task.get_options()["params"][0].get("name", "")
- params.append((i, p, dcmd[i]))
- break
- i += 1
- else:
- return mapname, False
+ if len(dcmd) <= 1:
+ return (mapname, False)
+
+ i = 1
+ while i < len(dcmd):
+ if "=" not in dcmd[i] and (not dcmd[i].startswith("-")):
+ task = gtask.parse_interface(dcmd[0])
+ # this expects the first parameter to be the right one
+ p = task.get_options()["params"][0].get("name", "")
+ params.append((i, p, dcmd[i]))
+ break
+ i += 1
if len(params) < 1:
return mapname, False
@@ -267,10 +267,9 @@ def ListOfCatsToRange(cats):
next = 0
j = i + 1
while j < len(cats):
- if cats[i + next] == cats[j] - 1:
- next += 1
- else:
+ if cats[i + next] != cats[j] - 1:
break
+ next += 1
j += 1
if next > 1:
@@ -302,22 +301,21 @@ def ListOfMapsets(get="ordered"):
if get == "all":
return mapsets_all
- if get in {"accessible", "ordered"}:
- ret = RunCommand("g.mapsets", read=True, quiet=True, flags="p", sep="newline")
- if not ret:
- return []
- mapsets_accessible = ret.splitlines()
- if get == "accessible":
- return mapsets_accessible
-
- mapsets_ordered = mapsets_accessible.copy()
- for mapset in mapsets_all:
- if mapset not in mapsets_accessible:
- mapsets_ordered.append(mapset)
- return mapsets_ordered
+ if get not in {"accessible", "ordered"}:
+ msg = "Invalid value for 'get' parameter of ListOfMapsets()"
+ raise ValueError(msg)
+ ret = RunCommand("g.mapsets", read=True, quiet=True, flags="p", sep="newline")
+ if not ret:
+ return []
+ mapsets_accessible = ret.splitlines()
+ if get == "accessible":
+ return mapsets_accessible
- msg = "Invalid value for 'get' parameter of ListOfMapsets()"
- raise ValueError(msg)
+ mapsets_ordered = mapsets_accessible.copy()
+ for mapset in mapsets_all:
+ if mapset not in mapsets_accessible:
+ mapsets_ordered.append(mapset)
+ return mapsets_ordered
def ListSortLower(list):
@@ -828,7 +826,21 @@ def StoreEnvVariable(key, value=None, envFile=None):
lineSkipped = []
if os.path.exists(envFile):
try:
- fd = open(envFile)
+ with open(envFile) as fd:
+ for line in fd:
+ line = line.rstrip(os.linesep)
+ try:
+ k, v = (x.strip() for x in line.split(" ", 1)[1].split("=", 1))
+ except Exception as e:
+ sys.stderr.write(
+ _("%s: line skipped - unable to parse '%s'\nReason: %s\n")
+ % (envFile, line, e)
+ )
+ lineSkipped.append(line)
+ continue
+ if k in environ:
+ sys.stderr.write(_("Duplicated key: %s\n") % k)
+ environ[k] = v
except OSError as error:
sys.stderr.write(
_("Unable to open file '{name}': {error}\n").format(
@@ -836,22 +848,6 @@ def StoreEnvVariable(key, value=None, envFile=None):
)
)
return
- for line in fd:
- line = line.rstrip(os.linesep)
- try:
- k, v = (x.strip() for x in line.split(" ", 1)[1].split("=", 1))
- except Exception as e:
- sys.stderr.write(
- _("%s: line skipped - unable to parse '%s'\nReason: %s\n")
- % (envFile, line, e)
- )
- lineSkipped.append(line)
- continue
- if k in environ:
- sys.stderr.write(_("Duplicated key: %s\n") % k)
- environ[k] = v
-
- fd.close()
# update environmental variables
if value is None:
@@ -861,7 +857,15 @@ def StoreEnvVariable(key, value=None, envFile=None):
# write update env file
try:
- fd = open(envFile, "w")
+ with open(envFile, "w") as fd:
+ expCmd = "set" if windows else "export"
+
+ fd.writelines(
+ "%s %s=%s\n" % (expCmd, key, value) for key, value in environ.items()
+ )
+
+ # write also skipped lines
+ fd.writelines(line + os.linesep for line in lineSkipped)
except OSError as error:
sys.stderr.write(
_("Unable to create file '{name}': {error}\n").format(
@@ -869,14 +873,6 @@ def StoreEnvVariable(key, value=None, envFile=None):
)
)
return
- expCmd = "set" if windows else "export"
-
- fd.writelines("%s %s=%s\n" % (expCmd, key, value) for key, value in environ.items())
-
- # write also skipped lines
- fd.writelines(line + os.linesep for line in lineSkipped)
-
- fd.close()
def SetAddOnPath(addonPath=None, key="PATH"):
diff --git a/gui/wxpython/core/workspace.py b/gui/wxpython/core/workspace.py
index bd09a9354a6..300e9993f5e 100644
--- a/gui/wxpython/core/workspace.py
+++ b/gui/wxpython/core/workspace.py
@@ -1730,7 +1730,11 @@ def read(self, parent):
:return: list of map layers
"""
try:
- file = open(self.filename)
+ with open(self.filename) as file: # Changed to context manager
+ line_id = 1
+ for line in file:
+ self.process_line(line.rstrip("\n"), line_id)
+ line_id += 1
except OSError:
wx.MessageBox(
parent=parent,
@@ -1740,13 +1744,6 @@ def read(self, parent):
)
return []
- line_id = 1
- for line in file:
- self.process_line(line.rstrip("\n"), line_id)
- line_id += 1
-
- file.close()
-
if self.num_error > 0:
wx.MessageBox(
parent=parent,
diff --git a/gui/wxpython/datacatalog/catalog.py b/gui/wxpython/datacatalog/catalog.py
index 4835061d968..c8b02422e1b 100644
--- a/gui/wxpython/datacatalog/catalog.py
+++ b/gui/wxpython/datacatalog/catalog.py
@@ -17,7 +17,6 @@
"""
import wx
-import os
from pathlib import Path
@@ -212,7 +211,7 @@ def OnAddGrassDB(self, event):
grassdb_node = self.tree.InsertGrassDb(name=grassdatabase)
# Offer to create a new location
- if grassdb_node and not os.listdir(grassdatabase):
+ if grassdb_node and not any(Path(grassdatabase).iterdir()):
message = _(
"Do you want to create a new project (also known as location)?"
)
diff --git a/gui/wxpython/dbmgr/vinfo.py b/gui/wxpython/dbmgr/vinfo.py
index 94dda140406..b3c9273e0eb 100644
--- a/gui/wxpython/dbmgr/vinfo.py
+++ b/gui/wxpython/dbmgr/vinfo.py
@@ -23,6 +23,7 @@
from core.gcmd import RunCommand, GError
from core.settings import UserSettings
import grass.script as gs
+from grass.exceptions import ScriptError
def GetUnicodeValue(value):
@@ -45,10 +46,9 @@ def GetDbEncoding():
then env variable), if not assumes unicode."""
enc = UserSettings.Get(group="atm", key="encoding", subkey="value")
if not enc and "GRASS_DB_ENCODING" in os.environ:
- enc = os.environ["GRASS_DB_ENCODING"]
- else:
- enc = "utf-8" # assuming UTF-8
- return enc
+ return os.environ["GRASS_DB_ENCODING"]
+ # assuming UTF-8
+ return "utf-8"
def CreateDbInfoDesc(panel, mapDBInfo, layer):
@@ -107,7 +107,7 @@ def SelectByPoint(self, queryCoords, qdist):
coord=(float(queryCoords[0]), float(queryCoords[1])),
distance=float(qdist),
)
- except gs.ScriptError:
+ except ScriptError:
GError(
parent=None,
message=_(
diff --git a/gui/wxpython/gcp/manager.py b/gui/wxpython/gcp/manager.py
index 6761cead483..6353f7de0c8 100644
--- a/gui/wxpython/gcp/manager.py
+++ b/gui/wxpython/gcp/manager.py
@@ -901,9 +901,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None:
flags="g",
)
- if ret:
- self.parent.src_maps = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -913,6 +911,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None:
% self.parent.grouppage.xygroup,
)
return
+ self.parent.src_maps = ret.splitlines()
elif maptype == "vector":
grassdatabase = self.parent.grassdatabase
@@ -1670,7 +1669,7 @@ def OnRMS(self, event):
targetMapWin = self.TgtMapWindow
targetMapWin.UpdateMap(render=False, renderVector=False)
- def CheckGCPcount(self, msg=False):
+ def CheckGCPcount(self, msg: bool = False) -> bool:
"""
Checks to make sure that the minimum number of GCPs have been defined and
are active for the selected transformation order
@@ -1692,9 +1691,10 @@ def CheckGCPcount(self, msg=False):
)
% self.gr_order,
)
- return False
- else:
- return True
+
+ return False
+
+ return True
def _getOverWriteDialog(self, maptype, overwrite):
"""Get overwrite confirm dialog
@@ -2011,9 +2011,7 @@ def RMSError(self, xygroup, order):
self.grwiz.SwitchEnv("target")
- if ret:
- errlist = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -2021,6 +2019,7 @@ def RMSError(self, xygroup, order):
),
)
return
+ errlist = ret.splitlines()
# insert error values into GCP list for checked items
sdfactor = float(UserSettings.Get(group="gcpman", key="rms", subkey="sdfactor"))
@@ -2051,12 +2050,13 @@ def RMSError(self, xygroup, order):
sumsq_bkw_err += float(bkw_err) ** 2
sum_fwd_err += float(fwd_err)
GCPcount += 1
- else:
- self.list.SetItem(index, 5, "")
- self.list.SetItem(index, 6, "")
- self.mapcoordlist[key][5] = 0.0
- self.mapcoordlist[key][6] = 0.0
- self.list.SetItemTextColour(index, wx.BLACK)
+ continue
+
+ self.list.SetItem(index, 5, "")
+ self.list.SetItem(index, 6, "")
+ self.mapcoordlist[key][5] = 0.0
+ self.mapcoordlist[key][6] = 0.0
+ self.list.SetItemTextColour(index, wx.BLACK)
# SD
if GCPcount > 0:
@@ -2143,9 +2143,7 @@ def GetNewExtent(self, region, map=None):
self.grwiz.SwitchEnv("target")
- if ret:
- errlist = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -2153,6 +2151,7 @@ def GetNewExtent(self, region, map=None):
),
)
return
+ errlist = ret.splitlines()
# fist corner
e, n = errlist[0].split()
diff --git a/gui/wxpython/gmodeler/model.py b/gui/wxpython/gmodeler/model.py
index ee846c62653..c5b2d8b93d2 100644
--- a/gui/wxpython/gmodeler/model.py
+++ b/gui/wxpython/gmodeler/model.py
@@ -495,25 +495,25 @@ def Validate(self):
continue
key, value = opt.split("=", 1)
sval = pattern.search(value)
- if sval:
- var = sval.group(2).strip()[1:] # strip '%' from beginning
- found = False
- for v in variables:
- if var.startswith(v):
- found = True
- break
- if not found:
- report = True
- for item in filter(
- lambda x: isinstance(x, ModelLoop), action.GetBlock()
- ):
- if var in item.GetLabel():
- report = False
- break
- if report:
- errList.append(
- cmd[0] + ": " + _("undefined variable '%s'") % var
- )
+ if not sval:
+ continue
+ var = sval.group(2).strip()[1:] # strip '%' from beginning
+ found = False
+ for v in variables:
+ if var.startswith(v):
+ found = True
+ break
+ if found:
+ continue
+ report = True
+ for item in filter(
+ lambda x: isinstance(x, ModelLoop), action.GetBlock()
+ ):
+ if var in item.GetLabel():
+ report = False
+ break
+ if report:
+ errList.append(cmd[0] + ": " + _("undefined variable '%s'") % var)
# TODO: check variables in file only optionally
# errList += self._substituteFile(action, checkOnly = True)
@@ -702,24 +702,24 @@ def Run(self, log, onDone, parent=None):
variables = self.GetVariables()
for variable in variables:
pattern = re.compile("%" + variable)
- if pattern.search(cond):
- value = ""
- if params and "variables" in params:
- for p in params["variables"]["params"]:
- if variable == p.get("name", ""):
- value = p.get("value", "")
- break
-
- if not value:
- value = variables[variable].get("value", "")
-
- if not value:
- continue
+ if not pattern.search(cond):
+ continue
+ value = ""
+ if params and "variables" in params:
+ for p in params["variables"]["params"]:
+ if variable == p.get("name", ""):
+ value = p.get("value", "")
+ break
+
+ if not value:
+ value = variables[variable].get("value", "")
- vtype = variables[variable].get("type", "string")
- if vtype == "string":
- value = '"' + value + '"'
- cond = pattern.sub(value, cond)
+ if not value:
+ continue
+ vtype = variables[variable].get("type", "string")
+ if vtype == "string":
+ value = '"' + value + '"'
+ cond = pattern.sub(value, cond)
# split condition
# TODO: this part needs some better solution
@@ -1211,12 +1211,11 @@ def GetLog(self, string=True, substitute=None):
cmd[idx] = pattern.sub(value, cmd[idx])
idx += 1
- if string:
- if cmd is None:
- return ""
- return " ".join(cmd)
-
- return cmd
+ if not string:
+ return cmd
+ if cmd is None:
+ return ""
+ return " ".join(cmd)
def GetLabel(self):
"""Get name"""
@@ -1975,12 +1974,11 @@ def _filterValue(self, value):
def _getNodeText(self, node, tag, default=""):
"""Get node text"""
p = node.find(tag)
- if p is not None:
- if p.text:
- return utils.normalize_whitespace(p.text)
- return ""
-
- return default
+ if p is None:
+ return default
+ if p.text:
+ return utils.normalize_whitespace(p.text)
+ return ""
def _processWindow(self):
"""Process window properties"""
@@ -2780,22 +2778,23 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):
name = p.get("name", None)
value = p.get("value", None)
- if (name and value) or (name in parameterizedParams):
- if name in parameterizedParams:
- parameterizedParam = self._getParamName(name, item)
- default_val = p.get("value", "")
+ if (not name or not value) and name not in parameterizedParams:
+ continue
- if len(default_val) > 0:
- parameterizedParam += f"|default({default_val})"
+ if name in parameterizedParams:
+ parameterizedParam = self._getParamName(name, item)
+ default_val = p.get("value", "")
- value = f"{{{{ {parameterizedParam} }}}}"
+ if len(default_val) > 0:
+ parameterizedParam += f"|default({default_val})"
+ value = f"{{{{ {parameterizedParam} }}}}"
- param_string = f'{{"param": "{name}", "value": "{value}"}}'
- age = p.get("age", "old")
- if age == "new":
- outputs.append(param_string)
- else:
- inputs.append(param_string)
+ param_string = f'{{"param": "{name}", "value": "{value}"}}'
+ age = p.get("age", "old")
+ if age == "new":
+ outputs.append(param_string)
+ else:
+ inputs.append(param_string)
ret += f'{" " * self.indent * 4}"module": "{task.get_name()}",\n'
ret += f'{" " * self.indent * 4}"id": "{self._getModuleNickname(item)}",\n'
@@ -2996,19 +2995,20 @@ def _write_input_outputs(self, item, intermediates):
# ComplexOutput if: outputting a new non-intermediate layer and
# either not empty or parameterized
if (
- age == "new"
- and not any(value in i for i in intermediates)
- and (value != "" or param in item.GetParameterizedParams()["params"])
- ):
- io_data = "outputs"
- object_type = "ComplexOutput"
- format_spec = self._getSupportedFormats(param["prompt"])
-
- self._write_input_output_object(
- io_data, object_type, param["name"], item, desc, format_spec, ""
+ age != "new"
+ or any(value in i for i in intermediates)
+ or (
+ value == "" and param not in item.GetParameterizedParams()["params"]
)
-
- self.fd.write("\n")
+ ):
+ continue
+ io_data = "outputs"
+ object_type = "ComplexOutput"
+ format_spec = self._getSupportedFormats(param["prompt"])
+ self._write_input_output_object(
+ io_data, object_type, param["name"], item, desc, format_spec, ""
+ )
+ self.fd.write("\n")
def _write_input_output_object(
self,
@@ -3060,45 +3060,49 @@ def _writePythonAction(self, item, variables={}, intermediates=None):
# output if: outputting a new non-intermediate layer and
# either not empty or parameterized
if (
- age == "new"
- and not any(value in i for i in intermediates)
- and (value != "" or param in item.GetParameterizedParams()["params"])
+ age != "new"
+ or any(value in i for i in intermediates)
+ or (
+ value == "" and param not in item.GetParameterizedParams()["params"]
+ )
):
- if param["prompt"] == "vector":
- command = "v.out.ogr"
- format = '"GML"'
- extension = ".gml"
- elif param["prompt"] == "raster":
- command = "r.out.gdal"
- format = '"GTiff"'
- extension = ".tif"
- else:
- # TODO: Support 3D
- command = "WRITE YOUR EXPORT COMMAND"
- format = '"WRITE YOUR EXPORT FORMAT"'
- extension = "WRITE YOUR EXPORT EXTENSION"
+ continue
- n = param.get("name", None)
- param_name = self._getParamName(n, item)
+ if param["prompt"] == "vector":
+ command = "v.out.ogr"
+ format = '"GML"'
+ extension = ".gml"
+ elif param["prompt"] == "raster":
+ command = "r.out.gdal"
+ format = '"GTiff"'
+ extension = ".tif"
+ else:
+ # TODO: Support 3D
+ command = "WRITE YOUR EXPORT COMMAND"
+ format = '"WRITE YOUR EXPORT FORMAT"'
+ extension = "WRITE YOUR EXPORT EXTENSION"
- keys = param.keys()
- if "parameterized" in keys and param["parameterized"] is True:
- param_request = 'request.inputs["{}"][0].data'.format(param_name)
- else:
- param_request = '"{}"'.format(param["value"])
+ n = param.get("name", None)
+ param_name = self._getParamName(n, item)
- # if True, write the overwrite parameter to the model command
- overwrite = self.model.GetProperties().get("overwrite", False)
- if overwrite is True:
- overwrite_string = ",\n{}overwrite=True".format(
- " " * (self.indent + 12)
- )
- else:
- overwrite_string = ""
+ keys = param.keys()
+ if "parameterized" in keys and param["parameterized"] is True:
+ param_request = 'request.inputs["{}"][0].data'.format(param_name)
+ else:
+ param_request = '"{}"'.format(param["value"])
- strcmd_len = len(strcmd.strip())
- self.fd.write(
- """
+ # if True, write the overwrite parameter to the model command
+ overwrite = self.model.GetProperties().get("overwrite", False)
+ if overwrite is True:
+ overwrite_string = ",\n{}overwrite=True".format(
+ " " * (self.indent + 12)
+ )
+ else:
+ overwrite_string = ""
+
+ strcmd_len = len(strcmd.strip())
+ self.fd.write(
+ """
{run_command}"{cmd}",
{indent1}input={input},
{indent2}output=os.path.join(
@@ -3106,37 +3110,35 @@ def _writePythonAction(self, item, variables={}, intermediates=None):
{indent4}{out} + "{format_ext}"),
{indent5}format={format}{overwrite_string})
""".format(
- run_command=strcmd,
- cmd=command,
- indent1=" " * (self.indent + strcmd_len),
- input=param_request,
- indent2=" " * (self.indent + strcmd_len),
- indent3=" " * (self.indent * 2 + strcmd_len),
- indent4=" " * (self.indent * 2 + strcmd_len),
- out=param_request,
- format_ext=extension,
- indent5=" " * (self.indent + strcmd_len),
- format=format,
- overwrite_string=overwrite_string,
- )
+ run_command=strcmd,
+ cmd=command,
+ indent1=" " * (self.indent + strcmd_len),
+ input=param_request,
+ indent2=" " * (self.indent + strcmd_len),
+ indent3=" " * (self.indent * 2 + strcmd_len),
+ indent4=" " * (self.indent * 2 + strcmd_len),
+ out=param_request,
+ format_ext=extension,
+ indent5=" " * (self.indent + strcmd_len),
+ format=format,
+ overwrite_string=overwrite_string,
)
+ )
- left_side_out = 'response.outputs["{}"].file'.format(param_name)
- right_side_out = (
- "os.path.join(\n{indent1}"
- 'tempfile.gettempdir(),\n{indent2}{out} + "'
- '{format_ext}")'.format(
- indent1=" " * (self.indent + 4),
- indent2=" " * (self.indent + 4),
- out=param_request,
- format_ext=extension,
- )
- )
- self.fd.write(
- "\n{}{} = {}".format(
- " " * self.indent, left_side_out, right_side_out
- )
+ left_side_out = 'response.outputs["{}"].file'.format(param_name)
+ right_side_out = (
+ "os.path.join(\n{indent1}"
+ 'tempfile.gettempdir(),\n{indent2}{out} + "'
+ '{format_ext}")'.format(
+ indent1=" " * (self.indent + 4),
+ indent2=" " * (self.indent + 4),
+ out=param_request,
+ format_ext=extension,
)
+ )
+ self.fd.write(
+ "\n{}{} = {}".format(" " * self.indent, left_side_out, right_side_out)
+ )
def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):
opts = task.get_options()
@@ -3154,25 +3156,26 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):
name = p.get("name", None)
value = p.get("value", None)
- if (name and value) or (name in parameterizedParams):
- ptype = p.get("type", "string")
- foundVar = False
+ if (not name or not value) and name not in parameterizedParams:
+ continue
- if name in parameterizedParams:
- foundVar = True
- if "input" in name:
- value = 'request.inputs["{}"][0].file'.format(
- self._getParamName(name, item)
- )
- else:
- value = 'request.inputs["{}"][0].data'.format(
- self._getParamName(name, item)
- )
+ ptype = p.get("type", "string")
+ foundVar = False
- if foundVar or ptype != "string":
- params.append("{}={}".format(name, value))
+ if name in parameterizedParams:
+ foundVar = True
+ if "input" in name:
+ value = 'request.inputs["{}"][0].file'.format(
+ self._getParamName(name, item)
+ )
else:
- params.append('{}="{}"'.format(name, value))
+ value = 'request.inputs["{}"][0].data'.format(
+ self._getParamName(name, item)
+ )
+ if foundVar or ptype != "string":
+ params.append("{}={}".format(name, value))
+ else:
+ params.append('{}="{}"'.format(name, value))
ret += '"%s"' % task.get_name()
if flags:
@@ -3541,28 +3544,29 @@ def _getPythonActionCmd(self, item, task, cmdIndent, variables={}):
elif ptype == "float":
value = list(map(float, value))
- if (name and value) or (name in parameterizedParams):
- if isinstance(value, list):
- foundVar = False
- for idx in range(len(value)):
- foundVar_, value[idx] = self._substitutePythonParamValue(
- value[idx], name, parameterizedParams, variables, item
- )
- if foundVar_ is True:
- foundVar = True
- else:
- foundVar, value = self._substitutePythonParamValue(
- value, name, parameterizedParams, variables, item
- )
+ if (not name or not value) and name not in parameterizedParams:
+ continue
- if (
- foundVar
- or isinstance(value, list)
- or (ptype != "string" and len(p.get("key_desc", [])) < 2)
- ):
- params.append("{}={}".format(name, value))
- else:
- params.append('{}="{}"'.format(name, value))
+ if isinstance(value, list):
+ foundVar = False
+ for idx in range(len(value)):
+ foundVar_, value[idx] = self._substitutePythonParamValue(
+ value[idx], name, parameterizedParams, variables, item
+ )
+ if foundVar_ is True:
+ foundVar = True
+ else:
+ foundVar, value = self._substitutePythonParamValue(
+ value, name, parameterizedParams, variables, item
+ )
+ if (
+ foundVar
+ or isinstance(value, list)
+ or (ptype != "string" and len(p.get("key_desc", [])) < 2)
+ ):
+ params.append("{}={}".format(name, value))
+ else:
+ params.append('{}="{}"'.format(name, value))
ret += '"%s"' % task.get_name()
if flags:
diff --git a/gui/wxpython/gmodeler/panels.py b/gui/wxpython/gmodeler/panels.py
index c05ce041047..509da20a1b8 100644
--- a/gui/wxpython/gmodeler/panels.py
+++ b/gui/wxpython/gmodeler/panels.py
@@ -530,16 +530,18 @@ def GetOptData(self, dcmd, layer, params, propwin):
data.Update()
# remove dead data items
- if not p.get("value", ""):
- data = layer.FindData(p.get("name", ""))
- if data:
- remList, upList = self.model.RemoveItem(data, layer)
- for item in remList:
- self.canvas.diagram.RemoveShape(item)
- item.__del__() # noqa: PLC2801, C2801
+ if p.get("value", ""):
+ continue
+ data = layer.FindData(p.get("name", ""))
+ if not data:
+ continue
+ remList, upList = self.model.RemoveItem(data, layer)
+ for item in remList:
+ self.canvas.diagram.RemoveShape(item)
+ item.__del__() # noqa: PLC2801, C2801
- for item in upList:
- item.Update()
+ for item in upList:
+ item.Update()
# valid / parameterized ?
layer.SetValid(params)
diff --git a/gui/wxpython/gui_core/dialogs.py b/gui/wxpython/gui_core/dialogs.py
index f79578c47a6..c0f369244c4 100644
--- a/gui/wxpython/gui_core/dialogs.py
+++ b/gui/wxpython/gui_core/dialogs.py
@@ -280,12 +280,11 @@ def GetName(self, full=False):
:param full: True to get fully qualified name
"""
name = self.element.GetValue()
- if full:
- if "@" in name:
- return name
- return name + "@" + grass.gisenv()["MAPSET"]
-
- return name.split("@", 1)[0]
+ if not full:
+ return name.split("@", 1)[0]
+ if "@" in name:
+ return name
+ return name + "@" + grass.gisenv()["MAPSET"]
class NewVectorDialog(VectorDialog):
@@ -532,12 +531,11 @@ def CreateNewVector(
caption=_("Overwrite?"),
style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION,
)
- if dlgOw.ShowModal() == wx.ID_YES:
- overwrite = True
- else:
+ if dlgOw.ShowModal() != wx.ID_YES:
dlgOw.Destroy()
dlg.Destroy()
return None
+ overwrite = True
if UserSettings.Get(group="cmd", key="overwrite", subkey="enabled"):
overwrite = True
diff --git a/gui/wxpython/gui_core/forms.py b/gui/wxpython/gui_core/forms.py
index 14d87728057..4034e6a0f93 100644
--- a/gui/wxpython/gui_core/forms.py
+++ b/gui/wxpython/gui_core/forms.py
@@ -83,6 +83,7 @@
from grass.script import core as grass
from grass.script import task as gtask
+from grass.exceptions import ScriptError
from core import globalvar
from gui_core.widgets import (
@@ -2408,9 +2409,15 @@ def OnCheckItem(index=None, flag=None, event=None):
pSqlWhere.append(p)
# collect ids
- pColumnIds = [p["wxId"] for p in pColumn]
- pLayerIds = [p["wxId"] for p in pLayer]
- pSqlWhereIds = [p["wxId"] for p in pSqlWhere]
+ pColumnIds = []
+ for p in pColumn:
+ pColumnIds += p["wxId"]
+ pLayerIds = []
+ for p in pLayer:
+ pLayerIds += p["wxId"]
+ pSqlWhereIds = []
+ for p in pSqlWhere:
+ pSqlWhereIds += p["wxId"]
# set wxId-bindings
if pMap:
@@ -2773,38 +2780,43 @@ def _switchPage(self, notification):
def OnColorChange(self, event):
myId = event.GetId()
for p in self.task.params:
- if "wxId" in p and myId in p["wxId"]:
- multiple = p["wxId"][1] is not None # multiple colors
- hasTansp = p["wxId"][2] is not None
- if multiple:
- # selected color is added at the end of textCtrl
- colorchooser = wx.FindWindowById(p["wxId"][0])
- new_color = colorchooser.GetValue()[:]
- new_label = utils.rgb2str.get(
- new_color, ":".join(list(map(str, new_color)))
- )
- textCtrl = wx.FindWindowById(p["wxId"][1])
- val = textCtrl.GetValue()
- sep = ","
- if val and val[-1] != sep:
- val += sep
- val += new_label
- textCtrl.SetValue(val)
- p["value"] = val
- elif hasTansp and wx.FindWindowById(p["wxId"][2]).GetValue():
- p["value"] = "none"
- else:
- colorchooser = wx.FindWindowById(p["wxId"][0])
- new_color = colorchooser.GetValue()[:]
- # This is weird: new_color is a 4-tuple and new_color[:] is
- # a 3-tuple under wx2.8.1
- new_label = utils.rgb2str.get(
- new_color, ":".join(list(map(str, new_color)))
- )
- colorchooser.SetLabel(new_label)
- colorchooser.SetColour(new_color)
- colorchooser.Refresh()
- p["value"] = colorchooser.GetLabel()
+ if "wxId" not in p or myId not in p["wxId"]:
+ continue
+
+ multiple = p["wxId"][1] is not None # multiple colors
+ hasTansp = p["wxId"][2] is not None
+ if multiple:
+ # selected color is added at the end of textCtrl
+ colorchooser = wx.FindWindowById(p["wxId"][0])
+ new_color = colorchooser.GetValue()[:]
+ new_label = utils.rgb2str.get(
+ new_color, ":".join(list(map(str, new_color)))
+ )
+ textCtrl = wx.FindWindowById(p["wxId"][1])
+ val = textCtrl.GetValue()
+ sep = ","
+ if val and val[-1] != sep:
+ val += sep
+ val += new_label
+ textCtrl.SetValue(val)
+ p["value"] = val
+
+ continue
+ if hasTansp and wx.FindWindowById(p["wxId"][2]).GetValue():
+ p["value"] = "none"
+ continue
+
+ colorchooser = wx.FindWindowById(p["wxId"][0])
+ new_color = colorchooser.GetValue()[:]
+ # This is weird: new_color is a 4-tuple and new_color[:] is
+ # a 3-tuple under wx2.8.1
+ new_label = utils.rgb2str.get(
+ new_color, ":".join(list(map(str, new_color)))
+ )
+ colorchooser.SetLabel(new_label)
+ colorchooser.SetColour(new_color)
+ colorchooser.Refresh()
+ p["value"] = colorchooser.GetLabel()
self.OnUpdateValues()
def OnUpdateValues(self, event=None):
@@ -2896,25 +2908,24 @@ def OnSetSymbol(self, event):
myId = event.GetId()
for p in self.task.params:
- if "wxId" in p and myId in p["wxId"]:
- from gui_core.dialogs import SymbolDialog
-
- dlg = SymbolDialog(
- self, symbolPath=globalvar.SYMBDIR, currentSymbol=p["value"]
- )
- if dlg.ShowModal() == wx.ID_OK:
- img = dlg.GetSelectedSymbolPath()
- p["value"] = dlg.GetSelectedSymbolName()
-
- bitmapButton = wx.FindWindowById(p["wxId"][0])
- label = wx.FindWindowById(p["wxId"][1])
+ if "wxId" not in p or myId not in p["wxId"]:
+ continue
+ from gui_core.dialogs import SymbolDialog
- bitmapButton.SetBitmapLabel(wx.Bitmap(img + ".png"))
- label.SetLabel(p["value"])
+ dlg = SymbolDialog(
+ self, symbolPath=globalvar.SYMBDIR, currentSymbol=p["value"]
+ )
+ if dlg.ShowModal() == wx.ID_OK:
+ img = dlg.GetSelectedSymbolPath()
+ p["value"] = dlg.GetSelectedSymbolName()
+ bitmapButton = wx.FindWindowById(p["wxId"][0])
+ label = wx.FindWindowById(p["wxId"][1])
+ bitmapButton.SetBitmapLabel(wx.Bitmap(img + ".png"))
+ label.SetLabel(p["value"])
- self.OnUpdateValues(event)
+ self.OnUpdateValues(event)
- dlg.Destroy()
+ dlg.Destroy()
def OnTimelineTool(self, event):
"""Show Timeline Tool with dataset(s) from gselect.
@@ -2925,35 +2936,37 @@ def OnTimelineTool(self, event):
myId = event.GetId()
for p in self.task.params:
- if "wxId" in p and myId in p["wxId"]:
- select = self.FindWindowById(p["wxId"][0])
- if not select.GetValue():
- gcmd.GMessage(parent=self, message=_("No dataset given."))
- return
- datasets = select.GetValue().split(",")
- from timeline import frame
+ if "wxId" not in p or myId not in p["wxId"]:
+ continue
+ select = self.FindWindowById(p["wxId"][0])
+ if not select.GetValue():
+ gcmd.GMessage(parent=self, message=_("No dataset given."))
+ return
+ datasets = select.GetValue().split(",")
+ from timeline import frame
- frame.run(parent=self, datasets=datasets)
+ frame.run(parent=self, datasets=datasets)
def OnSelectFont(self, event):
"""Select font using font dialog"""
myId = event.GetId()
for p in self.task.params:
- if "wxId" in p and myId in p["wxId"]:
- from gui_core.dialogs import DefaultFontDialog
-
- dlg = DefaultFontDialog(
- parent=self,
- title=_("Select font"),
- style=wx.DEFAULT_DIALOG_STYLE,
- type="font",
- )
- if dlg.ShowModal() == wx.ID_OK:
- if dlg.font:
- p["value"] = dlg.font
- self.FindWindowById(p["wxId"][1]).SetValue(dlg.font)
- self.OnUpdateValues(event)
- dlg.Destroy()
+ if "wxId" not in p or myId not in p["wxId"]:
+ continue
+ from gui_core.dialogs import DefaultFontDialog
+
+ dlg = DefaultFontDialog(
+ parent=self,
+ title=_("Select font"),
+ style=wx.DEFAULT_DIALOG_STYLE,
+ type="font",
+ )
+ if dlg.ShowModal() == wx.ID_OK:
+ if dlg.font:
+ p["value"] = dlg.font
+ self.FindWindowById(p["wxId"][1]).SetValue(dlg.font)
+ self.OnUpdateValues(event)
+ dlg.Destroy()
def OnUpdateSelection(self, event):
"""Update dialog (layers, tables, columns, etc.)"""
@@ -3076,7 +3089,7 @@ def ParseCommand(self, cmd, completed=None):
try:
global _blackList
self.grass_task = gtask.parse_interface(cmd[0], blackList=_blackList)
- except (grass.ScriptError, ValueError) as e:
+ except (ScriptError, ValueError) as e:
raise gcmd.GException(e.value)
# if layer parameters previously set, re-insert them into dialog
@@ -3102,32 +3115,34 @@ def ParseCommand(self, cmd, completed=None):
else:
self.grass_task.set_flag(option[1], True)
cmd_validated.append(option)
- else: # parameter
- try:
- key, value = option.split("=", 1)
- except ValueError:
- if self.grass_task.firstParam:
- if i == 0: # add key name of first parameter if not given
- key = self.grass_task.firstParam
- value = option
- else:
- raise gcmd.GException(
- _("Unable to parse command '%s'") % " ".join(cmd)
- )
- else:
- continue
+ continue
- task = self.grass_task.get_param(key, raiseError=False)
- if not task:
- err.append(
- _("%(cmd)s: parameter '%(key)s' not available")
- % {"cmd": cmd[0], "key": key}
- )
+ # parameter
+ try:
+ key, value = option.split("=", 1)
+ except ValueError:
+ if self.grass_task.firstParam:
+ if i == 0: # add key name of first parameter if not given
+ key = self.grass_task.firstParam
+ value = option
+ else:
+ raise gcmd.GException(
+ _("Unable to parse command '%s'") % " ".join(cmd)
+ )
+ else:
continue
- self.grass_task.set_param(key, value)
- cmd_validated.append(key + "=" + value)
- i += 1
+ task = self.grass_task.get_param(key, raiseError=False)
+ if not task:
+ err.append(
+ _("%(cmd)s: parameter '%(key)s' not available")
+ % {"cmd": cmd[0], "key": key}
+ )
+ continue
+
+ self.grass_task.set_param(key, value)
+ cmd_validated.append(key + "=" + value)
+ i += 1
# update original command list
cmd = cmd_validated
@@ -3179,16 +3194,17 @@ def GetCommandInputMapParamKey(self, cmd):
self.grass_task = gtask.processTask(tree).get_task()
for p in self.grass_task.params:
- if p.get("name", "") in {"input", "map"}:
- age = p.get("age", "")
- prompt = p.get("prompt", "")
- element = p.get("element", "")
- if (
- age == "old"
- and element in {"cell", "grid3", "vector"}
- and prompt in {"raster", "raster_3d", "vector"}
- ):
- return p.get("name", None)
+ if p.get("name", "") not in {"input", "map"}:
+ continue
+ age = p.get("age", "")
+ prompt = p.get("prompt", "")
+ element = p.get("element", "")
+ if (
+ age == "old"
+ and (element in {"cell", "grid3", "vector"})
+ and (prompt in {"raster", "raster_3d", "vector"})
+ ):
+ return p.get("name", None)
return None
diff --git a/gui/wxpython/gui_core/goutput.py b/gui/wxpython/gui_core/goutput.py
index 6676eb69935..75a1edb8fea 100644
--- a/gui/wxpython/gui_core/goutput.py
+++ b/gui/wxpython/gui_core/goutput.py
@@ -619,12 +619,13 @@ def AddStyledMessage(self, message, style=None):
for c in message:
if c == "\b":
self.linePos -= 1
- else:
- self.SetCurrentPos(self.linePos)
- self.ReplaceSelection(c)
- self.linePos = self.GetCurrentPos()
- if c != " ":
- last_c = c
+ continue
+
+ self.SetCurrentPos(self.linePos)
+ self.ReplaceSelection(c)
+ self.linePos = self.GetCurrentPos()
+ if c != " ":
+ last_c = c
if last_c not in (digits):
self.AddTextWrapped("\n", wrap=None)
self.linePos = -1
diff --git a/gui/wxpython/gui_core/gselect.py b/gui/wxpython/gui_core/gselect.py
index bcb744d8562..5f6689974f2 100644
--- a/gui/wxpython/gui_core/gselect.py
+++ b/gui/wxpython/gui_core/gselect.py
@@ -596,30 +596,32 @@ def _getElementList(self, element, mapsets=None, elements=None, exclude=False):
sys.stderr.write(_("GSelect: invalid item: %s") % e)
continue
- if self.seltree.ItemHasChildren(mapset_node):
- sel = UserSettings.Get(
- group="appearance", key="elementListExpand", subkey="selection"
- )
- collapse = True
-
- if sel == 0: # collapse all except PERMANENT and current
- if mapset in {"PERMANENT", curr_mapset}:
- collapse = False
- elif sel == 1: # collapse all except PERMANENT
- if mapset == "PERMANENT":
- collapse = False
- elif sel == 2: # collapse all except current
- if mapset == curr_mapset:
- collapse = False
- elif sel == 3: # collapse all
- pass
- elif sel == 4: # expand all
+ if not self.seltree.ItemHasChildren(mapset_node):
+ continue
+
+ sel = UserSettings.Get(
+ group="appearance", key="elementListExpand", subkey="selection"
+ )
+ collapse = True
+
+ if sel == 0: # collapse all except PERMANENT and current
+ if mapset in {"PERMANENT", curr_mapset}:
+ collapse = False
+ elif sel == 1: # collapse all except PERMANENT
+ if mapset == "PERMANENT":
collapse = False
+ elif sel == 2: # collapse all except current
+ if mapset == curr_mapset:
+ collapse = False
+ elif sel == 3: # collapse all
+ pass
+ elif sel == 4: # expand all
+ collapse = False
- if collapse:
- self.seltree.CollapseAllChildren(mapset_node)
- else:
- self.seltree.ExpandAllChildren(mapset_node)
+ if collapse:
+ self.seltree.CollapseAllChildren(mapset_node)
+ else:
+ self.seltree.ExpandAllChildren(mapset_node)
if first_mapset:
# select first mapset (MSW hack)
@@ -637,22 +639,24 @@ def _addItems(self, elist, elements, mapset, exclude, node):
"""
elist = gs.naturally_sorted(elist)
for elem in elist:
- if elem != "":
- fullqElem = elem + "@" + mapset
- if self.filterItems and fullqElem not in self.filterItems:
- continue # skip items missed in self.filterItems
-
- if elements is not None:
- if (exclude and fullqElem in elements) or (
- not exclude and fullqElem not in elements
- ):
- continue
+ if elem == "":
+ continue
- if self.filterElements:
- if self.filterElements(fullqElem):
- self.AddItem(elem, mapset=mapset, node=False, parent=node)
- else:
+ fullqElem = elem + "@" + mapset
+ if self.filterItems and fullqElem not in self.filterItems:
+ continue # skip items missed in self.filterItems
+
+ if elements is not None:
+ if (exclude and fullqElem in elements) or (
+ not exclude and fullqElem not in elements
+ ):
+ continue
+
+ if self.filterElements:
+ if self.filterElements(fullqElem):
self.AddItem(elem, mapset=mapset, node=False, parent=node)
+ else:
+ self.AddItem(elem, mapset=mapset, node=False, parent=node)
def AddItem(self, value, mapset=None, node=True, parent=None):
if not parent:
@@ -2091,20 +2095,21 @@ def GetDsn(self):
connection_string = None
for conn in ret.splitlines():
db_login = conn.split("|")
- if db_login[0] == "pg":
- user, password, host, port = db_login[2:]
- connection_string = (
- f"PG:dbname={self.dbWidgets['choice'].GetStringSelection()}"
- )
- if user:
- connection_string += f" user={user}"
- if password:
- connection_string += f" password={password}"
- if host:
- connection_string += f" host={host}"
- if port:
- connection_string += f" port={port}"
- return connection_string
+ if db_login[0] != "pg":
+ continue
+ user, password, host, port = db_login[2:]
+ connection_string = (
+ f"PG:dbname={self.dbWidgets['choice'].GetStringSelection()}"
+ )
+ if user:
+ connection_string += f" user={user}"
+ if password:
+ connection_string += f" password={password}"
+ if host:
+ connection_string += f" host={host}"
+ if port:
+ connection_string += f" port={port}"
+ return connection_string
if not connection_string:
GError(parent=self, message=message)
return
@@ -2968,26 +2973,26 @@ def _isMapSelected(self):
def _chckMap(self):
"""Check if selected map in 'input' widget is the same as selected map in
lmgr"""
- if self._isMapSelected():
- layerList = self.giface.GetLayerList()
- layerSelected = layerList.GetSelectedLayer()
- # d.vect module
- inputName = self.task.get_param(value="map", raiseError=False)
- if not inputName:
- inputName = self.task.get_param("input")
- if inputName["value"] != str(layerSelected):
- if inputName["value"] == "" or inputName["value"] is None:
- GWarning(_("Input vector map is not selected"))
- return False
- GWarning(
- _(
- "Input vector map <%s> and selected map <%s> in layer manager "
- "are different. Operation canceled."
- )
- % (inputName["value"], str(layerSelected))
- )
- return False
+ if not self._isMapSelected():
+ return False
+ layerList = self.giface.GetLayerList()
+ layerSelected = layerList.GetSelectedLayer()
+ # d.vect module
+ inputName = self.task.get_param(value="map", raiseError=False)
+ if not inputName:
+ inputName = self.task.get_param("input")
+ if inputName["value"] == str(layerSelected):
return True
+ if inputName["value"] == "" or inputName["value"] is None:
+ GWarning(_("Input vector map is not selected"))
+ return False
+ GWarning(
+ _(
+ "Input vector map <%s> and selected map <%s> in layer manager "
+ "are different. Operation canceled."
+ )
+ % (inputName["value"], str(layerSelected))
+ )
return False
def _onClick(self, evt=None):
diff --git a/gui/wxpython/gui_core/menu.py b/gui/wxpython/gui_core/menu.py
index a512b6eea19..2f462625dbd 100644
--- a/gui/wxpython/gui_core/menu.py
+++ b/gui/wxpython/gui_core/menu.py
@@ -62,11 +62,11 @@ def _createMenu(self, node):
label = child.label
subMenu = self._createMenu(child)
menu.AppendMenu(wx.ID_ANY, label, subMenu)
- else:
- data = child.data.copy()
- data.pop("label")
+ continue
+ data = child.data.copy()
+ data.pop("label")
- self._createMenuItem(menu, label=child.label, **data)
+ self._createMenuItem(menu, label=child.label, **data)
return menu
diff --git a/gui/wxpython/gui_core/vselect.py b/gui/wxpython/gui_core/vselect.py
index 206c1dbb43e..cded2aa9be7 100644
--- a/gui/wxpython/gui_core/vselect.py
+++ b/gui/wxpython/gui_core/vselect.py
@@ -30,6 +30,7 @@
from gui_core.wrap import Button, ListCtrl
import grass.script as gs
+from grass.exceptions import ScriptError
from grass.pydispatch.signal import Signal
@@ -302,7 +303,7 @@ def QuerySelectedMap(self):
distance=threshold,
skip_attributes=True,
)
- except gs.ScriptError:
+ except ScriptError:
GError(
parent=self, message=_("Failed to query vector map(s) <%s>.") % self.map
)
diff --git a/gui/wxpython/gui_core/widgets.py b/gui/wxpython/gui_core/widgets.py
index 47bd3a1957c..3c84af4ecbc 100644
--- a/gui/wxpython/gui_core/widgets.py
+++ b/gui/wxpython/gui_core/widgets.py
@@ -183,12 +183,12 @@ def DeletePage(self, page):
:return bool: True if page was deleted, False if not exists
"""
delPageIndex = self.GetPageIndexByName(page)
- if delPageIndex != -1:
- ret = self.classObject.DeletePage(self.widget, delPageIndex)
- if ret:
- del self.notebookPages[page]
- return ret
- return False
+ if delPageIndex == -1:
+ return False
+ ret = self.classObject.DeletePage(self.widget, delPageIndex)
+ if ret:
+ del self.notebookPages[page]
+ return ret
def RemovePage(self, page):
"""Delete page without deleting the associated window.
@@ -197,12 +197,12 @@ def RemovePage(self, page):
:return: True if page was deleted, False if not exists
"""
delPageIndex = self.GetPageIndexByName(page)
- if delPageIndex != -1:
- ret = self.classObject.RemovePage(self.widget, delPageIndex)
- if ret:
- del self.notebookPages[page]
- return ret
- return False
+ if delPageIndex == -1:
+ return False
+ ret = self.classObject.RemovePage(self.widget, delPageIndex)
+ if ret:
+ del self.notebookPages[page]
+ return ret
def SetSelectionByName(self, page):
"""Set active notebook page.
diff --git a/gui/wxpython/iclass/frame.py b/gui/wxpython/iclass/frame.py
index 4bb9e66b6c4..9901ccf3322 100644
--- a/gui/wxpython/iclass/frame.py
+++ b/gui/wxpython/iclass/frame.py
@@ -792,25 +792,25 @@ def ImportClasses(self, vector):
for cat in cats:
listCtrl.AddCategory(cat=cat, name="class_%d" % cat, color="0:0:0")
+
+ return
+
# connection, table and columns exists
- else:
- columns = ["cat", "class", "color"]
- ret = RunCommand(
- "v.db.select",
- quiet=True,
- parent=self,
- flags="c",
- map=vector,
- layer=1,
- columns=",".join(columns),
- read=True,
- )
- records = ret.strip().splitlines()
- for record in records:
- record = record.split("|")
- listCtrl.AddCategory(
- cat=int(record[0]), name=record[1], color=record[2]
- )
+ columns = ["cat", "class", "color"]
+ ret = RunCommand(
+ "v.db.select",
+ quiet=True,
+ parent=self,
+ flags="c",
+ map=vector,
+ layer=1,
+ columns=",".join(columns),
+ read=True,
+ )
+ records = ret.strip().splitlines()
+ for record in records:
+ record = record.split("|")
+ listCtrl.AddCategory(cat=int(record[0]), name=record[1], color=record[2])
def OnExportAreas(self, event):
"""Export training areas"""
diff --git a/gui/wxpython/image2target/ii2t_gis_set.py b/gui/wxpython/image2target/ii2t_gis_set.py
index 1022ef2c9b5..e2b3da9e60d 100644
--- a/gui/wxpython/image2target/ii2t_gis_set.py
+++ b/gui/wxpython/image2target/ii2t_gis_set.py
@@ -345,12 +345,11 @@ def _set_properties(self, version, revision):
sys.stderr.write(
_("ERROR: Location <%s> not found\n") % self.GetRCValue("LOCATION_NAME")
)
- if len(self.listOfLocations) > 0:
- self.lblocations.SetSelection(0, force=True)
- self.lblocations.EnsureVisible(0)
- location = self.listOfLocations[0]
- else:
+ if len(self.listOfLocations) <= 0:
return
+ self.lblocations.SetSelection(0, force=True)
+ self.lblocations.EnsureVisible(0)
+ location = self.listOfLocations[0]
# list of mapsets
self.UpdateMapsets(os.path.join(self.gisdbase, location))
@@ -1111,34 +1110,32 @@ def OnStart(self, event):
ret = dlg.ShowModal()
dlg.Destroy()
- if ret == wx.ID_YES:
- dlg1 = wx.MessageDialog(
- parent=self,
- message=_(
- "ARE YOU REALLY SURE?\n\n"
- "If you really are running another GRASS session doing this "
- "could corrupt your data. Have another look in the processor "
- "manager just to be sure..."
- ),
- caption=_("Lock file found"),
- style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE,
- )
+ if ret != wx.ID_YES:
+ return
- ret = dlg1.ShowModal()
- dlg1.Destroy()
+ dlg1 = wx.MessageDialog(
+ parent=self,
+ message=_(
+ "ARE YOU REALLY SURE?\n\n"
+ "If you really are running another GRASS session doing this "
+ "could corrupt your data. Have another look in the processor "
+ "manager just to be sure..."
+ ),
+ caption=_("Lock file found"),
+ style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE,
+ )
+ ret = dlg1.ShowModal()
+ dlg1.Destroy()
- if ret == wx.ID_YES:
- try:
- os.remove(lockfile)
- except OSError as e:
- GError(
- _("Unable to remove '%(lock)s'.\n\nDetails: %(reason)s")
- % {"lock": lockfile, "reason": e}
- )
- else:
- return
- else:
+ if ret != wx.ID_YES:
return
+ try:
+ os.remove(lockfile)
+ except OSError as e:
+ GError(
+ _("Unable to remove '%(lock)s'.\n\nDetails: %(reason)s")
+ % {"lock": lockfile, "reason": e}
+ )
self.SetLocation(dbase, location, mapset)
self.ExitSuccessfully()
diff --git a/gui/wxpython/image2target/ii2t_manager.py b/gui/wxpython/image2target/ii2t_manager.py
index 97d528bcf7d..183537519e0 100644
--- a/gui/wxpython/image2target/ii2t_manager.py
+++ b/gui/wxpython/image2target/ii2t_manager.py
@@ -910,9 +910,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None:
flags="g",
)
- if ret:
- self.parent.src_maps = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -922,6 +920,7 @@ def OnEnterPage(self, event: WizardEvent | None = None) -> None:
% self.parent.grouppage.xygroup,
)
return
+ self.parent.src_maps = ret.splitlines()
elif maptype == "vector":
grassdatabase = self.parent.grassdatabase
@@ -1703,7 +1702,7 @@ def OnRMS(self, event):
targetMapWin = self.TgtMapWindow
targetMapWin.UpdateMap(render=False, renderVector=False)
- def CheckGCPcount(self, msg=False):
+ def CheckGCPcount(self, msg: bool = False) -> bool:
"""
Checks to make sure that the minimum number of GCPs have been defined and
are active for the selected transformation order
@@ -1725,9 +1724,10 @@ def CheckGCPcount(self, msg=False):
)
% self.gr_order,
)
- return False
- else:
- return True
+
+ return False
+
+ return True
def OnGeorect(self, event):
"""
@@ -1959,9 +1959,7 @@ def RMSError(self, xygroup, order):
self.grwiz.SwitchEnv("target")
- if ret:
- errlist = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -1970,6 +1968,7 @@ def RMSError(self, xygroup, order):
),
)
return
+ errlist = ret.splitlines()
# insert error values into GCP list for checked items
sdfactor = float(UserSettings.Get(group="gcpman", key="rms", subkey="sdfactor"))
@@ -2000,12 +1999,13 @@ def RMSError(self, xygroup, order):
sumsq_bkw_err += float(bkw_err) ** 2
sum_fwd_err += float(fwd_err)
GCPcount += 1
- else:
- self.list.SetItem(index, 7, "")
- self.list.SetItem(index, 8, "")
- self.mapcoordlist[key][7] = 0.0
- self.mapcoordlist[key][8] = 0.0
- self.list.SetItemTextColour(index, wx.BLACK)
+ continue
+
+ self.list.SetItem(index, 7, "")
+ self.list.SetItem(index, 8, "")
+ self.mapcoordlist[key][7] = 0.0
+ self.mapcoordlist[key][8] = 0.0
+ self.list.SetItemTextColour(index, wx.BLACK)
# SD
if GCPcount > 0:
@@ -2093,9 +2093,7 @@ def GetNewExtent(self, region, map=None):
self.grwiz.SwitchEnv("target")
- if ret:
- errlist = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -2104,6 +2102,7 @@ def GetNewExtent(self, region, map=None):
),
)
return
+ errlist = ret.splitlines()
# fist corner
e, n = errlist[0].split()
diff --git a/gui/wxpython/iscatt/controllers.py b/gui/wxpython/iscatt/controllers.py
index f87569b2698..873ddf02071 100644
--- a/gui/wxpython/iscatt/controllers.py
+++ b/gui/wxpython/iscatt/controllers.py
@@ -957,16 +957,15 @@ def SetData(self):
bands = []
while True:
- if dlg.ShowModal() == wx.ID_OK:
- bands = dlg.GetGroupBandsErr(parent=self.scatt_mgr.guiparent)
- if bands:
- name, s = dlg.GetData()
- group = gs.find_file(name=name, element="group")
- self.set_g["group"] = group["name"]
- self.set_g["subg"] = s
-
- break
- else:
+ if dlg.ShowModal() != wx.ID_OK:
+ break
+ bands = dlg.GetGroupBandsErr(parent=self.scatt_mgr.guiparent)
+ if bands:
+ name, s = dlg.GetData()
+ group = gs.find_file(name=name, element="group")
+ self.set_g["group"] = group["name"]
+ self.set_g["subg"] = s
+
break
dlg.Destroy()
diff --git a/gui/wxpython/iscatt/frame.py b/gui/wxpython/iscatt/frame.py
index 542d8acc2c3..46a4f1c6547 100644
--- a/gui/wxpython/iscatt/frame.py
+++ b/gui/wxpython/iscatt/frame.py
@@ -694,16 +694,15 @@ def OnRename(self, event):
dlg.CentreOnParent()
while True:
- if dlg.ShowModal() == wx.ID_OK:
- name = dlg.GetNewName().strip()
- if not name:
- GMessage(parent=self, message=_("Empty name was inserted."))
- else:
- self.cats_mgr.SetCategoryAttrs(cat_id, {"name": name})
- break
- else:
+ if dlg.ShowModal() != wx.ID_OK:
break
+ name = dlg.GetNewName().strip()
+ if name:
+ self.cats_mgr.SetCategoryAttrs(cat_id, {"name": name})
+ break
+ GMessage(parent=self, message=_("Empty name was inserted."))
+
dlg.Destroy()
def _setCatAttrs(self, cat_id, attrs):
diff --git a/gui/wxpython/lmgr/workspace.py b/gui/wxpython/lmgr/workspace.py
index 7971e3c4064..395fd0b61a5 100644
--- a/gui/wxpython/lmgr/workspace.py
+++ b/gui/wxpython/lmgr/workspace.py
@@ -317,35 +317,37 @@ def Load(self, filename):
for overlay in gxwXml.overlays:
# overlay["cmd"][0] name of command e.g. d.barscale, d.legend
# overlay["cmd"][1:] parameters and flags
- if overlay["display"] == i:
- if overlay["cmd"][0] == "d.legend.vect":
- mapdisplay[i].AddLegendVect(overlay["cmd"])
- if overlay["cmd"][0] == "d.legend":
- mapdisplay[i].AddLegendRast(overlay["cmd"])
- if overlay["cmd"][0] == "d.barscale":
- mapdisplay[i].AddBarscale(overlay["cmd"])
- if overlay["cmd"][0] == "d.northarrow":
- mapdisplay[i].AddArrow(overlay["cmd"])
- if overlay["cmd"][0] == "d.text":
- mapdisplay[i].AddDtext(overlay["cmd"])
+ if overlay["display"] != i:
+ continue
+ if overlay["cmd"][0] == "d.legend.vect":
+ mapdisplay[i].AddLegendVect(overlay["cmd"])
+ if overlay["cmd"][0] == "d.legend":
+ mapdisplay[i].AddLegendRast(overlay["cmd"])
+ if overlay["cmd"][0] == "d.barscale":
+ mapdisplay[i].AddBarscale(overlay["cmd"])
+ if overlay["cmd"][0] == "d.northarrow":
+ mapdisplay[i].AddArrow(overlay["cmd"])
+ if overlay["cmd"][0] == "d.text":
+ mapdisplay[i].AddDtext(overlay["cmd"])
# avoid double-rendering when loading workspace
# mdisp.MapWindow2D.UpdateMap()
# nviz
- if gxwXml.displays[i]["viewMode"] == "3d":
- mapdisplay[i].AddNviz()
- self.lmgr.nvizUpdateState(
- view=gxwXml.nviz_state["view"],
- iview=gxwXml.nviz_state["iview"],
- light=gxwXml.nviz_state["light"],
- )
- mapdisplay[i].MapWindow3D.constants = gxwXml.nviz_state["constants"]
- for idx, constant in enumerate(mapdisplay[i].MapWindow3D.constants):
- mapdisplay[i].MapWindow3D.AddConstant(constant, i + 1)
- for page in ("view", "light", "fringe", "constant", "cplane"):
- self.lmgr.nvizUpdatePage(page)
- self.lmgr.nvizUpdateSettings()
- mapdisplay[i].toolbars["map"].combo.SetSelection(1)
+ if gxwXml.displays[i]["viewMode"] != "3d":
+ continue
+ mapdisplay[i].AddNviz()
+ self.lmgr.nvizUpdateState(
+ view=gxwXml.nviz_state["view"],
+ iview=gxwXml.nviz_state["iview"],
+ light=gxwXml.nviz_state["light"],
+ )
+ mapdisplay[i].MapWindow3D.constants = gxwXml.nviz_state["constants"]
+ for idx, constant in enumerate(mapdisplay[i].MapWindow3D.constants):
+ mapdisplay[i].MapWindow3D.AddConstant(constant, i + 1)
+ for page in ("view", "light", "fringe", "constant", "cplane"):
+ self.lmgr.nvizUpdatePage(page)
+ self.lmgr.nvizUpdateSettings()
+ mapdisplay[i].toolbars["map"].combo.SetSelection(1)
#
# load layout
diff --git a/gui/wxpython/location_wizard/dialogs.py b/gui/wxpython/location_wizard/dialogs.py
index 74a59cca525..6573aeb717a 100644
--- a/gui/wxpython/location_wizard/dialogs.py
+++ b/gui/wxpython/location_wizard/dialogs.py
@@ -50,9 +50,7 @@ def __init__(
self.parent = parent
self.location = location
- #
# default values
- #
# 2D
self.north = 1.0
self.south = 0.0
@@ -67,9 +65,7 @@ def __init__(
# self.ewres3 = 1.0
self.tbres = 1.0
- #
# inputs
- #
# 2D
self.tnorth = self.MakeTextCtrl(
text=str(self.north), size=(150, -1), parent=panel
@@ -80,43 +76,26 @@ def __init__(
self.tnsres = self.MakeTextCtrl(str(self.nsres), size=(150, -1), parent=panel)
self.tewres = self.MakeTextCtrl(str(self.ewres), size=(150, -1), parent=panel)
- #
# labels
- #
self.lrows = self.MakeLabel(parent=panel)
self.lcols = self.MakeLabel(parent=panel)
self.lcells = self.MakeLabel(parent=panel)
- #
# buttons
- #
self.bset = self.MakeButton(text=_("&Set region"), id=wx.ID_OK, parent=panel)
self.bcancel = Button(panel, id=wx.ID_CANCEL)
self.bset.SetDefault()
- #
# image
- #
self.img = wx.Image(
os.path.join(globalvar.IMGDIR, "qgis_world.png"), wx.BITMAP_TYPE_PNG
).ConvertToBitmap()
- #
# set current working environment to PERMANENT mapset
# in selected location in order to set default region (WIND)
- #
envval = {}
ret = RunCommand("g.gisenv", read=True)
- if ret:
- for line in ret.splitlines():
- key, val = line.split("=")
- envval[key] = val
- self.currlocation = envval["LOCATION_NAME"].strip("';")
- self.currmapset = envval["MAPSET"].strip("';")
- if self.currlocation != self.location or self.currmapset != "PERMANENT":
- RunCommand("g.gisenv", set="LOCATION_NAME=%s" % self.location)
- RunCommand("g.gisenv", set="MAPSET=PERMANENT")
- else:
+ if not ret:
dlg = wx.MessageBox(
parent=self,
message=_("Invalid location selected."),
@@ -124,17 +103,19 @@ def __init__(
style=wx.ID_OK | wx.ICON_ERROR,
)
return
+ for line in ret.splitlines():
+ key, val = line.split("=")
+ envval[key] = val
+ self.currlocation = envval["LOCATION_NAME"].strip("';")
+ self.currmapset = envval["MAPSET"].strip("';")
+ if self.currlocation != self.location or self.currmapset != "PERMANENT":
+ RunCommand("g.gisenv", set="LOCATION_NAME=%s" % self.location)
+ RunCommand("g.gisenv", set="MAPSET=PERMANENT")
- #
# get current region settings
- #
region = {}
ret = RunCommand("g.region", read=True, flags="gp3")
- if ret:
- for line in ret.splitlines():
- key, val = line.split("=")
- region[key] = float(val)
- else:
+ if not ret:
dlg = wx.MessageBox(
parent=self,
message=_("Invalid region"),
@@ -144,8 +125,10 @@ def __init__(
dlg.ShowModal()
dlg.Destroy()
return
+ for line in ret.splitlines():
+ key, val = line.split("=")
+ region[key] = float(val)
- #
# update values
# 2D
self.north = float(region["n"])
@@ -166,9 +149,7 @@ def __init__(
self.depth = int(region["depths"])
self.cells3 = int(region["cells3"])
- #
# 3D box collapsible
- #
self.infoCollapseLabelExp = _("Click here to show 3D settings")
self.infoCollapseLabelCol = _("Click here to hide 3D settings")
self.settings3D = wx.CollapsiblePane(
@@ -184,9 +165,7 @@ def __init__(
self.settings3D,
)
- #
# set current region settings
- #
self.tnorth.SetValue(str(self.north))
self.tsouth.SetValue(str(self.south))
self.twest.SetValue(str(self.west))
@@ -202,9 +181,7 @@ def __init__(
self.lcols.SetLabel(_("Cols: %d") % self.cols)
self.lcells.SetLabel(_("Cells: %d") % self.cells)
- #
# bindings
- #
self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset)
self.Bind(wx.EVT_BUTTON, self.OnCancel, self.bcancel)
self.tnorth.Bind(wx.EVT_TEXT, self.OnValue)
diff --git a/gui/wxpython/location_wizard/wizard.py b/gui/wxpython/location_wizard/wizard.py
index 885b80a26a5..39d1bf7fea4 100644
--- a/gui/wxpython/location_wizard/wizard.py
+++ b/gui/wxpython/location_wizard/wizard.py
@@ -73,7 +73,7 @@
)
from location_wizard.dialogs import SelectTransformDialog
-from grass.exceptions import OpenError
+from grass.exceptions import OpenError, ScriptError
from grass.grassdb.checks import location_exists
from grass.script import core as grass
from grass.script import decode
@@ -2739,7 +2739,7 @@ def OnWizFinished(self):
desc=self.startpage.locTitle,
)
- except grass.ScriptError as e:
+ except ScriptError as e:
return e.value
return None
diff --git a/gui/wxpython/mapdisp/frame.py b/gui/wxpython/mapdisp/frame.py
index 52eae9f6224..45dd4f52109 100644
--- a/gui/wxpython/mapdisp/frame.py
+++ b/gui/wxpython/mapdisp/frame.py
@@ -64,6 +64,7 @@
import grass.script as gs
from grass.pydispatch.signal import Signal
+from grass.exceptions import ScriptError
if TYPE_CHECKING:
import lmgr.frame
@@ -1103,7 +1104,7 @@ def QueryMap(self, east, north, qdist, rast, vect):
encoding=encoding,
multiple=True,
)
- except gs.ScriptError:
+ except ScriptError:
GError(
parent=self,
message=_(
@@ -1216,23 +1217,23 @@ def AddTmpVectorMapLayer(
cmd[-1].append("layer=%d" % layer)
cmd[-1].append("cats=%s" % ListOfCatsToRange(lcats))
- if addLayer:
- args = {}
- if useId:
- args["ltype"] = "vector"
- else:
- args["ltype"] = "command"
-
- return self.Map.AddLayer(
- name=globalvar.QUERYLAYER,
- command=cmd,
- active=True,
- hidden=True,
- opacity=1.0,
- render=True,
- **args,
- )
- return cmd
+ if not addLayer:
+ return cmd
+
+ args = {}
+ if useId:
+ args["ltype"] = "vector"
+ else:
+ args["ltype"] = "command"
+ return self.Map.AddLayer(
+ name=globalvar.QUERYLAYER,
+ command=cmd,
+ active=True,
+ hidden=True,
+ opacity=1.0,
+ render=True,
+ **args,
+ )
def OnMeasureDistance(self, event):
self._onMeasure(MeasureDistanceController)
diff --git a/gui/wxpython/mapdisp/main.py b/gui/wxpython/mapdisp/main.py
index 76ae6218d5a..42f47e2dfd8 100644
--- a/gui/wxpython/mapdisp/main.py
+++ b/gui/wxpython/mapdisp/main.py
@@ -216,24 +216,26 @@ def GetLayersFromCmdFile(self):
exists = False
for i, layer in enumerate(existingLayers):
- if layer.GetCmd(string=True) == utils.GetCmdString(
+ if layer.GetCmd(string=True) != utils.GetCmdString(
cmdlist_to_tuple(cmd)
):
- exists = True
-
- if layersOrder[i] == -1:
- layersOrder[i] = next_layer
- next_layer += 1
- # layer must be put higher in render order (same cmd was
- # insered more times)
- # TODO delete rendurant cmds from cmd file?
- else:
- for j, l_order in enumerate(layersOrder):
- if l_order > layersOrder[i]:
- layersOrder[j] -= 1
- layersOrder[i] = next_layer - 1
-
- break
+ continue
+
+ exists = True
+
+ if layersOrder[i] == -1:
+ layersOrder[i] = next_layer
+ next_layer += 1
+ # layer must be put higher in render order (same cmd was
+ # insered more times)
+ # TODO delete rendurant cmds from cmd file?
+ else:
+ for j, l_order in enumerate(layersOrder):
+ if l_order > layersOrder[i]:
+ layersOrder[j] -= 1
+ layersOrder[i] = next_layer - 1
+
+ break
if exists:
continue
diff --git a/gui/wxpython/mapdisp/statusbar.py b/gui/wxpython/mapdisp/statusbar.py
index 7e60e762281..ae0b3b832d0 100644
--- a/gui/wxpython/mapdisp/statusbar.py
+++ b/gui/wxpython/mapdisp/statusbar.py
@@ -626,11 +626,11 @@ def GetCenterString(self, map):
projOut=projection,
flags="d",
)
- if coord:
- if proj in {"ll", "latlong", "longlat"} and format == "DMS":
- return "%s" % utils.Deg2DMS(coord[0], coord[1], precision=precision)
- return "%.*f; %.*f" % (precision, coord[0], precision, coord[1])
- raise SbException(_("Error in projection (check the settings)"))
+ if not coord:
+ raise SbException(_("Error in projection (check the settings)"))
+ if proj in {"ll", "latlong", "longlat"} and format == "DMS":
+ return "%s" % utils.Deg2DMS(coord[0], coord[1], precision=precision)
+ return "%.*f; %.*f" % (precision, coord[0], precision, coord[1])
if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS":
return "%s" % utils.Deg2DMS(
region["center_easting"],
@@ -786,23 +786,21 @@ def ReprojectENFromMap(self, e, n, useDefinedProjection, precision, format):
@throws SbException if useDefinedProjection is True and projection is not
defined in UserSettings
"""
- if useDefinedProjection:
- settings = UserSettings.Get(
- group="projection", key="statusbar", subkey="proj4"
- )
- if not settings:
- raise SbException(_("Projection not defined (check the settings)"))
- # reproject values
- proj, coord = utils.ReprojectCoordinates(
- coord=(e, n), projOut=settings, flags="d"
- )
- if coord:
- e, n = coord
- if proj in {"ll", "latlong", "longlat"} and format == "DMS":
- return utils.Deg2DMS(e, n, precision=precision)
- return "%.*f; %.*f" % (precision, e, precision, n)
+ if not useDefinedProjection:
+ if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS":
+ return utils.Deg2DMS(e, n, precision=precision)
+ return "%.*f; %.*f" % (precision, e, precision, n)
+ settings = UserSettings.Get(group="projection", key="statusbar", subkey="proj4")
+ if not settings:
+ raise SbException(_("Projection not defined (check the settings)"))
+ # reproject values
+ proj, coord = utils.ReprojectCoordinates(
+ coord=(e, n), projOut=settings, flags="d"
+ )
+ if not coord:
raise SbException(_("Error in projection (check the settings)"))
- if self.mapFrame.GetMap().projinfo["proj"] == "ll" and format == "DMS":
+ e, n = coord
+ if proj in {"ll", "latlong", "longlat"} and format == "DMS":
return utils.Deg2DMS(e, n, precision=precision)
return "%.*f; %.*f" % (precision, e, precision, n)
diff --git a/gui/wxpython/mapwin/buffered.py b/gui/wxpython/mapwin/buffered.py
index a808875f2a8..bdeeaf1314c 100644
--- a/gui/wxpython/mapwin/buffered.py
+++ b/gui/wxpython/mapwin/buffered.py
@@ -797,18 +797,19 @@ def GetOverlay(self):
imgs = []
for overlay in self.Map.GetListOfLayers(ltype="overlay", active=True):
if (
- overlay.mapfile is not None
- and os.path.isfile(overlay.mapfile)
- and os.path.getsize(overlay.mapfile)
+ overlay.mapfile is None
+ or not os.path.isfile(overlay.mapfile)
+ or (not os.path.getsize(overlay.mapfile))
):
- img = utils.autoCropImageFromFile(overlay.mapfile)
+ continue
+ img = utils.autoCropImageFromFile(overlay.mapfile)
- for key in list(self.imagedict.keys()):
- if self.imagedict[key]["id"] == overlay.id:
- del self.imagedict[key]
+ for key in list(self.imagedict.keys()):
+ if self.imagedict[key]["id"] == overlay.id:
+ del self.imagedict[key]
- self.imagedict[img] = {"id": overlay.id, "layer": overlay}
- imgs.append(img)
+ self.imagedict[img] = {"id": overlay.id, "layer": overlay}
+ imgs.append(img)
return imgs
@@ -1214,23 +1215,17 @@ def DrawLines(self, pdc=None, polycoords=None):
if not polycoords:
polycoords = self.polycoords
- if len(polycoords) > 0:
- self.plineid = wx.ID_NEW + 1
- # convert from EN to XY
- coords = []
- for p in polycoords:
- coords.append(self.Cell2Pixel(p))
-
- self.Draw(pdc, drawid=self.plineid, pdctype="polyline", coords=coords)
-
- Debug.msg(
- 4,
- "BufferedWindow.DrawLines(): coords=%s, id=%s" % (coords, self.plineid),
- )
-
- return self.plineid
-
- return -1
+ if len(polycoords) <= 0:
+ return -1
+ self.plineid = wx.ID_NEW + 1
+ # convert from EN to XY
+ coords = [self.Cell2Pixel(p) for p in polycoords]
+ self.Draw(pdc, drawid=self.plineid, pdctype="polyline", coords=coords)
+ Debug.msg(
+ 4,
+ "BufferedWindow.DrawLines(): coords=%s, id=%s" % (coords, self.plineid),
+ )
+ return self.plineid
def DrawPolylines(self, pdc, coords, pen, drawid=None):
"""Draw polyline in PseudoDC.
diff --git a/gui/wxpython/modules/extensions.py b/gui/wxpython/modules/extensions.py
index 7837a92589d..9d65b8431a3 100644
--- a/gui/wxpython/modules/extensions.py
+++ b/gui/wxpython/modules/extensions.py
@@ -383,23 +383,25 @@ def Load(self, url, full=True):
currentNode.data = {"command": value}
elif currentNode is not None:
currentNode.data[key] = value
- else:
- try:
- prefix, name = line.strip().split(".", 1)
- except ValueError:
- prefix = ""
- name = line.strip()
-
- if self._expandPrefix(prefix) == prefix:
- prefix = ""
- module = prefix + "." + name
- mainNode = self.mainNodes[self._expandPrefix(prefix)]
- currentNode = self.model.AppendNode(parent=mainNode, label=module)
- currentNode.data = {
- "command": module,
- "keywords": "",
- "description": "",
- }
+
+ continue
+
+ try:
+ prefix, name = line.strip().split(".", 1)
+ except ValueError:
+ prefix = ""
+ name = line.strip()
+
+ if self._expandPrefix(prefix) == prefix:
+ prefix = ""
+ module = prefix + "." + name
+ mainNode = self.mainNodes[self._expandPrefix(prefix)]
+ currentNode = self.model.AppendNode(parent=mainNode, label=module)
+ currentNode.data = {
+ "command": module,
+ "keywords": "",
+ "description": "",
+ }
class ManageExtensionWindow(wx.Frame):
diff --git a/gui/wxpython/modules/import_export.py b/gui/wxpython/modules/import_export.py
index d83d468facf..2c160830689 100644
--- a/gui/wxpython/modules/import_export.py
+++ b/gui/wxpython/modules/import_export.py
@@ -398,13 +398,12 @@ def _getLayersToReprojetion(self, projMatch_idx, grassName_idx):
ret = dlg.ShowModal()
- if ret == wx.ID_OK:
- # do not import unchecked layers
- for itm in reversed(list(dlg.GetData(checked=False))):
- idx = itm[-1]
- layers.pop(idx)
- else:
+ if ret != wx.ID_OK:
return None
+ # do not import unchecked layers
+ for itm in reversed(list(dlg.GetData(checked=False))):
+ idx = itm[-1]
+ layers.pop(idx)
return layers
diff --git a/gui/wxpython/nviz/animation.py b/gui/wxpython/nviz/animation.py
index 1eeb8d1aea8..fbc4bbed761 100644
--- a/gui/wxpython/nviz/animation.py
+++ b/gui/wxpython/nviz/animation.py
@@ -196,26 +196,25 @@ def SaveAnimationFile(self, path, prefix, format):
self.currentFrame = 0
self.mode = "save"
for params in self.animationList:
- if not self.stopSaving:
- self.UpdateView(params)
- number = ("{frame" + formatter + "}").format(frame=self.currentFrame)
- filename = "{prefix}_{number}.{ext}".format(
- prefix=prefix, number=number, ext=self.formats[format]
- )
- filepath = os.path.join(path, filename)
- self.mapWindow.SaveToFile(
- FileName=filepath,
- FileType=self.formats[format],
- width=size[0],
- height=size[1],
- )
- self.currentFrame += 1
-
- wx.GetApp().Yield()
- toolWin.UpdateFrameIndex(index=self.currentFrame, goToFrame=False)
- else:
+ if self.stopSaving:
self.stopSaving = False
break
+ self.UpdateView(params)
+ number = ("{frame" + formatter + "}").format(frame=self.currentFrame)
+ filename = "{prefix}_{number}.{ext}".format(
+ prefix=prefix, number=number, ext=self.formats[format]
+ )
+ filepath = os.path.join(path, filename)
+ self.mapWindow.SaveToFile(
+ FileName=filepath,
+ FileType=self.formats[format],
+ width=size[0],
+ height=size[1],
+ )
+ self.currentFrame += 1
+
+ wx.GetApp().Yield()
+ toolWin.UpdateFrameIndex(index=self.currentFrame, goToFrame=False)
self.animationSaved = True
self.PostFinishedEvent()
diff --git a/gui/wxpython/nviz/mapwindow.py b/gui/wxpython/nviz/mapwindow.py
index b3f05ed6f04..2b716ef2131 100644
--- a/gui/wxpython/nviz/mapwindow.py
+++ b/gui/wxpython/nviz/mapwindow.py
@@ -2595,16 +2595,18 @@ def NvizCmdCommand(self):
cmdLColor += "%s," % nvizData["lines"]["color"]["value"]
cmdLMode += "%s," % nvizData["lines"]["mode"]["type"]
cmdLPos += "0,0,%d," % nvizData["lines"]["height"]["value"]
- if (vInfo["points"] + vInfo["centroids"]) > 0:
- cmdPoints += (
- "%s," % self.tree.GetLayerInfo(vector, key="maplayer").GetName()
- )
- cmdPWidth += "%d," % nvizData["points"]["width"]["value"]
- cmdPSize += "%d," % nvizData["points"]["size"]["value"]
- cmdPColor += "%s," % nvizData["points"]["color"]["value"]
- cmdPMarker += "%s," % markers[nvizData["points"]["marker"]["value"]]
- cmdPPos += "0,0,%d," % nvizData["points"]["height"]["value"]
- cmdPLayer += "1,1,"
+ if vInfo["points"] + vInfo["centroids"] <= 0:
+ continue
+ cmdPoints += (
+ "%s," % self.tree.GetLayerInfo(vector, key="maplayer").GetName()
+ )
+ cmdPWidth += "%d," % nvizData["points"]["width"]["value"]
+ cmdPSize += "%d," % nvizData["points"]["size"]["value"]
+ cmdPColor += "%s," % nvizData["points"]["color"]["value"]
+ cmdPMarker += "%s," % markers[nvizData["points"]["marker"]["value"]]
+ cmdPPos += "0,0,%d," % nvizData["points"]["height"]["value"]
+ cmdPLayer += "1,1,"
+
if cmdLines:
cmd += "vline=" + cmdLines.strip(",") + " "
cmd += "vline_width=" + cmdLWidth.strip(",") + " "
diff --git a/gui/wxpython/nviz/tools.py b/gui/wxpython/nviz/tools.py
index f43de80944d..e398000ac00 100644
--- a/gui/wxpython/nviz/tools.py
+++ b/gui/wxpython/nviz/tools.py
@@ -5457,18 +5457,19 @@ def UpdateVectorPage(self, layer, data, updateName=True):
display.SetSelection(1)
else:
display.SetSelection(0)
- if data[vtype]["mode"]["type"] == "surface":
- rasters = self.mapWindow.GetLayerNames("raster")
- constants = self.mapWindow.GetLayerNames("constant")
- surfaces = rasters + constants
- surfaceWin = self.FindWindowById(self.win["vector"][vtype]["surface"])
- surfaceWin.SetItems(surfaces)
- for idx, surface in enumerate(surfaces):
- try: # TODO fix this mess
- selected = data[vtype]["mode"]["surface"]["show"][idx]
- except (TypeError, IndexError, KeyError):
- selected = False
- surfaceWin.Check(idx, selected)
+ if data[vtype]["mode"]["type"] != "surface":
+ continue
+ rasters = self.mapWindow.GetLayerNames("raster")
+ constants = self.mapWindow.GetLayerNames("constant")
+ surfaces = rasters + constants
+ surfaceWin = self.FindWindowById(self.win["vector"][vtype]["surface"])
+ surfaceWin.SetItems(surfaces)
+ for idx, surface in enumerate(surfaces):
+ try: # TODO fix this mess
+ selected = data[vtype]["mode"]["surface"]["show"][idx]
+ except (TypeError, IndexError, KeyError):
+ selected = False
+ surfaceWin.Check(idx, selected)
for type in ("slider", "text"):
win = self.FindWindowById(self.win["vector"]["lines"]["height"][type])
diff --git a/gui/wxpython/nviz/wxnviz.py b/gui/wxpython/nviz/wxnviz.py
index d4875212343..0c52eb14c15 100644
--- a/gui/wxpython/nviz/wxnviz.py
+++ b/gui/wxpython/nviz/wxnviz.py
@@ -467,13 +467,13 @@ def GetFocus(
) -> tuple[float, float, float] | tuple[Literal[-1], Literal[-1], Literal[-1]]:
"""Get focus"""
Debug.msg(3, "Nviz::GetFocus()")
- if Nviz_has_focus(self.data):
- x = c_float()
- y = c_float()
- z = c_float()
- Nviz_get_focus(self.data, byref(x), byref(y), byref(z))
- return x.value, y.value, z.value
- return (-1, -1, -1)
+ if not Nviz_has_focus(self.data):
+ return (-1, -1, -1)
+ x = c_float()
+ y = c_float()
+ z = c_float()
+ Nviz_get_focus(self.data, byref(x), byref(y), byref(z))
+ return (x.value, y.value, z.value)
def SetFocus(self, x: float, y: float, z: float) -> None:
"""Set focus"""
diff --git a/gui/wxpython/photo2image/ip2i_manager.py b/gui/wxpython/photo2image/ip2i_manager.py
index f7a43bbcf6b..1c5206de67a 100644
--- a/gui/wxpython/photo2image/ip2i_manager.py
+++ b/gui/wxpython/photo2image/ip2i_manager.py
@@ -1048,7 +1048,7 @@ def OnRMS(self, event):
targetMapWin = self.TgtMapWindow
targetMapWin.UpdateMap(render=False)
- def CheckGCPcount(self, msg=False):
+ def CheckGCPcount(self, msg: bool = False) -> bool:
"""
Checks to make sure that the minimum number of GCPs have been defined and
are active for the selected transformation order
@@ -1070,9 +1070,10 @@ def CheckGCPcount(self, msg=False):
)
% self.gr_order,
)
- return False
- else:
- return True
+
+ return False
+
+ return True
def OnGeorect(self, event):
"""
@@ -1266,9 +1267,7 @@ def RMSError(self, xygroup, order):
self.grwiz.SwitchEnv("target")
- if ret:
- errlist = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -1276,6 +1275,7 @@ def RMSError(self, xygroup, order):
),
)
return
+ errlist = ret.splitlines()
# insert error values into GCP list for checked items
sdfactor = float(UserSettings.Get(group="gcpman", key="rms", subkey="sdfactor"))
@@ -1306,12 +1306,13 @@ def RMSError(self, xygroup, order):
sumsq_bkw_err += float(bkw_err) ** 2
sum_fwd_err += float(fwd_err)
GCPcount += 1
- else:
- self.list.SetItem(index, 5, "")
- self.list.SetItem(index, 6, "")
- self.mapcoordlist[key][5] = 0.0
- self.mapcoordlist[key][6] = 0.0
- self.list.SetItemTextColour(index, wx.BLACK)
+
+ continue
+ self.list.SetItem(index, 5, "")
+ self.list.SetItem(index, 6, "")
+ self.mapcoordlist[key][5] = 0.0
+ self.mapcoordlist[key][6] = 0.0
+ self.list.SetItemTextColour(index, wx.BLACK)
# SD
if GCPcount > 0:
@@ -1401,9 +1402,7 @@ def GetNewExtent(self, region, map=None):
self.grwiz.SwitchEnv("target")
- if ret:
- errlist = ret.splitlines()
- else:
+ if not ret:
GError(
parent=self,
message=_(
@@ -1411,6 +1410,7 @@ def GetNewExtent(self, region, map=None):
),
)
return
+ errlist = ret.splitlines()
# fist corner
e, n = errlist[0].split()
diff --git a/gui/wxpython/psmap/dialogs.py b/gui/wxpython/psmap/dialogs.py
index 41ae0bbceb7..bb76213b2bf 100644
--- a/gui/wxpython/psmap/dialogs.py
+++ b/gui/wxpython/psmap/dialogs.py
@@ -51,6 +51,7 @@
from wx import PyValidator as Validator
import grass.script as gs
+from grass.exceptions import ScriptError
from core.gcmd import GError, GMessage, RunCommand
from core.utils import PilImageToWxImage, cmp
from dbmgr.vinfo import VectorDBInfo
@@ -1394,138 +1395,114 @@ def update(self):
mapFrameDict["scaleType"] = scaleType
if mapFrameDict["scaleType"] == 0:
- if self.select.GetValue():
- mapFrameDict["drawMap"] = self.drawMap.GetValue()
- mapFrameDict["map"] = self.select.GetValue()
- mapFrameDict["mapType"] = self.mapType
- mapFrameDict["region"] = None
-
- if mapFrameDict["drawMap"]:
- if mapFrameDict["mapType"] == "raster":
- mapFile = gs.find_file(mapFrameDict["map"], element="cell")
- if mapFile["file"] == "":
- GMessage("Raster %s not found" % mapFrameDict["map"])
- return False
- raster = self.instruction.FindInstructionByType("raster")
- if raster:
- raster["raster"] = mapFrameDict["map"]
- else:
- raster = Raster(NewId(), env=self.env)
- raster["raster"] = mapFrameDict["map"]
- raster["isRaster"] = True
- self.instruction.AddInstruction(raster)
-
- elif mapFrameDict["mapType"] == "vector":
- mapFile = gs.find_file(mapFrameDict["map"], element="vector")
- if mapFile["file"] == "":
- GMessage("Vector %s not found" % mapFrameDict["map"])
- return False
-
- vector = self.instruction.FindInstructionByType("vector")
- isAdded = False
- if vector:
- for each in vector["list"]:
- if each[0] == mapFrameDict["map"]:
- isAdded = True
- if not isAdded:
- topoInfo = gs.vector_info_topo(map=mapFrameDict["map"])
- if topoInfo:
- if bool(topoInfo["areas"]):
- topoType = "areas"
- elif bool(topoInfo["lines"]):
- topoType = "lines"
- else:
- topoType = "points"
- label = "(".join(mapFrameDict["map"].split("@")) + ")"
-
- if not vector:
- vector = Vector(NewId(), env=self.env)
- vector["list"] = []
- self.instruction.AddInstruction(vector)
- id = NewId()
- vector["list"].insert(
- 0, [mapFrameDict["map"], topoType, id, 1, label]
- )
- vProp = VProperties(id, topoType, env=self.env)
- vProp["name"], vProp["label"], vProp["lpos"] = (
- mapFrameDict["map"],
- label,
- 1,
- )
- self.instruction.AddInstruction(vProp)
- else:
- return False
-
- self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(
- self,
- scaleType=0,
- map=mapFrameDict["map"],
- env=self.env,
- mapType=self.mapType,
- rect=self.mapFrameDict["rect"],
+ if not self.select.GetValue():
+ wx.MessageBox(
+ message=_("No map selected!"),
+ caption=_("Invalid input"),
+ style=wx.OK | wx.ICON_ERROR,
)
+ return False
- if self.rectAdjusted:
- mapFrameDict["rect"] = self.rectAdjusted
- else:
- mapFrameDict["rect"] = self.mapFrameDict["rect"]
-
- mapFrameDict["scale"] = self.scale[0]
+ mapFrameDict["drawMap"] = self.drawMap.GetValue()
+ mapFrameDict["map"] = self.select.GetValue()
+ mapFrameDict["mapType"] = self.mapType
+ mapFrameDict["region"] = None
- mapFrameDict["center"] = self.center[0]
- # set region
- if self.mapType == "raster":
- self.env["GRASS_REGION"] = gs.region_env(
- raster=mapFrameDict["map"], env=self.env
- )
- if self.mapType == "vector":
+ if mapFrameDict["drawMap"]:
+ if mapFrameDict["mapType"] == "raster":
+ mapFile = gs.find_file(mapFrameDict["map"], element="cell")
+ if mapFile["file"] == "":
+ GMessage("Raster %s not found" % mapFrameDict["map"])
+ return False
raster = self.instruction.FindInstructionByType("raster")
- rasterId = raster.id if raster else None
-
- if rasterId:
- self.env["GRASS_REGION"] = gs.region_env(
- vector=mapFrameDict["map"],
- raster=self.instruction[rasterId]["raster"],
- env=self.env,
- )
+ if raster:
+ raster["raster"] = mapFrameDict["map"]
else:
- self.env["GRASS_REGION"] = gs.region_env(
- vector=mapFrameDict["map"], env=self.env
- )
+ raster = Raster(NewId(), env=self.env)
+ raster["raster"] = mapFrameDict["map"]
+ raster["isRaster"] = True
+ self.instruction.AddInstruction(raster)
+
+ elif mapFrameDict["mapType"] == "vector":
+ mapFile = gs.find_file(mapFrameDict["map"], element="vector")
+ if mapFile["file"] == "":
+ GMessage("Vector %s not found" % mapFrameDict["map"])
+ return False
+
+ vector = self.instruction.FindInstructionByType("vector")
+ isAdded = False
+ if vector:
+ for each in vector["list"]:
+ if each[0] == mapFrameDict["map"]:
+ isAdded = True
+ if not isAdded:
+ topoInfo = gs.vector_info_topo(map=mapFrameDict["map"])
+ if topoInfo:
+ if bool(topoInfo["areas"]):
+ topoType = "areas"
+ elif bool(topoInfo["lines"]):
+ topoType = "lines"
+ else:
+ topoType = "points"
+ label = "(".join(mapFrameDict["map"].split("@")) + ")"
+
+ if not vector:
+ vector = Vector(NewId(), env=self.env)
+ vector["list"] = []
+ self.instruction.AddInstruction(vector)
+ id = NewId()
+ vector["list"].insert(
+ 0, [mapFrameDict["map"], topoType, id, 1, label]
+ )
+ vProp = VProperties(id, topoType, env=self.env)
+ vProp["name"], vProp["label"], vProp["lpos"] = (
+ mapFrameDict["map"],
+ label,
+ 1,
+ )
+ self.instruction.AddInstruction(vProp)
+ else:
+ return False
+
+ self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(
+ self,
+ scaleType=0,
+ map=mapFrameDict["map"],
+ env=self.env,
+ mapType=self.mapType,
+ rect=self.mapFrameDict["rect"],
+ )
+ if self.rectAdjusted:
+ mapFrameDict["rect"] = self.rectAdjusted
else:
- wx.MessageBox(
- message=_("No map selected!"),
- caption=_("Invalid input"),
- style=wx.OK | wx.ICON_ERROR,
- )
- return False
+ mapFrameDict["rect"] = self.mapFrameDict["rect"]
- elif mapFrameDict["scaleType"] == 1:
- if self.select.GetValue():
- mapFrameDict["drawMap"] = False
- mapFrameDict["map"] = None
- mapFrameDict["mapType"] = None
- mapFrameDict["region"] = self.select.GetValue()
- self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(
- self,
- scaleType=1,
- region=mapFrameDict["region"],
- rect=self.mapFrameDict["rect"],
- env=self.env,
- )
- if self.rectAdjusted:
- mapFrameDict["rect"] = self.rectAdjusted
- else:
- mapFrameDict["rect"] = self.mapFrameDict["rect"]
+ mapFrameDict["scale"] = self.scale[0]
- mapFrameDict["scale"] = self.scale[1]
- mapFrameDict["center"] = self.center[1]
- # set region
+ mapFrameDict["center"] = self.center[0]
+ # set region
+ if self.mapType == "raster":
self.env["GRASS_REGION"] = gs.region_env(
- region=mapFrameDict["region"], env=self.env
+ raster=mapFrameDict["map"], env=self.env
)
- else:
+ if self.mapType == "vector":
+ raster = self.instruction.FindInstructionByType("raster")
+ rasterId = raster.id if raster else None
+
+ if rasterId:
+ self.env["GRASS_REGION"] = gs.region_env(
+ vector=mapFrameDict["map"],
+ raster=self.instruction[rasterId]["raster"],
+ env=self.env,
+ )
+ else:
+ self.env["GRASS_REGION"] = gs.region_env(
+ vector=mapFrameDict["map"], env=self.env
+ )
+
+ elif mapFrameDict["scaleType"] == 1:
+ if not self.select.GetValue():
wx.MessageBox(
message=_("No region selected!"),
caption=_("Invalid input"),
@@ -1533,6 +1510,29 @@ def update(self):
)
return False
+ mapFrameDict["drawMap"] = False
+ mapFrameDict["map"] = None
+ mapFrameDict["mapType"] = None
+ mapFrameDict["region"] = self.select.GetValue()
+ self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(
+ self,
+ scaleType=1,
+ region=mapFrameDict["region"],
+ rect=self.mapFrameDict["rect"],
+ env=self.env,
+ )
+ if self.rectAdjusted:
+ mapFrameDict["rect"] = self.rectAdjusted
+ else:
+ mapFrameDict["rect"] = self.mapFrameDict["rect"]
+
+ mapFrameDict["scale"] = self.scale[1]
+ mapFrameDict["center"] = self.center[1]
+ # set region
+ self.env["GRASS_REGION"] = gs.region_env(
+ region=mapFrameDict["region"], env=self.env
+ )
+
elif scaleType == 2:
mapFrameDict["drawMap"] = False
mapFrameDict["map"] = None
@@ -2193,7 +2193,7 @@ def __init__(self, parent, id, vectors, tmpSettings):
try:
self.mapDBInfo = VectorDBInfo(self.vectorName)
self.layers = self.mapDBInfo.layers.keys()
- except gs.ScriptError:
+ except ScriptError:
self.connection = False
self.layers = []
if not self.layers:
diff --git a/gui/wxpython/psmap/frame.py b/gui/wxpython/psmap/frame.py
index 41536cd921d..2ad6a38a15a 100644
--- a/gui/wxpython/psmap/frame.py
+++ b/gui/wxpython/psmap/frame.py
@@ -1298,26 +1298,26 @@ def DialogDataChanged(self, id):
else:
self.deleteObject(id)
- if itype == "vectorLegend":
- if not self.instruction.FindInstructionByType("vector"):
- self.deleteObject(id)
- elif self.instruction[id]["vLegend"]:
- self.canvas.UpdateLabel(itype=itype, id=id)
- drawRectangle = self.canvas.CanvasPaperCoordinates(
- rect=self.instruction[id]["rect"], canvasToPaper=False
- )
- self.canvas.Draw(
- pen=self.pen[itype],
- brush=self.brush[itype],
- pdc=self.canvas.pdcObj,
- drawid=id,
- pdctype="rectText",
- bb=drawRectangle,
- )
- self.canvas.RedrawSelectBox(id)
-
- else:
- self.deleteObject(id)
+ if itype != "vectorLegend":
+ continue
+ if not self.instruction.FindInstructionByType("vector"):
+ self.deleteObject(id)
+ elif self.instruction[id]["vLegend"]:
+ self.canvas.UpdateLabel(itype=itype, id=id)
+ drawRectangle = self.canvas.CanvasPaperCoordinates(
+ rect=self.instruction[id]["rect"], canvasToPaper=False
+ )
+ self.canvas.Draw(
+ pen=self.pen[itype],
+ brush=self.brush[itype],
+ pdc=self.canvas.pdcObj,
+ drawid=id,
+ pdctype="rectText",
+ bb=drawRectangle,
+ )
+ self.canvas.RedrawSelectBox(id)
+ else:
+ self.deleteObject(id)
def OnPageChanged(self, event):
"""GNotebook page has changed"""
diff --git a/gui/wxpython/psmap/instructions.py b/gui/wxpython/psmap/instructions.py
index 4528e0a0d93..6281eeb96cb 100644
--- a/gui/wxpython/psmap/instructions.py
+++ b/gui/wxpython/psmap/instructions.py
@@ -43,6 +43,7 @@
from core.utils import GetCmdString
from dbmgr.vinfo import VectorDBInfo
from grass.script.task import cmdlist_to_tuple
+from grass.exceptions import ScriptError
from gui_core.wrap import NewId as wxNewId
from psmap.utils import ( # Add any additional required names from psmap.utils here
@@ -101,21 +102,22 @@ def __contains__(self, id):
def __delitem__(self, id):
"""Delete instruction"""
for each in self.instruction:
- if each.id == id:
- if each.type == "map":
- # must remove raster, vector layers, labels too
- vektor = self.FindInstructionByType("vector", list=True)
- vProperties = self.FindInstructionByType("vProperties", list=True)
- raster = self.FindInstructionByType("raster", list=True)
- labels = self.FindInstructionByType("labels", list=True)
- for item in vektor + vProperties + raster + labels:
- if item in self.instruction:
- self.instruction.remove(item)
-
- self.instruction.remove(each)
- if id in self.objectsToDraw:
- self.objectsToDraw.remove(id)
- return
+ if each.id != id:
+ continue
+ if each.type == "map":
+ # must remove raster, vector layers, labels too
+ vektor = self.FindInstructionByType("vector", list=True)
+ vProperties = self.FindInstructionByType("vProperties", list=True)
+ raster = self.FindInstructionByType("raster", list=True)
+ labels = self.FindInstructionByType("labels", list=True)
+ for item in vektor + vProperties + raster + labels:
+ if item in self.instruction:
+ self.instruction.remove(item)
+
+ self.instruction.remove(each)
+ if id in self.objectsToDraw:
+ self.objectsToDraw.remove(id)
+ return
def AddInstruction(self, instruction):
"""Add instruction"""
@@ -532,7 +534,7 @@ def SetRegion(self, regionInstruction):
try:
self.env["GRASS_REGION"] = gs.region_env(env=self.env, **cmd[1])
- except gs.ScriptError as e:
+ except ScriptError as e:
GError(_("Region cannot be set\n%s") % e)
return False
@@ -1212,21 +1214,21 @@ def GetImageOrigSize(self, imagePath):
If eps, size is read from image header.
"""
fileName = os.path.split(imagePath)[1]
+ if os.path.splitext(fileName)[1].lower() != ".eps":
+ # we can use wx.Image
+ img = wx.Image(fileName, type=wx.BITMAP_TYPE_ANY)
+ return (img.GetWidth(), img.GetHeight())
+
# if eps, read info from header
- if os.path.splitext(fileName)[1].lower() == ".eps":
- bbInfo = "%%BoundingBox"
- file = open(imagePath)
- w = h = 0
+ bbInfo = "%%BoundingBox"
+ w = h = 0
+ with open(imagePath) as file:
while file:
line = file.readline()
if line.find(bbInfo) == 0:
w, h = line.split()[3:5]
break
- file.close()
- return float(w), float(h)
- # we can use wx.Image
- img = wx.Image(fileName, type=wx.BITMAP_TYPE_ANY)
- return img.GetWidth(), img.GetHeight()
+ return (float(w), float(h))
class NorthArrow(Image):
@@ -1909,7 +1911,7 @@ def Read(self, instruction, text):
return False
try:
info = gs.find_file(map, element="cell")
- except gs.ScriptError as e:
+ except ScriptError as e:
GError(message=e.value)
return False
instr["raster"] = info["fullname"]
@@ -1937,29 +1939,30 @@ def Read(self, instruction, text, **kwargs):
instr = {}
for line in text:
- if line.startswith(("vpoints", "vlines", "vareas")):
- # subtype
- if line.startswith("vpoints"):
- subType = "points"
- elif line.startswith("vlines"):
- subType = "lines"
- elif line.startswith("vareas"):
- subType = "areas"
- # name of vector map
- vmap = line.split()[1]
- try:
- info = gs.find_file(vmap, element="vector")
- except gs.ScriptError as e:
- GError(message=e.value)
- return False
- vmap = info["fullname"]
- # id
- id = kwargs["id"]
- # lpos
- lpos = kwargs["vectorMapNumber"]
- # label
- label = "(".join(vmap.split("@")) + ")"
- break
+ if not line.startswith(("vpoints", "vlines", "vareas")):
+ continue
+ # subtype
+ if line.startswith("vpoints"):
+ subType = "points"
+ elif line.startswith("vlines"):
+ subType = "lines"
+ elif line.startswith("vareas"):
+ subType = "areas"
+ # name of vector map
+ vmap = line.split()[1]
+ try:
+ info = gs.find_file(vmap, element="vector")
+ except ScriptError as e:
+ GError(message=e.value)
+ return False
+ vmap = info["fullname"]
+ # id
+ id = kwargs["id"]
+ # lpos
+ lpos = kwargs["vectorMapNumber"]
+ # label
+ label = "(".join(vmap.split("@")) + ")"
+ break
instr = [vmap, subType, id, lpos, label]
if not self.instruction["list"]:
self.instruction["list"] = []
@@ -2121,7 +2124,7 @@ def Read(self, instruction, text, **kwargs):
instr = {}
try:
info = gs.find_file(name=text[0].split()[1], element="vector")
- except gs.ScriptError as e:
+ except ScriptError as e:
GError(message=e.value)
return False
instr["name"] = info["fullname"]
diff --git a/gui/wxpython/psmap/utils.py b/gui/wxpython/psmap/utils.py
index 10b10f96297..5da20ff61a6 100644
--- a/gui/wxpython/psmap/utils.py
+++ b/gui/wxpython/psmap/utils.py
@@ -25,6 +25,7 @@
from core.gcmd import GError, RunCommand
import grass.script as gs
+from grass.exceptions import ScriptError
try:
from PIL import Image as PILImage # noqa
@@ -195,26 +196,24 @@ def PaperMapCoordinates(mapInstr, x, y, paperToMap=True, env=None):
mapWidthEN = region["e"] - region["w"]
mapHeightEN = region["n"] - region["s"]
- if paperToMap:
- diffX = x - mapInstr["rect"].GetX()
- diffY = y - mapInstr["rect"].GetY()
- diffEW = diffX * mapWidthEN / mapWidthPaper
- diffNS = diffY * mapHeightEN / mapHeightPaper
- e = region["w"] + diffEW
- n = region["n"] - diffNS
-
- if projInfo()["proj"] == "ll":
- return e, n
- return int(e), int(n)
-
- diffEW = x - region["w"]
- diffNS = region["n"] - y
- diffX = mapWidthPaper * diffEW / mapWidthEN
- diffY = mapHeightPaper * diffNS / mapHeightEN
- xPaper = mapInstr["rect"].GetX() + diffX
- yPaper = mapInstr["rect"].GetY() + diffY
-
- return xPaper, yPaper
+ if not paperToMap:
+ diffEW = x - region["w"]
+ diffNS = region["n"] - y
+ diffX = mapWidthPaper * diffEW / mapWidthEN
+ diffY = mapHeightPaper * diffNS / mapHeightEN
+ xPaper = mapInstr["rect"].GetX() + diffX
+ yPaper = mapInstr["rect"].GetY() + diffY
+ return (xPaper, yPaper)
+
+ diffX = x - mapInstr["rect"].GetX()
+ diffY = y - mapInstr["rect"].GetY()
+ diffEW = diffX * mapWidthEN / mapWidthPaper
+ diffNS = diffY * mapHeightEN / mapHeightPaper
+ e = region["w"] + diffEW
+ n = region["n"] - diffNS
+ if projInfo()["proj"] == "ll":
+ return (e, n)
+ return (int(e), int(n))
def AutoAdjust(self, scaleType, rect, env, map=None, mapType=None, region=None):
@@ -228,7 +227,7 @@ def AutoAdjust(self, scaleType, rect, env, map=None, mapType=None, region=None):
if mapType == "raster":
try:
res = gs.read_command("g.region", flags="gu", raster=map, env=env)
- except gs.ScriptError:
+ except ScriptError:
pass
elif mapType == "vector":
res = gs.read_command("g.region", flags="gu", vector=map, env=env)
@@ -242,7 +241,7 @@ def AutoAdjust(self, scaleType, rect, env, map=None, mapType=None, region=None):
else:
return None, None, None
# fails after switching location
- except (gs.ScriptError, gs.CalledModuleError):
+ except (ScriptError, gs.CalledModuleError):
pass
if not currRegionDict:
@@ -392,7 +391,7 @@ def GetMapBounds(filename, env, portrait=True):
.split(","),
)
)
- except (gs.ScriptError, IndexError):
+ except (ScriptError, IndexError):
GError(message=_("Unable to run `ps.map -b`"))
return None
return Rect2D(bb[0], bb[3], bb[2] - bb[0], bb[1] - bb[3])
diff --git a/gui/wxpython/rlisetup/sampling_frame.py b/gui/wxpython/rlisetup/sampling_frame.py
index e62737449e6..bc61ef4f109 100644
--- a/gui/wxpython/rlisetup/sampling_frame.py
+++ b/gui/wxpython/rlisetup/sampling_frame.py
@@ -216,28 +216,26 @@ def createRegion(self):
)
ret = dlg.ShowModal()
while True:
- if ret == wx.ID_OK:
- raster = dlg.GetValue()
- if checkMapExists(raster):
- GMessage(
- parent=self,
- message=_(
- "The raster file %s already exists, please change name"
- )
- % raster,
- )
- ret = dlg.ShowModal()
- else:
- dlg.Destroy()
- marea = self.writeArea(
- self._registeredGraphics.GetItem(0).GetCoords(), raster
- )
- self.nextRegion(next=True, area=marea)
- break
- else:
+ if ret != wx.ID_OK:
self.nextRegion(next=False)
break
+ raster = dlg.GetValue()
+ if not checkMapExists(raster):
+ dlg.Destroy()
+ marea = self.writeArea(
+ self._registeredGraphics.GetItem(0).GetCoords(), raster
+ )
+ self.nextRegion(next=True, area=marea)
+ break
+
+ GMessage(
+ parent=self,
+ message=_("The raster file %s already exists, please change name")
+ % raster,
+ )
+ ret = dlg.ShowModal()
+
def nextRegion(self, next=True, area=None):
self.mapWindow.ClearLines()
item = self._registeredGraphics.GetItem(0)
@@ -336,26 +334,24 @@ def createCircle(self, c):
)
ret = dlg.ShowModal()
while True:
- if ret == wx.ID_OK:
- raster = dlg.GetValue()
- if checkMapExists(raster):
- GMessage(
- parent=self,
- message=_(
- "The raster file %s already exists, please change name"
- )
- % raster,
- )
- ret = dlg.ShowModal()
- else:
- dlg.Destroy()
- circle = self.writeCircle(c, raster)
- self.nextCircle(next=True, circle=circle)
- break
- else:
+ if ret != wx.ID_OK:
self.nextCircle(next=False)
break
+ raster = dlg.GetValue()
+ if not checkMapExists(raster):
+ dlg.Destroy()
+ circle = self.writeCircle(c, raster)
+ self.nextCircle(next=True, circle=circle)
+ break
+
+ GMessage(
+ parent=self,
+ message=_("The raster file %s already exists, please change name")
+ % raster,
+ )
+ ret = dlg.ShowModal()
+
def nextCircle(self, next=True, circle=None):
self.mapWindow.ClearLines()
item = self._registeredGraphics.GetItem(0)
diff --git a/gui/wxpython/startup/guiutils.py b/gui/wxpython/startup/guiutils.py
index bb5cbc88d0d..135714d779f 100644
--- a/gui/wxpython/startup/guiutils.py
+++ b/gui/wxpython/startup/guiutils.py
@@ -199,11 +199,9 @@ def create_location_interactively(guiparent, grassdb):
)
# Returns database and location created by user
# and a mapset user may want to switch to
- gWizard_output = (gWizard.grassdatabase, gWizard.location, mapset)
- else:
- # Returns PERMANENT mapset when user mapset not defined
- gWizard_output = (gWizard.grassdatabase, gWizard.location, "PERMANENT")
- return gWizard_output
+ return (gWizard.grassdatabase, gWizard.location, mapset)
+ # Returns PERMANENT mapset when user mapset not defined
+ return (gWizard.grassdatabase, gWizard.location, "PERMANENT")
def rename_mapset_interactively(guiparent, grassdb, location, mapset):
diff --git a/gui/wxpython/tplot/frame.py b/gui/wxpython/tplot/frame.py
index 21fe822cf4a..b624b16b5ba 100755
--- a/gui/wxpython/tplot/frame.py
+++ b/gui/wxpython/tplot/frame.py
@@ -632,67 +632,64 @@ def _getSTVDData(self, timeseries):
for i in range(len(rows)):
row = rows[i]
values = out[i]
- if str(row["layer"]) == str(values["Layer"]):
- lay = "{map}_{layer}".format(
- map=row["name"], layer=values["Layer"]
- )
- self.timeDataV[name][lay] = {}
- self.timeDataV[name][lay]["start_datetime"] = row["start_time"]
- self.timeDataV[name][lay]["end_datetime"] = row["start_time"]
- self.timeDataV[name][lay]["value"] = values["Attributes"][
- attribute
- ]
- else:
- wherequery = ""
- cats = self._getExistingCategories(rows[0]["name"], cats)
- totcat = len(cats)
- ncat = 1
- for cat in cats:
- if ncat == 1 and totcat != 1:
- wherequery += "{k}={c} or".format(c=cat, k="{key}")
- elif ncat == 1 and totcat == 1:
- wherequery += "{k}={c}".format(c=cat, k="{key}")
- elif ncat == totcat:
- wherequery += " {k}={c}".format(c=cat, k="{key}")
- else:
- wherequery += " {k}={c} or".format(c=cat, k="{key}")
+ if str(row["layer"]) != str(values["Layer"]):
+ continue
+ lay = "{map}_{layer}".format(map=row["name"], layer=values["Layer"])
+ self.timeDataV[name][lay] = {}
+ self.timeDataV[name][lay]["start_datetime"] = row["start_time"]
+ self.timeDataV[name][lay]["end_datetime"] = row["start_time"]
+ self.timeDataV[name][lay]["value"] = values["Attributes"][attribute]
- catn = "cat{num}".format(num=cat)
- self.plotNameListV.append("{na}+{cat}".format(na=name, cat=catn))
- self.timeDataV[name][catn] = OrderedDict()
- ncat += 1
- for row in rows:
- lay = int(row["layer"])
- catkey = self._parseVDbConn(row["name"], lay)
- if not catkey:
- GError(
- parent=self,
- showTraceback=False,
- message=_(
- "No connection between vector map {vmap} and layer {la}"
- ).format(vmap=row["name"], la=lay),
- )
- return
- vals = gs.vector_db_select(
- map=row["name"],
- layer=lay,
- where=wherequery.format(key=catkey),
- columns=attribute,
+ continue
+
+ wherequery = ""
+ cats = self._getExistingCategories(rows[0]["name"], cats)
+ totcat = len(cats)
+ ncat = 1
+ for cat in cats:
+ if ncat == 1 and totcat != 1:
+ wherequery += "{k}={c} or".format(c=cat, k="{key}")
+ elif ncat == 1 and totcat == 1:
+ wherequery += "{k}={c}".format(c=cat, k="{key}")
+ elif ncat == totcat:
+ wherequery += " {k}={c}".format(c=cat, k="{key}")
+ else:
+ wherequery += " {k}={c} or".format(c=cat, k="{key}")
+
+ catn = "cat{num}".format(num=cat)
+ self.plotNameListV.append("{na}+{cat}".format(na=name, cat=catn))
+ self.timeDataV[name][catn] = OrderedDict()
+ ncat += 1
+ for row in rows:
+ lay = int(row["layer"])
+ catkey = self._parseVDbConn(row["name"], lay)
+ if not catkey:
+ GError(
+ parent=self,
+ showTraceback=False,
+ message=_(
+ "No connection between vector map {vmap} and layer {la}"
+ ).format(vmap=row["name"], la=lay),
)
- layn = "lay{num}".format(num=lay)
- for cat in cats:
- catn = "cat{num}".format(num=cat)
- if layn not in self.timeDataV[name][catn].keys():
- self.timeDataV[name][catn][layn] = {}
- self.timeDataV[name][catn][layn]["start_datetime"] = row[
- "start_time"
- ]
- self.timeDataV[name][catn][layn]["end_datetime"] = row[
- "end_time"
- ]
- self.timeDataV[name][catn][layn]["value"] = vals["values"][
- int(cat)
- ][0]
+ return
+ vals = gs.vector_db_select(
+ map=row["name"],
+ layer=lay,
+ where=wherequery.format(key=catkey),
+ columns=attribute,
+ )
+ layn = "lay{num}".format(num=lay)
+ for cat in cats:
+ catn = "cat{num}".format(num=cat)
+ if layn not in self.timeDataV[name][catn].keys():
+ self.timeDataV[name][catn][layn] = {}
+ self.timeDataV[name][catn][layn]["start_datetime"] = row[
+ "start_time"
+ ]
+ self.timeDataV[name][catn][layn]["end_datetime"] = row["end_time"]
+ self.timeDataV[name][catn][layn]["value"] = vals["values"][
+ int(cat)
+ ][0]
self.unit = unit
self.temporalType = mode
return
diff --git a/gui/wxpython/vdigit/dialogs.py b/gui/wxpython/vdigit/dialogs.py
index 369855c94fc..8d617f62d8b 100644
--- a/gui/wxpython/vdigit/dialogs.py
+++ b/gui/wxpython/vdigit/dialogs.py
@@ -426,29 +426,31 @@ def ApplyChanges(self, fid):
for cat in catsCurr[0][layer]:
if layer not in catsCurr[1].keys() or cat not in catsCurr[1][layer]:
catList.append(cat)
- if catList != []:
- add = action == "catadd"
-
- newfid = self.digit.SetLineCats(fid, layer, catList, add)
- if len(self.cats.keys()) == 1:
- self.fidText.SetLabel("%d" % newfid)
- else:
- choices = self.fidMulti.GetItems()
- choices[choices.index(str(fid))] = str(newfid)
- self.fidMulti.SetItems(choices)
- self.fidMulti.SetStringSelection(str(newfid))
-
- self.cats[newfid] = self.cats[fid]
- del self.cats[fid]
-
- fid = newfid
- if self.fid < 0:
- wx.MessageBox(
- parent=self,
- message=_("Unable to update vector map."),
- caption=_("Error"),
- style=wx.OK | wx.ICON_ERROR,
- )
+
+ if catList == []:
+ continue
+
+ add = action == "catadd"
+ newfid = self.digit.SetLineCats(fid, layer, catList, add)
+ if len(self.cats.keys()) == 1:
+ self.fidText.SetLabel("%d" % newfid)
+ else:
+ choices = self.fidMulti.GetItems()
+ choices[choices.index(str(fid))] = str(newfid)
+ self.fidMulti.SetItems(choices)
+ self.fidMulti.SetStringSelection(str(newfid))
+
+ self.cats[newfid] = self.cats[fid]
+ del self.cats[fid]
+
+ fid = newfid
+ if self.fid < 0:
+ wx.MessageBox(
+ parent=self,
+ message=_("Unable to update vector map."),
+ caption=_("Error"),
+ style=wx.OK | wx.ICON_ERROR,
+ )
self.cats_orig[fid] = copy.deepcopy(cats)
diff --git a/gui/wxpython/vdigit/toolbars.py b/gui/wxpython/vdigit/toolbars.py
index e3fc9657a51..9e0e66b70a8 100644
--- a/gui/wxpython/vdigit/toolbars.py
+++ b/gui/wxpython/vdigit/toolbars.py
@@ -995,31 +995,32 @@ def OnSelectMap(self, event):
disableAdd=True,
)
- if dlg and dlg.GetName():
- # add layer to map layer tree/map display
- mapName = dlg.GetName() + "@" + gs.gisenv()["MAPSET"]
- self._giface.GetLayerList().AddLayer(
- ltype="vector",
- name=mapName,
- checked=True,
- cmd=["d.vect", "map=%s" % mapName],
- )
-
- vectLayers = self.UpdateListOfLayers(updateTool=True)
- selection = vectLayers.index(mapName)
-
- # create table ?
- if dlg.IsChecked("table"):
- # TODO: starting of tools such as atm, iclass,
- # plots etc. should be handled in some better way
- # than starting randomly from mapdisp and lmgr
- self.openATM.emit(selection="table")
- dlg.Destroy()
- else:
+ if not dlg or not dlg.GetName():
self.combo.SetValue(_("Select vector map"))
if dlg:
dlg.Destroy()
return
+
+ # add layer to map layer tree/map display
+ mapName = dlg.GetName() + "@" + gs.gisenv()["MAPSET"]
+ self._giface.GetLayerList().AddLayer(
+ ltype="vector",
+ name=mapName,
+ checked=True,
+ cmd=["d.vect", "map=%s" % mapName],
+ )
+
+ vectLayers = self.UpdateListOfLayers(updateTool=True)
+ selection = vectLayers.index(mapName)
+
+ # create table ?
+ if dlg.IsChecked("table"):
+ # TODO: starting of tools such as atm, iclass,
+ # plots etc. should be handled in some better way
+ # than starting randomly from mapdisp and lmgr
+ self.openATM.emit(selection="table")
+ dlg.Destroy()
+
else:
selection = event.GetSelection() - 1 # first option is 'New vector map'
@@ -1058,10 +1059,9 @@ def StartEditing(self, mapLayer):
caption=_("Digitizer error"),
style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION | wx.CENTRE,
)
- if dlg.ShowModal() == wx.ID_YES:
- RunCommand("v.build", map=mapLayer.GetName())
- else:
+ if dlg.ShowModal() != wx.ID_YES:
return
+ RunCommand("v.build", map=mapLayer.GetName())
# deactivate layer
self.Map.ChangeLayerActive(mapLayer, False)
diff --git a/gui/wxpython/vdigit/wxdigit.py b/gui/wxpython/vdigit/wxdigit.py
index 8f486e27005..712d2961f7f 100644
--- a/gui/wxpython/vdigit/wxdigit.py
+++ b/gui/wxpython/vdigit/wxdigit.py
@@ -421,11 +421,11 @@ def _getSnapMode(self):
:return: snap mode
"""
threshold = self._display.GetThreshold()
- if threshold > 0.0:
- if UserSettings.Get(group="vdigit", key="snapToVertex", subkey="enabled"):
- return SNAPVERTEX
- return SNAP
- return NO_SNAP
+ if threshold <= 0.0:
+ return NO_SNAP
+ if UserSettings.Get(group="vdigit", key="snapToVertex", subkey="enabled"):
+ return SNAPVERTEX
+ return SNAP
def _getNewFeaturesLayer(self):
"""Returns layer of new feature (from settings)"""
@@ -868,13 +868,14 @@ def _getLineAreasCategories(self, ln_id):
areas = [left.value, right.value]
for i, a in enumerate(areas):
- if a > 0:
- centroid = Vect_get_area_centroid(self.poMapInfo, a)
- if centroid <= 0:
- continue
- c = self._getCategories(centroid)
- if c:
- cats[i] = c
+ if a <= 0:
+ continue
+ centroid = Vect_get_area_centroid(self.poMapInfo, a)
+ if centroid <= 0:
+ continue
+ c = self._getCategories(centroid)
+ if c:
+ cats[i] = c
return cats
@@ -1399,95 +1400,94 @@ def CopyCats(self, fromId, toId, copyAttrb=False):
if not copyAttrb:
# duplicate category
cat = catsFrom.cat[i]
- else:
- # duplicate attributes
- cat = self.cats[catsFrom.field[i]] + 1
- self.cats[catsFrom.field[i]] = cat
- poFi = Vect_get_field(self.poMapInfo, catsFrom.field[i])
- if not poFi:
- self._error.DbLink(i)
- return -1
+ continue
- fi = poFi.contents
- driver = db_start_driver(fi.driver)
- if not driver:
- self._error.Driver(fi.driver)
- return -1
+ # duplicate attributes
+ cat = self.cats[catsFrom.field[i]] + 1
+ self.cats[catsFrom.field[i]] = cat
+ poFi = Vect_get_field(self.poMapInfo, catsFrom.field[i])
+ if not poFi:
+ self._error.DbLink(i)
+ return -1
- handle = dbHandle()
- db_init_handle(byref(handle))
- db_set_handle(byref(handle), fi.database, None)
- if db_open_database(driver, byref(handle)) != DB_OK:
- db_shutdown_driver(driver)
- self._error.Database(fi.driver, fi.database)
- return -1
+ fi = poFi.contents
+ driver = db_start_driver(fi.driver)
+ if not driver:
+ self._error.Driver(fi.driver)
+ return -1
- stmt = dbString()
- db_init_string(byref(stmt))
- db_set_string(
- byref(stmt),
- "SELECT * FROM %s WHERE %s=%d"
- % (fi.table, fi.key, catsFrom.cat[i]),
+ handle = dbHandle()
+ db_init_handle(byref(handle))
+ db_set_handle(byref(handle), fi.database, None)
+ if db_open_database(driver, byref(handle)) != DB_OK:
+ db_shutdown_driver(driver)
+ self._error.Database(fi.driver, fi.database)
+ return -1
+
+ stmt = dbString()
+ db_init_string(byref(stmt))
+ db_set_string(
+ byref(stmt),
+ "SELECT * FROM %s WHERE %s=%d"
+ % (fi.table, fi.key, catsFrom.cat[i]),
+ )
+
+ cursor = dbCursor()
+ if (
+ db_open_select_cursor(
+ driver, byref(stmt), byref(cursor), DB_SEQUENTIAL
)
+ != DB_OK
+ ):
+ db_close_database_shutdown_driver(driver)
+ return -1
- cursor = dbCursor()
- if (
- db_open_select_cursor(
- driver, byref(stmt), byref(cursor), DB_SEQUENTIAL
- )
- != DB_OK
- ):
+ table = db_get_cursor_table(byref(cursor))
+ ncols = db_get_table_number_of_columns(table)
+
+ sql = "INSERT INTO %s VALUES (" % fi.table
+ # fetch the data
+ more = c_int()
+ while True:
+ if db_fetch(byref(cursor), DB_NEXT, byref(more)) != DB_OK:
db_close_database_shutdown_driver(driver)
return -1
-
- table = db_get_cursor_table(byref(cursor))
- ncols = db_get_table_number_of_columns(table)
-
- sql = "INSERT INTO %s VALUES (" % fi.table
- # fetch the data
- more = c_int()
- while True:
- if db_fetch(byref(cursor), DB_NEXT, byref(more)) != DB_OK:
- db_close_database_shutdown_driver(driver)
- return -1
- if not more.value:
- break
-
- value_string = dbString()
- for col in range(ncols):
- if col > 0:
- sql += ","
-
- column = db_get_table_column(table, col)
- if db_get_column_name(column) == fi.key:
- sql += "%d" % cat
- continue
-
- value = db_get_column_value(column)
- db_convert_column_value_to_string(
- column, byref(value_string)
+ if not more.value:
+ break
+
+ value_string = dbString()
+ for col in range(ncols):
+ if col > 0:
+ sql += ","
+
+ column = db_get_table_column(table, col)
+ if db_get_column_name(column) == fi.key:
+ sql += "%d" % cat
+ continue
+
+ value = db_get_column_value(column)
+ db_convert_column_value_to_string(
+ column, byref(value_string)
+ )
+ if db_test_value_isnull(value):
+ sql += "NULL"
+ else:
+ ctype = db_sqltype_to_Ctype(
+ db_get_column_sqltype(column)
)
- if db_test_value_isnull(value):
- sql += "NULL"
+ if ctype != DB_C_TYPE_STRING:
+ sql += db_get_string(byref(value_string))
else:
- ctype = db_sqltype_to_Ctype(
- db_get_column_sqltype(column)
- )
- if ctype != DB_C_TYPE_STRING:
- sql += db_get_string(byref(value_string))
- else:
- sql += "'%s'" % db_get_string(
- byref(value_string)
- )
-
- sql += ")"
- db_set_string(byref(stmt), sql)
- if db_execute_immediate(driver, byref(stmt)) != DB_OK:
- db_close_database_shutdown_driver(driver)
- return -1
+ sql += "'%s'" % db_get_string(byref(value_string))
+ sql += ")"
+ db_set_string(byref(stmt), sql)
+ if db_execute_immediate(driver, byref(stmt)) != DB_OK:
db_close_database_shutdown_driver(driver)
- G_free(poFi)
+ return -1
+
+ db_close_database_shutdown_driver(driver)
+ G_free(poFi)
if Vect_cat_set(poCatsTo, catsFrom.field[i], cat) < 1:
continue
diff --git a/gui/wxpython/vdigit/wxdisplay.py b/gui/wxpython/vdigit/wxdisplay.py
index f7381fe763f..156397e6266 100644
--- a/gui/wxpython/vdigit/wxdisplay.py
+++ b/gui/wxpython/vdigit/wxdisplay.py
@@ -1225,14 +1225,15 @@ def GetDuplicates(self):
Vect_read_line(self.poMapInfo, BPoints, None, line2)
- if Vect_line_check_duplicate(APoints, BPoints, WITHOUT_Z):
- if i not in ids:
- ids[i] = []
- ids[i].append((line1, self._getCatString(line1)))
- self.selected["idsDupl"].append(line1)
-
- ids[i].append((line2, self._getCatString(line2)))
- self.selected["idsDupl"].append(line2)
+ if not Vect_line_check_duplicate(APoints, BPoints, WITHOUT_Z):
+ continue
+ if i not in ids:
+ ids[i] = []
+ ids[i].append((line1, self._getCatString(line1)))
+ self.selected["idsDupl"].append(line1)
+
+ ids[i].append((line2, self._getCatString(line2)))
+ self.selected["idsDupl"].append(line2)
Vect_destroy_line_struct(APoints)
Vect_destroy_line_struct(BPoints)
diff --git a/gui/wxpython/vnet/dialogs.py b/gui/wxpython/vnet/dialogs.py
index ca928a6b164..19d8e6c8a93 100644
--- a/gui/wxpython/vnet/dialogs.py
+++ b/gui/wxpython/vnet/dialogs.py
@@ -1189,15 +1189,16 @@ def SetData(self, key, data):
self.CheckItem(idx, True)
elif not v and self.IsItemChecked(idx):
self.CheckItem(idx, False)
- else:
- found = 0
- for col in self.colsData:
- if k == col[0]:
- found = 1
- break
-
- if found:
- self.EditCellKey(key, k, v)
+ continue
+
+ found = 0
+ for col in self.colsData:
+ if k == col[0]:
+ found = 1
+ break
+
+ if found:
+ self.EditCellKey(key, k, v)
def OnItemSelected(self, event):
"""Item selected"""
diff --git a/gui/wxpython/vnet/vnet_core.py b/gui/wxpython/vnet/vnet_core.py
index cb1df07441d..eaf4874c86f 100644
--- a/gui/wxpython/vnet/vnet_core.py
+++ b/gui/wxpython/vnet/vnet_core.py
@@ -1092,42 +1092,40 @@ def ComputeNodes(self, activate):
inpName, mapSet = inpFullName.split("@")
computeNodes = True
- if "inputMap" not in self.snapData:
- pass
- elif inpFullName != self.snapData["inputMap"].GetVectMapName():
- self.snapData["inputMap"] = VectMap(None, inpFullName)
- elif self.snapData["inputMap"].VectMapState() == 1:
- computeNodes = False
+ if "inputMap" in self.snapData:
+ if inpFullName != self.snapData["inputMap"].GetVectMapName():
+ self.snapData["inputMap"] = VectMap(None, inpFullName)
+ elif self.snapData["inputMap"].VectMapState() == 1:
+ computeNodes = False
+
+ if not computeNodes:
+ # map is already created and up to date for input data
+ self.snapPts.AddRenderLayer()
+ self.giface.updateMap.emit(render=True, renderVector=True)
+ self.snapping.emit(evt="computing_points_done")
+ return 1
# new map needed
- if computeNodes:
- if "cmdThread" not in self.snapData:
- self.snapData["cmdThread"] = CmdThread(self)
- else:
- self.snapData["cmdThread"].abort()
-
- cmd = [
- "v.to.points",
- "input=" + params["input"],
- "output=" + self.snapPts.GetVectMapName(),
- "use=node",
- "--overwrite",
- ]
- # process GRASS command with argument
- self.snapData["inputMap"] = VectMap(None, inpFullName)
- self.snapData["inputMap"].SaveVectMapState()
-
- self.Bind(EVT_CMD_DONE, self._onNodesDone)
- self.snapData["cmdThread"].RunCmd(cmd)
+ if "cmdThread" not in self.snapData:
+ self.snapData["cmdThread"] = CmdThread(self)
+ else:
+ self.snapData["cmdThread"].abort()
+ cmd = [
+ "v.to.points",
+ "input=" + params["input"],
+ "output=" + self.snapPts.GetVectMapName(),
+ "use=node",
+ "--overwrite",
+ ]
+ # process GRASS command with argument
+ self.snapData["inputMap"] = VectMap(None, inpFullName)
+ self.snapData["inputMap"].SaveVectMapState()
- self.snapping.emit(evt="computing_points")
+ self.Bind(EVT_CMD_DONE, self._onNodesDone)
+ self.snapData["cmdThread"].RunCmd(cmd)
+ self.snapping.emit(evt="computing_points")
- return 0
- # map is already created and up to date for input data
- self.snapPts.AddRenderLayer()
- self.giface.updateMap.emit(render=True, renderVector=True)
- self.snapping.emit(evt="computing_points_done")
- return 1
+ return 0
def _onNodesDone(self, event):
"""Update map window, when map with nodes to snap is created"""
diff --git a/gui/wxpython/vnet/vnet_data.py b/gui/wxpython/vnet/vnet_data.py
index e8e05839e70..137840879c8 100644
--- a/gui/wxpython/vnet/vnet_data.py
+++ b/gui/wxpython/vnet/vnet_data.py
@@ -928,14 +928,12 @@ def DeleteTmpMap(self, vectMap):
:return: True if was removed
:return: False if does not contain the map
"""
- if vectMap:
- vectMap.DeleteRenderLayer()
- RunCommand(
- "g.remove", flags="f", type="vector", name=vectMap.GetVectMapName()
- )
- self.RemoveFromTmpMaps(vectMap)
- return True
- return False
+ if not vectMap:
+ return False
+ vectMap.DeleteRenderLayer()
+ RunCommand("g.remove", flags="f", type="vector", name=vectMap.GetVectMapName())
+ self.RemoveFromTmpMaps(vectMap)
+ return True
def DeleteAllTmpMaps(self):
"""Delete all temporary maps in the class"""
diff --git a/gui/wxpython/vnet/vnet_utils.py b/gui/wxpython/vnet/vnet_utils.py
index 7157ac8a20e..2f32fd2b94d 100644
--- a/gui/wxpython/vnet/vnet_utils.py
+++ b/gui/wxpython/vnet/vnet_utils.py
@@ -73,15 +73,14 @@ def SnapToNode(e, n, tresh, vectMap):
vectlib.WITHOUT_Z,
)
- if nodeNum > 0:
- e = c_double(0)
- n = c_double(0)
- vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) # z
- e = e.value
- n = n.value
- else:
+ if nodeNum <= 0:
vectlib.Vect_close(openedMap)
return False
+ e = c_double(0)
+ n = c_double(0)
+ vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None)
+ e = e.value
+ n = n.value
return e, n
@@ -110,15 +109,14 @@ def GetNearestNodeCat(e, n, layer, tresh, vectMap):
vectlib.WITHOUT_Z,
)
- if nodeNum > 0:
- e = c_double(0)
- n = c_double(0)
- vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None) # z
- e = e.value
- n = n.value
- else:
+ if nodeNum <= 0:
vectlib.Vect_close(openedMap)
return -1
+ e = c_double(0)
+ n = c_double(0)
+ vectlib.Vect_get_node_coor(openedMap, nodeNum, byref(e), byref(n), None)
+ e = e.value
+ n = n.value
box = vectlib.bound_box()
List = POINTER(vectlib.boxlist)
diff --git a/gui/wxpython/vnet/widgets.py b/gui/wxpython/vnet/widgets.py
index d5a0964a5ac..d05519be772 100644
--- a/gui/wxpython/vnet/widgets.py
+++ b/gui/wxpython/vnet/widgets.py
@@ -507,22 +507,19 @@ def ShowColumn(self, colName, pos):
"""
if pos < 0 or pos >= self.GetColumnCount():
return False
- if colName in self.hiddenCols:
- col = self.hiddenCols[colName]
-
- for item in enumerate(self.itemDataMap):
- item[1].insert(pos, col["itemDataMap"][item[0]])
- for item in enumerate(self.selIdxs):
- item[1].insert(pos, col["selIdxs"][item[0]])
-
- self.colsData.insert(pos, col["colsData"])
-
- self.InsertColumnItem(pos, col["wxCol"])
- self.ResizeColumns()
- del self.hiddenCols[colName]
- return True
-
- return False
+ if colName not in self.hiddenCols:
+ return False
+ col = self.hiddenCols[colName]
+
+ for item in enumerate(self.itemDataMap):
+ item[1].insert(pos, col["itemDataMap"][item[0]])
+ for item in enumerate(self.selIdxs):
+ item[1].insert(pos, col["selIdxs"][item[0]])
+ self.colsData.insert(pos, col["colsData"])
+ self.InsertColumnItem(pos, col["wxCol"])
+ self.ResizeColumns()
+ del self.hiddenCols[colName]
+ return True
def IsShown(self, colName) -> bool:
"""Is column shown
diff --git a/gui/wxpython/wxplot/base.py b/gui/wxpython/wxplot/base.py
index 057894c0250..21d4a442a77 100755
--- a/gui/wxpython/wxplot/base.py
+++ b/gui/wxpython/wxplot/base.py
@@ -247,11 +247,12 @@ def InitRasterOpts(self, rasterList, plottype):
rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]]
else:
rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]]
- else:
- r = randint(0, 255)
- b = randint(0, 255)
- g = randint(0, 255)
- rdict[r]["pcolor"] = (r, g, b, 255)
+ continue
+
+ r = randint(0, 255)
+ b = randint(0, 255)
+ g = randint(0, 255)
+ rdict[r]["pcolor"] = (r, g, b, 255)
return rdict
@@ -322,11 +323,12 @@ def InitRasterPairs(self, rasterList, plottype):
if idx <= len(self.colorList):
rdict[rpair]["pcolor"] = self.colorDict[self.colorList[idx]]
- else:
- r = randint(0, 255)
- b = randint(0, 255)
- g = randint(0, 255)
- rdict[rpair]["pcolor"] = (r, g, b, 255)
+ continue
+
+ r = randint(0, 255)
+ b = randint(0, 255)
+ g = randint(0, 255)
+ rdict[rpair]["pcolor"] = (r, g, b, 255)
return rdict
diff --git a/gui/wxpython/wxplot/profile.py b/gui/wxpython/wxplot/profile.py
index 5b63f3cabab..37185c7409d 100644
--- a/gui/wxpython/wxplot/profile.py
+++ b/gui/wxpython/wxplot/profile.py
@@ -262,16 +262,18 @@ def SetupProfile(self):
for r in self.raster.keys():
self.raster[r]["datalist"] = []
datalist = self.CreateDatalist(r, self.coordstr)
- if len(datalist) > 0:
- self.raster[r]["datalist"] = datalist
+ if len(datalist) <= 0:
+ continue
+
+ self.raster[r]["datalist"] = datalist
- # update ylabel to match units if they exist
- if self.raster[r]["units"] != "":
- self.ylabel += "%s (%d)," % (self.raster[r]["units"], i)
- i += 1
+ # update ylabel to match units if they exist
+ if self.raster[r]["units"] != "":
+ self.ylabel += "%s (%d)," % (self.raster[r]["units"], i)
+ i += 1
- # update title
- self.ptitle += " %s ," % r.split("@")[0]
+ # update title
+ self.ptitle += " %s ," % r.split("@")[0]
self.ptitle = self.ptitle.rstrip(",")
diff --git a/imagery/i.atcorr/create_iwave.py b/imagery/i.atcorr/create_iwave.py
index 27c1e8e1e42..6aab9ccd065 100644
--- a/imagery/i.atcorr/create_iwave.py
+++ b/imagery/i.atcorr/create_iwave.py
@@ -255,72 +255,79 @@ def get_max_wavelength(c, rthresh, fi):
print(" %s (%inm - %inm)" % (bands[b], min_wavelength, max_wavelength))
# writing...
- outfile = open(os.path.join(folder, sensor + "_cpp_template.txt"), "w")
- outfile.write("/* Following filter function created using create_iwave.py */\n\n")
-
- # single band case
- if len(bands) == 1:
- outfile.write("void IWave::%s()\n{\n\n" % (sensor.lower()))
- outfile.write(" /* %s of %s */\n" % (bands[0], sensor))
- outfile.write(" static const float sr[%i] = {" % (len(filter_f)))
- filter_text = pretty_print(filter_f)
- outfile.write(filter_text)
-
- # calculate wl slot for band start
- # slots range from 250 to 4000 at 2.5 increments (total 1500)
- s_start = int((limits[0] * 1000 - 250) / 2.5)
-
- outfile.write("\n")
- outfile.write(" ffu.wlinf = %.4ff;\n" % (limits[0]))
- outfile.write(" ffu.wlsup = %.4ff;\n" % (limits[1]))
- outfile.write(" int i = 0;\n")
- outfile.write(" for(i = 0; i < %i; i++)\tffu.s[i] = 0;\n" % (s_start))
- outfile.write(
- " for(i = 0; i < %i; i++)\tffu.s[%i+i] = sr[i];\n"
- % (len(filter_f), s_start)
- )
+ outpath = os.path.join(folder, sensor + "_cpp_template.txt")
+ with open(outpath, "w") as outfile:
outfile.write(
- " for(i = %i; i < 1501; i++)\tffu.s[i] = 0;\n"
- % (s_start + len(filter_f))
+ "/* Following filter function created using create_iwave.py */\n\n"
)
- outfile.write("}\n")
- else: # more than 1 band
- outfile.write("void IWave::%s(int iwa)\n{\n\n" % (sensor.lower()))
- # writing bands
- for b in range(len(bands)):
- outfile.write(" /* %s of %s */\n" % (bands[b], sensor))
+ # single band case
+ if len(bands) == 1:
+ outfile.write("void IWave::%s()\n{\n\n" % (sensor.lower()))
+ outfile.write(" /* %s of %s */\n" % (bands[0], sensor))
+ outfile.write(" static const float sr[%i] = {" % (len(filter_f)))
+ filter_text = pretty_print(filter_f)
+ outfile.write(filter_text)
+
+ # calculate wl slot for band start
+ # slots range from 250 to 4000 at 2.5 increments (total 1500)
+ s_start = int((limits[0] * 1000 - 250) / 2.5)
+
+ outfile.write("\n")
+ outfile.write(" ffu.wlinf = %.4ff;\n" % (limits[0]))
+ outfile.write(" ffu.wlsup = %.4ff;\n" % (limits[1]))
+ outfile.write(" int i = 0;\n")
+ outfile.write(" for(i = 0; i < %i; i++)\tffu.s[i] = 0;\n" % (s_start))
outfile.write(
- " static const float sr%i[%i] = {\n" % (b + 1, len(filter_f[b]))
+ " for(i = 0; i < %i; i++)\tffu.s[%i+i] = sr[i];\n"
+ % (len(filter_f), s_start)
)
- filter_text = pretty_print(filter_f[b])
- outfile.write(filter_text + "\n };\n\t\n")
-
- # writing band limits
- inf = ", ".join(["%.4f" % i[0] for i in limits])
- sup = ", ".join(["%.4f" % i[1] for i in limits])
+ outfile.write(
+ " for(i = %i; i < 1501; i++)\tffu.s[i] = 0;\n"
+ % (s_start + len(filter_f))
+ )
+ outfile.write("}\n")
+
+ else: # more than 1 band
+ outfile.write("void IWave::%s(int iwa)\n{\n\n" % (sensor.lower()))
+ # writing bands
+ for b in range(len(bands)):
+ outfile.write(" /* %s of %s */\n" % (bands[b], sensor))
+ outfile.write(
+ " static const float sr%i[%i] = {\n" % (b + 1, len(filter_f[b]))
+ )
+ filter_text = pretty_print(filter_f[b])
+ outfile.write(filter_text + "\n };\n\t\n")
+
+ # writing band limits
+ inf = ", ".join(["%.4f" % i[0] for i in limits])
+ sup = ", ".join(["%.4f" % i[1] for i in limits])
- outfile.write(" static const float wli[%i] = {%s};\n" % (len(bands), inf))
- outfile.write(" static const float wls[%i] = {%s};\n" % (len(bands), sup))
+ outfile.write(
+ " static const float wli[%i] = {%s};\n" % (len(bands), inf)
+ )
+ outfile.write(
+ " static const float wls[%i] = {%s};\n" % (len(bands), sup)
+ )
- outfile.write("\n")
- outfile.write(" ffu.wlinf = (float)wli[iwa-1];\n")
- outfile.write(" ffu.wlsup = (float)wls[iwa-1];\n\n")
+ outfile.write("\n")
+ outfile.write(" ffu.wlinf = (float)wli[iwa-1];\n")
+ outfile.write(" ffu.wlsup = (float)wls[iwa-1];\n\n")
- outfile.write(" int i;\n")
- outfile.write(" for(i = 0; i < 1501; i++) ffu.s[i] = 0;\n\n")
+ outfile.write(" int i;\n")
+ outfile.write(" for(i = 0; i < 1501; i++) ffu.s[i] = 0;\n\n")
- outfile.write(" switch(iwa)\n {\n")
+ outfile.write(" switch(iwa)\n {\n")
- # now start of case part...
- for b in range(len(bands)):
- s_start = int((limits[b][0] * 1000 - 250) / 2.5)
- outfile.write(
- " case %i: for(i = 0; i < %i; i++) ffu.s[%i+i] = sr%i[i];\n"
- % ((b + 1), len(filter_f[b]), s_start, (b + 1))
- )
- outfile.write(" break;\n")
- outfile.write(" }\n}\n")
+ # now start of case part...
+ for b in range(len(bands)):
+ s_start = int((limits[b][0] * 1000 - 250) / 2.5)
+ outfile.write(
+ " case %i: for(i = 0; i < %i; i++) ffu.s[%i+i] = sr%i[i];\n"
+ % ((b + 1), len(filter_f[b]), s_start, (b + 1))
+ )
+ outfile.write(" break;\n")
+ outfile.write(" }\n}\n")
def main():
diff --git a/lib/nviz/exag.c b/lib/nviz/exag.c
index b13897bd963..088ac97e9e2 100644
--- a/lib/nviz/exag.c
+++ b/lib/nviz/exag.c
@@ -29,7 +29,8 @@
int Nviz_get_exag_height(double *val, double *min, double *max)
{
float longdim, exag, texag, hmin, hmax, fmin, fmax;
- int nsurfs, i, *surf_list;
+ int nsurfs, i;
+ int *surf_list = NULL;
surf_list = GS_get_surf_list(&nsurfs);
if (nsurfs) {
@@ -63,6 +64,7 @@ int Nviz_get_exag_height(double *val, double *min, double *max)
G_debug(1, "Nviz_get_exag_height(): value = %f min = %f max = %f", *val,
min ? *min : 0.0, max ? *max : 0.0);
+ G_free(surf_list);
return 1;
}
@@ -77,7 +79,8 @@ int Nviz_get_exag_height(double *val, double *min, double *max)
double Nviz_get_exag(void)
{
float exag, texag;
- int nsurfs, i, *surf_list;
+ int nsurfs, i;
+ int *surf_list = NULL;
surf_list = GS_get_surf_list(&nsurfs);
@@ -91,9 +94,7 @@ double Nviz_get_exag(void)
if (exag == 0.0)
exag = 1.0;
-
- if (nsurfs > 0)
- G_free(surf_list);
+ G_free(surf_list);
G_debug(1, "Nviz_get_exag(): value = %f", exag);
return exag;
diff --git a/lib/vector/Vlib/open_ogr.c b/lib/vector/Vlib/open_ogr.c
index 894a2cfc11c..a085bcca31c 100644
--- a/lib/vector/Vlib/open_ogr.c
+++ b/lib/vector/Vlib/open_ogr.c
@@ -150,8 +150,10 @@ int V2_open_old_ogr(struct Map_info *Map)
Map->mapset);
if (Vect_open_fidx(Map, &(Map->fInfo.ogr.offset)) != 0) {
+ const char *map_name = Vect_get_full_name(Map);
G_warning(_("Unable to open feature index file for vector map <%s>"),
- Vect_get_full_name(Map));
+ map_name);
+ G_free((void *)map_name);
G_zero(&(Map->fInfo.ogr.offset), sizeof(struct Format_info_offset));
}
@@ -268,14 +270,17 @@ int Vect_open_fidx(struct Map_info *Map, struct Format_info_offset *offset)
dig_file_init(&fp);
fp.file = G_fopen_old(elem, GV_FIDX_ELEMENT, Map->mapset);
if (fp.file == NULL) {
- G_debug(1, "unable to open fidx file for vector map <%s>",
- Vect_get_full_name(Map));
+ const char *map_name = Vect_get_full_name(Map);
+ G_debug(1, "unable to open fidx file for vector map <%s>", map_name);
+ G_free((void *)map_name);
return -1;
}
/* Header */
- if (0 >= dig__fread_port_C(buf, 5, &fp))
+ if (0 >= dig__fread_port_C(buf, 5, &fp)) {
+ fclose(fp.file);
return -1;
+ }
Version_Major = buf[0];
Version_Minor = buf[1];
Back_Major = buf[2];
@@ -302,23 +307,29 @@ int Vect_open_fidx(struct Map_info *Map, struct Format_info_offset *offset)
/* Body */
/* bytes 6 - 9 : header size */
- if (0 >= dig__fread_port_L(&length, 1, &fp))
+ if (0 >= dig__fread_port_L(&length, 1, &fp)) {
+ fclose(fp.file);
return -1;
+ }
G_debug(4, " header size %ld", length);
G_fseek(fp.file, length, SEEK_SET);
/* number of records */
- if (0 >= dig__fread_port_I(&(offset->array_num), 1, &fp))
+ if (0 >= dig__fread_port_I(&(offset->array_num), 1, &fp)) {
+ fclose(fp.file);
return -1;
+ }
/* alloc space */
offset->array = (int *)G_malloc(offset->array_num * sizeof(int));
offset->array_alloc = offset->array_num;
/* offsets */
- if (0 >= dig__fread_port_I(offset->array, offset->array_num, &fp))
+ if (0 >= dig__fread_port_I(offset->array, offset->array_num, &fp)) {
+ fclose(fp.file);
return -1;
+ }
fclose(fp.file);
diff --git a/pyproject.toml b/pyproject.toml
index b3bdd21a8d5..b1758030f21 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -268,12 +268,6 @@ ignore = [
# Other ignores:
"**.py" = ["PYI066"]
"*/testsuite/**.py" = ["PT009", "PT027"]
-"gui/wxpython/core/globalvar.py" = ["PTH208"]
-"gui/wxpython/core/render.py" = ["SIM115"]
-"gui/wxpython/core/settings.py" = ["PTH208", "SIM115"]
-"gui/wxpython/core/utils.py" = ["SIM115"]
-"gui/wxpython/core/workspace.py" = ["SIM115"]
-"gui/wxpython/datacatalog/catalog.py" = ["PTH208"]
"gui/wxpython/dbmgr/base.py" = ["SIM115"]
"gui/wxpython/gcp/manager.py" = ["PTH208"]
"gui/wxpython/gmodeler/panels.py" = ["SIM115"]
@@ -299,7 +293,6 @@ ignore = [
"gui/wxpython/vnet/vnet_data.py" = ["SIM115"]
"gui/wxpython/web_services/dialogs.py" = ["SIM115"]
"gui/wxpython/wxplot/profile.py" = ["A005", "SIM115"]
-"imagery/i.atcorr/create_iwave.py" = ["SIM115"]
"lib/imagery/testsuite/test_imagery_signature_management.py" = ["SIM115"]
"lib/imagery/testsuite/test_imagery_sigsetfile.py" = ["FURB152"]
"lib/init/grass.py" = ["SIM115"]
@@ -380,9 +373,6 @@ ignore = [
"temporal/t.register/testsuite/test_t_register_raster.py" = ["FLY002"]
"temporal/t.register/testsuite/test_t_register_raster_file.py" = ["FLY002"]
"temporal/t.remove/t.remove.py" = ["SIM115"]
-"utils/generate_release_notes.py" = ["PGH004"]
-"utils/gitlog2changelog.py" = ["SIM115"]
-"utils/thumbnails.py" = ["PTH208"]
"vector/v.fill.holes/examples.ipynb" = ["PTH201"]
[tool.ruff.lint.flake8-import-conventions.extend-aliases]
diff --git a/python/grass/grassdb/checks.py b/python/grass/grassdb/checks.py
index 052addac248..a458ad71432 100644
--- a/python/grass/grassdb/checks.py
+++ b/python/grass/grassdb/checks.py
@@ -20,7 +20,6 @@
import grass.grassdb.config as cfg
import grass.script as gs
from grass.script import gisenv
-from itertools import starmap
def mapset_exists(path: str | os.PathLike[str], location=None, mapset=None) -> bool:
@@ -525,7 +524,10 @@ def get_reasons_locations_not_removable(locations):
Returns messages as list if there were any failed checks, otherwise empty list.
"""
- return list(starmap(get_reasons_location_not_removable, locations))
+ messages = []
+ for grassdb, location in locations:
+ messages += get_reasons_location_not_removable(grassdb, location)
+ return messages
def get_reasons_location_not_removable(grassdb, location):
@@ -556,7 +558,9 @@ def get_reasons_location_not_removable(grassdb, location):
)
# Append to the list of tuples
- mapsets = [(grassdb, location, g_mapset) for g_mapset in g_mapsets]
+ mapsets = []
+ for g_mapset in g_mapsets:
+ mapsets.append((grassdb, location, g_mapset))
# Concentenate both checks
messages += get_reasons_mapsets_not_removable(mapsets, check_permanent=False)
@@ -585,7 +589,9 @@ def get_reasons_grassdb_not_removable(grassdb):
g_locations = get_list_of_locations(grassdb)
# Append to the list of tuples
- locations = [(grassdb, g_location) for g_location in g_locations]
+ locations = []
+ for g_location in g_locations:
+ locations.append((grassdb, g_location))
return get_reasons_locations_not_removable(locations)
@@ -596,11 +602,12 @@ def get_list_of_locations(dbase):
:return: list of locations (sorted)
"""
- locations = [
- os.path.basename(location)
- for location in glob.glob(os.path.join(dbase, "*"))
- if os.path.join(location, "PERMANENT") in glob.glob(os.path.join(location, "*"))
- ]
+ locations = []
+ for location in glob.glob(os.path.join(dbase, "*")):
+ if os.path.join(location, "PERMANENT") in glob.glob(
+ os.path.join(location, "*")
+ ):
+ locations.append(os.path.basename(location))
locations.sort(key=lambda x: x.lower())
diff --git a/raster/r.geomorphon/r.geomorphon.html b/raster/r.geomorphon/r.geomorphon.html
index 36b85ce51fd..20338fa0315 100644
--- a/raster/r.geomorphon/r.geomorphon.html
+++ b/raster/r.geomorphon/r.geomorphon.html
@@ -33,9 +33,9 @@
What is geomorphon:
different from the horizon. Two lines-of-sight are necessary due to zenith
LOS only, does not detect positive forms correctly.
-
There are 3**8 = 6561 possible ternary patterns (8-tuples). However by
-eliminating all patterns that are results of either rotation or reflection
-of other patterns we get a set of 498 patterns remain referred as geomorphons.
+
There are 3**8 = 6561 possible ternary patterns (8-tuples). By removing
+all patterns that are the result of either rotation or reflection of other
+patterns, a set of 498 patterns remains, referred to as geomorphons.
This is a comprehensive and exhaustive set of idealized landforms that are
independent of the size, relief, and orientation of the actual landform.
diff --git a/raster/r.li/r.li.html b/raster/r.li/r.li.html
index 37e40d6cfc7..ca38ef92ce0 100644
--- a/raster/r.li/r.li.html
+++ b/raster/r.li/r.li.html
@@ -1,4 +1,6 @@
-
+
+
+
DESCRIPTION
The r.li suite is a toolset for multiscale analysis of
diff --git a/raster/r.resamp.stats/main.c b/raster/r.resamp.stats/main.c
index efa2c67cbf3..f329eea856f 100644
--- a/raster/r.resamp.stats/main.c
+++ b/raster/r.resamp.stats/main.c
@@ -149,6 +149,9 @@ static void resamp_unweighted(void)
Rast_put_d_row(outfile, outbuf);
}
+ G_free(row_map);
+ G_free(col_map);
+ G_free(values);
}
static void resamp_weighted(void)
@@ -233,6 +236,9 @@ static void resamp_weighted(void)
Rast_put_d_row(outfile, outbuf);
}
+ G_free(row_map);
+ G_free(col_map);
+ G_free(values);
}
int main(int argc, char *argv[])
diff --git a/raster/r.sim/r.sim.sediment/main.c b/raster/r.sim/r.sim.sediment/main.c
index f49fa8fb880..5f84843acb8 100644
--- a/raster/r.sim/r.sim.sediment/main.c
+++ b/raster/r.sim/r.sim.sediment/main.c
@@ -388,15 +388,15 @@ int main(int argc, char *argv[])
threads, abs(threads));
threads = abs(threads);
}
+ if (threads > 1 && Rast_mask_is_present()) {
+ G_warning(_("Parallel processing disabled due to active mask."));
+ threads = 1;
+ }
#if defined(_OPENMP)
omp_set_num_threads(threads);
#else
threads = 1;
#endif
- if (threads > 1 && Rast_mask_is_present()) {
- G_warning(_("Parallel processing disabled due to active mask."));
- threads = 1;
- }
G_message(_("Number of threads: %d"), threads);
/* sscanf(parm.nwalk->answer, "%d", &wp.maxwa); */
diff --git a/raster/r.sim/r.sim.water/main.c b/raster/r.sim/r.sim.water/main.c
index d4a545172a5..82a5152ff7b 100644
--- a/raster/r.sim/r.sim.water/main.c
+++ b/raster/r.sim/r.sim.water/main.c
@@ -416,15 +416,15 @@ int main(int argc, char *argv[])
threads, abs(threads));
threads = abs(threads);
}
+ if (threads > 1 && Rast_mask_is_present()) {
+ G_warning(_("Parallel processing disabled due to active mask."));
+ threads = 1;
+ }
#if defined(_OPENMP)
omp_set_num_threads(threads);
#else
threads = 1;
#endif
- if (threads > 1 && Rast_mask_is_present()) {
- G_warning(_("Parallel processing disabled due to active mask."));
- threads = 1;
- }
G_message(_("Number of threads: %d"), threads);
/* if no rain map input, then: */
diff --git a/utils/generate_release_notes.py b/utils/generate_release_notes.py
index 4ad19fdb060..8c6c79043fa 100755
--- a/utils/generate_release_notes.py
+++ b/utils/generate_release_notes.py
@@ -125,7 +125,7 @@ def print_by_category(changes, categories, file=None):
def binder_badge(tag):
"""Get mybinder Binder badge from a given tag, hash, or branch"""
binder_image_url = "https://mybinder.org/badge_logo.svg"
- binder_url = f"https://mybinder.org/v2/gh/OSGeo/grass/{tag}?urlpath=lab%2Ftree%2Fdoc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb" # noqa
+ binder_url = f"https://mybinder.org/v2/gh/OSGeo/grass/{tag}?urlpath=lab%2Ftree%2Fdoc%2Fexamples%2Fnotebooks%2Fjupyter_example.ipynb"
return f"[![Binder]({binder_image_url})]({binder_url})"
diff --git a/utils/gitlog2changelog.py b/utils/gitlog2changelog.py
index f878041ca83..9b60f7c54fb 100755
--- a/utils/gitlog2changelog.py
+++ b/utils/gitlog2changelog.py
@@ -30,9 +30,6 @@
process = subprocess.Popen(git_command, stdout=subprocess.PIPE, encoding="utf8")
fin = process.stdout
-# Create a ChangeLog file in the current directory.
-fout = open("ChangeLog", "w")
-
# Set up the loop variables in order to locate the blocks we want
authorFound = False
dateFound = False
@@ -45,101 +42,101 @@
wrapper = TextWrapper(initial_indent="\t", subsequent_indent="\t ")
-# The main part of the loop
-for line in fin:
- # The commit line marks the start of a new commit object.
- if line.startswith("commit"):
- # Start all over again...
- authorFound = False
- dateFound = False
- messageFound = False
- messageNL = False
- message = ""
- filesFound = False
- files = ""
- continue
- # Match the author line and extract the part we want
- # (Don't use startswith to allow Author override inside commit message.)
- elif "Author:" in line:
- authorList = re.split(r": ", line, 1)
- try:
- author = authorList[1]
- author = author[0 : len(author) - 1]
- authorFound = True
- except Exception as e:
- print(f"Could not parse authorList = '{line}'. Error: {e!s}")
+with open("ChangeLog", "w") as fout:
+ # The main part of the loop
+ for line in fin:
+ # The commit line marks the start of a new commit object.
+ if line.startswith("commit"):
+ # Start all over again...
+ authorFound = False
+ dateFound = False
+ messageFound = False
+ messageNL = False
+ message = ""
+ filesFound = False
+ files = ""
+ continue
+ # Match the author line and extract the part we want
+ # (Don't use startswith to allow Author override inside commit message.)
+ elif "Author:" in line:
+ authorList = re.split(r": ", line, 1)
+ try:
+ author = authorList[1]
+ author = author[0 : len(author) - 1]
+ authorFound = True
+ except Exception as e:
+ print(f"Could not parse authorList = '{line}'. Error: {e!s}")
- # Match the date line
- elif line.startswith("Date:"):
- dateList = re.split(r": ", line, 1)
- try:
- date = dateList[1]
- date = date[0 : len(date) - 1]
- dateFound = True
- except Exception as e:
- print(f"Could not parse dateList = '{line}'. Error: {e!s}")
- # The Fossil-IDs, svn-id, ad sign off lines are ignored:
- elif (
- line.startswith((" Fossil-ID:", " [[SVN:"))
- or " git-svn-id:" in line
- or "Signed-off-by" in line
- ):
- continue
- # Extract the actual commit message for this commit
- elif authorFound & dateFound & messageFound is False:
- # Find the commit message if we can
- if len(line) == 1:
- if messageNL:
+ # Match the date line
+ elif line.startswith("Date:"):
+ dateList = re.split(r": ", line, 1)
+ try:
+ date = dateList[1]
+ date = date[0 : len(date) - 1]
+ dateFound = True
+ except Exception as e:
+ print(f"Could not parse dateList = '{line}'. Error: {e!s}")
+ # The Fossil-IDs, svn-id, ad sign off lines are ignored:
+ elif (
+ line.startswith((" Fossil-ID:", " [[SVN:"))
+ or " git-svn-id:" in line
+ or "Signed-off-by" in line
+ ):
+ continue
+ # Extract the actual commit message for this commit
+ elif authorFound & dateFound & messageFound is False:
+ # Find the commit message if we can
+ if len(line) == 1:
+ if messageNL:
+ messageFound = True
+ else:
+ messageNL = True
+ elif len(line) == 4:
messageFound = True
+ elif len(message) == 0:
+ message += line.strip()
else:
- messageNL = True
- elif len(line) == 4:
- messageFound = True
- elif len(message) == 0:
- message += line.strip()
- else:
- message = message + " " + line.strip()
- # If this line is hit all of the files have been stored for this commit
- elif re.search(r"files? changed", line):
- filesFound = True
- continue
- # Collect the files for this commit. FIXME: Still need to add +/- to files
- elif authorFound & dateFound & messageFound:
- fileList = re.split(r" \| ", line, 2)
- if len(fileList) > 1:
- if len(files) > 0:
- files = files + ", " + fileList[0].strip()
+ message = message + " " + line.strip()
+ # If this line is hit all of the files have been stored for this commit
+ elif re.search(r"files? changed", line):
+ filesFound = True
+ continue
+ # Collect the files for this commit. FIXME: Still need to add +/- to files
+ elif authorFound & dateFound & messageFound:
+ fileList = re.split(r" \| ", line, 2)
+ if len(fileList) > 1:
+ if len(files) > 0:
+ files = files + ", " + fileList[0].strip()
+ else:
+ files = fileList[0].strip()
+ # All of the parts of the commit have been found - write out the entry
+ if authorFound & dateFound & messageFound & filesFound:
+ # First the author line, only outputted if it is the first for that
+ # author on this day
+ authorLine = date + " " + author
+ if len(prevAuthorLine) == 0:
+ fout.write(authorLine + "\n\n")
+ elif authorLine == prevAuthorLine:
+ pass
else:
- files = fileList[0].strip()
- # All of the parts of the commit have been found - write out the entry
- if authorFound & dateFound & messageFound & filesFound:
- # First the author line, only outputted if it is the first for that
- # author on this day
- authorLine = date + " " + author
- if len(prevAuthorLine) == 0:
- fout.write(authorLine + "\n\n")
- elif authorLine == prevAuthorLine:
- pass
- else:
- fout.write("\n" + authorLine + "\n\n")
+ fout.write("\n" + authorLine + "\n\n")
- # Assemble the actual commit message line(s) and limit the line length
- # to 80 characters.
- commitLine = "* " + files + ": " + message
+ # Assemble the actual commit message line(s) and limit the line length
+ # to 80 characters.
+ commitLine = "* " + files + ": " + message
- # Write out the commit line
- fout.write(wrapper.fill(commitLine) + "\n")
+ # Write out the commit line
+ fout.write(wrapper.fill(commitLine) + "\n")
- # Now reset all the variables ready for a new commit block.
- authorFound = False
- dateFound = False
- messageFound = False
- messageNL = False
- message = ""
- filesFound = False
- files = ""
- prevAuthorLine = authorLine
+ # Now reset all the variables ready for a new commit block.
+ authorFound = False
+ dateFound = False
+ messageFound = False
+ messageNL = False
+ message = ""
+ filesFound = False
+ files = ""
+ prevAuthorLine = authorLine
# Close the input and output lines now that we are finished.
fin.close()
-fout.close()
diff --git a/utils/grass_html2md.sh b/utils/grass_html2md.sh
new file mode 100755
index 00000000000..9ac2e548ae1
--- /dev/null
+++ b/utils/grass_html2md.sh
@@ -0,0 +1,69 @@
+#!/bin/bash
+set -eu
+
+###############################################################################
+# Convert recursively all .html files to .md (GitHub flavoured Markdown)
+#
+# Dependencies:
+# pandoc
+# wget
+#
+# Author(s):
+# Martin Landa, Markus Neteler
+#
+# Usage:
+# If you have "pandoc" in PATH, execute for HTML file conversion in
+# current directory and subdirectories:
+# ./utils/grass_html2md.sh
+#
+# COPYRIGHT: (C) 2024 by the GRASS Development Team
+#
+# This program is free software under the GNU General Public
+# License (>=v2). Read the file COPYING that comes with GRASS
+# for details.
+#
+###############################################################################
+
+# cleanup at user break
+cleanup()
+{
+ rm -f "${f%%.html}_tmp.html"
+}
+
+# what to do in case of user break:
+exitprocedure()
+{
+ echo "User break!"
+ cleanup
+ exit 1
+}
+# shell check for user break (signal list: trap -l)
+trap "exitprocedure" 2 3 15
+
+# path to LUA file (./utils/pandoc_codeblock.lua)
+UTILSPATH="utils"
+
+# run recursively: HTML to MD
+for f in $(find . -name *.html); do
+ echo "${f}"
+
+ # HTML: Process the tmp file to selectively replace .html with .md only in relative URLs
+ sed -E '
+ # Step 1: Preserve http/https links with .html (and optional anchors)
+ s|(|\1_KEEPHTML\2">|g;
+ # Step 2: Replace .html with .md for local links (with or without anchors)
+ s|(|\1\2.md\3">|g;
+ # Step 3: Restore preserved http/https links with .html
+ s|_KEEPHTML||g;
+' "${f%%.html}.html" > "${f%%.html}_tmp.html"
+
+ cat "${f%%.html}_tmp.html" | \
+ sed 's#