- """.format(layer, reason)
- bodyHtml = bodyHtml.replace('WRITTING_ERRORS', errors)
- return bodyHtml.replace('STEP_ELAPSED_TIME', elapsedTime) + "\n"
+ """.format(
+ layer, reason
+ )
+ bodyHtml = bodyHtml.replace("WRITTING_ERRORS", errors)
+ return bodyHtml.replace("STEP_ELAPSED_TIME", elapsedTime) + "\n"
- def convertFromMap(self, conversionMap=None, featureConversionMap=None, feedback=None):
+ def convertFromMap(
+ self, conversionMap=None, featureConversionMap=None, feedback=None
+ ):
"""
Converts all datasets from a conversion map.
:param conversionMap: (dict) conversion map generated by Datasource Conversion tool.
@@ -644,10 +765,16 @@ def convertFromMap(self, conversionMap=None, featureConversionMap=None, feedback
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
# input setup
- self.conversionUpdated.emit(self.tr("\nConversion Step {0} started...\n\n").format(conversionStep))
- self.conversionUpdated.emit(self.tr("[INPUT] Reading {0}'s layers...\n").format(inputDb))
+ self.conversionUpdated.emit(
+ self.tr("\nConversion Step {0} started...\n\n").format(conversionStep)
+ )
+ self.conversionUpdated.emit(
+ self.tr("[INPUT] Reading {0}'s layers...\n").format(inputDb)
+ )
if inputDb not in allInputLayers:
- allInputLayers[inputDb] = self.readInputLayers(datasourcePath=inputDb, feedback=multiStepFeedback)
+ allInputLayers[inputDb] = self.readInputLayers(
+ datasourcePath=inputDb, feedback=multiStepFeedback
+ )
inputLayers = allInputLayers[inputDb]
for currentOutput, conversionStepMap in enumerate(conversionStepMaps):
startTime = time.time()
@@ -657,57 +784,98 @@ def convertFromMap(self, conversionMap=None, featureConversionMap=None, feedback
outputDb = conversionStepMap["outDs"]
if outputDb not in allOutputLayers:
if conversionStepMap["createDs"]:
- self.conversionUpdated.emit(self.tr("[OUTPUT] Creating dataset {0}...\n").format(outputDb))
- outputAbstractDb, error = self.checkAndCreateDataset(conversionStepMap)
+ self.conversionUpdated.emit(
+ self.tr("[OUTPUT] Creating dataset {0}...\n").format(
+ outputDb
+ )
+ )
+ outputAbstractDb, error = self.checkAndCreateDataset(
+ conversionStepMap
+ )
del outputAbstractDb
if error != "":
k = "{0} to {1}".format(inputDb, outputDb)
- self.conversionUpdated.emit(self.tr("Dataset creation error ({0}): '{1}'\n").format(outputDb, error))
+ self.conversionUpdated.emit(
+ self.tr("Dataset creation error ({0}): '{1}'\n").format(
+ outputDb, error
+ )
+ )
errors[k] = error
- conversionSummary += self.addConversionStepToLog(conversionStep, inputDb, outputDb, \
- inputLayers, errors, {}, {}, "{0:.2f} s".format(time.time() - startTime))
+ conversionSummary += self.addConversionStepToLog(
+ conversionStep,
+ inputDb,
+ outputDb,
+ inputLayers,
+ errors,
+ {},
+ {},
+ "{0:.2f} s".format(time.time() - startTime),
+ )
conversionStep += 1
continue
- self.conversionUpdated.emit(self.tr("[OUTPUT] Reading {0}'s layers...\n").format(outputDb))
+ self.conversionUpdated.emit(
+ self.tr("[OUTPUT] Reading {0}'s layers...\n").format(outputDb)
+ )
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
- allOutputLayers[outputDb] = self.readOutputLayers(datasourcePath=outputDb, feedback=multiStepFeedback)
+ allOutputLayers[outputDb] = self.readOutputLayers(
+ datasourcePath=outputDb, feedback=multiStepFeedback
+ )
outputLayers = allOutputLayers[outputDb]
# now conversion starts
- self.conversionUpdated.emit(self.tr("Preparing {0}'s layers for conversion...").format(inputDb))
+ self.conversionUpdated.emit(
+ self.tr("Preparing {0}'s layers for conversion...").format(inputDb)
+ )
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
- preparedLayers = self.prepareInputLayers(inputLayers, conversionStepMap, feedback=multiStepFeedback)
+ preparedLayers = self.prepareInputLayers(
+ inputLayers, conversionStepMap, feedback=multiStepFeedback
+ )
self.conversionUpdated.emit(self.tr("Mapping features..."))
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
- mappedFeatures = self.mapFeatures(preparedLayers, outputLayers, feedback=multiStepFeedback)
+ mappedFeatures = self.mapFeatures(
+ preparedLayers, outputLayers, feedback=multiStepFeedback
+ )
- self.conversionUpdated.emit(self.tr("Loading layers to {0}...").format(outputDb))
+ self.conversionUpdated.emit(
+ self.tr("Loading layers to {0}...").format(outputDb)
+ )
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
successfulLayers, failedLayers = self.loadToOuput(
- mappedFeatures, outputLayers, conversionStepMap["conversionMode"],\
- feedback=multiStepFeedback
- )
+ mappedFeatures,
+ outputLayers,
+ conversionStepMap["conversionMode"],
+ feedback=multiStepFeedback,
+ )
# log update
- conversionSummary += self.addConversionStepToLog(conversionStep, inputDb, outputDb, inputLayers, \
- errors, successfulLayers, failedLayers, "{0:.2f} s".format(time.time() - startTime))
+ conversionSummary += self.addConversionStepToLog(
+ conversionStep,
+ inputDb,
+ outputDb,
+ inputLayers,
+ errors,
+ successfulLayers,
+ failedLayers,
+ "{0:.2f} s".format(time.time() - startTime),
+ )
conversionStep += 1
self.conversionFinished.emit()
return {
- 'creationErrors' : errors,
- 'successfulLayers' : successfulLayers,
- 'failedLayers' : failedLayers,
- 'status' : not feedback.isCanceled(),
- 'log' : conversionSummary
+ "creationErrors": errors,
+ "successfulLayers": successfulLayers,
+ "failedLayers": failedLayers,
+ "status": not feedback.isCanceled(),
+ "log": conversionSummary,
}
-
+
def run(self):
elapsedTime = time.time()
self.output = self.convertFromMap()
- self.output['elapsedTime'] = "{0:.2f} s".format(time.time() - elapsedTime)
- self.output['log'] = self.output['log'].replace('ELAPSED_TIME', self.output['elapsedTime'])
- return self.output['status']
-
+ self.output["elapsedTime"] = "{0:.2f} s".format(time.time() - elapsedTime)
+ self.output["log"] = self.output["log"].replace(
+ "ELAPSED_TIME", self.output["elapsedTime"]
+ )
+ return self.output["status"]
diff --git a/DsgTools/core/EditingTools/editingHandler.py b/DsgTools/core/EditingTools/editingHandler.py
index 68ab3a044..6cfcf03ff 100644
--- a/DsgTools/core/EditingTools/editingHandler.py
+++ b/DsgTools/core/EditingTools/editingHandler.py
@@ -21,5 +21,6 @@
***************************************************************************/
"""
+
class EditingHandler:
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/core/EditingTools/enviromentSetter.py b/DsgTools/core/EditingTools/enviromentSetter.py
index be334461b..d590a3069 100644
--- a/DsgTools/core/EditingTools/enviromentSetter.py
+++ b/DsgTools/core/EditingTools/enviromentSetter.py
@@ -20,14 +20,17 @@
* *
***************************************************************************/
"""
-from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory
+from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import (
+ LayerLoaderFactory,
+)
from qgis.core import QgsProject
+
class EnviromentSetter:
def __init__(self, iface):
self.layerFactory = LayerLoaderFactory()
self.iface = iface
-
+
def setEnviroment(self, parameterDict):
"""
:param parameterDict (dict): dictionary with parameters
@@ -39,22 +42,20 @@ def setEnviroment(self, parameterDict):
'framePolygon' : polygon of the working area
}
"""
- #Step 1: Load layers
+ # Step 1: Load layers
layerLoader = self.layerFactory.makeLoader(
- iface=self.iface,
- abstractDb=parameterDict['abstractDb']
+ iface=self.iface, abstractDb=parameterDict["abstractDb"]
)
loadedLayerDict = layerLoader.loadedLayers(
- inputList=parameterDict['layerList'],
- stylePath=parameterDict['stylePath'],
- loadEditingStructure=True
+ inputList=parameterDict["layerList"],
+ stylePath=parameterDict["stylePath"],
+ loadEditingStructure=True,
)
self.setLayerOrdering(
- vectorLayerDict=loadedLayerDict,
- layerOrder=parameterDict['layerList']
+ vectorLayerDict=loadedLayerDict, layerOrder=parameterDict["layerList"]
)
- self.createGrid(parameterDict['workingAreaPolygon'])
- self.setWorkArea(parameterDict['workingAreaPolygon'])
+ self.createGrid(parameterDict["workingAreaPolygon"])
+ self.setWorkArea(parameterDict["workingAreaPolygon"])
def createGrid(self, workingAreaPolygon):
"""
diff --git a/DsgTools/core/EditingTools/gridAndLabelCreator.py b/DsgTools/core/EditingTools/gridAndLabelCreator.py
index 9e6346d77..ce1166fa6 100644
--- a/DsgTools/core/EditingTools/gridAndLabelCreator.py
+++ b/DsgTools/core/EditingTools/gridAndLabelCreator.py
@@ -22,13 +22,27 @@
"""
from builtins import str, range, abs, round
from math import floor, ceil, pow
-from qgis.core import QgsProject, QgsVectorLayer, QgsCoordinateTransform, \
- QgsCoordinateReferenceSystem, QgsFillSymbol, QgsLineSymbol, \
- QgsSimpleFillSymbolLayer, QgsSingleSymbolRenderer, \
- QgsInvertedPolygonRenderer, QgsRuleBasedRenderer, QgsPoint,\
- QgsGeometry, QgsGeometryGeneratorSymbolLayer
-from qgis.core import QgsRuleBasedLabeling, QgsPalLayerSettings, QgsTextFormat, \
- QgsPropertyCollection
+from qgis.core import (
+ QgsProject,
+ QgsVectorLayer,
+ QgsCoordinateTransform,
+ QgsCoordinateReferenceSystem,
+ QgsFillSymbol,
+ QgsLineSymbol,
+ QgsSimpleFillSymbolLayer,
+ QgsSingleSymbolRenderer,
+ QgsInvertedPolygonRenderer,
+ QgsRuleBasedRenderer,
+ QgsPoint,
+ QgsGeometry,
+ QgsGeometryGeneratorSymbolLayer,
+)
+from qgis.core import (
+ QgsRuleBasedLabeling,
+ QgsPalLayerSettings,
+ QgsTextFormat,
+ QgsPropertyCollection,
+)
from qgis.utils import iface
from qgis.gui import QgsMessageBar
from PyQt5.QtGui import QColor, QFont
@@ -37,12 +51,57 @@
class GridAndLabelCreator(object):
def __init__(self, parent=None):
super(GridAndLabelCreator, self).__init__()
-
- def geo_test(self, layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor):
+
+ def geo_test(
+ self,
+ layer,
+ index,
+ id_attr,
+ id_value,
+ spacing,
+ crossX,
+ crossY,
+ scale,
+ color,
+ fontSize,
+ font,
+ fontLL,
+ llcolor,
+ ):
if layer.crs().isGeographic() == False:
- self.styleCreator(layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, True)
+ self.styleCreator(
+ layer,
+ index,
+ id_attr,
+ id_value,
+ spacing,
+ crossX,
+ crossY,
+ scale,
+ color,
+ fontSize,
+ font,
+ fontLL,
+ llcolor,
+ True,
+ )
else:
- self.styleCreator(layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, False)
+ self.styleCreator(
+ layer,
+ index,
+ id_attr,
+ id_value,
+ spacing,
+ crossX,
+ crossY,
+ scale,
+ color,
+ fontSize,
+ font,
+ fontLL,
+ llcolor,
+ False,
+ )
pass
def utmLLtransform(self, utmcheck, p1, trLLUTM):
@@ -51,21 +110,47 @@ def utmLLtransform(self, utmcheck, p1, trLLUTM):
return p1
pass
- def crossLinegenerator(self, xmin_source, ymin_source, px, py, u, t, dx, dy, utmcheck, trLLUTM):
- p1 = QgsPoint(xmin_source+px*u, ymin_source+py*t)
- p2 = QgsPoint(xmin_source+px*u+dx, ymin_source+py*t+dy)
+ def crossLinegenerator(
+ self, xmin_source, ymin_source, px, py, u, t, dx, dy, utmcheck, trLLUTM
+ ):
+ p1 = QgsPoint(xmin_source + px * u, ymin_source + py * t)
+ p2 = QgsPoint(xmin_source + px * u + dx, ymin_source + py * t + dy)
self.utmLLtransform(utmcheck, p1, trLLUTM)
self.utmLLtransform(utmcheck, p2, trLLUTM)
- properties = {'color': 'black'}
+ properties = {"color": "black"}
line_temp = QgsLineSymbol.createSimple(properties)
line_temp.setWidth(0.05)
symb = QgsGeometryGeneratorSymbolLayer.create(properties)
symb.setSymbolType(1)
symb.setSubSymbol(line_temp)
- symb.setGeometryExpression('make_line(make_point('+str(p1.x())+',('+str(p1.y())+')),make_point('+str(p2.x())+',('+str(p2.y())+')))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(p1.x())
+ + ",("
+ + str(p1.y())
+ + ")),make_point("
+ + str(p2.x())
+ + ",("
+ + str(p2.y())
+ + ")))"
+ )
return symb
- def gridLinesymbolMaker(self, x1, y1, x2, y2, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, isVertical):
+ def gridLinesymbolMaker(
+ self,
+ x1,
+ y1,
+ x2,
+ y2,
+ xmax_source,
+ xmin_source,
+ ymax_source,
+ ymin_source,
+ trUTMLL,
+ trLLUTM,
+ utmcheck,
+ isVertical,
+ ):
a1 = QgsPoint(x1, y1)
a2 = QgsPoint(x2, y2)
a1.transform(trUTMLL)
@@ -80,9 +165,25 @@ def gridLinesymbolMaker(self, x1, y1, x2, y2, xmax_source, xmin_source, ymax_sou
p2 = QgsPoint(xmax_source, a2.y())
self.utmLLtransform(utmcheck, p1, trLLUTM)
self.utmLLtransform(utmcheck, p2, trLLUTM)
- return [a1,a2,p1,p2]
+ return [a1, a2, p1, p2]
- def utm_symb_generator(self, grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, t, u, geo_bound_bb, bound_UTM_bb, utmcheck):
+ def utm_symb_generator(
+ self,
+ grid_spacing,
+ trUTMLL,
+ trLLUTM,
+ grid_symb,
+ properties,
+ geo_number_x,
+ geo_number_y,
+ UTM_num_x,
+ UTM_num_y,
+ t,
+ u,
+ geo_bound_bb,
+ bound_UTM_bb,
+ utmcheck,
+ ):
xmin_source = float(geo_bound_bb.split()[1])
ymin_source = float(geo_bound_bb.split()[2])
xmax_source = float(geo_bound_bb.split()[3])
@@ -91,156 +192,416 @@ def utm_symb_generator(self, grid_spacing, trUTMLL, trLLUTM, grid_symb, properti
ymin_UTM = float(bound_UTM_bb.split()[2])
xmax_UTM = float(bound_UTM_bb.split()[3])
ymax_UTM = float(bound_UTM_bb.split()[4])
- test_line = [None]*2
- properties = {'color': 'black'}
+ test_line = [None] * 2
+ properties = {"color": "black"}
line_temp = QgsLineSymbol.createSimple(properties)
line_temp.setWidth(0.05)
symb = QgsGeometryGeneratorSymbolLayer.create(properties)
symb.setSymbolType(1)
symb.setSubSymbol(line_temp)
- #Test First And Last Grid Lines
- #Vertical
+ # Test First And Last Grid Lines
+ # Vertical
if (t == 1 and u == 0) or (t == UTM_num_x and u == 0):
- #Symbol vertices
- auxPointlist = self.gridLinesymbolMaker(((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymin_UTM, ((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymax_UTM, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, True)
- #0: left bound; 1: right bound
- test_line[0] = QgsGeometry.fromWkt('LINESTRING ('+str(xmin_source)+' '+str(ymin_source)+','+str(xmin_source)+' '+str(ymax_source)+')')
- test_line[1] = QgsGeometry.fromWkt('LINESTRING ('+str(xmax_source)+' '+str(ymin_source)+','+str(xmax_source)+' '+str(ymax_source)+')')
- test_grid = QgsGeometry.fromPolyline([auxPointlist[0],auxPointlist[1]])
+ # Symbol vertices
+ auxPointlist = self.gridLinesymbolMaker(
+ ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing),
+ ymin_UTM,
+ ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing),
+ ymax_UTM,
+ xmax_source,
+ xmin_source,
+ ymax_source,
+ ymin_source,
+ trUTMLL,
+ trLLUTM,
+ utmcheck,
+ True,
+ )
+ # 0: left bound; 1: right bound
+ test_line[0] = QgsGeometry.fromWkt(
+ "LINESTRING ("
+ + str(xmin_source)
+ + " "
+ + str(ymin_source)
+ + ","
+ + str(xmin_source)
+ + " "
+ + str(ymax_source)
+ + ")"
+ )
+ test_line[1] = QgsGeometry.fromWkt(
+ "LINESTRING ("
+ + str(xmax_source)
+ + " "
+ + str(ymin_source)
+ + ","
+ + str(xmax_source)
+ + " "
+ + str(ymax_source)
+ + ")"
+ )
+ test_grid = QgsGeometry.fromPolyline([auxPointlist[0], auxPointlist[1]])
if test_line[0].intersects(test_grid):
mid_point = test_line[0].intersection(test_grid).vertexAt(0)
self.utmLLtransform(utmcheck, mid_point, trLLUTM)
if auxPointlist[0].x() > auxPointlist[1].x():
- symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "))"
+ )
else:
- symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
elif test_line[1].intersects(test_grid):
mid_point = test_line[1].intersection(test_grid).vertexAt(0)
self.utmLLtransform(utmcheck, mid_point, trLLUTM)
if auxPointlist[0].x() < auxPointlist[1].x():
- symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "))"
+ )
else:
- symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
else:
- symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
- #Horizontal
+ # Horizontal
elif (u == 1 and t == 0) or (u == UTM_num_y and t == 0):
- #Symbol vertices
- auxPointlist = self.gridLinesymbolMaker(xmin_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, False)
- #0: bottom bound; 1: upper bound
- test_line[0] = QgsGeometry.fromWkt('LINESTRING ('+str(xmin_source)+' '+str(ymin_source)+','+str(xmax_source)+' '+str(ymin_source)+')')
- test_line[1] = QgsGeometry.fromWkt('LINESTRING ('+str(xmin_source)+' '+str(ymax_source)+','+str(xmax_source)+' '+str(ymax_source)+')')
- test_grid = QgsGeometry.fromPolyline([auxPointlist[0],auxPointlist[1]])
+ # Symbol vertices
+ auxPointlist = self.gridLinesymbolMaker(
+ xmin_UTM,
+ ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing),
+ xmax_UTM,
+ ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing),
+ xmax_source,
+ xmin_source,
+ ymax_source,
+ ymin_source,
+ trUTMLL,
+ trLLUTM,
+ utmcheck,
+ False,
+ )
+ # 0: bottom bound; 1: upper bound
+ test_line[0] = QgsGeometry.fromWkt(
+ "LINESTRING ("
+ + str(xmin_source)
+ + " "
+ + str(ymin_source)
+ + ","
+ + str(xmax_source)
+ + " "
+ + str(ymin_source)
+ + ")"
+ )
+ test_line[1] = QgsGeometry.fromWkt(
+ "LINESTRING ("
+ + str(xmin_source)
+ + " "
+ + str(ymax_source)
+ + ","
+ + str(xmax_source)
+ + " "
+ + str(ymax_source)
+ + ")"
+ )
+ test_grid = QgsGeometry.fromPolyline([auxPointlist[0], auxPointlist[1]])
if test_line[0].intersects(test_grid):
mid_point = test_line[0].intersection(test_grid).vertexAt(0)
self.utmLLtransform(utmcheck, mid_point, trLLUTM)
if auxPointlist[0].y() > auxPointlist[1].y():
- symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "))"
+ )
else:
- symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
elif test_line[1].intersects(test_grid):
mid_point = test_line[1].intersection(test_grid).vertexAt(0)
self.utmLLtransform(utmcheck, mid_point, trLLUTM)
if auxPointlist[0].y() < auxPointlist[1].y():
- symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(mid_point.x())+','+str(mid_point.y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "))"
+ )
else:
- symb.setGeometryExpression('make_line(make_point('+str(mid_point.x())+','+str(mid_point.y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))')
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(mid_point.x())
+ + ","
+ + str(mid_point.y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
else:
- symb.setGeometryExpression("make_line(make_point("+str(auxPointlist[2].x())+","+str(auxPointlist[2].y())+"), make_point("+str(auxPointlist[3].x())+","+str(auxPointlist[3].y())+"))")
-
- #Inner Grid Lines
- #Vertical
- elif (not(t == 1)) and (not(t == UTM_num_x)) and u == 0:
- auxPointlist = self.gridLinesymbolMaker(((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymin_UTM, ((floor(xmin_UTM/grid_spacing)+t)*grid_spacing), ymax_UTM, xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, True)
- symb.setGeometryExpression('make_line(make_point('+str(auxPointlist[2].x())+','+str(auxPointlist[2].y())+'), make_point('+str(auxPointlist[3].x())+','+str(auxPointlist[3].y())+'))')
- #Horizontal
- elif (not(u == 1)) and (not(u == UTM_num_y)) and t == 0:
- auxPointlist = self.gridLinesymbolMaker(xmin_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_UTM, ((floor(ymin_UTM/grid_spacing)+u)*grid_spacing), xmax_source, xmin_source, ymax_source, ymin_source, trUTMLL, trLLUTM, utmcheck, False)
- symb.setGeometryExpression("make_line(make_point("+str(auxPointlist[2].x())+","+str(auxPointlist[2].y())+"), make_point("+str(auxPointlist[3].x())+","+str(auxPointlist[3].y())+"))")
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
+
+ # Inner Grid Lines
+ # Vertical
+ elif (not (t == 1)) and (not (t == UTM_num_x)) and u == 0:
+ auxPointlist = self.gridLinesymbolMaker(
+ ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing),
+ ymin_UTM,
+ ((floor(xmin_UTM / grid_spacing) + t) * grid_spacing),
+ ymax_UTM,
+ xmax_source,
+ xmin_source,
+ ymax_source,
+ ymin_source,
+ trUTMLL,
+ trLLUTM,
+ utmcheck,
+ True,
+ )
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
+ # Horizontal
+ elif (not (u == 1)) and (not (u == UTM_num_y)) and t == 0:
+ auxPointlist = self.gridLinesymbolMaker(
+ xmin_UTM,
+ ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing),
+ xmax_UTM,
+ ((floor(ymin_UTM / grid_spacing) + u) * grid_spacing),
+ xmax_source,
+ xmin_source,
+ ymax_source,
+ ymin_source,
+ trUTMLL,
+ trLLUTM,
+ utmcheck,
+ False,
+ )
+ symb.setGeometryExpression(
+ "make_line(make_point("
+ + str(auxPointlist[2].x())
+ + ","
+ + str(auxPointlist[2].y())
+ + "), make_point("
+ + str(auxPointlist[3].x())
+ + ","
+ + str(auxPointlist[3].y())
+ + "))"
+ )
grid_symb.appendSymbolLayer(symb)
return grid_symb
- def grid_labeler(self, coord_base_x, coord_base_y, px, py, u, t, dx, dy, vAlign, hAlign, desc, fSize, fontType, expression_str, trLLUTM, trUTMLL, llcolor, utmcheck, scale):
+ def grid_labeler(
+ self,
+ coord_base_x,
+ coord_base_y,
+ px,
+ py,
+ u,
+ t,
+ dx,
+ dy,
+ vAlign,
+ hAlign,
+ desc,
+ fSize,
+ fontType,
+ expression_str,
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ ):
if utmcheck:
- pgrid = QgsPoint(coord_base_x + px*u, coord_base_y + py*t)
+ pgrid = QgsPoint(coord_base_x + px * u, coord_base_y + py * t)
pgrid.transform(trLLUTM)
- pgrid = QgsPoint(pgrid.x()+ dx, pgrid.y()+ dy)
+ pgrid = QgsPoint(pgrid.x() + dx, pgrid.y() + dy)
else:
- pgrid = QgsPoint(coord_base_x + px*u + dx, coord_base_y + py*t + dy)
+ pgrid = QgsPoint(coord_base_x + px * u + dx, coord_base_y + py * t + dy)
- #Label Format Settings
+ # Label Format Settings
settings = QgsPalLayerSettings()
settings.Placement = QgsPalLayerSettings.Free
settings.isExpression = True
textprop = QgsTextFormat()
textprop.setColor(llcolor)
textprop.setSizeUnit(1)
- textprop.setSize(fSize*scale*1.324)
+ textprop.setSize(fSize * scale * 1.324)
textprop.setFont(QFont(fontType))
textprop.setLineHeight(1)
settings.setFormat(textprop)
settings.fieldName = expression_str
- #Label Name and Position
+ # Label Name and Position
datadefined = QgsPropertyCollection()
datadefined.setProperty(9, pgrid.x())
datadefined.setProperty(10, pgrid.y())
- if not(hAlign == ''):
+ if not (hAlign == ""):
datadefined.setProperty(11, hAlign)
- if not(vAlign == ''):
+ if not (vAlign == ""):
datadefined.setProperty(12, vAlign)
datadefined.setProperty(20, 1)
-
- #Creating and Activating Labeling Rule
+
+ # Creating and Activating Labeling Rule
settings.setDataDefinedProperties(datadefined)
rule = QgsRuleBasedLabeling.Rule(settings)
rule.setDescription(desc)
rule.setActive(True)
-
- return rule
- def utm_grid_labeler(self, root_rule, x_UTM, y_UTM, x_geo, y_geo, px, py, trUTMLL, trLLUTM, u, isVertical, dx, dy, dyO, dy1, vAlign, hAlign, desc, fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangetest, geo_bb_or):
+ return rule
+ def utm_grid_labeler(
+ self,
+ root_rule,
+ x_UTM,
+ y_UTM,
+ x_geo,
+ y_geo,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ u,
+ isVertical,
+ dx,
+ dy,
+ dyO,
+ dy1,
+ vAlign,
+ hAlign,
+ desc,
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ rangetest,
+ geo_bb_or,
+ ):
- x_colec = [float(geo_bb_or.split()[2*i]) for i in range(1,5)]
+ x_colec = [float(geo_bb_or.split()[2 * i]) for i in range(1, 5)]
x_colec.sort()
- y_colec = [float(geo_bb_or.split()[2*i+1]) for i in range(1,5)]
+ y_colec = [float(geo_bb_or.split()[2 * i + 1]) for i in range(1, 5)]
y_colec.sort()
ang = float(geo_bb_or.split()[13])
if ang > 0:
- if 'Bot' in desc:
+ if "Bot" in desc:
x_min_test = x_colec[0]
x_max_test = x_colec[2]
- elif 'Up' in desc:
+ elif "Up" in desc:
x_min_test = x_colec[1]
x_max_test = x_colec[3]
- elif 'Left' in desc:
+ elif "Left" in desc:
y_min_test = y_colec[1]
y_max_test = y_colec[3]
- elif 'Right' in desc:
+ elif "Right" in desc:
y_min_test = y_colec[0]
y_max_test = y_colec[2]
elif ang <= 0:
- if 'Bot' in desc:
+ if "Bot" in desc:
x_min_test = x_colec[1]
x_max_test = x_colec[3]
- elif 'Up' in desc:
+ elif "Up" in desc:
x_min_test = x_colec[0]
x_max_test = x_colec[2]
- elif 'Left' in desc:
+ elif "Left" in desc:
y_min_test = y_colec[0]
y_max_test = y_colec[2]
- elif 'Right' in desc:
+ elif "Right" in desc:
y_min_test = y_colec[1]
y_max_test = y_colec[3]
x_min = float(geo_bound_bb.split()[1])
y_min = float(geo_bound_bb.split()[2])
x_max = float(geo_bound_bb.split()[3])
y_max = float(geo_bound_bb.split()[4])
-
+
# Check if is labeling grid's vertical lines
if isVertical:
# Displacing UTM Label that overlaps Geo Label
@@ -249,189 +610,531 @@ def utm_grid_labeler(self, root_rule, x_UTM, y_UTM, x_geo, y_geo, px, py, trUTML
else:
dx0 = dx
dx = 0
- test_plac = QgsPoint(((floor(x_UTM/grid_spacing)+u)*grid_spacing),y_UTM)
+ test_plac = QgsPoint(
+ ((floor(x_UTM / grid_spacing) + u) * grid_spacing), y_UTM
+ )
test_plac.transform(trUTMLL)
- ancX = QgsPoint(((floor(x_UTM/grid_spacing)+u)*grid_spacing)+dx,y_UTM)
+ ancX = QgsPoint(
+ ((floor(x_UTM / grid_spacing) + u) * grid_spacing) + dx, y_UTM
+ )
ancX.transform(trUTMLL)
- ancY = QgsPoint(ancX.x(),y_geo)
+ ancY = QgsPoint(ancX.x(), y_geo)
if utmcheck:
ancY.transform(trLLUTM)
- test = QgsPoint(((floor(x_UTM/grid_spacing)+u)*grid_spacing),y_UTM)
+ test = QgsPoint(((floor(x_UTM / grid_spacing) + u) * grid_spacing), y_UTM)
test.transform(trUTMLL)
- if u == 1 and 'Up' in desc:
+ if u == 1 and "Up" in desc:
deltaDneg = 0.0022
deltaDpos = 0.0011
- elif u == 1 and 'Bot' in desc:
+ elif u == 1 and "Bot" in desc:
deltaDneg = 0.00125
deltaDpos = 0.0011
else:
deltaDneg = 0.00095
deltaDpos = 0.0011
- testif = abs(floor(abs(round(test.x(), 4) - (x_min % (px)) - (deltaDneg*(fSize/1.5) * scale/10))/px) - floor(abs(round(test.x(), 4) - (x_min % (px)) + (deltaDpos*(fSize/1.5) * scale/10))/px))
+ testif = abs(
+ floor(
+ abs(
+ round(test.x(), 4)
+ - (x_min % (px))
+ - (deltaDneg * (fSize / 1.5) * scale / 10)
+ )
+ / px
+ )
+ - floor(
+ abs(
+ round(test.x(), 4)
+ - (x_min % (px))
+ + (deltaDpos * (fSize / 1.5) * scale / 10)
+ )
+ / px
+ )
+ )
if testif >= 1:
- ancY = QgsPoint(ancY.x(),ancY.y()+dyO)
+ ancY = QgsPoint(ancY.x(), ancY.y() + dyO)
else:
- ancY = QgsPoint(ancY.x(),ancY.y()+dy)
+ ancY = QgsPoint(ancY.x(), ancY.y() + dy)
x = ancX.x() + dx0
if utmcheck:
ancY.transform(trUTMLL)
- y =ancY.y()
- full_label = str((floor(x_UTM/grid_spacing)+u)*grid_spacing)
- if test_plac.x() < (x_min_test + (0.0005 * scale/10)) or test_plac.x() > (x_max_test - (0.0005 * scale/10)):
- rule_fake = self.grid_labeler(x, y, 0, 0, 0, 0, 0, 0, vAlign, hAlign, desc, fSize, fontType, 'fail', trLLUTM, trUTMLL, QColor('black'), utmcheck, scale)
+ y = ancY.y()
+ full_label = str((floor(x_UTM / grid_spacing) + u) * grid_spacing)
+ if test_plac.x() < (x_min_test + (0.0005 * scale / 10)) or test_plac.x() > (
+ x_max_test - (0.0005 * scale / 10)
+ ):
+ rule_fake = self.grid_labeler(
+ x,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ vAlign,
+ hAlign,
+ desc,
+ fSize,
+ fontType,
+ "fail",
+ trLLUTM,
+ trUTMLL,
+ QColor("black"),
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(rule_fake)
return root_rule
# Labeling grid's horizontal lines
else:
- test_plac = QgsPoint(x_UTM,(floor(y_UTM/grid_spacing)+u)*grid_spacing)
+ test_plac = QgsPoint(
+ x_UTM, (floor(y_UTM / grid_spacing) + u) * grid_spacing
+ )
test_plac.transform(trUTMLL)
- ancX = QgsPoint(x_UTM,(floor(y_UTM/grid_spacing)+u)*grid_spacing)
+ ancX = QgsPoint(x_UTM, (floor(y_UTM / grid_spacing) + u) * grid_spacing)
ancX.transform(trUTMLL)
ancX = QgsPoint(x_geo, ancX.y())
ancY = QgsPoint(x_geo, ancX.y())
if utmcheck:
ancY.transform(trLLUTM)
# Displacing UTM Label it overlaps with Geo Label
- test = QgsPoint(x_UTM,(floor(y_UTM/grid_spacing)+u)*grid_spacing)
+ test = QgsPoint(x_UTM, (floor(y_UTM / grid_spacing) + u) * grid_spacing)
test.transform(trUTMLL)
- testif = abs(floor(abs(round(test.y(), 4) - (y_min % (py)) - (0.0004*(fSize/1.5) * scale/10))/py) - floor(abs(round(test.y(), 4) - (y_min % (py)))/py))
+ testif = abs(
+ floor(
+ abs(
+ round(test.y(), 4)
+ - (y_min % (py))
+ - (0.0004 * (fSize / 1.5) * scale / 10)
+ )
+ / py
+ )
+ - floor(abs(round(test.y(), 4) - (y_min % (py))) / py)
+ )
if testif >= 1:
- ancY = QgsPoint(ancY.x(),ancY.y()+dy1)
+ ancY = QgsPoint(ancY.x(), ancY.y() + dy1)
else:
- testif2 = abs(floor(abs(round(test.y(), 4) - (y_min % (py)))/py) - floor(abs(round(test.y(), 4) - (y_min % (py)) + (0.0004*(fSize/1.5) * scale/10))/py))
+ testif2 = abs(
+ floor(abs(round(test.y(), 4) - (y_min % (py))) / py)
+ - floor(
+ abs(
+ round(test.y(), 4)
+ - (y_min % (py))
+ + (0.0004 * (fSize / 1.5) * scale / 10)
+ )
+ / py
+ )
+ )
if testif2 >= 1:
- ancY = QgsPoint(ancY.x(),ancY.y()+dyO)
+ ancY = QgsPoint(ancY.x(), ancY.y() + dyO)
else:
- ancY = QgsPoint(ancY.x(),ancY.y()+dy)
+ ancY = QgsPoint(ancY.x(), ancY.y() + dy)
if utmcheck:
dx0 = 0
ancX.transform(trLLUTM)
- ancX = QgsPoint(ancX.x()+dx, ancX.y())
+ ancX = QgsPoint(ancX.x() + dx, ancX.y())
ancX.transform(trUTMLL)
ancY.transform(trUTMLL)
else:
dx0 = dx
x = ancX.x() + dx0
y = ancY.y()
- full_label = str((floor(y_UTM/grid_spacing)+u)*grid_spacing)
- if test_plac.y() < (y_min_test + (0.0002 * scale/10)) or test_plac.y() > (y_max_test- (0.0002 * scale/10)):
- rule_fake = self.grid_labeler(x, y, 0, 0, 0, 0, 0, 0, vAlign, hAlign, desc, fSize, fontType, 'fail', trLLUTM, trUTMLL, QColor('black'), utmcheck, scale)
+ full_label = str((floor(y_UTM / grid_spacing) + u) * grid_spacing)
+ if test_plac.y() < (y_min_test + (0.0002 * scale / 10)) or test_plac.y() > (
+ y_max_test - (0.0002 * scale / 10)
+ ):
+ rule_fake = self.grid_labeler(
+ x,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ vAlign,
+ hAlign,
+ desc,
+ fSize,
+ fontType,
+ "fail",
+ trLLUTM,
+ trUTMLL,
+ QColor("black"),
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(rule_fake)
return root_rule
- ctrl_uni = {0:u'\u2070',1:u'\u00B9',2:u'\u00B2',3:u'\u00B3',4:u'\u2074',5:u'\u2075',6:u'\u2076',7:u'\u2077',8:u'\u2078',9:u'\u2079','m':u'\u1D50'}
+ ctrl_uni = {
+ 0: "\u2070",
+ 1: "\u00B9",
+ 2: "\u00B2",
+ 3: "\u00B3",
+ 4: "\u2074",
+ 5: "\u2075",
+ 6: "\u2076",
+ 7: "\u2077",
+ 8: "\u2078",
+ 9: "\u2079",
+ "m": "\u1D50",
+ }
full_label = [char for char in full_label]
- for j in range(0,len(full_label)):
- if not (j == len(full_label)-5 or j == len(full_label)-4):
+ for j in range(0, len(full_label)):
+ if not (j == len(full_label) - 5 or j == len(full_label) - 4):
full_label[j] = ctrl_uni[int(full_label[j])]
- full_label = ''.join(full_label)
- expression_str = str('\'') + full_label + str('\'')
+ full_label = "".join(full_label)
+ expression_str = str("'") + full_label + str("'")
fontType.setWeight(50)
- fSizeAlt = fSize * 5/3
- if u == min(rangetest) and any(spec_lbl in desc for spec_lbl in ('Bot','Left')):
- extra_label = ' ' + 'N'
- dyT = 0.5*scale*fSize/1.5
+ fSizeAlt = fSize * 5 / 3
+ if u == min(rangetest) and any(
+ spec_lbl in desc for spec_lbl in ("Bot", "Left")
+ ):
+ extra_label = " " + "N"
+ dyT = 0.5 * scale * fSize / 1.5
if len(expression_str) == 9:
- dxT = 3.5*scale*fSize/1.5
+ dxT = 3.5 * scale * fSize / 1.5
elif len(expression_str) == 6:
- dxT = 1.5*scale*fSize/1.5
+ dxT = 1.5 * scale * fSize / 1.5
elif len(expression_str) == 7:
- dxT = 2.5*scale*fSize/1.5
+ dxT = 2.5 * scale * fSize / 1.5
if isVertical:
- extra_label = ' ' + 'E'
- dyT = 0.5*scale*fSize/1.5
- dxT = 3.0*scale*fSize/1.5
- expression_str =str('\'') + full_label + extra_label + str('\'')
- plac_m = QgsPoint(x,y)
+ extra_label = " " + "E"
+ dyT = 0.5 * scale * fSize / 1.5
+ dxT = 3.0 * scale * fSize / 1.5
+ expression_str = str("'") + full_label + extra_label + str("'")
+ plac_m = QgsPoint(x, y)
plac_m.transform(trLLUTM)
- plac_new = QgsPoint(plac_m.x()+dxT,plac_m.y()+dyT)
+ plac_new = QgsPoint(plac_m.x() + dxT, plac_m.y() + dyT)
plac_new.transform(trUTMLL)
- ruleUTM2 = self.grid_labeler(plac_new.x(), plac_new.y(), 0, 0, 0, 0, 0, 0, vAlign, 'Center', desc+'m', fSizeAlt, fontType, str('\'')+ctrl_uni['m']+str('\''), trLLUTM, trUTMLL, QColor('black'), utmcheck, scale)
+ ruleUTM2 = self.grid_labeler(
+ plac_new.x(),
+ plac_new.y(),
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ vAlign,
+ "Center",
+ desc + "m",
+ fSizeAlt,
+ fontType,
+ str("'") + ctrl_uni["m"] + str("'"),
+ trLLUTM,
+ trUTMLL,
+ QColor("black"),
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruleUTM2)
- ruleUTM = self.grid_labeler(x, y, 0, 0, 0, 0, 0, 0, vAlign, hAlign, desc, fSizeAlt, fontType, expression_str, trLLUTM, trUTMLL, QColor('black'), utmcheck, scale)
+ ruleUTM = self.grid_labeler(
+ x,
+ y,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ vAlign,
+ hAlign,
+ desc,
+ fSizeAlt,
+ fontType,
+ expression_str,
+ trLLUTM,
+ trUTMLL,
+ QColor("black"),
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruleUTM)
return root_rule
def conv_dec_gms(self, base_coord, coord_spacing, u, neg_character, pos_character):
-
- xbase = base_coord + coord_spacing*u
+
+ xbase = base_coord + coord_spacing * u
x = abs(xbase)
- xdeg = floor(round(x,4))
- xmin = floor(round(((x - xdeg)*60),4))
- xseg = floor(round(((x - xdeg - xmin/60)*3600),4))
+ xdeg = floor(round(x, 4))
+ xmin = floor(round(((x - xdeg) * 60), 4))
+ xseg = floor(round(((x - xdeg - xmin / 60) * 3600), 4))
if xbase < 0:
xhem = neg_character
else:
xhem = pos_character
- conv_exp_str = '\'' + str(xdeg).rjust(2,'0') + 'º ' + str(xmin).rjust(2,'0') + str('\\') + str('\' ') + str(xseg).rjust(2,'0') + '"\'' + '+\' ' + str(xhem) + '\''
+ conv_exp_str = (
+ "'"
+ + str(xdeg).rjust(2, "0")
+ + "º "
+ + str(xmin).rjust(2, "0")
+ + str("\\")
+ + str("' ")
+ + str(xseg).rjust(2, "0")
+ + "\"'"
+ + "+' "
+ + str(xhem)
+ + "'"
+ )
return conv_exp_str
- def geoGridcreator(self, grid_symb, geo_bound_bb, geo_number_x, geo_number_y, scale, utmcheck, trLLUTM):
+ def geoGridcreator(
+ self,
+ grid_symb,
+ geo_bound_bb,
+ geo_number_x,
+ geo_number_y,
+ scale,
+ utmcheck,
+ trLLUTM,
+ ):
xmin_source = float(geo_bound_bb.split()[1])
ymin_source = float(geo_bound_bb.split()[2])
xmax_source = float(geo_bound_bb.split()[3])
ymax_source = float(geo_bound_bb.split()[4])
-
- px = (xmax_source-xmin_source)/(geo_number_x+1)
- py = (ymax_source-ymin_source)/(geo_number_y+1)
-
- for u in range(1, (geo_number_x+2)):
- for t in range(0, (geo_number_y+2)):
- symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, -0.00002145*scale, 0, utmcheck, trLLUTM)
+
+ px = (xmax_source - xmin_source) / (geo_number_x + 1)
+ py = (ymax_source - ymin_source) / (geo_number_y + 1)
+
+ for u in range(1, (geo_number_x + 2)):
+ for t in range(0, (geo_number_y + 2)):
+ symb_cross = self.crossLinegenerator(
+ xmin_source,
+ ymin_source,
+ px,
+ py,
+ u,
+ t,
+ -0.00002145 * scale,
+ 0,
+ utmcheck,
+ trLLUTM,
+ )
grid_symb.appendSymbolLayer(symb_cross)
- for u in range(0, (geo_number_x+2)):
- for t in range(1, (geo_number_y+2)):
- symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, 0, -0.00002145*scale, utmcheck, trLLUTM)
+ for u in range(0, (geo_number_x + 2)):
+ for t in range(1, (geo_number_y + 2)):
+ symb_cross = self.crossLinegenerator(
+ xmin_source,
+ ymin_source,
+ px,
+ py,
+ u,
+ t,
+ 0,
+ -0.00002145 * scale,
+ utmcheck,
+ trLLUTM,
+ )
grid_symb.appendSymbolLayer(symb_cross)
- for u in range(0, (geo_number_x+1)):
- for t in range(0, (geo_number_y+2)):
- symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, 0.00002145*scale, 0, utmcheck, trLLUTM)
+ for u in range(0, (geo_number_x + 1)):
+ for t in range(0, (geo_number_y + 2)):
+ symb_cross = self.crossLinegenerator(
+ xmin_source,
+ ymin_source,
+ px,
+ py,
+ u,
+ t,
+ 0.00002145 * scale,
+ 0,
+ utmcheck,
+ trLLUTM,
+ )
grid_symb.appendSymbolLayer(symb_cross)
- for u in range(0, (geo_number_x+2)):
- for t in range(0, (geo_number_y+1)):
- symb_cross = self.crossLinegenerator(xmin_source, ymin_source, px, py, u, t, 0, 0.00002145*scale, utmcheck, trLLUTM)
+ for u in range(0, (geo_number_x + 2)):
+ for t in range(0, (geo_number_y + 1)):
+ symb_cross = self.crossLinegenerator(
+ xmin_source,
+ ymin_source,
+ px,
+ py,
+ u,
+ t,
+ 0,
+ 0.00002145 * scale,
+ utmcheck,
+ trLLUTM,
+ )
grid_symb.appendSymbolLayer(symb_cross)
-
+
return grid_symb
- def geoGridlabelPlacer(self, geo_bound_bb, geo_number_x, geo_number_y, dx, dy, fSize, LLfontType, trLLUTM, trUTMLL, llcolor, utmcheck, scale):
+ def geoGridlabelPlacer(
+ self,
+ geo_bound_bb,
+ geo_number_x,
+ geo_number_y,
+ dx,
+ dy,
+ fSize,
+ LLfontType,
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ ):
xmin_source = float(geo_bound_bb.split()[1])
ymin_source = float(geo_bound_bb.split()[2])
xmax_source = float(geo_bound_bb.split()[3])
ymax_source = float(geo_bound_bb.split()[4])
- px = (xmax_source-xmin_source)/(geo_number_x+1)
- py = (ymax_source-ymin_source)/(geo_number_y+1)
+ px = (xmax_source - xmin_source) / (geo_number_x + 1)
+ py = (ymax_source - ymin_source) / (geo_number_y + 1)
root_rule = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
- #Upper
- for u in range(0, geo_number_x+2):
- if u ==0:
- ruletemp = self.grid_labeler (xmin_source, ymax_source, px, py, u, 0, dx[2], dy[0], '', 'Center', 'Up '+str(u+1), fSize, LLfontType, str(self.conv_dec_gms(xmin_source, px, u, 'W', 'E'))+'+\'. GREENWICH\'', trLLUTM, trUTMLL, llcolor, utmcheck, scale)
+ # Upper
+ for u in range(0, geo_number_x + 2):
+ if u == 0:
+ ruletemp = self.grid_labeler(
+ xmin_source,
+ ymax_source,
+ px,
+ py,
+ u,
+ 0,
+ dx[2],
+ dy[0],
+ "",
+ "Center",
+ "Up " + str(u + 1),
+ fSize,
+ LLfontType,
+ str(self.conv_dec_gms(xmin_source, px, u, "W", "E"))
+ + "+'. GREENWICH'",
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruletemp)
else:
- ruletemp = self.grid_labeler (xmin_source, ymax_source, px, py, u, 0, 0, dy[0], '', 'Center', 'Up '+str(u+1), fSize, LLfontType, self.conv_dec_gms(xmin_source, px, u, 'W', 'E'), trLLUTM, trUTMLL, llcolor, utmcheck, scale)
+ ruletemp = self.grid_labeler(
+ xmin_source,
+ ymax_source,
+ px,
+ py,
+ u,
+ 0,
+ 0,
+ dy[0],
+ "",
+ "Center",
+ "Up " + str(u + 1),
+ fSize,
+ LLfontType,
+ self.conv_dec_gms(xmin_source, px, u, "W", "E"),
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruletemp)
- #Bottom
- for b in range(0, geo_number_x+2):
- ruletemp = self.grid_labeler (xmin_source, ymin_source, px, py, b, 0, 0, dy[1], '', 'Center', 'Bot '+str(b+1), fSize, LLfontType, self.conv_dec_gms(xmin_source, px, b, 'W', 'E'), trLLUTM, trUTMLL, llcolor, utmcheck, scale)
+ # Bottom
+ for b in range(0, geo_number_x + 2):
+ ruletemp = self.grid_labeler(
+ xmin_source,
+ ymin_source,
+ px,
+ py,
+ b,
+ 0,
+ 0,
+ dy[1],
+ "",
+ "Center",
+ "Bot " + str(b + 1),
+ fSize,
+ LLfontType,
+ self.conv_dec_gms(xmin_source, px, b, "W", "E"),
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruletemp)
- #Right
- for r in range(0, geo_number_y+2):
- ruletemp = self.grid_labeler (xmax_source, ymin_source, px, py, 0, r, dx[0], 0, 'Half', '', 'Right '+str(r+1), fSize, LLfontType, self.conv_dec_gms(ymin_source, py, r, 'S', 'N'), trLLUTM, trUTMLL, llcolor, utmcheck, scale)
+ # Right
+ for r in range(0, geo_number_y + 2):
+ ruletemp = self.grid_labeler(
+ xmax_source,
+ ymin_source,
+ px,
+ py,
+ 0,
+ r,
+ dx[0],
+ 0,
+ "Half",
+ "",
+ "Right " + str(r + 1),
+ fSize,
+ LLfontType,
+ self.conv_dec_gms(ymin_source, py, r, "S", "N"),
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruletemp)
- #Left
- for l in range(0, geo_number_y+2):
- ruletemp = self.grid_labeler (xmin_source, ymin_source, px, py, 0, l, dx[1], 0, 'Half', '', 'Left '+str(l+1), fSize, LLfontType, self.conv_dec_gms(ymin_source, py, l, 'S', 'N'), trLLUTM, trUTMLL, llcolor, utmcheck, scale)
+ # Left
+ for l in range(0, geo_number_y + 2):
+ ruletemp = self.grid_labeler(
+ xmin_source,
+ ymin_source,
+ px,
+ py,
+ 0,
+ l,
+ dx[1],
+ 0,
+ "Half",
+ "",
+ "Left " + str(l + 1),
+ fSize,
+ LLfontType,
+ self.conv_dec_gms(ymin_source, py, l, "S", "N"),
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ )
root_rule.appendChild(ruletemp)
return root_rule
- def utmGridlabelPlacer(self, root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0, dy1, fSize, fontType, scale, utmcheck, geo_bb_or):
+ def utmGridlabelPlacer(
+ self,
+ root_rule,
+ grid_spacing,
+ geo_bound_bb,
+ bound_UTM_bb,
+ geo_number_x,
+ geo_number_y,
+ UTM_num_x,
+ UTM_num_y,
+ trUTMLL,
+ trLLUTM,
+ dx,
+ dy,
+ dy0,
+ dy1,
+ fSize,
+ fontType,
+ scale,
+ utmcheck,
+ geo_bb_or,
+ ):
xmin_source = float(geo_bound_bb.split()[1])
ymin_source = float(geo_bound_bb.split()[2])
xmax_source = float(geo_bound_bb.split()[3])
@@ -440,50 +1143,228 @@ def utmGridlabelPlacer(self, root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb
ymin_UTM = float(bound_UTM_bb.split()[2])
xmax_UTM = float(bound_UTM_bb.split()[3])
ymax_UTM = float(bound_UTM_bb.split()[4])
- px = (xmax_source-xmin_source)/(geo_number_x+1)
- py = (ymax_source-ymin_source)/(geo_number_y+1)
+ px = (xmax_source - xmin_source) / (geo_number_x + 1)
+ py = (ymax_source - ymin_source) / (geo_number_y + 1)
if grid_spacing > 0:
# Bottom
ruletest = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
- ruletest = self.utm_grid_labeler (ruletest, xmin_UTM, ymin_UTM, 0, ymin_source, px, py, trUTMLL, trLLUTM, 1, True, 0, dy[1]+0.4*(scale)*fSize/1.5, dy0[1]+0.4*(scale)*fSize/1.5, 0, 'Top', 'Center', 'UTMBotTest', fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, range(1), geo_bb_or)
+ ruletest = self.utm_grid_labeler(
+ ruletest,
+ xmin_UTM,
+ ymin_UTM,
+ 0,
+ ymin_source,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ 1,
+ True,
+ 0,
+ dy[1] + 0.4 * (scale) * fSize / 1.5,
+ dy0[1] + 0.4 * (scale) * fSize / 1.5,
+ 0,
+ "Top",
+ "Center",
+ "UTMBotTest",
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ range(1),
+ geo_bb_or,
+ )
rulechild = ruletest.children()[0]
- if rulechild.settings().fieldName == 'fail':
- rangeUD = range(2, UTM_num_x+1)
+ if rulechild.settings().fieldName == "fail":
+ rangeUD = range(2, UTM_num_x + 1)
else:
- rangeUD = range(1, UTM_num_x+1)
+ rangeUD = range(1, UTM_num_x + 1)
for u in rangeUD:
- root_rule = self.utm_grid_labeler (root_rule, xmin_UTM, ymin_UTM, 0, ymin_source, px, py, trUTMLL, trLLUTM, u, True, 0, dy[1]+0.4*(scale)*fSize/1.5, dy0[1]+0.4*(scale)*fSize/1.5, 0, 'Top', 'Center', 'UTMBot'+str(u), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeUD, geo_bb_or)
+ root_rule = self.utm_grid_labeler(
+ root_rule,
+ xmin_UTM,
+ ymin_UTM,
+ 0,
+ ymin_source,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ u,
+ True,
+ 0,
+ dy[1] + 0.4 * (scale) * fSize / 1.5,
+ dy0[1] + 0.4 * (scale) * fSize / 1.5,
+ 0,
+ "Top",
+ "Center",
+ "UTMBot" + str(u),
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ rangeUD,
+ geo_bb_or,
+ )
# Upper
- rangeUD = range(1, UTM_num_x+1)
+ rangeUD = range(1, UTM_num_x + 1)
for u in rangeUD:
- root_rule = self.utm_grid_labeler (root_rule, xmin_UTM, ymax_UTM, 0, ymax_source, px, py, trUTMLL, trLLUTM, u, True, 0, dy[0]-1.3*(scale)*fSize/1.5, dy0[0]-1.3*(scale)*fSize/1.5, 0, 'Bottom', 'Center', 'UTMUp'+str(u), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeUD, geo_bb_or)
+ root_rule = self.utm_grid_labeler(
+ root_rule,
+ xmin_UTM,
+ ymax_UTM,
+ 0,
+ ymax_source,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ u,
+ True,
+ 0,
+ dy[0] - 1.3 * (scale) * fSize / 1.5,
+ dy0[0] - 1.3 * (scale) * fSize / 1.5,
+ 0,
+ "Bottom",
+ "Center",
+ "UTMUp" + str(u),
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ rangeUD,
+ geo_bb_or,
+ )
# Left
ruletest = QgsRuleBasedLabeling.Rule(QgsPalLayerSettings())
- ruletest = self.utm_grid_labeler (ruletest, xmin_UTM, ymin_UTM, xmin_source, 0, px, py, trUTMLL, trLLUTM, 1, False, dx[2]-3.1*scale*fSize/1.5, dy[3], dy0[3], dy1[1], 'Bottom', 'Center', 'UTMLeftTest', fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, range(1), geo_bb_or)
+ ruletest = self.utm_grid_labeler(
+ ruletest,
+ xmin_UTM,
+ ymin_UTM,
+ xmin_source,
+ 0,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ 1,
+ False,
+ dx[2] - 3.1 * scale * fSize / 1.5,
+ dy[3],
+ dy0[3],
+ dy1[1],
+ "Bottom",
+ "Center",
+ "UTMLeftTest",
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ range(1),
+ geo_bb_or,
+ )
rulechild = ruletest.children()[0]
- if rulechild.settings().fieldName == 'fail':
- rangeLat = range(2, UTM_num_y+1)
+ if rulechild.settings().fieldName == "fail":
+ rangeLat = range(2, UTM_num_y + 1)
else:
- rangeLat = range(1, UTM_num_y+1)
+ rangeLat = range(1, UTM_num_y + 1)
for u in rangeLat:
- if u==min(rangeLat):
- extra_dist = -2.0*scale*fSize/1.5
+ if u == min(rangeLat):
+ extra_dist = -2.0 * scale * fSize / 1.5
else:
extra_dist = 0
- root_rule = self.utm_grid_labeler (root_rule, xmin_UTM, ymin_UTM, xmin_source, 0, px, py, trUTMLL, trLLUTM, u, False, dx[2]+extra_dist, dy[3], dy0[3], dy1[1], 'Bottom', 'Center', 'UTMLeft'+str(u), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeLat, geo_bb_or)
+ root_rule = self.utm_grid_labeler(
+ root_rule,
+ xmin_UTM,
+ ymin_UTM,
+ xmin_source,
+ 0,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ u,
+ False,
+ dx[2] + extra_dist,
+ dy[3],
+ dy0[3],
+ dy1[1],
+ "Bottom",
+ "Center",
+ "UTMLeft" + str(u),
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ rangeLat,
+ geo_bb_or,
+ )
# Right
- rangeLat = range(1, UTM_num_y+1)
+ rangeLat = range(1, UTM_num_y + 1)
for u in rangeLat:
- root_rule = self.utm_grid_labeler (root_rule, xmax_UTM, ymin_UTM, xmax_source, 0, px, py, trUTMLL, trLLUTM, u, False, dx[3], dy[3], dy0[3], dy1[1], '', 'Center', 'UTMRight'+str(1), fSize, fontType, grid_spacing, scale, utmcheck, geo_bound_bb, rangeLat, geo_bb_or)
+ root_rule = self.utm_grid_labeler(
+ root_rule,
+ xmax_UTM,
+ ymin_UTM,
+ xmax_source,
+ 0,
+ px,
+ py,
+ trUTMLL,
+ trLLUTM,
+ u,
+ False,
+ dx[3],
+ dy[3],
+ dy0[3],
+ dy1[1],
+ "",
+ "Center",
+ "UTMRight" + str(1),
+ fSize,
+ fontType,
+ grid_spacing,
+ scale,
+ utmcheck,
+ geo_bound_bb,
+ rangeLat,
+ geo_bb_or,
+ )
return root_rule
- def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY, scale, color, fontSize, font, fontLL, llcolor, utmcheck):
+ def styleCreator(
+ self,
+ layer,
+ index,
+ id_attr,
+ id_value,
+ spacing,
+ crossX,
+ crossY,
+ scale,
+ color,
+ fontSize,
+ font,
+ fontLL,
+ llcolor,
+ utmcheck,
+ ):
"""Getting Input Data For Grid Generation"""
grid_spacing = spacing
geo_number_x = crossX
@@ -492,23 +1373,27 @@ def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY,
fontType = font
LLfontType = fontLL
- #Loading feature
+ # Loading feature
layer_bound = layer
- query = '"'+str(id_attr)+'"='+str(id_value)
+ query = '"' + str(id_attr) + '"=' + str(id_value)
layer_bound.selectByExpression(query, QgsVectorLayer.SelectBehavior(0))
feature_bound = layer_bound.selectedFeatures()[0]
layer_bound.removeSelection()
- #Getting Feature Source CRS and Geometry
+ # Getting Feature Source CRS and Geometry
if utmcheck:
feature_geometry = feature_bound.geometry()
bound_UTM = layer_bound.crs().authid()
feature_bbox = feature_geometry.boundingBox()
- bound_UTM_bb = str(feature_bbox).replace(',','').replace('>','')
+ bound_UTM_bb = str(feature_bbox).replace(",", "").replace(">", "")
# Transforming to Geographic
- transform_feature = QgsCoordinateTransform(QgsCoordinateReferenceSystem(bound_UTM), QgsCoordinateReferenceSystem('EPSG:4674'), QgsProject.instance())
+ transform_feature = QgsCoordinateTransform(
+ QgsCoordinateReferenceSystem(bound_UTM),
+ QgsCoordinateReferenceSystem("EPSG:4674"),
+ QgsProject.instance(),
+ )
feature_geometry.transform(transform_feature)
- bound_sourcecrs = 'EPSG:4674'
+ bound_sourcecrs = "EPSG:4674"
feature_bbox = feature_geometry.boundingBox()
feature_bbox_or = feature_geometry.orientedMinimumBoundingBox()
else:
@@ -516,106 +1401,195 @@ def styleCreator(self, layer, index, id_attr, id_value, spacing, crossX, crossY,
bound_sourcecrs = layer_bound.crs().authid()
feature_bbox = feature_geometry.boundingBox()
feature_bbox_or = feature_geometry.orientedMinimumBoundingBox()
- geo_bound_bb = str(feature_bbox).replace(',','').replace('>','')
- oriented_geo_bb = str(feature_bbox_or).replace(',','').replace('>','').replace('((','').replace('))','')
+ geo_bound_bb = str(feature_bbox).replace(",", "").replace(">", "")
+ oriented_geo_bb = (
+ str(feature_bbox_or)
+ .replace(",", "")
+ .replace(">", "")
+ .replace("((", "")
+ .replace("))", "")
+ )
- #Defining CRSs Transformations
+ # Defining CRSs Transformations
inom = feature_bound[index]
- if inom[0]=='N':
- bound_UTM = 'EPSG:319' + str(72 + int(inom[3:5])-18)
- elif inom[0]=='S':
- bound_UTM = 'EPSG:319' + str(78 + int(inom[3:5])-18)
+ if inom[0] == "N":
+ bound_UTM = "EPSG:319" + str(72 + int(inom[3:5]) - 18)
+ elif inom[0] == "S":
+ bound_UTM = "EPSG:319" + str(78 + int(inom[3:5]) - 18)
else:
- iface.messageBar().pushMessage("Error", "Invalid index attribute", level=Qgis.Critical)
+ iface.messageBar().pushMessage(
+ "Error", "Invalid index attribute", level=Qgis.Critical
+ )
return
- trLLUTM = QgsCoordinateTransform(QgsCoordinateReferenceSystem(bound_sourcecrs), QgsCoordinateReferenceSystem(bound_UTM), QgsProject.instance())
- trUTMLL = QgsCoordinateTransform(QgsCoordinateReferenceSystem(bound_UTM), QgsCoordinateReferenceSystem(bound_sourcecrs), QgsProject.instance())
+ trLLUTM = QgsCoordinateTransform(
+ QgsCoordinateReferenceSystem(bound_sourcecrs),
+ QgsCoordinateReferenceSystem(bound_UTM),
+ QgsProject.instance(),
+ )
+ trUTMLL = QgsCoordinateTransform(
+ QgsCoordinateReferenceSystem(bound_UTM),
+ QgsCoordinateReferenceSystem(bound_sourcecrs),
+ QgsProject.instance(),
+ )
- #Defining UTM Grid Symbology Type
+ # Defining UTM Grid Symbology Type
renderer = layer.renderer()
- properties = {'color': 'black'}
+ properties = {"color": "black"}
grid_symb = QgsFillSymbol.createSimple(properties)
symb_out = QgsSimpleFillSymbolLayer()
- symb_out.setStrokeColor(QColor('black'))
- symb_out.setFillColor(QColor('white'))
+ symb_out.setStrokeColor(QColor("black"))
+ symb_out.setFillColor(QColor("white"))
symb_out.setStrokeWidth(0.05)
-
""" Creating UTM Grid """
if not utmcheck:
geo_UTM = feature_bound.geometry()
geo_UTM.transform(trLLUTM)
- bound_UTM_bb = str(geo_UTM.boundingBox()).replace(',','').replace('>','')
+ bound_UTM_bb = str(geo_UTM.boundingBox()).replace(",", "").replace(">", "")
xmin_UTM = float(bound_UTM_bb.split()[1])
ymin_UTM = float(bound_UTM_bb.split()[2])
xmax_UTM = float(bound_UTM_bb.split()[3])
ymax_UTM = float(bound_UTM_bb.split()[4])
if grid_spacing > 0:
- UTM_num_x = floor(xmax_UTM/grid_spacing) - floor(xmin_UTM/grid_spacing)
- UTM_num_y = floor(ymax_UTM/grid_spacing) - floor(ymin_UTM/grid_spacing)
- #Generating Vertical Lines
- for x in range(1, UTM_num_x+1):
- grid_symb= self.utm_symb_generator (grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, x, 0, geo_bound_bb, bound_UTM_bb, utmcheck)
- #Generating Horizontal Lines
- for y in range(1, UTM_num_y+1):
- grid_symb = self.utm_symb_generator (grid_spacing, trUTMLL, trLLUTM, grid_symb, properties, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, 0, y, geo_bound_bb, bound_UTM_bb, utmcheck)
+ UTM_num_x = floor(xmax_UTM / grid_spacing) - floor(xmin_UTM / grid_spacing)
+ UTM_num_y = floor(ymax_UTM / grid_spacing) - floor(ymin_UTM / grid_spacing)
+ # Generating Vertical Lines
+ for x in range(1, UTM_num_x + 1):
+ grid_symb = self.utm_symb_generator(
+ grid_spacing,
+ trUTMLL,
+ trLLUTM,
+ grid_symb,
+ properties,
+ geo_number_x,
+ geo_number_y,
+ UTM_num_x,
+ UTM_num_y,
+ x,
+ 0,
+ geo_bound_bb,
+ bound_UTM_bb,
+ utmcheck,
+ )
+ # Generating Horizontal Lines
+ for y in range(1, UTM_num_y + 1):
+ grid_symb = self.utm_symb_generator(
+ grid_spacing,
+ trUTMLL,
+ trLLUTM,
+ grid_symb,
+ properties,
+ geo_number_x,
+ geo_number_y,
+ UTM_num_x,
+ UTM_num_y,
+ 0,
+ y,
+ geo_bound_bb,
+ bound_UTM_bb,
+ utmcheck,
+ )
""" Creating Geo Grid """
- grid_symb = self.geoGridcreator(grid_symb, geo_bound_bb, geo_number_x, geo_number_y, scale, utmcheck, trLLUTM)
+ grid_symb = self.geoGridcreator(
+ grid_symb,
+ geo_bound_bb,
+ geo_number_x,
+ geo_number_y,
+ scale,
+ utmcheck,
+ trLLUTM,
+ )
""" Rendering UTM and Geographic Grid """
- #Changing UTM Grid Color
+ # Changing UTM Grid Color
grid_symb.setColor(color)
grid_symb.changeSymbolLayer(0, symb_out)
- #Creating Rule Based Renderer (Rule For The Other Features)
- properties = {'color': 'white'}
+ # Creating Rule Based Renderer (Rule For The Other Features)
+ properties = {"color": "white"}
ext_grid_symb = QgsFillSymbol.createSimple(properties)
symb_ot = QgsRuleBasedRenderer.Rule(ext_grid_symb)
- symb_ot.setFilterExpression('\"'+str(id_attr)+'\" <> '+str(id_value))
- symb_ot.setLabel('other')
- #Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule)
+ symb_ot.setFilterExpression('"' + str(id_attr) + '" <> ' + str(id_value))
+ symb_ot.setLabel("other")
+ # Creating Rule Based Renderer (Rule For The Selected Feature, Root Rule)
symb_new = QgsRuleBasedRenderer.Rule(grid_symb)
- symb_new.setFilterExpression('\"'+str(id_attr)+'\" = '+str(id_value))
- symb_new.setLabel('layer')
+ symb_new.setFilterExpression('"' + str(id_attr) + '" = ' + str(id_value))
+ symb_new.setLabel("layer")
symb_new.appendChild(symb_ot)
- #Applying New Renderer
+ # Applying New Renderer
render_base = QgsRuleBasedRenderer(symb_new)
new_renderer = QgsInvertedPolygonRenderer.convertFromRenderer(render_base)
layer_bound.setRenderer(new_renderer)
""" Labeling Geo Grid """
if utmcheck:
- dx = [2*scale*fSize/1.5, -13.6*scale*fSize/1.5, 6*scale*fSize/1.5]
- dy = [1.7*scale*fSize/1.5, -3.8*scale*fSize/1.5]
+ dx = [
+ 2 * scale * fSize / 1.5,
+ -13.6 * scale * fSize / 1.5,
+ 6 * scale * fSize / 1.5,
+ ]
+ dy = [1.7 * scale * fSize / 1.5, -3.8 * scale * fSize / 1.5]
else:
- dx = [0.000018*scale, -0.000120*scale, 0.00005*scale]
- dy = [0.000015*scale, -0.000040*scale]
+ dx = [0.000018 * scale, -0.000120 * scale, 0.00005 * scale]
+ dy = [0.000015 * scale, -0.000040 * scale]
- root_rule = self.geoGridlabelPlacer(geo_bound_bb, geo_number_x, geo_number_y, dx, dy, fSize, LLfontType, trLLUTM, trUTMLL, llcolor, utmcheck, scale)
+ root_rule = self.geoGridlabelPlacer(
+ geo_bound_bb,
+ geo_number_x,
+ geo_number_y,
+ dx,
+ dy,
+ fSize,
+ LLfontType,
+ trLLUTM,
+ trUTMLL,
+ llcolor,
+ utmcheck,
+ scale,
+ )
""" Labeling UTM Grid"""
if utmcheck:
dx = [-2.7, -9.7, -6.2, 5.4]
- dx = [i*scale*fSize/1.5 for i in dx]
+ dx = [i * scale * fSize / 1.5 for i in dx]
dy = [2.5, -1.7, -0.5, -1.5]
- dy = [i*scale*fSize/1.5 for i in dy]
+ dy = [i * scale * fSize / 1.5 for i in dy]
dy0 = [5.45, -4.8, -3.2, -4.2]
- dy0 = [i*scale*fSize/1.5 for i in dy0]
+ dy0 = [i * scale * fSize / 1.5 for i in dy0]
dy1 = [2.15, 1.2]
- dy1 = [i*scale*fSize/1.5 for i in dy1]
+ dy1 = [i * scale * fSize / 1.5 for i in dy1]
else:
dx = [-0.00003, -0.000107, -0.000070, 0.000060]
- dx = [i*scale*fSize/1.5 for i in dx]
+ dx = [i * scale * fSize / 1.5 for i in dx]
dy = [0.000027, 0.000016, -0.000041, -0.000052]
- dy = [i*scale*fSize/1.5 for i in dy]
+ dy = [i * scale * fSize / 1.5 for i in dy]
dy0 = [0.0000644, 0.000053, -0.000076, -0.000087]
- dy0 = [i*scale*fSize/1.5 for i in dy0]
+ dy0 = [i * scale * fSize / 1.5 for i in dy0]
dy1 = [0.000032, 0.000020]
- dy1 = [i*scale*fSize/1.5 for i in dy1]
-
- root_rule = self.utmGridlabelPlacer(root_rule, grid_spacing, geo_bound_bb, bound_UTM_bb, geo_number_x, geo_number_y, UTM_num_x, UTM_num_y, trUTMLL, trLLUTM, dx, dy, dy0, dy1, fSize, fontType, scale, utmcheck, oriented_geo_bb)
+ dy1 = [i * scale * fSize / 1.5 for i in dy1]
+ root_rule = self.utmGridlabelPlacer(
+ root_rule,
+ grid_spacing,
+ geo_bound_bb,
+ bound_UTM_bb,
+ geo_number_x,
+ geo_number_y,
+ UTM_num_x,
+ UTM_num_y,
+ trUTMLL,
+ trLLUTM,
+ dx,
+ dy,
+ dy0,
+ dy1,
+ fSize,
+ fontType,
+ scale,
+ utmcheck,
+ oriented_geo_bb,
+ )
""" Activating Labels """
rules = QgsRuleBasedLabeling(root_rule)
diff --git a/DsgTools/core/EditingTools/productExporter.py b/DsgTools/core/EditingTools/productExporter.py
index f4a34f86e..22a449d51 100644
--- a/DsgTools/core/EditingTools/productExporter.py
+++ b/DsgTools/core/EditingTools/productExporter.py
@@ -24,6 +24,7 @@
from qgis.core import QgsLayoutExporter, QgsProject, QgsPrintLayout, QgsReadWriteContext
from qgis.PyQt.QtXml import QDomDocument
+
class ProductExporter(object):
def __init__(self):
self.layout = QgsPrintLayout(QgsProject.instance())
@@ -31,7 +32,7 @@ def __init__(self):
def populateTemplate(self, templateXMLContent):
templateDomDoc = QDomDocument()
templateDomDoc.setContent(templateXMLContent)
- #TODO: Adicionar um parser para o XML para substituir
+ # TODO: Adicionar um parser para o XML para substituir
# informações pertinentes, como por exemplo, id da
# camada de atlas.
self.layout.loadFromTemplate(templateDomDoc, QgsReadWriteContext())
@@ -41,11 +42,12 @@ def export(self, parameterDict):
def exportPdf(self, outputPath, feedback=None):
exporter = QgsLayoutExporter(self.layout)
- result, error = exporter.exportToPdfs(self.layout.atlas(),
- outputPath,
- settings=QgsLayoutExporter.PdfExportSettings(),
- feedback=feedback
- )
+ result, error = exporter.exportToPdfs(
+ self.layout.atlas(),
+ outputPath,
+ settings=QgsLayoutExporter.PdfExportSettings(),
+ feedback=feedback,
+ )
return result, error
def exportTiff(self):
diff --git a/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py
index b378b7731..f3530c6c4 100644
--- a/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py
+++ b/DsgTools/core/Factories/DbCreatorFactory/dbCreator.py
@@ -21,117 +21,163 @@
***************************************************************************/
"""
-#5 Imports
+# 5 Imports
from builtins import str
from builtins import range
from qgis.PyQt.QtCore import QSettings, pyqtSignal, QObject
-#DsgTools imports
+# DsgTools imports
from ..DbFactory.dbFactory import DbFactory
from ..DbFactory.abstractDb import AbstractDb
from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
+
class DbCreator(QObject):
- def __init__(self, createParam, parentWidget = None):
- super(DbCreator,self).__init__()
+ def __init__(self, createParam, parentWidget=None):
+ super(DbCreator, self).__init__()
self.dbFactory = DbFactory()
self.parentWidget = parentWidget
if isinstance(createParam, str):
self.outputDir = createParam
if isinstance(createParam, AbstractDb):
self.abstractDb = createParam
- self.scaleMIDict = {1:'100k',2:'50k',3:'25k',4:'10k',5:'5k',6:'2k',7:'1k'}
-
+ self.scaleMIDict = {
+ 1: "100k",
+ 2: "50k",
+ 3: "25k",
+ 4: "10k",
+ 5: "5k",
+ 6: "2k",
+ 7: "1k",
+ }
+
def getType(self):
- #Abstract method.
+ # Abstract method.
return None
-
- def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
- #Abstract method.
+
+ def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None):
+ # Abstract method.
pass
- def buildDatabaseName(self, dbBaseName, prefix = None, sufix = None):
+ def buildDatabaseName(self, dbBaseName, prefix=None, sufix=None):
attrNameList = []
if prefix:
attrNameList.append(prefix)
attrNameList.append(dbBaseName)
if sufix:
attrNameList.append(sufix)
- return '_'.join(attrNameList)
-
- def buildAutoIncrementingDbNameList(self, dbInitialBaseName, numberOfDatabases, prefix = None, sufix = None):
+ return "_".join(attrNameList)
+
+ def buildAutoIncrementingDbNameList(
+ self, dbInitialBaseName, numberOfDatabases, prefix=None, sufix=None
+ ):
dbNameList = []
for i in range(numberOfDatabases):
- dbBaseName = dbInitialBaseName + str(i+1)
+ dbBaseName = dbInitialBaseName + str(i + 1)
dbNameList.append(self.buildDatabaseName(dbBaseName, prefix, sufix))
return dbNameList
-
- def batchCreateDb(self, dbNameList, srid, paramDict = dict()):
+
+ def batchCreateDb(self, dbNameList, srid, paramDict=dict()):
outputDbDict = dict()
errorDict = dict()
templateDb = None
if self.parentWidget:
- progress = ProgressWidget(1,len(dbNameList),self.tr('Creating databases... '),parent = self.parentWidget)
+ progress = ProgressWidget(
+ 1,
+ len(dbNameList),
+ self.tr("Creating databases... "),
+ parent=self.parentWidget,
+ )
progress.initBar()
for dbName in dbNameList:
try:
- if not templateDb:
- newDb = self.createDb(dbName, srid, paramDict = paramDict, parentWidget = self.parentWidget)
+ if not templateDb:
+ newDb = self.createDb(
+ dbName,
+ srid,
+ paramDict=paramDict,
+ parentWidget=self.parentWidget,
+ )
templateDb = dbName
else:
- paramDict['templateDb'] = templateDb
- newDb = self.createDb(dbName, srid, paramDict, parentWidget = self.parentWidget)
+ paramDict["templateDb"] = templateDb
+ newDb = self.createDb(
+ dbName, srid, paramDict, parentWidget=self.parentWidget
+ )
outputDbDict[dbName] = newDb
except Exception as e:
if dbName not in list(errorDict.keys()):
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
else:
- errorDict[dbName] += '\n' + ':'.join(e.args)
+ errorDict[dbName] += "\n" + ":".join(e.args)
if self.parentWidget:
progress.step()
return outputDbDict, errorDict
-
- def createDbWithAutoIncrementingName(self, dbInitialBaseName, srid, numberOfDatabases, prefix = None, sufix = None, paramDict = dict()):
- dbNameList = self.buildAutoIncrementingDbNameList(dbInitialBaseName, numberOfDatabases, prefix, sufix)
+
+ def createDbWithAutoIncrementingName(
+ self,
+ dbInitialBaseName,
+ srid,
+ numberOfDatabases,
+ prefix=None,
+ sufix=None,
+ paramDict=dict(),
+ ):
+ dbNameList = self.buildAutoIncrementingDbNameList(
+ dbInitialBaseName, numberOfDatabases, prefix, sufix
+ )
return self.batchCreateDb(dbNameList, srid, paramDict)
-
- def createDbFromMIList(self, miList, srid, prefix = None, sufix = None, createFrame = False, paramDict = dict()):
+
+ def createDbFromMIList(
+ self, miList, srid, prefix=None, sufix=None, createFrame=False, paramDict=dict()
+ ):
outputDbDict = dict()
errorDict = dict()
templateDb = None
if self.parentWidget:
- progress = ProgressWidget(1,2*len(miList)+1,self.tr('Creating databases... '),parent = self.parentWidget)
+ progress = ProgressWidget(
+ 1,
+ 2 * len(miList) + 1,
+ self.tr("Creating databases... "),
+ parent=self.parentWidget,
+ )
progress.initBar()
progress.step()
for mi in miList:
dbName = self.buildDatabaseName(mi, prefix, sufix)
try:
- if not templateDb:
- newDb = self.createDb(dbName, srid, paramDict, parentWidget = self.parentWidget)
+ if not templateDb:
+ newDb = self.createDb(
+ dbName, srid, paramDict, parentWidget=self.parentWidget
+ )
templateDb = dbName
else:
- paramDict['templateDb'] = templateDb
- newDb = self.createDb(dbName, srid, paramDict, parentWidget = self.parentWidget)
+ paramDict["templateDb"] = templateDb
+ newDb = self.createDb(
+ dbName, srid, paramDict, parentWidget=self.parentWidget
+ )
outputDbDict[dbName] = newDb
except Exception as e:
if dbName not in list(errorDict.keys()):
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
else:
- errorDict[dbName] += '\n' + ':'.join(e.args)
+ errorDict[dbName] += "\n" + ":".join(e.args)
if self.parentWidget:
progress.step()
if createFrame:
for dbName in list(outputDbDict.keys()):
- try:
- scale = self.scaleMIDict[len(mi.split('-'))]
+ try:
+ scale = self.scaleMIDict[len(mi.split("-"))]
mi = [i for i in miList if i in dbName][0]
- outputDbDict[dbName].createFrame('mi', scale, mi, paramDict = paramDict)
+ outputDbDict[dbName].createFrame(
+ "mi", scale, mi, paramDict=paramDict
+ )
except Exception as e:
if dbName not in list(errorDict.keys()):
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
else:
- errorDict[dbName] += '\n' + ':'.join(e.args)
+ errorDict[dbName] += "\n" + ":".join(e.args)
if self.parentWidget:
progress.step()
- return outputDbDict, errorDict
\ No newline at end of file
+ return outputDbDict, errorDict
diff --git a/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py b/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py
index 9f5edab97..55294a118 100644
--- a/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py
+++ b/DsgTools/core/Factories/DbCreatorFactory/dbCreatorFactory.py
@@ -25,23 +25,33 @@
from qgis.core import Qgis, QgsMessageLog
from qgis.PyQt.QtSql import QSqlDatabase
-#DSG Tools imports
+
+# DSG Tools imports
from .spatialiteDbCreator import SpatialiteDbCreator
from .postgisDbCreator import PostgisDbCreator
from .geopackageDbCreator import GeopackageDbCreator
+
class DbCreatorFactory(object):
- def createDbCreatorFactory(self, driverName, createParam, parentWidget = None):
- #TODO Treat none return
- if not ('QPSQL' in QSqlDatabase.drivers()): #Driver wasn't loaded
- QgsMessageLog.logMessage('QT PSQL driver not installed!', 'DSGTools Plugin', Qgis.Critical)
+ def createDbCreatorFactory(self, driverName, createParam, parentWidget=None):
+ # TODO Treat none return
+ if not ("QPSQL" in QSqlDatabase.drivers()): # Driver wasn't loaded
+ QgsMessageLog.logMessage(
+ "QT PSQL driver not installed!", "DSGTools Plugin", Qgis.Critical
+ )
+ return None
+ if not ("QSQLITE" in QSqlDatabase.drivers()): # Driver wasn't loaded
+ QgsMessageLog.logMessage(
+ "QT QSQLITE driver not installed!", "DSGTools Plugin", Qgis.Critical
+ )
return None
- if not ('QSQLITE' in QSqlDatabase.drivers()): #Driver wasn't loaded
- QgsMessageLog.logMessage('QT QSQLITE driver not installed!', 'DSGTools Plugin', Qgis.Critical)
- return None
creators = {
- "QSQLITE" : SpatialiteDbCreator,
- "QPSQL" : PostgisDbCreator,
- "GPKG" : GeopackageDbCreator
+ "QSQLITE": SpatialiteDbCreator,
+ "QPSQL": PostgisDbCreator,
+ "GPKG": GeopackageDbCreator,
}
- return creators[driverName](createParam, parentWidget) if driverName in creators else None
+ return (
+ creators[driverName](createParam, parentWidget)
+ if driverName in creators
+ else None
+ )
diff --git a/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py
index 577b25a8a..26afc593e 100644
--- a/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py
+++ b/DsgTools/core/Factories/DbCreatorFactory/geopackageDbCreator.py
@@ -26,47 +26,64 @@
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.Factories.DbCreatorFactory.dbCreator import DbCreator
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import (
+ ProgressWidget,
+)
from DsgTools.core.dsgEnums import DsgEnums
+
class GeopackageDbCreator(DbCreator):
-
- def __init__(self, createParam, parentWidget = None):
- super(GeopackageDbCreator,self).__init__(createParam)
+ def __init__(self, createParam, parentWidget=None):
+ super(GeopackageDbCreator, self).__init__(createParam)
self.parentWidget = parentWidget
-
+
def instantiateNewDb(self, dbPath):
newDb = self.dbFactory.createDbFactory(DsgEnums.DriverGeopackage)
newDb.connectDatabase(dbPath)
return newDb
-
+
def getTemplateLocation(self, version):
- if version == '2.1.3':
+ if version == "2.1.3":
return os.path.join(
- os.path.dirname(__file__), '..', '..', '..', 'core',
- 'DbModels', 'Geopackage', '213', 'seed_edgv213.gpkg'
- )
- elif version == '3.0':
+ os.path.dirname(__file__),
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "Geopackage",
+ "213",
+ "seed_edgv213.gpkg",
+ )
+ elif version == "3.0":
return os.path.join(
- os.path.dirname(__file__), '..', '..', '..', 'core',
- 'DbModels', 'Geopackage', '3', 'seed_edgv3.gpkg'
- )
- return ''
-
- def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
- destination = os.path.join(self.outputDir,dbName+'.gpkg')
- if 'version' not in list(paramDict.keys()):
- raise Exception('Undefined database version')
- edgvPath = self.getTemplateLocation(paramDict['version'])
- f = open(edgvPath,'rb')
- g = open(destination,'wb')
+ os.path.dirname(__file__),
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "Geopackage",
+ "3",
+ "seed_edgv3.gpkg",
+ )
+ return ""
+
+ def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None):
+ destination = os.path.join(self.outputDir, dbName + ".gpkg")
+ if "version" not in list(paramDict.keys()):
+ raise Exception("Undefined database version")
+ edgvPath = self.getTemplateLocation(paramDict["version"])
+ f = open(edgvPath, "rb")
+ g = open(destination, "wb")
x = f.readlines()
if parentWidget:
progress = ProgressWidget(
- 1, len(x)+2,
- self.tr('Creating Geopackage {0}... ').format(dbName),
- parent=parentWidget
- )
+ 1,
+ len(x) + 2,
+ self.tr("Creating Geopackage {0}... ").format(dbName),
+ parent=parentWidget,
+ )
progress.initBar()
for i in x:
g.write(i)
@@ -74,7 +91,7 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
progress.step()
g.close()
f.close()
- #TODO: put defineSrid into AbstractDb
+ # TODO: put defineSrid into AbstractDb
self.defineSrid(destination, srid)
if parentWidget:
progress.step()
@@ -82,11 +99,13 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
if parentWidget:
progress.step()
return newDb
-
+
def defineSrid(self, destination, srid):
con = sqlite3.connect(destination)
cursor = con.cursor()
- cursor.execute("UPDATE gpkg_geometry_columns SET srs_id={srid}".format(srid=srid))
+ cursor.execute(
+ "UPDATE gpkg_geometry_columns SET srs_id={srid}".format(srid=srid)
+ )
con.commit()
cursor.close()
con.close()
diff --git a/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py
index 70ec47522..9a9029aaf 100644
--- a/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py
+++ b/DsgTools/core/Factories/DbCreatorFactory/postgisDbCreator.py
@@ -25,12 +25,12 @@
from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
from DsgTools.core.dsgEnums import DsgEnums
+
class PostgisDbCreator(DbCreator):
-
- def __init__(self, createParam, parentWidget = None):
- super(self.__class__,self).__init__(createParam)
+ def __init__(self, createParam, parentWidget=None):
+ super(self.__class__, self).__init__(createParam)
self.parentWidget = parentWidget
-
+
def instantiateNewDb(self, dbName):
host = self.abstractDb.db.hostName()
port = self.abstractDb.db.port()
@@ -39,11 +39,11 @@ def instantiateNewDb(self, dbName):
newDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS)
newDb.connectDatabaseWithParameters(host, port, dbName, user, password)
return newDb
-
+
def checkAndCreateTemplate(self, version):
- '''
+ """
checks and create an edgv template
- '''
+ """
if version:
hasTemplate = self.abstractDb.checkTemplate(version)
if hasTemplate:
@@ -53,32 +53,38 @@ def checkAndCreateTemplate(self, version):
if mustUpdateTemplate:
templateName = templateDb.db.databaseName()
templateDb.__del__()
- self.abstractDb.dropDatabase(templateName, dropTemplate = True)
+ self.abstractDb.dropDatabase(templateName, dropTemplate=True)
hasTemplate = False
if not hasTemplate:
self.abstractDb.createTemplateDatabase(version)
templateName = self.abstractDb.getTemplateName(version)
templateDb = self.instantiateNewDb(templateName)
templateDb.setStructureFromSql(version, 4674)
-
- def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
- '''
+
+ def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None):
+ """
dbName: new database name
srid: coordinate system of database
paramDict = {'templateDb': database to be used as template. Default is edgv}
- '''
- #0. if 'templateDb' in paramDict.keys: use createFromTemplate then end createDb
- if 'templateDb' in list(paramDict.keys()):
- self.abstractDb.createDbFromTemplate(dbName, templateName = paramDict['templateDb'], parentWidget = parentWidget)
+ """
+ # 0. if 'templateDb' in paramDict.keys: use createFromTemplate then end createDb
+ if "templateDb" in list(paramDict.keys()):
+ self.abstractDb.createDbFromTemplate(
+ dbName, templateName=paramDict["templateDb"], parentWidget=parentWidget
+ )
return self.instantiateNewDb(dbName)
else:
- #1. test if edgv template is created
- #2. if edgv template is not created, create it
- if paramDict['isTemplateEdgv']:
- self.checkAndCreateTemplate(paramDict['version'])
- #3. create db from template
- self.abstractDb.createDbFromTemplate(dbName, templateName = paramDict['templateName'], parentWidget = parentWidget)
+ # 1. test if edgv template is created
+ # 2. if edgv template is not created, create it
+ if paramDict["isTemplateEdgv"]:
+ self.checkAndCreateTemplate(paramDict["version"])
+ # 3. create db from template
+ self.abstractDb.createDbFromTemplate(
+ dbName,
+ templateName=paramDict["templateName"],
+ parentWidget=parentWidget,
+ )
newDb = self.instantiateNewDb(dbName)
- newDb.updateDbSRID(srid, parentWidget = parentWidget)
+ newDb.updateDbSRID(srid, parentWidget=parentWidget)
newDb.checkAndCreateStyleTable()
return newDb
diff --git a/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py b/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py
index 631f6d325..7100309be 100644
--- a/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py
+++ b/DsgTools/core/Factories/DbCreatorFactory/spatialiteDbCreator.py
@@ -29,35 +29,60 @@
from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
from DsgTools.core.dsgEnums import DsgEnums
+
class SpatialiteDbCreator(DbCreator):
-
- def __init__(self, createParam, parentWidget = None):
- super(self.__class__,self).__init__(createParam)
+ def __init__(self, createParam, parentWidget=None):
+ super(self.__class__, self).__init__(createParam)
self.parentWidget = parentWidget
-
+
def instantiateNewDb(self, dbPath):
newDb = self.dbFactory.createDbFactory(DsgEnums.DriverSpatiaLite)
newDb.connectDatabase(dbPath)
return newDb
-
+
def getTemplateLocation(self, version):
currentPath = os.path.dirname(__file__)
- if version == '2.1.3':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','SpatiaLite', '213', 'seed_edgv213.sqlite')
- elif version == '3.0':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','SpatiaLite', '3', 'seed_edgv3.sqlite')
+ if version == "2.1.3":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "SpatiaLite",
+ "213",
+ "seed_edgv213.sqlite",
+ )
+ elif version == "3.0":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "SpatiaLite",
+ "3",
+ "seed_edgv3.sqlite",
+ )
return edgvPath
-
- def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
- destination = os.path.join(self.outputDir,dbName+'.sqlite')
- if 'version' not in list(paramDict.keys()):
- raise Exception('Undefined database version')
- edgvPath = self.getTemplateLocation(paramDict['version'])
- f = open(edgvPath,'rb')
- g = open(destination,'wb')
+
+ def createDb(self, dbName, srid, paramDict=dict(), parentWidget=None):
+ destination = os.path.join(self.outputDir, dbName + ".sqlite")
+ if "version" not in list(paramDict.keys()):
+ raise Exception("Undefined database version")
+ edgvPath = self.getTemplateLocation(paramDict["version"])
+ f = open(edgvPath, "rb")
+ g = open(destination, "wb")
x = f.readlines()
if parentWidget:
- progress = ProgressWidget(1,len(x)+2,self.tr('Creating Spatialite {0}... ').format(dbName), parent = parentWidget)
+ progress = ProgressWidget(
+ 1,
+ len(x) + 2,
+ self.tr("Creating Spatialite {0}... ").format(dbName),
+ parent=parentWidget,
+ )
progress.initBar()
for i in x:
g.write(i)
@@ -65,7 +90,7 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
progress.step()
g.close()
f.close()
- #TODO: put defineSrid into AbstractDb
+ # TODO: put defineSrid into AbstractDb
self.defineSrid(destination, srid)
if parentWidget:
progress.step()
@@ -73,11 +98,11 @@ def createDb(self, dbName, srid, paramDict = dict(), parentWidget = None):
if parentWidget:
progress.step()
return newDb
-
+
def defineSrid(self, destination, srid):
con = sqlite3.connect(destination)
cursor = con.cursor()
srid_sql = (srid,)
- cursor.execute("UPDATE geometry_columns SET srid=?",srid_sql)
+ cursor.execute("UPDATE geometry_columns SET srid=?", srid_sql)
con.commit()
- con.close()
\ No newline at end of file
+ con.close()
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py
index b5119d24a..9a1cd943c 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/attributeCustomization.py
@@ -1,4 +1,4 @@
- # -*- coding: utf-8 -*-
+# -*- coding: utf-8 -*-
"""
/***************************************************************************
DsgTools
@@ -20,56 +20,89 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
+# DsgTools Imports
from builtins import map
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class AttributeCustomization(DbCustomization):
def __init__(self, customJson):
super(AttributeCustomization, self).__init__(customJson)
-
+
def buildSql(self):
- '''
+ """
self.customJson['AttributeToAdd'] = [{'schemaName':'schema', 'tableName':'nome', 'attrList':[-list of attrDef-], childrenToAlter:[-list of children-]}]
attrDef = [{'attrName':'nome', 'attrType':'varchar(80)', 'isPk':False, 'isNullable':True, 'references':None, 'defaultValue':None, 'filter':[]}]
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['AttributeToAdd']:
- schema = modItem['schemaName']
- table = modItem['tableName']
- for attr in modItem['attrList']:
- auxSql = 'ALTER TABLE "{0}"."{1}" ADD COLUMN {2} {3}'.format(schema,table,attr['attrName'],attr['attrType'])
- if not attr['isNullable']:
- auxSql += ' NOT NULL '
- if 'references' in list(attr.keys()):
- if attr['references']:
- if attr['defaultValue']:
- auxSql += ' REFERENCES {0} DEFAULT {1}'.format(attr['references'], attr['defaultValue'])
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["AttributeToAdd"]:
+ schema = modItem["schemaName"]
+ table = modItem["tableName"]
+ for attr in modItem["attrList"]:
+ auxSql = 'ALTER TABLE "{0}"."{1}" ADD COLUMN {2} {3}'.format(
+ schema, table, attr["attrName"], attr["attrType"]
+ )
+ if not attr["isNullable"]:
+ auxSql += " NOT NULL "
+ if "references" in list(attr.keys()):
+ if attr["references"]:
+ if attr["defaultValue"]:
+ auxSql += " REFERENCES {0} DEFAULT {1}".format(
+ attr["references"], attr["defaultValue"]
+ )
else:
- auxSql += ' REFERENCES {0}'.format(attr['references'])
- auxSql += ';\n'
+ auxSql += " REFERENCES {0}".format(attr["references"])
+ auxSql += ";\n"
sql += auxSql
- if len(attr['filter']) > 0:
- sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n'''.format(schema, table, attr['attrName'], '::SMALLINT,'.join(map(str,attr['filter']))+'::SMALLINT')
- for child in modItem['childrenToAlter']:
- sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n'''.format(child['schema'], child['table'], attr['attrName'], '::SMALLINT,'.join(map(str,attr['filter']))+'::SMALLINT')
- if attr['references']:
- sql += '''ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n'''.format(schema, table, attr['attrName'], attr['references'])
- for child in modItem['childrenToAlter']:
- sql += '''ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n'''.format(child['schema'], child['table'], attr['attrName'], attr['references'])
- if attr['defaultValue']:
- sql += '''ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};'''.format(schema, table, attr['attrName'], attr['defaultValue'])
- for child in modItem['childrenToAlter']:
- sql += '''ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};'''.format(child['schema'], child['table'], attr['attrName'], attr['defaultValue'])
+ if len(attr["filter"]) > 0:
+ sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n""".format(
+ schema,
+ table,
+ attr["attrName"],
+ "::SMALLINT,".join(map(str, attr["filter"])) + "::SMALLINT",
+ )
+ for child in modItem["childrenToAlter"]:
+ sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{1}_{2}_check CHECK ({2} = ANY(ARRAY[{3}]);\n""".format(
+ child["schema"],
+ child["table"],
+ attr["attrName"],
+ "::SMALLINT,".join(map(str, attr["filter"])) + "::SMALLINT",
+ )
+ if attr["references"]:
+ sql += """ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n""".format(
+ schema, table, attr["attrName"], attr["references"]
+ )
+ for child in modItem["childrenToAlter"]:
+ sql += """ALTER TABLE "{0}"."{1}"\n ADD CONSTRAINT "{1}_{2}_fk FOREIGN KEY({2}) \n REFERENCES dominios."{3}" (code) MATCH FULL \n ON UPDATE NO ACTION ON DELETE NO ACTION;\n""".format(
+ child["schema"],
+ child["table"],
+ attr["attrName"],
+ attr["references"],
+ )
+ if attr["defaultValue"]:
+ sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};""".format(
+ schema, table, attr["attrName"], attr["defaultValue"]
+ )
+ for child in modItem["childrenToAlter"]:
+ sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN {2} SET DEFAULT {3};""".format(
+ child["schema"],
+ child["table"],
+ attr["attrName"],
+ attr["defaultValue"],
+ )
return sql
-
+
def buildUndoSql(self):
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['AttributeToAdd']:
- schema = modItem['schemaName']
- table = modItem['tableName']
- for attr in modItem['attrList']:
- sql += 'ALTER TABLE "{0}"."{1}" DROP COLUMN IF EXISTS "{2}" CASCADE;'.format(schema, table, attr['attrName'])
- return sql
\ No newline at end of file
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["AttributeToAdd"]:
+ schema = modItem["schemaName"]
+ table = modItem["tableName"]
+ for attr in modItem["attrList"]:
+ sql += 'ALTER TABLE "{0}"."{1}" DROP COLUMN IF EXISTS "{2}" CASCADE;'.format(
+ schema, table, attr["attrName"]
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py
index 313eebe68..bf06cc264 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/classCustomization.py
@@ -20,44 +20,55 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class ClassCustomization(DbCustomization):
def __init__(self, customJson):
super(ClassCustomization, self).__init__(customJson)
-
+
def buildSql(self):
"""
Parses customJson and builds sqls to create class
{'name':name, 'attrs':attrList,'schema':schema}
"""
- #Abstract method. Must be reimplemented in each child.
+ # Abstract method. Must be reimplemented in each child.
sql = """"""
pkClause = """"""
- for table in self.customJson['ClassToAdd']:
- sql += """CREATE TABLE "{0}"."{1}" (\n""".format(table['schema'],table['name'])
+ for table in self.customJson["ClassToAdd"]:
+ sql += """CREATE TABLE "{0}"."{1}" (\n""".format(
+ table["schema"], table["name"]
+ )
pkClause = None
paramsSqlList = []
- for params in table['attrs']:
- paramSql = """ "{0}" {1}""".format(params['attrName'], params['attrType'])
- if not params['isNullable']:
+ for params in table["attrs"]:
+ paramSql = """ "{0}" {1}""".format(
+ params["attrName"], params["attrType"]
+ )
+ if not params["isNullable"]:
paramSql += """ NOT NULL"""
- if params['isPk']:
- pkClause = """ CONSTRAINT {0}_pk PRIMARY KEY ({1})""".format(table['name'],params['attrName'])
+ if params["isPk"]:
+ pkClause = """ CONSTRAINT {0}_pk PRIMARY KEY ({1})""".format(
+ table["name"], params["attrName"]
+ )
paramsSqlList.append(paramSql)
if pkClause:
paramsSqlList.append(pkClause)
sql += """,\n""".join(paramsSqlList)
sql += """\n);\n"""
return sql
-
+
def buildUndoSql(self):
"""
Parses customJson and builds undo sql.
"""
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for table in self.customJson['ClassToAdd']:
- sql += """DROP TABLE "{0}"."{1}";\n""".format(table['schema'],table['name'])
- return sql
\ No newline at end of file
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for table in self.customJson["ClassToAdd"]:
+ sql += """DROP TABLE "{0}"."{1}";\n""".format(
+ table["schema"], table["name"]
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py
index 68e1e4aea..dede22e9e 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/codeNameCustomization.py
@@ -20,26 +20,33 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class CodeNameCustomization(DbCustomization):
def __init__(self, customJson):
super(CodeNameCustomization, self).__init__(customJson)
-
+
def buildSql(self):
- '''
+ """
{'domainTable':domainTable, 'codeValue':codeValue, 'oldCodeName':oldCodeName, 'newCodeName':newCodeName}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['CodeNameToChange']:
- sql += '''UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n'''.format(modItem['domainTable'], modItem['newCodeName'], modItem['codeValue'])
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["CodeNameToChange"]:
+ sql += """UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n""".format(
+ modItem["domainTable"], modItem["newCodeName"], modItem["codeValue"]
+ )
return sql
-
+
def buildUndoSql(self):
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['CodeNameToChange']:
- sql += '''UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n'''.format(modItem['domainTable'], modItem['oldCodeName'], modItem['codeValue'])
- return sql
\ No newline at end of file
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["CodeNameToChange"]:
+ sql += """UPDATE dominios."{0}" SET code_name = '{1}' where code = {2};\n""".format(
+ modItem["domainTable"], modItem["oldCodeName"], modItem["codeValue"]
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py
index 46879c266..19700257a 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomization.py
@@ -20,30 +20,36 @@
* *
***************************************************************************/
"""
-#Qt Imports
+# Qt Imports
from builtins import str
from qgis.PyQt.Qt import QObject
+
class DbCustomization(QObject):
def __init__(self, validatedJSONDict):
super(DbCustomization, self).__init__()
- self.log = ''
- self.errorLog = ''
+ self.log = ""
+ self.errorLog = ""
self.jsonDict = validatedJSONDict
-
+
def getName(self):
- return str(self.__class__).split('.')[-1].replace('\'>', '').replace('Customization','')
-
+ return (
+ str(self.__class__)
+ .split(".")[-1]
+ .replace("'>", "")
+ .replace("Customization", "")
+ )
+
def getLog(self):
return self.log
-
- def logEvent(self,event):
+
+ def logEvent(self, event):
self.log += event
-
+
def buildSql(self):
- #Abstract method. Must be reimplemented in each child.
+ # Abstract method. Must be reimplemented in each child.
pass
-
+
def buildUndoSql(self):
- #Abstract method. Must be reimplemented in each child.
- pass
\ No newline at end of file
+ # Abstract method. Must be reimplemented in each child.
+ pass
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py
index c17fb8535..c235bc8ef 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/dbCustomizationFactory.py
@@ -20,35 +20,51 @@
* *
***************************************************************************/
"""
-#DsgTools imports
+# DsgTools imports
from builtins import object
-from DsgTools.core.Factories.DbCustomizationFactory.attributeCustomization import AttributeCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.classCustomization import ClassCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.codeNameCustomization import CodeNameCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.defaultCustomization import DefaultCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.newDomainTableCustomization import NewDomainTableCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.domainValueCustomization import DomainValueCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.nullityCustomization import NullityCustomization
-from DsgTools.core.Factories.DbCustomizationFactory.filterCustomization import FilterCustomization
+from DsgTools.core.Factories.DbCustomizationFactory.attributeCustomization import (
+ AttributeCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.classCustomization import (
+ ClassCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.codeNameCustomization import (
+ CodeNameCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.defaultCustomization import (
+ DefaultCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.newDomainTableCustomization import (
+ NewDomainTableCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.domainValueCustomization import (
+ DomainValueCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.nullityCustomization import (
+ NullityCustomization,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.filterCustomization import (
+ FilterCustomization,
+)
class DbCustomizationFactory(object):
def createCustomization(self, type, validatedJSONDict):
- if type == 'attribute':
+ if type == "attribute":
return AttributeCustomization(validatedJSONDict)
- elif type == 'class':
+ elif type == "class":
return ClassCustomization(validatedJSONDict)
- elif type == 'codeName':
+ elif type == "codeName":
return CodeNameCustomization(validatedJSONDict)
- elif type == 'default':
- return DefaultCustomization(validatedJSONDict)
- elif type == 'domain':
+ elif type == "default":
+ return DefaultCustomization(validatedJSONDict)
+ elif type == "domain":
return NewDomainTableCustomization(validatedJSONDict)
- elif type == 'domainValue':
+ elif type == "domainValue":
return DomainValueCustomization(validatedJSONDict)
- elif type == 'nullity':
+ elif type == "nullity":
return NullityCustomization(validatedJSONDict)
- elif type == 'filter':
+ elif type == "filter":
return FilterCustomization(validatedJSONDict)
else:
- raise Exception(self.tr('Customization type not defined.'))
+ raise Exception(self.tr("Customization type not defined."))
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py
index a843dc8af..ff87fb3ee 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/defaultCustomization.py
@@ -20,30 +20,42 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class DefaultCustomization(DbCustomization):
def __init__(self, customJson):
super(DefaultCustomization, self).__init__(customJson)
-
+
def buildSql(self, abstractDb):
"""
{'schema': schema, 'table': table, 'attrName':attrName, 'oldValue':oldValue, 'newValue':newValue}
"""
- #Abstract method. Must be reimplemented in each child.
+ # Abstract method. Must be reimplemented in each child.
sql = """"""
- for modItem in self.customJson['ChangeDefault']:
- sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], modItem['newValue'])
+ for modItem in self.customJson["ChangeDefault"]:
+ sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format(
+ modItem["schema"],
+ modItem["table"],
+ modItem["attrName"],
+ modItem["newValue"],
+ )
return sql
-
+
def buildUndoSql(self):
"""
{'schema': schema, 'table': table, 'attrName':attrName, 'oldValue':oldValue, 'newValue':newValue}
"""
- #Abstract method. Must be reimplemented in each child.
+ # Abstract method. Must be reimplemented in each child.
sql = """"""
- for modItem in self.customJson['ChangeDefault']:
- sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], modItem['oldValue'])
+ for modItem in self.customJson["ChangeDefault"]:
+ sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" SET DEFAULT {3};\n""".format(
+ modItem["schema"],
+ modItem["table"],
+ modItem["attrName"],
+ modItem["oldValue"],
+ )
return sql
-
\ No newline at end of file
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py
index 1c4b14893..936eb862e 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/domainValueCustomization.py
@@ -20,29 +20,36 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class DomainValueCustomization(DbCustomization):
def __init__(self, customJson):
super(DomainValueCustomization, self).__init__(customJson)
-
+
def buildSql(self):
- '''
+ """
{'domainName':domainName, 'code':code, 'codeName':codeName}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['domainValue']:
- sql += '''INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n'''.format(modItem['domainName'], modItem['code'], modItem['codeName'])
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["domainValue"]:
+ sql += """INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n""".format(
+ modItem["domainName"], modItem["code"], modItem["codeName"]
+ )
return sql
-
+
def buildUndoSql(self):
- '''
+ """
{'domainName':domainName, 'valueDict': valueDict}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['domainValue']:
- sql += '''DELETE FROM dominios."{0}" where code = {1};'''.format(modItem['domainName'], modItem['code'])
- return sql
\ No newline at end of file
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["domainValue"]:
+ sql += """DELETE FROM dominios."{0}" where code = {1};""".format(
+ modItem["domainName"], modItem["code"]
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py
index 19609ea3e..a627c16ae 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/filterCustomization.py
@@ -20,36 +20,59 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
+# DsgTools Imports
from builtins import map
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class FilterCustomization(DbCustomization):
def __init__(self, customJson):
super(FilterCustomization, self).__init__(customJson)
-
+
def buildSql(self):
- '''
+ """
{'schema':schema, 'tableName':tableName, 'attrName':attrName, 'filterName':filterName,'originalFilterList':originalFilterList, 'valueList':valueList, 'operation':operation, 'isMulti':isMulti}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['FilterValue']:
- filterList = modItem['originalFilterList']
- if modItem['code'] not in filterList:
- filterList.append(modItem['code'])
- sql += ''''ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS {2};\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName'])
- sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT {2} CHECK ({3} = ANY(ARRAY[{4}]);\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName'], modItem['attrName'], '::SMALLINT,'.join(map(str,filterList))+'::SMALLINT')
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["FilterValue"]:
+ filterList = modItem["originalFilterList"]
+ if modItem["code"] not in filterList:
+ filterList.append(modItem["code"])
+ sql += (
+ """'ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS {2};\n""".format(
+ modItem["schema"], modItem["tableName"], modItem["filterName"]
+ )
+ )
+ sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT {2} CHECK ({3} = ANY(ARRAY[{4}]);\n""".format(
+ modItem["schema"],
+ modItem["tableName"],
+ modItem["filterName"],
+ modItem["attrName"],
+ "::SMALLINT,".join(map(str, filterList)) + "::SMALLINT",
+ )
return sql
-
+
def buildUndoSql(self):
- '''
+ """
{'domainName':domainName, 'valueDict': valueDict}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['FilterValue']:
- filterList = modItem['originalFilterList']
- sql += '''ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS "{2}";\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName'])
- sql += '''ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{2}" CHECK ({3} = ANY(ARRAY[{4}]);\n'''.format(modItem['schema'], modItem['tableName'], modItem['filterName'], modItem['attrName'], '::SMALLINT,'.join(map(str,filterList))+'::SMALLINT')
- return sql
\ No newline at end of file
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["FilterValue"]:
+ filterList = modItem["originalFilterList"]
+ sql += (
+ """ALTER TABLE "{0}"."{1}" DROP CONSTRAINT IF EXISTS "{2}";\n""".format(
+ modItem["schema"], modItem["tableName"], modItem["filterName"]
+ )
+ )
+ sql += """ALTER TABLE "{0}"."{1}" ADD CONSTRAINT "{2}" CHECK ({3} = ANY(ARRAY[{4}]);\n""".format(
+ modItem["schema"],
+ modItem["tableName"],
+ modItem["filterName"],
+ modItem["attrName"],
+ "::SMALLINT,".join(map(str, filterList)) + "::SMALLINT",
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py
index b7596c09d..973194601 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/newDomainTableCustomization.py
@@ -20,32 +20,41 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class NewDomainTableCustomization(DbCustomization):
def __init__(self, customJson):
super(NewDomainTableCustomization, self).__init__(customJson)
-
+
def buildSql(self):
- '''
+ """
{'domainName':domainName, 'valueDict': valueDict}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['AddDomainTable']:
- sql += '''CREATE TABLE IF NOT EXISTS dominios."{0}";\n'''.format(modItem['domainName'])
- for code in list(modItem['valueDict'].keys()):
- sql += '''INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n'''.format(modItem['domainName'],code, modItem['valueDict'][code])
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["AddDomainTable"]:
+ sql += """CREATE TABLE IF NOT EXISTS dominios."{0}";\n""".format(
+ modItem["domainName"]
+ )
+ for code in list(modItem["valueDict"].keys()):
+ sql += """INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n""".format(
+ modItem["domainName"], code, modItem["valueDict"][code]
+ )
return sql
-
+
def buildUndoSql(self):
- '''
+ """
{'domainName':domainName, 'valueDict': valueDict}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['AddDomainTable']:
- for code in list(modItem['valueDict'].keys()):
- sql += '''DROP TABLE IF EXISTS dominios."{0}";'''.format(modItem['domainName'])
- return sql
\ No newline at end of file
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["AddDomainTable"]:
+ for code in list(modItem["valueDict"].keys()):
+ sql += """DROP TABLE IF EXISTS dominios."{0}";""".format(
+ modItem["domainName"]
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py
index addc0ba25..0fd56be18 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/newDomainValueCustomization.py
@@ -20,29 +20,36 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class NewDomainValueCustomization(DbCustomization):
def __init__(self, customJson):
super(NewDomainValueCustomization, self).__init__(customJson)
-
+
def buildSql(self):
- '''
+ """
{'domainName':domainName, 'code':code, 'code_name':code_name}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['AddDomainValue']:
- sql += '''INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n'''.format(modItem['domainName'], code, code_name)
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["AddDomainValue"]:
+ sql += """INSERT INTO dominios."{0}" (code, code_name) VALUES ({1}, '{2}');\n""".format(
+ modItem["domainName"], code, code_name
+ )
return sql
-
+
def buildUndoSql(self):
- '''
+ """
{'domainName':domainName, 'code':code, 'code_name':code_name}
- '''
- #Abstract method. Must be reimplemented in each child.
- sql = ''
- for modItem in self.customJson['AddDomainValue']:
- sql += '''DELETE FROM dominios."{0}" where code = {1};\n'''.format(modItem['domainName'], modItem['code'])
- return sql
\ No newline at end of file
+ """
+ # Abstract method. Must be reimplemented in each child.
+ sql = ""
+ for modItem in self.customJson["AddDomainValue"]:
+ sql += """DELETE FROM dominios."{0}" where code = {1};\n""".format(
+ modItem["domainName"], modItem["code"]
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py b/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py
index ad812a700..49d5a593b 100644
--- a/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py
+++ b/DsgTools/core/Factories/DbCustomizationFactory/nullityCustomization.py
@@ -20,37 +20,44 @@
* *
***************************************************************************/
"""
-#DsgTools Imports
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import DbCustomization
+# DsgTools Imports
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomization import (
+ DbCustomization,
+)
+
class NullityCustomization(DbCustomization):
def __init__(self, customJson):
super(NullityCustomization, self).__init__(customJson)
-
+
def buildSql(self):
"""
{'schema':schema, 'table':table, 'attrName':attrName, 'notNull':notNull}
"""
- #Abstract method. Must be reimplemented in each child.
+ # Abstract method. Must be reimplemented in each child.
sql = """"""
- for modItem in self.customJson['ChangeNullity']:
- if modItem['notNull']:
- nullClause = 'SET'
+ for modItem in self.customJson["ChangeNullity"]:
+ if modItem["notNull"]:
+ nullClause = "SET"
else:
- nullClause = 'DROP'
- sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], nullClause)
+ nullClause = "DROP"
+ sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format(
+ modItem["schema"], modItem["table"], modItem["attrName"], nullClause
+ )
return sql
-
+
def buildUndoSql(self):
"""
{'schema':schema, 'table':table, 'attrName':attrName, 'notNull':notNull}
"""
- #Abstract method. Must be reimplemented in each child.
+ # Abstract method. Must be reimplemented in each child.
sql = """"""
- for modItem in self.customJson['ChangeNullity']:
- if not modItem['notNull']:
- nullClause = 'SET'
+ for modItem in self.customJson["ChangeNullity"]:
+ if not modItem["notNull"]:
+ nullClause = "SET"
else:
- nullClause = 'DROP'
- sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format(modItem['schema'], modItem['table'], modItem['attrName'], nullClause)
- return sql
\ No newline at end of file
+ nullClause = "DROP"
+ sql += """ALTER TABLE ONLY "{0}"."{1}" ALTER COLUMN "{2}" {3} NOT NULL;\n""".format(
+ modItem["schema"], modItem["table"], modItem["attrName"], nullClause
+ )
+ return sql
diff --git a/DsgTools/core/Factories/DbFactory/abstractDb.py b/DsgTools/core/Factories/DbFactory/abstractDb.py
index 61282d3f0..745a687c9 100644
--- a/DsgTools/core/Factories/DbFactory/abstractDb.py
+++ b/DsgTools/core/Factories/DbFactory/abstractDb.py
@@ -32,21 +32,31 @@
from ...Utils.utils import Utils
from DsgTools.core.Utils.FrameTools.map_index import UtmGrid
+
class DbSignals(QObject):
updateLog = pyqtSignal(str)
clearLog = pyqtSignal()
+
class AbstractDb(QObject):
def __init__(self):
"""
Constructor
"""
- super(AbstractDb,self).__init__()
- self.conversionTypeDict = dict({'QPSQL':'postgis','QSQLITE':'spatialite'})
+ super(AbstractDb, self).__init__()
+ self.conversionTypeDict = dict({"QPSQL": "postgis", "QSQLITE": "spatialite"})
self.utils = Utils()
self.signals = DbSignals()
self.slotConnected = False
- self.versionFolderDict = dict({'2.1.3':'edgv_213','2.1.3 Pro':'edgv_213_pro','FTer_2a_Ed':'edgv_FTer_2a_Ed','3.0':'3','3.0 Pro':'3_Pro'})
+ self.versionFolderDict = dict(
+ {
+ "2.1.3": "edgv_213",
+ "2.1.3 Pro": "edgv_213_pro",
+ "FTer_2a_Ed": "edgv_FTer_2a_Ed",
+ "3.0": "3",
+ "3.0 Pro": "3_Pro",
+ }
+ )
self.utmGrid = UtmGrid()
def __del__(self):
@@ -57,17 +67,19 @@ def __del__(self):
self.closeDatabase()
except:
pass
-
+
def closeDatabase(self):
pass
-
+
def checkAndOpenDb(self):
"""
Check and open the database
"""
if not self.db.isOpen():
if not self.db.open():
- raise Exception(self.tr('Error opening database: ')+self.db.lastError().text())
+ raise Exception(
+ self.tr("Error opening database: ") + self.db.lastError().text()
+ )
def getType(self):
"""
@@ -90,60 +102,61 @@ def countElements(self, layers):
listaQuantidades = []
for layer in layers:
(schema, className) = self.getTableSchema(layer)
- if layer.split('_')[-1].lower() in ['p','l','a'] or schema == 'complexos':
+ if layer.split("_")[-1].lower() in ["p", "l", "a"] or schema == "complexos":
sql = self.gen.getElementCountFromLayer(layer)
- query = QSqlQuery(sql,self.db)
+ query = QSqlQuery(sql, self.db)
query.next()
number = query.value(0)
if not query.exec_(sql):
- raise Exception(self.tr("Problem counting elements: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem counting elements: ")
+ + query.lastError().text()
+ )
listaQuantidades.append([layer, number])
return listaQuantidades
-
+
def getLayersWithElements(self, layerList):
self.checkAndOpenDb()
lyrWithElemList = []
for lyr in layerList:
# schema=self.getTableSchemaFromDb(lyr)
sql = self.gen.getElementCountFromLayer(lyr)
- query = QSqlQuery(sql,self.db)
+ query = QSqlQuery(sql, self.db)
query.next()
if query.value(0) is not None and query.value(0) > 1:
lyrWithElemList.append(lyr)
return lyrWithElemList
- def getLayersWithElementsV2(self, layerList, useInheritance = False):
+ def getLayersWithElementsV2(self, layerList, useInheritance=False):
self.checkAndOpenDb()
lyrWithElemList = []
for layer in layerList:
if isinstance(layer, dict):
- schema = layer['tableSchema']
- lyr = layer['tableName']
+ schema = layer["tableSchema"]
+ lyr = layer["tableName"]
else:
- if '.' in layer:
- schema, lyr = layer.replace('"','').split('.')
+ if "." in layer:
+ schema, lyr = layer.replace('"', "").split(".")
else:
lyr = layer
schema = self.getTableSchemaFromDb(lyr)
sql = self.gen.getElementCountFromLayerV2(schema, lyr, useInheritance)
- query = QSqlQuery(sql,self.db)
+ query = QSqlQuery(sql, self.db)
if not query.next():
# use may not have permission to read the table from schema
QgsMessageLog.logMessage(
- self.tr("Unable to read table {0}. Error message: '{1}'")\
- .format(
- self.db.databaseName(),
- self.db.lastError().databaseText()
- ),
+ self.tr("Unable to read table {0}. Error message: '{1}'").format(
+ self.db.databaseName(), self.db.lastError().databaseText()
+ ),
"DSGTools Plugin",
- Qgis.Warning
+ Qgis.Warning,
)
continue
if query.value(0) > 0:
lyrWithElemList.append(lyr)
return lyrWithElemList
-
+
def findEPSG(self, parameters=dict()):
"""
Finds the database EPSG
@@ -152,7 +165,9 @@ def findEPSG(self, parameters=dict()):
sql = self.gen.getSrid(parameters=parameters)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem finding EPSG: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem finding EPSG: ") + query.lastError().text()
+ )
srid = -1
while query.next():
srid = query.value(0)
@@ -168,11 +183,11 @@ def listWithElementsFromDatabase(self, classList):
classListWithNumber = self.countElements(classList)
classesWithElements = dict()
for cl in classListWithNumber:
- if cl[1]>0:
- classesWithElements[cl[0]]=cl[1]
+ if cl[1] > 0:
+ classesWithElements[cl[0]] = cl[1]
return classesWithElements
- def listClassesWithElementsFromDatabase(self, useComplex = True, primitiveFilter = []):
+ def listClassesWithElementsFromDatabase(self, useComplex=True, primitiveFilter=[]):
"""
List classes with elements. Uses all classes (complex included)
"""
@@ -193,7 +208,10 @@ def getAggregationAttributes(self):
sql = self.gen.getAggregationColumn()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting aggregation attributes: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting aggregation attributes: ")
+ + query.lastError().text()
+ )
while query.next():
value = query.value(0)
columns.append(value)
@@ -217,18 +235,18 @@ def buildFieldMap(self):
def validateWithOutputDatabaseSchema(self, outputAbstractDb):
return None
-
+
def convertDatabase(self, outputAbstractDb, type):
"""
Converts database
"""
self.signals.clearLog.emit()
- if outputAbstractDb.db.driverName() == 'QPSQL':
- return self.convertToPostgis(outputAbstractDb,type)
- if outputAbstractDb.db.driverName() == 'QSQLITE':
- return self.convertToSpatialite(outputAbstractDb,type)
+ if outputAbstractDb.db.driverName() == "QPSQL":
+ return self.convertToPostgis(outputAbstractDb, type)
+ if outputAbstractDb.db.driverName() == "QSQLITE":
+ return self.convertToSpatialite(outputAbstractDb, type)
return None
-
+
def makeValidationSummary(self, invalidatedDataDict):
"""
Makes the database conversion validation summary
@@ -238,108 +256,210 @@ def makeValidationSummary(self, invalidatedDataDict):
if len(invalidatedDataDict[key]) > 0:
hasErrors = True
if hasErrors:
- self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Validation Problems Summary')))
+ self.signals.updateLog.emit(
+ "\n" + "{:-^60}".format(self.tr("Validation Problems Summary"))
+ )
for key in list(invalidatedDataDict.keys()):
-
- if key == 'nullLine' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Classes with null lines:')+'\n')
- self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n')
+
+ if key == "nullLine" and len(invalidatedDataDict[key]) > 0:
+ self.signals.updateLog.emit(
+ "\n\n" + self.tr("Classes with null lines:") + "\n"
+ )
+ self.signals.updateLog.emit(
+ "\n\n"
+ + "{:<50}".format(self.tr("Class"))
+ + self.tr("Elements")
+ + "\n\n"
+ )
for cl in list(invalidatedDataDict[key].keys()):
- self.signals.updateLog.emit('{:<50}'.format(cl)+str(invalidatedDataDict[key][cl])+'\n')
+ self.signals.updateLog.emit(
+ "{:<50}".format(cl)
+ + str(invalidatedDataDict[key][cl])
+ + "\n"
+ )
- if key == 'nullPk' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Classes with null primary keys:')+'\n')
- self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n')
+ if key == "nullPk" and len(invalidatedDataDict[key]) > 0:
+ self.signals.updateLog.emit(
+ "\n\n" + self.tr("Classes with null primary keys:") + "\n"
+ )
+ self.signals.updateLog.emit(
+ "\n\n"
+ + "{:<50}".format(self.tr("Class"))
+ + self.tr("Elements")
+ + "\n\n"
+ )
for cl in list(invalidatedDataDict[key].keys()):
- self.signals.updateLog.emit('{:<50}'.format(cl)+str(invalidatedDataDict[key][cl])+'\n')
+ self.signals.updateLog.emit(
+ "{:<50}".format(cl)
+ + str(invalidatedDataDict[key][cl])
+ + "\n"
+ )
- if key == 'notInDomain' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Features with attributes not in domain:')+'\n\n')
+ if key == "notInDomain" and len(invalidatedDataDict[key]) > 0:
+ self.signals.updateLog.emit(
+ "\n\n"
+ + self.tr("Features with attributes not in domain:")
+ + "\n\n"
+ )
for cl in list(invalidatedDataDict[key].keys()):
- self.signals.updateLog.emit('\n'+self.tr('Class: ')+cl+'\n')
+ self.signals.updateLog.emit(
+ "\n" + self.tr("Class: ") + cl + "\n"
+ )
for id in list(invalidatedDataDict[key][cl].keys()):
- attrCommaList = '(id,'+','.join(list(invalidatedDataDict[key][cl][id].keys()))+') = '
+ attrCommaList = (
+ "(id,"
+ + ",".join(
+ list(invalidatedDataDict[key][cl][id].keys())
+ )
+ + ") = "
+ )
at = list(invalidatedDataDict[key][cl][id].keys())
- valueList = '('+str(id)
+ valueList = "(" + str(id)
for i in range(len(at)):
- valueList += ','+str(invalidatedDataDict[key][cl][id][at[i]])
- valueList += ')\n'
- self.signals.updateLog.emit(attrCommaList+valueList)
+ valueList += "," + str(
+ invalidatedDataDict[key][cl][id][at[i]]
+ )
+ valueList += ")\n"
+ self.signals.updateLog.emit(attrCommaList + valueList)
- if key == 'nullAttribute' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Features with null attributes in a not null field:')+'\n\n')
+ if key == "nullAttribute" and len(invalidatedDataDict[key]) > 0:
+ self.signals.updateLog.emit(
+ "\n\n"
+ + self.tr("Features with null attributes in a not null field:")
+ + "\n\n"
+ )
for cl in list(invalidatedDataDict[key].keys()):
- self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n')
+ self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n")
for id in list(invalidatedDataDict[key][cl].keys()):
- attrCommaList = '(id,'+','.join(list(invalidatedDataDict[key][cl][id].keys()))+') = '
- valueList = '('+str(id)
+ attrCommaList = (
+ "(id,"
+ + ",".join(
+ list(invalidatedDataDict[key][cl][id].keys())
+ )
+ + ") = "
+ )
+ valueList = "(" + str(id)
for attr in list(invalidatedDataDict[key][cl][id].keys()):
- valueList += ','+str(invalidatedDataDict[key][cl][id][attr])
- valueList += ')\n'
- self.signals.updateLog.emit(attrCommaList+valueList)
+ valueList += "," + str(
+ invalidatedDataDict[key][cl][id][attr]
+ )
+ valueList += ")\n"
+ self.signals.updateLog.emit(attrCommaList + valueList)
- if key == 'nullComplexFk' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Features with invalid uuid foreign key:')+'\n\n')
+ if key == "nullComplexFk" and len(invalidatedDataDict[key]) > 0:
+ self.signals.updateLog.emit(
+ "\n\n"
+ + self.tr("Features with invalid uuid foreign key:")
+ + "\n\n"
+ )
for cl in list(invalidatedDataDict[key].keys()):
- self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n')
+ self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n")
for id in list(invalidatedDataDict[key][cl].keys()):
- attrCommaList = '(id,'+','.join(list(invalidatedDataDict[key][cl][id].keys()))+') = '
- valueList = '('+str(id)
+ attrCommaList = (
+ "(id,"
+ + ",".join(
+ list(invalidatedDataDict[key][cl][id].keys())
+ )
+ + ") = "
+ )
+ valueList = "(" + str(id)
for attr in list(invalidatedDataDict[key][cl][id].keys()):
- valueList += ','+str(invalidatedDataDict[key][cl][id][attr])
- valueList += ')\n'
- self.signals.updateLog.emit(attrCommaList+valueList)
-
- if key == 'classNotFoundInOutput' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Classes with classes that have elements but do not have output equivalent:')+'\n\n')
+ valueList += "," + str(
+ invalidatedDataDict[key][cl][id][attr]
+ )
+ valueList += ")\n"
+ self.signals.updateLog.emit(attrCommaList + valueList)
+
+ if key == "classNotFoundInOutput" and len(invalidatedDataDict[key]) > 0:
+ self.signals.updateLog.emit(
+ "\n\n"
+ + self.tr(
+ "Classes with classes that have elements but do not have output equivalent:"
+ )
+ + "\n\n"
+ )
for cl in invalidatedDataDict[key]:
- self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n')
-
- if key == 'attributeNotFoundInOutput' and len(invalidatedDataDict[key])>0:
- self.signals.updateLog.emit('\n\n'+self.tr('Classes with attributes that have no output attribute equivalent:')+'\n\n')
+ self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n")
+
+ if (
+ key == "attributeNotFoundInOutput"
+ and len(invalidatedDataDict[key]) > 0
+ ):
+ self.signals.updateLog.emit(
+ "\n\n"
+ + self.tr(
+ "Classes with attributes that have no output attribute equivalent:"
+ )
+ + "\n\n"
+ )
for cl in list(invalidatedDataDict[key].keys()):
- self.signals.updateLog.emit(self.tr('Class: ')+cl+'\n')
- valueList = '('+','.join(invalidatedDataDict[key][cl])+')\n'
+ self.signals.updateLog.emit(self.tr("Class: ") + cl + "\n")
+ valueList = "(" + ",".join(invalidatedDataDict[key][cl]) + ")\n"
self.signals.updateLog.emit(valueList)
-
+
return hasErrors
-
- def buildReadSummary(self,inputOgrDb,outputAbstractDb,classList):
+
+ def buildReadSummary(self, inputOgrDb, outputAbstractDb, classList):
"""
Builds the conversion read summary
"""
- self.signals.clearLog.emit() #Clears log
+ self.signals.clearLog.emit() # Clears log
inputType = self.conversionTypeDict[self.db.driverName()]
outputType = self.conversionTypeDict[outputAbstractDb.db.driverName()]
- self.signals.updateLog.emit(self.tr('Conversion type: ')+inputType+'2'+outputType+'\n')
- self.signals.updateLog.emit('\n'+self.tr('Input database: ')+self.db.databaseName()+'\n')
- self.signals.updateLog.emit('\n'+self.tr('Output database: ')+outputAbstractDb.db.databaseName()+'\n')
- self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Read Summary')))
- self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n')
+ self.signals.updateLog.emit(
+ self.tr("Conversion type: ") + inputType + "2" + outputType + "\n"
+ )
+ self.signals.updateLog.emit(
+ "\n" + self.tr("Input database: ") + self.db.databaseName() + "\n"
+ )
+ self.signals.updateLog.emit(
+ "\n"
+ + self.tr("Output database: ")
+ + outputAbstractDb.db.databaseName()
+ + "\n"
+ )
+ self.signals.updateLog.emit("\n" + "{:-^60}".format(self.tr("Read Summary")))
+ self.signals.updateLog.emit(
+ "\n\n" + "{:<50}".format(self.tr("Class")) + self.tr("Elements") + "\n\n"
+ )
for cl in classList:
- self.signals.updateLog.emit('{:<50}'.format(cl)+str(inputOgrDb.GetLayerByName(str(cl)).GetFeatureCount())+'\n')
+ self.signals.updateLog.emit(
+ "{:<50}".format(cl)
+ + str(inputOgrDb.GetLayerByName(str(cl)).GetFeatureCount())
+ + "\n"
+ )
return None
-
+
def makeTranslationMap(self, layerName, layer, outLayer, fieldMapper):
"""
Makes the translation map
"""
- layerFieldMapper=fieldMapper[layerName]
+ layerFieldMapper = fieldMapper[layerName]
layerDef = layer.GetLayerDefn()
outLayerDef = outLayer.GetLayerDefn()
- panMap = []
+ panMap = []
for i in range(layerDef.GetFieldCount()):
featureDef = layerDef.GetFieldDefn(i)
fieldName = featureDef.GetName()
if fieldName in list(layerFieldMapper.keys()):
name = layerFieldMapper[fieldName]
fieldId = outLayerDef.GetFieldIndex(name)
- panMap.append(fieldId)
+ panMap.append(fieldId)
else:
panMap.append(-1)
return panMap
-
- def translateLayer(self, inputLayer, inputLayerName, outputLayer, outputFileName, layerPanMap, errorDict, defaults={}, translateValues={}):
+
+ def translateLayer(
+ self,
+ inputLayer,
+ inputLayerName,
+ outputLayer,
+ outputFileName,
+ layerPanMap,
+ errorDict,
+ defaults={},
+ translateValues={},
+ ):
"""
Makes the layer conversion
"""
@@ -351,66 +471,87 @@ def translateLayer(self, inputLayer, inputLayerName, outputLayer, outputFileName
coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)
initialCount = outputLayer.GetFeatureCount()
count = 0
- feat=inputLayer.GetNextFeature()
- #for feat in inputLayer:
+ feat = inputLayer.GetNextFeature()
+ # for feat in inputLayer:
while feat:
if not feat.geometry():
continue
inputId = feat.GetFID()
if feat.geometry().GetGeometryCount() > 1:
- #Deaggregator
+ # Deaggregator
for geom in feat.geometry():
- newFeat=ogr.Feature(outputLayer.GetLayerDefn())
- newFeat.SetFromWithMap(feat,True,layerPanMap)
+ newFeat = ogr.Feature(outputLayer.GetLayerDefn())
+ newFeat.SetFromWithMap(feat, True, layerPanMap)
auxGeom = ogr.Geometry(newFeat.geometry().GetGeometryType())
- auxGeom.AssignSpatialReference(newFeat.geometry().GetSpatialReference())
+ auxGeom.AssignSpatialReference(
+ newFeat.geometry().GetSpatialReference()
+ )
auxGeom.AddGeometry(geom)
if coordTrans != None:
auxGeom.Transform(coordTrans)
newFeat.SetGeometry(auxGeom)
- out=outputLayer.CreateFeature(newFeat)
+ out = outputLayer.CreateFeature(newFeat)
if out != 0:
- self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId])
+ self.utils.buildNestedDict(
+ errorDict, [inputLayerName], [inputId]
+ )
else:
count += 1
else:
- newFeat=ogr.Feature(outputLayer.GetLayerDefn())
- newFeat.SetFromWithMap(feat,True,layerPanMap)
+ newFeat = ogr.Feature(outputLayer.GetLayerDefn())
+ newFeat.SetFromWithMap(feat, True, layerPanMap)
if coordTrans != None:
geom = feat.GetGeometryRef()
geom.Transform(coordTrans)
newFeat.SetGeometry(geom)
- out=outputLayer.CreateFeature(newFeat)
+ out = outputLayer.CreateFeature(newFeat)
if out != 0:
self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId])
else:
count += 1
- feat=inputLayer.GetNextFeature()
+ feat = inputLayer.GetNextFeature()
return count
-
- def translateDS(self, inputDS, outputDS, fieldMap, inputLayerList, errorDict,invalidated=None):
+
+ def translateDS(
+ self, inputDS, outputDS, fieldMap, inputLayerList, errorDict, invalidated=None
+ ):
"""
Translates the data source
"""
- self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Write Summary')))
- self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Elements')+'\n\n')
+ self.signals.updateLog.emit("\n" + "{:-^60}".format(self.tr("Write Summary")))
+ self.signals.updateLog.emit(
+ "\n\n" + "{:<50}".format(self.tr("Class")) + self.tr("Elements") + "\n\n"
+ )
status = False
for inputLyr in list(inputLayerList.keys()):
schema = self.getTableSchema(inputLyr)
attrList = list(fieldMap[inputLyr].keys())
-
- #sql = self.gen.getFeaturesWithSQL(inputLyr,attrList) #order elements here
- #inputOgrLayer = inputDS.ExecuteSQL(sql.encode('utf-8'))
- #Here I had to change the way of loading because of features ids. I need to use inputDs.GetLayerByName
-
- inputOgrLayer = inputDS.GetLayerByName(str(inputLyr)) #new way of loading layer. The old way was an attempt to make a general rule for conversion between edgv versions
- outputFileName = self.translateOGRLayerNameToOutputFormat(inputLyr,outputDS)
- outputLayer=outputDS.GetLayerByName(outputFileName)
- #order conversion here
- layerPanMap=self.makeTranslationMap(inputLyr, inputOgrLayer,outputLayer, fieldMap)
+
+ # sql = self.gen.getFeaturesWithSQL(inputLyr,attrList) #order elements here
+ # inputOgrLayer = inputDS.ExecuteSQL(sql.encode('utf-8'))
+ # Here I had to change the way of loading because of features ids. I need to use inputDs.GetLayerByName
+
+ inputOgrLayer = inputDS.GetLayerByName(
+ str(inputLyr)
+ ) # new way of loading layer. The old way was an attempt to make a general rule for conversion between edgv versions
+ outputFileName = self.translateOGRLayerNameToOutputFormat(
+ inputLyr, outputDS
+ )
+ outputLayer = outputDS.GetLayerByName(outputFileName)
+ # order conversion here
+ layerPanMap = self.makeTranslationMap(
+ inputLyr, inputOgrLayer, outputLayer, fieldMap
+ )
ini = outputLayer.GetFeatureCount()
if invalidated == None:
- iter=self.translateLayer(inputOgrLayer, inputLyr, outputLayer, outputFileName, layerPanMap, errorDict)
+ iter = self.translateLayer(
+ inputOgrLayer,
+ inputLyr,
+ outputLayer,
+ outputFileName,
+ layerPanMap,
+ errorDict,
+ )
else:
needsFix = False
for keyDict in list(invalidated.values()):
@@ -423,38 +564,62 @@ def translateDS(self, inputDS, outputDS, fieldMap, inputLayerList, errorDict,inv
needsFix = True
break
if needsFix:
- iter = self.translateLayerWithDataFix(inputOgrLayer, inputLyr, outputLayer, outputFileName, layerPanMap, invalidated, errorDict)
+ iter = self.translateLayerWithDataFix(
+ inputOgrLayer,
+ inputLyr,
+ outputLayer,
+ outputFileName,
+ layerPanMap,
+ invalidated,
+ errorDict,
+ )
else:
- iter=self.translateLayer(inputOgrLayer, inputLyr, outputLayer, outputFileName, layerPanMap, errorDict)
+ iter = self.translateLayer(
+ inputOgrLayer,
+ inputLyr,
+ outputLayer,
+ outputFileName,
+ layerPanMap,
+ errorDict,
+ )
if iter == -1:
status = False
- self.signals.updateLog.emit('{:<50}'.format(self.tr('Error on layer ')+inputLyr+self.tr('. Conversion not performed.')+'\n'))
+ self.signals.updateLog.emit(
+ "{:<50}".format(
+ self.tr("Error on layer ")
+ + inputLyr
+ + self.tr(". Conversion not performed.")
+ + "\n"
+ )
+ )
return status
- diff = outputLayer.GetFeatureCount()-ini
+ diff = outputLayer.GetFeatureCount() - ini
if iter == diff:
status = True
else:
status = False
- self.signals.updateLog.emit('{:<50}'.format(str(outputFileName))+str(diff)+'\n')
+ self.signals.updateLog.emit(
+ "{:<50}".format(str(outputFileName)) + str(diff) + "\n"
+ )
self.writeErrorLog(errorDict)
outputDS.Destroy()
return status
-
+
def buildInvalidatedDict(self):
"""
Builds the initial state of the conversion invalidated dictionary
"""
invalidated = dict()
- invalidated['nullLine'] = dict()
- invalidated['nullPk'] = dict()
- invalidated['notInDomain'] = dict()
- invalidated['nullAttribute'] = dict()
- invalidated['classNotFoundInOutput'] = []
- invalidated['attributeNotFoundInOutput'] = dict()
- invalidated['nullComplexFk'] = dict()
+ invalidated["nullLine"] = dict()
+ invalidated["nullPk"] = dict()
+ invalidated["notInDomain"] = dict()
+ invalidated["nullAttribute"] = dict()
+ invalidated["classNotFoundInOutput"] = []
+ invalidated["attributeNotFoundInOutput"] = dict()
+ invalidated["nullComplexFk"] = dict()
return invalidated
-
- def prepareForConversion(self,outputAbstractDb):
+
+ def prepareForConversion(self, outputAbstractDb):
"""
Executes preconditions for the conversion
"""
@@ -465,10 +630,21 @@ def prepareForConversion(self,outputAbstractDb):
outputOgrDb = outputAbstractDb.buildOgrDatabase()
inputLayerList = self.listClassesWithElementsFromDatabase()
errorDict = dict()
- self.buildReadSummary(inputOgrDb,outputAbstractDb,inputLayerList)
+ self.buildReadSummary(inputOgrDb, outputAbstractDb, inputLayerList)
return (inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict)
- def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, outputFileName, layerPanMap, invalidated, errorDict, defaults={}, translateValues={}):
+ def translateLayerWithDataFix(
+ self,
+ inputLayer,
+ inputLayerName,
+ outputLayer,
+ outputFileName,
+ layerPanMap,
+ invalidated,
+ errorDict,
+ defaults={},
+ translateValues={},
+ ):
"""
casos e tratamentos:
1. nullLine: os atributos devem ser varridos e, caso seja linha nula, ignorar o envio
@@ -489,15 +665,15 @@ def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, out
if inSpatialRef != outSpatialRef:
coordTrans = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)
count = 0
- feat=inputLayer.GetNextFeature()
- (schema,className) = self.getTableSchema(inputLayerName)
+ feat = inputLayer.GetNextFeature()
+ (schema, className) = self.getTableSchema(inputLayerName)
outputOgrLyrDict = self.getOgrLayerIndexDict(outputLayer)
- if inputLayerName not in invalidated['classNotFoundInOutput']:
+ if inputLayerName not in invalidated["classNotFoundInOutput"]:
while feat:
if not feat.geometry():
continue
nullLine = True
- #Case 1: nullLine
+ # Case 1: nullLine
for i in range(fieldCount):
if feat.GetField(i) != None:
nullLine = False
@@ -505,43 +681,97 @@ def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, out
if feat.GetFID() != -1 or feat.geometry() != None:
nullLine = False
if not nullLine:
- if inputLayerName not in invalidated['classNotFoundInOutput']:
- newFeat=ogr.Feature(outputLayer.GetLayerDefn())
+ if inputLayerName not in invalidated["classNotFoundInOutput"]:
+ newFeat = ogr.Feature(outputLayer.GetLayerDefn())
inputId = feat.GetFID()
- #Case 2: nullPk in complex:
- newFeat.SetFromWithMap(feat,True,layerPanMap)
- if schema == 'complexos' and feat.GetFID() == -1:
+ # Case 2: nullPk in complex:
+ newFeat.SetFromWithMap(feat, True, layerPanMap)
+ if schema == "complexos" and feat.GetFID() == -1:
newFeat.SetFID(uuid4())
- #Case 3
+ # Case 3
for j in range(inputLayer.GetLayerDefn().GetFieldCount()):
if layerPanMap[j] != -1:
- if inputLayerName in list(invalidated['notInDomain'].keys()):
- if inputId in list(invalidated['notInDomain'][inputLayerName].keys()):
- if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetName() in list(invalidated['notInDomain'][inputLayerName][inputId].keys()):
+ if inputLayerName in list(
+ invalidated["notInDomain"].keys()
+ ):
+ if inputId in list(
+ invalidated["notInDomain"][
+ inputLayerName
+ ].keys()
+ ):
+ if outputLayer.GetLayerDefn().GetFieldDefn(
+ layerPanMap[j]
+ ).GetName() in list(
+ invalidated["notInDomain"][inputLayerName][
+ inputId
+ ].keys()
+ ):
newFeat.UnsetField(layerPanMap[j])
- if inputLayerName in list(invalidated['nullAttribute'].keys()):
- if inputId in list(invalidated['nullAttribute'][inputLayerName].keys()):
- if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetName() in list(invalidated['nullAttribute'][inputLayerName][inputId].keys()):
- if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetTypeName() == 'String':
- newFeat.SetField(layerPanMap[j],'-9999')
- if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetTypeName() == 'Integer':
- newFeat.SetField(layerPanMap[j],-9999)
- if inputLayerName in list(invalidated['nullComplexFk'].keys()):
- if inputId in list(invalidated['nullComplexFk'][inputLayerName].keys()):
- if outputLayer.GetLayerDefn().GetFieldDefn(layerPanMap[j]).GetName() in list(invalidated['nullComplexFk'][inputLayerName][inputId].keys()):
+ if inputLayerName in list(
+ invalidated["nullAttribute"].keys()
+ ):
+ if inputId in list(
+ invalidated["nullAttribute"][
+ inputLayerName
+ ].keys()
+ ):
+ if outputLayer.GetLayerDefn().GetFieldDefn(
+ layerPanMap[j]
+ ).GetName() in list(
+ invalidated["nullAttribute"][
+ inputLayerName
+ ][inputId].keys()
+ ):
+ if (
+ outputLayer.GetLayerDefn()
+ .GetFieldDefn(layerPanMap[j])
+ .GetTypeName()
+ == "String"
+ ):
+ newFeat.SetField(
+ layerPanMap[j], "-9999"
+ )
+ if (
+ outputLayer.GetLayerDefn()
+ .GetFieldDefn(layerPanMap[j])
+ .GetTypeName()
+ == "Integer"
+ ):
+ newFeat.SetField(layerPanMap[j], -9999)
+ if inputLayerName in list(
+ invalidated["nullComplexFk"].keys()
+ ):
+ if inputId in list(
+ invalidated["nullComplexFk"][
+ inputLayerName
+ ].keys()
+ ):
+ if outputLayer.GetLayerDefn().GetFieldDefn(
+ layerPanMap[j]
+ ).GetName() in list(
+ invalidated["nullComplexFk"][
+ inputLayerName
+ ][inputId].keys()
+ ):
newFeat.UnsetField(layerPanMap[j])
if newFeat.geometry().GetGeometryCount() > 1:
- #Deaggregator
+ # Deaggregator
for geom in newFeat.geometry():
- auxGeom = ogr.Geometry(newFeat.geometry().GetGeometryType())
- auxGeom.AssignSpatialReference(newFeat.geometry().GetSpatialReference())
+ auxGeom = ogr.Geometry(
+ newFeat.geometry().GetGeometryType()
+ )
+ auxGeom.AssignSpatialReference(
+ newFeat.geometry().GetSpatialReference()
+ )
auxGeom.AddGeometry(geom)
if coordTrans != None:
auxGeom.Transform(coordTrans)
newFeat.SetGeometry(auxGeom)
- out=outputLayer.CreateFeature(newFeat)
+ out = outputLayer.CreateFeature(newFeat)
if out != 0:
- self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId])
+ self.utils.buildNestedDict(
+ errorDict, [inputLayerName], [inputId]
+ )
else:
count += 1
else:
@@ -549,39 +779,41 @@ def translateLayerWithDataFix(self, inputLayer, inputLayerName, outputLayer, out
geom = feat.GetGeometryRef()
geom.Transform(coordTrans)
newFeat.SetGeometry(geom)
- out=outputLayer.CreateFeature(newFeat)
+ out = outputLayer.CreateFeature(newFeat)
if out != 0:
- self.utils.buildNestedDict(errorDict, [inputLayerName], [inputId])
+ self.utils.buildNestedDict(
+ errorDict, [inputLayerName], [inputId]
+ )
else:
count += 1
- feat=inputLayer.GetNextFeature()
+ feat = inputLayer.GetNextFeature()
return count
else:
return -1
-
+
def buildOgrDatabase(self):
"""
Build a OGR database
"""
con = self.makeOgrConn()
- ogrDb = ogr.Open(con,update=1)
+ ogrDb = ogr.Open(con, update=1)
return ogrDb
-
+
def reorderTupleList(self, ls):
"""
Reorders a tuple list
ls: list to be reordered
"""
- if 'OGC_FID' in ls:
- idField = 'OGC_FID'
+ if "OGC_FID" in ls:
+ idField = "OGC_FID"
else:
- idField = 'id'
+ idField = "id"
index = ls.index(idField)
reordered = [ls[index]]
reordered.extend(ls[0:index])
- reordered.extend(ls[index+1::])
+ reordered.extend(ls[index + 1 : :])
return reordered
-
+
def getOgrLayerIndexDict(self, lyr):
"""
Gets ogr field definitions
@@ -589,21 +821,28 @@ def getOgrLayerIndexDict(self, lyr):
ogrDict = dict()
layerDef = lyr.GetLayerDefn()
for i in range(layerDef.GetFieldCount()):
- ogrDict[i] = layerDef.GetFieldDefn(i).GetName()
+ ogrDict[i] = layerDef.GetFieldDefn(i).GetName()
return ogrDict
-
- def writeErrorLog(self,errorDict):
+
+ def writeErrorLog(self, errorDict):
"""
Writes conversion error log
"""
errorClasses = list(errorDict.keys())
- if len(errorClasses)>0:
- self.signals.updateLog.emit('\n'+'{:-^60}'.format(self.tr('Features not converted')))
- self.signals.updateLog.emit('\n\n'+'{:<50}'.format(self.tr('Class'))+self.tr('Feature id')+'\n\n')
+ if len(errorClasses) > 0:
+ self.signals.updateLog.emit(
+ "\n" + "{:-^60}".format(self.tr("Features not converted"))
+ )
+ self.signals.updateLog.emit(
+ "\n\n"
+ + "{:<50}".format(self.tr("Class"))
+ + self.tr("Feature id")
+ + "\n\n"
+ )
for cl in errorClasses:
for id in errorDict[cl]:
- self.signals.updateLog.emit('\n\n'+'{:<50}'.format(cl+str(id)))
-
+ self.signals.updateLog.emit("\n\n" + "{:<50}".format(cl + str(id)))
+
def getQmlDir(self):
"""
Gets the QML directory
@@ -612,95 +851,99 @@ def getQmlDir(self):
if Qgis.QGIS_VERSION_INT >= 30000:
# treat old implementations (bug fixes on domain values)
implVersion = self.implementationVersion()
- if implVersion == '' or float(implVersion) < 3:
- qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_37_impl_2')
+ if implVersion == "" or float(implVersion) < 3:
+ qmlVersionPath = os.path.join(
+ currentPath, "..", "..", "Qmls", "qgis_37_impl_2"
+ )
else:
- qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_37')
+ qmlVersionPath = os.path.join(
+ currentPath, "..", "..", "Qmls", "qgis_37"
+ )
elif Qgis.QGIS_VERSION_INT >= 20600:
- qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_26')
+ qmlVersionPath = os.path.join(currentPath, "..", "..", "Qmls", "qgis_26")
else:
- qmlVersionPath = os.path.join(currentPath, '..', '..', 'Qmls', 'qgis_22')
+ qmlVersionPath = os.path.join(currentPath, "..", "..", "Qmls", "qgis_22")
version = self.getDatabaseVersion()
- if version == '3.0':
- qmlPath = os.path.join(qmlVersionPath, 'edgv_3')
- elif version == '3.0 Pro':
- qmlPath = os.path.join(qmlVersionPath, 'edgv_3_pro')
- elif version == '2.1.3':
- qmlPath = os.path.join(qmlVersionPath, 'edgv_213')
- elif version == '2.1.3 Pro':
- qmlPath = os.path.join(qmlVersionPath, 'edgv_213_pro')
- elif version == 'FTer_2a_Ed':
- qmlPath = os.path.join(qmlVersionPath, 'FTer_2a_Ed')
+ if version == "3.0":
+ qmlPath = os.path.join(qmlVersionPath, "edgv_3")
+ elif version == "3.0 Pro":
+ qmlPath = os.path.join(qmlVersionPath, "edgv_3_pro")
+ elif version == "2.1.3":
+ qmlPath = os.path.join(qmlVersionPath, "edgv_213")
+ elif version == "2.1.3 Pro":
+ qmlPath = os.path.join(qmlVersionPath, "edgv_213_pro")
+ elif version == "FTer_2a_Ed":
+ qmlPath = os.path.join(qmlVersionPath, "FTer_2a_Ed")
else:
- qmlPath = ''
+ qmlPath = ""
return qmlPath
-
+
def getStyleDirectory(self, dbVersion):
"""
dbVersion: database version in the format of abstractDb.getVersion()
Gets the directory of the styles
"""
currentPath = os.path.dirname(__file__)
- styleDir = os.path.join(currentPath, '..', '..', 'Styles')
- if dbVersion == '2.1.3':
- styleDir = os.path.join(styleDir, 'edgv_213')
- elif dbVersion == '2.1.3 Pro':
- styleDir = os.path.join(styleDir, 'edgv_213_pro')
- elif dbVersion == '3.0':
- styleDir = os.path.join(styleDir, 'edgv_3')
- elif dbVersion == '3.0 Pro':
- styleDir = os.path.join(styleDir, 'edgv_3_pro')
- elif dbVersion == 'FTer_2a_Ed':
- styleDir = os.path.join(styleDir, 'edgv_FTer_2a_Ed')
+ styleDir = os.path.join(currentPath, "..", "..", "Styles")
+ if dbVersion == "2.1.3":
+ styleDir = os.path.join(styleDir, "edgv_213")
+ elif dbVersion == "2.1.3 Pro":
+ styleDir = os.path.join(styleDir, "edgv_213_pro")
+ elif dbVersion == "3.0":
+ styleDir = os.path.join(styleDir, "edgv_3")
+ elif dbVersion == "3.0 Pro":
+ styleDir = os.path.join(styleDir, "edgv_3_pro")
+ elif dbVersion == "FTer_2a_Ed":
+ styleDir = os.path.join(styleDir, "edgv_FTer_2a_Ed")
else:
- styleDir = os.path.join(styleDir, 'Non_EDGV')
+ styleDir = os.path.join(styleDir, "Non_EDGV")
return styleDir
def getStyleDict(self, dbVersion):
"""
dbVersion: database version in the format of abstractDb.getVersion()
- The first iteration of walk lists all dirs as the second element of the list in next(os.walk(styleDir))[1].
+ The first iteration of walk lists all dirs as the second element of the list in next(os.walk(styleDir))[1].
"""
styleDir = self.getStyleDirectory(dbVersion)
styleList = []
try:
for f in os.listdir(styleDir):
- if '.py' in f.lower() or '.pyc' in f.lower():
+ if ".py" in f.lower() or ".pyc" in f.lower():
continue
styleList.append(f)
except FileNotFoundError:
# in case style folder is not found, it will be created
currentPath = os.path.dirname(__file__)
- if not os.path.exists(os.path.join(currentPath, '..', '..', 'Styles')):
- os.makedirs(os.path.join(currentPath, '..', '..', 'Styles'))
+ if not os.path.exists(os.path.join(currentPath, "..", "..", "Styles")):
+ os.makedirs(os.path.join(currentPath, "..", "..", "Styles"))
if not os.path.exists(styleDir):
os.makedirs(styleDir)
styleDict = dict()
try:
for s in styleList:
- if '.DS_Store' not in s: #mac os ignore
- styleDict['dir:'+s] = os.path.join(styleDir, s)
- #here we get the styles from db if there are any
+ if ".DS_Store" not in s: # mac os ignore
+ styleDict["dir:" + s] = os.path.join(styleDir, s)
+ # here we get the styles from db if there are any
except:
pass
try:
dbStyles = self.getStylesFromDb(dbVersion)
if dbStyles:
for style in dbStyles:
- name = style.split('/')[-1]
- styleDict['db:'+name] = 'db:'+style
+ name = style.split("/")[-1]
+ styleDict["db:" + name] = "db:" + style
except:
pass
return styleDict
-
+
def makeValueRelationDict(self, table, codes):
"""
Makes the value relation dictionary (multi valued attributes)
"""
self.checkAndOpenDb()
ret = dict()
- in_clause = '(%s)' % ",".join(map(str, codes))
+ in_clause = "(%s)" % ",".join(map(str, codes))
sql = self.gen.makeRelationDict(table, in_clause)
query = QSqlQuery(sql, self.db)
while query.next():
@@ -708,35 +951,41 @@ def makeValueRelationDict(self, table, codes):
code_name = query.value(1)
ret[code_name] = code
return ret
-
+
def createFrameFromInom(self, inom):
frame = self.utmGrid.getQgsPolygonFrame(inom)
return frame
-
- def insertFrame(self, scale, mi, inom, frame, paramDict = dict()):
+
+ def insertFrame(self, scale, mi, inom, frame, paramDict=dict()):
self.checkAndOpenDb()
srid = self.findEPSG()
- geoSrid = QgsCoordinateReferenceSystem(int(srid)).geographicCrsAuthId().split(':')[-1]
- sql = self.gen.insertFrame(scale, mi, inom, frame, srid, geoSrid, paramDict = paramDict)
+ geoSrid = (
+ QgsCoordinateReferenceSystem(int(srid)).geographicCrsAuthId().split(":")[-1]
+ )
+ sql = self.gen.insertFrame(
+ scale, mi, inom, frame, srid, geoSrid, paramDict=paramDict
+ )
self.db.transaction()
query = QSqlQuery(self.db)
if not query.exec_(sql):
self.db.rollback()
self.db.close()
- raise Exception(self.tr('Problem inserting frame: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem inserting frame: ") + query.lastError().text()
+ )
self.db.commit()
# self.db.close()
-
+
def prepareCreateFrame(self, type, scale, param):
- if type == 'mi':
+ if type == "mi":
mi = str(param)
- if scale == '250k':
+ if scale == "250k":
inom = self.utmGrid.getINomenFromMIR(str(param))
else:
inom = self.utmGrid.getINomenFromMI(str(param))
- elif type == 'inom':
+ elif type == "inom":
inom = str(param)
- if scale == '250k':
+ if scale == "250k":
mi = self.utmGrid.getINomenFromMIR(inom)
else:
mi = self.utmGrid.getMIfromInom(inom)
@@ -745,7 +994,10 @@ def prepareCreateFrame(self, type, scale, param):
def getQmlDict(self, layerList):
edgvVersion = self.getDatabaseVersion()
- if edgvVersion in ['2.1.3','FTer_2a_Ed']: #this does not have 3.0, do not change it!!!!
+ if edgvVersion in [
+ "2.1.3",
+ "FTer_2a_Ed",
+ ]: # this does not have 3.0, do not change it!!!!
qmlPath = self.getQmlDir()
return self.utils.parseMultiQml(qmlPath, layerList)
else:
@@ -755,7 +1007,7 @@ def getQmlDict(self, layerList):
qmlPath = self.getQmlDir()
return self.utils.parseMultiQml(qmlPath, layerList)
return self.utils.parseMultiFromDb(qmlRecordDict, layerList)
-
+
def getQmlRecordDict(self, inputLayer):
self.checkAndOpenDb()
if isinstance(inputLayer, list):
@@ -764,23 +1016,25 @@ def getQmlRecordDict(self, inputLayer):
sql = self.gen.getQmlRecords([inputLayer])
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting qmlRecordDict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting qmlRecordDict: ") + query.lastError().text()
+ )
qmlDict = dict()
while query.next():
- if isinstance(inputLayer, list):
+ if isinstance(inputLayer, list):
qmlDict[query.value(0)] = query.value(1)
else:
return query.value(1)
return qmlDict
-
+
def getQml(self, layerName):
- if self.getDatabaseVersion() == '3.0':
+ if self.getDatabaseVersion() == "3.0":
try:
- return (self.getQmlRecordDict(layerName), 'db')
+ return (self.getQmlRecordDict(layerName), "db")
except:
- return (self.getQmlDir(), 'dir')
+ return (self.getQmlDir(), "dir")
else:
- return (self.getQmlDir(), 'dir')
+ return (self.getQmlDir(), "dir")
def implementationVersion(self):
"""
@@ -792,17 +1046,17 @@ def implementationVersion(self):
self.checkAndOpenDb()
query = QSqlQuery(self.gen.implementationVersion(), self.db)
if not query.isActive():
- return ''
+ return ""
while query.next():
version = query.value(0)
break
return version if version is not None else -1
-
+
def getVersionString(self):
version = self.getDatabaseVersion()
- if version == 'Non_EDGV':
+ if version == "Non_EDGV":
return self.tr("Unknown DB model")
- if version in ['2.1.3', '3.0']:
+ if version in ["2.1.3", "3.0"]:
version = f"EDGV {version}"
implementation = self.implementationVersion()
return f"{version} impl. {implementation}"
@@ -815,7 +1069,9 @@ def getImplementationVersion(self):
sql = self.gen.getImplementationVersion()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting implementation version: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting implementation version: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
diff --git a/DsgTools/core/Factories/DbFactory/dbFactory.py b/DsgTools/core/Factories/DbFactory/dbFactory.py
index 4a0f879d9..3826729f6 100644
--- a/DsgTools/core/Factories/DbFactory/dbFactory.py
+++ b/DsgTools/core/Factories/DbFactory/dbFactory.py
@@ -24,7 +24,7 @@
from qgis.PyQt.QtSql import QSqlDatabase
from qgis.core import QgsMessageLog, Qgis
-#DSG Tools imports
+# DSG Tools imports
from .spatialiteDb import SpatialiteDb
from .postgisDb import PostgisDb
from .geopackageDb import GeopackageDb
@@ -34,17 +34,18 @@
from builtins import object
import os
+
class DbFactory(object):
def createDbFactory(self, driver):
- #TODO Treat none return
- if not ('QPSQL' in QSqlDatabase.drivers()): #Driver wasn't loaded
- raise Exception('QT PSQL driver not installed!')
- if not ('QSQLITE' in QSqlDatabase.drivers()): #Driver wasn't loaded
- raise Exception('QT QSQLITE driver not installed!')
+ # TODO Treat none return
+ if not ("QPSQL" in QSqlDatabase.drivers()): # Driver wasn't loaded
+ raise Exception("QT PSQL driver not installed!")
+ if not ("QSQLITE" in QSqlDatabase.drivers()): # Driver wasn't loaded
+ raise Exception("QT QSQLITE driver not installed!")
dbs = {
- DsgEnums.DriverSpatiaLite : lambda : SpatialiteDb(),
- DsgEnums.DriverPostGIS : lambda : PostgisDb(),
- DsgEnums.DriverGeopackage : lambda : GeopackageDb(),
- DsgEnums.DriverShapefile : lambda : ShapefileDb()
+ DsgEnums.DriverSpatiaLite: lambda: SpatialiteDb(),
+ DsgEnums.DriverPostGIS: lambda: PostgisDb(),
+ DsgEnums.DriverGeopackage: lambda: GeopackageDb(),
+ DsgEnums.DriverShapefile: lambda: ShapefileDb(),
}
return dbs[driver]() if driver in dbs else None
diff --git a/DsgTools/core/Factories/DbFactory/geopackageDb.py b/DsgTools/core/Factories/DbFactory/geopackageDb.py
index 4645ebf08..3772e2540 100644
--- a/DsgTools/core/Factories/DbFactory/geopackageDb.py
+++ b/DsgTools/core/Factories/DbFactory/geopackageDb.py
@@ -23,7 +23,7 @@
from qgis.PyQt.QtSql import QSqlQuery, QSqlDatabase
from qgis.PyQt.QtWidgets import QFileDialog
-from qgis.core import QgsCoordinateReferenceSystem
+from qgis.core import QgsCoordinateReferenceSystem
from .spatialiteDb import SpatialiteDb
from ..SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
@@ -32,33 +32,40 @@
from osgeo import ogr, osr
import os
+
class GeopackageDb(SpatialiteDb):
"""
Geopackage is an OGC format base on SpatiLite, hence, it
should inherit methods from SpatiaLite driver.
"""
+
def __init__(self):
"""
Constructor.
"""
super(GeopackageDb, self).__init__()
- self.gen = SqlGeneratorFactory().createSqlGenerator(driver=DsgEnums.DriverGeopackage)
-
+ self.gen = SqlGeneratorFactory().createSqlGenerator(
+ driver=DsgEnums.DriverGeopackage
+ )
+
def getDatabaseName(self):
"""
Gets the database name.
:return: (str) database name.
"""
# reimplementation
- return os.path.basename(self.db.databaseName()).split('.gpkg')[0]
-
+ return os.path.basename(self.db.databaseName()).split(".gpkg")[0]
+
def connectDatabaseWithGui(self):
"""
Connects to database using user interface dialog
"""
# reimplementation
fd = QFileDialog()
- filename = fd.getOpenFileName(caption=self.tr('Select a DSGTools Geopackage file'),filter=self.tr('Geopackage file databases (*.gpkg)'))
+ filename = fd.getOpenFileName(
+ caption=self.tr("Select a DSGTools Geopackage file"),
+ filter=self.tr("Geopackage file databases (*.gpkg)"),
+ )
filename = filename[0] if isinstance(filename, tuple) else filename
self.db.setDatabaseName(filename)
@@ -73,11 +80,13 @@ def listClassesFromDatabase(self):
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem listing geom classes: ") + query.lastError().text()
+ )
while query.next():
classList.append(str(query.value(0)))
return classList
-
+
def getTablesFromDatabase(self):
"""
Gets all tables from database except for configuration tables.
@@ -90,15 +99,22 @@ def getTablesFromDatabase(self):
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem getting tables from database: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting tables from database: ")
+ + query.lastError().text()
+ )
while query.next():
- #table name
+ # table name
table = query.value(0)
- if 'gpkg_' not in table.lower() and 'rtree_' not in table.lower() and table.lower() != 'sqlite_sequence':
+ if (
+ "gpkg_" not in table.lower()
+ and "rtree_" not in table.lower()
+ and table.lower() != "sqlite_sequence"
+ ):
ret.append(table)
return ret
-
+
def getGeomColumnDict(self):
"""
Dict in the form 'geomName':[-list of table names-]
@@ -107,25 +123,29 @@ def getGeomColumnDict(self):
sql = self.gen.getGeomColumnDict()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom column dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom column dict: ") + query.lastError().text()
+ )
geomDict = dict()
while query.next():
geomColumn = query.value(0)
tableName = query.value(1)
- lyrName = '_'.join(tableName.split('_')[1::])
+ lyrName = "_".join(tableName.split("_")[1::])
if geomColumn not in list(geomDict.keys()):
geomDict[geomColumn] = []
geomDict[geomColumn].append(lyrName)
return geomDict
-
+
def getTableSchemaFromDb(self, table):
self.checkAndOpenDb()
sql = self.gen.getFullTablesName(table)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting full table name: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting full table name: ") + query.lastError().text()
+ )
while query.next():
- return query.value(0).split('_')[0]
+ return query.value(0).split("_")[0]
def getGeomTypeDict(self, loadCentroids=False):
self.checkAndOpenDb()
@@ -133,57 +153,65 @@ def getGeomTypeDict(self, loadCentroids=False):
sql = self.gen.getGeomByPrimitive(edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom types from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom types from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
while query.next():
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
type_ = query.value(0)
else:
type_ = self.getResolvedGeomType(query.value(0))
tableName = query.value(1)
- layerName = '_'.join(tableName.split('_')[1::])
+ layerName = "_".join(tableName.split("_")[1::])
if type_ not in list(geomDict.keys()):
geomDict[type_] = []
if layerName not in geomDict[type_]:
geomDict[type_].append(layerName)
return geomDict
- def getGeomDict(self, getCentroids = False):
- '''
+ def getGeomDict(self, getCentroids=False):
+ """
returns a dict like this:
{'tablePerspective' : {
'layerName' :
- '''
+ """
self.checkAndOpenDb()
edgvVersion = self.getDatabaseVersion()
sql = self.gen.getGeomTablesFromGeometryColumns(edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tables from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tables from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
- geomDict['primitivePerspective'] = self.getGeomTypeDict()
- geomDict['tablePerspective'] = dict()
+ geomDict["primitivePerspective"] = self.getGeomTypeDict()
+ geomDict["tablePerspective"] = dict()
while query.next():
isCentroid = False
srid = query.value(0)
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
geometryType = query.value(2)
else:
geometryType = self.getResolvedGeomType(query.value(2))
tableName = query.value(3)
- tableSchema = tableName.split('_')[0]
+ tableSchema = tableName.split("_")[0]
geometryColumn = query.value(1)
- layerName = '_'.join(tableName.split('_')[1::])
- if layerName not in list(geomDict['tablePerspective'].keys()):
- geomDict['tablePerspective'][layerName] = dict()
- geomDict['tablePerspective'][layerName]['schema'] = tableSchema
- geomDict['tablePerspective'][layerName]['srid'] = str(srid)
- geomDict['tablePerspective'][layerName]['geometryColumn'] = geometryColumn
- geomDict['tablePerspective'][layerName]['geometryType'] = geometryType
- geomDict['tablePerspective'][layerName]['tableName'] = tableName
+ layerName = "_".join(tableName.split("_")[1::])
+ if layerName not in list(geomDict["tablePerspective"].keys()):
+ geomDict["tablePerspective"][layerName] = dict()
+ geomDict["tablePerspective"][layerName]["schema"] = tableSchema
+ geomDict["tablePerspective"][layerName]["srid"] = str(srid)
+ geomDict["tablePerspective"][layerName][
+ "geometryColumn"
+ ] = geometryColumn
+ geomDict["tablePerspective"][layerName]["geometryType"] = geometryType
+ geomDict["tablePerspective"][layerName]["tableName"] = tableName
return geomDict
- def getGeomColumnTupleList(self, showViews = False):
+ def getGeomColumnTupleList(self, showViews=False):
"""
list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)]
centroids are hidden by default
@@ -193,42 +221,50 @@ def getGeomColumnTupleList(self, showViews = False):
sql = self.gen.getGeomColumnTupleList(edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tuple list: ") + query.lastError().text()
+ )
geomList = []
while query.next():
geomList.append(
(
- query.value(0).split('_')[0],
- '_'.join(query.value(0).split('_')[1::]),
+ query.value(0).split("_")[0],
+ "_".join(query.value(0).split("_")[1::]),
query.value(1),
self.getResolvedGeomType(query.value(2)),
- 'BASE TABLE'
+ "BASE TABLE",
)
)
return geomList
-
+
def getResolvedGeomType(self, geometryType):
- geomDict = {0:'GEOMETRY',
- 1:'POINT',
- 2:'LINESTRING',
- 3:'POLYGON',
- 4:'MULTIPOINT',
- 5:'MULTILINESTRING',
- 6:'MULTIPOLYGON',
- 7:'GEOMETRYCOLLECTION',
- 8:'CIRCULARSTRING',
- 9:'COMPOUNDCURVE',
- 10:'CURVEPOLYGON',
- 11:'MULTICURVE',
- 12:'MULTISURFACE',
- 13:'CURVE',
- 14:'SURFACE'}
- return geometryType if geometryType in geomDict.values() else geomDict[int(geometryType)]
+ geomDict = {
+ 0: "GEOMETRY",
+ 1: "POINT",
+ 2: "LINESTRING",
+ 3: "POLYGON",
+ 4: "MULTIPOINT",
+ 5: "MULTILINESTRING",
+ 6: "MULTIPOLYGON",
+ 7: "GEOMETRYCOLLECTION",
+ 8: "CIRCULARSTRING",
+ 9: "COMPOUNDCURVE",
+ 10: "CURVEPOLYGON",
+ 11: "MULTICURVE",
+ 12: "MULTISURFACE",
+ 13: "CURVE",
+ 14: "SURFACE",
+ }
+ return (
+ geometryType
+ if geometryType in geomDict.values()
+ else geomDict[int(geometryType)]
+ )
def getType(self):
"""
Gets the driver name.
:return: (str) driver name.
"""
- return 'GPKG'
+ return "GPKG"
diff --git a/DsgTools/core/Factories/DbFactory/postgisDb.py b/DsgTools/core/Factories/DbFactory/postgisDb.py
index 17fbf06fd..eef08558a 100644
--- a/DsgTools/core/Factories/DbFactory/postgisDb.py
+++ b/DsgTools/core/Factories/DbFactory/postgisDb.py
@@ -24,11 +24,13 @@
from qgis.core import Qgis
from qgis.PyQt.QtSql import QSqlQuery, QSqlDatabase
from qgis.PyQt.QtCore import QSettings
-from qgis.core import (Qgis,
- QgsMessageLog,
- QgsCredentials,
- QgsVectorLayer,
- QgsDataSourceUri)
+from qgis.core import (
+ Qgis,
+ QgsMessageLog,
+ QgsCredentials,
+ QgsVectorLayer,
+ QgsDataSourceUri,
+)
from .abstractDb import AbstractDb
from ..SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
@@ -48,11 +50,13 @@ def __init__(self):
Constructor
"""
super(PostgisDb, self).__init__()
- #setting database type to postgresql
- self.db = QSqlDatabase('QPSQL')
- #setting up a sql generator
- self.gen = SqlGeneratorFactory().createSqlGenerator(driver=DsgEnums.DriverPostGIS)
- self.databaseEncoding = 'utf-8'
+ # setting database type to postgresql
+ self.db = QSqlDatabase("QPSQL")
+ # setting up a sql generator
+ self.gen = SqlGeneratorFactory().createSqlGenerator(
+ driver=DsgEnums.DriverPostGIS
+ )
+ self.databaseEncoding = "utf-8"
def closeDatabase(self):
if self.db is not None and self.db.isOpen():
@@ -63,7 +67,12 @@ def getDatabaseParameters(self):
"""
Gets (host, port, user, password)
"""
- return (self.db.hostName(), self.db.port(), self.db.userName(), self.db.password())
+ return (
+ self.db.hostName(),
+ self.db.port(),
+ self.db.userName(),
+ self.db.password(),
+ )
def getDatabaseName(self):
"""
@@ -79,13 +88,19 @@ def connectDatabase(self, conn=None):
Connects to database
conn: connection parameters. It can be a OGR connection or a QSettings connection
"""
- if conn.split(':')[0] == 'PG':
- connSplit = conn.split(' ')
+ if conn.split(":")[0] == "PG":
+ connSplit = conn.split(" ")
parDict = dict()
for i in connSplit[1::]:
- par = i.split('=')
+ par = i.split("=")
parDict[par[0]] = par[1]
- self.connectDatabaseWithParameters(parDict['host'], parDict['port'], parDict['dbname'], parDict['user'], parDict['password'])
+ self.connectDatabaseWithParameters(
+ parDict["host"],
+ parDict["port"],
+ parDict["dbname"],
+ parDict["user"],
+ parDict["password"],
+ )
else:
self.connectDatabaseWithQSettings(conn)
@@ -105,7 +120,9 @@ def getCredentials(self, host, port, user, database):
conInfo = "host={0} port={1} dbname={2}".format(host, port, database)
check = False
while not check:
- (success, user, password) = QgsCredentials.instance().get(conInfo, user, None)
+ (success, user, password) = QgsCredentials.instance().get(
+ conInfo, user, None
+ )
if not success:
return
if self.testCredentials(host, port, database, user, password):
@@ -131,21 +148,23 @@ def connectDatabaseWithQSettings(self, name):
Connects to database with parameters
name: QSettings connection name
"""
- #getting connection parameters from qsettings
+ # getting connection parameters from qsettings
(host, port, database, user, password) = self.getConnectionFromQSettings(name)
self.db.setHostName(host)
- if type(port) != 'int':
+ if type(port) != "int":
self.db.setPort(int(port))
else:
self.db.setPort(port)
self.db.setDatabaseName(database)
self.db.setUserName(user)
- if not password or password == '':
- conInfo = 'host='+host+' port='+port+' dbname='+database
+ if not password or password == "":
+ conInfo = "host=" + host + " port=" + port + " dbname=" + database
check = False
while not check:
try:
- (success, user, password) = QgsCredentials.instance().get(conInfo, user, None)
+ (success, user, password) = QgsCredentials.instance().get(
+ conInfo, user, None
+ )
if not success:
return
self.db.setPassword(password)
@@ -165,13 +184,19 @@ def getDatabaseVersion(self):
sql = self.gen.getEDGVVersion()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- return 'Non_EDGV'
- version = '-1'
+ return "Non_EDGV"
+ version = "-1"
while query.next():
version = query.value(0)
return version
- def listGeomClassesFromDatabase(self, primitiveFilter = [], withElements = False, excludeViews = True, getGeometryColumn = False):
+ def listGeomClassesFromDatabase(
+ self,
+ primitiveFilter=[],
+ withElements=False,
+ excludeViews=True,
+ getGeometryColumn=False,
+ ):
"""
Gets a list with geometry classes from database
returns dict if getGeometryColumn = True
@@ -179,45 +204,63 @@ def listGeomClassesFromDatabase(self, primitiveFilter = [], withElements = False
"""
self.checkAndOpenDb()
classList = []
- schemaList = [i for i in self.getGeomSchemaList() if i not in ['validation', 'views']]
- #primitiveFilter building
+ schemaList = [
+ i for i in self.getGeomSchemaList() if i not in ["validation", "views"]
+ ]
+ # primitiveFilter building
dbPrimitiveList = []
if len(primitiveFilter) > 0:
for primitive in primitiveFilter:
- if primitive == 'p':
- dbPrimitiveList.append('POINT')
- dbPrimitiveList.append('MULTIPOINT')
- if primitive == 'l':
- dbPrimitiveList.append('LINESTRING')
- dbPrimitiveList.append('MULTILINESTRING')
- if primitive == 'a':
- dbPrimitiveList.append('POLYGON')
- dbPrimitiveList.append('MULTIPOLYGON')
- sql = self.gen.getGeomTables(schemaList, dbPrimitiveList = dbPrimitiveList, excludeViews = excludeViews, geomColumn = getGeometryColumn)
- query = QSqlQuery(sql, self.db)
- if not query.isActive():
- raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text())
+ if primitive == "p":
+ dbPrimitiveList.append("POINT")
+ dbPrimitiveList.append("MULTIPOINT")
+ if primitive == "l":
+ dbPrimitiveList.append("LINESTRING")
+ dbPrimitiveList.append("MULTILINESTRING")
+ if primitive == "a":
+ dbPrimitiveList.append("POLYGON")
+ dbPrimitiveList.append("MULTIPOLYGON")
+ sql = self.gen.getGeomTables(
+ schemaList,
+ dbPrimitiveList=dbPrimitiveList,
+ excludeViews=excludeViews,
+ geomColumn=getGeometryColumn,
+ )
+ query = QSqlQuery(sql, self.db)
+ if not query.isActive():
+ raise Exception(
+ self.tr("Problem listing geom classes: ") + query.lastError().text()
+ )
localList = []
while query.next():
tableSchema = query.value(0)
tableName = query.value(1)
- layerName = tableSchema+'.'+tableName
- geometryColumn = ''
+ layerName = tableSchema + "." + tableName
+ geometryColumn = ""
if getGeometryColumn:
geometryColumn = query.value(2)
- localList.append({'schema':tableSchema, 'tableName':tableName, 'layerName':layerName, 'geometryColumn':geometryColumn})
- #remove possible duplicates to filter layers with elements
+ localList.append(
+ {
+ "schema": tableSchema,
+ "tableName": tableName,
+ "layerName": layerName,
+ "geometryColumn": geometryColumn,
+ }
+ )
+ # remove possible duplicates to filter layers with elements
layerNameList = []
for i in localList:
- if i['layerName'] not in layerNameList:
- layerNameList.append(i['layerName'])
+ if i["layerName"] not in layerNameList:
+ layerNameList.append(i["layerName"])
if withElements:
listWithElements = self.getLayersWithElementsV2(layerNameList)
- partialTagList = [i for i in localList if i['tableName'] in listWithElements]
+ partialTagList = [
+ i for i in localList if i["tableName"] in listWithElements
+ ]
else:
partialTagList = localList
if not getGeometryColumn:
- classList = [i['layerName'] for i in partialTagList]
+ classList = [i["layerName"] for i in partialTagList]
else:
classList = partialTagList
return classList
@@ -231,12 +274,14 @@ def listComplexClassesFromDatabase(self):
sql = self.gen.getTablesFromDatabase()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem listing complex classes: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem listing complex classes: ") + query.lastError().text()
+ )
while query.next():
tableSchema = query.value(0)
tableName = query.value(1)
- layerName = tableSchema+'.'+tableName
- if tableSchema == 'complexos':
+ layerName = tableSchema + "." + tableName
+ if tableSchema == "complexos":
classList.append(layerName)
classList.sort()
return classList
@@ -247,15 +292,15 @@ def storeConnection(self, server):
"""
(host, port, user, password) = self.getServerConfiguration(server)
database = self.db.databaseName()
- connection = server+'_'+database
+ connection = server + "_" + database
settings = QSettings()
- if not settings.contains('PostgreSQL/connections/'+connection+'/database'):
- settings.beginGroup('PostgreSQL/connections/'+connection)
- settings.setValue('database', database)
- settings.setValue('host', host)
- settings.setValue('port', port)
- settings.setValue('username', user)
- settings.setValue('password', password)
+ if not settings.contains("PostgreSQL/connections/" + connection + "/database"):
+ settings.beginGroup("PostgreSQL/connections/" + connection)
+ settings.setValue("database", database)
+ settings.setValue("host", host)
+ settings.setValue("port", port)
+ settings.setValue("username", user)
+ settings.setValue("password", password)
settings.endGroup()
return True
return False
@@ -266,14 +311,14 @@ def getConnectionFromQSettings(self, conName):
conName: connection name stored
"""
settings = QSettings()
- settings.beginGroup('PostgreSQL/connections/'+conName)
- host = settings.value('host')
- port = settings.value('port')
- database = settings.value('database')
- user = settings.value('username')
- password = settings.value('password')
+ settings.beginGroup("PostgreSQL/connections/" + conName)
+ host = settings.value("host")
+ port = settings.value("port")
+ database = settings.value("database")
+ user = settings.value("username")
+ password = settings.value("password")
settings.endGroup()
- return (host, port, database, user, password)
+ return (host, port, database, user, password)
def getServerConfiguration(self, name):
"""
@@ -281,11 +326,11 @@ def getServerConfiguration(self, name):
name: server name
"""
settings = QSettings()
- settings.beginGroup('PostgreSQL/servers/'+name)
- host = settings.value('host')
- port = settings.value('port')
- user = settings.value('username')
- password = settings.value('password')
+ settings.beginGroup("PostgreSQL/servers/" + name)
+ host = settings.value("host")
+ port = settings.value("port")
+ user = settings.value("username")
+ password = settings.value("password")
settings.endGroup()
return (host, port, user, password)
@@ -295,23 +340,32 @@ def getStructureDict(self):
"""
self.checkAndOpenDb()
classDict = dict()
- sql = self.gen.getStructure(self.getDatabaseVersion())
+ sql = self.gen.getStructure(self.getDatabaseVersion())
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting database structure: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting database structure: ")
+ + query.lastError().text()
+ )
while query.next():
- className = str(query.value(0))+'.'+str(query.value(1))
+ className = str(query.value(0)) + "." + str(query.value(1))
fieldName = str(query.value(2))
- if str(query.value(0)) == 'complexos' or className.split('_')[-1] in ['p','l','a']:
+ if str(query.value(0)) == "complexos" or className.split("_")[-1] in [
+ "p",
+ "l",
+ "a",
+ ]:
if className not in list(classDict.keys()):
- classDict[className]=dict()
- classDict[className][fieldName]=fieldName
- if 'geom' in list(classDict[className].keys()):
- classDict[className]['geom'] = 'GEOMETRY'
- if str(query.value(0)) != 'complexos' and 'id' in list(classDict[className].keys()):
- classDict[className]['id'] = 'OGC_FID'
+ classDict[className] = dict()
+ classDict[className][fieldName] = fieldName
+ if "geom" in list(classDict[className].keys()):
+ classDict[className]["geom"] = "GEOMETRY"
+ if str(query.value(0)) != "complexos" and "id" in list(
+ classDict[className].keys()
+ ):
+ classDict[className]["id"] = "OGC_FID"
return classDict
-
+
def makeOgrConn(self):
"""
Makes a OGR connection string
@@ -321,7 +375,18 @@ def makeOgrConn(self):
dbHost = self.db.hostName()
dbPass = self.db.password()
dbPort = str(self.db.port())
- constring = 'PG: dbname=\''+dbName+'\' user=\''+dbUser+'\' host=\''+dbHost+'\' password=\''+dbPass+'\' port='+dbPort
+ constring = (
+ "PG: dbname='"
+ + dbName
+ + "' user='"
+ + dbUser
+ + "' host='"
+ + dbHost
+ + "' password='"
+ + dbPass
+ + "' port="
+ + dbPort
+ )
return constring
def getNotNullDict(self):
@@ -329,26 +394,32 @@ def getNotNullDict(self):
Gets a dictionary with all not null fields for the edgv database used
"""
self.checkAndOpenDb()
- if self.getDatabaseVersion() == '2.1.3':
- schemaList = ['cb', 'complexos']
- elif self.getDatabaseVersion() in ('3.0', '2.1.3 Pro', '3.0 Pro'):
- schemaList = ['edgv', 'complexos']
- elif self.getDatabaseVersion() == 'FTer_2a_Ed':
- schemaList = ['pe','ge', 'complexos']
+ if self.getDatabaseVersion() == "2.1.3":
+ schemaList = ["cb", "complexos"]
+ elif self.getDatabaseVersion() in ("3.0", "2.1.3 Pro", "3.0 Pro"):
+ schemaList = ["edgv", "complexos"]
+ elif self.getDatabaseVersion() == "FTer_2a_Ed":
+ schemaList = ["pe", "ge", "complexos"]
else:
- QgsMessageLog.logMessage(self.tr('Operation not defined for this database version!'), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.tr("Operation not defined for this database version!"),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
return None
-
+
sql = self.gen.getNotNullFields(schemaList)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem executing query: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ") + query.lastError().text()
+ )
notNullDict = dict()
while query.next():
schemaName = str(query.value(0))
className = str(query.value(1))
attName = str(query.value(2))
- cl = schemaName+'.'+className
+ cl = schemaName + "." + className
if cl not in list(notNullDict.keys()):
notNullDict[cl] = []
notNullDict[cl].append(attName)
@@ -359,21 +430,27 @@ def getDomainDict(self):
SHOULD BE DEPRECATED OR IN FOR A MAJOR REFACTORY!!!!!
Gets the domain dictionary for the edgv database used
"""
- self.checkAndOpenDb()
- if self.getDatabaseVersion() == '2.1.3':
- schemaList = ['cb', 'complexos', 'dominios']
- elif self.getDatabaseVersion() in ('3.0', '2.1.3 Pro', '3.0 Pro'):
- schemaList = ['edgv', 'complexos', 'dominios']
- elif self.getDatabaseVersion() == 'FTer_2a_Ed':
- schemaList = ['pe','ge', 'complexos']
+ self.checkAndOpenDb()
+ if self.getDatabaseVersion() == "2.1.3":
+ schemaList = ["cb", "complexos", "dominios"]
+ elif self.getDatabaseVersion() in ("3.0", "2.1.3 Pro", "3.0 Pro"):
+ schemaList = ["edgv", "complexos", "dominios"]
+ elif self.getDatabaseVersion() == "FTer_2a_Ed":
+ schemaList = ["pe", "ge", "complexos"]
else:
- QgsMessageLog.logMessage(self.tr('Operation not defined for this database version!'), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.tr("Operation not defined for this database version!"),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
return
-
+
sql = self.gen.validateWithDomain(schemaList)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem executing query: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ") + query.lastError().text()
+ )
classDict = dict()
domainDict = dict()
@@ -384,11 +461,13 @@ def getDomainDict(self):
domainName = str(query.value(3))
domainTable = str(query.value(4))
domainQuery = str(query.value(5))
- cl = schemaName+'.'+className
- query2 = QSqlQuery(domainQuery,self.db)
+ cl = schemaName + "." + className
+ query2 = QSqlQuery(domainQuery, self.db)
while query2.next():
value = int(query2.value(0))
- classDict = self.utils.buildNestedDict(classDict,[str(cl),str(attName)],[value])
+ classDict = self.utils.buildNestedDict(
+ classDict, [str(cl), str(attName)], [value]
+ )
return classDict
def translateAbstractDbLayerNameToOutputFormat(self, lyr, outputAbstractDb):
@@ -397,9 +476,9 @@ def translateAbstractDbLayerNameToOutputFormat(self, lyr, outputAbstractDb):
lyr: layer name that will be translated
outputAbstractDb: output database
"""
- if outputAbstractDb.db.driverName() == 'QSQLITE':
- return str(lyr.split('.')[0]+'_'+'_'.join(lyr.split('.')[1::]))
- if outputAbstractDb.db.driverName() == 'QPSQL':
+ if outputAbstractDb.db.driverName() == "QSQLITE":
+ return str(lyr.split(".")[0] + "_" + "_".join(lyr.split(".")[1::]))
+ if outputAbstractDb.db.driverName() == "QPSQL":
return lyr
def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput):
@@ -408,31 +487,39 @@ def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput):
lyr: layer name that will be translated
ogrOutput: ogr output
"""
- if ogrOutput.GetDriver().name == 'SQLite':
- return str(lyr.split('.')[0]+'_'+'_'.join(lyr.split('.')[1::]))
- if ogrOutput.GetDriver().name == 'PostgreSQL':
+ if ogrOutput.GetDriver().name == "SQLite":
+ return str(lyr.split(".")[0] + "_" + "_".join(lyr.split(".")[1::]))
+ if ogrOutput.GetDriver().name == "PostgreSQL":
return lyr
- def getTableSchema(self,lyr):
+ def getTableSchema(self, lyr):
"""
DEPRECATED
Gets the table schema
lyr: layer name
"""
- schema = lyr.split('.')[0]
- className = '_'.join(lyr.split('.')[1::])
+ schema = lyr.split(".")[0]
+ className = "_".join(lyr.split(".")[1::])
return (schema, className)
-
+
def convertToSpatialite(self, outputAbstractDb, type=None):
"""
Converts this to a spatialite database
outputAbstractDb: spatialite output
type: conversion type
"""
- (inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) = self.prepareForConversion(outputAbstractDb)
- status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict)
+ (
+ inputOgrDb,
+ outputOgrDb,
+ fieldMap,
+ inputLayerList,
+ errorDict,
+ ) = self.prepareForConversion(outputAbstractDb)
+ status = self.translateDS(
+ inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict
+ )
return status
-
+
def obtainLinkColumn(self, complexClass, aggregatedClass):
"""
Obtains the link column between complex and aggregated class
@@ -440,44 +527,52 @@ def obtainLinkColumn(self, complexClass, aggregatedClass):
aggregatedClass: aggregated class name
"""
self.checkAndOpenDb()
- complexClass = complexClass.replace('complexos.', '')
- #query to obtain the link column between the complex and the feature layer
+ complexClass = complexClass.replace("complexos.", "")
+ # query to obtain the link column between the complex and the feature layer
sql = self.gen.getLinkColumn(complexClass, aggregatedClass)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem obtaining link column: ")+query.lastError().text())
- column_name = ''
+ raise Exception(
+ self.tr("Problem obtaining link column: ") + query.lastError().text()
+ )
+ column_name = ""
while query.next():
column_name = query.value(0)
return column_name
def loadAssociatedFeatures(self, complex):
"""
- Loads all the features associated to the complex
+ Loads all the features associated to the complex
complex: complex class name
"""
self.checkAndOpenDb()
associatedDict = dict()
- complex = complex.replace('complexos.', '')
- #query to get the possible links to the selected complex in the combobox
+ complex = complex.replace("complexos.", "")
+ # query to get the possible links to the selected complex in the combobox
sql = self.gen.getComplexLinks(complex)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem loading associated features: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem loading associated features: ")
+ + query.lastError().text()
+ )
while query.next():
- #setting the variables
+ # setting the variables
complex_schema = query.value(0)
complex = query.value(1)
aggregated_schema = query.value(2)
aggregated_class = query.value(3)
column_name = query.value(4)
- #query to obtain the created complexes
+ # query to obtain the created complexes
sql = self.gen.getComplexData(complex_schema, complex)
complexQuery = QSqlQuery(sql, self.db)
if not complexQuery.isActive():
- raise Exception(self.tr("Problem loading associated features: ")+complexQuery.lastError().text())
+ raise Exception(
+ self.tr("Problem loading associated features: ")
+ + complexQuery.lastError().text()
+ )
while complexQuery.next():
complex_uuid = complexQuery.value(0)
@@ -485,30 +580,43 @@ def loadAssociatedFeatures(self, complex):
if not (complex_uuid and name):
continue
-
- associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [])
-
- #query to obtain the id of the associated feature
- sql = self.gen.getAssociatedFeaturesData(aggregated_schema, aggregated_class, column_name, complex_uuid)
+
+ associatedDict = self.utils.buildNestedDict(
+ associatedDict, [name, complex_uuid, aggregated_class], []
+ )
+
+ # query to obtain the id of the associated feature
+ sql = self.gen.getAssociatedFeaturesData(
+ aggregated_schema, aggregated_class, column_name, complex_uuid
+ )
associatedQuery = QSqlQuery(sql, self.db)
if not associatedQuery.isActive():
- raise Exception(self.tr("Problem loading associated features: ")+associatedQuery.lastError().text())
+ raise Exception(
+ self.tr("Problem loading associated features: ")
+ + associatedQuery.lastError().text()
+ )
while associatedQuery.next():
ogc_fid = associatedQuery.value(0)
- associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [ogc_fid])
+ associatedDict = self.utils.buildNestedDict(
+ associatedDict,
+ [name, complex_uuid, aggregated_class],
+ [ogc_fid],
+ )
return associatedDict
-
+
def isComplexClass(self, className):
"""
Checks if a class is a complex class
className: class name to be checked
"""
self.checkAndOpenDb()
- #getting all complex tables
+ # getting all complex tables
query = QSqlQuery(self.gen.getComplexTablesFromDatabase(), self.db)
if not query.isActive():
- raise Exception(self.tr("Problem executing query: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ") + query.lastError().text()
+ )
while query.next():
if query.value(0) == className:
@@ -525,23 +633,29 @@ def disassociateComplexFromComplex(self, aggregated_class, link_column, id):
sql = self.gen.disassociateComplexFromComplex(aggregated_class, link_column, id)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem disassociating complex from complex: ') + '\n' + query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem disassociating complex from complex: ")
+ + "\n"
+ + query.lastError().text()
+ )
+
def getUsers(self):
"""
Gets 'this' database users
"""
self.checkAndOpenDb()
ret = []
-
+
sql = self.gen.getUsers()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting users: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting users: ") + query.lastError().text()
+ )
while query.next():
ret.append(query.value(0))
-
+
ret.sort()
return ret
@@ -557,7 +671,9 @@ def getUserRelatedRoles(self, username):
sql = self.gen.getUserRelatedRoles(username)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting user roles: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting user roles: ") + query.lastError().text()
+ )
while query.next():
rolname = query.value(0)
@@ -570,7 +686,7 @@ def getUserRelatedRoles(self, username):
installed.sort()
assigned.sort()
return installed, assigned
-
+
def getRoles(self):
"""
Gets roles installed in 'this' database
@@ -581,7 +697,9 @@ def getRoles(self):
sql = self.gen.getRoles()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting roles: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting roles: ") + query.lastError().text()
+ )
while query.next():
ret.append(query.value(0))
@@ -589,27 +707,32 @@ def getRoles(self):
ret.sort()
return ret
- def createRole(self, role, roleDict, permissionManager = False):
+ def createRole(self, role, roleDict, permissionManager=False):
"""
Creates a role into this database
role: role name
dict: role definitions
"""
self.checkAndOpenDb()
- #making this so the instaciated permissions stay with different names
- uuid = str(uuid4()).replace('-', '_')
- role += '_'+uuid
+ # making this so the instaciated permissions stay with different names
+ uuid = str(uuid4()).replace("-", "_")
+ role += "_" + uuid
sql = self.gen.createRole(role, roleDict)
- split = sql.split(';')
+ split = sql.split(";")
query = QSqlQuery(self.db)
-
+
if permissionManager:
if not query.exec_(sql):
- raise Exception(self.tr('Problem assigning profile: ') +role+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem assigning profile: ")
+ + role
+ + "\n"
+ + query.lastError().text()
+ )
return role
- #try to revoke the permissions
+ # try to revoke the permissions
try:
self.dropRole(role)
except:
@@ -617,12 +740,17 @@ def createRole(self, role, roleDict, permissionManager = False):
for inner in split:
if not query.exec_(inner):
- if '42710' in query.lastError().text():
- #In this case the role is already created (duplicate object error). We just need to proceed executing the grants.
+ if "42710" in query.lastError().text():
+ # In this case the role is already created (duplicate object error). We just need to proceed executing the grants.
continue
else:
- raise Exception(self.tr('Problem assigning profile: ') +role+'\n'+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem assigning profile: ")
+ + role
+ + "\n"
+ + query.lastError().text()
+ )
+
def dropRole(self, role):
"""
Deletes a role from 'this' database
@@ -630,16 +758,21 @@ def dropRole(self, role):
"""
self.checkAndOpenDb()
sql = self.gen.dropRole(role)
- split = sql.split('#')
+ split = sql.split("#")
query = QSqlQuery(self.db)
for inner in split:
if not query.exec_(inner):
- if '2BP01' in query.lastError().text():
- #In this case the role is still used by other databases, therefore it shouldn't be dropped.
+ if "2BP01" in query.lastError().text():
+ # In this case the role is still used by other databases, therefore it shouldn't be dropped.
continue
else:
- raise Exception(self.tr('Problem removing profile: ') +role+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem removing profile: ")
+ + role
+ + "\n"
+ + query.lastError().text()
+ )
def alterUserPass(self, user, newpassword):
"""
@@ -652,7 +785,12 @@ def alterUserPass(self, user, newpassword):
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem altering user\'s password: ') +user+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem altering user's password: ")
+ + user
+ + "\n"
+ + query.lastError().text()
+ )
def createUser(self, user, password, isSuperUser):
"""
@@ -666,7 +804,12 @@ def createUser(self, user, password, isSuperUser):
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem creating user: ') +user+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating user: ")
+ + user
+ + "\n"
+ + query.lastError().text()
+ )
def removeUser(self, user):
"""
@@ -678,7 +821,12 @@ def removeUser(self, user):
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem removing user: ') +user+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem removing user: ")
+ + user
+ + "\n"
+ + query.lastError().text()
+ )
def grantRole(self, user, role):
"""
@@ -691,7 +839,12 @@ def grantRole(self, user, role):
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem granting profile: ') +role+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem granting profile: ")
+ + role
+ + "\n"
+ + query.lastError().text()
+ )
def revokeRole(self, user, role):
"""
@@ -704,7 +857,12 @@ def revokeRole(self, user, role):
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem revoking profile: ') +role+'\n'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem revoking profile: ")
+ + role
+ + "\n"
+ + query.lastError().text()
+ )
def getTablesFromDatabase(self):
"""
@@ -716,10 +874,13 @@ def getTablesFromDatabase(self):
sql = self.gen.getTablesFromDatabase()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting tables from database: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting tables from database: ")
+ + query.lastError().text()
+ )
while query.next():
- #table name
+ # table name
ret.append("{0}.{1}".format(query.value(0), query.value(1)))
return ret
@@ -732,72 +893,99 @@ def getRolePrivileges(self, role, dbname):
"""
self.checkAndOpenDb()
privilegesDict = dict()
-
+
sql = self.gen.getRolePrivileges(role, dbname)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting role privileges: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem getting role privileges: ") + query.lastError().text()
+ )
+
while query.next():
schema = query.value(3)
table = query.value(4)
privilege = query.value(5)
-
- if schema in ['cb', 'public', 'complexos', 'dominios', 'pe', 'ge']:
- privilegesDict = self.utils.buildNestedDict(privilegesDict, [schema, table], [privilege])
-
+
+ if schema in ["cb", "public", "complexos", "dominios", "pe", "ge"]:
+ privilegesDict = self.utils.buildNestedDict(
+ privilegesDict, [schema, table], [privilege]
+ )
+
permissionsDict = dict()
for schema in list(privilegesDict.keys()):
for table in list(privilegesDict[schema].keys()):
- split = table.split('_')
+ split = table.split("_")
category = split[0]
- layerName = schema+'.'+table
-
+ layerName = schema + "." + table
+
if schema not in list(permissionsDict.keys()):
permissionsDict[schema] = dict()
-
+
if category not in list(permissionsDict[schema].keys()):
permissionsDict[schema][category] = dict()
privileges = privilegesDict[schema][table]
- write = ['DELETE', 'INSERT', 'SELECT', 'UPDATE', 'TRUNCATE', 'REFERENCES', 'TRIGGER']
+ write = [
+ "DELETE",
+ "INSERT",
+ "SELECT",
+ "UPDATE",
+ "TRUNCATE",
+ "REFERENCES",
+ "TRIGGER",
+ ]
if all((permission in privileges for permission in write)):
if layerName not in permissionsDict[schema][category]:
permissionsDict[schema][category][layerName] = dict()
- permissionsDict[schema][category][layerName]['read'] = '2'#read yes
- permissionsDict[schema][category][layerName]['write'] = '2'#write yes
+ permissionsDict[schema][category][layerName][
+ "read"
+ ] = "2" # read yes
+ permissionsDict[schema][category][layerName][
+ "write"
+ ] = "2" # write yes
else:
if layerName not in permissionsDict[schema][category]:
permissionsDict[schema][category][layerName] = dict()
- permissionsDict[schema][category][layerName]['read'] = '2'#read yes
- permissionsDict[schema][category][layerName]['write'] = '0'#write no
-
- return permissionsDict
+ permissionsDict[schema][category][layerName][
+ "read"
+ ] = "2" # read yes
+ permissionsDict[schema][category][layerName][
+ "write"
+ ] = "0" # write no
+
+ return permissionsDict
def getFrameLayerName(self):
"""
Gets the frame layer name
"""
- return 'public.aux_moldura_a'
-
- def getEDGVDbsFromServer(self, parentWidget = None, getDatabaseVersions = True):
+ return "public.aux_moldura_a"
+
+ def getEDGVDbsFromServer(self, parentWidget=None, getDatabaseVersions=True):
"""
Gets edgv databases from 'this' server
"""
- #Can only be used in postgres database.
+ # Can only be used in postgres database.
self.checkAndOpenDb()
- query = QSqlQuery(self.gen.getDatabasesFromServer(),self.db)
+ query = QSqlQuery(self.gen.getDatabasesFromServer(), self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting EDGV databases: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting EDGV databases: ") + query.lastError().text()
+ )
dbList = []
-
+
while query.next():
dbList.append(query.value(0))
-
+
edvgDbList = []
if parentWidget:
- progress = ProgressWidget(1,len(dbList),self.tr('Reading selected databases... '), parent = parentWidget)
+ progress = ProgressWidget(
+ 1,
+ len(dbList),
+ self.tr("Reading selected databases... "),
+ parent=parentWidget,
+ )
progress.initBar()
if getDatabaseVersions:
for database in dbList:
@@ -811,10 +999,11 @@ def getEDGVDbsFromServer(self, parentWidget = None, getDatabaseVersions = True):
if not db.open():
# raise Exception(self.tr("Problem opening databases: ")+db.lastError().databaseText())
QgsMessageLog.logMessage(
- self.tr("Unable to load {0}. Error message: '{1}'")\
- .format(database, db.lastError().databaseText()),
+ self.tr("Unable to load {0}. Error message: '{1}'").format(
+ database, db.lastError().databaseText()
+ ),
"DSGTools Plugin",
- Qgis.Warning
+ Qgis.Warning,
)
continue
@@ -824,53 +1013,67 @@ def getEDGVDbsFromServer(self, parentWidget = None, getDatabaseVersions = True):
count = query2.value(0)
if count > 0:
query3 = QSqlQuery(db)
- if query3.exec_(self.gen.getEDGVVersionAndImplementationVersion()):
+ if query3.exec_(
+ self.gen.getEDGVVersionAndImplementationVersion()
+ ):
while query3.next():
version = query3.value(0)
implVersion = query3.value(1)
if version:
- edvgDbList.append((database, version, implVersion))
- else:
edvgDbList.append(
- (database, 'Non_EDGV', -1))
+ (database, version, implVersion)
+ )
+ else:
+ edvgDbList.append((database, "Non_EDGV", -1))
elif "42501" in query3.lastError().databaseText():
# user may have some privileges on database,
# but may not be granted on all schemas of a
# database
QgsMessageLog.logMessage(
- self.tr("Unable to load '{0}'. User '{1}'"
- " has insufficient privileges.")\
- .format(database, db.userName()),
+ self.tr(
+ "Unable to load '{0}'. User '{1}'"
+ " has insufficient privileges."
+ ).format(database, db.userName()),
"DSGTools Plugin",
- Qgis.Warning
+ Qgis.Warning,
)
else:
- edvgDbList.append((database,'Non_EDGV', -1))
+ edvgDbList.append((database, "Non_EDGV", -1))
if parentWidget:
progress.step()
else:
for database in dbList:
- if database not in ['postgres', 'dsgtools_admindb', 'template_edgv_213', 'template_edgv_3', 'template_edgv_fter_2a_ed', 'template0', 'template1']:
+ if database not in [
+ "postgres",
+ "dsgtools_admindb",
+ "template_edgv_213",
+ "template_edgv_3",
+ "template_edgv_fter_2a_ed",
+ "template0",
+ "template1",
+ ]:
edvgDbList.append(database)
if parentWidget:
- progress.step()
+ progress.step()
return edvgDbList
-
+
def getDbsFromServer(self):
"""
Gets databases from 'this' server
"""
- #Can only be used in postgres database.
+ # Can only be used in postgres database.
self.checkAndOpenDb()
- query = QSqlQuery(self.gen.getDatabasesFromServer(),self.db)
+ query = QSqlQuery(self.gen.getDatabasesFromServer(), self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting databases: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting databases: ") + query.lastError().text()
+ )
dbList = []
-
+
while query.next():
dbList.append(query.value(0))
return dbList
-
+
def checkSuperUser(self):
"""
Checks if the user used to connect to this database is a super user
@@ -882,10 +1085,12 @@ def checkSuperUser(self):
value = query.value(0)
return value
else:
- raise Exception(self.tr("Problem checking user: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem checking user: ") + query.lastError().text()
+ )
return False
-
- def checkTemplateImplementationVersion(self, edgvVersion = None):
+
+ def checkTemplateImplementationVersion(self, edgvVersion=None):
"""
Returns True if templateSql version is larger than installed template
Works when abstractDb is connected to the template
@@ -899,7 +1104,8 @@ def checkTemplateImplementationVersion(self, edgvVersion = None):
return True
else:
return False
- def dropDatabase(self, candidateName, dropTemplate = False):
+
+ def dropDatabase(self, candidateName, dropTemplate=False):
"""
Drops a database from server
candidataName: database name
@@ -907,16 +1113,24 @@ def dropDatabase(self, candidateName, dropTemplate = False):
self.checkAndOpenDb()
if self.checkSuperUser():
if dropTemplate:
- self.setDbAsTemplate(dbName = candidateName, setTemplate = False)
+ self.setDbAsTemplate(dbName=candidateName, setTemplate=False)
self.dropAllConections(candidateName)
sql = self.gen.dropDatabase(candidateName)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem dropping database: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem dropping database: ") + query.lastError().text()
+ )
else:
- raise Exception(self.tr('Problem dropping database: user must have permission for that.'))
-
- def createResolvedDomainViews(self, createViewClause, fromClause, useTransaction = True):
+ raise Exception(
+ self.tr(
+ "Problem dropping database: user must have permission for that."
+ )
+ )
+
+ def createResolvedDomainViews(
+ self, createViewClause, fromClause, useTransaction=True
+ ):
"""
Creates a view with all domain values resolved
createViewClause: sql query to create the view
@@ -926,23 +1140,28 @@ def createResolvedDomainViews(self, createViewClause, fromClause, useTransaction
if self.checkSuperUser():
filename = self.getSqlViewFile()
if filename != None:
- file = codecs.open(filename, encoding='utf-8', mode="r")
+ file = codecs.open(filename, encoding="utf-8", mode="r")
sql = file.read()
- sql = sql.replace('[VIEW]', createViewClause).replace('[FROM]', fromClause)
+ sql = sql.replace("[VIEW]", createViewClause).replace(
+ "[FROM]", fromClause
+ )
file.close()
- commands = sql.split('#')
- commands = [i for i in sql.split('#') if i != '']
+ commands = sql.split("#")
+ commands = [i for i in sql.split("#") if i != ""]
if useTransaction:
self.db.transaction()
query = QSqlQuery(self.db)
for command in commands:
if not query.exec_(command):
if useTransaction:
- self.db.rollback()
- raise Exception(self.tr('Problem creating views: ') + query.lastError().text())
+ self.db.rollback()
+ raise Exception(
+ self.tr("Problem creating views: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def getSqlViewFile(self):
"""
Gets the sql view file
@@ -951,12 +1170,30 @@ def getSqlViewFile(self):
currentPath = os.path.dirname(__file__)
dbVersion = self.getDatabaseVersion()
file = None
- if dbVersion == '2.1.3':
- file = os.path.join(currentPath,'..','..','DbTools','PostGISTool', 'sqls', '213', 'views_213.sql')
- if dbVersion == 'FTer_2a_Ed':
- file = os.path.join(currentPath,'..','..','DbTools','PostGISTool', 'sqls', 'FTer_2a_Ed', 'views_edgvFter_2a_Ed.sql')
+ if dbVersion == "2.1.3":
+ file = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "DbTools",
+ "PostGISTool",
+ "sqls",
+ "213",
+ "views_213.sql",
+ )
+ if dbVersion == "FTer_2a_Ed":
+ file = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "DbTools",
+ "PostGISTool",
+ "sqls",
+ "FTer_2a_Ed",
+ "views_edgvFter_2a_Ed.sql",
+ )
return file
-
+
def getInvalidGeomRecords(self, cl, geometryColumn, keyColumn):
"""
Gets invalid geometry data from database
@@ -967,15 +1204,18 @@ def getInvalidGeomRecords(self, cl, geometryColumn, keyColumn):
sql = self.gen.getInvalidGeom(tableSchema, tableName, geometryColumn, keyColumn)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting invalid geometries: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting invalid geometries: ")
+ + query.lastError().text()
+ )
while query.next():
featId = query.value(0)
reason = query.value(1)
geom = query.value(2)
- invalidRecordsList.append( (featId, reason, geom) )
+ invalidRecordsList.append((featId, reason, geom))
return invalidRecordsList
-
- def insertFlags(self, flagTupleList, processName, useTransaction = True):
+
+ def insertFlags(self, flagTupleList, processName, useTransaction=True):
"""
Inserts flags into database
flagTupleList: flag tuple list
@@ -988,29 +1228,53 @@ def insertFlags(self, flagTupleList, processName, useTransaction = True):
query = QSqlQuery(self.db)
for record in flagTupleList:
try:
- dimension = self.getDimension(record[3]) # getting geometry dimension
+ dimension = self.getDimension(
+ record[3]
+ ) # getting geometry dimension
except Exception as e:
raise e
# specific EPSG search
- flagSRID = self.findEPSG(parameters={'tableSchema':'validation', 'tableName':'aux_flags_validacao_p', 'geometryColumn':'geom'})
+ flagSRID = self.findEPSG(
+ parameters={
+ "tableSchema": "validation",
+ "tableName": "aux_flags_validacao_p",
+ "geometryColumn": "geom",
+ }
+ )
try:
- tableSchema, tableName = record[0].split('.')
- parameters = {'tableSchema':tableSchema, 'tableName':tableName, 'geometryColumn':record[4]}
+ tableSchema, tableName = record[0].split(".")
+ parameters = {
+ "tableSchema": tableSchema,
+ "tableName": tableName,
+ "geometryColumn": record[4],
+ }
srid = self.findEPSG(parameters=parameters)
except:
srid = flagSRID
- #actual flag insertion
- sql = self.gen.insertFlagIntoDb(record[0], record[1], record[2], record[3], srid, processName, dimension, record[4], flagSRID)
+ # actual flag insertion
+ sql = self.gen.insertFlagIntoDb(
+ record[0],
+ record[1],
+ record[2],
+ record[3],
+ srid,
+ processName,
+ dimension,
+ record[4],
+ flagSRID,
+ )
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem inserting flags: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem inserting flags: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
return len(flagTupleList)
else:
return 0
-
+
def deleteProcessFlags(self, processName=None, className=None, flagId=None):
"""
Deletes flags from database
@@ -1018,17 +1282,21 @@ def deleteProcessFlags(self, processName=None, className=None, flagId=None):
className: class name that will have all flags removed
"""
self.checkAndOpenDb()
- sql = self.gen.deleteFlags(processName = processName, className = className, flagId = flagId)
- sqlList = sql.split('#')
+ sql = self.gen.deleteFlags(
+ processName=processName, className=className, flagId=flagId
+ )
+ sqlList = sql.split("#")
query = QSqlQuery(self.db)
self.db.transaction()
for inner in sqlList:
if not query.exec_(inner):
self.db.rollback()
- raise Exception(self.tr('Problem deleting flags: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem deleting flags: ") + query.lastError().text()
+ )
self.db.commit()
-
- def checkAndCreateValidationStructure(self, useTransaction = True):
+
+ def checkAndCreateValidationStructure(self, useTransaction=True):
"""
Checks if the validation structure is already created, if not it should be created now
"""
@@ -1036,14 +1304,16 @@ def checkAndCreateValidationStructure(self, useTransaction = True):
sql = self.gen.checkValidationStructure()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem creating structure: ')+query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating structure: ") + query.lastError().text()
+ )
created = True
while query.next():
if query.value(0) == 0:
created = False
if not created:
sqltext = self.gen.createValidationStructure(self.findEPSG())
- sqlList = sqltext.split('#')
+ sqlList = sqltext.split("#")
query2 = QSqlQuery(self.db)
if useTransaction:
self.db.transaction()
@@ -1051,10 +1321,13 @@ def checkAndCreateValidationStructure(self, useTransaction = True):
if not query2.exec_(sql2):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating structure: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating structure: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def getValidationStatus(self, processName):
"""
Gets the validation status for a specific process
@@ -1062,9 +1335,11 @@ def getValidationStatus(self, processName):
"""
self.checkAndOpenDb()
sql = self.gen.validationStatus(processName)
- query = QSqlQuery(sql,self.db)
+ query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem acquiring status: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem acquiring status: ") + query.lastError().text()
+ )
ret = None
while query.next():
ret = query.value(0)
@@ -1079,7 +1354,9 @@ def getValidationStatusText(self, processName):
sql = self.gen.validationStatusText(processName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem acquiring status: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem acquiring status: ") + query.lastError().text()
+ )
ret = None
while query.next():
ret = query.value(0)
@@ -1094,8 +1371,10 @@ def setValidationProcessStatus(self, processName, log, status):
sql = self.gen.setValidationStatusQuery(processName, log, status)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem setting status: ') + query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem setting status: ") + query.lastError().text()
+ )
+
def getRunningProc(self):
"""
Gets the active running process into database
@@ -1104,14 +1383,16 @@ def getRunningProc(self):
sql = self.gen.getRunningProc()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting running process: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting running process: ") + query.lastError().text()
+ )
while query.next():
processName = query.value(0)
status = query.value(1)
if status == 3:
return processName
return None
-
+
def isLyrInDb(self, lyr):
"""
Checks if a layer is in the database
@@ -1120,25 +1401,57 @@ def isLyrInDb(self, lyr):
candidateHost = candidateUri.host()
candidatePort = int(candidateUri.port())
candidateDb = candidateUri.database()
- if self.db.hostName() == candidateHost and self.db.port() == candidatePort and self.db.databaseName() == candidateDb:
+ if (
+ self.db.hostName() == candidateHost
+ and self.db.port() == candidatePort
+ and self.db.databaseName() == candidateDb
+ ):
return True
else:
return False
-
- def testSpatialRule(self, class_a, necessity, predicate_function, class_b, min_card, max_card, rule, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn):
+
+ def testSpatialRule(
+ self,
+ class_a,
+ necessity,
+ predicate_function,
+ class_b,
+ min_card,
+ max_card,
+ rule,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ ):
"""
Tests spatial predicates to check whether a rule is broken
"""
self.checkAndOpenDb()
- sql = self.gen.testSpatialRule(class_a, necessity, predicate_function, class_b, min_card, max_card, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn)
+ sql = self.gen.testSpatialRule(
+ class_a,
+ necessity,
+ predicate_function,
+ class_b,
+ min_card,
+ max_card,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem testing spatial rule: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem testing spatial rule: ") + query.lastError().text()
+ )
ret = []
- flagClass = class_a.replace('_temp', '')
+ flagClass = class_a.replace("_temp", "")
while query.next():
feat_id = query.value(0)
- reason = self.tr('Feature id {} from {} violates rule {} {}').format(feat_id, class_a, rule.decode('utf-8'), class_b)
+ reason = self.tr("Feature id {} from {} violates rule {} {}").format(
+ feat_id, class_a, rule.decode("utf-8"), class_b
+ )
geom = query.value(1)
# storing flags for class_a
ret.append((flagClass, feat_id, reason, geom, aGeomColumn))
@@ -1153,27 +1466,31 @@ def getDimension(self, geom):
sql = self.gen.getDimension(geom)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting dimension: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting dimension: ") + query.lastError().text()
+ )
dimension = 0
while query.next():
dimension = query.value(0)
return dimension
-
+
def getExplodeCandidates(self, cl):
"""
Gets multi geometries (i.e number of parts > 1) that will be deaggregated later
"""
self.checkAndOpenDb()
- sql= self.gen.getMulti(cl)
+ sql = self.gen.getMulti(cl)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem exploding candidates: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem exploding candidates: ") + query.lastError().text()
+ )
idList = []
while query.next():
idList.append(query.value(0))
return idList
- def getURI(self, table, useOnly = True, geomColumn = 'geom'):
+ def getURI(self, table, useOnly=True, geomColumn="geom"):
"""
Gets tabel URI
table: table name
@@ -1187,21 +1504,21 @@ def getURI(self, table, useOnly = True, geomColumn = 'geom'):
database = self.db.databaseName()
user = self.db.userName()
password = self.db.password()
-
+
if useOnly:
sql = self.gen.loadLayerFromDatabase(table)
else:
sql = self.gen.loadLayerFromDatabaseUsingInh(table)
-
+
uri = QgsDataSourceUri()
- uri.setConnection(str(host),str(port), str(database), str(user), str(password))
+ uri.setConnection(str(host), str(port), str(database), str(user), str(password))
id = self.getPrimaryKeyColumn(table)
uri.setDataSource(schema, layer_name, geomColumn, sql, id)
uri.disableSelectAtId(True)
-
+
return uri
-
- def getURIV2(self, tableSchema, tableName, geometryColumnm, sql = ''):
+
+ def getURIV2(self, tableSchema, tableName, geometryColumnm, sql=""):
"""
New inplementation giving parameters.
"""
@@ -1212,12 +1529,12 @@ def getURIV2(self, tableSchema, tableName, geometryColumnm, sql = ''):
password = self.db.password()
uri = QgsDataSourceUri()
- uri.setConnection(str(host),str(port), str(database), str(user), str(password))
- id = self.getPrimaryKeyColumn('{0}.{1}'.format(tableSchema, tableName))
+ uri.setConnection(str(host), str(port), str(database), str(user), str(password))
+ id = self.getPrimaryKeyColumn("{0}.{1}".format(tableSchema, tableName))
uri.setDataSource(tableSchema, tableName, geometryColumnm, sql, id)
-
+
return uri
-
+
def getDuplicatedGeomRecords(self, cl, geometryColumn, keyColumn):
"""
Gets duplicated records
@@ -1228,12 +1545,17 @@ def getDuplicatedGeomRecords(self, cl, geometryColumn, keyColumn):
self.checkAndOpenDb()
tupleList = []
tableSchema, tableName = self.getTableSchema(cl)
- sql = self.gen.getDuplicatedGeom(tableSchema, tableName, geometryColumn, keyColumn)
+ sql = self.gen.getDuplicatedGeom(
+ tableSchema, tableName, geometryColumn, keyColumn
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting duplicated geometries: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting duplicated geometries: ")
+ + query.lastError().text()
+ )
while query.next():
- tupleList.append( (query.value(0),query.value(2)) )
+ tupleList.append((query.value(0), query.value(2)))
return tupleList
def getSmallAreasRecords(self, cl, tol, geometryColumn, keyColumn):
@@ -1246,17 +1568,21 @@ def getSmallAreasRecords(self, cl, tol, geometryColumn, keyColumn):
self.checkAndOpenDb()
smallAreasTupleList = []
tableSchema, tableName = self.getTableSchema(cl)
- sql = self.gen.getSmallAreas(tableSchema, tableName, tol, geometryColumn, keyColumn)
+ sql = self.gen.getSmallAreas(
+ tableSchema, tableName, tol, geometryColumn, keyColumn
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting small areas: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting small areas: ") + query.lastError().text()
+ )
while query.next():
- smallAreasTupleList.append( (query.value(0),query.value(1)) )
+ smallAreasTupleList.append((query.value(0), query.value(1)))
return smallAreasTupleList
- def getSmallLinesRecords(self,classesWithGeom, tol, geometryColumn, keyColumn):
+ def getSmallLinesRecords(self, classesWithGeom, tol, geometryColumn, keyColumn):
"""
- Gets small lines records
+ Gets small lines records
tol: tolerance
geometryColumn: geometryColumn
keyColumn: pk column
@@ -1265,15 +1591,30 @@ def getSmallLinesRecords(self,classesWithGeom, tol, geometryColumn, keyColumn):
smallLinesDict = dict()
for cl in classesWithGeom:
tableSchema, tableName = self.getTableSchema(cl)
- sql = self.gen.getSmallLines(tableSchema, tableName, tol, geometryColumn, keyColumn)
+ sql = self.gen.getSmallLines(
+ tableSchema, tableName, tol, geometryColumn, keyColumn
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting small lines: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting small lines: ") + query.lastError().text()
+ )
while query.next():
- smallLinesDict = self.utils.buildNestedDict(smallLinesDict, [cl,query.value(0)], query.value(1))
+ smallLinesDict = self.utils.buildNestedDict(
+ smallLinesDict, [cl, query.value(0)], query.value(1)
+ )
return smallLinesDict
- def getVertexNearEdgesRecords(self, tableSchema, tableName, tol, geometryColumn, keyColumn, geomType, useTransaction = True):
+ def getVertexNearEdgesRecords(
+ self,
+ tableSchema,
+ tableName,
+ tol,
+ geometryColumn,
+ keyColumn,
+ geomType,
+ useTransaction=True,
+ ):
"""
Gets vertexes near edges. These vertexes are problematic and should be treated
tableSchema: table schema
@@ -1284,8 +1625,10 @@ def getVertexNearEdgesRecords(self, tableSchema, tableName, tol, geometryColumn,
"""
self.checkAndOpenDb()
result = []
- sql = self.gen.prepareVertexNearEdgesStruct(tableSchema, tableName, geometryColumn, keyColumn, geomType)
- sqlList = sql.split('#')
+ sql = self.gen.prepareVertexNearEdgesStruct(
+ tableSchema, tableName, geometryColumn, keyColumn, geomType
+ )
+ sqlList = sql.split("#")
if useTransaction:
self.db.transaction()
for sql2 in sqlList:
@@ -1293,25 +1636,35 @@ def getVertexNearEdgesRecords(self, tableSchema, tableName, tol, geometryColumn,
if not query.exec_(sql2):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem preparing auxiliary structure: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem preparing auxiliary structure: ")
+ + query.lastError().text()
+ )
# specific EPSG search
- parameters = {'tableSchema': tableSchema, 'tableName': tableName, 'geometryColumn': geometryColumn}
+ parameters = {
+ "tableSchema": tableSchema,
+ "tableName": tableName,
+ "geometryColumn": geometryColumn,
+ }
epsg = self.findEPSG(parameters=parameters)
sql = self.gen.getVertexNearEdgesStruct(epsg, tol, geometryColumn, keyColumn)
- query = QSqlQuery(sql,self.db)
+ query = QSqlQuery(sql, self.db)
if not query.isActive():
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem getting vertex near edges: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting vertex near edges: ")
+ + query.lastError().text()
+ )
while query.next():
id = query.value(0)
geom = query.value(1)
- result.append((id,geom))
+ result.append((id, geom))
if useTransaction:
self.db.commit()
return result
- def removeFeatures(self, cl, processList, keyColumn, useTransaction = True):
+ def removeFeatures(self, cl, processList, keyColumn, useTransaction=True):
"""
Removes features from class
cl: class name
@@ -1320,7 +1673,7 @@ def removeFeatures(self, cl, processList, keyColumn, useTransaction = True):
"""
self.checkAndOpenDb()
tableSchema, tableName = self.getTableSchema(cl)
- idList = [i['id'] for i in processList]
+ idList = [i["id"] for i in processList]
sql = self.gen.deleteFeatures(tableSchema, tableName, idList, keyColumn)
query = QSqlQuery(self.db)
if useTransaction:
@@ -1328,7 +1681,12 @@ def removeFeatures(self, cl, processList, keyColumn, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem deleting features from ')+cl+': '+ query.lastError().text())
+ raise Exception(
+ self.tr("Problem deleting features from ")
+ + cl
+ + ": "
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
return len(idList)
@@ -1346,12 +1704,17 @@ def getNotSimpleRecords(self, cl, geometryColumn, keyColumn):
sql = self.gen.getNotSimple(tableSchema, tableName, geometryColumn, keyColumn)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting not simple geometries: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting not simple geometries: ")
+ + query.lastError().text()
+ )
while query.next():
- tupleList.append( (query.value(0), query.value(1)) )
+ tupleList.append((query.value(0), query.value(1)))
return tupleList
- def getOutOfBoundsAnglesRecords(self, tableSchema, tableName, tol, geometryColumn, geomType, keyColumn):
+ def getOutOfBoundsAnglesRecords(
+ self, tableSchema, tableName, tol, geometryColumn, geomType, keyColumn
+ ):
"""
Gets records with anchor points (points between segments) that are out of bounds (i.e outside a limit tolerance)
tableSchema: table schema
@@ -1362,10 +1725,15 @@ def getOutOfBoundsAnglesRecords(self, tableSchema, tableName, tol, geometryColum
"""
self.checkAndOpenDb()
result = []
- sql = self.gen.getOutofBoundsAngles(tableSchema, tableName, tol, geometryColumn, geomType, keyColumn)
+ sql = self.gen.getOutofBoundsAngles(
+ tableSchema, tableName, tol, geometryColumn, geomType, keyColumn
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting not out of bounds angles: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting not out of bounds angles: ")
+ + query.lastError().text()
+ )
while query.next():
id = query.value(0)
geom = query.value(1)
@@ -1382,17 +1750,19 @@ def getFlagsDictByProcess(self, processName):
sql = self.gen.getFlagsByProcess(processName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting flags dict: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting flags dict: ") + query.lastError().text()
+ )
while query.next():
cl = query.value(0)
id = query.value(1)
- geometry_column = query.value(2)
+ geometry_column = query.value(2)
if cl not in list(flagsDict.keys()):
flagsDict[cl] = []
- flagsDict[cl].append({'id':str(id), 'geometry_column':geometry_column})
+ flagsDict[cl].append({"id": str(id), "geometry_column": geometry_column})
return flagsDict
-
- def forceValidity(self, cl, processList, keyColumn, useTransaction = True):
+
+ def forceValidity(self, cl, processList, keyColumn, useTransaction=True):
"""
Forces geometry validity (i.e uses ST_MakeValid)
cl: class
@@ -1401,23 +1771,34 @@ def forceValidity(self, cl, processList, keyColumn, useTransaction = True):
"""
self.checkAndOpenDb()
tableSchema, tableName = self.getTableSchema(cl)
- idList = [i['id'] for i in processList]
- geometryColumn = processList[0]['geometry_column']
+ idList = [i["id"] for i in processList]
+ geometryColumn = processList[0]["geometry_column"]
# specific EPSG search
- parameters = {'tableSchema':tableSchema, 'tableName':tableName, 'geometryColumn':geometryColumn}
+ parameters = {
+ "tableSchema": tableSchema,
+ "tableName": tableName,
+ "geometryColumn": geometryColumn,
+ }
srid = self.findEPSG(parameters=parameters)
- sql = self.gen.forceValidity(tableSchema, tableName, idList, srid, keyColumn, geometryColumn)
+ sql = self.gen.forceValidity(
+ tableSchema, tableName, idList, srid, keyColumn, geometryColumn
+ )
query = QSqlQuery(self.db)
if useTransaction:
self.db.transaction()
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem forcing validity of features from ')+cl+': '+ query.lastError().text())
+ raise Exception(
+ self.tr("Problem forcing validity of features from ")
+ + cl
+ + ": "
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
return len(idList)
-
+
def getTableExtent(self, tableSchema, tableName):
"""
Forces geometry validity (i.e uses ST_MakeValid)
@@ -1428,8 +1809,10 @@ def getTableExtent(self, tableSchema, tableName):
sql = self.gen.getTableExtent(tableSchema, tableName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting table extent: ') + query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem getting table extent: ") + query.lastError().text()
+ )
+
extent = None
while query.next():
xmin = query.value(0)
@@ -1439,7 +1822,7 @@ def getTableExtent(self, tableSchema, tableName):
extent = (xmin, xmax, ymin, ymax)
return extent
- def getOrphanGeomTables(self, loading = False):
+ def getOrphanGeomTables(self, loading=False):
"""
Gets parent classes
"""
@@ -1447,13 +1830,15 @@ def getOrphanGeomTables(self, loading = False):
sql = self.gen.getOrphanGeomTablesWithElements(loading)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting orphan tables: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting orphan tables: ") + query.lastError().text()
+ )
result = []
while query.next():
result.append(query.value(0))
return result
- def getOrphanGeomTablesWithElements(self, loading = False):
+ def getOrphanGeomTablesWithElements(self, loading=False):
"""
Gets populated parent classes
"""
@@ -1461,20 +1846,27 @@ def getOrphanGeomTablesWithElements(self, loading = False):
sql = self.gen.getOrphanGeomTablesWithElements(loading)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting orphan tables: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting orphan tables: ") + query.lastError().text()
+ )
result = []
while query.next():
orphanCandidate = query.value(0)
sql2 = self.gen.getOrphanTableElementCount(orphanCandidate)
query2 = QSqlQuery(sql2, self.db)
if not query2.isActive():
- raise Exception(self.tr('Problem counting orphan table: ') + query2.lastError().text())
+ raise Exception(
+ self.tr("Problem counting orphan table: ")
+ + query2.lastError().text()
+ )
while query2.next():
if query2.value(0):
result.append(query.value(0))
return result
-
- def updateGeometries(self, tableSchema, tableName, tuplas, epsg, useTransaction = True):
+
+ def updateGeometries(
+ self, tableSchema, tableName, tuplas, epsg, useTransaction=True
+ ):
"""
Updates geometries on database
tableSchema: table schema
@@ -1491,16 +1883,22 @@ def updateGeometries(self, tableSchema, tableName, tuplas, epsg, useTransaction
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem updating geometries: ') + query.lastError().text())
- sqlDel = self.gen.deleteFeaturesNotIn(tableSchema, tableName, list(tuplas.keys()))
+ raise Exception(
+ self.tr("Problem updating geometries: ") + query.lastError().text()
+ )
+ sqlDel = self.gen.deleteFeaturesNotIn(
+ tableSchema, tableName, list(tuplas.keys())
+ )
query2 = QSqlQuery(self.db)
if not query2.exec_(sqlDel):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem deleting geometries: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem deleting geometries: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def checkCentroidAuxStruct(self):
"""
Checks the centroid structure
@@ -1509,13 +1907,15 @@ def checkCentroidAuxStruct(self):
sql = self.gen.checkCentroidAuxStruct()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem checking structure: ')+query.lastError().text())
+ raise Exception(
+ self.tr("Problem checking structure: ") + query.lastError().text()
+ )
while query.next():
if query.value(0) == None:
return False
return True
-
- def createCentroidAuxStruct(self, earthCoverageClasses, useTransaction = True):
+
+ def createCentroidAuxStruct(self, earthCoverageClasses, useTransaction=True):
"""
Creates the centroid structure
earthCoverageClasses: earth coverage configuration diciotnary
@@ -1525,26 +1925,29 @@ def createCentroidAuxStruct(self, earthCoverageClasses, useTransaction = True):
self.db.transaction()
for cl in earthCoverageClasses:
# getting table schema
- if '.' in cl:
- tableSchema = cl.split('.')[0]
- tableName = cl.split('.')[-1]
+ if "." in cl:
+ tableSchema = cl.split(".")[0]
+ tableName = cl.split(".")[-1]
else:
tableSchema = self.getTableSchemaFromDb(cl)
tableName = cl
# specific EPSG search
- parameters = {'tableSchema':tableSchema, 'tableName':tableName}
+ parameters = {"tableSchema": tableSchema, "tableName": tableName}
srid = self.findEPSG(parameters=parameters)
sqltext = self.gen.createCentroidColumn(tableSchema, tableName, srid)
- sqlList = sqltext.split('#')
+ sqlList = sqltext.split("#")
query = QSqlQuery(self.db)
for sql2 in sqlList:
if not query.exec_(sql2):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating centroid structure: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating centroid structure: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def checkAndCreateCentroidAuxStruct(self, earthCoverageClasses):
"""
Checks the centroid structure. If not already created, it creates the centroid structure
@@ -1552,7 +1955,7 @@ def checkAndCreateCentroidAuxStruct(self, earthCoverageClasses):
"""
if not self.checkCentroidAuxStruct():
self.createCentroidAuxStruct(earthCoverageClasses)
-
+
def getEarthCoverageClasses(self):
"""
Gets the earth coverage classes from earth coverage configuration dictionary.
@@ -1561,7 +1964,10 @@ def getEarthCoverageClasses(self):
sql = self.gen.getEarthCoverageDict()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting earth coverage tables: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting earth coverage tables: ")
+ + query.lastError().text()
+ )
result = []
while query.next():
result.append(query.value(0))
@@ -1575,11 +1981,14 @@ def getEarthCoverageDict(self):
sql = self.gen.getEarthCoverageDict()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting earth coverage structure: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting earth coverage structure: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
- def setEarthCoverageDict(self, textDict, useTransaction = True):
+ def setEarthCoverageDict(self, textDict, useTransaction=True):
"""
Sets the earth coverage configuration dictionary.
textDict: earth coverage configuration dictionary
@@ -1592,11 +2001,14 @@ def setEarthCoverageDict(self, textDict, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem setting earth coverage structure: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem setting earth coverage structure: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
- def updateEarthCoverageDict(self, updateDict, oldDict, useTransaction = True):
+ def updateEarthCoverageDict(self, updateDict, oldDict, useTransaction=True):
"""
Updates earthCoverage, creating new centroids and removing old unused ones.
"""
@@ -1610,11 +2022,10 @@ def updateEarthCoverageDict(self, updateDict, oldDict, useTransaction = True):
for centroid in oldList:
if centroid not in updateList:
removalList.append(centroid)
- self.createCentroidAuxStruct(creationList, useTransaction = useTransaction)
- self.dropCentroids(removalList, useTransaction = useTransaction)
+ self.createCentroidAuxStruct(creationList, useTransaction=useTransaction)
+ self.dropCentroids(removalList, useTransaction=useTransaction)
-
- def dropCentroids(self, classList, useTransaction = True):
+ def dropCentroids(self, classList, useTransaction=True):
"""
Drops the centroid structure
classList: classes to be altered
@@ -1625,9 +2036,9 @@ def dropCentroids(self, classList, useTransaction = True):
query = QSqlQuery(self.db)
for cl in classList:
# getting table schema
- if '.' not in cl:
+ if "." not in cl:
tableSchema = self.getTableSchemaFromDb(cl)
- fullTableName = tableSchema+'.'+cl
+ fullTableName = tableSchema + "." + cl
else:
fullTableName = cl
# making the query using table schema and table name
@@ -1635,7 +2046,9 @@ def dropCentroids(self, classList, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem dropping centroids: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem dropping centroids: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
@@ -1659,11 +2072,14 @@ def getEarthCoverageCentroids(self):
query = QSqlQuery(sql, self.db)
centroidList = []
if not query.isActive():
- raise Exception(self.tr('Problem getting earth coverage structure: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting earth coverage structure: ")
+ + query.lastError().text()
+ )
while query.next():
- table = query.value(0).split('_')
- table[-1] = 'c'
- layerName = '_'.join(table)
+ table = query.value(0).split("_")
+ table[-1] = "c"
+ layerName = "_".join(table)
centroidList.append(layerName)
return centroidList
@@ -1677,20 +2093,24 @@ def getWhoAmI(self, cl, id):
sql = self.gen.getWhoAmI(cl, id)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting class name: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting class name: ") + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def getDbOID(self):
self.checkAndOpenDb()
sql = self.gen.getDbOID(self.db.databaseName())
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem getting db oid: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting db oid: ") + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
- def snapToGrid(self, classList, tol, srid, geometryColumn, useTransaction = True):
+
+ def snapToGrid(self, classList, tol, srid, geometryColumn, useTransaction=True):
"""
Snaps tables to grid (i.e executes ST_SnapToGrid)
classList: classes to be altered
@@ -1706,11 +2126,15 @@ def snapToGrid(self, classList, tol, srid, geometryColumn, useTransaction = True
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem snapping to grid: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem snapping to grid: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def snapLinesToFrame(self, classList, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn):
+
+ def snapLinesToFrame(
+ self, classList, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn
+ ):
"""
Snaps lines to frame. This means the lines are prolonged to the frame according to the specified tolerance
classList: classes to be altered
@@ -1723,14 +2147,27 @@ def snapLinesToFrame(self, classList, frameTable, tol, geometryColumn, keyColumn
self.db.transaction()
query = QSqlQuery(self.db)
for cl in classList:
- sqls = self.gen.snapLinesToFrame(cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn)
- for sql in sqls.split('#'):
+ sqls = self.gen.snapLinesToFrame(
+ cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn
+ )
+ for sql in sqls.split("#"):
if not query.exec_(sql):
self.db.rollback()
- raise Exception(self.tr('Problem snapping to frame: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem snapping to frame: ")
+ + query.lastError().text()
+ )
self.db.commit()
-
- def densifyFrame(self, classList, frameTable, snapTolerance, geometryColumn, frameGeometryColumn, useTransaction = True):
+
+ def densifyFrame(
+ self,
+ classList,
+ frameTable,
+ snapTolerance,
+ geometryColumn,
+ frameGeometryColumn,
+ useTransaction=True,
+ ):
"""
Densifies the frame creating new vertexes where the lines were snapped
classList: classes to be altered
@@ -1740,15 +2177,21 @@ def densifyFrame(self, classList, frameTable, snapTolerance, geometryColumn, fra
self.db.transaction()
query = QSqlQuery(self.db)
for cl in classList:
- sql = self.gen.densifyFrame(cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn)
+ sql = self.gen.densifyFrame(
+ cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn
+ )
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem densifying frame: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem densifying frame: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def recursiveSnap(self, classList, tol, geometryColumn, keyColumn, useTransaction = True):
+
+ def recursiveSnap(
+ self, classList, tol, geometryColumn, keyColumn, useTransaction=True
+ ):
"""
Executes a recursive snap within the class
classList: classes to be snapped
@@ -1762,17 +2205,22 @@ def recursiveSnap(self, classList, tol, geometryColumn, keyColumn, useTransactio
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating recursive snap function: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating recursive snap function: ")
+ + query.lastError().text()
+ )
for cl in classList:
sql = self.gen.executeRecursiveSnap(cl, tol)
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem snapping class: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem snapping class: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def runQuery(self, sql, errorMsg, params, useTransaction = True):
+
+ def runQuery(self, sql, errorMsg, params, useTransaction=True):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
@@ -1782,7 +2230,7 @@ def runQuery(self, sql, errorMsg, params, useTransaction = True):
self.db.rollback()
raise Exception(errorMsg + query.lastError().text())
result = dict()
- key = ','.join(params)
+ key = ",".join(params)
result[key] = []
while query.next():
newElement = []
@@ -1799,21 +2247,31 @@ def createTempTable(self, tableName, geomColumnName, useTransaction=True):
self.db.transaction()
query = QSqlQuery(self.db)
sql = self.gen.createTempTable(tableName)
- sqls = sql.split('#')
+ sqls = sql.split("#")
for s in sqls:
if not query.exec_(s):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating temp table {}: '.format(tableName)) + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating temp table {}: ".format(tableName))
+ + query.lastError().text()
+ )
indexSql = self.gen.createSpatialIndex(tableName, geomColumnName)
if not query.exec_(indexSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating spatial index on temp table {}: '.format(tableName)) + query.lastError().text())
+ raise Exception(
+ self.tr(
+ "Problem creating spatial index on temp table {}: ".format(
+ tableName
+ )
+ )
+ + query.lastError().text()
+ )
if useTransaction:
- self.db.commit()
-
- def dropTempTable(self, tableName, useTransaction = True):
+ self.db.commit()
+
+ def dropTempTable(self, tableName, useTransaction=True):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
@@ -1822,11 +2280,14 @@ def dropTempTable(self, tableName, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem dropping temp table {}: '.format(tableName)) + query.lastError().text())
+ raise Exception(
+ self.tr("Problem dropping temp table {}: ".format(tableName))
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def createStyleTable(self, useTransaction = True):
+
+ def createStyleTable(self, useTransaction=True):
if useTransaction:
self.db.transaction()
createSql = self.gen.createStyleTable()
@@ -1834,16 +2295,20 @@ def createStyleTable(self, useTransaction = True):
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating style table: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating style table: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
- def checkAndCreateStyleTable(self, useTransaction = True):
+ def checkAndCreateStyleTable(self, useTransaction=True):
self.checkAndOpenDb()
sql = self.gen.checkStyleTable()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting style table: ") + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting style table: ") + query.lastError().text()
+ )
query.next()
created = query.value(0)
if not created:
@@ -1854,61 +2319,76 @@ def checkAndCreateStyleTable(self, useTransaction = True):
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating style table: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating style table: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
return created
-
- def getStylesFromDb(self,dbVersion):
+
+ def getStylesFromDb(self, dbVersion):
self.checkAndOpenDb()
sql = self.gen.getStylesFromDb(dbVersion)
if not sql:
return []
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting styles from db: ") + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting styles from db: ") + query.lastError().text()
+ )
styleList = []
while query.next():
styleList.append(query.value(0))
return styleList
-
- def getStyle(self, styleName, table_name, parsing = True):
+
+ def getStyle(self, styleName, table_name, parsing=True):
self.checkAndOpenDb()
sql = self.gen.getStyle(styleName, table_name)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting styles from db: ") + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting styles from db: ") + query.lastError().text()
+ )
styleList = []
query.next()
qml = query.value(0)
- #TODO: post parse qml to remove possible attribute value type
+ # TODO: post parse qml to remove possible attribute value type
if parsing:
if qml:
qml = self.utils.parseStyle(qml)
tempPath = None
if qml:
- tempPath = os.path.join(os.path.dirname(__file__), 'temp.qml')
- with open(tempPath, 'w') as f:
+ tempPath = os.path.join(os.path.dirname(__file__), "temp.qml")
+ with open(tempPath, "w") as f:
f.writelines(qml)
f.close()
return tempPath
-
- def importStyle(self, styleName, table_name, qml, tableSchema, useTransaction = True):
+
+ def importStyle(self, styleName, table_name, qml, tableSchema, useTransaction=True):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
query = QSqlQuery(self.db)
parsedQml = self.utils.parseStyle(qml)
dbName = self.db.databaseName()
- sql = self.gen.importStyle(styleName, table_name, parsedQml, tableSchema,dbName)
+ sql = self.gen.importStyle(
+ styleName, table_name, parsedQml, tableSchema, dbName
+ )
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem importing style')+ styleName+'/'+ table_name +':' + query.lastError().text())
+ raise Exception(
+ self.tr("Problem importing style")
+ + styleName
+ + "/"
+ + table_name
+ + ":"
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def updateStyle(self, styleName, table_name, qml, tableSchema, useTransaction = True):
+
+ def updateStyle(self, styleName, table_name, qml, tableSchema, useTransaction=True):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
@@ -1918,11 +2398,18 @@ def updateStyle(self, styleName, table_name, qml, tableSchema, useTransaction =
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem importing style')+ styleName+'/'+ table_name +':' + query.lastError().text())
+ raise Exception(
+ self.tr("Problem importing style")
+ + styleName
+ + "/"
+ + table_name
+ + ":"
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def deleteStyle(self, styleName, useTransaction = True):
+
+ def deleteStyle(self, styleName, useTransaction=True):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
@@ -1931,76 +2418,112 @@ def deleteStyle(self, styleName, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem importing style')+ styleName+':' + query.lastError().text())
+ raise Exception(
+ self.tr("Problem importing style")
+ + styleName
+ + ":"
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def importStylesIntoDb(self, styleFolder, useTransaction = True):
+
+ def importStylesIntoDb(self, styleFolder, useTransaction=True):
"""
path: path to folder
styleFolder: folder with version. Example: edgv_213/example
"""
if self.versionFolderDict[self.getDatabaseVersion()] not in styleFolder:
- raise Exception(self.tr('Style ')+styleFolder+self.tr(' does not match the version of database ') + self.db.databaseName())
- path = os.path.join(os.path.dirname(__file__),'..', '..','Styles')
- stylePath = os.path.join(path,styleFolder)
+ raise Exception(
+ self.tr("Style ")
+ + styleFolder
+ + self.tr(" does not match the version of database ")
+ + self.db.databaseName()
+ )
+ path = os.path.join(os.path.dirname(__file__), "..", "..", "Styles")
+ stylePath = os.path.join(path, styleFolder)
availableStyles = next(os.walk(stylePath))[2]
- created = self.checkAndCreateStyleTable(useTransaction = useTransaction)
+ created = self.checkAndCreateStyleTable(useTransaction=useTransaction)
for style in availableStyles:
- #filtering and checking file names for special characters
- if style[0] == '.':
+ # filtering and checking file names for special characters
+ if style[0] == ".":
continue
if not re.match("^[a-zA-Z0-9_.]*$", style):
- raise Exception(self.tr('Problem importing style ')+style)
+ raise Exception(self.tr("Problem importing style ") + style)
- tableName = style.split('.')[0]
- localStyle = os.path.join(stylePath,style)
+ tableName = style.split(".")[0]
+ localStyle = os.path.join(stylePath, style)
tableSchema = self.getTableSchemaFromDb(tableName)
- #check if style already exists. If it does, update it.
- #if style does not exist, create one.
- if self.getStyle(styleFolder, tableName, parsing = False):
- self.updateStyle(styleFolder, tableName, localStyle, tableSchema, useTransaction = useTransaction)
+ # check if style already exists. If it does, update it.
+ # if style does not exist, create one.
+ if self.getStyle(styleFolder, tableName, parsing=False):
+ self.updateStyle(
+ styleFolder,
+ tableName,
+ localStyle,
+ tableSchema,
+ useTransaction=useTransaction,
+ )
else:
try:
- self.importStyle(styleFolder, tableName, localStyle, tableSchema, useTransaction = useTransaction)
+ self.importStyle(
+ styleFolder,
+ tableName,
+ localStyle,
+ tableSchema,
+ useTransaction=useTransaction,
+ )
except Exception as e:
- raise Exception(self.tr('Problem importing style ')+style+':'+':'.join(e.args))
+ raise Exception(
+ self.tr("Problem importing style ")
+ + style
+ + ":"
+ + ":".join(e.args)
+ )
- def getTableSchemaFromDb(self,table):
+ def getTableSchemaFromDb(self, table):
self.checkAndOpenDb()
sql = self.gen.getTableSchemaFromDb(table)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting table schema from db: ") + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting table schema from db: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
- def getAllStylesDict(self, perspective = 'style'):
+
+ def getAllStylesDict(self, perspective="style"):
"""
Returns a dict of styles in a form acording to perspective:
if perspective = 'style' : [styleName][dbName][tableName] = timestamp
- if perspective = 'database' : [dbName][styleName][tableName] = timestamp
+ if perspective = 'database' : [dbName][styleName][tableName] = timestamp
"""
self.checkAndOpenDb()
sql = self.gen.getAllStylesFromDb()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting styles from db: ") + query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting styles from db: ") + query.lastError().text()
+ )
styleDict = dict()
while query.next():
dbName = query.value(0)
styleName = query.value(1)
tableName = query.value(2)
timestamp = query.value(3)
- if perspective == 'style':
- styleDict = self.utils.buildNestedDict(styleDict, [styleName, dbName, tableName], timestamp)
- elif perspective == 'database':
- styleDict = self.utils.buildNestedDict(styleDict, [dbName, styleName, tableName], timestamp)
+ if perspective == "style":
+ styleDict = self.utils.buildNestedDict(
+ styleDict, [styleName, dbName, tableName], timestamp
+ )
+ elif perspective == "database":
+ styleDict = self.utils.buildNestedDict(
+ styleDict, [dbName, styleName, tableName], timestamp
+ )
return styleDict
-
- def runSqlFromFile(self, sqlFilePath, useTransaction = True, encoding = 'utf-8'):
+
+ def runSqlFromFile(self, sqlFilePath, useTransaction=True, encoding="utf-8"):
self.checkAndOpenDb()
- file = codecs.open(sqlFilePath, encoding=encoding, mode='r')
+ file = codecs.open(sqlFilePath, encoding=encoding, mode="r")
sql = file.read()
query = QSqlQuery(self.db)
if useTransaction:
@@ -2008,28 +2531,39 @@ def runSqlFromFile(self, sqlFilePath, useTransaction = True, encoding = 'utf-8')
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem running sql ')+ sqlFilePath +':' + query.lastError().text())
+ raise Exception(
+ self.tr("Problem running sql ")
+ + sqlFilePath
+ + ":"
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def getStructureDict2(self):
"""
Don't know the purpose of this method
"""
self.checkAndOpenDb()
-
- if self.getDatabaseVersion() == '2.1.3':
- schemaList = ['cb', 'complexos', 'dominios']
- elif self.getDatabaseVersion() == 'FTer_2a_Ed':
- schemaList = ['pe','ge', 'complexos']
+
+ if self.getDatabaseVersion() == "2.1.3":
+ schemaList = ["cb", "complexos", "dominios"]
+ elif self.getDatabaseVersion() == "FTer_2a_Ed":
+ schemaList = ["pe", "ge", "complexos"]
else:
- QgsMessageLog.logMessage(self.tr('Operation not defined for this database version!'), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.tr("Operation not defined for this database version!"),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
return
-
+
sql = self.gen.validateWithDomain(schemaList)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem executing query: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ") + query.lastError().text()
+ )
classDict = dict()
domainDict = dict()
@@ -2040,27 +2574,32 @@ def getStructureDict2(self):
domainName = str(query.value(3))
domainTable = str(query.value(4))
domainQuery = str(query.value(5))
- cl = schemaName+'.'+className
- query2 = QSqlQuery(domainQuery,self.db)
+ cl = schemaName + "." + className
+ query2 = QSqlQuery(domainQuery, self.db)
while query2.next():
value = int(query2.value(0))
code_name = query2.value(1)
- classDict = self.utils.buildNestedDict(classDict,[str(cl),str(attName)],[(value,code_name)])
- #TODO: get constraints
+ classDict = self.utils.buildNestedDict(
+ classDict, [str(cl), str(attName)], [(value, code_name)]
+ )
+ # TODO: get constraints
return classDict
-
+
def getGeomSchemaList(self):
self.checkAndOpenDb()
sql = self.gen.getGeometricSchemas()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
schemaList = []
while query.next():
schemaList.append(query.value(0))
return schemaList
-
- def getGeomDict(self, geomTypeDict, insertCategory = False):
+
+ def getGeomDict(self, geomTypeDict, insertCategory=False):
"""
returns a dict like this:
{'tablePerspective' : {
@@ -2071,10 +2610,13 @@ def getGeomDict(self, geomTypeDict, insertCategory = False):
sql = self.gen.getGeomTablesFromGeometryColumns()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tables from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tables from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
- geomDict['primitivePerspective'] = geomTypeDict
- geomDict['tablePerspective'] = dict()
+ geomDict["primitivePerspective"] = geomTypeDict
+ geomDict["tablePerspective"] = dict()
while query.next():
isCentroid = False
srid = query.value(0)
@@ -2083,25 +2625,29 @@ def getGeomDict(self, geomTypeDict, insertCategory = False):
tableName = query.value(4)
geometryColumn = query.value(1)
layerName = tableName
- if geometryColumn == 'centroid':
- table = layerName.split('_')
- table[-1] = 'c'
- layerName = '_'.join(table)
- if layerName not in list(geomDict['tablePerspective'].keys()):
- geomDict['tablePerspective'][layerName] = dict()
- geomDict['tablePerspective'][layerName]['schema'] = tableSchema
- geomDict['tablePerspective'][layerName]['srid'] = str(srid)
- geomDict['tablePerspective'][layerName]['geometryColumn'] = geometryColumn
- geomDict['tablePerspective'][layerName]['geometryType'] = geometryType
- geomDict['tablePerspective'][layerName]['tableName'] = tableName
+ if geometryColumn == "centroid":
+ table = layerName.split("_")
+ table[-1] = "c"
+ layerName = "_".join(table)
+ if layerName not in list(geomDict["tablePerspective"].keys()):
+ geomDict["tablePerspective"][layerName] = dict()
+ geomDict["tablePerspective"][layerName]["schema"] = tableSchema
+ geomDict["tablePerspective"][layerName]["srid"] = str(srid)
+ geomDict["tablePerspective"][layerName][
+ "geometryColumn"
+ ] = geometryColumn
+ geomDict["tablePerspective"][layerName]["geometryType"] = geometryType
+ geomDict["tablePerspective"][layerName]["tableName"] = tableName
if insertCategory:
- if edgvVersion == 'Non_EDGV':
- geomDict['tablePerspective'][layerName]['category'] = ''
+ if edgvVersion == "Non_EDGV":
+ geomDict["tablePerspective"][layerName]["category"] = ""
else:
- geomDict['tablePerspective'][layerName]['category'] = layerName.split('_')[0]
+ geomDict["tablePerspective"][layerName][
+ "category"
+ ] = layerName.split("_")[0]
return geomDict
-
- def getDbDomainDict(self, auxGeomDict, buildOtherInfo = False):
+
+ def getDbDomainDict(self, auxGeomDict, buildOtherInfo=False):
"""
returns a dict like this:
{'adm_posto_fiscal_a': {
@@ -2117,66 +2663,92 @@ def getDbDomainDict(self, auxGeomDict, buildOtherInfo = False):
}
"""
self.checkAndOpenDb()
- #gets only schemas of classes with geom, to speed up the process.
+ # gets only schemas of classes with geom, to speed up the process.
checkConstraintDict = self.getCheckConstraintDict()
notNullDict = self.getNotNullDictV2()
multiDict = self.getMultiColumnsDict()
sql = self.gen.getGeomTablesDomains()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
while query.next():
- #parse done in parseFkQuery to make code cleaner.
- tableName, fkAttribute, domainTable, domainReferencedAttribute = self.parseFkQuery(query.value(0),query.value(1))
+ # parse done in parseFkQuery to make code cleaner.
+ (
+ tableName,
+ fkAttribute,
+ domainTable,
+ domainReferencedAttribute,
+ ) = self.parseFkQuery(query.value(0), query.value(1))
if tableName not in list(geomDict.keys()):
geomDict[tableName] = dict()
- if 'columns' not in list(geomDict[tableName].keys()):
- geomDict[tableName]['columns'] = dict()
- if fkAttribute not in list(geomDict[tableName]['columns'].keys()):
- geomDict[tableName]['columns'][fkAttribute] = dict()
- geomDict[tableName]['columns'][fkAttribute]['references'] = domainTable
- geomDict[tableName]['columns'][fkAttribute]['refPk'] = domainReferencedAttribute
- values, otherKey = self.getLayerColumnDict(domainReferencedAttribute, domainTable)
- geomDict[tableName]['columns'][fkAttribute]['values'] = values
- geomDict[tableName]['columns'][fkAttribute]['otherKey'] = otherKey
- geomDict[tableName]['columns'][fkAttribute]['constraintList'] = []
- geomDict[tableName]['columns'][fkAttribute]['isMulti'] = False
+ if "columns" not in list(geomDict[tableName].keys()):
+ geomDict[tableName]["columns"] = dict()
+ if fkAttribute not in list(geomDict[tableName]["columns"].keys()):
+ geomDict[tableName]["columns"][fkAttribute] = dict()
+ geomDict[tableName]["columns"][fkAttribute]["references"] = domainTable
+ geomDict[tableName]["columns"][fkAttribute][
+ "refPk"
+ ] = domainReferencedAttribute
+ values, otherKey = self.getLayerColumnDict(
+ domainReferencedAttribute, domainTable
+ )
+ geomDict[tableName]["columns"][fkAttribute]["values"] = values
+ geomDict[tableName]["columns"][fkAttribute]["otherKey"] = otherKey
+ geomDict[tableName]["columns"][fkAttribute]["constraintList"] = []
+ geomDict[tableName]["columns"][fkAttribute]["isMulti"] = False
if tableName in list(checkConstraintDict.keys()):
if fkAttribute in list(checkConstraintDict[tableName].keys()):
- geomDict[tableName]['columns'][fkAttribute]['constraintList'] = checkConstraintDict[tableName][fkAttribute]
- geomDict[tableName]['columns'][fkAttribute]['nullable'] = True
+ geomDict[tableName]["columns"][fkAttribute][
+ "constraintList"
+ ] = checkConstraintDict[tableName][fkAttribute]
+ geomDict[tableName]["columns"][fkAttribute]["nullable"] = True
if tableName in list(notNullDict.keys()):
- if fkAttribute in notNullDict[tableName]['attributes']:
- geomDict[tableName]['columns'][fkAttribute]['nullable'] = False
+ if fkAttribute in notNullDict[tableName]["attributes"]:
+ geomDict[tableName]["columns"][fkAttribute]["nullable"] = False
if tableName in list(multiDict.keys()):
if fkAttribute in multiDict[tableName]:
- geomDict[tableName]['columns'][fkAttribute]['isMulti'] = True
+ geomDict[tableName]["columns"][fkAttribute]["isMulti"] = True
for tableName in list(multiDict.keys()):
- if tableName in list(auxGeomDict['tablePerspective'].keys()):
+ if tableName in list(auxGeomDict["tablePerspective"].keys()):
for fkAttribute in multiDict[tableName]:
if tableName not in list(geomDict.keys()):
geomDict[tableName] = dict()
- if 'columns' not in list(geomDict[tableName].keys()):
- geomDict[tableName]['columns'] = dict()
- if fkAttribute not in list(geomDict[tableName]['columns'].keys()):
- geomDict[tableName]['columns'][fkAttribute] = dict()
- geomDict[tableName]['columns'][fkAttribute]['references'] = None
+ if "columns" not in list(geomDict[tableName].keys()):
+ geomDict[tableName]["columns"] = dict()
+ if fkAttribute not in list(geomDict[tableName]["columns"].keys()):
+ geomDict[tableName]["columns"][fkAttribute] = dict()
+ geomDict[tableName]["columns"][fkAttribute]["references"] = None
if fkAttribute in list(checkConstraintDict[tableName].keys()):
- geomDict[tableName]['columns'][fkAttribute]['constraintList'] = checkConstraintDict[tableName][fkAttribute]
- geomDict[tableName]['columns'][fkAttribute]['nullable'] = True
+ geomDict[tableName]["columns"][fkAttribute][
+ "constraintList"
+ ] = checkConstraintDict[tableName][fkAttribute]
+ geomDict[tableName]["columns"][fkAttribute]["nullable"] = True
if tableName in list(notNullDict.keys()):
- if fkAttribute in notNullDict[tableName]['attributes']:
- geomDict[tableName]['columns'][fkAttribute]['nullable'] = False
+ if fkAttribute in notNullDict[tableName]["attributes"]:
+ geomDict[tableName]["columns"][fkAttribute][
+ "nullable"
+ ] = False
if tableName in list(multiDict.keys()):
if fkAttribute in multiDict[tableName]:
- geomDict[tableName]['columns'][fkAttribute]['isMulti'] = True
- geomDict[tableName]['columns'][fkAttribute]['refPk'] = 'code'
- geomDict[tableName]['columns'][fkAttribute]['otherKey'] = 'code_name'
- geomDict[tableName]['columns'][fkAttribute]['values'] = dict()
-
+ geomDict[tableName]["columns"][fkAttribute][
+ "isMulti"
+ ] = True
+ geomDict[tableName]["columns"][fkAttribute][
+ "refPk"
+ ] = "code"
+ geomDict[tableName]["columns"][fkAttribute][
+ "otherKey"
+ ] = "code_name"
+ geomDict[tableName]["columns"][fkAttribute][
+ "values"
+ ] = dict()
+
return geomDict
-
+
def getCheckConstraintDict(self, layerFilter=None):
"""
returns a dict like this:
@@ -2188,127 +2760,168 @@ def getCheckConstraintDict(self, layerFilter=None):
}
"""
self.checkAndOpenDb()
- #gets only schemas of classes with geom, to speed up the process.
+ # gets only schemas of classes with geom, to speed up the process.
sql = self.gen.getGeomTableConstraints(layerFilter=layerFilter)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
while query.next():
- #parse done in parseCheckConstraintQuery to make code cleaner.
- tableName, attribute, checkList = self.parseCheckConstraintQuery(query.value(0),query.value(1))
+ # parse done in parseCheckConstraintQuery to make code cleaner.
+ tableName, attribute, checkList = self.parseCheckConstraintQuery(
+ query.value(0), query.value(1)
+ )
if tableName not in list(geomDict.keys()):
geomDict[tableName] = dict()
geomDict[tableName][attribute] = checkList
return geomDict
-
+
def parseFkQuery(self, queryValue0, queryValue1):
- if '.' in queryValue0:
- splitList = queryValue0.split('.')
+ if "." in queryValue0:
+ splitList = queryValue0.split(".")
tableName = splitList[1]
else:
tableName = queryValue0
fkText = queryValue1
- fkAttribute = fkText.split(')')[0].replace('FOREIGN KEY (','')
- subtextList = fkText.split(' REFERENCES ')[-1].replace(' MATCH FULL','').split('(')
+ fkAttribute = fkText.split(")")[0].replace("FOREIGN KEY (", "")
+ subtextList = (
+ fkText.split(" REFERENCES ")[-1].replace(" MATCH FULL", "").split("(")
+ )
domainTable = subtextList[0]
- if '.' not in domainTable:
- auxDomain = domainTable.replace('"','')
- domainTable = '''"{0}"."{1}"'''.format(self.getTableSchemaFromDb(auxDomain), auxDomain)
- domainReferencedAttribute = subtextList[1].replace(')','')
- return tableName.replace('"',''), fkAttribute.replace('"',''), domainTable, domainReferencedAttribute
+ if "." not in domainTable:
+ auxDomain = domainTable.replace('"', "")
+ domainTable = '''"{0}"."{1}"'''.format(
+ self.getTableSchemaFromDb(auxDomain), auxDomain
+ )
+ domainReferencedAttribute = subtextList[1].replace(")", "")
+ return (
+ tableName.replace('"', ""),
+ fkAttribute.replace('"', ""),
+ domainTable,
+ domainReferencedAttribute,
+ )
def parseCheckConstraintQuery(self, queryValue0, queryValue1):
try:
- if 'ANY' in queryValue1 or '@' in queryValue1:
+ if "ANY" in queryValue1 or "@" in queryValue1:
return self.parseCheckConstraintWithAny(queryValue0, queryValue1)
else:
return self.parseCheckConstraintWithOr(queryValue0, queryValue1)
except Exception as e:
- raise Exception(self.tr("Error parsing check constraint!\n"+':'.join(e.args)))
-
+ raise Exception(
+ self.tr("Error parsing check constraint!\n" + ":".join(e.args))
+ )
+
def parseCheckConstraintWithOr(self, queryValue0, queryValue1):
- if '.' in queryValue0:
- query0Split = queryValue0.split('.')
+ if "." in queryValue0:
+ query0Split = queryValue0.split(".")
tableSchema = query0Split[0]
tableName = query0Split[1]
else:
tableName = queryValue0
- query1Split = queryValue1.replace('CHECK ','').replace('(','').replace(')','').replace(' ','').replace('"','').split('OR')
+ query1Split = (
+ queryValue1.replace("CHECK ", "")
+ .replace("(", "")
+ .replace(")", "")
+ .replace(" ", "")
+ .replace('"', "")
+ .split("OR")
+ )
checkList = []
for i in query1Split:
- attrSplit = i.split('=')
+ attrSplit = i.split("=")
attribute = attrSplit[0]
try:
checkList.append(int(attrSplit[1]))
except:
- pass #ignore checks that are not from dsgtools
+ pass # ignore checks that are not from dsgtools
return tableName, attribute, checkList
-
+
def parseCheckConstraintWithAny(self, queryValue0, queryValue1):
- if '.' in queryValue0:
- query0Split = queryValue0.split('.')
+ if "." in queryValue0:
+ query0Split = queryValue0.split(".")
tableSchema = query0Split[0]
tableName = query0Split[1]
else:
tableName = queryValue0
- query1Split = queryValue1.replace('"','').replace('ANY','').replace('ARRAY','').replace('::smallint','').replace('(','').replace(')','').replace('CHECK','').replace('[','').replace(']','').replace(' ','')
+ query1Split = (
+ queryValue1.replace('"', "")
+ .replace("ANY", "")
+ .replace("ARRAY", "")
+ .replace("::smallint", "")
+ .replace("(", "")
+ .replace(")", "")
+ .replace("CHECK", "")
+ .replace("[", "")
+ .replace("]", "")
+ .replace(" ", "")
+ )
checkList = []
- splitToken = ''
- if '=' in query1Split:
- splitToken = '='
- elif '<@' in query1Split:
- splitToken = '<@'
+ splitToken = ""
+ if "=" in query1Split:
+ splitToken = "="
+ elif "<@" in query1Split:
+ splitToken = "<@"
equalSplit = query1Split.split(splitToken)
attribute = equalSplit[0]
- checkList = list(map(int,equalSplit[1].split(',')))
+ checkList = list(map(int, equalSplit[1].split(",")))
return tableName, attribute, checkList
-
+
def getMultiColumnsDict(self, layerFilter=None):
"""
- { 'table_name':[-list of columns-] }
+ { 'table_name':[-list of columns-] }
"""
self.checkAndOpenDb()
- #gets only schemas of classes with geom, to speed up the process.
+ # gets only schemas of classes with geom, to speed up the process.
if layerFilter:
sql = self.gen.getMultiColumnsFromTableList(layerFilter)
else:
- sql = self.gen.getMultiColumns(
- schemaList=self.getGeomSchemaList()
- )
+ sql = self.gen.getMultiColumns(schemaList=self.getGeomSchemaList())
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
while query.next():
- #TODO: check if 2.1.3 raises problem, because of empty query
+ # TODO: check if 2.1.3 raises problem, because of empty query
aux = json.loads(query.value(0))
- geomDict[aux['table_name']]=aux['attributes']
+ geomDict[aux["table_name"]] = aux["attributes"]
return geomDict
-
+
def getTablesJsonList(self):
self.checkAndOpenDb()
sql = self.gen.getTablesJsonList()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting tables dict from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting tables dict from db: ")
+ + query.lastError().text()
+ )
geomList = []
while query.next():
geomList.append(json.loads(query.value(0)))
- return geomList
-
+ return geomList
+
def getGeomTypeDict(self, loadCentroids=False):
self.checkAndOpenDb()
sql = self.gen.getGeomByPrimitive()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom types from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom types from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
while query.next():
aux = json.loads(query.value(0))
- geomDict[aux['geomtype']] = aux['classlist']
+ geomDict[aux["geomtype"]] = aux["classlist"]
return geomDict
-
+
def getGeomColumnDict(self):
"""
Dict in the form 'geomName':[-list of table names-]
@@ -2317,16 +2930,25 @@ def getGeomColumnDict(self):
sql = self.gen.getGeomColumnDict()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom column dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom column dict: ") + query.lastError().text()
+ )
geomDict = dict()
while query.next():
aux = json.loads(query.value(0))
- if aux['f2'] not in list(geomDict.keys()):
- geomDict[aux['f2']] = []
- geomDict[aux['f2']].append(aux['f1'])
+ if aux["f2"] not in list(geomDict.keys()):
+ geomDict[aux["f2"]] = []
+ geomDict[aux["f2"]].append(aux["f1"])
return geomDict
-
- def getGeomColumnTupleList(self, showViews = False, hideCentroids = True, primitiveFilter = None, withElements = False, layerFilter = None):
+
+ def getGeomColumnTupleList(
+ self,
+ showViews=False,
+ hideCentroids=True,
+ primitiveFilter=None,
+ withElements=False,
+ layerFilter=None,
+ ):
"""
list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)]
centroids are hidden by default
@@ -2338,120 +2960,160 @@ def getGeomColumnTupleList(self, showViews = False, hideCentroids = True, primit
try:
edgvVersion = self.getDatabaseVersion()
if hideCentroids:
- if self.checkIfExistsConfigTable('EarthCoverage'):
- propertyDict = self.getAllSettingsFromAdminDb('EarthCoverage')
+ if self.checkIfExistsConfigTable("EarthCoverage"):
+ propertyDict = self.getAllSettingsFromAdminDb("EarthCoverage")
propertyName = propertyDict[edgvVersion][0]
dbName = self.db.databaseName()
- settingDict = json.loads(self.getSettingFromAdminDb('EarthCoverage', propertyName, edgvVersion))
- earthCoverageDict = settingDict['earthCoverageDict']
- centroidTableList = [i.split('.')[-1] for i in list(earthCoverageDict.keys())]
+ settingDict = json.loads(
+ self.getSettingFromAdminDb(
+ "EarthCoverage", propertyName, edgvVersion
+ )
+ )
+ earthCoverageDict = settingDict["earthCoverageDict"]
+ centroidTableList = [
+ i.split(".")[-1] for i in list(earthCoverageDict.keys())
+ ]
except:
pass
-
- sql = self.gen.getGeomColumnTupleList(showViews = showViews)
+
+ sql = self.gen.getGeomColumnTupleList(showViews=showViews)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tuple list: ") + query.lastError().text()
+ )
localList = []
while query.next():
- if query.value(2) == 'centroid' and query.value(3) == 'POINT' and query.value(1) in centroidTableList:
+ if (
+ query.value(2) == "centroid"
+ and query.value(3) == "POINT"
+ and query.value(1) in centroidTableList
+ ):
continue
else:
- localList.append((query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)))
+ localList.append(
+ (
+ query.value(0),
+ query.value(1),
+ query.value(2),
+ query.value(3),
+ query.value(4),
+ )
+ )
if not withElements and primitiveFilter == []:
return localList
if withElements:
- listWithElements = self.getLayersWithElementsV2([{'tableSchema':i[0],'tableName':i[1]} for i in localList])
+ listWithElements = self.getLayersWithElementsV2(
+ [{"tableSchema": i[0], "tableName": i[1]} for i in localList]
+ )
geomList = [i for i in localList if i[1] in listWithElements]
else:
geomList = localList
if primitiveFilter != []:
geomTypeFilter = []
- if 'p' in primitiveFilter:
- geomTypeFilter.append('POINT')
- geomTypeFilter.append('MULTIPOINT')
- if 'l' in primitiveFilter:
- geomTypeFilter.append('LINESTRING')
- geomTypeFilter.append('MULTILINESTRING')
- if 'a' in primitiveFilter:
- geomTypeFilter.append('POLYGON')
- geomTypeFilter.append('MULTIPOLYGON')
+ if "p" in primitiveFilter:
+ geomTypeFilter.append("POINT")
+ geomTypeFilter.append("MULTIPOINT")
+ if "l" in primitiveFilter:
+ geomTypeFilter.append("LINESTRING")
+ geomTypeFilter.append("MULTILINESTRING")
+ if "a" in primitiveFilter:
+ geomTypeFilter.append("POLYGON")
+ geomTypeFilter.append("MULTIPOLYGON")
geomList = [i for i in geomList if i[3] in geomTypeFilter]
return geomList
-
- def getGeomColumnDictV2(self, showViews = False, hideCentroids = True, primitiveFilter = [], withElements = False, excludeValidation = False):
- geomList = self.getGeomColumnTupleList(showViews = showViews, hideCentroids = hideCentroids, primitiveFilter = primitiveFilter, withElements = withElements)
+
+ def getGeomColumnDictV2(
+ self,
+ showViews=False,
+ hideCentroids=True,
+ primitiveFilter=[],
+ withElements=False,
+ excludeValidation=False,
+ ):
+ geomList = self.getGeomColumnTupleList(
+ showViews=showViews,
+ hideCentroids=hideCentroids,
+ primitiveFilter=primitiveFilter,
+ withElements=withElements,
+ )
edgvVersion = self.getDatabaseVersion()
lyrDict = dict()
for tableSchema, tableName, geom, geomType, tableType in geomList:
if excludeValidation:
- if tableSchema == 'validation':
+ if tableSchema == "validation":
continue
- if edgvVersion == 'Non_EDGV':
+ if edgvVersion == "Non_EDGV":
lyrName = tableName
cat = tableSchema
else:
- lyrName = '_'.join(tableName.split('_')[1::])
- cat = tableName.split('_')[0]
- key = ','.join([cat, lyrName, geom, geomType, tableType])
- lyrDict[key] = {'tableSchema':tableSchema, 'tableName':tableName, 'geom':geom, 'geomType':geomType, 'tableType':tableType, 'lyrName':lyrName, 'cat':cat}
+ lyrName = "_".join(tableName.split("_")[1::])
+ cat = tableName.split("_")[0]
+ key = ",".join([cat, lyrName, geom, geomType, tableType])
+ lyrDict[key] = {
+ "tableSchema": tableSchema,
+ "tableName": tableName,
+ "geom": geom,
+ "geomType": geomType,
+ "tableType": tableType,
+ "lyrName": lyrName,
+ "cat": cat,
+ }
return lyrDict
-
- def getAuxInfoDict(self, layerFilter = None):
+
+ def getAuxInfoDict(self, layerFilter=None):
"""
- Dict with values of check constraint, null values and multi attributes
+ Dict with values of check constraint, null values and multi attributes
"""
return {
- 'attributeDomainDict' : self.getAttributeDomainDict(
- layerFilter = layerFilter
- ),
- 'checkConstraintDict' : self.getCheckConstraintDict(
- layerFilter = layerFilter
- )
+ "attributeDomainDict": self.getAttributeDomainDict(layerFilter=layerFilter),
+ "checkConstraintDict": self.getCheckConstraintDict(layerFilter=layerFilter),
}
-
- def getAttributeDomainDict(self, layerFilter = None):
+
+ def getAttributeDomainDict(self, layerFilter=None):
self.checkAndOpenDb()
sql = self.gen.getGeomTablesDomains(layerFilter=layerFilter)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting AttributeDomainDict: ")+query.lastError().text())
- attributeDomainDict = defaultdict(
- lambda : defaultdict(dict)
- )
+ raise Exception(
+ self.tr("Problem getting AttributeDomainDict: ")
+ + query.lastError().text()
+ )
+ attributeDomainDict = defaultdict(lambda: defaultdict(dict))
while query.next():
- tableName, fkAttribute, domainTable, domainReferencedAttribute = self.parseFkQuery(
- query.value(0),query.value(1)
- )
+ (
+ tableName,
+ fkAttribute,
+ domainTable,
+ domainReferencedAttribute,
+ ) = self.parseFkQuery(query.value(0), query.value(1))
newAttrDict = attributeDomainDict[tableName][fkAttribute]
domainPk = self.getPrimaryKeyColumn(domainTable)
- newAttrDict['references'] = domainTable
- newAttrDict['refPk'] = domainPk
+ newAttrDict["references"] = domainTable
+ newAttrDict["refPk"] = domainPk
values, otherKey = self.getLayerColumnDict(domainPk, domainTable)
- newAttrDict['otherKey'] = otherKey
- newAttrDict['values'] = values
- newAttrDict['filterAttr'] = self.getFilter(
- domainTable, domainPk, otherKey
- )
-
-
+ newAttrDict["otherKey"] = otherKey
+ newAttrDict["values"] = values
+ newAttrDict["filterAttr"] = self.getFilter(domainTable, domainPk, otherKey)
+
return attributeDomainDict
def getFilter(self, domainTable, domainPk, otherKey):
- tableSchema, tableName = domainTable.split('.')
+ tableSchema, tableName = domainTable.split(".")
knownColumns = [domainPk, otherKey]
sql = self.gen.getAttributesFromTable(tableSchema, tableName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting filter: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting filter: ") + query.lastError().text()
+ )
while query.next():
column_name = query.value(0)
if column_name not in knownColumns:
return column_name
return None
-
- def getTableMetadataDict(self, layerFilter = None, showViews = False):
+ def getTableMetadataDict(self, layerFilter=None, showViews=False):
"""
New method to handle information from database. Must be migrated to new postgisDb
returns a dict of 'table_name' : {
@@ -2482,47 +3144,46 @@ def getTableMetadataDict(self, layerFilter = None, showViews = False):
sql = self.gen.getTableMetadataDict(layerFilter=layerFilter)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text())
- metadataDict = defaultdict(lambda :{"columns" : defaultdict(dict)})
+ raise Exception(
+ self.tr("Problem getting geom tuple list: ") + query.lastError().text()
+ )
+ metadataDict = defaultdict(lambda: {"columns": defaultdict(dict)})
while query.next():
auxDict = json.loads(query.value(0))
newDict = metadataDict[auxDict["table_name"]]
self.setNewDictTableInfo(newDict, auxDict)
attrDict = newDict["columns"][auxDict["attr_name"]]
self.setNewAttrInfo(attrDict, auxDict, auxInfoDict)
-
+
return metadataDict
def setNewDictTableInfo(self, newDict, auxDict):
newDict["table_name"] = auxDict["table_name"]
newDict["table_schema"] = auxDict["table_schema"]
newDict["primary_key"] = self.getPrimaryKeyColumn(
- '.'.join(
- [
- auxDict["table_schema"],
- auxDict["table_name"]
- ]
- )
- )
+ ".".join([auxDict["table_schema"], auxDict["table_name"]])
+ )
newDict["geometry_column"] = auxDict["geometry_column"]
newDict["geometry_type"] = auxDict["geometry_type"]
-
+
def setNewAttrInfo(self, attrDict, auxDict, auxInfoDict):
attrDict["name"] = auxDict["attr_name"]
attrDict["nullable"] = auxDict["nullable"]
attrDict["column_type"] = auxDict["column_type"]
- attrDict["isMulti"] = True if 'ARRAY' in auxDict["column_type"] else False
- self.setReferenceInfo(attrDict, auxDict, auxInfoDict['attributeDomainDict'])
- self.setConstraintInfo(attrDict, auxDict, auxInfoDict['checkConstraintDict'])
-
+ attrDict["isMulti"] = True if "ARRAY" in auxDict["column_type"] else False
+ self.setReferenceInfo(attrDict, auxDict, auxInfoDict["attributeDomainDict"])
+ self.setConstraintInfo(attrDict, auxDict, auxInfoDict["checkConstraintDict"])
+
def setReferenceInfo(self, attrDict, auxDict, attributeDomainDict):
- if auxDict['table_name'] in attributeDomainDict and \
- auxDict["attr_name"] in attributeDomainDict[auxDict['table_name']]:
- attr_name_dict = attributeDomainDict[auxDict['table_name']][auxDict["attr_name"]]
- attrDict.update(
- attr_name_dict
- )
-
+ if (
+ auxDict["table_name"] in attributeDomainDict
+ and auxDict["attr_name"] in attributeDomainDict[auxDict["table_name"]]
+ ):
+ attr_name_dict = attributeDomainDict[auxDict["table_name"]][
+ auxDict["attr_name"]
+ ]
+ attrDict.update(attr_name_dict)
+
def getDomainDictFromDomainTable(self, refPk, domainTable, otherKey):
domainDict = dict()
self.checkAndOpenDb()
@@ -2531,24 +3192,28 @@ def getDomainDictFromDomainTable(self, refPk, domainTable, otherKey):
if not query.isActive():
raise Exception(
self.tr(
- "Problem getting getDomainDictFromDomainTable from table {table_name}:{query_error}"
- ).format(table_name=domainTable, query_error=query.lastError().text())
+ "Problem getting getDomainDictFromDomainTable from table {table_name}:{query_error}"
+ ).format(table_name=domainTable, query_error=query.lastError().text())
)
while query.next():
aux = json.loads(query.value(0))
- domainDict.update({aux[refPk]:aux[otherKey]})
+ domainDict.update({aux[refPk]: aux[otherKey]})
return domainDict
-
+
def setConstraintInfo(self, attrDict, auxDict, checkConstraintDict):
- if auxDict["table_name"] in checkConstraintDict and \
- auxDict["attr_name"] in checkConstraintDict[auxDict["table_name"]]:
- attrDict["constraintList"] = checkConstraintDict[auxDict["table_name"]][auxDict["attr_name"]]
+ if (
+ auxDict["table_name"] in checkConstraintDict
+ and auxDict["attr_name"] in checkConstraintDict[auxDict["table_name"]]
+ ):
+ attrDict["constraintList"] = checkConstraintDict[auxDict["table_name"]][
+ auxDict["attr_name"]
+ ]
def getLayersFilterByInheritance(self, layerList):
- filter = [i.split('.')[-1] for i in self.getOrphanGeomTables(loading = True)]
+ filter = [i.split(".")[-1] for i in self.getOrphanGeomTables(loading=True)]
filtered = []
for lyr in layerList:
- clause = lyr['tableName'] if isinstance(lyr, dict) else lyr
+ clause = lyr["tableName"] if isinstance(lyr, dict) else lyr
if clause in filter:
filtered.append(lyr)
return filtered
@@ -2562,48 +3227,60 @@ def getNotNullDictV2(self, layerFilter=None):
sql = self.gen.getNotNullDict(layerFilter=layerFilter)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting not null dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting not null dict: ") + query.lastError().text()
+ )
notNullDict = dict()
while query.next():
aux = json.loads(query.value(0))
- if aux['f1'] not in list(notNullDict.keys()):
- notNullDict[aux['f1']] = dict()
- notNullDict[aux['f1']]['schema'] = aux['f2']
- if 'attributes' not in list(notNullDict[aux['f1']].keys()):
- notNullDict[aux['f1']]['attributes'] = []
- notNullDict[aux['f1']]['attributes'] = aux['f3']
+ if aux["f1"] not in list(notNullDict.keys()):
+ notNullDict[aux["f1"]] = dict()
+ notNullDict[aux["f1"]]["schema"] = aux["f2"]
+ if "attributes" not in list(notNullDict[aux["f1"]].keys()):
+ notNullDict[aux["f1"]]["attributes"] = []
+ notNullDict[aux["f1"]]["attributes"] = aux["f3"]
return notNullDict
-
+
def getDomainDictV2(self, domainTable):
self.checkAndOpenDb()
sql = self.gen.getDomainDict(domainTable)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting domain dict from table ")+domainTable+':'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting domain dict from table ")
+ + domainTable
+ + ":"
+ + query.lastError().text()
+ )
domainDict = dict()
while query.next():
aux = json.loads(query.value(0))
- domainDict[aux['f2']] = aux['f1']
+ domainDict[aux["f2"]] = aux["f1"]
return domainDict
-
+
def getLayerColumnDict(self, refPk, domainTable):
self.checkAndOpenDb()
sql = self.gen.getDomainCodeDict(domainTable)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting layer column dict from table ")+domainTable+':'+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting layer column dict from table ")
+ + domainTable
+ + ":"
+ + query.lastError().text()
+ )
domainDict = dict()
otherKey = None
while query.next():
aux = json.loads(query.value(0))
if not otherKey:
- if 'code_name' in list(aux.keys()):
- otherKey = 'code_name'
+ if "code_name" in list(aux.keys()):
+ otherKey = "code_name"
else:
otherKey = [key for key in list(aux.keys()) if key != refPk][0]
domainDict[aux[refPk]] = aux[otherKey]
return domainDict, otherKey
-
+
def getGeomStructDict(self):
"""
Returns dict in the following format:
@@ -2611,25 +3288,34 @@ def getGeomStructDict(self):
"""
self.checkAndOpenDb()
sql = self.gen.getGeomStructDict()
- yesNoDict = {'YES':True, 'NO':False}
+ yesNoDict = {"YES": True, "NO": False}
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom struct dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom struct dict: ") + query.lastError().text()
+ )
geomStructDict = dict()
while query.next():
aux = json.loads(query.value(0))
- tableName = aux['table_name']
+ tableName = aux["table_name"]
if tableName not in list(geomStructDict.keys()):
geomStructDict[tableName] = dict()
- for d in aux['array_agg']:
- geomStructDict[tableName][d['f1']] = yesNoDict[d['f2']]
+ for d in aux["array_agg"]:
+ geomStructDict[tableName][d["f1"]] = yesNoDict[d["f2"]]
return geomStructDict
-
- def createDbFromTemplate(self, dbName, templateName, parentWidget = None):
- #check if created, if created prompt if drop is needed
+
+ def createDbFromTemplate(self, dbName, templateName, parentWidget=None):
+ # check if created, if created prompt if drop is needed
self.checkAndOpenDb()
if parentWidget:
- progress = ProgressWidget(1,2,self.tr('Creating database {0} from template {1}... ').format(dbName, templateName), parent = parentWidget)
+ progress = ProgressWidget(
+ 1,
+ 2,
+ self.tr("Creating database {0} from template {1}... ").format(
+ dbName, templateName
+ ),
+ parent=parentWidget,
+ )
progress.initBar()
self.dropAllConections(templateName)
if parentWidget:
@@ -2637,32 +3323,56 @@ def createDbFromTemplate(self, dbName, templateName, parentWidget = None):
sql = self.gen.createFromTemplate(dbName, templateName)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem creating from template: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating from template: ") + query.lastError().text()
+ )
self.checkAndCreateStyleTable()
- #this close is to allow creation from template
+ # this close is to allow creation from template
self.db.close()
if parentWidget:
progress.step()
-
+
def getViewDefinition(self, viewName):
self.checkAndOpenDb()
sql = self.gen.getViewDefinition(viewName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting view definition: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting view definition: ") + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
- def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parentWidget = None, threading = False):
- self.checkAndOpenDb()
- tableDictList = self.getParentGeomTables(getDictList = True, showViews = False, hideCentroids = False)
- viewList = ['''"{0}"."{1}"'''.format(i['tableSchema'],i['tableName']) for i in list(self.getGeomColumnDictV2(showViews = True, hideCentroids = False).values()) if i['tableType'] == 'VIEW']
- viewDefinitionDict = {i:self.getViewDefinition(i) for i in viewList}
+
+ def updateDbSRID(
+ self,
+ srid,
+ useTransaction=True,
+ closeAfterUse=True,
+ parentWidget=None,
+ threading=False,
+ ):
+ self.checkAndOpenDb()
+ tableDictList = self.getParentGeomTables(
+ getDictList=True, showViews=False, hideCentroids=False
+ )
+ viewList = [
+ '''"{0}"."{1}"'''.format(i["tableSchema"], i["tableName"])
+ for i in list(
+ self.getGeomColumnDictV2(showViews=True, hideCentroids=False).values()
+ )
+ if i["tableType"] == "VIEW"
+ ]
+ viewDefinitionDict = {i: self.getViewDefinition(i) for i in viewList}
if useTransaction:
self.db.transaction()
if parentWidget:
- progress = ProgressWidget(1, 2*len(viewList)+len(tableDictList), self.tr('Updating SRIDs from {0}... ').format(self.db.databaseName()), parent = parentWidget)
+ progress = ProgressWidget(
+ 1,
+ 2 * len(viewList) + len(tableDictList),
+ self.tr("Updating SRIDs from {0}... ").format(self.db.databaseName()),
+ parent=parentWidget,
+ )
progress.initBar()
for view in viewList:
viewSql = self.gen.dropView(view)
@@ -2673,7 +3383,9 @@ def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parent
if threading:
return (viewSql, query)
else:
- raise Exception(self.tr('Problem dropping views: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem dropping views: ") + query.lastError().text()
+ )
if parentWidget:
progress.step()
@@ -2686,11 +3398,15 @@ def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parent
if threading:
return (sridSql, query)
else:
- raise Exception(self.tr('Problem dropping views: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem dropping views: ") + query.lastError().text()
+ )
if parentWidget:
progress.step()
for viewName in viewList:
- createViewSql = self.gen.createViewStatement(viewName, viewDefinitionDict[viewName])
+ createViewSql = self.gen.createViewStatement(
+ viewName, viewDefinitionDict[viewName]
+ )
query = QSqlQuery(self.db)
if not query.exec_(createViewSql):
if useTransaction:
@@ -2698,16 +3414,18 @@ def updateDbSRID(self, srid, useTransaction = True, closeAfterUse = True, parent
if threading:
return (createViewSql, query)
else:
- raise Exception(self.tr('Problem dropping views: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem dropping views: ") + query.lastError().text()
+ )
if parentWidget:
progress.step()
if useTransaction:
self.db.commit()
- #this close is to allow creation from template
+ # this close is to allow creation from template
if closeAfterUse:
self.db.close()
-
- def checkTemplate(self, version = None):
+
+ def checkTemplate(self, version=None):
self.checkAndOpenDb()
if not version:
version = self.getDatabaseVersion()
@@ -2715,12 +3433,14 @@ def checkTemplate(self, version = None):
sql = self.gen.checkTemplate()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem setting as template: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem setting as template: ") + query.lastError().text()
+ )
while query.next():
if query.value(0) == dbName:
return True
return False
-
+
def createTemplateDatabase(self, version):
"""
version: edgv version
@@ -2733,7 +3453,7 @@ def createTemplateDatabase(self, version):
except:
pass
self.createDatabase(dbName)
-
+
def createDatabase(self, dbName):
"""
Creates a database with a given name
@@ -2742,21 +3462,25 @@ def createDatabase(self, dbName):
sql = self.gen.getCreateDatabase(dbName)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem creating database: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem creating database: ") + query.lastError().text()
+ )
+
def getTemplateName(self, version):
- if version == '2.1.3':
- return 'template_edgv_213'
- elif version == '2.1.3 Pro' or version == 'EDGV 2.1.3 Pro':
- return 'template_edgv_213_pro'
- elif version == 'FTer_2a_Ed':
- return 'template_edgv_fter_2a_ed'
- elif version == '3.0':
- return 'template_edgv_3'
- elif version in ('EDGV 3.0 Pro', '3.0 Pro'):
- return 'template_edgv_3_pro'
-
- def setDbAsTemplate(self, version = None, dbName = None, setTemplate = True, useTransaction = True):
+ if version == "2.1.3":
+ return "template_edgv_213"
+ elif version == "2.1.3 Pro" or version == "EDGV 2.1.3 Pro":
+ return "template_edgv_213_pro"
+ elif version == "FTer_2a_Ed":
+ return "template_edgv_fter_2a_ed"
+ elif version == "3.0":
+ return "template_edgv_3"
+ elif version in ("EDGV 3.0 Pro", "3.0 Pro"):
+ return "template_edgv_3_pro"
+
+ def setDbAsTemplate(
+ self, version=None, dbName=None, setTemplate=True, useTransaction=True
+ ):
self.checkAndOpenDb()
if not dbName:
dbName = self.getTemplateName(version)
@@ -2767,7 +3491,10 @@ def setDbAsTemplate(self, version = None, dbName = None, setTemplate = True, use
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr("Problem setting database as template: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem setting database as template: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
@@ -2776,51 +3503,122 @@ def checkIfTemplate(self, dbName):
sql = self.gen.checkIfTemplate(dbName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem checking template: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem checking template: ") + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def getCreationSqlPath(self, version):
currentPath = os.path.dirname(__file__)
- edgvPath = ''
- if version == '2.1.3':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '213', 'edgv213.sql')
- elif version == '2.1.3 Pro' or version == 'EDGV 2.1.3 Pro':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '213_Pro', 'edgv213_pro.sql')
- elif version == 'FTer_2a_Ed':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', 'FTer_2a_Ed', 'edgvFter_2a_Ed.sql')
- elif version == '3.0':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '3', 'edgv3.sql')
- elif version == '3.0 Pro':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', '3_Pro', 'edgv3_pro.sql')
- elif version == 'admin':
- edgvPath = os.path.join(currentPath,'..','..','..','core','DbModels','PostGIS', 'admin', 'dsgtools_admindb.sql')
+ edgvPath = ""
+ if version == "2.1.3":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "PostGIS",
+ "213",
+ "edgv213.sql",
+ )
+ elif version == "2.1.3 Pro" or version == "EDGV 2.1.3 Pro":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "PostGIS",
+ "213_Pro",
+ "edgv213_pro.sql",
+ )
+ elif version == "FTer_2a_Ed":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "PostGIS",
+ "FTer_2a_Ed",
+ "edgvFter_2a_Ed.sql",
+ )
+ elif version == "3.0":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "PostGIS",
+ "3",
+ "edgv3.sql",
+ )
+ elif version == "3.0 Pro":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "PostGIS",
+ "3_Pro",
+ "edgv3_pro.sql",
+ )
+ elif version == "admin":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "..",
+ "..",
+ "core",
+ "DbModels",
+ "PostGIS",
+ "admin",
+ "dsgtools_admindb.sql",
+ )
return edgvPath
-
- def getCommandsFromFile(self, edgvPath, epsg = None):
+
+ def getCommandsFromFile(self, edgvPath, epsg=None):
"""
Gets all sql commands from file
"""
- file = codecs.open(edgvPath, encoding='utf-8', mode="r")
+ file = codecs.open(edgvPath, encoding="utf-8", mode="r")
sql = file.read()
if epsg:
- sql = sql.replace('[epsg]', str(epsg))
+ sql = sql.replace("[epsg]", str(epsg))
file.close()
- commands = sql.split('#')
+ commands = sql.split("#")
return commands
-
+
def getImplementationVersionFromFile(self, edgvVersion):
edgvPath = self.getCreationSqlPath(edgvVersion)
commands = self.getCommandsFromFile(edgvPath)
- searchString = 'INSERT INTO public.db_metadata (edgvversion, dbimplversion) VALUES ('
+ searchString = (
+ "INSERT INTO public.db_metadata (edgvversion, dbimplversion) VALUES ("
+ )
for command in commands:
if searchString in command:
- return command.split(searchString)[-1].split(',')[-1].replace(')','').replace("'","")
+ return (
+ command.split(searchString)[-1]
+ .split(",")[-1]
+ .replace(")", "")
+ .replace("'", "")
+ )
- def setStructureFromSql(self, version, epsg, useTransaction = True, closeAfterUsage = True):
+ def setStructureFromSql(
+ self, version, epsg, useTransaction=True, closeAfterUsage=True
+ ):
self.checkAndOpenDb()
edgvPath = self.getCreationSqlPath(version)
- commands = [i for i in self.getCommandsFromFile(edgvPath, epsg = epsg) if i != '']
+ commands = [i for i in self.getCommandsFromFile(edgvPath, epsg=epsg) if i != ""]
if useTransaction:
self.db.transaction()
query = QSqlQuery(self.db)
@@ -2829,17 +3627,21 @@ def setStructureFromSql(self, version, epsg, useTransaction = True, closeAfterUs
if command and not query.exec_(command):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Error on database creation! ')+query.lastError().text()+ self.tr(' Db will be dropped.'))
+ raise Exception(
+ self.tr("Error on database creation! ")
+ + query.lastError().text()
+ + self.tr(" Db will be dropped.")
+ )
if useTransaction:
self.db.commit()
- self.alterSearchPath(version, useTransaction = useTransaction)
- self.setDbAsTemplate(version = version, useTransaction = useTransaction)
- self.createStyleTable(useTransaction = useTransaction)
- #this close is to allow creation from template
+ self.alterSearchPath(version, useTransaction=useTransaction)
+ self.setDbAsTemplate(version=version, useTransaction=useTransaction)
+ self.createStyleTable(useTransaction=useTransaction)
+ # this close is to allow creation from template
if closeAfterUsage:
self.db.close()
-
- def alterSearchPath(self, version, useTransaction = True):
+
+ def alterSearchPath(self, version, useTransaction=True):
self.checkAndOpenDb()
dbName = self.db.databaseName()
sql = self.gen.alterSearchPath(dbName, version)
@@ -2847,33 +3649,42 @@ def alterSearchPath(self, version, useTransaction = True):
query = QSqlQuery(self.db)
if not query.exec_(sql):
self.db.rollback()
- raise Exception(self.tr("Problem altering search path: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem altering search path: ") + query.lastError().text()
+ )
self.db.commit()
- def createFrame(self, type, scale, param, paramDict = dict()):
+ def createFrame(self, type, scale, param, paramDict=dict()):
mi, inom, frame = self.prepareCreateFrame(type, scale, param)
- self.insertFrame(scale, mi, inom, frame.asWkb(), paramDict = paramDict)
+ self.insertFrame(scale, mi, inom, frame.asWkb(), paramDict=paramDict)
return frame
-
+
def getUsersFromServer(self):
self.checkAndOpenDb()
ret = []
sql = self.gen.getUsersFromServer()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting users: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting users: ") + query.lastError().text()
+ )
while query.next():
ret.append((query.value(0), query.value(1)))
return ret
-
+
def reassignAndDropUser(self, user):
self.checkAndOpenDb()
sql = self.gen.reasignAndDropUser(user)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem removing user: ') +user+'\n'+query.lastError().text())
-
- def removeFeatureFlags(self, layer, featureId, processName, useTransaction = True):
+ raise Exception(
+ self.tr("Problem removing user: ")
+ + user
+ + "\n"
+ + query.lastError().text()
+ )
+
+ def removeFeatureFlags(self, layer, featureId, processName, useTransaction=True):
"""
Removes flags for a specific layer, feature id and process name
layer: layer name
@@ -2888,11 +3699,13 @@ def removeFeatureFlags(self, layer, featureId, processName, useTransaction = Tru
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem deleting flag: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem deleting flag: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def removeEmptyGeometries(self, layer, geometryColumn, useTransaction = True):
+
+ def removeEmptyGeometries(self, layer, geometryColumn, useTransaction=True):
"""
Removes empty geometries from layer
layer: layer name
@@ -2906,10 +3719,13 @@ def removeEmptyGeometries(self, layer, geometryColumn, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem removing empty geometries: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem removing empty geometries: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def getParamsFromConectedDb(self):
self.checkAndOpenDb()
host = self.db.hostName()
@@ -2923,11 +3739,13 @@ def createAdminDb(self):
Creates a database with a given name
"""
self.checkAndOpenDb()
- sql = self.gen.getCreateDatabase('dsgtools_admindb')
+ sql = self.gen.getCreateDatabase("dsgtools_admindb")
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem creating database: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem creating database: ") + query.lastError().text()
+ )
+
def hasAdminDb(self):
"""
Checks if server has a dsgtools_admindb
@@ -2936,12 +3754,14 @@ def hasAdminDb(self):
sql = self.gen.hasAdminDb()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem looking for admindb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem looking for admindb: ") + query.lastError().text()
+ )
while query.next():
if query.value(0):
return True
return False
-
+
def getRolesDict(self):
"""
Gets a dict with the format: 'dbname':{[-list of roles-]}
@@ -2950,27 +3770,34 @@ def getRolesDict(self):
sql = self.gen.getRolesDict()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting roles dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting roles dict: ") + query.lastError().text()
+ )
rolesDict = dict()
while query.next():
aux = json.loads(query.value(0))
- if aux['dbname'] not in list(rolesDict.keys()):
- rolesDict[aux['dbname']] = []
- rolesDict[aux['dbname']].append(aux['rolename'])
+ if aux["dbname"] not in list(rolesDict.keys()):
+ rolesDict[aux["dbname"]] = []
+ rolesDict[aux["dbname"]].append(aux["rolename"])
return rolesDict
-
+
def insertIntoPermissionProfile(self, name, jsondict, edgvversion):
"""
Inserts into public.permission_profile on dsgtools_admindb (name, jsondict, edgvversion)
"""
self.checkAndOpenDb()
- if self.db.databaseName() != 'dsgtools_admindb':
- raise Exception(self.tr('Error! Operation not defined for non dsgtools_admindb'))
+ if self.db.databaseName() != "dsgtools_admindb":
+ raise Exception(
+ self.tr("Error! Operation not defined for non dsgtools_admindb")
+ )
sql = self.gen.insertIntoPermissionProfile(name, jsondict, edgvversion)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem inserting into permission profile: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem inserting into permission profile: ")
+ + query.lastError().text()
+ )
+
def dropRoleOnDatabase(self, roleName):
"""
Drops role using drop owned by and drop role.
@@ -2980,8 +3807,13 @@ def dropRoleOnDatabase(self, roleName):
sql = self.gen.dropRoleOnDatabase(roleName)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem dropping profile: ")+ roleName + ' :' + query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem dropping profile: ")
+ + roleName
+ + " :"
+ + query.lastError().text()
+ )
+
def getRoleFromAdminDb(self, roleName, edgvVersion):
"""
Gets role from public.permission_profile
@@ -2990,10 +3822,13 @@ def getRoleFromAdminDb(self, roleName, edgvVersion):
sql = self.gen.getPermissionProfile(roleName, edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting roles from adminDb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting roles from adminDb: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def getAllRolesFromAdminDb(self):
"""
Gets role from public.permission_profile and returns a dict with format {edgvVersion:[-list of roles-]}
@@ -3002,13 +3837,16 @@ def getAllRolesFromAdminDb(self):
sql = self.gen.getAllPermissionProfiles()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting all roles from adminDb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting all roles from adminDb: ")
+ + query.lastError().text()
+ )
allRolesDict = dict()
while query.next():
aux = json.loads(query.value(0))
- allRolesDict[aux['edgvversion']] = aux['profiles']
+ allRolesDict[aux["edgvversion"]] = aux["profiles"]
return allRolesDict
-
+
def deletePermissionProfile(self, name, edgvversion):
"""
Deletes profile from public.permission_profiles
@@ -3017,38 +3855,49 @@ def deletePermissionProfile(self, name, edgvversion):
sql = self.gen.deletePermissionProfile(name, edgvversion)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem deleting permission profile: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem deleting permission profile: ")
+ + query.lastError().text()
+ )
+
def getGrantedRolesDict(self):
"""
Gets a dict in the format:
- { roleName : [-list of users-] }
+ { roleName : [-list of users-] }
"""
self.checkAndOpenDb()
sql = self.gen.getRolesWithGrantedUsers()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting granted roles dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting granted roles dict: ")
+ + query.lastError().text()
+ )
grantedRolesDict = dict()
while query.next():
aux = json.loads(query.value(0))
- if aux['profile'] not in list(grantedRolesDict.keys()):
- grantedRolesDict[aux['profile']] = []
- for user in aux['users']:
- if user not in grantedRolesDict[aux['profile']]:
- grantedRolesDict[aux['profile']].append(user)
+ if aux["profile"] not in list(grantedRolesDict.keys()):
+ grantedRolesDict[aux["profile"]] = []
+ for user in aux["users"]:
+ if user not in grantedRolesDict[aux["profile"]]:
+ grantedRolesDict[aux["profile"]].append(user)
return grantedRolesDict
-
+
def updatePermissionProfile(self, name, edgvVersion, newjsondict):
"""
Updates public.permission_profile with new definition.
"""
self.checkAndOpenDb()
- sql = self.gen.updateRecordFromPropertyTable('Permission', name, edgvVersion, newjsondict)
+ sql = self.gen.updateRecordFromPropertyTable(
+ "Permission", name, edgvVersion, newjsondict
+ )
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem updating permission profile: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem updating permission profile: ")
+ + query.lastError().text()
+ )
+
def getDomainTables(self):
"""
Lists all domain tables available.
@@ -3057,12 +3906,14 @@ def getDomainTables(self):
sql = self.gen.getDomainTables()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting domain tables: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting domain tables: ") + query.lastError().text()
+ )
domainList = []
while query.next():
domainList.append(query.value(0))
return domainList
-
+
def getGeometricSchemaList(self):
"""
Lists all schemas with geometries.
@@ -3071,12 +3922,15 @@ def getGeometricSchemaList(self):
sql = self.gen.getGeometricSchemaList()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geometric schema list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geometric schema list: ")
+ + query.lastError().text()
+ )
schemaList = []
while query.next():
schemaList.append(query.value(0))
return schemaList
-
+
def getGeometricTableListFromSchema(self, schema):
"""
Lists all tables with geometries from schema
@@ -3085,19 +3939,32 @@ def getGeometricTableListFromSchema(self, schema):
sql = self.gen.getGeometricTableListFromSchema(schema)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geometric table list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geometric table list: ")
+ + query.lastError().text()
+ )
tableList = []
while query.next():
tableList.append(query.value(1))
return tableList
-
- def getParentGeomTables(self, getTuple = False, getFullName = False, primitiveFilter = [], showViews = False, hideCentroids = True, getDictList = False):
+
+ def getParentGeomTables(
+ self,
+ getTuple=False,
+ getFullName=False,
+ primitiveFilter=[],
+ showViews=False,
+ hideCentroids=True,
+ getDictList=False,
+ ):
"""
Lists all tables with geometries from schema that are parents.
"""
self.checkAndOpenDb()
- layerDictList = self.getGeomColumnDictV2(showViews = showViews, hideCentroids = hideCentroids)
- geomTables = [i['tableName'] for i in list(layerDictList.values())]
+ layerDictList = self.getGeomColumnDictV2(
+ showViews=showViews, hideCentroids=hideCentroids
+ )
+ geomTables = [i["tableName"] for i in list(layerDictList.values())]
inhDict = self.getInheritanceDict()
# final parent list
@@ -3116,9 +3983,13 @@ def getParentGeomTables(self, getTuple = False, getFullName = False, primitiveFi
# we must check tables orphan tables (no parent and no child)
# if a table like this is a geometry table it should be stored
for geomTable in geomTables:
- if geomTable not in childList and geomTable not in parentList and geomTable not in parentGeomTables:
+ if (
+ geomTable not in childList
+ and geomTable not in parentList
+ and geomTable not in parentGeomTables
+ ):
parentGeomTables.append(geomTable)
-
+
# analyzing only the inheritance information
for parent in list(inhDict.keys()):
if parent in geomTables:
@@ -3129,48 +4000,67 @@ def getParentGeomTables(self, getTuple = False, getFullName = False, primitiveFi
# if the parent is not a geometry table all its children should be stored
for child in inhDict[parent]:
if child not in parentGeomTables:
- parentGeomTables.append(child)
+ parentGeomTables.append(child)
- #filters in case of filter
+ # filters in case of filter
if primitiveFilter != []:
- filterList = [i['tableName'] for i in list(self.getGeomColumnDictV2(showViews = showViews, hideCentroids = hideCentroids, primitiveFilter = primitiveFilter).values())]
+ filterList = [
+ i["tableName"]
+ for i in list(
+ self.getGeomColumnDictV2(
+ showViews=showViews,
+ hideCentroids=hideCentroids,
+ primitiveFilter=primitiveFilter,
+ ).values()
+ )
+ ]
aux = [i for i in parentGeomTables if i in filterList]
parentGeomTables = aux
parentGeomTables.sort()
if getDictList:
- filteredDictList = [i for i in list(layerDictList.values()) if i['tableName'] in parentGeomTables]
+ filteredDictList = [
+ i
+ for i in list(layerDictList.values())
+ if i["tableName"] in parentGeomTables
+ ]
return filteredDictList
- #output types
+ # output types
if getFullName:
parentFullList = []
for parent in parentGeomTables:
schema = self.getTableSchemaFromDb(parent)
- if schema not in ['views', 'validation'] and schema:
- parentFullList.append( schema+'.'+parent )
+ if schema not in ["views", "validation"] and schema:
+ parentFullList.append(schema + "." + parent)
return parentFullList
if not getTuple:
- return [i for i in parentGeomTables if self.getTableSchemaFromDb(i) not in ['views', 'validation'] ]
+ return [
+ i
+ for i in parentGeomTables
+ if self.getTableSchemaFromDb(i) not in ["views", "validation"]
+ ]
else:
parentTupleList = []
for parent in parentGeomTables:
schema = self.getTableSchemaFromDb(parent)
- if schema not in ['views', 'validation']:
- parentTupleList.append( (schema, parent) )
+ if schema not in ["views", "validation"]:
+ parentTupleList.append((schema, parent))
return parentTupleList
-
+
def getInheritanceDict(self):
self.checkAndOpenDb()
sql = self.gen.getInheritanceDict()
query = QSqlQuery(sql, self.db)
inhDict = dict()
if not query.isActive():
- raise Exception(self.tr("Problem getting inheritance: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting inheritance: ") + query.lastError().text()
+ )
while query.next():
aux = json.loads(query.value(0))
- inhDict[aux['parentname']] = aux['childname']
+ inhDict[aux["parentname"]] = aux["childname"]
return inhDict
-
- def getInheritanceBloodLine(self, parent, inhDict = None):
+
+ def getInheritanceBloodLine(self, parent, inhDict=None):
"""
Lists all tables that have parent as an ancestor.
"""
@@ -3179,10 +4069,10 @@ def getInheritanceBloodLine(self, parent, inhDict = None):
bloodLine = []
self.utils.getRecursiveInheritance(parent, bloodLine, inhDict)
return bloodLine
-
+
def getFullBloodLineDict(self, candidate):
pass
-
+
def getAttributeListFromTable(self, schema, tableName):
"""
Lists all attributes from table.
@@ -3191,24 +4081,28 @@ def getAttributeListFromTable(self, schema, tableName):
sql = self.gen.getAttributeListFromTable(schema, tableName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting attribute list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting attribute list: ") + query.lastError().text()
+ )
attributeList = []
while query.next():
attributeList.append(query.value(0))
return attributeList
-
+
def getAttributeJsonFromDb(self):
self.checkAndOpenDb()
sql = self.gen.getAttributeDictFromDb()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting attribute list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting attribute list: ") + query.lastError().text()
+ )
attributeJson = []
while query.next():
attributeJson.append(json.loads(query.value(0)))
return attributeJson
-
- def getAllDomainValues(self, domainTableList = []):
+
+ def getAllDomainValues(self, domainTableList=[]):
self.checkAndOpenDb()
if domainTableList == []:
domainTableList = self.getDomainTables()
@@ -3222,12 +4116,12 @@ def getAllDomainValues(self, domainTableList = []):
valueList.append(value)
valueList.sort()
return valueList
-
+
def getInheritanceTreeDict(self):
self.checkAndOpenDb()
inhDict = self.getInheritanceDict()
layerList = self.listGeomClassesFromDatabase()
- geomTables = [i.split('.')[-1] for i in layerList]
+ geomTables = [i.split(".")[-1] for i in layerList]
inhTreeDict = dict()
for parent in list(inhDict.keys()):
self.utils.getRecursiveInheritanceTreeDict(parent, inhTreeDict, inhDict)
@@ -3242,19 +4136,19 @@ def getInheritanceTreeDict(self):
for item in blackList:
inhTreeDict.pop(item)
childBlackList = []
- self.utils.getAllItemsInDict(inhTreeDict,childBlackList)
+ self.utils.getAllItemsInDict(inhTreeDict, childBlackList)
for geomTable in geomTables:
if geomTable not in childBlackList:
schema = self.getTableSchemaFromDb(geomTable)
- if schema not in ['views', 'validation']:
+ if schema not in ["views", "validation"]:
inhTreeDict[geomTable] = dict()
- r = {'root':inhTreeDict}
+ r = {"root": inhTreeDict}
return r
-
+
# def getInheritanceConstraintDict(self):
# """
# Returns a dict in the form:
- # {'tableName':{'attributeName': {'tableName','constraintName', 'filter'}
+ # {'tableName':{'attributeName': {'tableName','constraintName', 'filter'}
# }
# }
# """
@@ -3272,7 +4166,7 @@ def getInheritanceTreeDict(self):
# inhConstrDict[tableName] = dict()
# defList = queryResult['array_agg']
# for value in defList:
- # constraintName = value['f1']
+ # constraintName = value['f1']
# constraintDef = value['f2']
# attrName = constraintName.split('_')[-2]
# currTableName = constraintName.split('_'+attrName)[0]
@@ -3284,7 +4178,7 @@ def getInheritanceTreeDict(self):
# if currTag not in inhConstrDict[tableName][attrName]:
# inhConstrDict[tableName][attrName].append(currTag)
# return inhConstrDict
-
+
def getDefaultFromDb(self, schema, tableName, attrName):
"""
Gets default value from table
@@ -3293,23 +4187,34 @@ def getDefaultFromDb(self, schema, tableName, attrName):
sql = self.gen.getDefaultFromDb(schema, tableName, attrName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting default from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting default from db: ") + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def insertSettingIntoAdminDb(self, settingType, name, jsondict, edgvversion):
"""
Inserts setting into dsgtools_admindb (name, jsondict, edgvversion),
according to settingType
"""
self.checkAndOpenDb()
- if self.db.databaseName() != 'dsgtools_admindb':
- raise Exception(self.tr('Error! Operation not defined for non dsgtools_admindb'))
- sql = self.gen.insertSettingIntoAdminDb(settingType, name, jsondict, edgvversion)
+ if self.db.databaseName() != "dsgtools_admindb":
+ raise Exception(
+ self.tr("Error! Operation not defined for non dsgtools_admindb")
+ )
+ sql = self.gen.insertSettingIntoAdminDb(
+ settingType, name, jsondict, edgvversion
+ )
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem inserting property ")+settingType+self.tr(' into dsgtools_admindb: ')+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem inserting property ")
+ + settingType
+ + self.tr(" into dsgtools_admindb: ")
+ + query.lastError().text()
+ )
+
def getSettingFromAdminDb(self, settingType, settingName, edgvVersion):
"""
Gets role from public.permission_profile
@@ -3318,19 +4223,25 @@ def getSettingFromAdminDb(self, settingType, settingName, edgvVersion):
sql = self.gen.getSettingFromAdminDb(settingType, settingName, edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting setting from adminDb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting setting from adminDb: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def getSettingVersion(self, settingType, settingName):
self.checkAndOpenDb()
sql = self.gen.getSettingVersion(settingType, settingName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting setting from adminDb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting setting from adminDb: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def getAllSettingsFromAdminDb(self, settingType):
"""
Gets role from public.permission_profile and returns a dict with format {edgvVersion:[-list of roles-]}
@@ -3341,13 +4252,16 @@ def getAllSettingsFromAdminDb(self, settingType):
sql = self.gen.getAllSettingsFromAdminDb(settingType)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting settings from adminDb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting settings from adminDb: ")
+ + query.lastError().text()
+ )
allRolesDict = dict()
while query.next():
aux = json.loads(query.value(0))
- allRolesDict[aux['edgvversion']] = aux['settings']
+ allRolesDict[aux["edgvversion"]] = aux["settings"]
return allRolesDict
-
+
def deleteSettingFromAdminDb(self, settingType, name, edgvversion):
"""
Deletes profile from public.permission_profiles
@@ -3356,9 +4270,12 @@ def deleteSettingFromAdminDb(self, settingType, name, edgvversion):
sql = self.gen.deleteSettingFromAdminDb(settingType, name, edgvversion)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr("Problem deleting permission setting: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem deleting permission setting: ")
+ + query.lastError().text()
+ )
- def upgradePostgis(self, useTransaction = True):
+ def upgradePostgis(self, useTransaction=True):
self.checkAndOpenDb()
updateDict = self.getPostgisVersion()
if updateDict != dict():
@@ -3369,67 +4286,90 @@ def upgradePostgis(self, useTransaction = True):
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr("Problem upgrading postgis: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem upgrading postgis: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def getPostgisVersion(self):
self.checkAndOpenDb()
sql = self.gen.getPostgisVersion()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting postgis version: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting postgis version: ") + query.lastError().text()
+ )
updateDict = dict()
while query.next():
defaultVersion = query.value(1)
installedVersion = query.value(2)
- if defaultVersion != installedVersion and installedVersion not in ['', None]:
- updateDict[query.value(0)] = {'defaultVersion':defaultVersion, 'installedVersion':installedVersion}
+ if defaultVersion != installedVersion and installedVersion not in [
+ "",
+ None,
+ ]:
+ updateDict[query.value(0)] = {
+ "defaultVersion": defaultVersion,
+ "installedVersion": installedVersion,
+ }
return updateDict
-
+
def getCustomizationPerspectiveDict(self, perspective):
self.checkAndOpenDb()
sql = self.gen.getCustomizationPerspectiveDict(perspective)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting applied customizations: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting applied customizations: ")
+ + query.lastError().text()
+ )
customDict = dict()
while query.next():
jsonDict = json.loads(query.value(0))
- customDict[jsonDict['name']] = jsonDict['array_agg']
+ customDict[jsonDict["name"]] = jsonDict["array_agg"]
return customDict
- def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter = None):
+ def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter=None):
self.checkAndOpenDb()
- sql = self.gen.getPropertyPerspectiveDict(settingType, perspective, versionFilter)
+ sql = self.gen.getPropertyPerspectiveDict(
+ settingType, perspective, versionFilter
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting applied customizations: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting applied customizations: ")
+ + query.lastError().text()
+ )
customDict = dict()
while query.next():
jsonDict = json.loads(query.value(0))
- customDict[jsonDict['name']] = jsonDict['array_agg']
+ customDict[jsonDict["name"]] = jsonDict["array_agg"]
return customDict
-
- def createPropertyTable(self, settingType, useTransaction = True, isAdminDb = False):
+
+ def createPropertyTable(self, settingType, useTransaction=True, isAdminDb=False):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
- createSql = self.gen.createPropertyTable(settingType, isAdminDb = isAdminDb)
+ createSql = self.gen.createPropertyTable(settingType, isAdminDb=isAdminDb)
query = QSqlQuery(self.db)
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating Setting table: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating Setting table: ") + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def checkIfTableExists(self, schema, tableName):
self.checkAndOpenDb()
sql = self.gen.checkIfTableExists(schema, tableName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting checking if table exists: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting checking if table exists: ")
+ + query.lastError().text()
+ )
while query.next():
if query.value(0):
return True
@@ -3437,27 +4377,32 @@ def checkIfTableExists(self, schema, tableName):
def checkIfExistsConfigTable(self, settingType):
settingTable = self.gen.getSettingTable(settingType)
- return self.checkIfTableExists('public', settingTable)
-
+ return self.checkIfTableExists("public", settingTable)
+
def getRecordFromAdminDb(self, settingType, propertyName, edgvVersion):
self.checkAndOpenDb()
sql = self.gen.getRecordFromAdminDb(settingType, propertyName, edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting getting record from adminDb: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting getting record from adminDb: ")
+ + query.lastError().text()
+ )
retDict = dict()
while query.next():
- retDict['id'] = query.value(0)
- retDict['name'] = query.value(1)
- retDict['jsondict'] = query.value(2)
- retDict['edgvversion'] = query.value(3)
- #yes, this return is inside the while. Why? Because I said so!
+ retDict["id"] = query.value(0)
+ retDict["name"] = query.value(1)
+ retDict["jsondict"] = query.value(2)
+ retDict["edgvversion"] = query.value(3)
+ # yes, this return is inside the while. Why? Because I said so!
return retDict
-
- def insertRecordInsidePropertyTable(self, settingType, settingDict, edgvVersion, useTransaction = False):
+
+ def insertRecordInsidePropertyTable(
+ self, settingType, settingDict, edgvVersion, useTransaction=False
+ ):
self.checkAndOpenDb()
if edgvVersion != self.getDatabaseVersion():
- raise Exception(self.tr('Invalid property with database version.'))
+ raise Exception(self.tr("Invalid property with database version."))
if useTransaction:
self.db.transaction()
createSql = self.gen.insertRecordInsidePropertyTable(settingType, settingDict)
@@ -3465,18 +4410,24 @@ def insertRecordInsidePropertyTable(self, settingType, settingDict, edgvVersion,
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem inserting record inside property table: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem inserting record inside property table: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def getPropertyDict(self, settingType, getOnlySameVersion = False):
+
+ def getPropertyDict(self, settingType, getOnlySameVersion=False):
self.checkAndOpenDb()
if getOnlySameVersion:
myEdgvVersion = self.getDatabaseVersion()
sql = self.gen.getAllPropertiesFromDb(settingType)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting getting property dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting getting property dict: ")
+ + query.lastError().text()
+ )
propertyDict = dict()
while query.next():
edgvVersion = query.value(0)
@@ -3489,70 +4440,101 @@ def getPropertyDict(self, settingType, getOnlySameVersion = False):
propertyDict[edgvVersion] = dict()
propertyDict[edgvVersion][name] = jsonDict
return propertyDict
-
- def insertInstalledRecordIntoAdminDb(self, settingType, recDict, dbOid, useTransaction = False):
+
+ def insertInstalledRecordIntoAdminDb(
+ self, settingType, recDict, dbOid, useTransaction=False
+ ):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
- createSql = self.gen.insertInstalledRecordIntoAdminDb(settingType, recDict, dbOid)
+ createSql = self.gen.insertInstalledRecordIntoAdminDb(
+ settingType, recDict, dbOid
+ )
query = QSqlQuery(self.db)
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem inserting installed record into adminDb: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem inserting installed record into adminDb: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def removeRecordFromPropertyTable(self, settingType, configName, edgvVersion, useTransaction = False):
+
+ def removeRecordFromPropertyTable(
+ self, settingType, configName, edgvVersion, useTransaction=False
+ ):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
- createSql = self.gen.removeRecordFromPropertyTable(settingType, configName, edgvVersion)
+ createSql = self.gen.removeRecordFromPropertyTable(
+ settingType, configName, edgvVersion
+ )
query = QSqlQuery(self.db)
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem removing installed record into db: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem removing installed record into db: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
- def updateRecordFromPropertyTable(self, settingType, configName, edgvVersion, jsonDict, useTransaction = False):
+ def updateRecordFromPropertyTable(
+ self, settingType, configName, edgvVersion, jsonDict, useTransaction=False
+ ):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
- if isinstance(jsonDict,dict):
+ if isinstance(jsonDict, dict):
jsonDict = json.dumps(jsonDict, sort_keys=True, indent=4)
- createSql = self.gen.updateRecordFromPropertyTable(settingType, configName, edgvVersion, jsonDict)
+ createSql = self.gen.updateRecordFromPropertyTable(
+ settingType, configName, edgvVersion, jsonDict
+ )
query = QSqlQuery(self.db)
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem removing installed record into db: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem removing installed record into db: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
- def uninstallPropertyOnAdminDb(self, settingType, configName, edgvVersion, useTransaction = False, dbName = None):
+
+ def uninstallPropertyOnAdminDb(
+ self, settingType, configName, edgvVersion, useTransaction=False, dbName=None
+ ):
self.checkAndOpenDb()
if useTransaction:
self.db.transaction()
- createSql = self.gen.uninstallPropertyOnAdminDb(settingType, configName, edgvVersion, dbName = dbName)
+ createSql = self.gen.uninstallPropertyOnAdminDb(
+ settingType, configName, edgvVersion, dbName=dbName
+ )
query = QSqlQuery(self.db)
if not query.exec_(createSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem removing installed record into db: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem removing installed record into db: ")
+ + query.lastError().text()
+ )
if useTransaction:
self.db.commit()
-
+
def getPrimaryKeyColumn(self, tableName):
self.checkAndOpenDb()
sql = self.gen.getPrimaryKeyColumn(tableName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting primary key column: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting primary key column: ")
+ + query.lastError().text()
+ )
while query.next():
return query.value(0)
-
+
def dropAllConections(self, dbName):
"""
Terminates all database conections
@@ -3562,26 +4544,39 @@ def dropAllConections(self, dbName):
sql = self.gen.dropAllConections(dbName)
query = QSqlQuery(self.db)
if not query.exec_(sql):
- raise Exception(self.tr('Problem dropping database conections: ') + query.lastError().text())
-
- def getAttributesFromTable(self, tableSchema, tableName, typeFilter = [], returnType = 'list'):
+ raise Exception(
+ self.tr("Problem dropping database conections: ")
+ + query.lastError().text()
+ )
+
+ def getAttributesFromTable(
+ self, tableSchema, tableName, typeFilter=[], returnType="list"
+ ):
"""
Gets attributes from "tableSchema"."tableName" according to typeFilter
"""
self.checkAndOpenDb()
- sql = self.gen.getAttributesFromTable(tableSchema, tableName, typeFilter = typeFilter)
+ sql = self.gen.getAttributesFromTable(
+ tableSchema, tableName, typeFilter=typeFilter
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting attributes from table {0}.{1}: {2}").format(tableSchema, tableName, query.lastError().text()))
+ raise Exception(
+ self.tr("Problem getting attributes from table {0}.{1}: {2}").format(
+ tableSchema, tableName, query.lastError().text()
+ )
+ )
returnStruct = []
while query.next():
- if returnType == 'list':
+ if returnType == "list":
returnStruct.append(query.value(0))
else:
- returnStruct.append({'attrName':query.value(0), 'attrType':query.value(1)})
+ returnStruct.append(
+ {"attrName": query.value(0), "attrType": query.value(1)}
+ )
return returnStruct
- def checkAndCreatePostGISAddonsFunctions(self, useTransaction = True):
+ def checkAndCreatePostGISAddonsFunctions(self, useTransaction=True):
"""
Checks if PostGIS Add-ons functions are installed in the PostgreSQL choosed server.
If not, it creates the functions based on our git submodule (ext_dep folder)
@@ -3590,17 +4585,21 @@ def checkAndCreatePostGISAddonsFunctions(self, useTransaction = True):
sql = self.gen.checkPostGISAddonsInstallation()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem creating structure: ')+query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating structure: ") + query.lastError().text()
+ )
created = True
while query.next():
if query.value(0) == 0:
created = False
if not created:
current_dir = os.path.dirname(__file__)
- sql_file_path = os.path.join(current_dir, '..', '..', 'ext_dep', 'postgisaddon', 'postgis_addons.sql')
+ sql_file_path = os.path.join(
+ current_dir, "..", "..", "ext_dep", "postgisaddon", "postgis_addons.sql"
+ )
self.runSqlFromFile(sql_file_path, useTransaction)
- def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction = True):
+ def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction=True):
"""
Creates and populates a postgis table with features that compose the coverage layer
"""
@@ -3608,33 +4607,38 @@ def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction = Tru
if useTransaction:
self.db.transaction()
query = QSqlQuery(self.db)
- #getting srid from something like 'EPSG:31983'
- srid = coverageLayer.crs().authid().split(':')[-1]
- #complete table name
- tableName = 'validation.coverage'
+ # getting srid from something like 'EPSG:31983'
+ srid = coverageLayer.crs().authid().split(":")[-1]
+ # complete table name
+ tableName = "validation.coverage"
sql = self.gen.createCoverageTempTable(srid)
if not query.exec_(sql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating coverage temp table: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating coverage temp table: ")
+ + query.lastError().text()
+ )
for feat in coverageLayer.getFeatures():
# getting only the needed attribute values
- featid = feat['featid']
- classname = feat['classname']
+ featid = feat["featid"]
+ classname = feat["classname"]
if not feat.geometry():
continue
geometry = binascii.hexlify(feat.geometry().asWkb())
# values list and attributes list
values = [featid, classname, geometry]
- attributes = ['featid', 'classname', 'geom']
- # preparing
+ attributes = ["featid", "classname", "geom"]
+ # preparing
prepareValues = []
for attr in attributes:
- if attr == 'geom':
- prepareValues.append("""ST_SetSRID(ST_Multi(:{0}),{1})""".format(attr,str(srid)))
+ if attr == "geom":
+ prepareValues.append(
+ """ST_SetSRID(ST_Multi(:{0}),{1})""".format(attr, str(srid))
+ )
else:
- prepareValues.append(':'+attr)
- #getting sql
+ prepareValues.append(":" + attr)
+ # getting sql
insertSql = self.gen.populateTempTable(tableName, attributes, prepareValues)
query.prepare(insertSql)
# binding my values to avoid injections
@@ -3644,16 +4648,22 @@ def createAndPopulateCoverageTempTable(self, coverageLayer, useTransaction = Tru
if not query.exec_():
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem populating coverage temp table: ') + query.lastError().text())
- indexSql = self.gen.createSpatialIndex(tableName, 'geom')
+ raise Exception(
+ self.tr("Problem populating coverage temp table: ")
+ + query.lastError().text()
+ )
+ indexSql = self.gen.createSpatialIndex(tableName, "geom")
if not query.exec_(indexSql):
if useTransaction:
self.db.rollback()
- raise Exception(self.tr('Problem creating spatial index on coverage temp table: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem creating spatial index on coverage temp table: ")
+ + query.lastError().text()
+ )
if useTransaction:
- self.db.commit()
+ self.db.commit()
- def getGapsAndOverlapsRecords(self, frameTable, geomColumn, useTransaction = True):
+ def getGapsAndOverlapsRecords(self, frameTable, geomColumn, useTransaction=True):
"""
Identify gaps and overlaps in the coverage layer
"""
@@ -3663,18 +4673,24 @@ def getGapsAndOverlapsRecords(self, frameTable, geomColumn, useTransaction = Tru
sql = self.gen.checkCoverageForGapsWithFrame(frameTable, geomColumn)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting gaps: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting gaps: ") + query.lastError().text()
+ )
while query.next():
- reason = self.tr('Gap between the frame layer and coverage layer')
+ reason = self.tr("Gap between the frame layer and coverage layer")
geom = query.value(0)
- invalidCoverageRecordsList.append( (0, reason, geom) )
+ invalidCoverageRecordsList.append((0, reason, geom))
# checking for overlaps in coverage
- invalidCoverageRecordsList += self.getOverlapsRecords('validation.coverage_temp','geom','id')
+ invalidCoverageRecordsList += self.getOverlapsRecords(
+ "validation.coverage_temp", "geom", "id"
+ )
# checking for inner gaps in coverage
- invalidCoverageRecordsList += self.getGapsRecords('validation.coverage_temp','geom','id')
+ invalidCoverageRecordsList += self.getGapsRecords(
+ "validation.coverage_temp", "geom", "id"
+ )
return invalidCoverageRecordsList
- def getOverlapsRecords(self, table, geomColumn, keyColumn, useTransaction = True):
+ def getOverlapsRecords(self, table, geomColumn, keyColumn, useTransaction=True):
"""
Identify gaps and overlaps in the coverage layer
"""
@@ -3685,13 +4701,15 @@ def getOverlapsRecords(self, table, geomColumn, keyColumn, useTransaction = True
sql = self.gen.checkCoverageForOverlaps(table, geomColumn, keyColumn)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting overlaps: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting overlaps: ") + query.lastError().text()
+ )
while query.next():
- reason = self.tr('Overlap between the features of the layer')
+ reason = self.tr("Overlap between the features of the layer")
geom = query.value(0)
- invalidRecordsList.append( (0, reason, geom) )
+ invalidRecordsList.append((0, reason, geom))
return invalidRecordsList
-
+
def fillComboBoxProcessOrClasses(self, filterType=None):
"""
Returns a list of possible classes or processes
@@ -3703,29 +4721,33 @@ def fillComboBoxProcessOrClasses(self, filterType=None):
classesOrProcesses = []
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem filtering flags: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem filtering flags: ") + query.lastError().text()
+ )
classesOrProcesses.append("")
while query.next():
classesOrProcesses.append(str(query.value(0)))
return classesOrProcesses
- def getFilteredFlagsView(self, filterType=None,filteredElement=None):
+ def getFilteredFlagsView(self, filterType=None, filteredElement=None):
"""
Returns a list of flagged features accordingly to what
was chosen to filter and which element was chosen as such
- (e.g. a process named 'identifyDuplicatedGeometries')
- """
+ (e.g. a process named 'identifyDuplicatedGeometries')
+ """
self.checkAndOpenDb()
sql = self.gen.getFilteredFlagsQuery(filterType, filteredElement)
outFiltered = []
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem filtering flags: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem filtering flags: ") + query.lastError().text()
+ )
while query.next():
outFiltered.append(str(query.value(0)))
return outFiltered
- def createFilteredFlagsViewTable(self, filterType=None,filteredElement=None):
+ def createFilteredFlagsViewTable(self, filterType=None, filteredElement=None):
"""
Cretas a View Table if it doesn't exist and populates it
with data considering the users selection of filtering
@@ -3734,10 +4756,12 @@ def createFilteredFlagsViewTable(self, filterType=None,filteredElement=None):
sql = self.gen.createFilteredFlagsViewTableQuery(filterType, filteredElement)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem filtering flags: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem filtering flags: ") + query.lastError().text()
+ )
return
- def getGapsRecords(self, table, geomColumn, keyColumn, useTransaction = True):
+ def getGapsRecords(self, table, geomColumn, keyColumn, useTransaction=True):
"""
Identify gaps and overlaps in the coverage layer
"""
@@ -3748,11 +4772,13 @@ def getGapsRecords(self, table, geomColumn, keyColumn, useTransaction = True):
sql = self.gen.checkCoverageForGaps(table, geomColumn, keyColumn)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting gaps: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting gaps: ") + query.lastError().text()
+ )
while query.next():
- reason = self.tr('Gap between the features of the layer')
+ reason = self.tr("Gap between the features of the layer")
geom = query.value(0)
- invalidRecordsList.append( (0, reason, geom) )
+ invalidRecordsList.append((0, reason, geom))
return invalidRecordsList
def getNumberOfFlagsByProcess(self, processName):
@@ -3763,7 +4789,10 @@ def getNumberOfFlagsByProcess(self, processName):
sql = self.gen.getFlagsByProcess(processName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr('Problem while retrieving flags dict: ') + query.lastError().text())
+ raise Exception(
+ self.tr("Problem while retrieving flags dict: ")
+ + query.lastError().text()
+ )
nrFlags = 0
while query.next():
nrFlags += 1
@@ -3771,15 +4800,18 @@ def getNumberOfFlagsByProcess(self, processName):
def createValidationHistoryViewTable(self, idListString=None):
"""
- Creates the view table for validation processes history.
+ Creates the view table for validation processes history.
"""
self.checkAndOpenDb()
sql = self.gen.createValidationHistoryViewTableQuery(idListString=idListString)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem while retrieving validation processes history table: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem while retrieving validation processes history table: ")
+ + query.lastError().text()
+ )
return
-
+
def getValidationLog(self, idList=False):
"""
Returns a list of all logs registered for each process executed.
@@ -3788,18 +4820,21 @@ def getValidationLog(self, idList=False):
self.checkAndOpenDb()
sql = self.gen.getValidationLogQuery()
query = QSqlQuery(sql, self.db)
- log = [] # list of logs
- idL = [] # list of ID in the same order as the logs appears
+ log = [] # list of logs
+ idL = [] # list of ID in the same order as the logs appears
if not query.isActive():
- raise Exception(self.tr("Problem while retrieving validation processes history table: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem while retrieving validation processes history table: ")
+ + query.lastError().text()
+ )
while query.next():
log.append(query.value(0).encode(self.databaseEncoding))
idL.append(query.value(1))
- if idList:
+ if idList:
return log, idL
else:
return log
-
+
def getValidationHistory(self, idListString=False):
"""
Returns a list of all logs registered for each process executed.
@@ -3810,11 +4845,22 @@ def getValidationHistory(self, idListString=False):
self.checkAndOpenDb()
sql = self.gen.getValidationHistoryQuery(idListString=idListString)
query = QSqlQuery(sql, self.db)
- history = [] # list of logs
+ history = [] # list of logs
if not query.isActive():
- raise Exception(self.tr("Problem while retrieving validation processes history table: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem while retrieving validation processes history table: ")
+ + query.lastError().text()
+ )
while query.next():
- history.append([query.value(0), query.value(1), query.value(2), query.value(3), query.value(4)])
+ history.append(
+ [
+ query.value(0),
+ query.value(1),
+ query.value(2),
+ query.value(3),
+ query.value(4),
+ ]
+ )
return history
def createCompactValidationHistory(self, compactHistory):
@@ -3826,23 +4872,32 @@ def createCompactValidationHistory(self, compactHistory):
sql = self.gen.createCompactValidationHistoryQuery()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem while creating compact validation processes history table: ")+query.lastError().text())
+ raise Exception(
+ self.tr(
+ "Problem while creating compact validation processes history table: "
+ )
+ + query.lastError().text()
+ )
# table population
for log in compactHistory:
sql = self.gen.populateCompactValidationHistoryQuery(log=log)
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.rollback()
- raise Exception(self.tr("Problem while populating compact validation processes history table: ")+query.lastError().text())
+ raise Exception(
+ self.tr(
+ "Problem while populating compact validation processes history table: "
+ )
+ + query.lastError().text()
+ )
self.db.commit()
return True
def instantiateQgsVectorLayer(self, uri):
pass
-
- def setDataSourceUri(self, schema, tableName, geometryColumn, sql, pkColumm):
- uri = QgsDataSourceUri()
+ def setDataSourceUri(self, schema, tableName, geometryColumn, sql, pkColumm):
+ uri = QgsDataSourceUri()
def getLayerDict(self):
"""
@@ -3850,25 +4905,39 @@ def getLayerDict(self):
{'table_schema.table_name (geometryColumn):QgsVectorLayer'}
"""
lyrDict = dict()
- inputDict = self.getGeomColumnDictV2(excludeValidation = True)
+ inputDict = self.getGeomColumnDictV2(excludeValidation=True)
for key in list(inputDict.keys()):
- uri = self.getURIV2(inputDict[key]['tableSchema'], inputDict[key]['tableName'], inputDict[key]['geom'], '')
- lyr = QgsVectorLayer(uri.uri(), inputDict[key]['lyrName'], 'postgres', False)
- outputKey = '{0}.{1} ({2})'.format(inputDict[key]['tableSchema'], inputDict[key]['tableName'], inputDict[key]['geom'])
+ uri = self.getURIV2(
+ inputDict[key]["tableSchema"],
+ inputDict[key]["tableName"],
+ inputDict[key]["geom"],
+ "",
+ )
+ lyr = QgsVectorLayer(
+ uri.uri(), inputDict[key]["lyrName"], "postgres", False
+ )
+ outputKey = "{0}.{1} ({2})".format(
+ inputDict[key]["tableSchema"],
+ inputDict[key]["tableName"],
+ inputDict[key]["geom"],
+ )
lyrDict[outputKey] = lyr
return lyrDict
-
+
def getAttrListWithFilter(self):
self.checkAndOpenDb()
sql = self.gen.getAttrListWithFilter()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting list of attributes with filter: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting list of attributes with filter: ")
+ + query.lastError().text()
+ )
attrList = []
while query.next():
attrList.append(query.value(0))
return attrList
-
+
def getAttrFilterDomainJsonList(self, domainNameList):
self.checkAndOpenDb()
jsonDict = dict()
@@ -3877,12 +4946,15 @@ def getAttrFilterDomainJsonList(self, domainNameList):
query = QSqlQuery(sql, self.db)
localList = []
if not query.isActive():
- raise Exception(self.tr("Problem getting domain json list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting domain json list: ")
+ + query.lastError().text()
+ )
while query.next():
localList.append(json.loads(query.value(0)))
jsonDict[domainName] = localList
return jsonDict
-
+
def getFilterDict(self):
"""
returns a dict:
@@ -3894,15 +4966,23 @@ def getFilterDict(self):
sql = self.gen.getGeomTablesDomains()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
filterDict = dict()
attrList = self.getAttrListWithFilter()
jsonDict = self.getAttrFilterDomainJsonList(attrList)
while query.next():
- #parse done in parseFkQuery to make code cleaner.
- tableName, fkAttribute, domainTable, domainReferencedAttribute = self.parseFkQuery(query.value(0),query.value(1))
- if domainTable.split('.')[-1] in attrList:
- filterDict[tableName] = jsonDict[domainTable.split('.')[-1]]
+ # parse done in parseFkQuery to make code cleaner.
+ (
+ tableName,
+ fkAttribute,
+ domainTable,
+ domainReferencedAttribute,
+ ) = self.parseFkQuery(query.value(0), query.value(1))
+ if domainTable.split(".")[-1] in attrList:
+ filterDict[tableName] = jsonDict[domainTable.split(".")[-1]]
return filterDict
def databaseInfo(self):
@@ -3915,14 +4995,17 @@ def databaseInfo(self):
sql = self.gen.databaseInfo()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
out = []
while query.next():
rowDict = dict()
- rowDict['schema'] = query.value(0)
- rowDict['layer'] = query.value(1)
- rowDict['geomCol'] = query.value(2)
- rowDict['geomType'] = query.value(3)
- rowDict['srid'] = str(query.value(4))
+ rowDict["schema"] = query.value(0)
+ rowDict["layer"] = query.value(1)
+ rowDict["geomCol"] = query.value(2)
+ rowDict["geomType"] = query.value(3)
+ rowDict["srid"] = str(query.value(4))
out.append(rowDict)
return out
diff --git a/DsgTools/core/Factories/DbFactory/shapefileDb.py b/DsgTools/core/Factories/DbFactory/shapefileDb.py
index 134ee739d..08a194951 100644
--- a/DsgTools/core/Factories/DbFactory/shapefileDb.py
+++ b/DsgTools/core/Factories/DbFactory/shapefileDb.py
@@ -28,14 +28,16 @@
from .abstractDb import AbstractDb
from DsgTools.core.dsgEnums import DsgEnums
-from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory
+from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import (
+ LayerLoaderFactory,
+)
from osgeo import ogr, osr
import os, json
-class ShapefileDb(AbstractDb):
- def __init__(self, path=''):
+class ShapefileDb(AbstractDb):
+ def __init__(self, path=""):
"""
Constructor
"""
@@ -48,7 +50,7 @@ def getLayerLoader(self):
Gets the shapefile layer loader as designed in DSGTools plugin.
LAYER LOADERS SHOULD NOT be imported in abstract db. (Shapefile AbstractDb)s are
a concept extrapolation, and this is specific for this case.
- :return: (ShapefileLayerLoader) shapefile layer loader object.
+ :return: (ShapefileLayerLoader) shapefile layer loader object.
"""
# DIAMOND PROBLEM ALERT: this method requires care to be used; similar methods should be avoided!
return LayerLoaderFactory().makeLoader(iface, self)
@@ -60,12 +62,12 @@ def setLayersDict(self):
self.layerGeomCrsDict, temp = dict(), dict()
if self.databaseName():
ll = self.getLayerLoader()
- layerByNameAlias = lambda l : ll.getLayerByName(layer=l)
+ layerByNameAlias = lambda l: ll.getLayerByName(layer=l)
for shpLayer in self.getTablesFromDatabase():
temp[shpLayer] = dict()
vl = layerByNameAlias(l=shpLayer)
- temp[shpLayer]['crs'] = vl.crs()
- temp[shpLayer]['geomType'] = vl.geometryType()
+ temp[shpLayer]["crs"] = vl.crs()
+ temp[shpLayer]["geomType"] = vl.geometryType()
self.layerGeomCrsDict = temp
def __del__(self):
@@ -78,18 +80,22 @@ def __del__(self):
def isOpen(self):
"""
Checks if there is a loaded shapefile dataset (directory).
- :return: (bool) whether there is a valid dataset open.
+ :return: (bool) whether there is a valid dataset open.
"""
dn = self.databaseName()
- return dn is None or dn == ''
+ return dn is None or dn == ""
def checkAndOpenDb(self):
"""
Checks and opens the database (in this case, simply checks whether a valid path was chosen).
"""
fullpath = self.databaseName()
- if fullpath is None or fullpath == '':
- raise Exception(self.tr('Error opening database: a (valid) shapefiles path was not given.'))
+ if fullpath is None or fullpath == "":
+ raise Exception(
+ self.tr(
+ "Error opening database: a (valid) shapefiles path was not given."
+ )
+ )
# MUDAR AQUI QUANDO HOUVER MÉTODO DE LEITURA DE CAMADAS
# if :
# raise Exception(self.tr('Error opening database: ')+self.db.lastError().text())
@@ -99,7 +105,7 @@ def databaseName(self):
Gets full path for selected dataset.
:return: (str) fullpath as selected.
"""
- return self.fullpath if self.fullpath is not None else ''
+ return self.fullpath if self.fullpath is not None else ""
def getDatabaseName(self):
"""
@@ -107,9 +113,9 @@ def getDatabaseName(self):
:return: (str) dataset name.
"""
fullpath = self.databaseName()
- splitChar = '/' if '/' in fullpath else '\\'
- return fullpath.split(splitChar)[-1] if fullpath else ''
-
+ splitChar = "/" if "/" in fullpath else "\\"
+ return fullpath.split(splitChar)[-1] if fullpath else ""
+
def connectDatabase(self, conn=None):
"""
Connects to database.
@@ -119,13 +125,15 @@ def connectDatabase(self, conn=None):
self.connectDatabaseWithGui()
else:
self.setDatabaseName(conn)
-
+
def connectDatabaseWithGui(self):
"""
Connects to database using user interface dialog.
"""
fd = QFileDialog()
- filename = fd.getExistingDirectory(caption=self.tr('Select a Path to Shapefiles'))
+ filename = fd.getExistingDirectory(
+ caption=self.tr("Select a Path to Shapefiles")
+ )
filename = filename[0] if isinstance(filename, tuple) else filename
self.setDatabaseName(filename)
@@ -135,7 +143,7 @@ def setDatabaseName(self, path):
:para path: (str) path to directory containing shapefiles.
"""
self.fullpath = path
- if path != '':
+ if path != "":
# update layers dict
self.setLayersDict()
else:
@@ -143,7 +151,7 @@ def setDatabaseName(self, path):
# MUDAR AQUI O QUE FAZER QUANDO ALTERAR O NOME DA BASE DE DADOS
- def listGeomClassesFromDatabase(self, primitiveFilter = []):
+ def listGeomClassesFromDatabase(self, primitiveFilter=[]):
"""
Gets a list with geometry classes from database.
:return: (list-of-str) a list with all spatial SHP found, according to EDGV filing name standards.
@@ -156,7 +164,7 @@ def listGeomClassesFromDatabase(self, primitiveFilter = []):
# raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text())
for f in fileList:
layerName, ext = os.path.splitext(f)
- if ext.lower() != '.shp':
+ if ext.lower() != ".shp":
continue
if layerName.lower()[-2:] in ["_p", "_l", "_a"]:
classList.append(layerName)
@@ -171,7 +179,7 @@ def getTablesFromDatabase(self):
fileList = next(os.walk(self.databaseName()))[2]
for f in fileList:
layerName, ext = os.path.splitext(f)
- if ext.lower() != '.shp':
+ if ext.lower() != ".shp":
continue
classList.append(layerName)
return classList
@@ -183,10 +191,10 @@ def listComplexClassesFromDatabase(self):
self.checkAndOpenDb()
classList = []
for layerName in self.getTablesFromDatabase():
- tableSchema = layerName.split('_')[0]
- if tableSchema.lower() == 'complexos':
- classList.append(layerName)
- return classList
+ tableSchema = layerName.split("_")[0]
+ if tableSchema.lower() == "complexos":
+ classList.append(layerName)
+ return classList
def getAttributesFromLayer(self, layer, layerLoader):
"""
@@ -210,50 +218,58 @@ def getStructureDict(self):
layerLoader = self.getLayerLoader()
for shpLayer in self.getTablesFromDatabase():
schema, className = self.getTableSchema(lyr=shpLayer)
- if schema == 'complexos' or className[-2:].lower() in ['_p','_l','_a']:
+ if schema == "complexos" or className[-2:].lower() in ["_p", "_l", "_a"]:
if shpLayer not in list(classDict.keys()):
classDict[shpLayer] = dict()
# read attributes from .dbf file
attributes = []
- for att in self.getAttributesFromLayer(layer=shpLayer, layerLoader=layerLoader):
- classDict[shpLayer][att]=att
- if 'GEOMETRY' in list(classDict[shpLayer].keys()):
- classDict[shpLayer]['GEOMETRY'] = 'geom'
- elif 'geometry' in list(classDict[shpLayer].keys()):
- classDict[shpLayer]['geometry'] = 'geom'
- if 'OGC_FID' in list(classDict[shpLayer].keys()):
- classDict[shpLayer]['OGC_FID'] = 'id'
+ for att in self.getAttributesFromLayer(
+ layer=shpLayer, layerLoader=layerLoader
+ ):
+ classDict[shpLayer][att] = att
+ if "GEOMETRY" in list(classDict[shpLayer].keys()):
+ classDict[shpLayer]["GEOMETRY"] = "geom"
+ elif "geometry" in list(classDict[shpLayer].keys()):
+ classDict[shpLayer]["geometry"] = "geom"
+ if "OGC_FID" in list(classDict[shpLayer].keys()):
+ classDict[shpLayer]["OGC_FID"] = "id"
return classDict
-
- def getTableSchema(self,lyr):
+
+ def getTableSchema(self, lyr):
"""
Gets the table schema.
:param lyr: (str) layer name.
:return: (tuple-of-str) layer schema and name, in that order.
"""
- schema = lyr.split('_')[0]
- className = lyr[len(schema) + 1:]
+ schema = lyr.split("_")[0]
+ className = lyr[len(schema) + 1 :]
return (schema, className)
-
+
def getDatabaseVersion(self):
"""
Gets the database EDGV version.
"""
- edgvDict = {'213' : '2.1.3', '213pro' : '2.1.3 Pro', '213fter' : '2.1.3 FTer', '30' : '3.0', '30pro' : '3.0 Pro'}
+ edgvDict = {
+ "213": "2.1.3",
+ "213pro": "2.1.3 Pro",
+ "213fter": "2.1.3 FTer",
+ "30": "3.0",
+ "30pro": "3.0 Pro",
+ }
self.checkAndOpenDb()
- edgvVersion = 'Non EDGV'
- if 'DSGTools.edgv' in next(os.walk(self.databaseName()))[2]:
- with open(os.path.join(self.databaseName(), 'DSGTools.edgv'), 'r') as cf:
+ edgvVersion = "Non EDGV"
+ if "DSGTools.edgv" in next(os.walk(self.databaseName()))[2]:
+ with open(os.path.join(self.databaseName(), "DSGTools.edgv"), "r") as cf:
config = json.loads(cf.read())
- edgvVersion = config['edgv']
- return edgvDict[edgvVersion] if edgvVersion in edgvDict else 'Non EDGV'
+ edgvVersion = config["edgv"]
+ return edgvDict[edgvVersion] if edgvVersion in edgvDict else "Non EDGV"
# if not query.isActive():
# raise Exception(self.tr("Problem getting database version: ")+query.lastError().text())
while query.next():
version = query.value(0)
return version
-
+
def obtainLinkColumn(self, complexClass, aggregatedClass):
"""
Obtains the link column between complex and aggregated class
@@ -261,12 +277,16 @@ def obtainLinkColumn(self, complexClass, aggregatedClass):
aggregatedClass: aggregated class name
"""
self.checkAndOpenDb()
- #query to obtain the link column between the complex and the feature layer
- sql = self.gen.getLinkColumn(complexClass.replace('complexos_', ''), aggregatedClass)
+ # query to obtain the link column between the complex and the feature layer
+ sql = self.gen.getLinkColumn(
+ complexClass.replace("complexos_", ""), aggregatedClass
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem obtaining link column: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem obtaining link column: ") + query.lastError().text()
+ )
column_name = ""
while query.next():
column_name = query.value(0)
@@ -274,36 +294,42 @@ def obtainLinkColumn(self, complexClass, aggregatedClass):
def loadAssociatedFeatures(self, complex):
"""
- Loads all the features associated to the complex
+ Loads all the features associated to the complex
complex: complex class name
"""
self.checkAndOpenDb()
associatedDict = dict()
# query to get the possible links to the selected complex in the combobox
- complexName = complex.replace('complexos_', '')
+ complexName = complex.replace("complexos_", "")
sql = self.gen.getComplexLinks(complexName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem loading associated features: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem loading associated features: ")
+ + query.lastError().text()
+ )
while query.next():
- #setting the variables
+ # setting the variables
complex_schema = query.value(0)
complex = query.value(1)
aggregated_schema = query.value(2)
aggregated_class = query.value(3)
column_name = query.value(4)
-
- if aggregated_class.split('_')[-1] not in ['p', 'l', 'a']:
+
+ if aggregated_class.split("_")[-1] not in ["p", "l", "a"]:
continue
- #query to obtain the created complexes
+ # query to obtain the created complexes
sql = self.gen.getComplexData(complex_schema, complex)
complexQuery = QSqlQuery(sql, self.db)
if not complexQuery.isActive():
self.db.close()
- raise Exception(self.tr("Problem executing query: ")+complexQuery.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ")
+ + complexQuery.lastError().text()
+ )
while next(complexQuery):
complex_uuid = complexQuery.value(0)
@@ -312,20 +338,31 @@ def loadAssociatedFeatures(self, complex):
if not (complex_uuid and name):
continue
- associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [])
+ associatedDict = self.utils.buildNestedDict(
+ associatedDict, [name, complex_uuid, aggregated_class], []
+ )
- #query to obtain the id of the associated feature
- sql = self.gen.getAssociatedFeaturesData(aggregated_schema, aggregated_class, column_name, complex_uuid)
+ # query to obtain the id of the associated feature
+ sql = self.gen.getAssociatedFeaturesData(
+ aggregated_schema, aggregated_class, column_name, complex_uuid
+ )
associatedQuery = QSqlQuery(sql, self.db)
if not associatedQuery.isActive():
self.db.close()
- raise Exception(self.tr("Problem executing query: ")+associatedQuery.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ")
+ + associatedQuery.lastError().text()
+ )
while next(associatedQuery):
ogc_fid = associatedQuery.value(0)
- associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [ogc_fid])
+ associatedDict = self.utils.buildNestedDict(
+ associatedDict,
+ [name, complex_uuid, aggregated_class],
+ [ogc_fid],
+ )
return associatedDict
-
+
def isComplexClass(self, layer):
"""
Checks if a class is a complex class.
@@ -358,33 +395,35 @@ def getFrameLayerName(self):
"""
Gets the frame layer name
"""
- return 'public_aux_moldura_a'
+ return "public_aux_moldura_a"
- def getOrphanGeomTablesWithElements(self, loading = False):
+ def getOrphanGeomTablesWithElements(self, loading=False):
return []
-
+
def getOrphanGeomTables(self):
return []
-
+
def checkAndCreateStyleTable(self):
return None
- def getStylesFromDb(self,dbVersion):
+ def getStylesFromDb(self, dbVersion):
return None
def getGeomTypeDict(self, loadCentroids=False):
self.checkAndOpenDb()
geomDict = dict()
- if self.databaseName() != '' and self.layerGeomCrsDict != dict():
+ if self.databaseName() != "" and self.layerGeomCrsDict != dict():
for shpLayer in self.getTablesFromDatabase():
- geomType = self.getQgisResolvideGeomType(geometryType=self.layerGeomCrsDict[shpLayer]['geomType'])
+ geomType = self.getQgisResolvideGeomType(
+ geometryType=self.layerGeomCrsDict[shpLayer]["geomType"]
+ )
schema, layer = self.getTableSchema(lyr=shpLayer)
if geomType not in geomDict:
geomDict[geomType] = []
geomDict[geomType].append(layer)
return geomDict
-
- def getGeomDict(self, getCentroids = False):
+
+ def getGeomDict(self, getCentroids=False):
pass
"""
returns a dict like this:
@@ -393,68 +432,72 @@ def getGeomDict(self, getCentroids = False):
"""
self.checkAndOpenDb()
geomDict = dict()
- geomDict['primitivePerspective'] = self.getGeomTypeDict()
- geomDict['tablePerspective'] = dict()
- if self.databaseName() != '' and self.layerGeomCrsDict != dict():
+ geomDict["primitivePerspective"] = self.getGeomTypeDict()
+ geomDict["tablePerspective"] = dict()
+ if self.databaseName() != "" and self.layerGeomCrsDict != dict():
for shpLayer in self.getTablesFromDatabase():
- srid = self.layerGeomCrsDict[shpLayer]['crs'].authid().split(':')[-1]
- geometryType = self.layerGeomCrsDict[shpLayer]['geomType']
+ srid = self.layerGeomCrsDict[shpLayer]["crs"].authid().split(":")[-1]
+ geometryType = self.layerGeomCrsDict[shpLayer]["geomType"]
schema, layerName = self.getTableSchema(lyr=shpLayer)
# start this layer's dict and fill it up
- geomDict['tablePerspective'][layerName] = dict()
- geomDict['tablePerspective'][layerName]['schema'] = schema
- geomDict['tablePerspective'][layerName]['srid'] = str(srid)
- geomDict['tablePerspective'][layerName]['geometryColumn'] = 'N/A'
- geomDict['tablePerspective'][layerName]['geometryType'] = geometryType
- geomDict['tablePerspective'][layerName]['tableName'] = shpLayer
+ geomDict["tablePerspective"][layerName] = dict()
+ geomDict["tablePerspective"][layerName]["schema"] = schema
+ geomDict["tablePerspective"][layerName]["srid"] = str(srid)
+ geomDict["tablePerspective"][layerName]["geometryColumn"] = "N/A"
+ geomDict["tablePerspective"][layerName]["geometryType"] = geometryType
+ geomDict["tablePerspective"][layerName]["tableName"] = shpLayer
return geomDict
-
+
def getGeomColumnDict(self):
pass
"""
Dict in the form 'geomName':[-list of table names-]
"""
self.checkAndOpenDb()
- return { 'N/A' : self.listGeomClassesFromDatabase() }
+ return {"N/A": self.listGeomClassesFromDatabase()}
- def createFrame(self, type_, scale, param, paramDict = dict()):
+ def createFrame(self, type_, scale, param, paramDict=dict()):
mi, inom, frame = self.prepareCreateFrame(type_, scale, param)
self.insertFrame(scale, mi, inom, frame.asWkb())
return frame
-
+
def insertFrame(self, scale, mi, inom, frame):
self.checkAndOpenDb()
srid = self.findEPSG()
- geoSrid = QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(':')[-1]
+ geoSrid = (
+ QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(":")[-1]
+ )
ogr.UseExceptions()
outputDS = self.buildOgrDatabase()
- outputLayer=outputDS.GetLayerByName(self.getFrameLayerName())
- newFeat=ogr.Feature(outputLayer.GetLayerDefn())
+ outputLayer = outputDS.GetLayerByName(self.getFrameLayerName())
+ newFeat = ogr.Feature(outputLayer.GetLayerDefn())
auxGeom = ogr.CreateGeometryFromWkb(frame)
- #set geographic srid from frame
+ # set geographic srid from frame
geoSrs = ogr.osr.SpatialReference()
geoSrs.ImportFromEPSG(int(geoSrid))
auxGeom.AssignSpatialReference(geoSrs)
- #reproject geom
+ # reproject geom
outSpatialRef = outputLayer.GetSpatialRef()
coordTrans = osr.CoordinateTransformation(geoSrs, outSpatialRef)
auxGeom.Transform(coordTrans)
newFeat.SetGeometry(auxGeom)
- newFeat.SetField('mi', mi)
- newFeat.SetField('inom', inom)
- newFeat.SetField('escala', str(scale))
- out=outputLayer.CreateFeature(newFeat)
+ newFeat.SetField("mi", mi)
+ newFeat.SetField("inom", inom)
+ newFeat.SetField("escala", str(scale))
+ out = outputLayer.CreateFeature(newFeat)
outputDS.Destroy()
-
+
def getTableSchemaFromDb(self, table):
self.checkAndOpenDb()
for shpLayer in self.getTablesFromDatabase():
schema, layer = self.getTableSchema(lyr=shpLayer)
if table.lower() == layer.lower():
return schema
- raise Exception(self.tr("Unable to locate file '[SCHEMA]_{}.shp'.").format(table))
-
- def getGeomColumnTupleList(self, showViews = False):
+ raise Exception(
+ self.tr("Unable to locate file '[SCHEMA]_{}.shp'.").format(table)
+ )
+
+ def getGeomColumnTupleList(self, showViews=False):
"""
list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)]
centroids are hidden by default
@@ -463,8 +506,10 @@ def getGeomColumnTupleList(self, showViews = False):
geomList = []
for shpLayer in self.getTablesFromDatabase():
schema, table = self.getTableSchema(lyr=shpLayer)
- geomType = self.getQgisResolvideGeomType(geometryType=self.layerGeomCrsDict[shpLayer]['geomType'])
- geomList.append((schema, table, 'N/A', geomType, 'ESRI SHAPEFILE'))
+ geomType = self.getQgisResolvideGeomType(
+ geometryType=self.layerGeomCrsDict[shpLayer]["geomType"]
+ )
+ geomList.append((schema, table, "N/A", geomType, "ESRI SHAPEFILE"))
return geomList
def countElements(self, layers):
@@ -475,7 +520,7 @@ def countElements(self, layers):
"""
self.checkAndOpenDb()
listaQuantidades = []
- ll = lambda l : self.getLayerLoader().getLayerByName(layer=l)
+ ll = lambda l: self.getLayerLoader().getLayerByName(layer=l)
for layer in layers:
vl = ll(l=layer)
listaQuantidades.append([layer, vl.featureCount()])
@@ -502,7 +547,7 @@ def findEPSG(self, parameters=dict()):
"""
srid = None
for shp in self.layerGeomCrsDict:
- srid = self.layerGeomCrsDict[shp]['crs'].authid().split(':')[1]
+ srid = self.layerGeomCrsDict[shp]["crs"].authid().split(":")[1]
break
return int(srid)
@@ -513,29 +558,27 @@ def getQgisResolvideGeomType(self, geometryType):
:param geometryType: (int) geometry type code.
:return: (str) geometry type name.
"""
- geomDict = {
- 0 : 'POINT',
- 1 : 'LINESTRING',
- 2 : 'POLYGON'
- }
- return geomDict[geometryType] if geometryType in geomDict else ''
+ geomDict = {0: "POINT", 1: "LINESTRING", 2: "POLYGON"}
+ return geomDict[geometryType] if geometryType in geomDict else ""
def getResolvedGeomType(self, geometryType):
- geomDict = {0:'GEOMETRY',
- 1:'POINT',
- 2:'LINESTRING',
- 3:'POLYGON',
- 4:'MULTIPOINT',
- 5:'MULTILINESTRING',
- 6:'MULTIPOLYGON',
- 7:'GEOMETRYCOLLECTION',
- 8:'CIRCULARSTRING',
- 9:'COMPOUNDCURVE',
- 10:'CURVEPOLYGON',
- 11:'MULTICURVE',
- 12:'MULTISURFACE',
- 13:'CURVE',
- 14:'SURFACE'}
+ geomDict = {
+ 0: "GEOMETRY",
+ 1: "POINT",
+ 2: "LINESTRING",
+ 3: "POLYGON",
+ 4: "MULTIPOINT",
+ 5: "MULTILINESTRING",
+ 6: "MULTIPOLYGON",
+ 7: "GEOMETRYCOLLECTION",
+ 8: "CIRCULARSTRING",
+ 9: "COMPOUNDCURVE",
+ 10: "CURVEPOLYGON",
+ 11: "MULTICURVE",
+ 12: "MULTISURFACE",
+ 13: "CURVE",
+ 14: "SURFACE",
+ }
return geomDict[geometryType]
def databaseInfo(self):
@@ -547,18 +590,20 @@ def databaseInfo(self):
self.checkAndOpenDb()
out = []
ll = self.getLayerLoader()
- layerByNameAlias = lambda l : ll.getLayerByName(layer=l)
+ layerByNameAlias = lambda l: ll.getLayerByName(layer=l)
for shpLayer in self.getTablesFromDatabase():
# run through all .SHP files found (to include complexes and others non-EDGV filenames)
schema, table = self.getTableSchema(lyr=shpLayer)
vl = layerByNameAlias(l=shpLayer)
rowDict = dict()
- rowDict['schema'] = schema
- rowDict['layer'] = table
- rowDict['geomCol'] = 'N/A' # shape doesn't have geom column
+ rowDict["schema"] = schema
+ rowDict["layer"] = table
+ rowDict["geomCol"] = "N/A" # shape doesn't have geom column
# TODO: check geometry type for shapefile - such as in getResolvedGeomType, for SpatiaLite, for instance
- rowDict['geomType'] = self.getQgisResolvideGeomType(geometryType=vl.geometryType())
- rowDict['srid'] = vl.crs().authid().split(':')[-1]
+ rowDict["geomType"] = self.getQgisResolvideGeomType(
+ geometryType=vl.geometryType()
+ )
+ rowDict["srid"] = vl.crs().authid().split(":")[-1]
out.append(rowDict)
return out
@@ -567,7 +612,7 @@ def getType(self):
Gets the driver name.
:return: (str) driver name.
"""
- return 'SHP'
+ return "SHP"
def untouchedMethods(self):
"""
@@ -579,5 +624,5 @@ def untouchedMethods(self):
disassociateComplexFromComplex,
createFrame,
insertFrame,
- getResolvedGeomType
+ getResolvedGeomType,
]
diff --git a/DsgTools/core/Factories/DbFactory/spatialiteDb.py b/DsgTools/core/Factories/DbFactory/spatialiteDb.py
index be528b870..91f1f49b0 100644
--- a/DsgTools/core/Factories/DbFactory/spatialiteDb.py
+++ b/DsgTools/core/Factories/DbFactory/spatialiteDb.py
@@ -25,7 +25,7 @@
from qgis.PyQt.QtSql import QSqlQuery, QSqlDatabase
from qgis.PyQt.QtWidgets import QFileDialog
-from qgis.core import QgsCoordinateReferenceSystem
+from qgis.core import QgsCoordinateReferenceSystem
from .abstractDb import AbstractDb
from ..SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
@@ -33,150 +33,180 @@
from osgeo import ogr, osr
-class SpatialiteDb(AbstractDb):
+class SpatialiteDb(AbstractDb):
def __init__(self):
- '''
+ """
Constructor
- '''
- super(SpatialiteDb,self).__init__()
- self.db = QSqlDatabase('QSQLITE')
- self.gen = SqlGeneratorFactory().createSqlGenerator(driver=DsgEnums.DriverSpatiaLite)
+ """
+ super(SpatialiteDb, self).__init__()
+ self.db = QSqlDatabase("QSQLITE")
+ self.gen = SqlGeneratorFactory().createSqlGenerator(
+ driver=DsgEnums.DriverSpatiaLite
+ )
def closeDatabase(self):
if self.db is not None and self.db.isOpen():
self.db.close()
def getDatabaseName(self):
- '''
+ """
Gets the database name
- '''
- return self.db.databaseName().split('.sqlite')[0].split('/')[-1]
-
- def connectDatabase(self, conn = None):
- '''
+ """
+ return self.db.databaseName().split(".sqlite")[0].split("/")[-1]
+
+ def connectDatabase(self, conn=None):
+ """
Connects to database
conn: Database name
- '''
+ """
if conn is None:
self.connectDatabaseWithGui()
else:
self.db.setDatabaseName(conn)
-
+
def connectDatabaseWithGui(self):
- '''
+ """
Connects to database using user interface dialog
- '''
+ """
fd = QFileDialog()
- filename = fd.getOpenFileName(caption=self.tr('Select a DSGTools Spatialite file'),filter=self.tr('Spatialite file databases (*.sqlite)'))
+ filename = fd.getOpenFileName(
+ caption=self.tr("Select a DSGTools Spatialite file"),
+ filter=self.tr("Spatialite file databases (*.sqlite)"),
+ )
filename = filename[0] if isinstance(filename, tuple) else filename
self.db.setDatabaseName(filename)
-
- def listGeomClassesFromDatabase(self, primitiveFilter = []):
- '''
+
+ def listGeomClassesFromDatabase(self, primitiveFilter=[]):
+ """
Gets a list with geometry classes from database
- '''
+ """
self.checkAndOpenDb()
classList = []
sql = self.gen.getTablesFromDatabase()
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem listing geom classes: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem listing geom classes: ") + query.lastError().text()
+ )
while query.next():
tableName = str(query.value(0))
layerName = tableName
if tableName[-2:].lower() in ["_p", "_l", "_a"]:
classList.append(layerName)
return classList
-
+
def listComplexClassesFromDatabase(self):
- '''
+ """
Gets a list with complex classes from database
- '''
+ """
self.checkAndOpenDb()
classList = []
sql = self.gen.getTablesFromDatabase()
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem listing complex classes: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem listing complex classes: ") + query.lastError().text()
+ )
while query.next():
- tableName = str(query.value(0))
- layerName = tableName
- tableSchema = layerName.split('_')[0]
- if tableSchema == 'complexos':
- classList.append(layerName)
- return classList
+ tableName = str(query.value(0))
+ layerName = tableName
+ tableSchema = layerName.split("_")[0]
+ if tableSchema == "complexos":
+ classList.append(layerName)
+ return classList
def getStructureDict(self):
- '''
+ """
Gets database structure according to the edgv version
- '''
+ """
self.checkAndOpenDb()
classDict = dict()
- sql = self.gen.getStructure(self.getDatabaseVersion())
+ sql = self.gen.getStructure(self.getDatabaseVersion())
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem getting database structure: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting database structure: ")
+ + query.lastError().text()
+ )
while query.next():
className = str(query.value(0))
classSql = str(query.value(1))
- if className.split('_')[0] == 'complexos' or className.split('_')[-1] in ['p','l','a']:
+ if className.split("_")[0] == "complexos" or className.split("_")[-1] in [
+ "p",
+ "l",
+ "a",
+ ]:
if className not in list(classDict.keys()):
- classDict[className]=dict()
+ classDict[className] = dict()
classSql = classSql.split(className)[1]
- sqlList = classSql.replace('(','').replace(')','').replace('\"','').replace('\'','').split(',')
+ sqlList = (
+ classSql.replace("(", "")
+ .replace(")", "")
+ .replace('"', "")
+ .replace("'", "")
+ .split(",")
+ )
for s in sqlList:
- fieldName = str(s.strip().split(' ')[0])
- classDict[className][fieldName]=fieldName
+ fieldName = str(s.strip().split(" ")[0])
+ classDict[className][fieldName] = fieldName
- if 'GEOMETRY' in list(classDict[className].keys()):
- classDict[className]['GEOMETRY'] = 'geom'
- if 'geometry' in list(classDict[className].keys()):
- classDict[className]['geometry'] = 'geom'
- if 'OGC_FID' in list(classDict[className].keys()):
- classDict[className]['OGC_FID'] = 'id'
+ if "GEOMETRY" in list(classDict[className].keys()):
+ classDict[className]["GEOMETRY"] = "geom"
+ if "geometry" in list(classDict[className].keys()):
+ classDict[className]["geometry"] = "geom"
+ if "OGC_FID" in list(classDict[className].keys()):
+ classDict[className]["OGC_FID"] = "id"
return classDict
-
+
def makeOgrConn(self):
- '''
+ """
Makes a connection string for spatialite databases (e.g just the name)
- '''
+ """
constring = self.db.databaseName()
return constring
def validateWithOutputDatabaseSchema(self, outputAbstractDb):
- '''
+ """
Validates the conversion with the output database.
It generates a dictionary (invalidated) that stores conversion problems
- '''
+ """
self.checkAndOpenDb()
invalidated = self.buildInvalidatedDict()
inputdbStructure = self.getStructureDict()
outputdbStructure = outputAbstractDb.getStructureDict()
domainDict = outputAbstractDb.getDomainDict()
- classes = self.listClassesWithElementsFromDatabase()
+ classes = self.listClassesWithElementsFromDatabase()
notNullDict = outputAbstractDb.getNotNullDict()
-
+
for inputClass in list(classes.keys()):
- outputClass = self.translateAbstractDbLayerNameToOutputFormat(inputClass,outputAbstractDb)
- (schema,className) = self.getTableSchema(inputClass)
+ outputClass = self.translateAbstractDbLayerNameToOutputFormat(
+ inputClass, outputAbstractDb
+ )
+ (schema, className) = self.getTableSchema(inputClass)
if outputClass in list(outputdbStructure.keys()):
- outputAttrList = self.reorderTupleList(list(outputdbStructure[outputClass].keys()))
- inputAttrList = self.reorderTupleList(list(inputdbStructure[inputClass].keys()))
-
- sql = self.gen.getFeaturesWithSQL(inputClass,inputAttrList)
+ outputAttrList = self.reorderTupleList(
+ list(outputdbStructure[outputClass].keys())
+ )
+ inputAttrList = self.reorderTupleList(
+ list(inputdbStructure[inputClass].keys())
+ )
+
+ sql = self.gen.getFeaturesWithSQL(inputClass, inputAttrList)
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem executing query: ")+query.lastError().text())
-
+ raise Exception(
+ self.tr("Problem executing query: ") + query.lastError().text()
+ )
+
while query.next():
id = query.value(0)
- #detects null lines
+ # detects null lines
for i in range(len(inputAttrList)):
nullLine = True
value = query.value(i)
@@ -184,112 +214,208 @@ def validateWithOutputDatabaseSchema(self, outputAbstractDb):
nullLine = False
break
if nullLine:
- if cl not in list(invalidated['nullLine'].keys()):
- invalidated['nullLine'][inputClass]=0
- invalidated['nullLine'][inputClass]+=1
-
- #validates pks
+ if cl not in list(invalidated["nullLine"].keys()):
+ invalidated["nullLine"][inputClass] = 0
+ invalidated["nullLine"][inputClass] += 1
+
+ # validates pks
if id == None and (not nullLine):
- if cl not in list(invalidated['nullPk'].keys()):
- invalidated['nullPk'][inputClass]=0
- invalidated['nullPk'][inputClass]+=1
-
+ if cl not in list(invalidated["nullPk"].keys()):
+ invalidated["nullPk"][inputClass] = 0
+ invalidated["nullPk"][inputClass] += 1
+
for i in range(len(inputAttrList)):
value = query.value(i)
- #validates domain
- if outputClass in list(domainDict.keys()):
+ # validates domain
+ if outputClass in list(domainDict.keys()):
if inputAttrList[i] in list(domainDict[outputClass].keys()):
- if value not in domainDict[outputClass][inputAttrList[i]] and (not nullLine):
- invalidated = self.utils.buildNestedDict(invalidated, ['notInDomain',inputClass,id,inputAttrList[i]], value)
- #validates not nulls
+ if value not in domainDict[outputClass][
+ inputAttrList[i]
+ ] and (not nullLine):
+ invalidated = self.utils.buildNestedDict(
+ invalidated,
+ [
+ "notInDomain",
+ inputClass,
+ id,
+ inputAttrList[i],
+ ],
+ value,
+ )
+ # validates not nulls
if outputClass in list(notNullDict.keys()):
if outputClass in list(domainDict.keys()):
- if inputAttrList[i] in notNullDict[outputClass] and inputAttrList[i] not in list(domainDict[outputClass].keys()):
- if (value == None) and (not nullLine) and (inputAttrList[i] not in list(domainDict[outputClass].keys())):
- invalidated = self.utils.buildNestedDict(invalidated, ['nullAttribute',inputClass,id,inputAttrList[i]], value)
+ if inputAttrList[i] in notNullDict[
+ outputClass
+ ] and inputAttrList[i] not in list(
+ domainDict[outputClass].keys()
+ ):
+ if (
+ (value == None)
+ and (not nullLine)
+ and (
+ inputAttrList[i]
+ not in list(domainDict[outputClass].keys())
+ )
+ ):
+ invalidated = self.utils.buildNestedDict(
+ invalidated,
+ [
+ "nullAttribute",
+ inputClass,
+ id,
+ inputAttrList[i],
+ ],
+ value,
+ )
else:
if inputAttrList[i] in notNullDict[outputClass]:
try:
if value.isNull():
- invalidated = self.utils.buildNestedDict(invalidated, ['nullAttribute',inputClass,id,inputAttrList[i]], value)
+ invalidated = self.utils.buildNestedDict(
+ invalidated,
+ [
+ "nullAttribute",
+ inputClass,
+ id,
+ inputAttrList[i],
+ ],
+ value,
+ )
except:
- if (value == None) and (not nullLine) and (inputAttrList[i] not in list(domainDict[outputClass].keys())):
- invalidated = self.utils.buildNestedDict(invalidated, ['nullAttribute',inputClass,id,inputAttrList[i]], value)
+ if (
+ (value == None)
+ and (not nullLine)
+ and (
+ inputAttrList[i]
+ not in list(
+ domainDict[outputClass].keys()
+ )
+ )
+ ):
+ invalidated = self.utils.buildNestedDict(
+ invalidated,
+ [
+ "nullAttribute",
+ inputClass,
+ id,
+ inputAttrList[i],
+ ],
+ value,
+ )
if outputClass in list(domainDict.keys()):
- if (inputAttrList[i] not in ['geom','GEOMETRY','geometry','id','OGC_FID'] and schema != 'complexos') or (schema == 'complexos' and inputAttrList[i] != 'id'):
- if inputAttrList[i] not in list(outputdbStructure[outputClass].keys()):
- invalidated = self.utils.buildNestedDict(invalidated, ['attributeNotFoundInOutput',inputClass], [inputAttrList[i]])
- #validates fk field
- if 'id_' == inputAttrList[0:3]:
+ if (
+ inputAttrList[i]
+ not in ["geom", "GEOMETRY", "geometry", "id", "OGC_FID"]
+ and schema != "complexos"
+ ) or (schema == "complexos" and inputAttrList[i] != "id"):
+ if inputAttrList[i] not in list(
+ outputdbStructure[outputClass].keys()
+ ):
+ invalidated = self.utils.buildNestedDict(
+ invalidated,
+ ["attributeNotFoundInOutput", inputClass],
+ [inputAttrList[i]],
+ )
+ # validates fk field
+ if "id_" == inputAttrList[0:3]:
if not self.validateUUID(value):
- if inputAttrList[i] not in list(outputdbStructure[outputClass].keys()):
- invalidated = self.utils.buildNestedDict(invalidated, ['nullComplexFk',inputClass], [inputAttrList[i]])
+ if inputAttrList[i] not in list(
+ outputdbStructure[outputClass].keys()
+ ):
+ invalidated = self.utils.buildNestedDict(
+ invalidated,
+ ["nullComplexFk", inputClass],
+ [inputAttrList[i]],
+ )
else:
- invalidated['classNotFoundInOutput'].append(inputAttrList)
+ invalidated["classNotFoundInOutput"].append(inputAttrList)
return invalidated
-
+
def translateAbstractDbLayerNameToOutputFormat(self, lyr, outputAbstractDb):
- '''
+ """
Translates abstractdb layer name to output format
lyr: layer name that will be translated
outputAbstractDb: output database
- '''
- if outputAbstractDb.db.driverName() == 'QSQLITE':
+ """
+ if outputAbstractDb.db.driverName() == "QSQLITE":
return lyr
- if outputAbstractDb.db.driverName() == 'QPSQL':
- return str(lyr.split('_')[0]+'.'+'_'.join(lyr.split('_')[1::]))
-
+ if outputAbstractDb.db.driverName() == "QPSQL":
+ return str(lyr.split("_")[0] + "." + "_".join(lyr.split("_")[1::]))
+
def translateOGRLayerNameToOutputFormat(self, lyr, ogrOutput):
- '''
+ """
Translates ogr layer name to output format
lyr: layer name that will be translated
ogrOutput: ogr output
- '''
- if ogrOutput.GetDriver().name == 'SQLite':
+ """
+ if ogrOutput.GetDriver().name == "SQLite":
return lyr
- if ogrOutput.GetDriver().name == 'PostgreSQL':
- return str(lyr.split('_')[0]+'.'+'_'.join(lyr.split('_')[1::]))
-
- def getTableSchema(self,lyr):
- '''
+ if ogrOutput.GetDriver().name == "PostgreSQL":
+ return str(lyr.split("_")[0] + "." + "_".join(lyr.split("_")[1::]))
+
+ def getTableSchema(self, lyr):
+ """
Gets the table schema
lyr: layer name
- '''
- schema = lyr.split('_')[0]
- className = '_'.join(lyr.split('_')[1::])
+ """
+ schema = lyr.split("_")[0]
+ className = "_".join(lyr.split("_")[1::])
return (schema, className)
-
+
def convertToPostgis(self, outputAbstractDb, type=None):
- '''
+ """
Converts this to a postgis database
outputAbstractDb: postgis output
type: conversion type
- '''
- (inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict) = self.prepareForConversion(outputAbstractDb)
+ """
+ (
+ inputOgrDb,
+ outputOgrDb,
+ fieldMap,
+ inputLayerList,
+ errorDict,
+ ) = self.prepareForConversion(outputAbstractDb)
invalidated = self.validateWithOutputDatabaseSchema(outputAbstractDb)
hasErrors = self.makeValidationSummary(invalidated)
- if type == 'untouchedData':
+ if type == "untouchedData":
if hasErrors:
- self.signals.updateLog.emit('\n\n\n'+self.tr('Conversion not perfomed due to validation errors! Check log above for more information.'))
+ self.signals.updateLog.emit(
+ "\n\n\n"
+ + self.tr(
+ "Conversion not perfomed due to validation errors! Check log above for more information."
+ )
+ )
return False
else:
- status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict)
+ status = self.translateDS(
+ inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict
+ )
return status
- if type == 'fixData':
+ if type == "fixData":
if hasErrors:
- status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict, invalidated)
+ status = self.translateDS(
+ inputOgrDb,
+ outputOgrDb,
+ fieldMap,
+ inputLayerList,
+ errorDict,
+ invalidated,
+ )
return status
else:
- status = self.translateDS(inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict)
+ status = self.translateDS(
+ inputOgrDb, outputOgrDb, fieldMap, inputLayerList, errorDict
+ )
return status
return False
-
+
def getDatabaseVersion(self):
- '''
+ """
Gets the database version
- '''
+ """
self.checkAndOpenDb()
- version = '2.1.3'
+ version = "2.1.3"
sql = self.gen.getEDGVVersion()
query = QSqlQuery(sql, self.db)
# if not query.isActive():
@@ -297,57 +423,67 @@ def getDatabaseVersion(self):
while query.next():
version = query.value(0)
return version
-
+
def obtainLinkColumn(self, complexClass, aggregatedClass):
- '''
+ """
Obtains the link column between complex and aggregated class
complexClass: complex class name
aggregatedClass: aggregated class name
- '''
+ """
self.checkAndOpenDb()
- #query to obtain the link column between the complex and the feature layer
- sql = self.gen.getLinkColumn(complexClass.replace('complexos_', ''), aggregatedClass)
+ # query to obtain the link column between the complex and the feature layer
+ sql = self.gen.getLinkColumn(
+ complexClass.replace("complexos_", ""), aggregatedClass
+ )
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem obtaining link column: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem obtaining link column: ") + query.lastError().text()
+ )
column_name = ""
while query.next():
column_name = query.value(0)
return column_name
def loadAssociatedFeatures(self, complex):
- '''
- Loads all the features associated to the complex
+ """
+ Loads all the features associated to the complex
complex: complex class name
- '''
+ """
self.checkAndOpenDb()
associatedDict = dict()
- #query to get the possible links to the selected complex in the combobox
- complexName = complex.replace('complexos_', '')
+ # query to get the possible links to the selected complex in the combobox
+ complexName = complex.replace("complexos_", "")
sql = self.gen.getComplexLinks(complexName)
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem loading associated features: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem loading associated features: ")
+ + query.lastError().text()
+ )
while query.next():
- #setting the variables
+ # setting the variables
complex_schema = query.value(0)
complex = query.value(1)
aggregated_schema = query.value(2)
aggregated_class = query.value(3)
column_name = query.value(4)
-
- if aggregated_class.split('_')[-1] not in ['p', 'l', 'a']:
+
+ if aggregated_class.split("_")[-1] not in ["p", "l", "a"]:
continue
- #query to obtain the created complexes
+ # query to obtain the created complexes
sql = self.gen.getComplexData(complex_schema, complex)
complexQuery = QSqlQuery(sql, self.db)
if not complexQuery.isActive():
self.db.close()
- raise Exception(self.tr("Problem executing query: ")+complexQuery.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ")
+ + complexQuery.lastError().text()
+ )
while next(complexQuery):
complex_uuid = complexQuery.value(0)
@@ -356,54 +492,73 @@ def loadAssociatedFeatures(self, complex):
if not (complex_uuid and name):
continue
- associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [])
+ associatedDict = self.utils.buildNestedDict(
+ associatedDict, [name, complex_uuid, aggregated_class], []
+ )
- #query to obtain the id of the associated feature
- sql = self.gen.getAssociatedFeaturesData(aggregated_schema, aggregated_class, column_name, complex_uuid)
+ # query to obtain the id of the associated feature
+ sql = self.gen.getAssociatedFeaturesData(
+ aggregated_schema, aggregated_class, column_name, complex_uuid
+ )
associatedQuery = QSqlQuery(sql, self.db)
if not associatedQuery.isActive():
self.db.close()
- raise Exception(self.tr("Problem executing query: ")+associatedQuery.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ")
+ + associatedQuery.lastError().text()
+ )
while next(associatedQuery):
ogc_fid = associatedQuery.value(0)
- associatedDict = self.utils.buildNestedDict(associatedDict, [name, complex_uuid, aggregated_class], [ogc_fid])
+ associatedDict = self.utils.buildNestedDict(
+ associatedDict,
+ [name, complex_uuid, aggregated_class],
+ [ogc_fid],
+ )
return associatedDict
-
+
def isComplexClass(self, className):
- '''
+ """
Checks if a class is a complex class
className: class name to be checked
- '''
+ """
self.checkAndOpenDb()
- #getting all complex tables
+ # getting all complex tables
query = QSqlQuery(self.gen.getComplexTablesFromDatabase(), self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem executing query: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem executing query: ") + query.lastError().text()
+ )
while query.next():
- if query.value(0) == 'complexos_'+className:
+ if query.value(0) == "complexos_" + className:
return True
return False
def disassociateComplexFromComplex(self, aggregated_class, link_column, id):
- '''
+ """
Disassociates a complex from another complex
aggregated_class: aggregated class that will be disassociated
link_column: link column between complex and its aggregated class
id: complex id (uid) to be disassociated
- '''
- sql = self.gen.disassociateComplexFromComplex('complexos_'+aggregated_class, link_column, id)
+ """
+ sql = self.gen.disassociateComplexFromComplex(
+ "complexos_" + aggregated_class, link_column, id
+ )
query = QSqlQuery(self.db)
if not query.exec_(sql):
self.db.close()
- raise Exception(self.tr('Problem disassociating complex from complex: ') + '\n' + query.lastError().text())
+ raise Exception(
+ self.tr("Problem disassociating complex from complex: ")
+ + "\n"
+ + query.lastError().text()
+ )
def getTablesFromDatabase(self):
- '''
+ """
Gets all tables from database
- '''
+ """
self.checkAndOpenDb()
ret = []
@@ -411,29 +566,32 @@ def getTablesFromDatabase(self):
query = QSqlQuery(sql, self.db)
if not query.isActive():
self.db.close()
- raise Exception(self.tr("Problem getting tables from database: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting tables from database: ")
+ + query.lastError().text()
+ )
while query.next():
- #table name
+ # table name
ret.append(query.value(0))
return ret
def getFrameLayerName(self):
- '''
+ """
Gets the frame layer name
- '''
- return 'public_aux_moldura_a'
+ """
+ return "public_aux_moldura_a"
- def getOrphanGeomTablesWithElements(self, loading = False):
+ def getOrphanGeomTablesWithElements(self, loading=False):
return []
-
+
def getOrphanGeomTables(self):
return []
-
+
def checkAndCreateStyleTable(self):
return None
- def getStylesFromDb(self,dbVersion):
+ def getStylesFromDb(self, dbVersion):
return None
def getGeomTypeDict(self, loadCentroids=False):
@@ -442,114 +600,128 @@ def getGeomTypeDict(self, loadCentroids=False):
sql = self.gen.getGeomByPrimitive(edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom types from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom types from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
while query.next():
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
type = query.value(0)
else:
type = self.getResolvedGeomType(query.value(0))
tableName = query.value(1)
- layerName = '_'.join(tableName.split('_')[1::])
+ layerName = "_".join(tableName.split("_")[1::])
if type not in list(geomDict.keys()):
geomDict[type] = []
if layerName not in geomDict[type]:
geomDict[type].append(layerName)
return geomDict
-
- def getGeomDict(self, getCentroids = False):
- '''
+
+ def getGeomDict(self, getCentroids=False):
+ """
returns a dict like this:
{'tablePerspective' : {
'layerName' :
- '''
+ """
self.checkAndOpenDb()
edgvVersion = self.getDatabaseVersion()
sql = self.gen.getGeomTablesFromGeometryColumns(edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tables from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tables from db: ")
+ + query.lastError().text()
+ )
geomDict = dict()
- geomDict['primitivePerspective'] = self.getGeomTypeDict()
- geomDict['tablePerspective'] = dict()
+ geomDict["primitivePerspective"] = self.getGeomTypeDict()
+ geomDict["tablePerspective"] = dict()
while query.next():
isCentroid = False
srid = query.value(0)
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
geometryType = query.value(2)
else:
geometryType = self.getResolvedGeomType(query.value(2))
tableName = query.value(3)
- tableSchema = tableName.split('_')[0]
+ tableSchema = tableName.split("_")[0]
geometryColumn = query.value(1)
- layerName = '_'.join(tableName.split('_')[1::])
- if layerName not in list(geomDict['tablePerspective'].keys()):
- geomDict['tablePerspective'][layerName] = dict()
- geomDict['tablePerspective'][layerName]['schema'] = tableSchema
- geomDict['tablePerspective'][layerName]['srid'] = str(srid)
- geomDict['tablePerspective'][layerName]['geometryColumn'] = geometryColumn
- geomDict['tablePerspective'][layerName]['geometryType'] = geometryType
- geomDict['tablePerspective'][layerName]['tableName'] = tableName
+ layerName = "_".join(tableName.split("_")[1::])
+ if layerName not in list(geomDict["tablePerspective"].keys()):
+ geomDict["tablePerspective"][layerName] = dict()
+ geomDict["tablePerspective"][layerName]["schema"] = tableSchema
+ geomDict["tablePerspective"][layerName]["srid"] = str(srid)
+ geomDict["tablePerspective"][layerName][
+ "geometryColumn"
+ ] = geometryColumn
+ geomDict["tablePerspective"][layerName]["geometryType"] = geometryType
+ geomDict["tablePerspective"][layerName]["tableName"] = tableName
return geomDict
-
+
def getGeomColumnDict(self):
- '''
+ """
Dict in the form 'geomName':[-list of table names-]
- '''
+ """
self.checkAndOpenDb()
sql = self.gen.getGeomColumnDict()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom column dict: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom column dict: ") + query.lastError().text()
+ )
geomDict = dict()
while query.next():
geomColumn = query.value(0)
tableName = query.value(1)
- lyrName = '_'.join(tableName.split('_')[1::])
+ lyrName = "_".join(tableName.split("_")[1::])
if geomColumn not in list(geomDict.keys()):
geomDict[geomColumn] = []
geomDict[geomColumn].append(lyrName)
return geomDict
- def createFrame(self, type, scale, param, paramDict = dict()):
+ def createFrame(self, type, scale, param, paramDict=dict()):
mi, inom, frame = self.prepareCreateFrame(type, scale, param)
self.insertFrame(scale, mi, inom, frame.asWkb())
return frame
-
+
def insertFrame(self, scale, mi, inom, frame):
self.checkAndOpenDb()
srid = self.findEPSG()
- geoSrid = QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(':')[-1]
+ geoSrid = (
+ QgsCoordinateReferenceSystem(int(srid)).geographicCRSAuthId().split(":")[-1]
+ )
ogr.UseExceptions()
outputDS = self.buildOgrDatabase()
- outputLayer=outputDS.GetLayerByName('public_aux_moldura_a')
- newFeat=ogr.Feature(outputLayer.GetLayerDefn())
+ outputLayer = outputDS.GetLayerByName("public_aux_moldura_a")
+ newFeat = ogr.Feature(outputLayer.GetLayerDefn())
auxGeom = ogr.CreateGeometryFromWkb(frame)
- #set geographic srid from frame
+ # set geographic srid from frame
geoSrs = ogr.osr.SpatialReference()
geoSrs.ImportFromEPSG(int(geoSrid))
auxGeom.AssignSpatialReference(geoSrs)
- #reproject geom
+ # reproject geom
outSpatialRef = outputLayer.GetSpatialRef()
coordTrans = osr.CoordinateTransformation(geoSrs, outSpatialRef)
auxGeom.Transform(coordTrans)
newFeat.SetGeometry(auxGeom)
- newFeat.SetField('mi', mi)
- newFeat.SetField('inom', inom)
- newFeat.SetField('escala', str(scale))
- out=outputLayer.CreateFeature(newFeat)
+ newFeat.SetField("mi", mi)
+ newFeat.SetField("inom", inom)
+ newFeat.SetField("escala", str(scale))
+ out = outputLayer.CreateFeature(newFeat)
outputDS.Destroy()
-
+
def getTableSchemaFromDb(self, table):
self.checkAndOpenDb()
sql = self.gen.getFullTablesName(table)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting full table name: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting full table name: ") + query.lastError().text()
+ )
while query.next():
- return query.value(0).split('_')[0]
-
- def getGeomColumnTupleList(self, showViews = False):
+ return query.value(0).split("_")[0]
+
+ def getGeomColumnTupleList(self, showViews=False):
"""
list in the format [(table_schema, table_name, geometryColumn, geometryType, tableType)]
centroids are hidden by default
@@ -559,31 +731,51 @@ def getGeomColumnTupleList(self, showViews = False):
sql = self.gen.getGeomColumnTupleList(edgvVersion)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tuple list: ") + query.lastError().text()
+ )
geomList = []
while query.next():
- if edgvVersion in ['2.1.3','FTer_2a_Ed']:
- geomList.append((query.value(0).split('_')[0], '_'.join(query.value(0).split('_')[1::]), query.value(1), query.value(2), 'BASE TABLE'))
+ if edgvVersion in ["2.1.3", "FTer_2a_Ed"]:
+ geomList.append(
+ (
+ query.value(0).split("_")[0],
+ "_".join(query.value(0).split("_")[1::]),
+ query.value(1),
+ query.value(2),
+ "BASE TABLE",
+ )
+ )
else:
- geomList.append((query.value(0).split('_')[0], '_'.join(query.value(0).split('_')[1::]), query.value(1), self.getResolvedGeomType(int(query.value(2))), 'BASE TABLE'))
+ geomList.append(
+ (
+ query.value(0).split("_")[0],
+ "_".join(query.value(0).split("_")[1::]),
+ query.value(1),
+ self.getResolvedGeomType(int(query.value(2))),
+ "BASE TABLE",
+ )
+ )
return geomList
-
+
def getResolvedGeomType(self, geometryType):
- geomDict = {0:'GEOMETRY',
- 1:'POINT',
- 2:'LINESTRING',
- 3:'POLYGON',
- 4:'MULTIPOINT',
- 5:'MULTILINESTRING',
- 6:'MULTIPOLYGON',
- 7:'GEOMETRYCOLLECTION',
- 8:'CIRCULARSTRING',
- 9:'COMPOUNDCURVE',
- 10:'CURVEPOLYGON',
- 11:'MULTICURVE',
- 12:'MULTISURFACE',
- 13:'CURVE',
- 14:'SURFACE'}
+ geomDict = {
+ 0: "GEOMETRY",
+ 1: "POINT",
+ 2: "LINESTRING",
+ 3: "POLYGON",
+ 4: "MULTIPOINT",
+ 5: "MULTILINESTRING",
+ 6: "MULTIPOLYGON",
+ 7: "GEOMETRYCOLLECTION",
+ 8: "CIRCULARSTRING",
+ 9: "COMPOUNDCURVE",
+ 10: "CURVEPOLYGON",
+ 11: "MULTICURVE",
+ 12: "MULTISURFACE",
+ 13: "CURVE",
+ 14: "SURFACE",
+ }
return geomDict[geometryType]
def databaseInfo(self):
@@ -596,15 +788,18 @@ def databaseInfo(self):
sql = self.gen.databaseInfo()
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom schemas from db: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom schemas from db: ")
+ + query.lastError().text()
+ )
out = []
while query.next():
rowDict = dict()
- rowDict['schema'] = query.value(0).split('_')[0]
- rowDict['layer'] = query.value(0)[len(rowDict['schema']) + 1 :]
- rowDict['geomCol'] = query.value(1)
- rowDict['geomType'] = query.value(2)
- rowDict['srid'] = str(query.value(3))
+ rowDict["schema"] = query.value(0).split("_")[0]
+ rowDict["layer"] = query.value(0)[len(rowDict["schema"]) + 1 :]
+ rowDict["geomCol"] = query.value(1)
+ rowDict["geomType"] = query.value(2)
+ rowDict["srid"] = str(query.value(3))
out.append(rowDict)
return out
@@ -619,7 +814,9 @@ def tableFields(self, table):
sql = self.gen.tableFields(table)
query = QSqlQuery(sql, self.db)
if not query.isActive():
- raise Exception(self.tr("Problem getting geom tuple list: ")+query.lastError().text())
+ raise Exception(
+ self.tr("Problem getting geom tuple list: ") + query.lastError().text()
+ )
while query.next():
attrs.append(query.value(1))
return attrs
diff --git a/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py
index 113197c74..bc73ed7e2 100644
--- a/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py
+++ b/DsgTools/core/Factories/LayerLoaderFactory/edgvLayerLoader.py
@@ -23,13 +23,15 @@
from collections import defaultdict
import os
-from qgis.core import (Qgis,
- QgsField,
- QgsWkbTypes,
- QgsMessageLog,
- QgsVectorLayer,
- QgsDataSourceUri,
- QgsVectorLayerJoinInfo)
+from qgis.core import (
+ Qgis,
+ QgsField,
+ QgsWkbTypes,
+ QgsMessageLog,
+ QgsVectorLayer,
+ QgsDataSourceUri,
+ QgsVectorLayerJoinInfo,
+)
from qgis.utils import iface
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.Qt import QObject
@@ -37,41 +39,63 @@
from DsgTools.core.Utils.utils import Utils
+
class EDGVLayerLoader(QObject):
-
def __init__(self, iface, abstractDb, loadCentroids):
"""Constructor."""
super(EDGVLayerLoader, self).__init__()
-
+
self.abstractDb = abstractDb
- self.uri = QgsDataSourceUri()
+ self.uri = QgsDataSourceUri()
self.iface = iface
self.utils = Utils()
self.logErrorDict = dict()
- self.errorLog = ''
+ self.errorLog = ""
self.geomTypeDict = self.abstractDb.getGeomTypeDict(loadCentroids)
self.geomDict = self.abstractDb.getGeomDict(self.geomTypeDict)
- self.correspondenceDict = {'POINT':'Point', 'MULTIPOINT':'Point', 'LINESTRING':'Line','MULTILINESTRING':'Line', 'POLYGON':'Area', 'MULTIPOLYGON':'Area'}
-
+ self.correspondenceDict = {
+ "POINT": "Point",
+ "MULTIPOINT": "Point",
+ "LINESTRING": "Line",
+ "MULTILINESTRING": "Line",
+ "POLYGON": "Area",
+ "MULTIPOLYGON": "Area",
+ }
+
def preLoadStep(self, inputList):
if len(inputList) == 0:
return [], False
else:
if isinstance(inputList[0], dict):
- lyrList = [i['tableName'] for i in inputList]
+ lyrList = [i["tableName"] for i in inputList]
return lyrList, True
else:
return inputList, False
- def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], isEdgv=True, customForm=False, loadEditingStructure=False, parent=None):
+ def load(
+ self,
+ inputList,
+ useQml=False,
+ uniqueLoad=False,
+ useInheritance=False,
+ stylePath=None,
+ onlyWithElements=False,
+ geomFilterList=[],
+ isEdgv=True,
+ customForm=False,
+ loadEditingStructure=False,
+ parent=None,
+ ):
return None
-
+
def getStyle(self, stylePath, className):
- if 'db:' in stylePath['style']:
- return self.abstractDb.getStyle(stylePath['style'].split(':')[-1], className)
+ if "db:" in stylePath["style"]:
+ return self.abstractDb.getStyle(
+ stylePath["style"].split(":")[-1], className
+ )
else:
- return self.getStyleFromFile(stylePath['style'], className)
-
+ return self.getStyleFromFile(stylePath["style"], className)
+
def getStyleFromFile(self, stylePath, className):
styleName = "{0}.qml".format(className)
if styleName.lower() in [f.lower() for f in os.listdir(stylePath)]:
@@ -79,34 +103,40 @@ def getStyleFromFile(self, stylePath, className):
# dsgtools have the right to write on its own directory
# a temporary file "temp.qml"
tempPath = os.path.join(stylePath, "temp.qml")
- with open(tempPath, "w", encoding='utf-8') as f:
+ with open(tempPath, "w", encoding="utf-8") as f:
f.writelines(qml)
f.close()
return tempPath
else:
return None
-
+
def prepareLoad(self):
dbName = self.abstractDb.getDatabaseName()
- groupList = iface.legendInterface().groups()
+ groupList = iface.legendInterface().groups()
if dbName in groupList:
return groupList.index(dbName)
else:
- parentTreeNode = iface.legendInterface().addGroup(self.abstractDb.getDatabaseName(), -1)
+ parentTreeNode = iface.legendInterface().addGroup(
+ self.abstractDb.getDatabaseName(), -1
+ )
return parentTreeNode
def createMeasureColumn(self, layer):
if layer.geometryType() == QgsWkbTypes.PolygonGeometry:
- layer.addExpressionField('$area', QgsField(self.tr('area_otf'), QVariant.Double))
+ layer.addExpressionField(
+ "$area", QgsField(self.tr("area_otf"), QVariant.Double)
+ )
elif layer.geometryType() == QgsWkbTypes.LineGeometry:
- layer.addExpressionField('$length', QgsField(self.tr('length_otf'), QVariant.Double))
+ layer.addExpressionField(
+ "$length", QgsField(self.tr("length_otf"), QVariant.Double)
+ )
return layer
-
+
def getDatabaseGroup(self, rootNode):
dbName = self.abstractDb.getDatabaseName()
return self.createGroup(dbName, rootNode)
- def getLyrDict(self, inputList, isEdgv = True):
+ def getLyrDict(self, inputList, isEdgv=True):
"""
Builds lyrDict in order to build loading tree
lyrList: list of layers to be loaded
@@ -114,21 +144,26 @@ def getLyrDict(self, inputList, isEdgv = True):
"""
lyrDict = defaultdict(lambda: defaultdict(list))
if isinstance(inputList, list) and len(inputList) > 0:
- if isinstance(inputList[0],dict):
+ if isinstance(inputList[0], dict):
for elem in inputList:
- if elem['geomType'] == 'GEOMETRY':
+ if elem["geomType"] == "GEOMETRY":
continue
- lyrDict[self.correspondenceDict[elem['geomType']]][elem['cat']].append(elem)
+ lyrDict[self.correspondenceDict[elem["geomType"]]][
+ elem["cat"]
+ ].append(elem)
else:
for type in list(self.geomTypeDict.keys()):
# some tables are only registered as GEOMETRY and should not be considered
- if type == 'GEOMETRY':
+ if type == "GEOMETRY":
continue
for lyr in self.geomTypeDict[type]:
if lyr not in inputList:
continue
- cat = lyr.split('_')[0] if isEdgv \
+ cat = (
+ lyr.split("_")[0]
+ if isEdgv
else self.abstractDb.getTableSchemaFromDb(lyr)
+ )
lyrDict[self.correspondenceDict[type]][cat].append(lyr)
for type in list(lyrDict.keys()):
if lyrDict[type] == dict():
@@ -146,18 +181,20 @@ def prepareGroups(self, rootNode, lyrDict):
catList = list(lyrDict[geomNodeName].keys())
catList.sort()
for catNodeName in catList:
- groupDict[geomNodeName][catNodeName] = self.createGroup(catNodeName, geomNode)
+ groupDict[geomNodeName][catNodeName] = self.createGroup(
+ catNodeName, geomNode
+ )
return groupDict
-
+
def createGroup(self, groupName, rootNode):
groupNode = rootNode.findGroup(groupName)
if groupNode:
return groupNode
else:
return rootNode.addGroup(groupName)
-
+
def loadDomains(self, layerList, dbRootNode, edgvVersion):
- if edgvVersion not in ('FTer_2a_Ed', '3.0'):
+ if edgvVersion not in ("FTer_2a_Ed", "3.0"):
return dict()
domLayerDict = dict()
try:
@@ -165,7 +202,11 @@ def loadDomains(self, layerList, dbRootNode, edgvVersion):
except:
return dict()
domainNode = self.createGroup(self.tr("Domains"), dbRootNode)
- loadedDomainsDict = {} if not domainNode.findLayers() else {i.layer().name() : i.layer() for i in domainNode.findLayers()}
+ loadedDomainsDict = (
+ {}
+ if not domainNode.findLayers()
+ else {i.layer().name(): i.layer() for i in domainNode.findLayers()}
+ )
for lyr in layerList:
if lyr in qmlDict:
for attr in qmlDict[lyr]:
@@ -176,48 +217,49 @@ def loadDomains(self, layerList, dbRootNode, edgvVersion):
if attr not in list(domLayerDict[lyr].keys()):
domLayerDict[lyr][attr] = domLyr
return domLayerDict
-
+
def getDomainLyr(self, domain, loadedDomainsDict, domainNode):
if domain in loadedDomainsDict:
return loadedDomainsDict[domain]
domainLyr = self.loadDomain(domain, domainNode)
loadedDomainsDict[domain] = domainLyr
return domainLyr
-
def logError(self):
- msg = ''
+ msg = ""
for lyr in self.logErrorDict:
- msg += self.tr('Error for lyr ')+ lyr + ': ' +self.logErrorDict[lyr] + '\n'
+ msg += (
+ self.tr("Error for lyr ") + lyr + ": " + self.logErrorDict[lyr] + "\n"
+ )
self.errorLog += msg
- def setDataSource(self, schema, layer, geomColumn, sql, pkColumn='id'):
+ def setDataSource(self, schema, layer, geomColumn, sql, pkColumn="id"):
self.uri.setDataSource(schema, layer, geomColumn, sql, pkColumn)
- if sql == '':
+ if sql == "":
self.uri.disableSelectAtId(False)
else:
self.uri.disableSelectAtId(True)
def setDomainsAndRestrictionsWithQml(self, vlayer):
- qmldir = ''
+ qmldir = ""
try:
qmldir, qmlType = self.abstractDb.getQml(vlayer.name())
except Exception as e:
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return None
- if qmlType == 'db':
+ if qmlType == "db":
tempPath = os.path.join(os.path.dirname(__file__), "temp.qml")
- with open(tempPath, "w", encoding='utf-8') as f:
+ with open(tempPath, "w", encoding="utf-8") as f:
f.writelines(qmldir)
f.close()
vlayer.loadNamedStyle(tempPath, True)
os.remove(tempPath)
else:
- vlayerQml = os.path.join(qmldir, vlayer.name()+'.qml')
- #treat case of qml with multi
+ vlayerQml = os.path.join(qmldir, vlayer.name() + ".qml")
+ # treat case of qml with multi
vlayer.loadNamedStyle(vlayerQml, True)
return vlayer
-
+
def removeEmptyNodes(self, dbNode):
for geomNode in dbNode.children():
if not geomNode.findLayers():
@@ -226,31 +268,31 @@ def removeEmptyNodes(self, dbNode):
for catNode in geomNode.children():
if not catNode.findLayers():
geomNode.removeChildNode(catNode)
-
+
def getParams(self, inputParam):
if isinstance(inputParam, dict):
- lyrName = inputParam['lyrName']
- schema = inputParam['tableSchema']
- geomColumn = inputParam['geom']
- tableName = inputParam['tableName']
- srid = self.geomDict['tablePerspective'][tableName]['srid']
+ lyrName = inputParam["lyrName"]
+ schema = inputParam["tableSchema"]
+ geomColumn = inputParam["geom"]
+ tableName = inputParam["tableName"]
+ srid = self.geomDict["tablePerspective"][tableName]["srid"]
elif isinstance(inputParam, tuple):
schema, tableName = inputParam
lyrName = tableName
- geomColumn, srid = '', ''
+ geomColumn, srid = "", ""
else:
lyrName = inputParam
- tableName = self.geomDict['tablePerspective'][lyrName]['tableName']
- schema = self.geomDict['tablePerspective'][lyrName]['schema']
- geomColumn = self.geomDict['tablePerspective'][lyrName]['geometryColumn']
- srid = self.geomDict['tablePerspective'][lyrName]['srid']
+ tableName = self.geomDict["tablePerspective"][lyrName]["tableName"]
+ schema = self.geomDict["tablePerspective"][lyrName]["schema"]
+ geomColumn = self.geomDict["tablePerspective"][lyrName]["geometryColumn"]
+ srid = self.geomDict["tablePerspective"][lyrName]["srid"]
return lyrName, schema, geomColumn, tableName, srid
def getLayerByName(self, layer):
"""
Return the layer layer from a given layer name.
:param layer: (str) layer name.
- :return: (QgsVectorLayer) vector layer.
+ :return: (QgsVectorLayer) vector layer.
"""
try:
# self.provider is added on children classes
@@ -262,7 +304,7 @@ def getComplexLayerByName(self, layer):
"""
Return the layer layer from a given layer name.
:param layer: (str) layer name.
- :return: (QgsVectorLayer) vector layer.
+ :return: (QgsVectorLayer) vector layer.
"""
try:
# self.provider is added on children classes]
@@ -270,8 +312,10 @@ def getComplexLayerByName(self, layer):
return QgsVectorLayer(self.uri.uri(), table, self.provider)
except:
return None
-
- def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldName):
+
+ def buildJoin(
+ self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldName
+ ):
"""
Builds a join bewteen lyr and joinnedLyr.
:param originalLyr: QgsVectorLayer original layer;
@@ -284,7 +328,7 @@ def buildJoin(self, originalLyr, originalLyrFieldName, joinnedLyr, joinLyrFieldN
joinObject.setTargetFieldName(originalLyrFieldName)
joinObject.setJoinLayer(joinnedLyr)
joinObject.setJoinFieldNamesSubset()
- joinObject.upsertOnEdit(True) #set to enable edit on original lyr
+ joinObject.upsertOnEdit(True) # set to enable edit on original lyr
joinObject.setCascadedDelete(True)
joinObject.setDynamicFormEnabled(True)
joinObject.setEditable(True)
diff --git a/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py
index fb7cd469f..1c8af6b7b 100644
--- a/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py
+++ b/DsgTools/core/Factories/LayerLoaderFactory/geopackageLayerLoader.py
@@ -22,21 +22,28 @@
"""
import os
-from qgis.core import QgsVectorLayer, QgsMessageLog, QgsCoordinateReferenceSystem, Qgis, QgsProject
+from qgis.core import (
+ QgsVectorLayer,
+ QgsMessageLog,
+ QgsCoordinateReferenceSystem,
+ Qgis,
+ QgsProject,
+)
from .spatialiteLayerLoader import SpatialiteLayerLoader
+
class GeopackageLayerLoader(SpatialiteLayerLoader):
def __init__(self, iface, abstractDb, loadCentroids):
"""Constructor."""
super(GeopackageLayerLoader, self).__init__(iface, abstractDb, loadCentroids)
-
- self.provider = 'geopackage'
-
+
+ self.provider = "geopackage"
+
try:
dbVersion = abstractDb.getDatabaseVersion()
except Exception as e:
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return
self.buildUri()
@@ -57,12 +64,16 @@ def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict)
return lyr
vlayer = self.getLayerByName("{0}_{1}".format(schema, tableName))
if not vlayer.isValid():
- QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical)
- QgsProject.instance().addMapLayer(vlayer, addToLegend = False)
- crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId)
+ QgsMessageLog.logMessage(
+ vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical
+ )
+ QgsProject.instance().addMapLayer(vlayer, addToLegend=False)
+ crs = QgsCoordinateReferenceSystem(
+ int(srid), QgsCoordinateReferenceSystem.EpsgCrsId
+ )
vlayer.setCrs(crs)
vlayer = self.setDomainsAndRestrictionsWithQml(vlayer)
- vlayer = self.setMulti(vlayer,domLayerDict)
+ vlayer = self.setMulti(vlayer, domLayerDict)
if stylePath:
fullPath = self.getStyle(stylePath, tableName)
if fullPath:
@@ -75,11 +86,15 @@ def getLayerByName(self, layer):
"""
Return the layer layer from a given layer name.
:param layer: (str) table name - for GPKG it is [SCHEMA]_[CATEGORY]_[CLASS].
- :return: (QgsVectorLayer) vector layer.
+ :return: (QgsVectorLayer) vector layer.
"""
# parent class reimplementation
- schema = layer.split('_')[0]
- table = layer[len(schema) + 1:]
+ schema = layer.split("_")[0]
+ table = layer[len(schema) + 1 :]
lyrName, schema, geomColumn, tableName, srid = self.getParams(table)
- self.setDataSource('', layer, geomColumn, '')
- return QgsVectorLayer("{0}|layername={1}".format(self.abstractDb.db.databaseName(), layer), table, "ogr")
+ self.setDataSource("", layer, geomColumn, "")
+ return QgsVectorLayer(
+ "{0}|layername={1}".format(self.abstractDb.db.databaseName(), layer),
+ table,
+ "ogr",
+ )
diff --git a/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py b/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py
index df6a661da..14ae83e12 100644
--- a/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py
+++ b/DsgTools/core/Factories/LayerLoaderFactory/layerLoaderFactory.py
@@ -27,6 +27,7 @@
from .geopackageLayerLoader import GeopackageLayerLoader
from .shapefileLayerLoader import ShapefileLayerLoader
+
class LayerLoaderFactory(object):
def makeLoader(self, iface, abstractDb, loadCentroids=False):
"""
@@ -37,9 +38,9 @@ def makeLoader(self, iface, abstractDb, loadCentroids=False):
"""
driverName = abstractDb.getType()
loaders = {
- 'GPKG' : lambda : GeopackageLayerLoader(iface, abstractDb, loadCentroids),
- 'QSQLITE' : lambda : SpatialiteLayerLoader(iface, abstractDb, loadCentroids),
- 'QPSQL' : lambda : PostGISLayerLoader(iface, abstractDb, loadCentroids),
- 'SHP' : lambda : ShapefileLayerLoader(iface, abstractDb)
+ "GPKG": lambda: GeopackageLayerLoader(iface, abstractDb, loadCentroids),
+ "QSQLITE": lambda: SpatialiteLayerLoader(iface, abstractDb, loadCentroids),
+ "QPSQL": lambda: PostGISLayerLoader(iface, abstractDb, loadCentroids),
+ "SHP": lambda: ShapefileLayerLoader(iface, abstractDb),
}
return loaders[driverName]() if driverName in loaders else None
diff --git a/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py
index 97494bcfd..08dfad72d 100644
--- a/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py
+++ b/DsgTools/core/Factories/LayerLoaderFactory/postgisLayerLoader.py
@@ -24,22 +24,29 @@
from builtins import map, range, str
# QGIS imports
-from qgis.core import (Qgis, QgsCoordinateReferenceSystem, QgsDataSourceUri,
- QgsEditorWidgetSetup, QgsMessageLog, QgsProject,
- QgsVectorLayer)
+from qgis.core import (
+ Qgis,
+ QgsCoordinateReferenceSystem,
+ QgsDataSourceUri,
+ QgsEditorWidgetSetup,
+ QgsMessageLog,
+ QgsProject,
+ QgsVectorLayer,
+)
+
# Qt imports
from qgis.PyQt import QtCore, QtGui, uic
from qgis.PyQt.Qt import QObject
from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot
from qgis.utils import iface
-from ....core.LayerTools.CustomFormTools.customFormGenerator import \
- CustomFormGenerator
-from ....core.LayerTools.CustomFormTools.customInitCodeGenerator import \
- CustomInitCodeGenerator
-from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import \
- ProgressWidget
-#DsgTools imports
+from ....core.LayerTools.CustomFormTools.customFormGenerator import CustomFormGenerator
+from ....core.LayerTools.CustomFormTools.customInitCodeGenerator import (
+ CustomInitCodeGenerator,
+)
+from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
+
+# DsgTools imports
from .edgvLayerLoader import EDGVLayerLoader
@@ -47,8 +54,8 @@ class PostGISLayerLoader(EDGVLayerLoader):
def __init__(self, iface, abstractDb, loadCentroids):
"""Constructor."""
super(self.__class__, self).__init__(iface, abstractDb, loadCentroids)
-
- self.provider = 'postgres'
+
+ self.provider = "postgres"
self.setDatabaseConnection()
self.buildUri()
self.customFormGenerator = CustomFormGenerator()
@@ -65,10 +72,14 @@ def checkLoaded(self, name):
for ll in self.iface.mapCanvas().layers():
if ll.name() == name:
candidateUri = QgsDataSourceUri(ll.dataProvider().dataSourceUri())
- if self.host == candidateUri.host() and self.database == candidateUri.database() and self.port == int(candidateUri.port()):
+ if (
+ self.host == candidateUri.host()
+ and self.database == candidateUri.database()
+ and self.port == int(candidateUri.port())
+ ):
return ll
return loaded
-
+
def setDatabaseConnection(self):
"""
Sets database connection parameters
@@ -79,15 +90,23 @@ def setDatabaseConnection(self):
self.database = self.abstractDb.db.databaseName()
self.user = self.abstractDb.db.userName()
self.password = self.abstractDb.db.password()
-
+
def buildUri(self):
"""
Builds the database uri
:return:
"""
- self.uri.setConnection(str(self.host),str(self.port), str(self.database), str(self.user), str(self.password))
-
- def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilterList):
+ self.uri.setConnection(
+ str(self.host),
+ str(self.port),
+ str(self.database),
+ str(self.user),
+ str(self.password),
+ )
+
+ def filterLayerList(
+ self, layerList, useInheritance, onlyWithElements, geomFilterList
+ ):
"""
Filters the layers to be loaded
:param layerList: list of layers
@@ -97,27 +116,45 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte
:return:
"""
filterList = []
- lyrsWithElements = self.abstractDb.getLayersWithElementsV2(
- layerList,
- useInheritance=useInheritance
- ) if onlyWithElements else layerList
+ lyrsWithElements = (
+ self.abstractDb.getLayersWithElementsV2(
+ layerList, useInheritance=useInheritance
+ )
+ if onlyWithElements
+ else layerList
+ )
if len(geomFilterList) > 0:
finalSet = set()
for key in self.correspondenceDict:
finalSet = finalSet.union(
{
- lyr for lyr in lyrsWithElements if self.correspondenceDict[key] in geomFilterList \
- and key in self.geomTypeDict and lyr in self.geomTypeDict[key]
+ lyr
+ for lyr in lyrsWithElements
+ if self.correspondenceDict[key] in geomFilterList
+ and key in self.geomTypeDict
+ and lyr in self.geomTypeDict[key]
}
)
finalList = list(finalSet)
else:
finalList = lyrsWithElements
if finalList and isinstance(finalList[0], dict):
- finalList = [i['tableName'] for i in finalList]
+ finalList = [i["tableName"] for i in finalList]
return finalList
- def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], customForm=False, loadEditingStructure=False, parent=None):
+ def load(
+ self,
+ inputList,
+ useQml=False,
+ uniqueLoad=False,
+ useInheritance=False,
+ stylePath=None,
+ onlyWithElements=False,
+ geomFilterList=[],
+ customForm=False,
+ loadEditingStructure=False,
+ parent=None,
+ ):
"""
1. Get loaded layers
2. Filter layers;
@@ -126,18 +163,24 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
5. Build Groups;
6. Load Layers;
"""
- self.iface.mapCanvas().freeze() #done to speedup things
+ self.iface.mapCanvas().freeze() # done to speedup things
layerList, isDictList = self.preLoadStep(inputList)
- #2. Filter Layers:
- filteredLayerList = self.filterLayerList(inputList, useInheritance, onlyWithElements, geomFilterList)
- filteredDictList = [i for i in inputList if i['tableName'] in filteredLayerList] if isDictList else filteredLayerList
+ # 2. Filter Layers:
+ filteredLayerList = self.filterLayerList(
+ inputList, useInheritance, onlyWithElements, geomFilterList
+ )
+ filteredDictList = (
+ [i for i in inputList if i["tableName"] in filteredLayerList]
+ if isDictList
+ else filteredLayerList
+ )
edgvVersion = self.abstractDb.getDatabaseVersion()
isEdgv = not edgvVersion == "Non_EDGV"
rootNode = QgsProject.instance().layerTreeRoot()
dbNode = self.getDatabaseGroup(rootNode)
- #3. Load Domains
+ # 3. Load Domains
domLayerDict = self.loadDomains(filteredLayerList, dbNode, edgvVersion)
- #4. Get Aux dicts
+ # 4. Get Aux dicts
domainDict = self.abstractDb.getDbDomainDict(self.geomDict)
constraintDict = self.abstractDb.getCheckConstraintDict()
multiColumnsDict = self.abstractDb.getMultiColumnsDict()
@@ -147,10 +190,10 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
if customForm:
self.filterDict = self.abstractDb.getFilterDict()
self.rulesDict = dict()
-
- #5. Build Groups
+
+ # 5. Build Groups
groupDict = self.prepareGroups(dbNode, lyrDict)
- #6. load layers
+ # 6. load layers
loadedDict = dict()
if parent:
primNumber = 0
@@ -158,7 +201,9 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
for cat in list(lyrDict[prim].keys()):
for lyr in lyrDict[prim][cat]:
primNumber += 1
- localProgress = ProgressWidget(1, primNumber-1, self.tr('Loading layers... '), parent=parent)
+ localProgress = ProgressWidget(
+ 1, primNumber - 1, self.tr("Loading layers... "), parent=parent
+ )
for prim in list(lyrDict.keys()):
for cat in list(lyrDict[prim].keys()):
for lyr in lyrDict[prim][cat]:
@@ -175,23 +220,41 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
domLayerDict=domLayerDict,
edgvVersion=edgvVersion,
editingDict=editingDict,
- customForm = customForm
+ customForm=customForm,
)
if vlayer is None:
continue
- key = lyr['lyrName'] if isinstance(lyr, dict) else lyr
- loadedDict[key]=vlayer
+ key = lyr["lyrName"] if isinstance(lyr, dict) else lyr
+ loadedDict[key] = vlayer
except Exception as e:
- key = lyr['lyrName'] if isinstance(lyr, dict) else lyr
- self.logErrorDict[key] = self.tr('Error for layer ')+key+': '+':'.join(e.args)
+ key = lyr["lyrName"] if isinstance(lyr, dict) else lyr
+ self.logErrorDict[key] = (
+ self.tr("Error for layer ") + key + ": " + ":".join(e.args)
+ )
self.logError()
if parent:
localProgress.step()
self.removeEmptyNodes(dbNode)
- self.iface.mapCanvas().freeze(False) #done to speedup things
+ self.iface.mapCanvas().freeze(False) # done to speedup things
return loadedDict
- def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad, stylePath, domainDict, multiColumnsDict, domLayerDict, edgvVersion, geomColumn = None, isView = False, editingDict=None, customForm = False):
+ def loadLayer(
+ self,
+ inputParam,
+ parentNode,
+ useInheritance,
+ useQml,
+ uniqueLoad,
+ stylePath,
+ domainDict,
+ multiColumnsDict,
+ domLayerDict,
+ edgvVersion,
+ geomColumn=None,
+ isView=False,
+ editingDict=None,
+ customForm=False,
+ ):
"""
Loads a layer
:param lyrName: Layer name
@@ -209,26 +272,35 @@ def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad,
schema=schema,
layer=tableName,
geomColumn=geomColumn,
- sql='',
- pkColumn=self.abstractDb.getPrimaryKeyColumn(f'''"{schema}"."{tableName}"''')
+ sql="",
+ pkColumn=self.abstractDb.getPrimaryKeyColumn(
+ f'''"{schema}"."{tableName}"'''
+ ),
)
vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider)
- QgsProject.instance().addMapLayer(vlayer, addToLegend = False)
- crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId)
+ QgsProject.instance().addMapLayer(vlayer, addToLegend=False)
+ crs = QgsCoordinateReferenceSystem(
+ int(srid), QgsCoordinateReferenceSystem.EpsgCrsId
+ )
if vlayer is None:
return vlayer
if not vlayer.isValid():
- QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical
+ )
vlayer.setCrs(crs)
- vlayer = self.setDomainsAndRestrictionsWithQml(vlayer) if useQml \
+ vlayer = (
+ self.setDomainsAndRestrictionsWithQml(vlayer)
+ if useQml
else self.setDomainsAndRestrictions(
lyr=vlayer,
lyrName=tableName,
domainDict=domainDict,
multiColumnsDict=multiColumnsDict,
- domLayerDict=domLayerDict
+ domLayerDict=domLayerDict,
)
+ )
if stylePath is not None:
fullPath = self.getStyle(stylePath, tableName)
if fullPath:
@@ -240,7 +312,7 @@ def loadLayer(self, inputParam, parentNode, useInheritance, useQml, uniqueLoad,
vlayer = self.createMeasureColumn(vlayer)
parentNode.addLayer(vlayer)
return vlayer
-
+
def loadEditLayer(self, schema, tableName):
"""
Parses database to check which is the referenced edit layer and loads it
@@ -248,18 +320,23 @@ def loadEditLayer(self, schema, tableName):
:param tableName: original table name
returns editLyr, joinLyrFieldName
"""
- editLyrSchema, editLyrTableName, pkName, joinLyrFieldName = self.abstractDb.getEditTable(schema, tableName)
+ (
+ editLyrSchema,
+ editLyrTableName,
+ pkName,
+ joinLyrFieldName,
+ ) = self.abstractDb.getEditTable(schema, tableName)
uri = """dbname='{database}' host={host} port={port} user='{user}' password='{password}' key={primary_key} table=\"{schema}\".\"{table}\" sql=""".format(
- database=self.database,
- host=self.host,
- port=self.port,
- user=self.user,
- password=self.password,
- primary_key=pkName,
- schema=editLyrSchema,
- table=editLyrTableName
- )
-
+ database=self.database,
+ host=self.host,
+ port=self.port,
+ user=self.user,
+ password=self.password,
+ primary_key=pkName,
+ schema=editLyrSchema,
+ table=editLyrTableName,
+ )
+
def loadDomain(self, domainTableName, domainGroup):
"""
Loads layer domains
@@ -267,8 +344,18 @@ def loadDomain(self, domainTableName, domainGroup):
:param domainGroup:
:return:
"""
- #TODO: Avaliar se o table = deve ser diferente
- uri = "dbname='%s' host=%s port=%s user='%s' password='%s' key=code table=\"dominios\".\"%s\" sql=" % (self.database, self.host, self.port, self.user, self.password, domainTableName)
+ # TODO: Avaliar se o table = deve ser diferente
+ uri = (
+ "dbname='%s' host=%s port=%s user='%s' password='%s' key=code table=\"dominios\".\"%s\" sql="
+ % (
+ self.database,
+ self.host,
+ self.port,
+ self.user,
+ self.password,
+ domainTableName,
+ )
+ )
domLayer = QgsVectorLayer(uri, domainTableName, self.provider)
domainGroup.addLayer(domLayer)
return domLayer
@@ -282,7 +369,9 @@ def getStyleFromDb(self, edgvVersion, className):
"""
return self.abstractDb.getLyrStyle(edgvVersion, className)
- def setDomainsAndRestrictions(self, lyr, lyrName, domainDict, multiColumnsDict, domLayerDict):
+ def setDomainsAndRestrictions(
+ self, lyr, lyrName, domainDict, multiColumnsDict, domLayerDict
+ ):
"""
Adjusts the domain restriction to all attributes in the layer
:param lyr:
@@ -296,39 +385,68 @@ def setDomainsAndRestrictions(self, lyr, lyrName, domainDict, multiColumnsDict,
pkIdxList = lyr.primaryKeyAttributes()
for i in range(len(lyrAttributes)):
attrName = lyrAttributes[i].name()
- if attrName == 'id' or 'id_' in lyrAttributes[i].name() or i in pkIdxList:
- lyr.editFormConfig().setReadOnly(i,True)
+ if attrName == "id" or "id_" in lyrAttributes[i].name() or i in pkIdxList:
+ lyr.editFormConfig().setReadOnly(i, True)
else:
if lyrName in domainDict.keys():
- if attrName in list(domainDict[lyrName]['columns'].keys()):
- refTable = domainDict[lyrName]['columns'][attrName]['references']
- refPk = domainDict[lyrName]['columns'][attrName]['refPk']
- otherKey = domainDict[lyrName]['columns'][attrName]['otherKey']
- valueDict = domainDict[lyrName]['columns'][attrName]['values']
+ if attrName in list(domainDict[lyrName]["columns"].keys()):
+ refTable = domainDict[lyrName]["columns"][attrName][
+ "references"
+ ]
+ refPk = domainDict[lyrName]["columns"][attrName]["refPk"]
+ otherKey = domainDict[lyrName]["columns"][attrName]["otherKey"]
+ valueDict = domainDict[lyrName]["columns"][attrName]["values"]
isMulti = self.checkMulti(lyrName, attrName, multiColumnsDict)
if isMulti:
- #make filter
- if 'constraintList' in list(domainDict[lyrName]['columns'][attrName].keys()):
- #make editDict
+ # make filter
+ if "constraintList" in list(
+ domainDict[lyrName]["columns"][attrName].keys()
+ ):
+ # make editDict
if lyrName in domLayerDict:
if attrName in domLayerDict[lyrName]:
- filter = '{0} in ({1})'.format(refPk,','.join(map(str,domainDict[lyrName]['columns'][attrName]['constraintList'])))
- allowNull = domainDict[lyrName]['columns'][attrName]['nullable']
+ filter = "{0} in ({1})".format(
+ refPk,
+ ",".join(
+ map(
+ str,
+ domainDict[lyrName]["columns"][
+ attrName
+ ]["constraintList"],
+ )
+ ),
+ )
+ allowNull = domainDict[lyrName]["columns"][
+ attrName
+ ]["nullable"]
dom = domLayerDict[lyrName][attrName]
- editDict = {'Layer':dom.id(),'Key':refPk,'Value':otherKey,'AllowMulti':True,'AllowNull':allowNull,'FilterExpression':filter}
- widgetSetup = QgsEditorWidgetSetup('ValueRelation', editDict)
+ editDict = {
+ "Layer": dom.id(),
+ "Key": refPk,
+ "Value": otherKey,
+ "AllowMulti": True,
+ "AllowNull": allowNull,
+ "FilterExpression": filter,
+ }
+ widgetSetup = QgsEditorWidgetSetup(
+ "ValueRelation", editDict
+ )
lyr.setEditorWidgetSetup(i, widgetSetup)
else:
- #filter value dict
- constraintList = domainDict[lyrName]['columns'][attrName]['constraintList']
+ # filter value dict
+ constraintList = domainDict[lyrName]["columns"][attrName][
+ "constraintList"
+ ]
valueRelationDict = dict()
for key in list(valueDict.keys()):
- if len(constraintList) > 0:
+ if len(constraintList) > 0:
if key in constraintList:
valueRelationDict[valueDict[key]] = str(key)
else:
valueRelationDict[valueDict[key]] = str(key)
- widgetSetup = QgsEditorWidgetSetup('ValueMap',{'map':valueRelationDict})
+ widgetSetup = QgsEditorWidgetSetup(
+ "ValueMap", {"map": valueRelationDict}
+ )
lyr.setEditorWidgetSetup(i, widgetSetup)
return lyr
@@ -344,7 +462,7 @@ def checkMulti(self, tableName, attrName, multiColumnsDict):
if attrName in multiColumnsDict[tableName]:
return True
return False
-
+
def checkNotNull(self, lyrName, notNullDict):
"""
Checks not null attributes
@@ -354,27 +472,31 @@ def checkNotNull(self, lyrName, notNullDict):
"""
allowNull = True
if lyrName in list(notNullDict.keys()):
- if attrName in notNullDict[lyrName]['attributes']:
+ if attrName in notNullDict[lyrName]["attributes"]:
allowNull = False
return allowNull
def getPathUiForm(self, dbName, layerName):
- #alterar
- pathUiForm = os.path.join(
- os.path.dirname(__file__), '..', '..', 'LayerTools', 'CustomFormTools',
- 'formsCustom' ,
- '{0}_{1}.ui'.format(dbName, layerName)
+ # alterar
+ pathUiForm = os.path.join(
+ os.path.dirname(__file__),
+ "..",
+ "..",
+ "LayerTools",
+ "CustomFormTools",
+ "formsCustom",
+ "{0}_{1}.ui".format(dbName, layerName),
)
return pathUiForm
def newUiForm(self, pathUiForm):
formFile = open(pathUiForm, "wb")
return formFile
-
+
def loadFormCustom(self, lyr):
pathUiForm = self.getPathUiForm(self.database, lyr.name())
formFile = self.newUiForm(pathUiForm)
- #inserir flag do filtro
+ # inserir flag do filtro
withFilter = lyr.name() in self.filterDict
self.customFormGenerator.create(formFile, lyr, withFilter=withFilter)
lyr.editFormConfig().setInitCodeSource(2)
@@ -390,7 +512,7 @@ def getRulesSelected(self, lyr):
rules = []
# currentlayerName = lyr.name()
# if self.getRules():
- # allRules = self.getRules().getRulesToForm()
+ # allRules = self.getRules().getRulesToForm()
# selectedRuleOnOrder = { allRules["order_rules"][k.encode("utf-8")] : k.encode("utf-8") for k in data['selectedRulesType']}
# for order in reversed(sorted(selectedRuleOnOrder)):
# ruleName = selectedRuleOnOrder[order]
@@ -406,7 +528,9 @@ def createCustomInitCode(self, lyr):
# dbData = data['userData']['dbJson'][data['dbAlias']]
# layerData = dbData[data['nameGeom']][data['nameCatLayer']][data['layerName']]
if lyr.name() in list(self.filterDict.keys()):
- initCode = self.customInitCodeGenerator.getInitCodeWithFilter(self.filterDict[lyr.name()], rules) #layerData['filter'] é o resultado da query select * from dominios.
+ initCode = self.customInitCodeGenerator.getInitCodeWithFilter(
+ self.filterDict[lyr.name()], rules
+ ) # layerData['filter'] é o resultado da query select * from dominios.
return initCode
else:
initCode = self.customInitCodeGenerator.getInitCodeNotFilter(rules)
@@ -416,20 +540,24 @@ def getLayerByName(self, layer):
"""
Return the layer layer from a given layer name.
:param layer: (str) layer name.
- :return: (QgsVectorLayer) vector layer.
+ :return: (QgsVectorLayer) vector layer.
"""
# parent class reimplementation
- table = layer.split('.')[1]
+ table = layer.split(".")[1]
return self.loadQgsVectorLayer(table)
-
- def loadQgsVectorLayer(self, inputParam, uniqueLoad=False, addToCanvas=False, nonSpatial=False):
+
+ def loadQgsVectorLayer(
+ self, inputParam, uniqueLoad=False, addToCanvas=False, nonSpatial=False
+ ):
"""
Returns a QgsVectorLayer using the parameters from inputParam.
If uniqueLoad=True, checks if layer is already loaded and if it is,
returns it.
"""
try:
- lyrName, schema, geomColumn, tableName, srid = self.getParams(inputParam=inputParam)
+ lyrName, schema, geomColumn, tableName, srid = self.getParams(
+ inputParam=inputParam
+ )
except:
return None
lyr = self.checkLoaded(tableName)
@@ -437,8 +565,7 @@ def loadQgsVectorLayer(self, inputParam, uniqueLoad=False, addToCanvas=False, no
return lyr
pkColumn = self.abstractDb.getPrimaryKeyColumn(
"{table_schema}.{table_name}".format(
- table_schema=schema,
- table_name=tableName
+ table_schema=schema, table_name=tableName
)
)
if nonSpatial:
@@ -450,23 +577,29 @@ def loadQgsVectorLayer(self, inputParam, uniqueLoad=False, addToCanvas=False, no
password=self.password,
pk=pkColumn,
table_schema=schema,
- table_name=tableName
+ table_name=tableName,
)
else:
- self.setDataSource(schema, tableName, geomColumn, '', pkColumn=pkColumn)
+ self.setDataSource(schema, tableName, geomColumn, "", pkColumn=pkColumn)
uri = self.uri.uri()
lyr = QgsVectorLayer(uri, tableName, self.provider)
QgsProject.instance().addMapLayer(lyr, addToLegend=addToCanvas)
return lyr
-
- def loadLayersInsideProcessing(self, inputParamList, uniqueLoad=False, addToCanvas=True, nonSpatial=False, feedback=None):
+ def loadLayersInsideProcessing(
+ self,
+ inputParamList,
+ uniqueLoad=False,
+ addToCanvas=True,
+ nonSpatial=False,
+ feedback=None,
+ ):
"""
Loads layer inside qgis using processing. If uniqueLoad=True, only loads
if it is not loaded.
"""
outputLayers = []
- progressStep = 100/len(inputParamList) if len(inputParamList) else 0
+ progressStep = 100 / len(inputParamList) if len(inputParamList) else 0
for current, inputParam in enumerate(inputParamList):
if feedback is not None and feedback.isCanceled():
break
@@ -474,10 +607,10 @@ def loadLayersInsideProcessing(self, inputParamList, uniqueLoad=False, addToCanv
inputParam=inputParam,
uniqueLoad=uniqueLoad,
addToCanvas=addToCanvas,
- nonSpatial=nonSpatial
+ nonSpatial=nonSpatial,
)
if lyr is not None:
outputLayers.append(lyr)
if feedback is not None:
- feedback.setProgress(current*progressStep)
+ feedback.setProgress(current * progressStep)
return outputLayers
diff --git a/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py
index 75d0c055b..9494353a2 100644
--- a/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py
+++ b/DsgTools/core/Factories/LayerLoaderFactory/shapefileLayerLoader.py
@@ -29,12 +29,22 @@
from qgis.PyQt.Qt import QObject
# QGIS imports
-from qgis.core import QgsVectorLayer, QgsDataSourceUri, QgsMessageLog, QgsCoordinateReferenceSystem, QgsMessageLog, Qgis, QgsProject, QgsEditorWidgetSetup
+from qgis.core import (
+ QgsVectorLayer,
+ QgsDataSourceUri,
+ QgsMessageLog,
+ QgsCoordinateReferenceSystem,
+ QgsMessageLog,
+ Qgis,
+ QgsProject,
+ QgsEditorWidgetSetup,
+)
-#DsgTools imports
+# DsgTools imports
from .edgvLayerLoader import EDGVLayerLoader
from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
+
class ShapefileLayerLoader(EDGVLayerLoader):
def __init__(self, iface, abstractDb):
"""
@@ -44,11 +54,11 @@ def __init__(self, iface, abstractDb):
"""
# no reason for centroids to be used, so it'll be set to False always (parent requirement to init)
super(ShapefileLayerLoader, self).__init__(iface, abstractDb, False)
- self.provider = 'shapefile'
+ self.provider = "shapefile"
try:
dbVersion = abstractDb.getDatabaseVersion()
except Exception as e:
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return
self.buildUri()
@@ -58,11 +68,11 @@ def buildUri(self):
:return:
"""
self.uri.setDatabase(self.abstractDb.databaseName())
-
+
def checkLoaded(self, name):
"""
Checks if the layers is already loaded in the QGIS' TOC
- :param name:
+ :param name:
:return:
"""
loaded = None
@@ -74,7 +84,20 @@ def checkLoaded(self, name):
return ll
return loaded
- def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], isEdgv=True, customForm=False, editingDict=None, parent=None):
+ def load(
+ self,
+ inputList,
+ useQml=False,
+ uniqueLoad=False,
+ useInheritance=False,
+ stylePath=None,
+ onlyWithElements=False,
+ geomFilterList=[],
+ isEdgv=True,
+ customForm=False,
+ editingDict=None,
+ parent=None,
+ ):
"""
1. Get loaded layers
2. Filter layers;
@@ -83,52 +106,68 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
5. Build Groups;
6. Load Layers;
"""
- self.iface.mapCanvas().freeze() #done to speedup things
+ self.iface.mapCanvas().freeze() # done to speedup things
layerList, isDictList = self.preLoadStep(inputList)
- #2. Filter Layers:
- filteredLayerList = self.filterLayerList(layerList, False, onlyWithElements, geomFilterList)
- filteredDictList = [i for i in inputList if i['tableName'] in filteredLayerList] if isDictList else filteredLayerList
+ # 2. Filter Layers:
+ filteredLayerList = self.filterLayerList(
+ layerList, False, onlyWithElements, geomFilterList
+ )
+ filteredDictList = (
+ [i for i in inputList if i["tableName"] in filteredLayerList]
+ if isDictList
+ else filteredLayerList
+ )
edgvVersion = self.abstractDb.getDatabaseVersion()
rootNode = QgsProject.instance().layerTreeRoot()
dbNode = self.getDatabaseGroup(rootNode)
- #3. Load Domains
- #do this only if EDGV Version = FTer
+ # 3. Load Domains
+ # do this only if EDGV Version = FTer
domLayerDict = self.loadDomains(filteredLayerList, dbNode, edgvVersion)
- #4. Get Aux dicts
- lyrDict = self.getLyrDict(filteredDictList, isEdgv = isEdgv)
- #5. Build Groups
+ # 4. Get Aux dicts
+ lyrDict = self.getLyrDict(filteredDictList, isEdgv=isEdgv)
+ # 5. Build Groups
groupDict = self.prepareGroups(dbNode, lyrDict)
- #5. load layers
+ # 5. load layers
if parent:
primNumber = 0
for prim in list(lyrDict.keys()):
for cat in list(lyrDict[prim].keys()):
for lyr in lyrDict[prim][cat]:
primNumber += 1
- localProgress = ProgressWidget(1, primNumber-1, self.tr('Loading layers... '), parent=parent)
+ localProgress = ProgressWidget(
+ 1, primNumber - 1, self.tr("Loading layers... "), parent=parent
+ )
loadedDict = dict()
for prim in list(lyrDict.keys()):
for cat in list(lyrDict[prim].keys()):
for lyr in lyrDict[prim][cat]:
try:
- vlayer = self.loadLayer(lyr, groupDict[prim][cat], uniqueLoad, stylePath, domLayerDict)
+ vlayer = self.loadLayer(
+ lyr,
+ groupDict[prim][cat],
+ uniqueLoad,
+ stylePath,
+ domLayerDict,
+ )
if vlayer:
if isinstance(lyr, dict):
- key = lyr['lyrName']
+ key = lyr["lyrName"]
else:
key = lyr
- loadedDict[key]=vlayer
+ loadedDict[key] = vlayer
except Exception as e:
if isinstance(lyr, dict):
- key = lyr['lyrName']
+ key = lyr["lyrName"]
else:
key = lyr
- self.logErrorDict[key] = self.tr('Error for layer ')+key+': '+':'.join(e.args)
+ self.logErrorDict[key] = (
+ self.tr("Error for layer ") + key + ": " + ":".join(e.args)
+ )
self.logError()
if parent:
localProgress.step()
self.removeEmptyNodes(dbNode)
- self.iface.mapCanvas().freeze(False) #done to speedup things
+ self.iface.mapCanvas().freeze(False) # done to speedup things
return loadedDict
def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict):
@@ -145,21 +184,25 @@ def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict)
lyr = self.checkLoaded(tableName)
if uniqueLoad and lyr:
return lyr
- self.setDataSource('', '_'.join([schema,tableName]), geomColumn, '')
+ self.setDataSource("", "_".join([schema, tableName]), geomColumn, "")
vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider)
- QgsProject.instance().addMapLayer(vlayer, addToLegend = False)
- crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId)
+ QgsProject.instance().addMapLayer(vlayer, addToLegend=False)
+ crs = QgsCoordinateReferenceSystem(
+ int(srid), QgsCoordinateReferenceSystem.EpsgCrsId
+ )
vlayer.setCrs(crs)
vlayer = self.setDomainsAndRestrictionsWithQml(vlayer)
- vlayer = self.setMulti(vlayer,domLayerDict)
+ vlayer = self.setMulti(vlayer, domLayerDict)
if stylePath:
fullPath = self.getStyle(stylePath, tableName)
if fullPath:
vlayer.loadNamedStyle(fullPath, True)
- parentNode.addLayer(vlayer)
+ parentNode.addLayer(vlayer)
if not vlayer.isValid():
- QgsMessageLog.logMessage(vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ vlayer.error().summary(), "DSGTools Plugin", Qgis.Critical
+ )
vlayer = self.createMeasureColumn(vlayer)
return vlayer
@@ -170,11 +213,11 @@ def loadDomain(self, domainTableName, domainGroup):
:param domainGroup:
:return:
"""
- #TODO: Avaliar se o table = deve ser diferente
+ # TODO: Avaliar se o table = deve ser diferente
uri = QgsDataSourceUri()
uri.setDatabase(self.abstractDb.db.databaseName())
- uri.setDataSource('', 'dominios_'+domainTableName, None)
- #TODO Load domain layer into a group
+ uri.setDataSource("", "dominios_" + domainTableName, None)
+ # TODO Load domain layer into a group
domLayer = iface.addVectorLayer(uri.uri(), domainTableName, self.provider)
self.iface.legendInterface().moveLayer(domLayer, domainGroup)
return domLayer
@@ -182,7 +225,9 @@ def loadDomain(self, domainTableName, domainGroup):
def getStyleFromDb(self, edgvVersion, className):
return None
- def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilterList):
+ def filterLayerList(
+ self, layerList, useInheritance, onlyWithElements, geomFilterList
+ ):
"""
Filters the layers to be loaded
:param layerList: list of layers
@@ -193,7 +238,9 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte
"""
filterList = []
if onlyWithElements:
- semifinalList = self.abstractDb.getLayersWithElementsV2(layerList, useInheritance=False)
+ semifinalList = self.abstractDb.getLayersWithElementsV2(
+ layerList, useInheritance=False
+ )
else:
semifinalList = layerList
if len(geomFilterList) > 0:
@@ -202,12 +249,12 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte
if self.correspondenceDict[key] in geomFilterList:
if key in self.geomTypeDict:
for lyr in semifinalList:
- if lyr in self.geomTypeDict[key] and lyr not in finalList:
+ if lyr in self.geomTypeDict[key] and lyr not in finalList:
finalList.append(lyr)
else:
finalList = semifinalList
return finalList
-
+
def setMulti(self, vlayer, domLayerDict):
"""
Sets attributes with value relation
@@ -215,15 +262,15 @@ def setMulti(self, vlayer, domLayerDict):
:param domLayerDict:
:return:
"""
- #sweep vlayer to find v2
+ # sweep vlayer to find v2
attrList = vlayer.fields()
for field in attrList:
i = attrList.lookupField(field.name())
editorWidgetSetup = vlayer.editorWidgetSetup(i)
- if editorWidgetSetup.type() == 'ValueRelation':
+ if editorWidgetSetup.type() == "ValueRelation":
valueRelationDict = editorWidgetSetup.config()
domLayer = domLayerDict[vlayer.name()][field.name()]
- valueRelationDict['Layer'] = domLayer.id()
+ valueRelationDict["Layer"] = domLayer.id()
vlayer.setEditorWidgetSetup(i, valueRelationDict)
return vlayer
@@ -231,10 +278,10 @@ def getLayerByName(self, layer):
"""
Return the layer layer from a given layer name.
:param layer: (str) layer name.
- :return: (QgsVectorLayer) vector layer.
+ :return: (QgsVectorLayer) vector layer.
"""
# parent class reimplementation
path = os.path.join(self.abstractDb.databaseName(), "{0}.shp".format(layer))
- schema = layer.split('_')[0]
- table = layer[len(schema) + 1:].lower()
+ schema = layer.split("_")[0]
+ table = layer[len(schema) + 1 :].lower()
return QgsVectorLayer(path, table, "ogr")
diff --git a/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py b/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py
index d6a522c88..45f22f436 100644
--- a/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py
+++ b/DsgTools/core/Factories/LayerLoaderFactory/spatialiteLayerLoader.py
@@ -24,29 +24,32 @@
import json
from collections import defaultdict
-from qgis.core import (Qgis,
- QgsProject,
- QgsMessageLog,
- QgsVectorLayer,
- QgsDataSourceUri,
- QgsEditorWidgetSetup,
- QgsCoordinateReferenceSystem)
+from qgis.core import (
+ Qgis,
+ QgsProject,
+ QgsMessageLog,
+ QgsVectorLayer,
+ QgsDataSourceUri,
+ QgsEditorWidgetSetup,
+ QgsCoordinateReferenceSystem,
+)
from qgis.PyQt.QtSql import QSqlQuery
from .edgvLayerLoader import EDGVLayerLoader
from ....gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
+
class SpatialiteLayerLoader(EDGVLayerLoader):
def __init__(self, iface, abstractDb, loadCentroids):
"""Constructor."""
super(SpatialiteLayerLoader, self).__init__(iface, abstractDb, loadCentroids)
-
- self.provider = 'spatialite'
-
+
+ self.provider = "spatialite"
+
try:
dbVersion = abstractDb.getDatabaseVersion()
except Exception as e:
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return
self.buildUri()
@@ -57,11 +60,11 @@ def buildUri(self):
:return:
"""
self.uri.setDatabase(self.abstractDb.db.databaseName())
-
+
def checkLoaded(self, name):
"""
Checks if the layers is already loaded in the QGIS' TOC
- :param name:
+ :param name:
:return:
"""
loaded = None
@@ -77,7 +80,7 @@ def specialEdgvAttributes(self):
"""
Gets the list of attributes shared by many EDGV classes and have a different domain
depending on which category the EDGV class belongs to.
- :return: (list-of-str) list of "special" EDGV classes.
+ :return: (list-of-str) list of "special" EDGV classes.
"""
return ["finalidade", "relacionado", "coincidecomdentrode", "tipo"]
@@ -105,14 +108,15 @@ def domainMapping(self, modelVersion):
}
"""
basePath = os.path.join(
- os.path.dirname(__file__), "..", "..", "DbModels", "DomainMapping")
+ os.path.dirname(__file__), "..", "..", "DbModels", "DomainMapping"
+ )
path = {
"EDGV 3.0": os.path.join(basePath, "edgv_3.json"),
"3.0": os.path.join(basePath, "edgv_3.json"),
"EDGV 2.1.3 Pro": os.path.join(basePath, "edgv_213_pro.json"),
"2.1.3 Pro": os.path.join(basePath, "edgv_213_pro.json"),
"EDGV 2.1.3": os.path.join(basePath, "edgv_213.json"),
- "2.1.3": os.path.join(basePath, "edgv_213.json")
+ "2.1.3": os.path.join(basePath, "edgv_213.json"),
}.pop(modelVersion, None)
if path is None or not os.path.exists(path):
return dict()
@@ -133,7 +137,7 @@ def getAllEdgvDomainsFromTableName(self, schema, table):
edgv = self.abstractDb.getDatabaseVersion()
domainMap = self.domainMapping(edgv)
fullTablaName = schema + "_" + table
- sql = 'select code, code_name from dominios_{field} order by code'
+ sql = "select code, code_name from dominios_{field} order by code"
for fieldName in self.tableFields(fullTablaName):
if fullTablaName in domainMap:
domains = domainMap[fullTablaName]
@@ -165,7 +169,19 @@ def getAllEdgvDomainsFromTableName(self, schema, table):
ret[fieldName][code_name] = code
return ret
- def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False, stylePath=None, onlyWithElements=False, geomFilterList=[], customForm=False, editingDict=None, parent=None):
+ def load(
+ self,
+ inputList,
+ useQml=False,
+ uniqueLoad=False,
+ useInheritance=False,
+ stylePath=None,
+ onlyWithElements=False,
+ geomFilterList=[],
+ customForm=False,
+ editingDict=None,
+ parent=None,
+ ):
"""
1. Get loaded layers
2. Filter layers;
@@ -174,11 +190,17 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
5. Build Groups;
6. Load Layers;
"""
- self.iface.mapCanvas().freeze() #done to speedup things
+ self.iface.mapCanvas().freeze() # done to speedup things
layerList, isDictList = self.preLoadStep(inputList)
- #2. Filter Layers:
- filteredLayerList = self.filterLayerList(layerList, False, onlyWithElements, geomFilterList)
- filteredDictList = [i for i in inputList if i['tableName'] in filteredLayerList] if isDictList else filteredLayerList
+ # 2. Filter Layers:
+ filteredLayerList = self.filterLayerList(
+ layerList, False, onlyWithElements, geomFilterList
+ )
+ filteredDictList = (
+ [i for i in inputList if i["tableName"] in filteredLayerList]
+ if isDictList
+ else filteredLayerList
+ )
edgvVersion = self.abstractDb.getDatabaseVersion()
isEdgv = not edgvVersion == "Non_EDGV"
rootNode = QgsProject.instance().layerTreeRoot()
@@ -191,41 +213,51 @@ def load(self, inputList, useQml=False, uniqueLoad=False, useInheritance=False,
# loaded in any of our current use cases, this will be ignored and set to an
# empty dict
domLayerDict = dict()
- #4. Get Aux dicts
- lyrDict = self.getLyrDict(filteredDictList, isEdgv = isEdgv)
- #5. Build Groups
+ # 4. Get Aux dicts
+ lyrDict = self.getLyrDict(filteredDictList, isEdgv=isEdgv)
+ # 5. Build Groups
groupDict = self.prepareGroups(dbNode, lyrDict)
- #5. load layers
+ # 5. load layers
if parent:
primNumber = 0
for prim in list(lyrDict.keys()):
for cat in list(lyrDict[prim].keys()):
for lyr in lyrDict[prim][cat]:
primNumber += 1
- localProgress = ProgressWidget(1, primNumber-1, self.tr('Loading layers... '), parent=parent)
+ localProgress = ProgressWidget(
+ 1, primNumber - 1, self.tr("Loading layers... "), parent=parent
+ )
loadedDict = dict()
for prim in list(lyrDict.keys()):
for cat in list(lyrDict[prim].keys()):
for lyr in lyrDict[prim][cat]:
try:
- vlayer = self.loadLayer(lyr, groupDict[prim][cat], uniqueLoad, stylePath, domLayerDict)
+ vlayer = self.loadLayer(
+ lyr,
+ groupDict[prim][cat],
+ uniqueLoad,
+ stylePath,
+ domLayerDict,
+ )
if vlayer:
if isinstance(lyr, dict):
- key = lyr['lyrName']
+ key = lyr["lyrName"]
else:
key = lyr
- loadedDict[key]=vlayer
+ loadedDict[key] = vlayer
except Exception as e:
if isinstance(lyr, dict):
- key = lyr['lyrName']
+ key = lyr["lyrName"]
else:
key = lyr
- self.logErrorDict[key] = self.tr('Error for layer ')+key+': '+':'.join(e.args)
+ self.logErrorDict[key] = (
+ self.tr("Error for layer ") + key + ": " + ":".join(e.args)
+ )
self.logError()
if parent:
localProgress.step()
self.removeEmptyNodes(dbNode)
- self.iface.mapCanvas().freeze(False) #done to speedup things
+ self.iface.mapCanvas().freeze(False) # done to speedup things
return loadedDict
def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict):
@@ -242,11 +274,13 @@ def loadLayer(self, inputParam, parentNode, uniqueLoad, stylePath, domLayerDict)
lyr = self.checkLoaded(tableName)
if uniqueLoad and lyr:
return lyr
- self.setDataSource('', '_'.join([schema,tableName]), geomColumn, '')
+ self.setDataSource("", "_".join([schema, tableName]), geomColumn, "")
vlayer = QgsVectorLayer(self.uri.uri(), tableName, self.provider)
- QgsProject.instance().addMapLayer(vlayer, addToLegend = False)
- crs = QgsCoordinateReferenceSystem(int(srid), QgsCoordinateReferenceSystem.EpsgCrsId)
+ QgsProject.instance().addMapLayer(vlayer, addToLegend=False)
+ crs = QgsCoordinateReferenceSystem(
+ int(srid), QgsCoordinateReferenceSystem.EpsgCrsId
+ )
vlayer.setCrs(crs)
# vlayer = self.setDomainsAndRestrictionsWithQml(vlayer)
# vlayer = self.setMulti(vlayer, domLayerDict)
@@ -282,11 +316,11 @@ def loadDomain(self, domainTableName, domainGroup):
:param domainGroup:
:return:
"""
- #TODO: Avaliar se o table = deve ser diferente
+ # TODO: Avaliar se o table = deve ser diferente
uri = QgsDataSourceUri()
uri.setDatabase(self.abstractDb.db.databaseName())
- uri.setDataSource('', 'dominios_'+domainTableName, None)
- #TODO Load domain layer into a group
+ uri.setDataSource("", "dominios_" + domainTableName, None)
+ # TODO Load domain layer into a group
domLayer = self.iface.addVectorLayer(uri.uri(), domainTableName, self.provider)
self.iface.legendInterface().moveLayer(domLayer, domainGroup)
return domLayer
@@ -294,7 +328,9 @@ def loadDomain(self, domainTableName, domainGroup):
def getStyleFromDb(self, edgvVersion, className):
return None
- def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilterList):
+ def filterLayerList(
+ self, layerList, useInheritance, onlyWithElements, geomFilterList
+ ):
"""
Filters the layers to be loaded
:param layerList: list of layers
@@ -305,7 +341,9 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte
"""
filterList = []
if onlyWithElements:
- semifinalList = self.abstractDb.getLayersWithElementsV2(layerList, useInheritance=False)
+ semifinalList = self.abstractDb.getLayersWithElementsV2(
+ layerList, useInheritance=False
+ )
else:
semifinalList = layerList
if len(geomFilterList) > 0:
@@ -314,12 +352,12 @@ def filterLayerList(self, layerList, useInheritance, onlyWithElements, geomFilte
if self.correspondenceDict[key] in geomFilterList:
if key in self.geomTypeDict:
for lyr in semifinalList:
- if lyr in self.geomTypeDict[key] and lyr not in finalList:
+ if lyr in self.geomTypeDict[key] and lyr not in finalList:
finalList.append(lyr)
else:
finalList = semifinalList
return finalList
-
+
def setMulti(self, vlayer, domLayerDict):
"""
Sets attributes with value relation
@@ -327,15 +365,15 @@ def setMulti(self, vlayer, domLayerDict):
:param domLayerDict:
:return:
"""
- #sweep vlayer to find v2
+ # sweep vlayer to find v2
attrList = vlayer.fields()
for field in attrList:
i = attrList.lookupField(field.name())
editorWidgetSetup = vlayer.editorWidgetSetup(i)
- if editorWidgetSetup.type() == 'ValueRelation':
+ if editorWidgetSetup.type() == "ValueRelation":
valueRelationDict = editorWidgetSetup.config()
domLayer = domLayerDict[vlayer.name()][field.name()]
- valueRelationDict['Layer'] = domLayer.id()
+ valueRelationDict["Layer"] = domLayer.id()
vlayer.setEditorWidgetSetup(i, valueRelationDict)
return vlayer
@@ -343,11 +381,11 @@ def getLayerByName(self, layer):
"""
Return the layer layer from a given layer name.
:param layer: (str) layer name.
- :return: (QgsVectorLayer) vector layer.
+ :return: (QgsVectorLayer) vector layer.
"""
# parent class reimplementation
- schema = layer.split('_')[0]
- table = layer[len(schema) + 1:]
+ schema = layer.split("_")[0]
+ table = layer[len(schema) + 1 :]
lyrName, schema, geomColumn, tableName, srid = self.getParams(table)
- self.setDataSource('', layer, geomColumn, '')
+ self.setDataSource("", layer, geomColumn, "")
return QgsVectorLayer(self.uri.uri(), table, self.provider)
diff --git a/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py b/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py
index bb2386d58..23cf7cac0 100644
--- a/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py
+++ b/DsgTools/core/Factories/SqlFactory/geopackageSqlGenerator.py
@@ -23,8 +23,8 @@
from .spatialiteSqlGenerator import SpatialiteSqlGenerator
from DsgTools.core.dsgEnums import DsgEnums
-class GeopackageSqlGenerator(SpatialiteSqlGenerator):
+class GeopackageSqlGenerator(SpatialiteSqlGenerator):
def getEDGVVersion(self):
"""
Gets the version of the data model.
@@ -32,7 +32,7 @@ def getEDGVVersion(self):
sql = "SELECT edgvversion FROM db_metadata LIMIT 1"
return sql
- def getSrid(self, parameters = dict()):
+ def getSrid(self, parameters=dict()):
"""
Gets SRID for selected database (it is assumed all tables have the same SRID).
"""
@@ -43,7 +43,7 @@ def getGeomTablesFromGeometryColumns(self, edgvVersion):
"""
Gets a dict for tables and their geometry columns.
"""
- sql = 'select srs_id, column_name, geometry_type_name, table_name from gpkg_geometry_columns'
+ sql = "select srs_id, column_name, geometry_type_name, table_name from gpkg_geometry_columns"
return sql
def getGeomByPrimitive(self, edgvVersion):
@@ -55,11 +55,13 @@ def getGeomColumnDict(self):
return sql
def getFullTablesName(self, name):
- sql = "SELECT table_name as name FROM gpkg_geometry_columns WHERE table_name LIKE '%{0}%' ORDER BY name".format(name)
+ sql = "SELECT table_name as name FROM gpkg_geometry_columns WHERE table_name LIKE '%{0}%' ORDER BY name".format(
+ name
+ )
return sql
- def getGeomColumnTupleList(self, edgvVersion, showViews = False):
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
+ def getGeomColumnTupleList(self, edgvVersion, showViews=False):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
sql = """select table_name, column_name, geometry_type_name from gpkg_geometry_columns"""
else:
sql = """select table_name, column_name, geometry_type_name from gpkg_geometry_columns"""
@@ -69,14 +71,16 @@ def getTablesFromDatabase(self):
sql = "SELECT tbl_name as name, type FROM sqlite_master WHERE type='table' ORDER BY name"
return sql
- def getStructure(self,edgvVersion):
- sql = ''
- if edgvVersion == '2.1.3':
- sql = 'select tbl_name as name, sql from sqlite_master where type = \'table\' and (name like \'cb_%\' or name like \'complexos_%\' or name like \'public_%\')'
- elif edgvVersion == 'FTer_2a_Ed':
- sql = 'select tbl_name as name, sql from sqlite_master where type = \'table\' and (name like \'ge_%\' or name like \'pe_%\' or name like \'complexos_%\' or name like \'public_%\')'
- elif edgvVersion == '3.0':
- sql = sql = 'select tbl_name as name, sql from sqlite_master where type = \'table\' and (name like \'edgv_%\' or name like \'complexos_%\' or name like \'public_%\')'
+ def getStructure(self, edgvVersion):
+ sql = ""
+ if edgvVersion == "2.1.3":
+ sql = "select tbl_name as name, sql from sqlite_master where type = 'table' and (name like 'cb_%' or name like 'complexos_%' or name like 'public_%')"
+ elif edgvVersion == "FTer_2a_Ed":
+ sql = "select tbl_name as name, sql from sqlite_master where type = 'table' and (name like 'ge_%' or name like 'pe_%' or name like 'complexos_%' or name like 'public_%')"
+ elif edgvVersion == "3.0":
+ sql = (
+ sql
+ ) = "select tbl_name as name, sql from sqlite_master where type = 'table' and (name like 'edgv_%' or name like 'complexos_%' or name like 'public_%')"
return sql
def getComplexTablesFromDatabase(self):
diff --git a/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py b/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py
index b9cd110e7..a6e806cfa 100644
--- a/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py
+++ b/DsgTools/core/Factories/SqlFactory/postgisSqlGenerator.py
@@ -25,11 +25,16 @@
from .sqlGenerator import SqlGenerator
from ...dsgEnums import DsgEnums
-DB_ENCODING = 'utf-8'
+DB_ENCODING = "utf-8"
+
+
class PostGISSqlGenerator(SqlGenerator):
-
def getComplexLinks(self, complex):
- sql = "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from complex_schema where complex = \'"+complex+'\''
+ sql = (
+ "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from complex_schema where complex = '"
+ + complex
+ + "'"
+ )
return sql
def getComplexTablesFromDatabase(self):
@@ -37,38 +42,76 @@ def getComplexTablesFromDatabase(self):
return sql
def getComplexData(self, complex_schema, complex):
- sql = "SELECT id, nome from "+complex_schema+"."+complex
- return sql
-
- def getAssociatedFeaturesData(self, aggregated_schema, aggregated_class, column_name, complex_uuid):
- sql = "SELECT id from only "+aggregated_schema+"."+aggregated_class+" where "+column_name+"="+'\''+complex_uuid+'\''
+ sql = "SELECT id, nome from " + complex_schema + "." + complex
+ return sql
+
+ def getAssociatedFeaturesData(
+ self, aggregated_schema, aggregated_class, column_name, complex_uuid
+ ):
+ sql = (
+ "SELECT id from only "
+ + aggregated_schema
+ + "."
+ + aggregated_class
+ + " where "
+ + column_name
+ + "="
+ + "'"
+ + complex_uuid
+ + "'"
+ )
return sql
def getLinkColumn(self, complexClass, aggregatedClass):
- sql = "SELECT column_name from complex_schema where complex = \'"+complexClass+'\''+" and aggregated_class = "+'\''+aggregatedClass+'\''
+ sql = (
+ "SELECT column_name from complex_schema where complex = '"
+ + complexClass
+ + "'"
+ + " and aggregated_class = "
+ + "'"
+ + aggregatedClass
+ + "'"
+ )
return sql
- def getSrid(self, parameters = dict()):
+ def getSrid(self, parameters=dict()):
if parameters == dict():
- sql = "SELECT DISTINCT srid from geometry_columns WHERE f_table_schema <> \'tiger\' and f_table_schema <> \'topology\' LIMIT 1"
+ sql = "SELECT DISTINCT srid from geometry_columns WHERE f_table_schema <> 'tiger' and f_table_schema <> 'topology' LIMIT 1"
else:
whereClauseList = []
- if 'tableSchema' in list(parameters.keys()):
- whereClauseList.append("""f_table_schema = '{0}'""".format(parameters['tableSchema']))
- if 'tableName' in list(parameters.keys()):
- whereClauseList.append("""f_table_name = '{0}'""".format(parameters['tableName']))
- if 'geometryColumn' in list(parameters.keys()):
- whereClauseList.append("""f_geometry_column = '{0}'""".format(parameters['geometryColumn']))
- whereClause = ' AND '.join(whereClauseList)
- sql = """SELECT DISTINCT srid from geometry_columns WHERE {0} LIMIT 1""".format(whereClause)
+ if "tableSchema" in list(parameters.keys()):
+ whereClauseList.append(
+ """f_table_schema = '{0}'""".format(parameters["tableSchema"])
+ )
+ if "tableName" in list(parameters.keys()):
+ whereClauseList.append(
+ """f_table_name = '{0}'""".format(parameters["tableName"])
+ )
+ if "geometryColumn" in list(parameters.keys()):
+ whereClauseList.append(
+ """f_geometry_column = '{0}'""".format(parameters["geometryColumn"])
+ )
+ whereClause = " AND ".join(whereClauseList)
+ sql = """SELECT DISTINCT srid from geometry_columns WHERE {0} LIMIT 1""".format(
+ whereClause
+ )
return sql
def getTablesFromDatabase(self):
- sql = "select distinct table_schema, table_name from information_schema.columns where (table_schema <> \'dominios\' and table_schema <> \'topology\')"
+ sql = "select distinct table_schema, table_name from information_schema.columns where (table_schema <> 'dominios' and table_schema <> 'topology')"
return sql
def disassociateComplexFromComplex(self, aggregated_class, link_column, uuid):
- sql = "UPDATE complexos."+aggregated_class+" SET "+link_column+"=NULL WHERE id = "+'\''+uuid+'\''
+ sql = (
+ "UPDATE complexos."
+ + aggregated_class
+ + " SET "
+ + link_column
+ + "=NULL WHERE id = "
+ + "'"
+ + uuid
+ + "'"
+ )
return sql
def getTemplates(self):
@@ -76,89 +119,125 @@ def getTemplates(self):
return sql
def allowConnections(self, name):
- sql = "ALTER DATABASE "+name+" SET search_path = public, topology, cb, cc, complexos, ct;"
+ sql = (
+ "ALTER DATABASE "
+ + name
+ + " SET search_path = public, topology, cb, cc, complexos, ct;"
+ )
return sql
- def loadLayerFromDatabase(self, layer_name, pkColumn='id'):
- layer_name = '"."'.join(layer_name.replace('"','').split('.'))
- sql = '''{1} in (SELECT {1} FROM ONLY "{0}")'''.format(layer_name, pkColumn)
+ def loadLayerFromDatabase(self, layer_name, pkColumn="id"):
+ layer_name = '"."'.join(layer_name.replace('"', "").split("."))
+ sql = """{1} in (SELECT {1} FROM ONLY "{0}")""".format(layer_name, pkColumn)
return sql
- def loadLayerFromDatabaseUsingInh(self, layer_name, pkColumn='id'):
- layer_name = '"."'.join(layer_name.replace('"','').split('.'))
- sql = '''{1} in (SELECT {1} FROM ONLY "{0}")'''.format(layer_name, pkColumn)
+ def loadLayerFromDatabaseUsingInh(self, layer_name, pkColumn="id"):
+ layer_name = '"."'.join(layer_name.replace('"', "").split("."))
+ sql = """{1} in (SELECT {1} FROM ONLY "{0}")""".format(layer_name, pkColumn)
return sql
- def getCreateDatabase(self, name, dropIfExists = False):
- sql = ''
+ def getCreateDatabase(self, name, dropIfExists=False):
+ sql = ""
if dropIfExists:
- sql+= """DROP DATABASE IF EXISTS "{0}";""".format(name)
+ sql += """DROP DATABASE IF EXISTS "{0}";""".format(name)
sql += """CREATE DATABASE "{0}";""".format(name)
return sql
def insertFrameIntoTable(self, wkt):
- sql = "INSERT INTO aux_moldura_a(geom) VALUES(ST_GeomFromText("+wkt+"))"
+ sql = "INSERT INTO aux_moldura_a(geom) VALUES(ST_GeomFromText(" + wkt + "))"
return sql
def getElementCountFromLayer(self, table):
sql = "SELECT count(id) FROM ONLY {0} limit 1".format(table)
return sql
-
+
def getElementCountFromLayerV2(self, schema, table, useInheritance):
if useInheritance == False:
- sql = '''SELECT count(a) FROM ( SELECT * FROM ONLY "{0}"."{1}" ) as a'''.format(schema,table)
+ sql = """SELECT count(a) FROM ( SELECT * FROM ONLY "{0}"."{1}" ) as a""".format(
+ schema, table
+ )
else:
- sql = '''SELECT count(a) FROM ( SELECT * FROM "{0}"."{1}" ) as a'''.format(schema,table)
+ sql = """SELECT count(a) FROM ( SELECT * FROM "{0}"."{1}" ) as a""".format(
+ schema, table
+ )
return sql
def getElementCountFromLayerWithInh(self, layer):
- sql = "SELECT count(*) FROM "+layer
+ sql = "SELECT count(*) FROM " + layer
return sql
-
+
def getDatabasesFromServer(self):
- sql = "SELECT datname FROM pg_database where datname <> \'postgres\' and datname <> \'template\' and datname <> \'template0\' and datname <> \'template_postgis\' and datistemplate = 'f'"
+ sql = "SELECT datname FROM pg_database where datname <> 'postgres' and datname <> 'template' and datname <> 'template0' and datname <> 'template_postgis' and datistemplate = 'f'"
return sql
-
+
def dropDatabase(self, name):
sql = """DROP DATABASE "{0}" """.format(name)
return sql
-
+
def createRole(self, roleName, mydict):
sql = """CREATE ROLE "{0}" with NOLOGIN REPLICATION;\n""".format(roleName)
for db in list(mydict.keys()):
for schema in list(mydict[db].keys()):
for cat in list(mydict[db][schema].keys()):
for tableName in list(mydict[db][schema][cat].keys()):
- table = '''"{0}"."{1}"'''.format(schema,tableName)
+ table = '''"{0}"."{1}"'''.format(schema, tableName)
read = mydict[db][schema][cat][tableName]["read"]
write = mydict[db][schema][cat][tableName]["write"]
- if write == '2':
- sql+="""GRANT ALL ON {0} TO "{1}";\n""".format(table,roleName)
- elif read == '2':
- sql+="""GRANT SELECT ON {0} TO "{1}";\n""".format(table,roleName)
- sql += """GRANT ALL ON SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName)
- sql += """REVOKE CREATE ON SCHEMA "{0}" FROM "{1}";\n""".format(schema,roleName)
- sql += """GRANT USAGE ON SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName)
- sql += """GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName)
- sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA "{0}" TO "{1}";\n""".format(schema,roleName)
-
+ if write == "2":
+ sql += """GRANT ALL ON {0} TO "{1}";\n""".format(
+ table, roleName
+ )
+ elif read == "2":
+ sql += """GRANT SELECT ON {0} TO "{1}";\n""".format(
+ table, roleName
+ )
+ sql += """GRANT ALL ON SCHEMA "{0}" TO "{1}";\n""".format(
+ schema, roleName
+ )
+ sql += """REVOKE CREATE ON SCHEMA "{0}" FROM "{1}";\n""".format(
+ schema, roleName
+ )
+ sql += """GRANT USAGE ON SCHEMA "{0}" TO "{1}";\n""".format(
+ schema, roleName
+ )
+ sql += """GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA "{0}" TO "{1}";\n""".format(
+ schema, roleName
+ )
+ sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA "{0}" TO "{1}";\n""".format(
+ schema, roleName
+ )
+
# not needed anymore due to our generic approach
- #sql += """GRANT SELECT ON db_metadata TO "{0}";\n""".format(roleName)
- sql += """GRANT SELECT ON public.geometry_columns TO "{0}";\n""".format(roleName)
- sql += """GRANT ALL ON ALL TABLES IN SCHEMA information_schema TO "{0}";\n""".format(roleName)
- sql += """GRANT ALL ON ALL TABLES IN SCHEMA pg_catalog TO "{0}";\n""".format(roleName)
+ # sql += """GRANT SELECT ON db_metadata TO "{0}";\n""".format(roleName)
+ sql += """GRANT SELECT ON public.geometry_columns TO "{0}";\n""".format(
+ roleName
+ )
+ sql += """GRANT ALL ON ALL TABLES IN SCHEMA information_schema TO "{0}";\n""".format(
+ roleName
+ )
+ sql += """GRANT ALL ON ALL TABLES IN SCHEMA pg_catalog TO "{0}";\n""".format(
+ roleName
+ )
sql += """GRANT ALL ON SCHEMA information_schema TO "{0}";\n""".format(roleName)
sql += """GRANT ALL ON SCHEMA pg_catalog TO "{0}";\n""".format(roleName)
- sql += """REVOKE CREATE ON SCHEMA information_schema FROM "{0}";\n""".format(roleName)
+ sql += """REVOKE CREATE ON SCHEMA information_schema FROM "{0}";\n""".format(
+ roleName
+ )
sql += """REVOKE CREATE ON SCHEMA pg_catalog FROM "{0}";\n""".format(roleName)
- sql += """GRANT USAGE ON SCHEMA information_schema TO "{0}";\n""".format(roleName)
+ sql += """GRANT USAGE ON SCHEMA information_schema TO "{0}";\n""".format(
+ roleName
+ )
sql += """GRANT USAGE ON SCHEMA pg_catalog TO "{0}";\n""".format(roleName)
- sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA information_schema TO "{0}";\n""".format(roleName)
- sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA pg_catalog TO "{0}" """.format(roleName)
+ sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA information_schema TO "{0}";\n""".format(
+ roleName
+ )
+ sql += """GRANT USAGE ON ALL SEQUENCES IN SCHEMA pg_catalog TO "{0}" """.format(
+ roleName
+ )
return sql
def dropRole(self, role):
- sql = '''CREATE OR REPLACE FUNCTION droprole(name text) RETURNS void AS $BODY$
+ sql = """CREATE OR REPLACE FUNCTION droprole(name text) RETURNS void AS $BODY$
DECLARE
s text;
BEGIN
@@ -180,119 +259,140 @@ def dropRole(self, role):
END LOOP;
EXECUTE 'REVOKE ALL ON db_metadata FROM '|| name;
RETURN;
-
+
END
$BODY$ LANGUAGE plpgsql;#
- '''
- sql += 'SELECT droprole(\''+role+'\')#'
- sql += 'DROP ROLE IF EXISTS '+role
+ """
+ sql += "SELECT droprole('" + role + "')#"
+ sql += "DROP ROLE IF EXISTS " + role
return sql
-
+
def grantRole(self, user, role):
- sql = 'GRANT '+role+' TO '+user
+ sql = "GRANT " + role + " TO " + user
return sql
-
+
def revokeRole(self, user, role):
- sql = 'REVOKE '+role+' FROM '+user
+ sql = "REVOKE " + role + " FROM " + user
return sql
-
+
def getRoles(self):
- sql = 'SELECT rolname FROM pg_roles WHERE rolname <> \'postgres\' AND rolcanlogin = \'f\' AND rolname in (select split_part(unnest(nspacl)::text, \'=\', 1) from pg_namespace where nspname = \'pg_catalog\')'
+ sql = "SELECT rolname FROM pg_roles WHERE rolname <> 'postgres' AND rolcanlogin = 'f' AND rolname in (select split_part(unnest(nspacl)::text, '=', 1) from pg_namespace where nspname = 'pg_catalog')"
return sql
def getUserRelatedRoles(self, username):
- sql = '''select rolname, usename from
- (select * from pg_roles as r where r.rolcanlogin = \'f\' and r.rolname<>\'postgres\') as listaRoles left join
- (select * from pg_auth_members as m join pg_user as u on m.member = u.usesysid and u.usename=\'%s\')
+ sql = (
+ """select rolname, usename from
+ (select * from pg_roles as r where r.rolcanlogin = \'f\' and r.rolname<>\'postgres\') as listaRoles left join
+ (select * from pg_auth_members as m join pg_user as u on m.member = u.usesysid and u.usename=\'%s\')
as euTenho on euTenho.roleid=listaRoles.oid where rolname in (select split_part(unnest(nspacl)::text, \'=\', 1) from pg_namespace where nspname = \'pg_catalog\')
- ''' % username
+ """
+ % username
+ )
return sql
-
+
def getUsers(self):
- sql = 'SELECT usename FROM pg_user WHERE usename <> \'postgres\''
+ sql = "SELECT usename FROM pg_user WHERE usename <> 'postgres'"
return sql
-
- def createUser(self,user,password,isSuperuser):
+
+ def createUser(self, user, password, isSuperuser):
if isSuperuser:
- sql = 'CREATE ROLE '+user+' WITH SUPERUSER CREATEDB CREATEROLE REPLICATION LOGIN PASSWORD \''+password+'\';'
+ sql = (
+ "CREATE ROLE "
+ + user
+ + " WITH SUPERUSER CREATEDB CREATEROLE REPLICATION LOGIN PASSWORD '"
+ + password
+ + "';"
+ )
else:
- sql = 'CREATE ROLE '+user+' WITH LOGIN PASSWORD \''+password+'\';'
- return sql
-
- def removeUser(self,user):
- sql = 'DROP ROLE '+user
- return sql
-
- def alterUserPass(self,user,newPass):
- sql = 'ALTER ROLE '+user+' WITH PASSWORD \''+newPass+'\''
- return sql
-
- def validateWithDomain(self,schemaList):
- schemas = '\''+'\',\''.join(schemaList)+'\''
- sql = '''SELECT
- tc.table_schema,tc.table_name, kcu.column_name,
+ sql = "CREATE ROLE " + user + " WITH LOGIN PASSWORD '" + password + "';"
+ return sql
+
+ def removeUser(self, user):
+ sql = "DROP ROLE " + user
+ return sql
+
+ def alterUserPass(self, user, newPass):
+ sql = "ALTER ROLE " + user + " WITH PASSWORD '" + newPass + "'"
+ return sql
+
+ def validateWithDomain(self, schemaList):
+ schemas = "'" + "','".join(schemaList) + "'"
+ sql = (
+ """SELECT
+ tc.table_schema,tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name,
'SELECT ' || ccu.column_name || ' FROM dominios.' || ccu.table_name || ' ORDER BY ' || ccu.column_name || ' ASC'
- FROM
- information_schema.table_constraints AS tc
+ FROM
+ information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
- WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)''' % schemas
+ WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)"""
+ % schemas
+ )
return sql
-
- def getTableDomains(self,tableList):
- schemas = '\''+'\',\''.join(tableList)+'\''
- sql = '''SELECT
- tc.table_schema,tc.table_name, kcu.column_name,
+
+ def getTableDomains(self, tableList):
+ schemas = "'" + "','".join(tableList) + "'"
+ sql = (
+ """SELECT
+ tc.table_schema,tc.table_name, kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name,
'SELECT ' || ccu.column_name || ' FROM dominios.' || ccu.table_name || ' ORDER BY ' || ccu.column_name || ' ASC'
- FROM
- information_schema.table_constraints AS tc
+ FROM
+ information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
- WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)''' % schemas
- return sql
-
- def getNotNullFields(self,schemaList):
- schemas = '\''+'\',\''.join(schemaList)+'\''
- sql = 'select table_schema, table_name, column_name from information_schema.columns where is_nullable = \'NO\' and column_name not in (\'id\',\'geom\') and table_schema in (%s)' % schemas
- return sql
-
- def getFeaturesWithSQL(self,layer,attrList):
- ls = ','.join(attrList)
- sql = 'SELECT %s FROM ONLY %s' % (ls,layer)
- return sql
-
- def getStructure(self,edgvVersion):
- sql = ''
- if edgvVersion == '2.1.3':
- sql = 'SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (\'cb\',\'complexos\',\'public\')'
- elif edgvVersion == 'FTer_2a_Ed':
- sql = 'SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (\'ge\',\'pe\',\'complexos\',\'public\')'
- elif edgvVersion == '3.0':
- sql = 'SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in (\'edgv\',\'complexos\',\'public\')'
- return sql
-
+ WHERE constraint_type = 'FOREIGN KEY' and tc.constraint_schema in (%s)"""
+ % schemas
+ )
+ return sql
+
+ def getNotNullFields(self, schemaList):
+ schemas = "'" + "','".join(schemaList) + "'"
+ sql = (
+ "select table_schema, table_name, column_name from information_schema.columns where is_nullable = 'NO' and column_name not in ('id','geom') and table_schema in (%s)"
+ % schemas
+ )
+ return sql
+
+ def getFeaturesWithSQL(self, layer, attrList):
+ ls = ",".join(attrList)
+ sql = "SELECT %s FROM ONLY %s" % (ls, layer)
+ return sql
+
+ def getStructure(self, edgvVersion):
+ sql = ""
+ if edgvVersion == "2.1.3":
+ sql = "SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in ('cb','complexos','public')"
+ elif edgvVersion == "FTer_2a_Ed":
+ sql = "SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in ('ge','pe','complexos','public')"
+ elif edgvVersion == "3.0":
+ sql = "SELECT table_schema, table_name, column_name FROM INFORMATION_SCHEMA.COLUMNS where table_schema in ('edgv','complexos','public')"
+ return sql
+
def getAggregationColumn(self):
- sql = 'SELECT DISTINCT column_name FROM public.complex_schema'
+ sql = "SELECT DISTINCT column_name FROM public.complex_schema"
return sql
-
+
def getAggregatorFromId(self, className, id):
- sql = 'SELECT id from %s where id =\'%s\'' % (className,id)
- return sql
-
- def getAggregatorFromComplexSchema(self,aggregated,aggregationColumn):
- sql = 'SELECT complex from public.complex_schema where aggregated_class = \'%s\' and aggregationColumn = \'%s\'' % (aggregated,aggregationColumn)
+ sql = "SELECT id from %s where id ='%s'" % (className, id)
+ return sql
+
+ def getAggregatorFromComplexSchema(self, aggregated, aggregationColumn):
+ sql = (
+ "SELECT complex from public.complex_schema where aggregated_class = '%s' and aggregationColumn = '%s'"
+ % (aggregated, aggregationColumn)
+ )
return sql
-
+
def createCustomSort(self):
- sql = '''CREATE OR REPLACE FUNCTION
+ sql = """CREATE OR REPLACE FUNCTION
array_sort_dsg(
array_vals_to_sort anyarray
)
@@ -314,23 +414,30 @@ def createCustomSort(self):
END;
$BODY$
LANGUAGE plpgsql;
- '''
+ """
return sql
-
+
def getRolePrivileges(self, role, dbname):
- sql = 'SELECT * FROM information_schema.role_table_grants where grantee = \'%s\' and table_catalog = \'%s\' ORDER BY table_name' % (role, dbname)
+ sql = (
+ "SELECT * FROM information_schema.role_table_grants where grantee = '%s' and table_catalog = '%s' ORDER BY table_name"
+ % (role, dbname)
+ )
return sql
-
- def isSuperUser(self,user):
- sql = 'SELECT rolsuper FROM pg_roles WHERE rolname = \'%s\'' % user
+
+ def isSuperUser(self, user):
+ sql = "SELECT rolsuper FROM pg_roles WHERE rolname = '%s'" % user
return sql
def getInvalidGeom(self, tableSchema, tableName, geometryColumn, keyColumn):
- return '''select distinct f."{3}" as "{3}",(reason(ST_IsValidDetail(f."{2}",0))), (location(ST_IsValidDetail(f."{2}",0))) as "{2}" from (select "{3}", "{2}" from only "{0}"."{1}" where ST_IsValid("{2}") = 'f') as f'''.format(tableSchema, tableName, geometryColumn, keyColumn)
-
+ return """select distinct f."{3}" as "{3}",(reason(ST_IsValidDetail(f."{2}",0))), (location(ST_IsValidDetail(f."{2}",0))) as "{2}" from (select "{3}", "{2}" from only "{0}"."{1}" where ST_IsValid("{2}") = 'f') as f""".format(
+ tableSchema, tableName, geometryColumn, keyColumn
+ )
+
def getNonSimpleGeom(self, tableSchema, tableName):
- return '''select f.id as id,(reason(ST_IsValidDetail(f.geom,0))), (location(ST_IsValidDetail(f.geom,0))) as geom from (select id, geom from only "{0}"."{1}" where ST_IsSimple(geom) = 'f') as f'''.format(tableSchema,tableName)
-
+ return """select f.id as id,(reason(ST_IsValidDetail(f.geom,0))), (location(ST_IsValidDetail(f.geom,0))) as geom from (select id, geom from only "{0}"."{1}" where ST_IsSimple(geom) = 'f') as f""".format(
+ tableSchema, tableName
+ )
+
def checkValidationStructure(self):
return "select count(*) from information_schema.columns where table_name = 'aux_flags_validacao'"
@@ -348,22 +455,22 @@ def createValidationStructure(self, srid):
CONSTRAINT aux_flags_validacao_pk PRIMARY KEY (id)
WITH (FILLFACTOR = 100)
)#
-
+
CREATE TABLE validation.aux_flags_validacao_p (
geom geometry(MULTIPOINT, %s) NOT NULL,
CONSTRAINT aux_flags_validacao_p_pk PRIMARY KEY (id)
)INHERITS(validation.aux_flags_validacao)#
-
+
CREATE TABLE validation.aux_flags_validacao_l (
geom geometry(MULTILINESTRING, %s) NOT NULL,
CONSTRAINT aux_flags_validacao_l_pk PRIMARY KEY (id)
)INHERITS(validation.aux_flags_validacao)#
-
+
CREATE TABLE validation.aux_flags_validacao_a (
geom geometry(MULTIPOLYGON, %s) NOT NULL,
CONSTRAINT aux_flags_validacao_a_pk PRIMARY KEY (id)
)INHERITS(validation.aux_flags_validacao)#
-
+
CREATE TABLE validation.status
(
id smallint NOT NULL,
@@ -378,7 +485,7 @@ def createValidationStructure(self, srid):
finished timestamp NOT NULL default now(),
CONSTRAINT process_history_pk PRIMARY KEY (id),
CONSTRAINT process_history_status_fk FOREIGN KEY (status) REFERENCES validation.status (id) MATCH FULL ON UPDATE NO ACTION ON DELETE NO ACTION
-
+
)#
CREATE TABLE validation.settings(
id serial NOT NULL,
@@ -388,40 +495,75 @@ def createValidationStructure(self, srid):
CONSTRAINT settings_pk PRIMARY KEY (id)
)#
INSERT INTO validation.settings(earthcoverage) VALUES (NULL)#
- INSERT INTO validation.status(id,status) VALUES (0,'Not yet ran'), (1,'Finished'), (2,'Failed'), (3,'Running'), (4,'Finished with flags')
- """ % (srid, srid, srid)
+ INSERT INTO validation.status(id,status) VALUES (0,'Not yet ran'), (1,'Finished'), (2,'Failed'), (3,'Running'), (4,'Finished with flags')
+ """ % (
+ srid,
+ srid,
+ srid,
+ )
return sql
-
+
def validationStatus(self, processName):
- sql = "SELECT status FROM validation.process_history where process_name = '%s' ORDER BY finished DESC LIMIT 1; " % processName
+ sql = (
+ "SELECT status FROM validation.process_history where process_name = '%s' ORDER BY finished DESC LIMIT 1; "
+ % processName
+ )
return sql
-
+
def validationStatusText(self, processName):
- sql = "SELECT sta.status FROM validation.process_history as hist left join validation.status as sta on sta.id = hist.status where hist.process_name = '%s' ORDER BY hist.finished DESC LIMIT 1 " % processName
+ sql = (
+ "SELECT sta.status FROM validation.process_history as hist left join validation.status as sta on sta.id = hist.status where hist.process_name = '%s' ORDER BY hist.finished DESC LIMIT 1 "
+ % processName
+ )
return sql
-
- def setValidationStatusQuery(self, processName,log,status):
- sql = "INSERT INTO validation.process_history (process_name, log, status) values ('%s','%s',%s)" % (processName,log,status)
+
+ def setValidationStatusQuery(self, processName, log, status):
+ sql = (
+ "INSERT INTO validation.process_history (process_name, log, status) values ('%s','%s',%s)"
+ % (processName, log, status)
+ )
return sql
-
- def insertFlagIntoDb(self, layer, feat_id, reason, geom, srid, processName, dimension, geometryColumn, flagSRID):
+
+ def insertFlagIntoDb(
+ self,
+ layer,
+ feat_id,
+ reason,
+ geom,
+ srid,
+ processName,
+ dimension,
+ geometryColumn,
+ flagSRID,
+ ):
if dimension == 0:
- tableName = 'aux_flags_validacao_p'
+ tableName = "aux_flags_validacao_p"
elif dimension == 1:
- tableName = 'aux_flags_validacao_l'
+ tableName = "aux_flags_validacao_l"
elif dimension == 2:
- tableName = 'aux_flags_validacao_a'
- sql = u"""INSERT INTO validation.{0} (process_name, layer, feat_id, reason, geom, dimension, geometry_column) values
- ('{1}','{2}',{3},'{4}',ST_Transform(ST_SetSRID(ST_Multi('{5}'),{6}),{7}), {8}, '{9}');""".format(tableName, processName, layer, str(feat_id), reason, geom, srid, flagSRID, dimension, geometryColumn)
+ tableName = "aux_flags_validacao_a"
+ sql = """INSERT INTO validation.{0} (process_name, layer, feat_id, reason, geom, dimension, geometry_column) values
+ ('{1}','{2}',{3},'{4}',ST_Transform(ST_SetSRID(ST_Multi('{5}'),{6}),{7}), {8}, '{9}');""".format(
+ tableName,
+ processName,
+ layer,
+ str(feat_id),
+ reason,
+ geom,
+ srid,
+ flagSRID,
+ dimension,
+ geometryColumn,
+ )
return sql
-
+
def getRunningProc(self):
sql = "SELECT process_name, status FROM validation.process_history ORDER BY finished DESC LIMIT 1;"
return sql
-
+
def deleteFlags(self, processName=None, className=None, flagId=None):
if not processName and not className and not flagId:
- whereClause = ''
+ whereClause = ""
else:
clauseList = []
if processName:
@@ -438,85 +580,162 @@ def deleteFlags(self, processName=None, className=None, flagId=None):
except TypeError:
flagClause = """id = {0} """.format(flagId)
clauseList.append(flagClause)
- whereClause = """where {0}""".format(' AND '.join(clauseList))
+ whereClause = """where {0}""".format(" AND ".join(clauseList))
sql = """
- DELETE FROM validation.aux_flags_validacao_p
- WHERE id in
+ DELETE FROM validation.aux_flags_validacao_p
+ WHERE id in
(SELECT id FROM validation.aux_flags_validacao_p {0})#
-
- DELETE FROM validation.aux_flags_validacao_l
- WHERE id in
+
+ DELETE FROM validation.aux_flags_validacao_l
+ WHERE id in
(SELECT id FROM validation.aux_flags_validacao_l {0})#
- DELETE FROM validation.aux_flags_validacao_a
- WHERE id in
+ DELETE FROM validation.aux_flags_validacao_a
+ WHERE id in
(SELECT id FROM validation.aux_flags_validacao_a {0})
- """.format(whereClause)
+ """.format(
+ whereClause
+ )
return sql
-
- def testSpatialRule(self, class_a, necessity, predicate_function, class_b, min_card, max_card, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn):
- #TODO: Add SRIDS
- class_a = '"'+'"."'.join(class_a.replace('"','').split('.'))+'"'
- class_b = '"'+'"."'.join(class_b.replace('"','').split('.'))+'"'
+
+ def testSpatialRule(
+ self,
+ class_a,
+ necessity,
+ predicate_function,
+ class_b,
+ min_card,
+ max_card,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ ):
+ # TODO: Add SRIDS
+ class_a = '"' + '"."'.join(class_a.replace('"', "").split(".")) + '"'
+ class_b = '"' + '"."'.join(class_b.replace('"', "").split(".")) + '"'
# checking if the rule checks the layer with itself
- if class_a!=class_b:
- sameClassRestriction=''
+ if class_a != class_b:
+ sameClassRestriction = ""
else:
- sameClassRestriction=' WHERE a.{0} <> b.{1} '.format(aKeyColumn, bKeyColumn)
-
- if predicate_function == 'ST_Disjoint':
- if necessity == '\'f\'':
+ sameClassRestriction = " WHERE a.{0} <> b.{1} ".format(
+ aKeyColumn, bKeyColumn
+ )
+
+ if predicate_function == "ST_Disjoint":
+ if necessity == "'f'":
sql = """SELECT DISTINCT foo.id, foo.geom FROM
- (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom
+ (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom
FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo
WHERE foo.count > 0
- """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn)
- elif necessity == '\'t\'':
+ """.format(
+ predicate_function,
+ class_a,
+ class_b,
+ sameClassRestriction,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ )
+ elif necessity == "'t'":
sql = """SELECT DISTINCT foo.id, foo.geom FROM
- (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom
+ (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) = 'f' THEN 1 ELSE 0 END) count, a.{6} geom
FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo
WHERE foo.count = 0
- """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn)
+ """.format(
+ predicate_function,
+ class_a,
+ class_b,
+ sameClassRestriction,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ )
else:
- if necessity == '\'f\'':# must (be)
- if max_card == '*':
+ if necessity == "'f'": # must (be)
+ if max_card == "*":
sql = """SELECT DISTINCT foo.id, foo.geom FROM
- (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom
+ (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom
FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo
WHERE foo.count < {8}
- """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn, min_card)
+ """.format(
+ predicate_function,
+ class_a,
+ class_b,
+ sameClassRestriction,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ min_card,
+ )
elif min_card is None and max_card is None:
sql = """SELECT DISTINCT foo.id, foo.geom FROM
- (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom
+ (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom
FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo
WHERE foo.count != 0;
- """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn, min_card)
+ """.format(
+ predicate_function,
+ class_a,
+ class_b,
+ sameClassRestriction,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ min_card,
+ )
else:
sql = """SELECT DISTINCT foo.id, foo.geom FROM
- (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom
+ (SELECT a.{4} id, SUM(CASE WHEN {0}(a.{6},b.{7}) THEN 1 ELSE 0 END) count, a.{6} geom
FROM {1} as a,{2} as b {3} GROUP BY a.{4}, a.{6}) as foo
WHERE foo.count < {8} OR foo.count > {9}
- """.format(predicate_function, class_a, class_b, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn, min_card, max_card)
- elif necessity == '\'t\'':# must not (be)
- if class_a!=class_b:
- sameClassRestriction=''
+ """.format(
+ predicate_function,
+ class_a,
+ class_b,
+ sameClassRestriction,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ min_card,
+ max_card,
+ )
+ elif necessity == "'t'": # must not (be)
+ if class_a != class_b:
+ sameClassRestriction = ""
else:
- sameClassRestriction=' AND a.{0} <> b.{1} '.format(aKeyColumn, bKeyColumn)
-
+ sameClassRestriction = " AND a.{0} <> b.{1} ".format(
+ aKeyColumn, bKeyColumn
+ )
+
sql = """SELECT DISTINCT a.{5} id, (ST_Dump(ST_Intersection(a.{7}, b.{8}))).geom as geom
- FROM {0} as a, {1} as b
+ FROM {0} as a, {1} as b
WHERE {2}(a.{7},b.{8}) = {3} {4}
- """.format(class_a, class_b, predicate_function, necessity, sameClassRestriction, aKeyColumn, bKeyColumn, aGeomColumn, bGeomColumn)
+ """.format(
+ class_a,
+ class_b,
+ predicate_function,
+ necessity,
+ sameClassRestriction,
+ aKeyColumn,
+ bKeyColumn,
+ aGeomColumn,
+ bGeomColumn,
+ )
return sql
-
+
def getDimension(self, geom):
sql = "select ST_Dimension('%s')" % geom
return sql
-
- def getMulti(self,cl):
- #TODO: get pk
- cl = '"'+'"."'.join(cl.replace('"','').split('.'))+'"'
+
+ def getMulti(self, cl):
+ # TODO: get pk
+ cl = '"' + '"."'.join(cl.replace('"', "").split(".")) + '"'
sql = """select id from only {0} where ST_NumGeometries(geom) > 1""".format(cl)
return sql
@@ -524,26 +743,34 @@ def getDuplicatedGeom(self, schema, cl, geometryColumn, keyColumn):
sql = """select * from (
SELECT "{3}",
ROW_NUMBER() OVER(PARTITION BY "{2}" ORDER BY "{3}" asc) AS Row,
- geom FROM ONLY "{0}"."{1}"
+ geom FROM ONLY "{0}"."{1}"
) dups
- where
- dups.Row > 1""".format(schema, cl, geometryColumn, keyColumn)
+ where
+ dups.Row > 1""".format(
+ schema, cl, geometryColumn, keyColumn
+ )
return sql
-
+
def getSmallAreas(self, schema, cl, areaTolerance, geometryColumn, keyColumn):
sql = """select foo2."{4}", foo2."{3}" from (
- select "{4}", "{3}", ST_Area("{3}") as area from "{0}"."{1}"
- ) as foo2 where foo2.area < {2} order by foo2."{4}" """.format(schema, cl, areaTolerance, geometryColumn, keyColumn)
+ select "{4}", "{3}", ST_Area("{3}") as area from "{0}"."{1}"
+ ) as foo2 where foo2.area < {2} order by foo2."{4}" """.format(
+ schema, cl, areaTolerance, geometryColumn, keyColumn
+ )
return sql
-
+
def getSmallLines(self, schema, cl, areaTolerance, geometryColumn, keyColumn):
sql = """select foo2."{4}", foo2."{3}" from (
- select "{4}", "{3}", ST_Length("{3}") as len from "{0}"."{1}"
- ) as foo2 where len < {2} order by foo2."{4}" """.format(schema, cl, areaTolerance, geometryColumn, keyColumn)
+ select "{4}", "{3}", ST_Length("{3}") as len from "{0}"."{1}"
+ ) as foo2 where len < {2} order by foo2."{4}" """.format(
+ schema, cl, areaTolerance, geometryColumn, keyColumn
+ )
return sql
-
- def prepareVertexNearEdgesStruct(self, tableSchema, tableName, geometryColumn, keyColumn, geomType):
- if 'POLYGON' in geomType:
+
+ def prepareVertexNearEdgesStruct(
+ self, tableSchema, tableName, geometryColumn, keyColumn, geomType
+ ):
+ if "POLYGON" in geomType:
sql = """drop table if exists seg#
create temp table seg as (
SELECT segments."{3}" as "{3}", ST_MakeLine(sp,ep) as "{2}"
@@ -554,13 +781,15 @@ def prepareVertexNearEdgesStruct(self, tableSchema, tableName, geometryColumn, k
linestrings."{3}" as "{3}"
FROM
(SELECT "{3}" as "{3}", (ST_Dump(ST_Boundary("{2}"))).geom
- FROM only "{0}"."{1}"
+ FROM only "{0}"."{1}"
) AS linestrings
) AS segments)#
drop table if exists pontos#
create temp table pontos as select "{3}" as "{3}", (ST_DumpPoints("{2}")).geom as "{2}" from only "{0}"."{1}"#
create index pontos_gist on pontos using gist ("{2}")#
- create index seg_gist on seg using gist ("{2}")""".format(tableSchema, tableName, geometryColumn, keyColumn)
+ create index seg_gist on seg using gist ("{2}")""".format(
+ tableSchema, tableName, geometryColumn, keyColumn
+ )
else:
sql = """drop table if exists seg#
create temp table seg as (
@@ -572,37 +801,49 @@ def prepareVertexNearEdgesStruct(self, tableSchema, tableName, geometryColumn, k
linestrings."{3}" as "{3}"
FROM
(SELECT "{3}" as "{3}", (ST_Dump("{2}")).geom
- FROM only "{0}"."{1}"
+ FROM only "{0}"."{1}"
) AS linestrings
) AS segments)#
drop table if exists pontos#
create temp table pontos as select "{3}" as "{3}", (ST_DumpPoints("{2}")).geom as "{2}" from only "{0}"."{1}"#
create index pontos_gist on pontos using gist ("{2}")#
- create index seg_gist on seg using gist ("{2}")""".format(tableSchema, tableName, geometryColumn, keyColumn)
+ create index seg_gist on seg using gist ("{2}")""".format(
+ tableSchema, tableName, geometryColumn, keyColumn
+ )
return sql
def getVertexNearEdgesStruct(self, epsg, tol, geometryColumn, keyColumn):
- sql = """select pontos."{3}", ST_SetSRID(pontos."{2}",{0}) as "{2}" from pontos, seg where ST_DWithin(seg."{2}", pontos."{2}", {1}) and ST_Distance(seg."{2}", pontos."{2}") > 0""".format(epsg, tol, geometryColumn, keyColumn)
+ sql = """select pontos."{3}", ST_SetSRID(pontos."{2}",{0}) as "{2}" from pontos, seg where ST_DWithin(seg."{2}", pontos."{2}", {1}) and ST_Distance(seg."{2}", pontos."{2}") > 0""".format(
+ epsg, tol, geometryColumn, keyColumn
+ )
return sql
-
+
def deleteFeatures(self, schema, table, idList, keyColumn):
- sql = """DELETE FROM "{0}"."{1}"
- WHERE "{3}" in ({2})""".format(schema, table, ','.join(idList), keyColumn)
- return sql
-
- def deleteFeaturesNotIn(self,schema,table,idList):
- sql = """DELETE FROM "{0}"."{1}"
- WHERE id not in ({2})""" .format(schema,table,','.join(map(str,idList)))
- return sql
-
+ sql = """DELETE FROM "{0}"."{1}"
+ WHERE "{3}" in ({2})""".format(
+ schema, table, ",".join(idList), keyColumn
+ )
+ return sql
+
+ def deleteFeaturesNotIn(self, schema, table, idList):
+ sql = """DELETE FROM "{0}"."{1}"
+ WHERE id not in ({2})""".format(
+ schema, table, ",".join(map(str, idList))
+ )
+ return sql
+
def getNotSimple(self, tableSchema, tableName, geometryColumn, keyColumn):
sql = """select foo."{3}" as "{3}", ST_MULTI(st_startpoint(foo."{2}")) as "{2}" from (
- select "{3}" as "{3}", (ST_Dump(ST_Node(ST_SetSRID(ST_MakeValid("{2}"),ST_SRID("{2}"))))).geom as "{2}" from "{0}"."{1}"
- where ST_IsSimple("{2}") = 'f') as foo where st_equals(st_startpoint(foo."{2}"),st_endpoint(foo."{2}"))""".format(tableSchema, tableName, geometryColumn, keyColumn)
+ select "{3}" as "{3}", (ST_Dump(ST_Node(ST_SetSRID(ST_MakeValid("{2}"),ST_SRID("{2}"))))).geom as "{2}" from "{0}"."{1}"
+ where ST_IsSimple("{2}") = 'f') as foo where st_equals(st_startpoint(foo."{2}"),st_endpoint(foo."{2}"))""".format(
+ tableSchema, tableName, geometryColumn, keyColumn
+ )
return sql
- def getOutofBoundsAngles(self, tableSchema, tableName, angle, geometryColumn, geomType, keyColumn):
- if 'LINESTRING' in geomType:
+ def getOutofBoundsAngles(
+ self, tableSchema, tableName, angle, geometryColumn, geomType, keyColumn
+ ):
+ if "LINESTRING" in geomType:
sql = """
WITH result AS (SELECT points."{4}", points.anchor, (degrees
(
@@ -618,8 +859,10 @@ def getOutofBoundsAngles(self, tableSchema, tableName, angle, geometryColumn, ge
(SELECT "{4}" as "{4}", (ST_Dump("{3}")).geom as "{3}"
FROM only "{0}"."{1}"
) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
- select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format(tableSchema, tableName, angle, geometryColumn, keyColumn)
- elif 'POLYGON' in geomType:
+ select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format(
+ tableSchema, tableName, angle, geometryColumn, keyColumn
+ )
+ elif "POLYGON" in geomType:
sql = """
WITH result AS (SELECT points."{4}", points.anchor, (degrees
(
@@ -635,30 +878,41 @@ def getOutofBoundsAngles(self, tableSchema, tableName, angle, geometryColumn, ge
(SELECT "{4}" as "{4}", (ST_Dump(ST_Boundary(ST_ForceRHR((ST_Dump("{3}")).geom)))).geom as "{3}"
FROM only "{0}"."{1}"
) AS linestrings WHERE ST_NPoints(linestrings."{3}") > 2 ) as points)
- select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format(tableSchema, tableName, angle, geometryColumn, keyColumn)
+ select distinct "{4}", anchor, angle from result where (result.angle % 360) < {2} or result.angle > (360.0 - ({2} % 360.0))""".format(
+ tableSchema, tableName, angle, geometryColumn, keyColumn
+ )
return sql
-
+
def getFlagsByProcess(self, processName):
- sql = """select layer, feat_id, geometry_column from validation.aux_flags_validacao where process_name = '%s'""" % processName
+ sql = (
+ """select layer, feat_id, geometry_column from validation.aux_flags_validacao where process_name = '%s'"""
+ % processName
+ )
return sql
-
- def forceValidity(self, tableSchema, tableName, idList, srid, keyColumn, geometryColumn):
+
+ def forceValidity(
+ self, tableSchema, tableName, idList, srid, keyColumn, geometryColumn
+ ):
sql = """update "{0}"."{1}" set "{5}" = ST_Multi(result."{5}") from (
- select distinct parts."{4}", ST_Union(parts."{5}") as "{5}" from "{0}"."{1}" as source,
- (select "{4}" as "{4}", ST_Multi(((ST_Dump(ST_SetSRID(ST_MakeValid("{5}"), {3}))).geom)) as "{5}" from
+ select distinct parts."{4}", ST_Union(parts."{5}") as "{5}" from "{0}"."{1}" as source,
+ (select "{4}" as "{4}", ST_Multi(((ST_Dump(ST_SetSRID(ST_MakeValid("{5}"), {3}))).geom)) as "{5}" from
"{0}"."{1}" where "{4}" in ({2})) as parts where ST_GeometryType(parts."{5}") = ST_GeometryType(source."{5}") group by parts."{4}"
- ) as result where result."{4}" = "{0}"."{1}"."{4}" """.format(tableSchema, tableName, ','.join(idList), srid, keyColumn, geometryColumn)
+ ) as result where result."{4}" = "{0}"."{1}"."{4}" """.format(
+ tableSchema, tableName, ",".join(idList), srid, keyColumn, geometryColumn
+ )
return sql
-
+
def getTableExtent(self, tableSchema, tableName):
- #TODO: put geometry column
+ # TODO: put geometry column
sql = """
SELECT ST_XMin(ST_Extent(geom)), ST_XMax(ST_Extent(geom)), ST_YMin(ST_Extent(geom)), ST_YMax(ST_Extent(geom)) AS extent FROM "{0}"."{1}"
- """.format(tableSchema, tableName)
+ """.format(
+ tableSchema, tableName
+ )
return sql
-
- def getOrphanGeomTablesWithElements(self,loading = False):
- #TODO: Avaliate if deprecated
+
+ def getOrphanGeomTablesWithElements(self, loading=False):
+ # TODO: Avaliate if deprecated
if not loading:
sql = """
select pgcl2.n as tb from pg_class as pgcl
@@ -667,16 +921,16 @@ def getOrphanGeomTablesWithElements(self,loading = False):
left join pg_inherits as pginh on pginh.inhparent = pgcl.oid
join (select pgcl.oid, pgmsp.nspname as sc, pgcl.relname as n from pg_class as pgcl
join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid
- left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid)
+ left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid)
as pgcl2 on pgcl2.oid = pginh.inhrelid
where pgnsp.nspname in ('ge','pe', 'cb') and pgatt.attname IS NULL and pgcl.relkind = 'r'
- union
+ union
select distinct p.relname as tb from pg_class as p
- left join pg_inherits as inh on inh.inhrelid = p.oid
+ left join pg_inherits as inh on inh.inhrelid = p.oid
left join geometry_columns as gc on gc.f_table_name = p.relname
- where (inh.inhrelid IS NULL) and
+ where (inh.inhrelid IS NULL) and
gc.f_table_schema in ('cb', 'pe', 'ge')
-
+
order by tb
"""
else:
@@ -687,61 +941,67 @@ def getOrphanGeomTablesWithElements(self,loading = False):
left join pg_inherits as pginh on pginh.inhparent = pgcl.oid
join (select pgcl.oid, pgmsp.nspname as sc, pgcl.relname as n from pg_class as pgcl
join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid
- left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid)
+ left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid)
as pgcl2 on pgcl2.oid = pginh.inhrelid
where pgnsp.nspname in ('ge','pe', 'cb', 'public') and pgatt.attname IS NULL and pgcl.relkind = 'r'
- union
+ union
select distinct p.relname as tb from pg_class as p
- left join pg_inherits as inh on inh.inhrelid = p.oid
+ left join pg_inherits as inh on inh.inhrelid = p.oid
left join geometry_columns as gc on gc.f_table_name = p.relname
- where (inh.inhrelid IS NULL) and
+ where (inh.inhrelid IS NULL) and
gc.f_table_schema in ('cb', 'pe', 'ge', 'public')
-
+
order by tb
"""
return sql
-
+
def updateOriginalTable(self, tableSchema, tableName, result, epsg):
- #TODO: Put original id
+ # TODO: Put original id
sqls = []
for key in list(result.keys()):
geoms = []
for wkb in result[key]:
geoms.append("ST_SetSRID(ST_Multi('{0}'), {1})".format(wkb, epsg))
- array = ','.join(geoms)
- union = 'ST_Union(ARRAY[{}])'.format(array)
+ array = ",".join(geoms)
+ union = "ST_Union(ARRAY[{}])".format(array)
sql = """
UPDATE "{0}"."{1}" SET geom = ST_Multi({2}) WHERE id = {3}
- """.format(tableSchema, tableName, union, key)
+ """.format(
+ tableSchema, tableName, union, key
+ )
sqls.append(sql)
return sqls
-
+
def getOrphanTableElementCount(self, orphan):
- orphan = '"'+'"."'.join(orphan.replace('"','').split('.'))+'"'
+ orphan = '"' + '"."'.join(orphan.replace('"', "").split(".")) + '"'
sql = "select id from %s limit 1" % orphan
return sql
-
+
def checkCentroidAuxStruct(self):
sql = "select distinct count(column_name) from information_schema.columns where column_name = 'centroid' group by column_name"
return sql
-
+
def dropCentroid(self, table):
- table = '"'+'"."'.join(table.replace('"','').split('.'))+'"'
+ table = '"' + '"."'.join(table.replace('"', "").split(".")) + '"'
sql = "alter table %s drop column if exists centroid" % table
return sql
-
+
def createCentroidColumn(self, table_schema, table_name, srid):
sql = """alter table "{1}"."{2}" add column centroid geometry('POINT',{0})#
alter table "{1}"."{2}" alter column geom drop not null#
- CREATE INDEX {3} ON "{1}"."{2}" USING gist(centroid)""".format(srid,table_schema, table_name,table_name[:-2]+'_c_gist')
+ CREATE INDEX {3} ON "{1}"."{2}" USING gist(centroid)""".format(
+ srid, table_schema, table_name, table_name[:-2] + "_c_gist"
+ )
return sql
-
+
def createCentroidGist(self, table_schema, table_name):
- gistName = table_name[:-2]+'_c_gist'
- sql = '''CREATE INDEX {0} ON "{1}"."{2}" USING gist(centroid)'''.format(gistName,table_schema,table_name)
+ gistName = table_name[:-2] + "_c_gist"
+ sql = """CREATE INDEX {0} ON "{1}"."{2}" USING gist(centroid)""".format(
+ gistName, table_schema, table_name
+ )
return sql
-
+
def getEarthCoverageClasses(self):
sql = "select distinct table_schema || '.' || table_name from information_schema.columns where column_name = 'centroid'"
return sql
@@ -750,29 +1010,35 @@ def getEarthCoverageDict(self):
sql = "select earthcoverage from validation.settings limit 1"
return sql
- def setEarthCoverageDict(self,earthDict):
+ def setEarthCoverageDict(self, earthDict):
if earthDict:
sql = "update validation.settings set earthcoverage = '%s'" % earthDict
else:
sql = "update validation.settings set earthcoverage = NULL"
return sql
-
-
+
def makeRelationDict(self, table, codes):
- sql = """select code, code_name from dominios.%s where code in %s""" % (table, codes)
+ sql = """select code, code_name from dominios.%s where code in %s""" % (
+ table,
+ codes,
+ )
return sql
def getEarthCoverageCentroids(self):
sql = "select distinct table_name from information_schema.columns where column_name = 'centroid'"
return sql
-
+
def getWhoAmI(self, cl, id):
- sql = "select p.relname from {0} as c, pg_class as p where c.tableoid = p.oid and c.id = {1}".format(cl,id)
+ sql = "select p.relname from {0} as c, pg_class as p where c.tableoid = p.oid and c.id = {1}".format(
+ cl, id
+ )
return sql
-
- def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn):
- schema, table = cl.split('.')
- frameSchema, frameTable = frameTable.split('.')
+
+ def snapLinesToFrame(
+ self, cl, frameTable, tol, geometryColumn, keyColumn, frameGeometryColumn
+ ):
+ schema, table = cl.split(".")
+ frameSchema, frameTable = frameTable.split(".")
sql = """
update "{0}"."{1}" as classe set "{5}" = ST_Multi(agrupado."{5}")
from
@@ -780,11 +1046,11 @@ def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frame
select simplelines."{6}" as "{6}", ST_Union(simplelines.newline) as "{5}"
from
(
- select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom, 0,
+ select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom, 0,
ST_EndPoint(from_start)) as newline
from
( select a."{6}" as "{6}", a."{5}" as "{5}",
- ST_ShortestLine(st_startpoint((ST_Dump(a."{5}")).geom),
+ ST_ShortestLine(st_startpoint((ST_Dump(a."{5}")).geom),
ST_Boundary(m."{7}")) as from_start
from "{0}"."{1}" a, "{3}"."{4}" m
) as short
@@ -798,11 +1064,11 @@ def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frame
select simplelines."{6}" as "{6}", ST_Union(simplelines.newline) as "{5}"
from
(
- select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom,
+ select short."{6}", St_SetPoint((ST_Dump(short."{5}")).geom,
short.index - 1, ST_EndPoint(from_start)) as newline
from
( select a."{6}" as "{6}", a."{5}" as "{5}",
- ST_ShortestLine(st_endpoint((ST_Dump(a."{5}")).geom),
+ ST_ShortestLine(st_endpoint((ST_Dump(a."{5}")).geom),
ST_Boundary(m."{7}")) as from_start,
ST_NPoints((ST_Dump(a."{5}")).geom) as index
from "{0}"."{1}" a, "{3}"."{4}" m
@@ -810,93 +1076,116 @@ def snapLinesToFrame(self, cl, frameTable, tol, geometryColumn, keyColumn, frame
where ST_Length(from_start) < {2}
) as simplelines group by simplelines."{6}"
) as agrupado
- where classe."{6}" = agrupado."{6}"
- """.format(schema, table, str(tol), frameSchema, frameTable, geometryColumn, keyColumn, frameGeometryColumn)
+ where classe."{6}" = agrupado."{6}"
+ """.format(
+ schema,
+ table,
+ str(tol),
+ frameSchema,
+ frameTable,
+ geometryColumn,
+ keyColumn,
+ frameGeometryColumn,
+ )
return sql
-
- def densifyFrame(self, cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn):
- cl = '"'+'"."'.join(cl.replace('"','').split('.'))+'"'
- frameTable = '"'+'"."'.join(frameTable.replace('"','').split('.'))+'"'
+
+ def densifyFrame(
+ self, cl, frameTable, snapTolerance, geometryColumn, frameGeometryColumn
+ ):
+ cl = '"' + '"."'.join(cl.replace('"', "").split(".")) + '"'
+ frameTable = '"' + '"."'.join(frameTable.replace('"', "").split(".")) + '"'
sql = """
- update {2} m set {4} = st_multi(st_snap(m.{4},
+ update {2} m set {4} = st_multi(st_snap(m.{4},
foo.vertices, {1}))
from
(
- select st_union(st_boundary(a.{3})) as vertices from
+ select st_union(st_boundary(a.{3})) as vertices from
{0} a
- ) as foo
- """.format(cl, snapTolerance, frameTable, geometryColumn, frameGeometryColumn)
+ ) as foo
+ """.format(
+ cl, snapTolerance, frameTable, geometryColumn, frameGeometryColumn
+ )
return sql
def snapToGrid(self, cl, precision, srid, geometryColumn):
- schema, table = cl.split('.')
- sql = 'update "{0}"."{1}" set "{4}" = ST_SetSRID(ST_SnapToGrid("{4}",{2}),{3})'.format(schema, table, precision, srid, geometryColumn)
+ schema, table = cl.split(".")
+ sql = 'update "{0}"."{1}" set "{4}" = ST_SetSRID(ST_SnapToGrid("{4}",{2}),{3})'.format(
+ schema, table, precision, srid, geometryColumn
+ )
return sql
-
+
def makeRecursiveSnapFunction(self, geometryColumn, keyColumn):
sql = """
- CREATE OR REPLACE FUNCTION dsgsnap(tabela text, snap float) RETURNS void AS
+ CREATE OR REPLACE FUNCTION dsgsnap(tabela text, snap float) RETURNS void AS
$BODY$
DECLARE
id int;
BEGIN
FOR id in execute('select "{1}" from '||tabela)
LOOP
- EXECUTE
- 'update '||tabela||' as classe set "{0}" = st_multi(res."{0}")
- from
+ EXECUTE
+ 'update '||tabela||' as classe set "{0}" = st_multi(res."{0}")
+ from
(
- select st_snap(a."{0}", st_collect(b."{0}"), '||snap||') as "{0}", a."{1}" as "{1}"
- from '||tabela||' a, '||tabela||' b
+ select st_snap(a."{0}", st_collect(b."{0}"), '||snap||') as "{0}", a."{1}" as "{1}"
+ from '||tabela||' a, '||tabela||' b
where a."{1}" != b."{1}" and st_isempty(a."{0}") = FALSE and a."{1}" = '||id||'
group by a."{1}", a."{0}"
- ) as res
+ ) as res
where res."{1}" = classe."{1}" ';
END LOOP;
- RETURN;
+ RETURN;
END
$BODY$
LANGUAGE plpgsql;
- """.format(geometryColumn, keyColumn)
+ """.format(
+ geometryColumn, keyColumn
+ )
return sql
-
+
def executeRecursiveSnap(self, cl, tol):
- sql = 'SELECT dsgsnap(\'{0}\', {1})'.format(cl, str(tol))
+ sql = "SELECT dsgsnap('{0}', {1})".format(cl, str(tol))
return sql
-
+
def createTempTable(self, layerName):
- schema, tableName = layerName.split('.')
- sql = '''
+ schema, tableName = layerName.split(".")
+ sql = """
DROP TABLE IF EXISTS "{0}"."{1}_temp"#
CREATE TABLE "{0}"."{1}_temp" as (select * from "{0}"."{1}" where 1=2)
- '''.format(schema,tableName)
+ """.format(
+ schema, tableName
+ )
return sql
-
+
def dropTempTable(self, tableName):
- tableName = '"'+'"."'.join(tableName.replace('"','').split('.'))+'"'
- sql = '''DROP TABLE IF EXISTS {0}'''.format(tableName)
+ tableName = '"' + '"."'.join(tableName.replace('"', "").split(".")) + '"'
+ sql = """DROP TABLE IF EXISTS {0}""".format(tableName)
return sql
-
+
def populateTempTable(self, tableName, attributes, prepareValues):
- tableName = '"'+'"."'.join(tableName.split('.'))
- columnTupleString = '"'+'","'.join(map(str,attributes))+'"'
- valueTuppleString = ','.join(map(str,prepareValues))
- sql = """INSERT INTO {0}_temp"({1}) VALUES ({2})""".format(tableName, columnTupleString, valueTuppleString)
+ tableName = '"' + '"."'.join(tableName.split("."))
+ columnTupleString = '"' + '","'.join(map(str, attributes)) + '"'
+ valueTuppleString = ",".join(map(str, prepareValues))
+ sql = """INSERT INTO {0}_temp"({1}) VALUES ({2})""".format(
+ tableName, columnTupleString, valueTuppleString
+ )
return sql
-
- def createSpatialIndex(self, tableName, geomColumnName='geom'):
- tableName = '"'+'"."'.join(tableName.replace('"','').split('.'))
- sql = 'create index "{0}_temp_gist" on {1}_temp" using gist ({2})'.format(tableName.split('.')[-1].replace('"',''), tableName, geomColumnName)
+
+ def createSpatialIndex(self, tableName, geomColumnName="geom"):
+ tableName = '"' + '"."'.join(tableName.replace('"', "").split("."))
+ sql = 'create index "{0}_temp_gist" on {1}_temp" using gist ({2})'.format(
+ tableName.split(".")[-1].replace('"', ""), tableName, geomColumnName
+ )
return sql
-
+
def getStyles(self):
- sql = 'select description, f_table_schema, f_table_name, stylename from public.layer_styles where f_table_catalog = current_database()'
+ sql = "select description, f_table_schema, f_table_name, stylename from public.layer_styles where f_table_catalog = current_database()"
return sql
def checkStyleTable(self):
sql = "select relname from pg_class where relname = 'layer_styles' limit 1"
return sql
-
+
def createStyleTable(self):
sql = """
CREATE TABLE public.layer_styles
@@ -918,7 +1207,7 @@ def createStyleTable(self):
)
"""
return sql
-
+
def getStylesFromDb(self, dbVersion):
"""
Returns the stylenames of the database.
@@ -926,44 +1215,63 @@ def getStylesFromDb(self, dbVersion):
with previous DSGTools behaviour.
"""
sql = """
- select distinct replace(stylename,'/' || f_table_name, '')
- from public.layer_styles
+ select distinct replace(stylename,'/' || f_table_name, '')
+ from public.layer_styles
where f_table_catalog = current_database()
"""
return sql
-
+
def getStyle(self, styleName, table_name):
- sql = """SELECT styleqml from public.layer_styles where f_table_name = '{0}' and (stylename = '{1}' or stylename like '{1}/%')and f_table_catalog = current_database()""".format(table_name, styleName)
+ sql = """SELECT styleqml from public.layer_styles where f_table_name = '{0}' and (stylename = '{1}' or stylename like '{1}/%')and f_table_catalog = current_database()""".format(
+ table_name, styleName
+ )
return sql
-
+
def updateStyle(self, styleName, table_name, parsedQml, tableSchema):
- sql = """UPDATE public.layer_styles SET styleqml = '{0}', update_time = now() where f_table_name = '{1}' and description = '{2}'""".format(parsedQml.replace("'","''"),table_name, styleName)
+ sql = """UPDATE public.layer_styles SET styleqml = '{0}', update_time = now() where f_table_name = '{1}' and description = '{2}'""".format(
+ parsedQml.replace("'", "''"), table_name, styleName
+ )
return sql
-
+
def importStyle(self, styleName, table_name, parsedQml, tableSchema, dbName):
- #TODO:REDO it
- if table_name[-1] == 'c':
- geomColumn = 'centroid'
+ # TODO:REDO it
+ if table_name[-1] == "c":
+ geomColumn = "centroid"
else:
- geomColumn = 'geom'
- sql = """INSERT INTO public.layer_styles (styleqml, f_table_name, description, f_geometry_column, stylename, f_table_schema, f_table_catalog, useasdefault) VALUES ('"""+parsedQml.replace("'","''")+"""','{0}','{1}','{2}','{3}','{4}','{5}',FALSE)""".format(table_name, styleName, geomColumn, styleName.split('/')[-1]+'/'+table_name, tableSchema, dbName)
+ geomColumn = "geom"
+ sql = (
+ """INSERT INTO public.layer_styles (styleqml, f_table_name, description, f_geometry_column, stylename, f_table_schema, f_table_catalog, useasdefault) VALUES ('"""
+ + parsedQml.replace("'", "''")
+ + """','{0}','{1}','{2}','{3}','{4}','{5}',FALSE)""".format(
+ table_name,
+ styleName,
+ geomColumn,
+ styleName.split("/")[-1] + "/" + table_name,
+ tableSchema,
+ dbName,
+ )
+ )
return sql
-
+
def getTableSchemaFromDb(self, table):
- sql = """select distinct table_schema from information_schema.columns where table_name = '{0}' and table_schema not in ('validation','views')""".format(table)
+ sql = """select distinct table_schema from information_schema.columns where table_name = '{0}' and table_schema not in ('validation','views')""".format(
+ table
+ )
return sql
-
+
def getAllStylesFromDb(self):
sql = """SELECT DISTINCT f_table_catalog, description, f_table_name, update_time from public.layer_styles order by f_table_catalog, description, f_table_name asc """
return sql
-
+
def deleteStyle(self, styleName):
- sql = """delete from public.layer_styles where description = '{0}'""".format(styleName)
+ sql = """delete from public.layer_styles where description = '{0}'""".format(
+ styleName
+ )
return sql
-
+
# Atentar que a coluna consrc foi descontinuada no pg 12+ (issue #521)
# def getConstraints(self, schemaList):
- # sql = """select sch.nspname, cl.relname, c.conname, c.consrc from
+ # sql = """select sch.nspname, cl.relname, c.conname, c.consrc from
# (
# select * from pg_constraint where contype = 'c'
# ) as c join (
@@ -972,72 +1280,82 @@ def deleteStyle(self, styleName):
# left join pg_class as cl on c.conrelid = cl.oid
# """.format(','.schemaList)
# return sql
-
+
def getGeometricSchemas(self):
- sql = 'select distinct f_table_schema from public.geometry_columns'
+ sql = "select distinct f_table_schema from public.geometry_columns"
return sql
-
+
def getGeomTablesFromGeometryColumns(self):
- sql = 'select srid, f_geometry_column, type, f_table_schema, f_table_name from public.geometry_columns'
+ sql = "select srid, f_geometry_column, type, f_table_schema, f_table_name from public.geometry_columns"
return sql
-
- def getGeomTablesDomains(self, layerFilter = None):
- inClause = """'{text}'""".format(
- text='","'.join(layerFilter)
- ) if layerFilter \
+
+ def getGeomTablesDomains(self, layerFilter=None):
+ inClause = (
+ """'{text}'""".format(text='","'.join(layerFilter))
+ if layerFilter
else """select f_table_name from public.geometry_columns where f_table_schema <> 'views'"""
- sql = """select distinct case
+ )
+ sql = """select distinct case
when split_part(conrelid::regclass::text,'.',2) = '' then replace(split_part(conrelid::regclass::text,'.',1),'"','')
else replace(split_part(conrelid::regclass::text,'.',2),'"','')
- end as cl, pg_get_constraintdef(oid) FROM
- pg_constraint WHERE contype = 'f' and case
+ end as cl, pg_get_constraintdef(oid) FROM
+ pg_constraint WHERE contype = 'f' and case
when replace(split_part(conrelid::regclass::text,'.',2),'"','') = '' then replace(split_part(conrelid::regclass::text,'.',1),'"','')
else replace(split_part(conrelid::regclass::text,'.',2),'"','')
end in ({in_clause})
- """.format(in_clause=inClause)
+ """.format(
+ in_clause=inClause
+ )
return sql
-
- def getGeomTableConstraints(self, layerFilter = None):
- inClause = """'{text}'""".format(
- text='","'.join(layerFilter)
- ) if layerFilter \
+
+ def getGeomTableConstraints(self, layerFilter=None):
+ inClause = (
+ """'{text}'""".format(text='","'.join(layerFilter))
+ if layerFilter
else """select f_table_name from public.geometry_columns where f_table_schema <> 'views'"""
- sql = """select distinct case
+ )
+ sql = """select distinct case
when split_part(conrelid::regclass::text,'.',2) = '' then split_part(conrelid::regclass::text,'.',1)
else split_part(conrelid::regclass::text,'.',2)
- end as cl, pg_get_constraintdef(oid) FROM
- pg_constraint WHERE contype = 'c' and case
+ end as cl, pg_get_constraintdef(oid) FROM
+ pg_constraint WHERE contype = 'c' and case
when split_part(conrelid::regclass::text,'.',2) = '' then split_part(conrelid::regclass::text,'.',1)
else split_part(conrelid::regclass::text,'.',2)
end in ({in_clause})
order by cl
- """.format(in_clause=inClause)
+ """.format(
+ in_clause=inClause
+ )
return sql
-
+
def getMultiColumns(self, schemaList):
sql = """select row_to_json(a) from (
- select t.table_name, array_agg(t.column_name::text) as attributes from
- (select table_name, column_name from information_schema.columns
- where data_type = 'ARRAY' and table_schema in ({0})
+ select t.table_name, array_agg(t.column_name::text) as attributes from
+ (select table_name, column_name from information_schema.columns
+ where data_type = 'ARRAY' and table_schema in ({0})
) as t group by t.table_name
) as a
- """.format("'"+"','".join(schemaList)+"'")
+ """.format(
+ "'" + "','".join(schemaList) + "'"
+ )
return sql
-
+
def getMultiColumnsFromTableList(self, tableList):
sql = """select row_to_json(a) from (
- select t.table_name, array_agg(t.column_name::text) as attributes from
- (select table_name, column_name from information_schema.columns
- where data_type = 'ARRAY' and table_name in ({0})
+ select t.table_name, array_agg(t.column_name::text) as attributes from
+ (select table_name, column_name from information_schema.columns
+ where data_type = 'ARRAY' and table_name in ({0})
) as t group by t.table_name
) as a
- """.format("'"+"','".join(tableList)+"'")
+ """.format(
+ "'" + "','".join(tableList) + "'"
+ )
return sql
-
+
def getGeomByPrimitive(self):
sql = """select row_to_json(a) from (select type as geomtype, array_agg(f_table_name) as classlist from public.geometry_columns where f_table_schema not in ('views','topology') group by type) as a"""
return sql
-
+
def getTablesJsonList(self):
sql = """select row_to_json(a) from (select table_schema::text, table_name::text from information_schema.tables where table_schema not in ('pg_catalog', 'information_schema') order by table_schema, table_name) as a"""
return sql
@@ -1046,159 +1364,212 @@ def getGeomColumnDict(self):
sql = """select row_to_json(row(f_table_name, f_geometry_column)) from public.geometry_columns where f_table_schema not in ('views','topology')"""
return sql
- def getGeomColumnTupleList(self, showViews = False, filterList = None):
- filterLayersClause = 'AND f_table_name in ({table_name_list})'.format(
- table_name_list=','.join(filterList)
- ) if filterList else """ """
- showViewsClause = """ AND table_type = 'BASE TABLE'""" if not showViews else """ """
+ def getGeomColumnTupleList(self, showViews=False, filterList=None):
+ filterLayersClause = (
+ "AND f_table_name in ({table_name_list})".format(
+ table_name_list=",".join(filterList)
+ )
+ if filterList
+ else """ """
+ )
+ showViewsClause = (
+ """ AND table_type = 'BASE TABLE'""" if not showViews else """ """
+ )
sql = """select f_table_schema, f_table_name, f_geometry_column, type, table_type from (select distinct f_table_schema, f_table_name, f_geometry_column, type, f_table_schema || '.' || f_table_name as jc from public.geometry_columns as gc) as inn
left join (select table_schema || '.' || table_name as jc, table_type from information_schema.tables) as infs on inn.jc = infs.jc
where inn.type <> 'GEOMETRY' {where_layer_filter} {where_show_views}""".format(
- where_layer_filter=filterLayersClause,
- where_show_views=showViewsClause
- )
+ where_layer_filter=filterLayersClause, where_show_views=showViewsClause
+ )
return sql
-
+
def getNotNullDict(self, layerFilter=None):
- tableNameClause = """'{text}'""".format(
- text='","'.join(layerFilter)
- ) if layerFilter \
+ tableNameClause = (
+ """'{text}'""".format(text='","'.join(layerFilter))
+ if layerFilter
else """select distinct f_table_name from public.geometry_columns """
+ )
sql = """select row_to_json(row(table_name, table_schema, array_agg(column_name::text)))
- from information_schema.columns
- where table_name in ({table_name_clause})
+ from information_schema.columns
+ where table_name in ({table_name_clause})
and is_nullable = 'NO' and data_type = 'smallint'
group by table_name, table_schema
- """.format(table_name_clause=tableNameClause)
+ """.format(
+ table_name_clause=tableNameClause
+ )
return sql
-
+
def getTableMetadataDict(self, layerFilter=None):
sql = """select row_to_json(a) from (
select table_schema, table_name, column_name as attr_name, is_nullable::boolean as nullable, data_type as column_type, gc.f_geometry_column as geometry_column, gc.type as geometry_type
- from information_schema.columns as c
- left join public.geometry_columns as gc
+ from information_schema.columns as c
+ left join public.geometry_columns as gc
on c.table_name = gc.f_table_name and c.table_schema = gc.f_table_schema ) as a
where a.table_name in ({filter})
""".format(
- filter= """'{text}'""".format(
- text='","'.join(layerFilter)
- ) if layerFilter \
+ filter="""'{text}'""".format(text='","'.join(layerFilter))
+ if layerFilter
else """select f_table_name from public.geometry_columns where f_table_schema <> 'views'"""
)
return sql
-
+
def getDomainDict(self, domainTable):
- sql = """select row_to_json(row(code, code_name)) from {0}""".format(domainTable)
+ sql = """select row_to_json(row(code, code_name)) from {0}""".format(
+ domainTable
+ )
return sql
def getDomainCodeDict(self, domainTable):
- sql = """select row_to_json(a) from (select * from {0}) as a""".format(domainTable)
+ sql = """select row_to_json(a) from (select * from {0}) as a""".format(
+ domainTable
+ )
return sql
-
+
def getDomainCodeDictWithColumns(self, domainTable, refPk, otherKey):
sql = """select row_to_json(a) from (select {pk}, {fk} from {table}) as a""".format(
- table=domainTable,
- pk=refPk,
- fk=otherKey
- )
+ table=domainTable, pk=refPk, fk=otherKey
+ )
return sql
def getGeomStructDict(self):
sql = """select row_to_json(a) from (
- select table_name, array_agg(row_to_json(row(column_name::text, is_nullable))) from information_schema.columns where
- table_name in (select f_table_name from public.geometry_columns)
- and column_name not like 'id_%'
- and column_name not in ('id','geom')
+ select table_name, array_agg(row_to_json(row(column_name::text, is_nullable))) from information_schema.columns where
+ table_name in (select f_table_name from public.geometry_columns)
+ and column_name not like 'id_%'
+ and column_name not in ('id','geom')
and table_schema not in ('validation','views')
group by table_name
) as a
"""
return sql
-
- def insertFrame(self,scale,mi,inom,frame,srid,geoSrid, paramDict = dict()):
+
+ def insertFrame(self, scale, mi, inom, frame, srid, geoSrid, paramDict=dict()):
paramKeys = list(paramDict.keys())
- if 'tableSchema' not in paramKeys:
- tableSchema = 'public'
+ if "tableSchema" not in paramKeys:
+ tableSchema = "public"
else:
- tableSchema = paramDict['tableSchema']
- if 'tableName' not in paramKeys:
- tableName = 'aux_moldura_a'
+ tableSchema = paramDict["tableSchema"]
+ if "tableName" not in paramKeys:
+ tableName = "aux_moldura_a"
else:
- tableName = paramDict['tableName']
- if 'miAttr' not in paramKeys:
- miAttr = 'mi'
+ tableName = paramDict["tableName"]
+ if "miAttr" not in paramKeys:
+ miAttr = "mi"
else:
- miAttr = paramDict['miAttr']
- if 'inomAttr' not in paramKeys:
- inomAttr = 'inom'
+ miAttr = paramDict["miAttr"]
+ if "inomAttr" not in paramKeys:
+ inomAttr = "inom"
else:
- inomAttr = paramDict['inomAttr']
- if 'geom' not in paramKeys:
- geometryColumn = 'geom'
+ inomAttr = paramDict["inomAttr"]
+ if "geom" not in paramKeys:
+ geometryColumn = "geom"
else:
- geometryColumn = paramDict['geom']
- if 'geomType' not in paramKeys:
- geomType = 'MULTIPOLYGON'
+ geometryColumn = paramDict["geom"]
+ if "geomType" not in paramKeys:
+ geomType = "MULTIPOLYGON"
else:
- geomType = paramDict['geomType']
-
- if geomType == 'MULTIPOLYGON':
- sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform(ST_Multi(ST_GeomFromWKB({2},{3})), {4}))""".format(mi, inom, frame, geoSrid, srid, tableSchema, tableName, miAttr, inomAttr, geometryColumn)
+ geomType = paramDict["geomType"]
+
+ if geomType == "MULTIPOLYGON":
+ sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform(ST_Multi(ST_GeomFromWKB({2},{3})), {4}))""".format(
+ mi,
+ inom,
+ frame,
+ geoSrid,
+ srid,
+ tableSchema,
+ tableName,
+ miAttr,
+ inomAttr,
+ geometryColumn,
+ )
else:
- sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform((ST_SetSRID( (ST_Dump('{2}')).geom,{3})), {4}))""".format(mi, inom, frame, geoSrid, srid, tableSchema, tableName, miAttr, inomAttr, geometryColumn)
+ sql = """INSERT INTO "{5}"."{6}" ({7},{8},{9}) VALUES ('{0}','{1}',ST_Transform((ST_SetSRID( (ST_Dump('{2}')).geom,{3})), {4}))""".format(
+ mi,
+ inom,
+ frame,
+ geoSrid,
+ srid,
+ tableSchema,
+ tableName,
+ miAttr,
+ inomAttr,
+ geometryColumn,
+ )
return sql
-
- def createFromTemplate(self,dbName, templateName):
- sql = """CREATE DATABASE "{0}" with template = "{1}";""".format(dbName,templateName)
+
+ def createFromTemplate(self, dbName, templateName):
+ sql = """CREATE DATABASE "{0}" with template = "{1}";""".format(
+ dbName, templateName
+ )
return sql
-
+
def updateDbSRID(self, tableDict, srid):
- sql = """select UpdateGeometrySRID('{0}', '{1}', '{2}',{3})""".format(tableDict['tableSchema'], tableDict['tableName'], tableDict['geom'],srid)
+ sql = """select UpdateGeometrySRID('{0}', '{1}', '{2}',{3})""".format(
+ tableDict["tableSchema"], tableDict["tableName"], tableDict["geom"], srid
+ )
return sql
-
- def setDbAsTemplate(self, dbName, setTemplate = True):
+
+ def setDbAsTemplate(self, dbName, setTemplate=True):
if setTemplate:
- sql = """UPDATE pg_database set datistemplate = 't' where datname = '{0}';""".format(dbName)
+ sql = """UPDATE pg_database set datistemplate = 't' where datname = '{0}';""".format(
+ dbName
+ )
else:
- sql = """UPDATE pg_database set datistemplate = 'f' where datname = '{0}';""".format(dbName)
+ sql = """UPDATE pg_database set datistemplate = 'f' where datname = '{0}';""".format(
+ dbName
+ )
return sql
-
+
def checkTemplate(self):
sql = """select datname from pg_database where datistemplate = 't'"""
return sql
-
+
def checkIfTemplate(self, dbName):
- sql = """select datistemplate from pg_database where datname = '{0}'""".format(dbName)
+ sql = """select datistemplate from pg_database where datname = '{0}'""".format(
+ dbName
+ )
return sql
-
+
def alterSearchPath(self, dbName, version):
- if version == '2.1.3':
- sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'cb\',\'complexos\',\'dominios\';'.format(dbName)
- elif version == '2.1.3 Pro':
- sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'edgv\',\'dominios\';'.format(dbName)
- elif version == '3.0':
- sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'edgv\',\'complexos\',\'dominios\';'.format(dbName)
- elif version == 'FTer_2a_Ed':
- sql = 'ALTER DATABASE "{0}" SET search_path = "$user", public, topology,\'pe\',\'ge\',\'complexos\',\'dominios\';'.format(dbName)
- return sql
-
+ if version == "2.1.3":
+ sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'cb','complexos','dominios';".format(
+ dbName
+ )
+ elif version == "2.1.3 Pro":
+ sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'edgv','dominios';".format(
+ dbName
+ )
+ elif version == "3.0":
+ sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'edgv','complexos','dominios';".format(
+ dbName
+ )
+ elif version == "FTer_2a_Ed":
+ sql = "ALTER DATABASE \"{0}\" SET search_path = \"$user\", public, topology,'pe','ge','complexos','dominios';".format(
+ dbName
+ )
+ return sql
+
def getUsersFromServer(self):
sql = """SELECT usename, usesuper FROM pg_user WHERE usename <> 'postgres' order by usename"""
return sql
-
+
def reasignAndDropUser(self, user):
sql = """REASSIGN OWNED BY {0} to postgres; DROP USER {0};""".format(user)
return sql
def deleteFeatureFlagsFromDb(self, layer, feat_id, processName):
- sql = "DELETE FROM validation.aux_flags_validacao WHERE process_name = '{0}' AND layer = '{1}' AND feat_id = {2}".format(processName, layer, feat_id)
+ sql = "DELETE FROM validation.aux_flags_validacao WHERE process_name = '{0}' AND layer = '{1}' AND feat_id = {2}".format(
+ processName, layer, feat_id
+ )
return sql
-
+
def removeEmptyGeomtriesFromDb(self, layer, geometryColumn):
- schema, table = layer.split('.')
- sql = """DELETE FROM "{0}"."{1}" WHERE st_isempty("{2}") = TRUE""".format(schema, table, geometryColumn)
+ schema, table = layer.split(".")
+ sql = """DELETE FROM "{0}"."{1}" WHERE st_isempty("{2}") = TRUE""".format(
+ schema, table, geometryColumn
+ )
return sql
-
+
def hasAdminDb(self):
sql = """SELECT datname from pg_database where datname = 'dsgtools_admindb';"""
return sql
@@ -1211,163 +1582,188 @@ def getRolesDict(self):
return sql
def getSettingTable(self, settingType):
- if settingType == 'Permission':
- tableName = 'permission_profile'
- elif settingType == 'Customization':
- tableName = 'customization'
- elif settingType == 'EarthCoverage':
- tableName = 'earth_coverage'
- elif settingType == 'Style':
- tableName = 'style'
- elif settingType == 'FieldToolBoxConfig':
- tableName = 'field_toolbox_config'
- elif settingType == 'ValidationConfig':
- tableName = 'validation_config'
- elif settingType == 'AttributeRules':
- tableName = 'attribute_rules'
- elif settingType == 'SpatialRules':
- tableName = 'spatial_rules'
- elif settingType == 'ValidationWorkflow':
- tableName = 'validation_workflow'
+ if settingType == "Permission":
+ tableName = "permission_profile"
+ elif settingType == "Customization":
+ tableName = "customization"
+ elif settingType == "EarthCoverage":
+ tableName = "earth_coverage"
+ elif settingType == "Style":
+ tableName = "style"
+ elif settingType == "FieldToolBoxConfig":
+ tableName = "field_toolbox_config"
+ elif settingType == "ValidationConfig":
+ tableName = "validation_config"
+ elif settingType == "AttributeRules":
+ tableName = "attribute_rules"
+ elif settingType == "SpatialRules":
+ tableName = "spatial_rules"
+ elif settingType == "ValidationWorkflow":
+ tableName = "validation_workflow"
else:
- raise Exception('Setting type not defined!')
+ raise Exception("Setting type not defined!")
return tableName
def insertSettingIntoAdminDb(self, settingType, name, jsondict, edgvversion):
tableName = self.getSettingTable(settingType)
- sql = """INSERT INTO "public"."{0}" (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}'); """.format(tableName, name, jsondict, edgvversion)
+ sql = """INSERT INTO "public"."{0}" (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}'); """.format(
+ tableName, name, jsondict, edgvversion
+ )
return sql
-
+
def getSettingFromAdminDb(self, settingType, name, edgvversion):
tableName = self.getSettingTable(settingType)
- sql = """select jsondict as jsondict from "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format(tableName, name, edgvversion)
+ sql = """select jsondict as jsondict from "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format(
+ tableName, name, edgvversion
+ )
return sql
-
+
def deleteSettingFromAdminDb(self, settingType, name, edgvversion):
tableName = self.getSettingTable(settingType)
- sql = """DELETE FROM "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format(tableName, name, edgvversion)
+ sql = """DELETE FROM "public"."{0}" where name = '{1}' and edgvversion = '{2}';""".format(
+ tableName, name, edgvversion
+ )
return sql
-
+
def getAllSettingsFromAdminDb(self, settingType):
tableName = self.getSettingTable(settingType)
sql = """select row_to_json(a) from (
select edgvversion, array_agg(name) as settings from public.{0} group by edgvversion
- ) as a;""".format(tableName)
+ ) as a;""".format(
+ tableName
+ )
return sql
-
+
def dropRoleOnDatabase(self, roleName):
sql = """drop owned by "{0}" cascade;
- drop role "{0}";""".format(roleName)
+ drop role "{0}";""".format(
+ roleName
+ )
return sql
-
+
def getRolesWithGrantedUsers(self):
sql = """select row_to_json(a) from (
- select pgr.rolname as profile, array_agg(pgr2.rolname) as users from pg_auth_members as pgam
- left join pg_roles as pgr on pgam.roleid = pgr.oid
+ select pgr.rolname as profile, array_agg(pgr2.rolname) as users from pg_auth_members as pgam
+ left join pg_roles as pgr on pgam.roleid = pgr.oid
left join pg_roles as pgr2 on pgam.member = pgr2.oid
group by pgr.rolname
) as a;
"""
return sql
-
def getDomainTables(self):
- sql = '''select distinct table_name from information_schema.columns where table_schema = 'dominios' order by table_name asc'''
+ sql = """select distinct table_name from information_schema.columns where table_schema = 'dominios' order by table_name asc"""
return sql
-
+
def getGeometricSchemaList(self):
- sql = '''select distinct f_table_schema from public.geometry_columns order by f_table_schema asc;'''
+ sql = """select distinct f_table_schema from public.geometry_columns order by f_table_schema asc;"""
return sql
-
+
def getGeometricTableListFromSchema(self, schema):
if isinstance(schema, list):
- sql = '''select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema in ('{0}') and f_table_name in (
+ sql = """select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema in ('{0}') and f_table_name in (
select distinct table_name from information_schema.tables where table_type <> 'VIEW'
)
- order by f_table_name asc;'''.format("','".join(schema))
+ order by f_table_name asc;""".format(
+ "','".join(schema)
+ )
else:
- sql = '''select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema = '{0}' and f_table_name in (
+ sql = """select distinct f_table_schema, f_table_name from public.geometry_columns where f_table_schema = '{0}' and f_table_name in (
select distinct table_name from information_schema.tables where table_type <> 'VIEW'
)
- order by f_table_name asc;'''.format(schema)
+ order by f_table_name asc;""".format(
+ schema
+ )
return sql
-
+
def getParentGeomTables(self, schemaList):
- schemaList = [i for i in schemaList if i not in ['validation', 'views']]
+ schemaList = [i for i in schemaList if i not in ["validation", "views"]]
sql = """select pgnsp.nspname, pgcl2.n as tb from pg_class as pgcl
left join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid
left join pg_namespace as pgnsp on pgcl.relnamespace = pgnsp.oid
left join pg_inherits as pginh on pginh.inhparent = pgcl.oid
join (select pgcl.oid, pgmsp.nspname as sc, pgcl.relname as n from pg_class as pgcl
join (select * from pg_attribute where attname = 'geom') as pgatt on pgatt.attrelid = pgcl.oid
- left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid)
+ left join pg_namespace pgmsp on pgcl.relnamespace = pgmsp.oid)
as pgcl2 on pgcl2.oid = pginh.inhrelid
where pgnsp.nspname in ('{0}') and pgatt.attname IS NULL and pgcl.relkind = 'r'
- union
+ union
select distinct gc.f_table_schema,p.relname as tb from pg_class as p
- left join pg_inherits as inh on inh.inhrelid = p.oid
+ left join pg_inherits as inh on inh.inhrelid = p.oid
left join geometry_columns as gc on gc.f_table_name = p.relname
- where (inh.inhrelid IS NULL) and
+ where (inh.inhrelid IS NULL) and
gc.f_table_schema in ('{0}')
-
- order by tb""".format("','".join(schemaList))
+
+ order by tb""".format(
+ "','".join(schemaList)
+ )
return sql
-
+
def getInheritanceDict(self):
- sql = """select row_to_json(a) from (select pgc.relname parentname, array_agg(pgc1.relname) childname
- from pg_inherits as pginh
- left join pg_class pgc on pginh.inhparent = pgc.oid
+ sql = """select row_to_json(a) from (select pgc.relname parentname, array_agg(pgc1.relname) childname
+ from pg_inherits as pginh
+ left join pg_class pgc on pginh.inhparent = pgc.oid
left join pg_class as pgc1 on pginh.inhrelid = pgc1.oid
group by pgc.relname
) as a"""
return sql
-
- def getGeomTables(self, schemaList, dbPrimitiveList=[], excludeViews=True, geomColumn = False):
- primitiveClause = ''
- viewClause = ''
+
+ def getGeomTables(
+ self, schemaList, dbPrimitiveList=[], excludeViews=True, geomColumn=False
+ ):
+ primitiveClause = ""
+ viewClause = ""
if dbPrimitiveList != []:
- primitiveClause = """and type in ('{0}')""".format("','".join(dbPrimitiveList))
+ primitiveClause = """and type in ('{0}')""".format(
+ "','".join(dbPrimitiveList)
+ )
if excludeViews:
viewClause = """and f_table_name in (select table_name from information_schema.tables where table_type <> 'VIEW')"""
- selectClause = 'f_table_schema, f_table_name'
+ selectClause = "f_table_schema, f_table_name"
if geomColumn:
- selectClause += ',f_geometry_column'
- sql = """select distinct {0} from public.geometry_columns where f_table_schema in ('{1}') {2} {3} order by f_table_name""".format(selectClause, "','".join(schemaList), primitiveClause, viewClause)
+ selectClause += ",f_geometry_column"
+ sql = """select distinct {0} from public.geometry_columns where f_table_schema in ('{1}') {2} {3} order by f_table_name""".format(
+ selectClause, "','".join(schemaList), primitiveClause, viewClause
+ )
return sql
-
+
def getAttributeListFromTable(self, schema, tableName):
sql = """select distinct column_name from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name not in (
select f_geometry_column from public.geometry_columns where f_table_schema = '{0}' and f_table_name = '{1}'
)
- and column_name not like 'id%' order by column_name """.format(schema,tableName)
+ and column_name not like 'id%' order by column_name """.format(
+ schema, tableName
+ )
return sql
-
+
def getAttributeDictFromDb(self):
sql = """select row_to_json(a) from (select distinct table_schema, table_name, array_agg(column_name::text) as attributelist from information_schema.columns where table_schema not in ('views','validation')
and table_schema in (select distinct f_table_schema from public.geometry_columns)
and table_name in (select distinct f_table_name from public.geometry_columns)
-
+
and column_name not in (
select f_geometry_column from public.geometry_columns where f_table_schema = table_schema and f_table_name = table_name
)
and column_name not like 'id%' group by table_schema, table_name order by table_schema, table_name) as a"""
return sql
-
+
def getAttributeInfoFromTable(self, schema, tableName):
- sql = """ select row_to_json(a) from (select distinct column_name, data_type, is_nullable, column_default from information_schema.columns
+ sql = """ select row_to_json(a) from (select distinct column_name, data_type, is_nullable, column_default from information_schema.columns
where table_schema = '{0}' and table_name = '{1}' and column_name not in (
select f_geometry_column from public.geometry_columns where f_table_schema = '{0}' and f_table_name = '{1}'
)
and column_name not like 'id%' order by column_name ) as a
- """.format(schema,tableName)
+ """.format(
+ schema, tableName
+ )
return sql
-
+
def getAttrTypeDictFromDb(self):
sql = """ select row_to_json(a) from (
- select udt_name, array_agg(row_to_json(row(table_schema::text, table_name::text, column_name::text))) from information_schema.columns where
- table_name in (select f_table_name from public.geometry_columns)
- and column_name not like 'id_%'
- and column_name <> 'id'
+ select udt_name, array_agg(row_to_json(row(table_schema::text, table_name::text, column_name::text))) from information_schema.columns where
+ table_name in (select f_table_name from public.geometry_columns)
+ and column_name not like 'id_%'
+ and column_name <> 'id'
and column_name not in (
select f_geometry_column from public.geometry_columns where f_table_schema = table_schema and f_table_name = table_name
)
@@ -1376,15 +1772,15 @@ def getAttrTypeDictFromDb(self):
) as a
"""
return sql
-
+
def getAllDomainValues(self, domainTable):
sql = """ select code from dominios.{0}""".format(domainTable)
return sql
-
+
# Atentar que a coluna consrc foi descontinuada no pg 12+ (issue #521)
# def getConstraintDict(self, domainList):
# sql = """select row_to_json(result) from (
- # select a.tn as tablename, array_agg(row_to_json(row(a.conname::text, a.consrc::text))) from (select sch.nspname as sch, cl.relname as tn, c.conname as conname, c.consrc as consrc from
+ # select a.tn as tablename, array_agg(row_to_json(row(a.conname::text, a.consrc::text))) from (select sch.nspname as sch, cl.relname as tn, c.conname as conname, c.consrc as consrc from
# (
# select * from pg_constraint where contype = 'c'
# ) as c join (
@@ -1396,51 +1792,55 @@ def getAllDomainValues(self, domainTable):
# return sql
def getDefaultFromDb(self, schema, tableName, attrName):
- sql = """select column_default from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name = '{2}';""".format(schema, tableName, attrName)
+ sql = """select column_default from information_schema.columns where table_schema = '{0}' and table_name = '{1}' and column_name = '{2}';""".format(
+ schema, tableName, attrName
+ )
return sql
-
+
def upgradePostgis(self, updateDict):
- sql = ''
+ sql = ""
for key in updateDict:
- sql += """ALTER EXTENSION {0} UPDATE TO "{1}";""".format(key, updateDict[key]['defaultVersion'])
+ sql += """ALTER EXTENSION {0} UPDATE TO "{1}";""".format(
+ key, updateDict[key]["defaultVersion"]
+ )
return sql
-
+
def getPostgisVersion(self):
- sql = '''SELECT name, default_version,installed_version FROM pg_available_extensions WHERE name in ('postgis', 'postgis_topology')'''
+ sql = """SELECT name, default_version,installed_version FROM pg_available_extensions WHERE name in ('postgis', 'postgis_topology')"""
return sql
def getCustomizationPerspectiveDict(self, perspective):
if perspective == DsgEnums.Property:
- sql = '''select row_to_json(a) from (
- select name, array_agg(datname) from customization as custom
+ sql = """select row_to_json(a) from (
+ select name, array_agg(datname) from customization as custom
left join applied_customization as appcust on custom.id = appcust.id_customization
left join pg_database as pgd on pgd.oid = appcust.dboid group by name
- ) as a'''
+ ) as a"""
if perspective == DsgEnums.Database:
- sql = '''select row_to_json(a) from (
- select datname as name, array_agg(name) from customization as custom
+ sql = """select row_to_json(a) from (
+ select datname as name, array_agg(name) from customization as custom
left join applied_customization as appcust on custom.id = appcust.id_customization
left join pg_database as pgd on pgd.oid = appcust.dboid group by datname
- ) as a'''
+ ) as a"""
return sql
def getFieldToolBoxConfigPerspectiveDict(self, perspective):
if perspective == DsgEnums.Property:
- sql = '''select row_to_json(a) from (
- select name, array_agg(datname) from field_toolbox_config as custom
+ sql = """select row_to_json(a) from (
+ select name, array_agg(datname) from field_toolbox_config as custom
left join applied_field_toolbox_config as appcust on custom.id = appcust.id_applied_field_toolbox_config
left join pg_database as pgd on pgd.oid = appcust.dboid group by name
- ) as a'''
+ ) as a"""
if perspective == DsgEnums.Database:
- sql = '''select row_to_json(a) from (
- select datname as name, array_agg(name) from field_toolbox_config as custom
+ sql = """select row_to_json(a) from (
+ select datname as name, array_agg(name) from field_toolbox_config as custom
left join applied_field_toolbox_config as appcust on custom.id = appcust.id_applied_field_toolbox_config
left join pg_database as pgd on pgd.oid = appcust.dboid group by datname
- ) as a'''
+ ) as a"""
return sql
-
+
def createFieldToolBoxConfigTable(self):
- sql = '''CREATE TABLE IF NOT EXISTS public.field_toolbox_config(
+ sql = """CREATE TABLE IF NOT EXISTS public.field_toolbox_config(
id uuid NOT NULL DEFAULT uuid_generate_v4(),
name text,
jsondict text NOT NULL,
@@ -1449,21 +1849,25 @@ def createFieldToolBoxConfigTable(self):
CONSTRAINT field_toolbox_config_unique_name_and_version UNIQUE (name,edgvversion)
);
- '''
+ """
return sql
-
+
def checkIfTableExists(self, schema, tableName):
- sql = '''select table_name from information_schema.tables where table_schema = '{0}' and table_name = '{1}' limit 1'''.format(schema,tableName)
+ sql = """select table_name from information_schema.tables where table_schema = '{0}' and table_name = '{1}' limit 1""".format(
+ schema, tableName
+ )
return sql
-
+
def getRecordFromAdminDb(self, settingType, propertyName, edgvVersion):
tableName = self.getSettingTable(settingType)
- sql = '''SELECT id, name, jsondict, edgvversion from public.{0} where name = '{1}' and edgvversion = '{2}' '''.format(tableName, propertyName, edgvVersion)
+ sql = """SELECT id, name, jsondict, edgvversion from public.{0} where name = '{1}' and edgvversion = '{2}' """.format(
+ tableName, propertyName, edgvVersion
+ )
return sql
- def createPropertyTable(self, settingType, isAdminDb = False):
+ def createPropertyTable(self, settingType, isAdminDb=False):
tableName = self.getSettingTable(settingType)
- sql = '''CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public;
+ sql = """CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA public;
CREATE TABLE IF NOT EXISTS public.{0}(
id uuid NOT NULL DEFAULT uuid_generate_v4(),
name text,
@@ -1472,9 +1876,11 @@ def createPropertyTable(self, settingType, isAdminDb = False):
CONSTRAINT {0}_pk PRIMARY KEY (id),
CONSTRAINT {0}_unique_name_and_version UNIQUE (name,edgvversion)
);
- '''.format(tableName)
+ """.format(
+ tableName
+ )
if isAdminDb:
- sql += '''CREATE TABLE public.applied_{0}(
+ sql += """CREATE TABLE public.applied_{0}(
id uuid NOT NULL DEFAULT uuid_generate_v4(),
id_{0} uuid NOT NULL,
dboid oid NOT NULL,
@@ -1482,112 +1888,150 @@ def createPropertyTable(self, settingType, isAdminDb = False):
CONSTRAINT applied_{0}_id_{0}_config_fk FOREIGN KEY (id_{0}) REFERENCES public.{0} (id) MATCH SIMPLE ON UPDATE NO ACTION ON DELETE CASCADE
);
ALTER TABLE public.applied_{0} OWNER TO postgres;
- '''.format(tableName)
+ """.format(
+ tableName
+ )
return sql
- def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter = None):
+ def getPropertyPerspectiveDict(self, settingType, perspective, versionFilter=None):
if versionFilter:
- versionFilter = ''' where edgvversion = '{0}' '''.format(versionFilter)
+ versionFilter = """ where edgvversion = '{0}' """.format(versionFilter)
else:
- versionFilter = ''
+ versionFilter = ""
tableName = self.getSettingTable(settingType)
if perspective == DsgEnums.Property:
- sql = '''select row_to_json(a) from (
- select name, array_agg(datname) from public.{0} as custom
+ sql = """select row_to_json(a) from (
+ select name, array_agg(datname) from public.{0} as custom
left join applied_{0} as appcust on custom.id = appcust.id_{0}
- left join pg_database as pgd on pgd.oid = appcust.dboid
+ left join pg_database as pgd on pgd.oid = appcust.dboid
{1}
group by name
- ) as a'''.format(tableName, versionFilter)
+ ) as a""".format(
+ tableName, versionFilter
+ )
if perspective == DsgEnums.Database:
- sql = '''select row_to_json(a) from (
- select datname as name, array_agg(name) from public.{0} as custom
+ sql = """select row_to_json(a) from (
+ select datname as name, array_agg(name) from public.{0} as custom
right join applied_{0} as appcust on custom.id = appcust.id_{0}
- left join pg_database as pgd on pgd.oid = appcust.dboid
+ left join pg_database as pgd on pgd.oid = appcust.dboid
{1}
group by datname
- ) as a'''.format(tableName, versionFilter)
+ ) as a""".format(
+ tableName, versionFilter
+ )
return sql
-
+
def insertRecordInsidePropertyTable(self, settingType, settingDict):
tableName = self.getSettingTable(settingType)
- sql = '''INSERT INTO public.{0} (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}')'''.format(tableName, settingDict['name'], settingDict['jsondict'], settingDict['edgvversion'])
+ sql = """INSERT INTO public.{0} (name, jsondict, edgvversion) VALUES ('{1}','{2}','{3}')""".format(
+ tableName,
+ settingDict["name"],
+ settingDict["jsondict"],
+ settingDict["edgvversion"],
+ )
return sql
def insertInstalledRecordIntoAdminDb(self, settingType, recDict, dbOid):
settingTable = self.getSettingTable(settingType)
- tableName = 'applied_'+settingTable
- idName = 'id_'+settingTable
- sql = '''INSERT INTO public.{0} ({1}, dboid) VALUES ('{2}',{3})'''.format(tableName, idName, recDict['id'], dbOid)
+ tableName = "applied_" + settingTable
+ idName = "id_" + settingTable
+ sql = """INSERT INTO public.{0} ({1}, dboid) VALUES ('{2}',{3})""".format(
+ tableName, idName, recDict["id"], dbOid
+ )
return sql
-
+
def getDbOID(self, dbName):
- sql = '''SELECT oid from pg_database where datname = '{0}' '''.format(dbName)
+ sql = """SELECT oid from pg_database where datname = '{0}' """.format(dbName)
return sql
-
+
def getAllPropertiesFromDb(self, settingType):
tableName = self.getSettingTable(settingType)
- sql = '''select edgvversion, name, jsondict from public.{0}'''.format(tableName)
+ sql = """select edgvversion, name, jsondict from public.{0}""".format(tableName)
return sql
-
+
def removeRecordFromPropertyTable(self, settingType, configName, edgvVersion):
tableName = self.getSettingTable(settingType)
if not edgvVersion:
- sql = '''DELETE FROM public.{0} where name = '{1}';'''.format(tableName, configName)
+ sql = """DELETE FROM public.{0} where name = '{1}';""".format(
+ tableName, configName
+ )
else:
- sql = '''DELETE FROM public.{0} where name = '{1}' and edgvversion = '{2}';'''.format(tableName, configName, edgvVersion)
+ sql = """DELETE FROM public.{0} where name = '{1}' and edgvversion = '{2}';""".format(
+ tableName, configName, edgvVersion
+ )
return sql
- def updateRecordFromPropertyTable(self, settingType, configName, edgvVersion, jsonDict):
+ def updateRecordFromPropertyTable(
+ self, settingType, configName, edgvVersion, jsonDict
+ ):
tableName = self.getSettingTable(settingType)
- sql = '''UPDATE public.{0} SET jsondict = '{1}' where name = '{2}' and edgvversion = '{3}';'''.format(tableName, jsonDict, configName, edgvVersion)
+ sql = """UPDATE public.{0} SET jsondict = '{1}' where name = '{2}' and edgvversion = '{3}';""".format(
+ tableName, jsonDict, configName, edgvVersion
+ )
return sql
-
- def uninstallPropertyOnAdminDb(self, settingType, configName, edgvVersion, dbName = None):
+
+ def uninstallPropertyOnAdminDb(
+ self, settingType, configName, edgvVersion, dbName=None
+ ):
tableName = self.getSettingTable(settingType)
- dbNameFilterClause = ''
+ dbNameFilterClause = ""
if dbName:
- dbNameFilterClause = '''dboid in (select oid from pg_database where datname ='{0}') and '''.format(dbName)
- sql = '''DELETE FROM public.applied_{0} where {1} id_{0} in (select id from public.{0} where name = '{2}' and edgvversion = '{3}');'''.format(tableName, dbNameFilterClause, configName, edgvVersion)
+ dbNameFilterClause = """dboid in (select oid from pg_database where datname ='{0}') and """.format(
+ dbName
+ )
+ sql = """DELETE FROM public.applied_{0} where {1} id_{0} in (select id from public.{0} where name = '{2}' and edgvversion = '{3}');""".format(
+ tableName, dbNameFilterClause, configName, edgvVersion
+ )
return sql
-
+
def getSettingVersion(self, settingType, settingName):
tableName = self.getSettingTable(settingType)
- sql = '''select edgvversion from public.{0} where name = '{1}' '''.format(tableName, settingName)
+ sql = """select edgvversion from public.{0} where name = '{1}' """.format(
+ tableName, settingName
+ )
return sql
-
+
def getPrimaryKeyColumn(self, tableName):
- if '.' in tableName:
- tableSchema, tableName = tableName.replace("'","").replace('"','').split('.')
+ if "." in tableName:
+ tableSchema, tableName = (
+ tableName.replace("'", "").replace('"', "").split(".")
+ )
tableName = '''"{0}"."{1}"'''.format(tableSchema, tableName)
- sql = '''
+ sql = """
SELECT a.attname, format_type(a.atttypid, a.atttypmod) AS data_type
FROM pg_index i
JOIN pg_attribute a ON a.attrelid = i.indrelid
AND a.attnum = ANY(i.indkey)
WHERE i.indrelid = '{}'::regclass
- AND i.indisprimary;
- '''.format(tableName)
+ AND i.indisprimary;
+ """.format(
+ tableName
+ )
return sql
-
+
def getGeometryTablesCount(self):
- sql = '''select count(*) from public.geometry_columns'''
+ sql = """select count(*) from public.geometry_columns"""
return sql
-
+
def dropAllConections(self, dbName):
sql = """SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '{0}'
- AND pid <> pg_backend_pid();""".format(dbName)
+ AND pid <> pg_backend_pid();""".format(
+ dbName
+ )
return sql
- def getAttributesFromTable(self, tableSchema, tableName, typeFilter = None):
- whereClause = """""" if not typeFilter \
- else """ and data_type in ('{0}') """.format(
- "','".join(typeFilter)
- )
- sql = """select column_name, data_type from information_schema.columns where
- table_schema = '{0}' and table_name = '{1}' {2} order by column_name """.format(tableSchema, tableName, whereClause)
+ def getAttributesFromTable(self, tableSchema, tableName, typeFilter=None):
+ whereClause = (
+ """"""
+ if not typeFilter
+ else """ and data_type in ('{0}') """.format("','".join(typeFilter))
+ )
+ sql = """select column_name, data_type from information_schema.columns where
+ table_schema = '{0}' and table_name = '{1}' {2} order by column_name """.format(
+ tableSchema, tableName, whereClause
+ )
return sql
def getViewDefinition(self, viewName):
@@ -1597,8 +2041,8 @@ def getViewDefinition(self, viewName):
def dropView(self, viewName):
if '"' in viewName:
sql = """DROP VIEW {0} """.format(viewName)
- elif '.' in viewName:
- schema, name = viewName.split('.')
+ elif "." in viewName:
+ schema, name = viewName.split(".")
sql = """DROP VIEW "{0}"."{1}" """.format(schema, name)
else:
sql = """DROP VIEW "{0}" """.format(viewName)
@@ -1610,8 +2054,8 @@ def createViewStatement(self, viewName, viewDef):
def checkPostGISAddonsInstallation(self):
sql = """SELECT COUNT(*) FROM pg_proc WHERE proname = 'st_geotablesummary' """
- return sql
-
+ return sql
+
def createCoverageTempTable(self, srid):
sql = """
DROP TABLE IF EXISTS validation.coverage_temp;
@@ -1622,26 +2066,34 @@ def createCoverageTempTable(self, srid):
geom geometry(MULTIPOLYGON, {}) NOT NULL,
CONSTRAINT coverage_pk PRIMARY KEY (id)
)
- """.format(srid)
+ """.format(
+ srid
+ )
return sql
def checkCoverageForGapsWithFrame(self, frameTable, geomColumn):
- frameSchema, frameTable = frameTable.split('.')
+ frameSchema, frameTable = frameTable.split(".")
sql = """
select (ST_Dump(ST_SymDifference(a.geom, b.geom))).geom from
(select ST_Union({0}) as geom from "{1}"."{2}") as a,
(select ST_Union(geom) as geom from validation.coverage_temp) as b
- """.format(geomColumn, frameSchema, frameTable)
+ """.format(
+ geomColumn, frameSchema, frameTable
+ )
return sql
- def checkCoverageForOverlaps(self, table='validation.coverage_temp', geomColumn='geom', keyColumn='id'):
- tableSchema, tableName = table.split('.')
+ def checkCoverageForOverlaps(
+ self, table="validation.coverage_temp", geomColumn="geom", keyColumn="id"
+ ):
+ tableSchema, tableName = table.split(".")
sql = """
select (ST_Dump(foo.geom)).geom as geom from (
select (ST_GeoTableSummary('{0}', '{1}', '{2}', '{3}', 10, 'S3')).geom
- ) as foo
+ ) as foo
where ST_IsEmpty(foo.geom) = 'f'
- """.format(tableSchema, tableName, geomColumn, keyColumn)
+ """.format(
+ tableSchema, tableName, geomColumn, keyColumn
+ )
return sql
def getProcessOrClassFlags(self, filterType=None):
@@ -1652,16 +2104,16 @@ def getProcessOrClassFlags(self, filterType=None):
# filterType = filterType.lower()
sql = ""
# problemas com o Enum.
- if 'process' in filterType.lower():
+ if "process" in filterType.lower():
filterType = 0
elif filterType:
filterType = 1
- if filterType == DsgEnums.ProcessName:
+ if filterType == DsgEnums.ProcessName:
sql = """
- SELECT DISTINCT process_name
+ SELECT DISTINCT process_name
FROM validation.aux_flags_validacao;
"""
- elif filterType == DsgEnums.ClassName:
+ elif filterType == DsgEnums.ClassName:
sql = """
SELECT DISTINCT layer
FROM validation.aux_flags_validacao;
@@ -1675,7 +2127,7 @@ def getFilteredFlagsQuery(self, filterType=None, filteredElement=None):
"""
sql = ""
# problemas com o Enum.
- if 'process' in filterType.lower():
+ if "process" in filterType.lower():
filterTypeEnum = 0
elif filterType:
filterTypeEnum = 1
@@ -1683,45 +2135,49 @@ def getFilteredFlagsQuery(self, filterType=None, filteredElement=None):
SELECT * FROM validation.aux_flags_validacao;
"""
whereClause = ""
- if filterTypeEnum == DsgEnums.ProcessName:
+ if filterTypeEnum == DsgEnums.ProcessName:
whereClause = " WHERE process_name = '{0}';".format(filteredElement)
elif filterType == DsgEnums.ClassName:
whereClause = " WHERE layer = '{0}';".format(filteredElement)
- if filteredElement and filteredElement != '':
+ if filteredElement and filteredElement != "":
sql = sql + whereClause
return sql
def createFilteredFlagsViewTableQuery(self, filterType=None, filteredElement=None):
"""
- Returns the query for creating and populating a view table of flags raised in
+ Returns the query for creating and populating a view table of flags raised in
validation processes based on users settings.
"""
sql = """
- CREATE OR REPLACE VIEW validation.filtered_flags AS
+ CREATE OR REPLACE VIEW validation.filtered_flags AS
SELECT * FROM validation.aux_flags_validacao
"""
whereClause = ""
# problemas com o Enum.
- if 'process' in filterType.lower():
+ if "process" in filterType.lower():
filterTypeEnum = 0
elif filterType:
- filterTypeEnum = 1
- if filterTypeEnum == DsgEnums.ProcessName:
+ filterTypeEnum = 1
+ if filterTypeEnum == DsgEnums.ProcessName:
whereClause = " WHERE process_name = '{0}';".format(filteredElement)
elif filterTypeEnum == DsgEnums.ClassName:
whereClause = " WHERE layer = '{0}';".format(filteredElement)
- if filteredElement and filteredElement != '':
+ if filteredElement and filteredElement != "":
sql = sql + whereClause
return sql
-
- def checkCoverageForGaps(self, table='validation.coverage_temp', geomColumn='geom', keyColumn='id'):
- tableSchema, tableName = table.split('.')
+
+ def checkCoverageForGaps(
+ self, table="validation.coverage_temp", geomColumn="geom", keyColumn="id"
+ ):
+ tableSchema, tableName = table.split(".")
sql = """
select (ST_Dump(foo.geom)).geom as geom from (
select (ST_GeoTableSummary('{0}', '{1}', '{2}', '{3}', 10, 'S4')).geom
- ) as foo
+ ) as foo
where ST_IsEmpty(foo.geom) = 'f'
- """.format(tableSchema, tableName, geomColumn, keyColumn)
+ """.format(
+ tableSchema, tableName, geomColumn, keyColumn
+ )
return sql
def createValidationHistoryViewTableQuery(self, idListString=None):
@@ -1733,24 +2189,29 @@ def createValidationHistoryViewTableQuery(self, idListString=None):
This method uses the data on compact_process_history.
"""
sql = """
- CREATE OR REPLACE VIEW validation.process_history_view AS
+ CREATE OR REPLACE VIEW validation.process_history_view AS
SELECT t.process_name, t.log, s.status, t.finished
FROM validation.compact_process_history AS t
JOIN validation.status AS s ON t.status = s.id
ORDER BY t.finished DESC;
"""
if idListString:
- sql = sql.replace("ORDER BY t.finished DESC;", "WHERE t.id in {0} ORDER BY t.finished DESC;").format(idListString)
+ sql = sql.replace(
+ "ORDER BY t.finished DESC;",
+ "WHERE t.id in {0} ORDER BY t.finished DESC;",
+ ).format(idListString)
return sql
def getQmlRecords(self, layerList):
- sql = """select layername, domainqml from public.domain_qml where layername in ('{0}')""".format("','".join(layerList))
+ sql = """select layername, domainqml from public.domain_qml where layername in ('{0}')""".format(
+ "','".join(layerList)
+ )
return sql
-
+
def getImplementationVersion(self):
sql = """select dbimplversion from public.db_metadata limit 1"""
return sql
-
+
def getValidationLogQuery(self):
"""
Returns the query for a list of all logs UNIQUE registered for each
@@ -1759,7 +2220,7 @@ def getValidationLogQuery(self):
sql = """SELECT DISTINCT log, id FROM validation.compact_process_history;"""
# ALTERAR PARA FUNÇÃO DE UPDATE DA TABELA PARA QUE INCLUA OS NOMES DE USUÁRIOS
return sql
-
+
def getValidationHistoryQuery(self, idListString=None):
"""
Returns the query of all validation processes available informations.
@@ -1769,7 +2230,7 @@ def getValidationHistoryQuery(self, idListString=None):
if idListString:
sql = sql.replace(";", " WHERE id IN {};".format(idListString))
return sql
-
+
def createCompactValidationHistoryQuery(self):
"""
Returns the query for compact validation history table creation.
@@ -1795,18 +2256,33 @@ def populateCompactValidationHistoryQuery(self, logList):
sql = ""
if isinstance(logList, list):
for log in logList:
- sql += u"""INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".\
- format(log[0], log[1], log[2].replace(r"\n", "\n"), log[3], log[4].toPyDateTime())
+ sql += """INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".format(
+ log[0],
+ log[1],
+ log[2].replace(r"\n", "\n"),
+ log[3],
+ log[4].toPyDateTime(),
+ )
elif logList:
- sql += u"""INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".\
- format(logList[0], logList[1], logList[2].replace(r"\n", "\n"), logList[3], logList[4].toPyDateTime())
+ sql += """INSERT INTO validation.compact_process_history (id, process_name, log, status, finished) VALUES ({0}, '{1}', '{2}', {3}, '{4}');\n""".format(
+ logList[0],
+ logList[1],
+ logList[2].replace(r"\n", "\n"),
+ logList[3],
+ logList[4].toPyDateTime(),
+ )
return sql
+
def getAttrListWithFilter(self):
sql = """select distinct table_name from information_schema.columns where table_schema = 'dominios' and column_name = 'filter'"""
return sql
-
+
def getFilterJsonList(self, domainName):
- sql = """select row_to_json(a) from (select * from dominios.{0}) as a """.format(domainName)
+ sql = (
+ """select row_to_json(a) from (select * from dominios.{0}) as a """.format(
+ domainName
+ )
+ )
return sql
def databaseInfo(self):
diff --git a/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py b/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py
index c3746e872..f4e6ec7c2 100644
--- a/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py
+++ b/DsgTools/core/Factories/SqlFactory/spatialiteSqlGenerator.py
@@ -23,9 +23,15 @@
from .sqlGenerator import SqlGenerator
from ...dsgEnums import DsgEnums
+
class SpatialiteSqlGenerator(SqlGenerator):
def getComplexLinks(self, complex):
- sql = "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from public_complex_schema where complex = "+'\''+complex+'\''
+ sql = (
+ "SELECT complex_schema, complex, aggregated_schema, aggregated_class, column_name from public_complex_schema where complex = "
+ + "'"
+ + complex
+ + "'"
+ )
return sql
def getComplexTablesFromDatabase(self):
@@ -33,24 +39,64 @@ def getComplexTablesFromDatabase(self):
return sql
def getComplexData(self, complex_schema, complex):
- sql = "SELECT id, nome from "+complex_schema+"_"+complex
+ sql = "SELECT id, nome from " + complex_schema + "_" + complex
return sql
- def getAssociatedFeaturesData(self, aggregated_schema, aggregated_class, column_name, complex_uuid):
- if aggregated_schema == 'complexos':
- sql = "SELECT id from "+aggregated_schema+"_"+aggregated_class+" where "+column_name+"="+'\''+complex_uuid+'\''
+ def getAssociatedFeaturesData(
+ self, aggregated_schema, aggregated_class, column_name, complex_uuid
+ ):
+ if aggregated_schema == "complexos":
+ sql = (
+ "SELECT id from "
+ + aggregated_schema
+ + "_"
+ + aggregated_class
+ + " where "
+ + column_name
+ + "="
+ + "'"
+ + complex_uuid
+ + "'"
+ )
else:
- sql = "SELECT OGC_FID from "+aggregated_schema+"_"+aggregated_class+" where "+column_name+"="+'\''+complex_uuid+'\''
+ sql = (
+ "SELECT OGC_FID from "
+ + aggregated_schema
+ + "_"
+ + aggregated_class
+ + " where "
+ + column_name
+ + "="
+ + "'"
+ + complex_uuid
+ + "'"
+ )
return sql
def getLinkColumn(self, complexClass, aggregatedClass):
if self.isComplexClass(aggregatedClass):
- sql = 'SELECT column_name from public_complex_schema where complex = \''+complexClass+'\''+' and aggregated_class = '+'\''+aggregatedClass[10:]+'\''
+ sql = (
+ "SELECT column_name from public_complex_schema where complex = '"
+ + complexClass
+ + "'"
+ + " and aggregated_class = "
+ + "'"
+ + aggregatedClass[10:]
+ + "'"
+ )
else:
- sql = 'SELECT column_name from public_complex_schema where complex = \''+complexClass+'\''+' and aggregated_class = '+'\''+aggregatedClass+'\''
+ sql = (
+ "SELECT column_name from public_complex_schema where complex = '"
+ + complexClass
+ + "'"
+ + " and aggregated_class = "
+ + "'"
+ + aggregatedClass
+ + "'"
+ )
return sql
- def getSrid(self, parameters = dict()):
+ def getSrid(self, parameters=dict()):
sql = "SELECT srid from geometry_columns"
return sql
@@ -59,11 +105,20 @@ def getTablesFromDatabase(self):
return sql
def disassociateComplexFromComplex(self, aggregated_class, link_column, uuid):
- sql = "UPDATE "+aggregated_class+" SET "+link_column+"=NULL WHERE id = "+'\''+uuid+'\''
+ sql = (
+ "UPDATE "
+ + aggregated_class
+ + " SET "
+ + link_column
+ + "=NULL WHERE id = "
+ + "'"
+ + uuid
+ + "'"
+ )
return sql
def isComplexClass(self, aggregatedClass):
- size = len(aggregatedClass.split('_')[0])
+ size = len(aggregatedClass.split("_")[0])
if size == 9:
return True
return False
@@ -75,148 +130,168 @@ def getCreateDatabase(self, name):
return None
def insertFrameIntoTable(self, wkt):
- sql = "INSERT INTO public_aux_moldura_a(GEOMETRY) VALUES(GeomFromText("+wkt+"))"
+ sql = (
+ "INSERT INTO public_aux_moldura_a(GEOMETRY) VALUES(GeomFromText("
+ + wkt
+ + "))"
+ )
return sql
def getElementCountFromLayer(self, layer):
- sql = "SELECT count(*) FROM "+layer
+ sql = "SELECT count(*) FROM " + layer
return sql
-
+
def createRole(self, mydict):
return None
def dropRole(self, role):
return None
-
+
def grantRole(self, user, role):
return None
-
+
def revokeRole(self, user, role):
return None
-
+
def getRoles(self):
return None
-
+
def getUserRelatedRoles(self):
return None
-
+
def getUsers(self):
return None
-
+
def createUser(self):
- return None
-
+ return None
+
def removeUser(self):
- return None
+ return None
def alterUserPass(self):
- return None
-
+ return None
+
def validateWithDomain(self):
return None
-
+
def getNotNullFields(self):
return None
-
- def getFeaturesWithSQL(self,layer,attrList):
- ls = ','.join(attrList)
- sql = 'SELECT %s FROM %s' % (ls,layer)
- return sql
-
- def getStructure(self,edgvVersion):
- sql = ''
- if edgvVersion == '2.1.3':
- sql = 'select name, sql from sqlite_master where type = \'table\' and (name like \'cb_%\' or name like \'complexos_%\' or name like \'public_%\')'
- elif edgvVersion == 'FTer_2a_Ed':
- sql = 'select name, sql from sqlite_master where type = \'table\' and (name like \'ge_%\' or name like \'pe_%\' or name like \'complexos_%\' or name like \'public_%\')'
- elif edgvVersion == '3.0':
- sql = sql = 'select name, sql from sqlite_master where type = \'table\' and (name like \'edgv_%\' or name like \'complexos_%\' or name like \'public_%\')'
- return sql
-
+
+ def getFeaturesWithSQL(self, layer, attrList):
+ ls = ",".join(attrList)
+ sql = "SELECT %s FROM %s" % (ls, layer)
+ return sql
+
+ def getStructure(self, edgvVersion):
+ sql = ""
+ if edgvVersion == "2.1.3":
+ sql = "select name, sql from sqlite_master where type = 'table' and (name like 'cb_%' or name like 'complexos_%' or name like 'public_%')"
+ elif edgvVersion == "FTer_2a_Ed":
+ sql = "select name, sql from sqlite_master where type = 'table' and (name like 'ge_%' or name like 'pe_%' or name like 'complexos_%' or name like 'public_%')"
+ elif edgvVersion == "3.0":
+ sql = (
+ sql
+ ) = "select name, sql from sqlite_master where type = 'table' and (name like 'edgv_%' or name like 'complexos_%' or name like 'public_%')"
+ return sql
+
def getAggregationColumn(self):
- sql = 'SELECT DISTINCT column_name FROM public_complex_schema'
+ sql = "SELECT DISTINCT column_name FROM public_complex_schema"
return sql
def getAggregatorFromId(self, className, id):
- sql = 'SELECT id from %s where id =\'%s\'' % (className,id)
- return sql
-
- def getAggregatorFromComplexSchema(self,aggregated,aggregationColumn):
- sql = 'SELECT complex from public_complex_schema where aggregated_class = \'%s\' and aggregationColumn = \'%s\'' % (aggregated,aggregationColumn)
+ sql = "SELECT id from %s where id ='%s'" % (className, id)
+ return sql
+
+ def getAggregatorFromComplexSchema(self, aggregated, aggregationColumn):
+ sql = (
+ "SELECT complex from public_complex_schema where aggregated_class = '%s' and aggregationColumn = '%s'"
+ % (aggregated, aggregationColumn)
+ )
return sql
-
+
def createCustomSort(self):
return None
-
+
def getRolePrivileges(self, role, dbname):
return None
- def isSuperUser(self,user):
+ def isSuperUser(self, user):
return None
def getInvalidGeom(self, tableSchema, tableName):
return None
def makeRelationDict(self, table, in_clause):
- sql = 'select code, code_name from dominios_%s where code in %s' % (table, in_clause)
+ sql = "select code, code_name from dominios_%s where code in %s" % (
+ table,
+ in_clause,
+ )
return sql
def checkValidationStructure(self):
return None
- def createValidationStructure(self,srid):
+ def createValidationStructure(self, srid):
return None
-
+
def getEDGVVersion(self):
sql = "SELECT edgvversion FROM public_db_metadata LIMIT 1"
return sql
-
+
def getEDGVVersionAndImplementationVersion(self):
sql = "SELECT edgvversion, dbimplversion FROM public_db_metadata LIMIT 1"
return sql
-
+
def getStylesFromDb(self, dbVersion):
return None
def getGeomTablesFromGeometryColumns(self, edgvVersion):
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
- sql = 'select srid, f_geometry_column, type, f_table_name from geometry_columns'
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
+ sql = "select srid, f_geometry_column, type, f_table_name from geometry_columns"
else:
- sql = 'select srid, f_geometry_column, geometry_type, f_table_name from geometry_columns'
+ sql = "select srid, f_geometry_column, geometry_type, f_table_name from geometry_columns"
return sql
def getGeomByPrimitive(self, edgvVersion):
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
sql = """select type, f_table_name from geometry_columns"""
else:
sql = """select geometry_type, f_table_name from geometry_columns"""
return sql
-
+
def getGeomColumnDict(self):
sql = """select f_geometry_column, f_table_name from geometry_columns"""
return sql
-
- def insertFrame(self,scale,mi,inom,frame,srid,geoSrid, paramDict = dict()):
- sql = """INSERT INTO public_aux_moldura_a (mi,inom,escala,GEOMETRY) VALUES ('{0}','{1}','{2}',Transform(ST_GeomFromText('{3}',{4}), {5}))""".format(mi,inom,scale,frame,geoSrid,srid)
+
+ def insertFrame(self, scale, mi, inom, frame, srid, geoSrid, paramDict=dict()):
+ sql = """INSERT INTO public_aux_moldura_a (mi,inom,escala,GEOMETRY) VALUES ('{0}','{1}','{2}',Transform(ST_GeomFromText('{3}',{4}), {5}))""".format(
+ mi, inom, scale, frame, geoSrid, srid
+ )
return sql
-
+
def getElementCountFromLayerV2(self, schema, table, useInheritance):
- layer = '_'.join([schema, table])
+ layer = "_".join([schema, table])
return self.getElementCountFromLayer(layer)
-
+
def getFullTablesName(self, name):
- sql = "SELECT f_table_name as name FROM geometry_columns WHERE f_table_name LIKE '%{0}%' ORDER BY name".format(name)
+ sql = "SELECT f_table_name as name FROM geometry_columns WHERE f_table_name LIKE '%{0}%' ORDER BY name".format(
+ name
+ )
return sql
- def getGeomColumnTupleList(self, edgvVersion, showViews = False):
- if edgvVersion in ('2.1.3','FTer_2a_Ed'):
- sql = """select f_table_name, f_geometry_column, type from geometry_columns"""
+ def getGeomColumnTupleList(self, edgvVersion, showViews=False):
+ if edgvVersion in ("2.1.3", "FTer_2a_Ed"):
+ sql = (
+ """select f_table_name, f_geometry_column, type from geometry_columns"""
+ )
else:
sql = """select f_table_name, f_geometry_column, geometry_type from geometry_columns"""
return sql
def getQmlRecords(self, layerList):
- sql = """select layername, domainqml from public_domain_qml where layername in ('{0}')""".format("','".join(layerList))
+ sql = """select layername, domainqml from public_domain_qml where layername in ('{0}')""".format(
+ "','".join(layerList)
+ )
return sql
def databaseInfo(self):
@@ -229,7 +304,7 @@ def databaseInfo(self):
FROM geometry_columns
ORDER BY f_table_name ASC"""
return sql
-
+
def implementationVersion(self):
"""
Query to retrieve database's implementation version, if available.
diff --git a/DsgTools/core/Factories/SqlFactory/sqlGenerator.py b/DsgTools/core/Factories/SqlFactory/sqlGenerator.py
index 83470e612..55d32b6c9 100644
--- a/DsgTools/core/Factories/SqlFactory/sqlGenerator.py
+++ b/DsgTools/core/Factories/SqlFactory/sqlGenerator.py
@@ -23,6 +23,7 @@
from builtins import object
from ...dsgEnums import DsgEnums
+
class SqlGenerator(object):
def getComplexLinks(self, complex):
return None
@@ -33,7 +34,9 @@ def getComplexTablesFromDatabase(self):
def getComplexData(self, complex_schema, complex):
return None
- def getAssociatedFeaturesData(self, aggregated_schema, aggregated_class, column_name, complex_uuid):
+ def getAssociatedFeaturesData(
+ self, aggregated_schema, aggregated_class, column_name, complex_uuid
+ ):
return None
def getLinkColumn(self, complexClass, aggregatedClass):
@@ -45,7 +48,7 @@ def getSrid(self):
def getEDGVVersion(self):
sql = "SELECT edgvversion FROM db_metadata LIMIT 1"
return sql
-
+
def getEDGVVersionAndImplementationVersion(self):
sql = "SELECT edgvversion, dbimplversion FROM db_metadata LIMIT 1"
return sql
@@ -67,79 +70,79 @@ def insertFrameIntoTable(self, wkb):
def getDatabasesFromServer(self):
return None
-
+
def dropDatabase(self, name):
return None
-
+
def createRole(self, mydict):
return None
def dropRole(self, role):
return None
-
+
def grantRole(self, user, role):
return None
-
+
def revokeRole(self, user, role):
return None
-
+
def getRoles(self):
return None
-
+
def getUserRelatedRoles(self):
return None
-
+
def getUsers(self):
return None
-
+
def createUser(self):
return None
-
+
def removeUser(self):
- return None
+ return None
def alterUserPass(self):
return None
-
+
def validateWithDomain(self):
- return None
-
+ return None
+
def getNotNullFields(self):
- return None
-
- def getFeaturesWithSQL(self,layer,attrList):
return None
- def getStructure(self,edgvVersion):
+ def getFeaturesWithSQL(self, layer, attrList):
+ return None
+
+ def getStructure(self, edgvVersion):
return None
def getAggregationColumn(self):
return None
def getAggregatorFromId(self, className, id):
- return None
-
- def getAggregatorFromComplexSchema(self,aggregated,aggregationColumn):
return None
-
+
+ def getAggregatorFromComplexSchema(self, aggregated, aggregationColumn):
+ return None
+
def createCustomSort(self):
return None
-
+
def getRolePrivileges(self, role, dbname):
return None
- def isSuperUser(self,user):
+ def isSuperUser(self, user):
return None
-
+
def getInvalidGeom(self, tableSchema, tableName):
return None
def checkValidationStructure(self):
return None
- def createValidationStructure(self,srid):
+ def createValidationStructure(self, srid):
return None
-
+
def getTableExtent(self, tableSchema, tableName):
return None
@@ -148,4 +151,4 @@ def implementationVersion(self):
Query to retrieve database's implementation version, if available.
:return: (str) database's implementation version (e.g. '5.2').
"""
- return None
\ No newline at end of file
+ return None
diff --git a/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py b/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py
index 652205e58..daea0b75e 100644
--- a/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py
+++ b/DsgTools/core/Factories/SqlFactory/sqlGeneratorFactory.py
@@ -37,8 +37,8 @@ def createSqlGenerator(self, driver):
:return:
"""
genDict = {
- DsgEnums.DriverGeopackage : lambda : GeopackageSqlGenerator(),
- DsgEnums.DriverSpatiaLite : lambda : SpatialiteSqlGenerator(),
- DsgEnums.DriverPostGIS : lambda : PostGISSqlGenerator()
+ DsgEnums.DriverGeopackage: lambda: GeopackageSqlGenerator(),
+ DsgEnums.DriverSpatiaLite: lambda: SpatialiteSqlGenerator(),
+ DsgEnums.DriverPostGIS: lambda: PostGISSqlGenerator(),
}
return genDict[driver]()
diff --git a/DsgTools/core/Factories/ThreadFactory/dpiThread.py b/DsgTools/core/Factories/ThreadFactory/dpiThread.py
index 0a0035210..1e97a9b83 100644
--- a/DsgTools/core/Factories/ThreadFactory/dpiThread.py
+++ b/DsgTools/core/Factories/ThreadFactory/dpiThread.py
@@ -36,6 +36,7 @@
from .genericThread import GenericThread
+
class DpiMessages(QObject):
def __init__(self, thread):
super(DpiMessages, self).__init__()
@@ -43,13 +44,13 @@ def __init__(self, thread):
self.thread = thread
def getProblemMessage(self):
- return self.tr('Problem processing image: ')
+ return self.tr("Problem processing image: ")
def getProblemFeedbackMessage(self):
- return self.tr('Problem processing images. Check log for details.')
+ return self.tr("Problem processing images. Check log for details.")
def getUserCanceledFeedbackMessage(self):
- return self.tr('User canceled image processing!')
+ return self.tr("User canceled image processing!")
def getSuccessFeedbackMessage(self):
return self.tr("Successful image processing.")
@@ -61,6 +62,7 @@ def getSuccessfullFileCreation(self):
def progressCanceled(self):
self.thread.stopped[0] = True
+
class DpiThread(GenericThread):
def __init__(self):
"""
@@ -70,7 +72,18 @@ def __init__(self):
self.messenger = DpiMessages(self)
- def setParameters(self, filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg, stopped, bands = []):
+ def setParameters(
+ self,
+ filesList,
+ rasterType,
+ minOutValue,
+ maxOutValue,
+ outDir,
+ percent,
+ epsg,
+ stopped,
+ bands=[],
+ ):
"""
Sets thread parameters
filesList: files processed
@@ -111,7 +124,7 @@ def processImages(self, filesList):
steps = 0
for file in self.filesList:
- #Open image
+ # Open image
imgIn = osgeo.gdal.Open(file)
if not imgIn:
continue
@@ -125,7 +138,9 @@ def processImages(self, filesList):
problemOcurred = False
for file in self.filesList:
- ret = self.stretchImage(file, self.outDir, self.percent, self.epsg, self.bands)
+ ret = self.stretchImage(
+ file, self.outDir, self.percent, self.epsg, self.bands
+ )
if ret == 1:
pass
elif ret == 0:
@@ -143,74 +158,89 @@ def stretchImage(self, inFile, outDir, percent, epsg, bands):
Method that applies a specific histogram stretching to a group of images.
The method also performs a conversion changing the raster type.
"""
- #Getting the output raster type
- (rasterType, minOutValue, maxOutValue) = (self.rasterType, self.minOutValue, self.maxOutValue)
-
- #Open image
+ # Getting the output raster type
+ (rasterType, minOutValue, maxOutValue) = (
+ self.rasterType,
+ self.minOutValue,
+ self.maxOutValue,
+ )
+
+ # Open image
imgIn = osgeo.gdal.Open(inFile)
if not imgIn:
- QgsMessageLog.logMessage(self.messenger.getProblemMessage() + inFile, "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getProblemMessage() + inFile,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return 0
- #Setting the output file name
+ # Setting the output file name
fileName = inFile.split("/")[-1]
split = fileName.split(".")
baseName = split[0]
- extension = '.' + split[-1]
+ extension = "." + split[-1]
- #Defining the output driver
+ # Defining the output driver
outDriver = imgIn.GetDriver()
- createOptions = ['PHOTOMETRIC=RGB', 'ALPHA=NO']
+ createOptions = ["PHOTOMETRIC=RGB", "ALPHA=NO"]
- #creating temp file for contrast stretch
- outFileTmp = os.path.join(outDir, baseName+'_tmp'+extension)
- #creating output file for contrast stretch
- outFile = os.path.join(outDir, baseName+'_stretch'+extension)
+ # creating temp file for contrast stretch
+ outFileTmp = os.path.join(outDir, baseName + "_tmp" + extension)
+ # creating output file for contrast stretch
+ outFile = os.path.join(outDir, baseName + "_stretch" + extension)
- #if bands is empty, make a new file with the same band size
+ # if bands is empty, make a new file with the same band size
if bands == []:
bands = list(range(0, imgIn.RasterCount))
- #Creating a temp image, with the same input parameters, to store the converted input image to 8 bits
- imgOut = outDriver.Create(outFileTmp, imgIn.RasterXSize, imgIn.RasterYSize, len(bands), rasterType, options=createOptions)
+ # Creating a temp image, with the same input parameters, to store the converted input image to 8 bits
+ imgOut = outDriver.Create(
+ outFileTmp,
+ imgIn.RasterXSize,
+ imgIn.RasterYSize,
+ len(bands),
+ rasterType,
+ options=createOptions,
+ )
imgOut.SetProjection(imgIn.GetProjection())
imgOut.SetGeoTransform(imgIn.GetGeoTransform())
- #Linear stretching
- topPercent = 1.-percent/200.
- bottomPercent = percent/200.
+ # Linear stretching
+ topPercent = 1.0 - percent / 200.0
+ bottomPercent = percent / 200.0
outBandNumber = 1
for bandNumber in bands:
if not self.stopped[0]:
- b1 = imgIn.GetRasterBand(bandNumber+1)
+ b1 = imgIn.GetRasterBand(bandNumber + 1)
arr = b1.ReadAsArray()
# Updating progress
self.signals.stepProcessed.emit(self.getId())
- #computing percentile
+ # computing percentile
newArr = arr.flatten()
newArr.sort()
total = len(newArr)
if percent == 0:
minValue = float(newArr[0])
- maxValue = float(newArr[total-1])
+ maxValue = float(newArr[total - 1])
else:
- minValue = float(newArr[int(bottomPercent*total)])
- maxValue = float(newArr[int(math.ceil(topPercent*total))])
+ minValue = float(newArr[int(bottomPercent * total)])
+ maxValue = float(newArr[int(math.ceil(topPercent * total))])
del newArr
# Updating progress
self.signals.stepProcessed.emit(self.getId())
- #Transformation parameters
- #Rouding the values out of bounds
+ # Transformation parameters
+ # Rouding the values out of bounds
numpy.putmask(arr, arr > maxValue, maxValue)
numpy.putmask(arr, arr < minValue, minValue)
# Updating progress
self.signals.stepProcessed.emit(self.getId())
- #The maxOutValue and the minOutValue must be set according to the convertion that will be applied (e.g. 8 bits, 16 bits, 32 bits)
- a = (maxOutValue-minOutValue)/(maxValue-minValue)
- newArr = (arr-minValue)*a+minOutValue
+ # The maxOutValue and the minOutValue must be set according to the convertion that will be applied (e.g. 8 bits, 16 bits, 32 bits)
+ a = (maxOutValue - minOutValue) / (maxValue - minValue)
+ newArr = (arr - minValue) * a + minOutValue
# Updating progress
self.signals.stepProcessed.emit(self.getId())
@@ -221,31 +251,54 @@ def stretchImage(self, inFile, outDir, percent, epsg, bands):
# Updating progress
self.signals.stepProcessed.emit(self.getId())
- QgsMessageLog.logMessage("Band " + str(bandNumber) + ": "+str(minValue)+" , "+str(maxValue), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ "Band "
+ + str(bandNumber)
+ + ": "
+ + str(minValue)
+ + " , "
+ + str(maxValue),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
else:
- QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getUserCanceledFeedbackMessage(),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return -1
- #creating final image for reprojection
+ # creating final image for reprojection
outRasterSRS = osgeo.osr.SpatialReference()
outRasterSRS.ImportFromEPSG(epsg)
- #this code uses virtual raster to compute the parameters of the output image
- vrt = osgeo.gdal.AutoCreateWarpedVRT(imgOut, None, outRasterSRS.ExportToWkt(), osgeo.gdal.GRA_NearestNeighbour, 0.0)
- imgWGS = outDriver.CreateCopy(outFile, vrt, options = createOptions)
-
- #Checking if the output file was created with success
+ # this code uses virtual raster to compute the parameters of the output image
+ vrt = osgeo.gdal.AutoCreateWarpedVRT(
+ imgOut,
+ None,
+ outRasterSRS.ExportToWkt(),
+ osgeo.gdal.GRA_NearestNeighbour,
+ 0.0,
+ )
+ imgWGS = outDriver.CreateCopy(outFile, vrt, options=createOptions)
+
+ # Checking if the output file was created with success
if os.path.exists(outFile):
- QgsMessageLog.logMessage(self.messenger.getSuccessfullFileCreation() + outFile, "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getSuccessfullFileCreation() + outFile,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
# Updating progress
self.signals.stepProcessed.emit(self.getId())
- #Deleting the objects
+ # Deleting the objects
imgWGS = None
imgOut = None
imgIn = None
- #Unlinking the temp file
+ # Unlinking the temp file
osgeo.gdal.Unlink(outFileTmp)
return 1
diff --git a/DsgTools/core/Factories/ThreadFactory/genericThread.py b/DsgTools/core/Factories/ThreadFactory/genericThread.py
index 4bf0fb241..faabeb8b8 100644
--- a/DsgTools/core/Factories/ThreadFactory/genericThread.py
+++ b/DsgTools/core/Factories/ThreadFactory/genericThread.py
@@ -25,12 +25,14 @@
from uuid import uuid4
+
class ProcessSignals(QObject):
rangeCalculated = pyqtSignal(int, str)
stepProcessed = pyqtSignal(str)
processingFinished = pyqtSignal(int, str, str)
loadFile = pyqtSignal(str, bool)
+
class GenericThread(QRunnable):
def __init__(self):
"""
@@ -39,7 +41,7 @@ def __init__(self):
super(GenericThread, self).__init__()
self.id = str(uuid4())
-
+
self.signals = ProcessSignals()
def run(self):
diff --git a/DsgTools/core/Factories/ThreadFactory/inventoryThread.py b/DsgTools/core/Factories/ThreadFactory/inventoryThread.py
index aeab93910..8c82a4eb6 100644
--- a/DsgTools/core/Factories/ThreadFactory/inventoryThread.py
+++ b/DsgTools/core/Factories/ThreadFactory/inventoryThread.py
@@ -31,13 +31,24 @@
from qgis.PyQt.QtCore import pyqtSlot
# Import the PyQt and QGIS libraries
-from qgis.core import QgsMessageLog, QgsVectorFileWriter, QgsVectorLayer, \
- QgsCoordinateReferenceSystem, QgsCoordinateTransform, \
- QgsGeometry, QgsField, QgsPointXY, QgsProcessingMultiStepFeedback,\
- QgsFeature, QgsProject, QgsFields
+from qgis.core import (
+ QgsMessageLog,
+ QgsVectorFileWriter,
+ QgsVectorLayer,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsGeometry,
+ QgsField,
+ QgsPointXY,
+ QgsProcessingMultiStepFeedback,
+ QgsFeature,
+ QgsProject,
+ QgsFields,
+)
from .genericThread import GenericThread
+
class InventoryMessages(QObject):
def __init__(self, thread):
"""
@@ -47,40 +58,41 @@ def __init__(self, thread):
super(InventoryMessages, self).__init__()
self.thread = thread
-
+
def getInventoryErrorMessage(self):
"""
Returns generic error message
"""
- return self.tr('An error occurred while searching for files.')
-
+ return self.tr("An error occurred while searching for files.")
+
def getCopyErrorMessage(self):
"""
Returns copy error message
"""
- return self.tr('An error occurred while copying the files.')
-
+ return self.tr("An error occurred while copying the files.")
+
def getSuccessInventoryMessage(self):
"""
Returns success message
"""
- return self.tr('Inventory successfully created!')
-
+ return self.tr("Inventory successfully created!")
+
def getSuccessInventoryAndCopyMessage(self):
"""
Returns successful copy message
"""
- return self.tr('Inventory and copy performed successfully!')
+ return self.tr("Inventory and copy performed successfully!")
def getUserCanceledFeedbackMessage(self):
"""
Returns user canceled message
"""
- return self.tr('User canceled inventory processing!')
-
+ return self.tr("User canceled inventory processing!")
+
@pyqtSlot()
def progressCanceled(self):
- self.thread.stopped[0] = True
+ self.thread.stopped[0] = True
+
class InventoryThread(GenericThread):
def __init__(self):
@@ -94,17 +106,26 @@ def __init__(self):
gdal.DontUseExceptions()
ogr.DontUseExceptions()
self.layer_attributes = [
- QgsField('filename', QVariant.String),
- QgsField('date', QVariant.String),
- QgsField('size', QVariant.String),
- QgsField('extension', QVariant.String)
- ]
+ QgsField("filename", QVariant.String),
+ QgsField("date", QVariant.String),
+ QgsField("size", QVariant.String),
+ QgsField("extension", QVariant.String),
+ ]
self.qgsattr = QgsFields()
for i in self.layer_attributes:
self.qgsattr.append(i)
-
-
- def setParameters(self, parentFolder, outputFile, makeCopy, destinationFolder, formatsList, isWhitelist, isOnlyGeo, stopped):
+
+ def setParameters(
+ self,
+ parentFolder,
+ outputFile,
+ makeCopy,
+ destinationFolder,
+ formatsList,
+ isWhitelist,
+ isOnlyGeo,
+ stopped,
+ ):
self.parentFolder = parentFolder
self.outputFile = outputFile
self.makeCopy = makeCopy
@@ -113,48 +134,62 @@ def setParameters(self, parentFolder, outputFile, makeCopy, destinationFolder, f
self.stopped = stopped
self.isWhitelist = isWhitelist
self.isOnlyGeo = isOnlyGeo
-
+
def run(self):
"""
Runs the thread
"""
# Actual process
- (ret, msg) = self.makeInventory(self.parentFolder, self.outputFile, self.destinationFolder)
-
+ (ret, msg) = self.makeInventory(
+ self.parentFolder, self.outputFile, self.destinationFolder
+ )
+
if ret == 1:
self.signals.loadFile.emit(self.outputFile, self.isOnlyGeo)
-
+
self.signals.processingFinished.emit(ret, msg, self.getId())
-
+
def get_format_set(self, format_list):
- if 'shp' in format_list:
- return set(format_list + ['prj'])
+ if "shp" in format_list:
+ return set(format_list + ["prj"])
else:
return set(format_list)
-
- def make_inventory_from_processing(self, parent_folder, format_list, destination_folder=None, make_copy=False, onlyGeo=True, feedback=None):
+
+ def make_inventory_from_processing(
+ self,
+ parent_folder,
+ format_list,
+ destination_folder=None,
+ make_copy=False,
+ onlyGeo=True,
+ feedback=None,
+ ):
featList = []
fileList = []
format_set = self.get_format_set(format_list)
tuple_list = [i for i in os.walk(parent_folder)]
nSteps = len(tuple_list) if make_copy else len(tuple_list) - 1
- multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback) if feedback else None
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(nSteps, feedback) if feedback else None
+ )
for current_step, [root, dirs, files] in enumerate(tuple_list):
if feedback is not None:
if feedback.isCanceled():
return []
multiStepFeedback.setCurrentStep(current_step)
n_files = len(files)
- files_progress = 100/n_files if n_files else 0
+ files_progress = 100 / n_files if n_files else 0
for current, current_file in enumerate(files):
if multiStepFeedback is not None and multiStepFeedback.isCanceled():
break
- extension = current_file.split('.')[-1]
+ extension = current_file.split(".")[-1]
if extension not in format_set:
continue
full_path = self.get_full_path(current_file, root)
if gdal.Open(full_path) or ogr.Open(full_path):
- bbox_geom, attributes = self.computeBoxAndAttributes(None, full_path, extension, insertIntoMemory=False)
+ bbox_geom, attributes = self.computeBoxAndAttributes(
+ None, full_path, extension, insertIntoMemory=False
+ )
new_feat = self.get_new_feat(bbox_geom, attributes)
featList.append(new_feat)
fileList.append(full_path)
@@ -171,26 +206,22 @@ def make_inventory_from_processing(self, parent_folder, format_list, destination
self.copy_single_file(file_, destination_folder)
if multiStepFeedback is not None:
multiStepFeedback.pushInfo(
- self.tr('File {file} copied to {destination}').format(
- file=file_,
- destination=destination_folder
+ self.tr("File {file} copied to {destination}").format(
+ file=file_, destination=destination_folder
)
)
except Exception as e:
if multiStepFeedback is not None:
multiStepFeedback.pushInfo(
- self.tr('Error copying file {file}: {exception}\n').format(
- file=file_,
- exception='\n'.join(e.args)
+ self.tr("Error copying file {file}: {exception}\n").format(
+ file=file_, exception="\n".join(e.args)
)
)
return featList
-
-
def get_full_path(self, file_name, root):
- line = os.path.join(root,file_name)
- line = line.encode(encoding='UTF-8')
+ line = os.path.join(root, file_name)
+ line = line.encode(encoding="UTF-8")
return line
def get_new_feat(self, geom, attributes):
@@ -199,22 +230,25 @@ def get_new_feat(self, geom, attributes):
new_feat.setGeometry(geom)
return new_feat
-
def makeInventory(self, parentFolder, outputFile, destinationFolder):
"""
Makes the inventory
"""
# creating a csv file
try:
- csvfile = open(outputFile, 'wb')
+ csvfile = open(outputFile, "wb")
except IOError as e:
- QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO)
- return (0, self.messenger.getInventoryErrorMessage()+'\n'+e.strerror)
+ QgsMessageLog.logMessage(
+ self.messenger.getInventoryErrorMessage() + "\n" + e.strerror,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
+ return (0, self.messenger.getInventoryErrorMessage() + "\n" + e.strerror)
try:
outwriter = csv.writer(csvfile)
# defining the first row
- outwriter.writerow(['fileName', 'date', 'size (KB)', 'extension'])
+ outwriter.writerow(["fileName", "date", "size (KB)", "extension"])
# creating the memory layer used in only geo mode
layer = self.createMemoryLayer()
# iterating over the parent folder recursively
@@ -224,24 +258,24 @@ def makeInventory(self, parentFolder, outputFile, destinationFolder):
for file in files:
# check if the user stopped the operation
if not self.stopped[0]:
- extension = file.split('.')[-1]
+ extension = file.split(".")[-1]
# check if the file should be skipped
if not self.inventoryFile(extension):
continue
# making the full path
- line = os.path.join(root,file)
- line = line.encode(encoding='UTF-8')
+ line = os.path.join(root, file)
+ line = line.encode(encoding="UTF-8")
# changing the separator, it will be changed later
- line = line.replace(os.sep, '/')
+ line = line.replace(os.sep, "/")
# forcing the inventory of .prj files
- if extension == 'prj':
+ if extension == "prj":
self.writeLine(outwriter, line, extension)
else:
# check if GDAL/OGR recognizes the file
gdalSrc = gdal.Open(line)
ogrSrc = ogr.Open(line)
if gdalSrc or ogrSrc:
- #if only geo mode
+ # if only geo mode
if self.isOnlyGeo:
self.computeBoxAndAttributes(layer, line, extension)
else:
@@ -249,35 +283,57 @@ def makeInventory(self, parentFolder, outputFile, destinationFolder):
self.files.append(line)
gdalSrc = None
ogrSrc = None
-
+
self.signals.stepProcessed.emit(self.getId())
else:
- QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getUserCanceledFeedbackMessage(),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return (-1, self.messenger.getUserCanceledFeedbackMessage())
except csv.Error as e:
csvfile.close()
- QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+e, "DSGTools Plugin", QgsMessageLog.INFO)
- return (0, self.messenger.getInventoryErrorMessage()+'\n'+e)
+ QgsMessageLog.logMessage(
+ self.messenger.getInventoryErrorMessage() + "\n" + e,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
+ return (0, self.messenger.getInventoryErrorMessage() + "\n" + e)
except OSError as e:
csvfile.close()
- QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO)
- return (0, self.messenger.getInventoryErrorMessage()+'\n'+e.strerror)
+ QgsMessageLog.logMessage(
+ self.messenger.getInventoryErrorMessage() + "\n" + e.strerror,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
+ return (0, self.messenger.getInventoryErrorMessage() + "\n" + e.strerror)
except Exception as e:
csvfile.close()
- QgsMessageLog.logMessage(self.messenger.getInventoryErrorMessage()+'\n'+':'.join(e.args), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getInventoryErrorMessage() + "\n" + ":".join(e.args),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return (0, self.messenger.getInventoryErrorMessage())
csvfile.close()
-
+
if self.isOnlyGeo:
- error = QgsVectorFileWriter.writeAsVectorFormat(layer, self.outputFile, "utf-8", None, "ESRI Shapefile")
-
+ error = QgsVectorFileWriter.writeAsVectorFormat(
+ layer, self.outputFile, "utf-8", None, "ESRI Shapefile"
+ )
+
if self.makeCopy:
# return self.copyFiles(destinationFolder)
return self.copy(destinationFolder)
else:
- QgsMessageLog.logMessage(self.messenger.getSuccessInventoryMessage(), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getSuccessInventoryMessage(),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return (1, self.messenger.getSuccessInventoryMessage())
-
+
def computeBoxAndAttributes(self, layer, line, extension, insertIntoMemory=True):
"""
Computes bounding box and inventory attributes
@@ -297,7 +353,7 @@ def computeBoxAndAttributes(self, layer, line, extension, insertIntoMemory=True)
if not insertIntoMemory:
return qgsPolygon, attributes
self.insertIntoMemoryLayer(layer, qgsPolygon, attributes)
-
+
def copyFiles(self, destinationFolder):
"""
Copy inventoried files to the destination folder
@@ -305,22 +361,34 @@ def copyFiles(self, destinationFolder):
for fileName in self.files:
if not self.stopped[0]:
# adjusting the separators according to the OS
- fileName = fileName.replace('/', os.sep)
+ fileName = fileName.replace("/", os.sep)
file = fileName.split(os.sep)[-1]
newFileName = os.path.join(destinationFolder, file)
- newFileName = newFileName.replace('/', os.sep)
+ newFileName = newFileName.replace("/", os.sep)
# making tha actual copy
try:
shutil.copy2(fileName, newFileName)
except IOError as e:
- QgsMessageLog.logMessage(self.messenger.getCopyErrorMessage()+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO)
- return (0, self.messenger.getCopyErrorMessage()+'\n'+e.strerror)
+ QgsMessageLog.logMessage(
+ self.messenger.getCopyErrorMessage() + "\n" + e.strerror,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
+ return (0, self.messenger.getCopyErrorMessage() + "\n" + e.strerror)
else:
- QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getUserCanceledFeedbackMessage(),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return (-1, self.messenger.getUserCanceledFeedbackMessage())
- QgsMessageLog.logMessage(self.messenger.getSuccessInventoryAndCopyMessage(), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getSuccessInventoryAndCopyMessage(),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return (1, self.messenger.getSuccessInventoryAndCopyMessage())
def copy(self, destinationFolder):
@@ -330,10 +398,10 @@ def copy(self, destinationFolder):
"""
for fileName in self.files:
# adjusting the separators according to the OS
- fileName = fileName.replace('/', os.sep)
+ fileName = fileName.replace("/", os.sep)
file = fileName.split(os.sep)[-1]
newFileName = os.path.join(destinationFolder, file)
- newFileName = newFileName.replace('/', os.sep)
+ newFileName = newFileName.replace("/", os.sep)
try:
gdalSrc = gdal.Open(fileName)
@@ -343,17 +411,28 @@ def copy(self, destinationFolder):
elif gdalSrc:
self.copyGDALDataSource(gdalSrc, newFileName)
except Exception as e:
- QgsMessageLog.logMessage(self.messenger.getCopyErrorMessage()+'\n'+':'.join(e.args), "DSGTools Plugin", QgsMessageLog.INFO)
- return (0, self.messenger.getCopyErrorMessage()+'\n'+':'.join(e.args))
-
- QgsMessageLog.logMessage(self.messenger.getSuccessInventoryAndCopyMessage(), "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.messenger.getCopyErrorMessage() + "\n" + ":".join(e.args),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
+ return (
+ 0,
+ self.messenger.getCopyErrorMessage() + "\n" + ":".join(e.args),
+ )
+
+ QgsMessageLog.logMessage(
+ self.messenger.getSuccessInventoryAndCopyMessage(),
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
return (1, self.messenger.getSuccessInventoryAndCopyMessage())
-
+
def copy_single_file(self, file_name, destination_folder):
- file_name = file_name.replace('/', os.sep)
+ file_name = file_name.replace("/", os.sep)
file_ = file_name.split(os.sep)[-1]
newFileName = os.path.join(destination_folder, file_)
- newFileName = newFileName.replace('/', os.sep)
+ newFileName = newFileName.replace("/", os.sep)
gdalSrc = gdal.Open(fileName)
ogrSrc = ogr.Open(fileName)
if ogrSrc:
@@ -371,7 +450,7 @@ def copyGDALDataSource(self, gdalSrc, newFileName):
dst_ds = driver.CreateCopy(newFileName, gdalSrc)
ogrSrc = None
dst_ds = None
-
+
def copyOGRDataSource(self, ogrSrc, newFileName):
"""
Copies a OGR datasource
@@ -389,9 +468,9 @@ def isInFormatsList(self, ext):
ext: file extension
"""
if ext in self.formatsList:
- return True
+ return True
return False
-
+
def inventoryFile(self, ext):
"""
Check is the extension should be analyzed
@@ -401,7 +480,7 @@ def inventoryFile(self, ext):
return self.isInFormatsList(ext)
else:
return not self.isInFormatsList(ext)
-
+
def writeLine(self, outwriter, line, extension):
"""
Write CSV line
@@ -411,7 +490,7 @@ def writeLine(self, outwriter, line, extension):
"""
row = self.makeAttributes(line, extension)
outwriter.writerow(row)
-
+
def makeAttributes(self, line, extension):
"""
Make the attributes array
@@ -419,29 +498,29 @@ def makeAttributes(self, line, extension):
extension: file extension
"""
creationDate = time.ctime(os.path.getctime(line))
- size = os.path.getsize(line)/1000.
-
+ size = os.path.getsize(line) / 1000.0
+
return [str(line), creationDate, size, extension]
-
+
def getRasterExtent(self, gt, cols, rows):
- """
+ """
Return list of corner coordinates from a geotransform
@param gt: geotransform
@param cols: number of columns in the dataset
@param rows: number of rows in the dataset
@return: coordinates of each corner
"""
- ext=[]
- xarr=[0,cols]
- yarr=[0,rows]
-
+ ext = []
+ xarr = [0, cols]
+ yarr = [0, rows]
+
for px in xarr:
for py in yarr:
- x=gt[0]+(px*gt[1])+(py*gt[2])
- y=gt[3]+(px*gt[4])+(py*gt[5])
- ext.append([x,y])
+ x = gt[0] + (px * gt[1]) + (py * gt[2])
+ y = gt[3] + (px * gt[4]) + (py * gt[5])
+ ext.append([x, y])
yarr.reverse()
- return ext
+ return ext
def getExtent(self, filename):
"""
@@ -457,7 +536,7 @@ def getExtent(self, filename):
layer = ogrSrc.GetLayer(id)
extent = layer.GetExtent()
spatialRef = layer.GetSpatialRef()
-
+
# Create a Polygon from the extent tuple
ring = ogr.Geometry(ogr.wkbLinearRing)
ring.AddPoint(extent[0], extent[2])
@@ -467,9 +546,9 @@ def getExtent(self, filename):
ring.AddPoint(extent[0], extent[2])
box = ogr.Geometry(ogr.wkbPolygon)
box.AddGeometry(ring)
-
+
poly = poly.Union(box)
-
+
ogrSrc = None
if not spatialRef:
return (None, None)
@@ -483,30 +562,30 @@ def getExtent(self, filename):
ring = ogr.Geometry(ogr.wkbLinearRing)
for pt in ext:
- ring.AddPoint(pt[0],pt[1])
+ ring.AddPoint(pt[0], pt[1])
ring.AddPoint(ext[0][0], ext[0][1])
box = ogr.Geometry(ogr.wkbPolygon)
box.AddGeometry(ring)
-
+
prjWkt = gdalSrc.GetProjectionRef()
gdalSrc = None
return (box, prjWkt)
else:
return (None, None)
-
+
def createMemoryLayer(self):
"""
Creates a memory layer
"""
- layer = QgsVectorLayer('Polygon?crs=4326', 'Inventory', 'memory')
+ layer = QgsVectorLayer("Polygon?crs=4326", "Inventory", "memory")
if not layer.isValid():
return None
provider = layer.dataProvider()
provider.addAttributes(self.layer_attributes)
layer.updateFields()
return layer
-
+
def reprojectBoundingBox(self, crsSrc, ogrPoly):
"""
Reprojects the bounding box
@@ -514,8 +593,10 @@ def reprojectBoundingBox(self, crsSrc, ogrPoly):
ogrPoly: ogr polygon
"""
crsDest = QgsCoordinateReferenceSystem(4326)
- coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance())
-
+ coordinateTransformer = QgsCoordinateTransform(
+ crsSrc, crsDest, QgsProject.instance()
+ )
+
newPolyline = []
ring = ogrPoly.GetGeometryRef(0)
for i in range(ring.GetPointCount()):
@@ -525,7 +606,7 @@ def reprojectBoundingBox(self, crsSrc, ogrPoly):
qgsPolygon = QgsGeometry.fromPolygonXY([newPolyline])
qgsPolygon.transform(coordinateTransformer)
return qgsPolygon
-
+
def insertIntoMemoryLayer(self, layer, poly, attributes):
"""
Inserts the poly into memory layer
@@ -535,7 +616,7 @@ def insertIntoMemoryLayer(self, layer, poly, attributes):
"""
provider = layer.dataProvider()
- #Creating the feature
+ # Creating the feature
feature = QgsFeature()
feature.setGeometry(poly)
feature.setAttributes(attributes)
diff --git a/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py b/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py
index 20bf098c1..44bab6c93 100644
--- a/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py
+++ b/DsgTools/core/Factories/ThreadFactory/postgisDbThread.py
@@ -34,11 +34,12 @@
from ..DbFactory.dbFactory import DbFactory
from DsgTools.core.dsgEnums import DsgEnums
+
class PostgisDbMessages(QObject):
def __init__(self, thread):
"""
PostGIS database creation messages constructor
- :param thread:
+ :param thread:
"""
super(PostgisDbMessages, self).__init__()
@@ -48,19 +49,28 @@ def getProblemMessage(self, command, query):
"""
Returns database structure creation error message
"""
- return self.tr("Problem on database structure creation: ")+'SQL: '+command+'\n'+query.lastError().text()+'\n'
+ return (
+ self.tr("Problem on database structure creation: ")
+ + "SQL: "
+ + command
+ + "\n"
+ + query.lastError().text()
+ + "\n"
+ )
def getProblemFeedbackMessage(self):
"""
Returns database creation error message
"""
- return self.tr('Problem creating the database structure!\n Check the Log terminal for details.')
+ return self.tr(
+ "Problem creating the database structure!\n Check the Log terminal for details."
+ )
def getUserCanceledFeedbackMessage(self):
"""
Returns user canceled error message
"""
- return self.tr('User canceled the database structure creation!')
+ return self.tr("User canceled the database structure creation!")
def getSuccessFeedbackMessage(self):
"""
@@ -72,15 +82,16 @@ def getSuccessFeedbackMessage(self):
def progressCanceled(self):
self.thread.stopped[0] = True
+
class PostgisDbThread(GenericThread):
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""
Constructor.
"""
super(PostgisDbThread, self).__init__()
self.factory = SqlGeneratorFactory()
- #setting the sql generator
+ # setting the sql generator
self.gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS)
self.messenger = PostgisDbMessages(self)
self.dbFactory = DbFactory()
@@ -90,9 +101,9 @@ def setParameters(self, abstractDb, dbName, version, epsg, stopped):
"""
Sets thread parameters
"""
- self.abstractDb = abstractDb #database = postgis
+ self.abstractDb = abstractDb # database = postgis
self.dbName = dbName
- self.db = None
+ self.db = None
self.version = version
self.epsg = epsg
self.stopped = stopped
@@ -105,7 +116,7 @@ def run(self):
(ret, msg) = self.createDatabaseStructure()
self.signals.processingFinished.emit(ret, msg, self.getId())
- def connectToTemplate(self, setInnerDb = True):
+ def connectToTemplate(self, setInnerDb=True):
"""
Connects to the template database to speed up database creation
:return:
@@ -127,15 +138,15 @@ def createDatabaseStructure(self):
Creates database structure according to the selected edgv version
"""
currentPath = os.path.dirname(__file__)
- currentPath = os.path.join(currentPath, '..', '..', 'DbTools', 'PostGISTool')
- if self.version == '2.1.3':
- edgvPath = os.path.join(currentPath, 'sqls', '213', 'edgv213.sql')
- elif self.version == '2.1.3 Pro':
- edgvPath = os.path.join(currentPath, 'sqls', '213_Pro', 'edgv213_pro.sql')
- elif self.version == '3.0':
- edgvPath = os.path.join(currentPath, 'sqls', '3', 'edgv3.sql')
+ currentPath = os.path.join(currentPath, "..", "..", "DbTools", "PostGISTool")
+ if self.version == "2.1.3":
+ edgvPath = os.path.join(currentPath, "sqls", "213", "edgv213.sql")
+ elif self.version == "2.1.3 Pro":
+ edgvPath = os.path.join(currentPath, "sqls", "213_Pro", "edgv213_pro.sql")
+ elif self.version == "3.0":
+ edgvPath = os.path.join(currentPath, "sqls", "3", "edgv3.sql")
else:
- edgvPath = ''
+ edgvPath = ""
return self.loadDatabaseStructure(edgvPath)
def loadDatabaseStructure(self, edgvPath):
@@ -146,22 +157,22 @@ def loadDatabaseStructure(self, edgvPath):
commands = []
hasTemplate = self.abstractDb.checkTemplate(self.version)
if hasTemplate:
- templateDb = self.connectToTemplate(setInnerDb = False)
+ templateDb = self.connectToTemplate(setInnerDb=False)
mustUpdateTemplate = templateDb.checkTemplateImplementationVersion()
if mustUpdateTemplate:
templateName = templateDb.db.databaseName()
templateDb.__del__()
- self.abstractDb.dropDatabase(templateName, dropTemplate = True)
+ self.abstractDb.dropDatabase(templateName, dropTemplate=True)
hasTemplate = False
if not hasTemplate:
- file = codecs.open(edgvPath, encoding='utf-8', mode="r")
+ file = codecs.open(edgvPath, encoding="utf-8", mode="r")
sql = file.read()
- sql = sql.replace('[epsg]', '4674')
+ sql = sql.replace("[epsg]", "4674")
file.close()
- commands = [i for i in sql.split('#') if i != '']
+ commands = [i for i in sql.split("#") if i != ""]
# Progress bar steps calculated
- self.signals.rangeCalculated.emit(len(commands)+4, self.getId())
-
+ self.signals.rangeCalculated.emit(len(commands) + 4, self.getId())
+
if not hasTemplate:
try:
self.abstractDb.createTemplateDatabase(self.version)
@@ -169,68 +180,117 @@ def loadDatabaseStructure(self, edgvPath):
self.connectToTemplate()
self.signals.stepProcessed.emit(self.getId())
except Exception as e:
- return (0, self.messenger.getProblemFeedbackMessage()+'\n'+':'.join(e.args))
+ return (
+ 0,
+ self.messenger.getProblemFeedbackMessage()
+ + "\n"
+ + ":".join(e.args),
+ )
self.db.open()
self.db.transaction()
query = QSqlQuery(self.db)
-
+
for command in commands:
if not self.stopped[0]:
if not query.exec_(command):
- QgsMessageLog.logMessage(self.messenger.getProblemMessage(command, query), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.messenger.getProblemMessage(command, query),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
self.db.rollback()
self.db.close()
self.dropDatabase(self.db)
return (0, self.messenger.getProblemFeedbackMessage())
-
+
# Updating progress
self.signals.stepProcessed.emit(self.getId())
else:
self.db.rollback()
self.db.close()
- self.dropDatabase(self.db)
- QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", Qgis.Info)
+ self.dropDatabase(self.db)
+ QgsMessageLog.logMessage(
+ self.messenger.getUserCanceledFeedbackMessage(),
+ "DSGTools Plugin",
+ Qgis.Info,
+ )
return (-1, self.messenger.getUserCanceledFeedbackMessage())
-
+
self.db.commit()
- if self.version == '2.1.3':
- sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'cb\',\'complexos\',\'dominios\';' % self.db.databaseName()
- elif self.version == '2.1.3 Pro':
- sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'edgv\',\'dominios\';' % self.db.databaseName()
- elif self.version == 'FTer_2a_Ed':
- sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'pe\',\'ge\',\'complexos\',\'dominios\';' % self.db.databaseName()
- elif self.version == '3.0':
- sql = 'ALTER DATABASE %s SET search_path = "$user", public, topology,\'edgv\',\'complexos\',\'dominios\';' % self.db.databaseName()
-
+ if self.version == "2.1.3":
+ sql = (
+ "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'cb','complexos','dominios';"
+ % self.db.databaseName()
+ )
+ elif self.version == "2.1.3 Pro":
+ sql = (
+ "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'edgv','dominios';"
+ % self.db.databaseName()
+ )
+ elif self.version == "FTer_2a_Ed":
+ sql = (
+ "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'pe','ge','complexos','dominios';"
+ % self.db.databaseName()
+ )
+ elif self.version == "3.0":
+ sql = (
+ "ALTER DATABASE %s SET search_path = \"$user\", public, topology,'edgv','complexos','dominios';"
+ % self.db.databaseName()
+ )
+
if sql:
if not query.exec_(sql):
- QgsMessageLog.logMessage(self.messenger.getProblemMessage(command, query), "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.messenger.getProblemMessage(command, query),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
return (0, self.messenger.getProblemFeedbackMessage())
- #this commit was missing, so alter database statement was not commited.
+ # this commit was missing, so alter database statement was not commited.
self.db.commit()
self.db.close()
self.abstractDb.setDbAsTemplate(self.version)
- #creates from template
+ # creates from template
if not self.stopped[0]:
templateName = self.abstractDb.getTemplateName(self.version)
- self.abstractDb.createDbFromTemplate(self.dbName, templateName, parentWidget = self.parent)
+ self.abstractDb.createDbFromTemplate(
+ self.dbName, templateName, parentWidget=self.parent
+ )
self.signals.stepProcessed.emit(self.getId())
- #5. alter spatial structure
+ # 5. alter spatial structure
createdDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS)
- createdDb.connectDatabaseWithParameters(self.abstractDb.db.hostName(), self.abstractDb.db.port(), self.dbName, self.abstractDb.db.userName(), self.abstractDb.db.password())
- errorTuple = createdDb.updateDbSRID(self.epsg, parentWidget = self.parent, threading = True)
+ createdDb.connectDatabaseWithParameters(
+ self.abstractDb.db.hostName(),
+ self.abstractDb.db.port(),
+ self.dbName,
+ self.abstractDb.db.userName(),
+ self.abstractDb.db.password(),
+ )
+ errorTuple = createdDb.updateDbSRID(
+ self.epsg, parentWidget=self.parent, threading=True
+ )
# if an error occur during the thread we should pass the message to the main thread
if errorTuple:
- QgsMessageLog.logMessage(self.messenger.getProblemMessage(errorTuple[0], errorTuple[1]), "DSGTools Plugin", Qgis.Critical)
- return (0, self.messenger.getProblemFeedbackMessage())
+ QgsMessageLog.logMessage(
+ self.messenger.getProblemMessage(errorTuple[0], errorTuple[1]),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ return (0, self.messenger.getProblemFeedbackMessage())
self.signals.stepProcessed.emit(self.getId())
else:
- QgsMessageLog.logMessage(self.messenger.getUserCanceledFeedbackMessage(), "DSGTools Plugin", Qgis.Info)
+ QgsMessageLog.logMessage(
+ self.messenger.getUserCanceledFeedbackMessage(),
+ "DSGTools Plugin",
+ Qgis.Info,
+ )
return (-1, self.messenger.getUserCanceledFeedbackMessage())
- QgsMessageLog.logMessage(self.messenger.getSuccessFeedbackMessage(), "DSGTools Plugin", Qgis.Info)
+ QgsMessageLog.logMessage(
+ self.messenger.getSuccessFeedbackMessage(), "DSGTools Plugin", Qgis.Info
+ )
return (1, self.messenger.getSuccessFeedbackMessage())
- def dropDatabase(self,db):
+ def dropDatabase(self, db):
"""
Drops the created database case a problem occurs during database creation
db: QSqlDatabase to be dropped
@@ -239,8 +299,8 @@ def dropDatabase(self,db):
port = db.port()
user = db.userName()
password = db.password()
- database = 'postgres'
- pgDB = QSqlDatabase('QPSQL')
+ database = "postgres"
+ pgDB = QSqlDatabase("QPSQL")
pgDB.setHostName(host)
pgDB.setPort(port)
pgDB.setUserName(user)
@@ -250,4 +310,4 @@ def dropDatabase(self,db):
return False
sql = self.gen.dropDatabase(db.databaseName())
query = QSqlQuery(pgDB)
- return query.exec_(sql)
\ No newline at end of file
+ return query.exec_(sql)
diff --git a/DsgTools/core/Factories/ThreadFactory/threadFactory.py b/DsgTools/core/Factories/ThreadFactory/threadFactory.py
index 8119983d0..d662fa8d1 100644
--- a/DsgTools/core/Factories/ThreadFactory/threadFactory.py
+++ b/DsgTools/core/Factories/ThreadFactory/threadFactory.py
@@ -25,6 +25,7 @@
from .dpiThread import DpiThread
from .inventoryThread import InventoryThread
+
class ThreadFactory(object):
def makeProcess(self, name):
"""
@@ -32,11 +33,11 @@ def makeProcess(self, name):
:param name:
:return:
"""
- if name == 'pgdb':
+ if name == "pgdb":
return PostgisDbThread()
- elif name == 'dpi':
+ elif name == "dpi":
return DpiThread()
- elif name == 'inventory':
+ elif name == "inventory":
return InventoryThread()
else:
return None
diff --git a/DsgTools/core/GeometricTools/attributeHandler.py b/DsgTools/core/GeometricTools/attributeHandler.py
index 21ee1f3b0..a742dfe2b 100644
--- a/DsgTools/core/GeometricTools/attributeHandler.py
+++ b/DsgTools/core/GeometricTools/attributeHandler.py
@@ -22,25 +22,38 @@
"""
from __future__ import absolute_import
from builtins import range
-from qgis.core import QgsMessageLog, QgsVectorLayer, QgsGeometry, QgsField, \
- QgsVectorDataProvider, QgsFeatureRequest, QgsExpression, \
- QgsFeature, QgsSpatialIndex, Qgis, QgsCoordinateTransform, \
- QgsWkbTypes
+from qgis.core import (
+ QgsMessageLog,
+ QgsVectorLayer,
+ QgsGeometry,
+ QgsField,
+ QgsVectorDataProvider,
+ QgsFeatureRequest,
+ QgsExpression,
+ QgsFeature,
+ QgsSpatialIndex,
+ Qgis,
+ QgsCoordinateTransform,
+ QgsWkbTypes,
+)
from qgis.PyQt.Qt import QObject
+
class AttributeHandler(QObject):
- def __init__(self, iface, parent = None):
+ def __init__(self, iface, parent=None):
super(AttributeHandler, self).__init__()
self.parent = parent
self.iface = iface
- def setFeatureAttributes(self, newFeature, attributeDict, editBuffer=None, oldFeat=None):
+ def setFeatureAttributes(
+ self, newFeature, attributeDict, editBuffer=None, oldFeat=None
+ ):
"""
Changes attribute values according to the reclassification dict using the edit buffer
newFeature: newly added
editBuffer: layer edit buffer
"""
- #setting the attributes using the reclassification dictionary
+ # setting the attributes using the reclassification dictionary
fields = newFeature.fields()
for attribute in attributeDict:
idx = fields.lookupField(attribute)
@@ -49,22 +62,22 @@ def setFeatureAttributes(self, newFeature, attributeDict, editBuffer=None, oldFe
continue
reclass = attributeDict[attribute]
if isinstance(reclass, dict):
- value = reclass['value']
- if reclass['ignored']: #ignore clause
+ value = reclass["value"]
+ if reclass["ignored"]: # ignore clause
if oldFeat:
value = oldFeat[attribute]
else:
value = None
else:
value = reclass
- if value == '':
+ if value == "":
continue
- #actual attribute change
+ # actual attribute change
if editBuffer:
- #this way we are working with the edit buffer
+ # this way we are working with the edit buffer
editBuffer.changeAttributeValue(newFeature.id(), idx, value)
else:
- #this way are working with selected features and inserting a new one in the layer
+ # this way are working with selected features and inserting a new one in the layer
newFeature.setAttribute(idx, value)
# if not editBuffer:
# # we should return when under the normal behavior
@@ -72,7 +85,15 @@ def setFeatureAttributes(self, newFeature, attributeDict, editBuffer=None, oldFe
def getTuppleAttribute(self, feature, unifiedLyr, bList=None):
bList = [] if bList is None else bList
- attributes = [field.name() for idx, field in enumerate(feature.fields()) if (field.type() != 6 and idx not in unifiedLyr.primaryKeyAttributes() and field.name() not in bList)]
+ attributes = [
+ field.name()
+ for idx, field in enumerate(feature.fields())
+ if (
+ field.type() != 6
+ and idx not in unifiedLyr.primaryKeyAttributes()
+ and field.name() not in bList
+ )
+ ]
attributes.sort()
- attributeList = [u'{0}'.format(feature[attribute]) for attribute in attributes]
- return ','.join(attributeList)
+ attributeList = ["{0}".format(feature[attribute]) for attribute in attributes]
+ return ",".join(attributeList)
diff --git a/DsgTools/core/GeometricTools/featureHandler.py b/DsgTools/core/GeometricTools/featureHandler.py
index a19515e55..786dba0a3 100644
--- a/DsgTools/core/GeometricTools/featureHandler.py
+++ b/DsgTools/core/GeometricTools/featureHandler.py
@@ -25,10 +25,24 @@
import itertools
import sys
import os
-from qgis.core import QgsMessageLog, QgsVectorLayer, QgsGeometry, QgsField, QgsVectorDataProvider, \
- QgsFeatureRequest, QgsExpression, QgsFeature, QgsSpatialIndex, Qgis, \
- QgsCoordinateTransform, QgsWkbTypes, QgsProcessingMultiStepFeedback,\
- QgsVectorLayerUtils, QgsCoordinateReferenceSystem, QgsProject
+from qgis.core import (
+ QgsMessageLog,
+ QgsVectorLayer,
+ QgsGeometry,
+ QgsField,
+ QgsVectorDataProvider,
+ QgsFeatureRequest,
+ QgsExpression,
+ QgsFeature,
+ QgsSpatialIndex,
+ Qgis,
+ QgsCoordinateTransform,
+ QgsWkbTypes,
+ QgsProcessingMultiStepFeedback,
+ QgsVectorLayerUtils,
+ QgsCoordinateReferenceSystem,
+ QgsProject,
+)
from qgis.PyQt.Qt import QObject, QVariant
from .geometryHandler import GeometryHandler
@@ -49,19 +63,30 @@ def __init__(self, iface=None, parent=None):
self.utmGrid = UtmGrid()
self.stepsTotal = 0
- def reclassifyFeatures(self, featureList, destinationLayer, reclassificationDict, coordinateTransformer, parameterDict):
+ def reclassifyFeatures(
+ self,
+ featureList,
+ destinationLayer,
+ reclassificationDict,
+ coordinateTransformer,
+ parameterDict,
+ ):
newFeatList = []
deleteList = []
for feat in featureList:
geom = self.geometryHandler.reprojectWithCoordinateTransformer(
- feat.geometry(), coordinateTransformer)
+ feat.geometry(), coordinateTransformer
+ )
geomList = self.geometryHandler.adjustGeometry(geom, parameterDict)
newFeatList += self.createFeaturesWithAttributeDict(
- geomList, feat, reclassificationDict, destinationLayer)
+ geomList, feat, reclassificationDict, destinationLayer
+ )
deleteList.append(feat.id())
return newFeatList, deleteList
- def createFeaturesWithAttributeDict(self, geomList, originalFeat, attributeDict, destinationLayer):
+ def createFeaturesWithAttributeDict(
+ self, geomList, originalFeat, attributeDict, destinationLayer
+ ):
"""
Creates a newFeatureList using each geom from geomList. attributeDict is used to set attributes
"""
@@ -71,7 +96,8 @@ def createFeaturesWithAttributeDict(self, geomList, originalFeat, attributeDict,
newFeature = QgsFeature(fields)
newFeature.setGeometry(geom)
newFeature = self.attributeHandler.setFeatureAttributes(
- newFeature, attributeDict, oldFeat=originalFeat)
+ newFeature, attributeDict, oldFeat=originalFeat
+ )
newFeatureList.append(newFeature)
return newFeatureList
@@ -92,21 +118,36 @@ def createFeatureFromLayer(self, layer, attributes=None, geom=None, fields=None)
newFeature.setGeometry(geom)
if attributes:
newFeature = self.attributeHandler.setFeatureAttributes(
- newFeature, attributes)
+ newFeature, attributes
+ )
return newFeature
- def createUnifiedFeature(self, unifiedLyr, feature, classname, bList=None, attributeTupple=False, coordinateTransformer=None, parameterDict=None):
+ def createUnifiedFeature(
+ self,
+ unifiedLyr,
+ feature,
+ classname,
+ bList=None,
+ attributeTupple=False,
+ coordinateTransformer=None,
+ parameterDict=None,
+ ):
parameterDict = {} if parameterDict is None else parameterDict
bList = [] if bList is None else bList
newFeats = []
- for geom in self.geometryHandler.handleGeometry(feature.geometry(), parameterDict=parameterDict, coordinateTransformer=coordinateTransformer):
+ for geom in self.geometryHandler.handleGeometry(
+ feature.geometry(),
+ parameterDict=parameterDict,
+ coordinateTransformer=coordinateTransformer,
+ ):
newfeat = QgsFeature(unifiedLyr.fields())
newfeat.setGeometry(feature.geometry())
- newfeat['featid'] = feature.id()
- newfeat['layer'] = classname
+ newfeat["featid"] = feature.id()
+ newfeat["layer"] = classname
if attributeTupple:
- newfeat['tupple'] = self.attributeHandler.getTuppleAttribute(
- feature, unifiedLyr, bList=bList)
+ newfeat["tupple"] = self.attributeHandler.getTuppleAttribute(
+ feature, unifiedLyr, bList=bList
+ )
newFeats.append(newfeat)
return newFeats
@@ -130,13 +171,17 @@ def newFeature(self, geom=None, fields=None, attributeMap=None):
if geom:
feat.setGeometry(geom)
if attributeMap:
- feat = self.attributeHandler.setFeatureAttributes(
- feat, attributeMap)
+ feat = self.attributeHandler.setFeatureAttributes(feat, attributeMap)
return feat
- def handleFeature(self, featList, featureWithoutGeom, lyr,
- parameterDict=None,
- coordinateTransformer=None):
+ def handleFeature(
+ self,
+ featList,
+ featureWithoutGeom,
+ lyr,
+ parameterDict=None,
+ coordinateTransformer=None,
+ ):
"""
Handles a feature list to return geometries to update
and a new feature list.
@@ -153,7 +198,8 @@ def handleFeature(self, featList, featureWithoutGeom, lyr,
geomList = []
for feat in featList:
geomList += self.geometryHandler.handleGeometry(
- feat.geometry(), parameterDict, coordinateTransformer)
+ feat.geometry(), parameterDict, coordinateTransformer
+ )
geomToUpdate = None
newFeatList = []
if not geomList:
@@ -163,16 +209,18 @@ def handleFeature(self, featList, featureWithoutGeom, lyr,
geomToUpdate = geom
continue
else:
- newFeat = self.getNewFeatureWithoutGeom(
- featureWithoutGeom, lyr)
+ newFeat = self.getNewFeatureWithoutGeom(featureWithoutGeom, lyr)
newFeat.setGeometry(geom)
newFeatList.append(newFeat)
return geomToUpdate, newFeatList, False
- def handleConvertedFeature(self, feat, lyr, parameterDict=None, coordinateTransformer=None):
+ def handleConvertedFeature(
+ self, feat, lyr, parameterDict=None, coordinateTransformer=None
+ ):
parameterDict = {} if parameterDict is None else parameterDict
geomList = self.geometryHandler.handleGeometry(
- feat.geometry(), parameterDict, coordinateTransformer)
+ feat.geometry(), parameterDict, coordinateTransformer
+ )
newFeatSet = set()
for geom in geomList:
newFeat = QgsVectorLayerUtils.createFeature(lyr, geom)
@@ -190,7 +238,8 @@ def getFeatureOuterShellAndHoles(self, feat, isMulti):
geom = feat.geometry()
outershells, donutholes = self.geometryHandler.getOuterShellAndHoles(
- geom, isMulti)
+ geom, isMulti
+ )
outershellList = []
for shell in outershells:
outerShellFeat = QgsFeature(feat)
@@ -204,7 +253,9 @@ def getFeatureOuterShellAndHoles(self, feat, isMulti):
donutHoleList.append(newFeat)
return outershellList, donutHoleList
- def mergeLineFeatures(self, featList, lyr, idsToRemove, networkDict, parameterDict=None, feedback=None):
+ def mergeLineFeatures(
+ self, featList, lyr, idsToRemove, networkDict, parameterDict=None, feedback=None
+ ):
parameterDict = {} if parameterDict is None else parameterDict
changeDict = dict()
size = 100 / len(featList)
@@ -228,22 +279,25 @@ def mergeLineFeatures(self, featList, lyr, idsToRemove, networkDict, parameterDi
intersectionPoint = geom_a.intersection(geom_b)
for pointPart in intersectionPoint.asGeometryCollection():
point = pointPart.asPoint()
- if (point in networkDict and len(networkDict[point]) == 2):
- newGeom = self.geometryHandler.handleGeometry(geom_a.combine(geom_b).mergeLines(
- ), parameterDict)[0] # only one candidate is possible because features are touching
+ if point in networkDict and len(networkDict[point]) == 2:
+ newGeom = self.geometryHandler.handleGeometry(
+ geom_a.combine(geom_b).mergeLines(), parameterDict
+ )[
+ 0
+ ] # only one candidate is possible because features are touching
feat_a.setGeometry(newGeom)
lyr.updateFeature(feat_a)
idsToRemove.append(id_b)
# changeDict[id_a] = newGeom
if feedback:
- feedback.setProgress(size*current)
+ feedback.setProgress(size * current)
# for id, geom in changeDict.items():
# lyr.changeGeometry(id, geom)
def getNewGridFeat(self, index, geom, fields):
feat = QgsFeature(fields)
- feat['inom'] = index
- feat['mi'] = self.utmGrid.get_MI_MIR_from_inom(index)
+ feat["inom"] = index
+ feat["mi"] = self.utmGrid.get_MI_MIR_from_inom(index)
feat.setGeometry(geom)
return feat
@@ -257,7 +311,7 @@ def getSystematicGridFeatures(
xSubdivisions=3,
ySubdivisions=3,
constraintDict=None,
- feedback=None
+ feedback=None,
):
if feedback is not None and feedback.isCanceled():
return
@@ -268,7 +322,7 @@ def getSystematicGridFeatures(
coordinateTransformer,
constraintDict,
xSubdivisions=xSubdivisions,
- ySubdivisions=ySubdivisions
+ ySubdivisions=ySubdivisions,
)
if frameGeom is None:
return
@@ -278,7 +332,7 @@ def getSystematicGridFeatures(
scaleId = self.utmGrid.getScaleIdFromiNomen(index)
sufixIterator = list(
itertools.chain.from_iterable(
- self.utmGrid.scaleText[scaleId+1]
+ self.utmGrid.scaleText[scaleId + 1]
) # flatten list into one single list
)
# localMultiStepFeedback = QgsProcessingMultiStepFeedback(
@@ -289,17 +343,18 @@ def getSystematicGridFeatures(
if feedback is not None and feedback.isCanceled():
break
# localMultiStepFeedback.setCurrentStep(i)
- inomen2 = '{oldInomem}-{newPart}'.format(
- oldInomem=index,
- newPart=line)
- if constraintDict is not None \
- and self.createGridItem(
- inomen2,
- coordinateTransformer,
- constraintDict,
- xSubdivisions=xSubdivisions,
- ySubdivisions=ySubdivisions
- ) is None:
+ inomen2 = "{oldInomem}-{newPart}".format(oldInomem=index, newPart=line)
+ if (
+ constraintDict is not None
+ and self.createGridItem(
+ inomen2,
+ coordinateTransformer,
+ constraintDict,
+ xSubdivisions=xSubdivisions,
+ ySubdivisions=ySubdivisions,
+ )
+ is None
+ ):
continue
self.getSystematicGridFeatures(
featureList,
@@ -310,66 +365,69 @@ def getSystematicGridFeatures(
xSubdivisions=xSubdivisions,
ySubdivisions=ySubdivisions,
constraintDict=constraintDict,
- feedback=feedback
+ feedback=feedback,
)
- def createGridItem(self, index, coordinateTransformer, constraintDict, xSubdivisions=3, ySubdivisions=3):
- frameGeom = self.utmGrid.getQgsPolygonFrame(index, xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions)
+ def createGridItem(
+ self,
+ index,
+ coordinateTransformer,
+ constraintDict,
+ xSubdivisions=3,
+ ySubdivisions=3,
+ ):
+ frameGeom = self.utmGrid.getQgsPolygonFrame(
+ index, xSubdivisions=xSubdivisions, ySubdivisions=ySubdivisions
+ )
frameGeom.transform(coordinateTransformer)
if constraintDict is None:
return frameGeom
frameBB = frameGeom.boundingBox()
engine = QgsGeometry.createGeometryEngine(frameGeom.constGet())
engine.prepareGeometry()
- for fid in constraintDict['spatialIdx'].intersects(frameBB):
- if getattr(engine, constraintDict['predicate'])(
- constraintDict['idDict'][fid].geometry().constGet()
+ for fid in constraintDict["spatialIdx"].intersects(frameBB):
+ if getattr(engine, constraintDict["predicate"])(
+ constraintDict["idDict"][fid].geometry().constGet()
):
return frameGeom
return None
def getSystematicGridFeaturesWithConstraint(
- self,
- featureList,
- inputLyr,
- stopScale,
- coordinateTransformer,
- fields,
- xSubdivisions=3,
- ySubdivisions=3,
- feedback=None,
- predicate=None
- ):
+ self,
+ featureList,
+ inputLyr,
+ stopScale,
+ coordinateTransformer,
+ fields,
+ xSubdivisions=3,
+ ySubdivisions=3,
+ feedback=None,
+ predicate=None,
+ ):
"""
TODO: Progress
"""
if feedback is not None and feedback.isCanceled():
return
- predicate = 'intersects' if predicate is None else predicate
+ predicate = "intersects" if predicate is None else predicate
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
multiStepFeedback.setCurrentStep(0)
- multiStepFeedback.pushInfo(self.tr('Creating spatial index'))
+ multiStepFeedback.pushInfo(self.tr("Creating spatial index"))
spatialIdx, idDict = self.buildSpatialIndexAndIdDict(
- inputLyr,
- feedback=multiStepFeedback
- )
- multiStepFeedback.pushInfo(self.tr('Getting candidate start indexes'))
- xmin, ymin, xmax, ymax = self.getLyrUnprojectedGeographicBounds(
- inputLyr
- )
- inomenList = self.utmGrid.get_INOM_range_from_BB(
- xmin, ymin, xmax, ymax
+ inputLyr, feedback=multiStepFeedback
)
+ multiStepFeedback.pushInfo(self.tr("Getting candidate start indexes"))
+ xmin, ymin, xmax, ymax = self.getLyrUnprojectedGeographicBounds(inputLyr)
+ inomenList = self.utmGrid.get_INOM_range_from_BB(xmin, ymin, xmax, ymax)
multiStepFeedback.setCurrentStep(1)
- multiStepFeedback.pushInfo(self.tr('Building grid'))
+ multiStepFeedback.pushInfo(self.tr("Building grid"))
gridMultistepFeedback = QgsProcessingMultiStepFeedback(
- len(inomenList),
- multiStepFeedback
+ len(inomenList), multiStepFeedback
)
constraintDict = {
- 'spatialIdx': spatialIdx,
- 'idDict': idDict,
- 'predicate': predicate
+ "spatialIdx": spatialIdx,
+ "idDict": idDict,
+ "predicate": predicate,
}
sys.setrecursionlimit(10**7)
@@ -383,8 +441,9 @@ def compute(x):
xSubdivisions=xSubdivisions,
ySubdivisions=ySubdivisions,
constraintDict=constraintDict,
- feedback=gridMultistepFeedback
+ feedback=gridMultistepFeedback,
)
+
pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count())
futures = []
current_idx = 0
@@ -392,9 +451,7 @@ def compute(x):
# gridMultistepFeedback.setCurrentStep(i)
if gridMultistepFeedback.isCanceled():
break
- futures.append(
- pool.submit(compute, inomen)
- )
+ futures.append(pool.submit(compute, inomen))
for x in concurrent.futures.as_completed(futures):
if gridMultistepFeedback.isCanceled():
@@ -402,8 +459,7 @@ def compute(x):
gridMultistepFeedback.setCurrentStep(current_idx)
current_idx += 1
- def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None,
- featureRequest=None):
+ def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None, featureRequest=None):
"""
creates a spatial index for the input layer
:param inputLyr: (QgsVectorLayer) input layer;
@@ -413,23 +469,29 @@ def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None,
spatialIdx = QgsSpatialIndex()
idDict = {}
featCount = inputLyr.featureCount()
- size = 100/featCount if featCount else 0
- iterator = inputLyr.getFeatures() if featureRequest is None\
+ size = 100 / featCount if featCount else 0
+ iterator = (
+ inputLyr.getFeatures()
+ if featureRequest is None
else inputLyr.getFeatures(featureRequest)
-
- def addFeatureAlias(x): return self.addFeatureToSpatialIndex(
- current=x[0],
- feat=x[1],
- spatialIdx=spatialIdx,
- idDict=idDict,
- size=size,
- feedback=feedback
)
+
+ def addFeatureAlias(x):
+ return self.addFeatureToSpatialIndex(
+ current=x[0],
+ feat=x[1],
+ spatialIdx=spatialIdx,
+ idDict=idDict,
+ size=size,
+ feedback=feedback,
+ )
+
list(map(addFeatureAlias, enumerate(iterator)))
return spatialIdx, idDict
- def addFeatureToSpatialIndex(self, current, feat, spatialIdx,
- idDict, size, feedback):
+ def addFeatureToSpatialIndex(
+ self, current, feat, spatialIdx, idDict, size, feedback
+ ):
"""
Adds feature to spatial index. Used along side with a
python map operator to improve performance.
@@ -454,7 +516,7 @@ def getLyrUnprojectedGeographicBounds(self, inputLyr):
coordinateTransformer = QgsCoordinateTransform(
crs,
QgsCoordinateReferenceSystem(crs.geographicCrsAuthId()),
- QgsProject.instance()
+ QgsProject.instance(),
)
reprojectedGeographicBB = coordinateTransformer.transformBoundingBox(
inputLyr.extent()
diff --git a/DsgTools/core/GeometricTools/geometryHandler.py b/DsgTools/core/GeometricTools/geometryHandler.py
index b3fd64980..8799e24ab 100644
--- a/DsgTools/core/GeometricTools/geometryHandler.py
+++ b/DsgTools/core/GeometricTools/geometryHandler.py
@@ -27,9 +27,17 @@
from functools import partial
from itertools import combinations
-from qgis.core import (Qgis, QgsCoordinateReferenceSystem,
- QgsCoordinateTransform, QgsGeometry, QgsPoint,
- QgsPointXY, QgsProject, QgsVectorLayer, QgsWkbTypes)
+from qgis.core import (
+ Qgis,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsGeometry,
+ QgsPoint,
+ QgsPointXY,
+ QgsProject,
+ QgsVectorLayer,
+ QgsWkbTypes,
+)
from qgis.PyQt.Qt import QObject
@@ -40,58 +48,67 @@ def __init__(self, iface=None, parent=None):
self.iface = iface
if self.iface:
self.canvas = iface.mapCanvas()
-
+
def getClockWiseList(self, pointList):
pointSum = 0
for i in range(len(pointList) - 1):
- pointSum += (pointList[i+1].x() - pointList[i].x())*(pointList[i+1].y() + pointList[i].y())
+ pointSum += (pointList[i + 1].x() - pointList[i].x()) * (
+ pointList[i + 1].y() + pointList[i].y()
+ )
if pointSum > 0:
return pointList
else:
return pointList[::-1]
-
+
def reprojectWithCoordinateTransformer(self, geom, coordinateTransformer):
if coordinateTransformer:
geom.transform(coordinateTransformer)
return geom
-
+
def adjustGeometry(self, geom, parameterDict):
geomList = []
if geom is not None:
- if 'geometry' in dir(geom):
- if not parameterDict['hasMValues']:
+ if "geometry" in dir(geom):
+ if not parameterDict["hasMValues"]:
geom.geometry().dropMValue()
- if not parameterDict['hasZValues']:
+ if not parameterDict["hasZValues"]:
geom.geometry().dropZValue()
if geom.isMultipart():
parts = geom.asGeometryCollection()
for part in parts:
- if parameterDict['isMulti']:
+ if parameterDict["isMulti"]:
part.convertToMultiType()
geomList.append(part)
else:
- if parameterDict['isMulti']:
+ if parameterDict["isMulti"]:
geom.convertToMultiType()
geomList.append(geom)
return geomList
-
- def reprojectFeature(self, geom, referenceCrs, destinationCrs=None, coordinateTransformer=None, debugging=False):
+
+ def reprojectFeature(
+ self, geom, referenceCrs, destinationCrs=None, coordinateTransformer=None
+ ):
"""
Reprojects geom from the canvas crs to the reference crs.
:param geom: geometry to be reprojected
- :param referenceCrs: reference CRS (coordinate reference system).
+ :param referenceCrs: reference CRS (coordinate reference system).
:param canvasCrs: canvas CRS. If not given, it'll be evaluated on runtime execution.
:param coordinateTransformer: the coordinate transformer for canvas to reference CRS
- :param debbuging: if True, method returns the the list [geometry, canvasCrs, referenceCrs, coordinateTransformer]
"""
if not destinationCrs:
destinationCrs = QgsProject.instance().crs()
- if destinationCrs.authid() != referenceCrs.authid():
- if not coordinateTransformer:
- coordinateTransformer = QgsCoordinateTransform(destinationCrs, referenceCrs, QgsProject.instance())
- geom.transform(coordinateTransformer)
- if debugging:
- return [geom, canvasCrs, referenceCrs, coordinateTransformer]
+ if destinationCrs.authid() == referenceCrs.authid():
+ return
+ coordinateTransformer = (
+ QgsCoordinateTransform(
+ QgsCoordinateReferenceSystem(destinationCrs),
+ QgsCoordinateReferenceSystem(referenceCrs),
+ QgsProject.instance(),
+ )
+ if not coordinateTransformer
+ else coordinateTransformer
+ )
+ geom.transform(coordinateTransformer)
def reprojectSearchArea(self, layer, geom):
"""
@@ -100,16 +117,18 @@ def reprojectSearchArea(self, layer, geom):
:param geom: (QgsRectangle) rectangle representing search area.
:return: (QgsRectangle) rectangle representing reprojected search area.
"""
- #geom always have canvas coordinates
+ # geom always have canvas coordinates
epsg = self.canvas.mapSettings().destinationCrs().authid()
- #getting srid from something like 'EPSG:31983'
+ # getting srid from something like 'EPSG:31983'
srid = layer.crs().authid()
if epsg == srid:
return geom
crsSrc = QgsCoordinateReferenceSystem(epsg)
crsDest = QgsCoordinateReferenceSystem(srid)
# Creating a transformer
- coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance()) # here we have to put authid, not srid
+ coordinateTransformer = QgsCoordinateTransform(
+ crsSrc, crsDest, QgsProject.instance()
+ ) # here we have to put authid, not srid
auxGeom = QgsGeometry.fromRect(geom)
auxGeom.transform(coordinateTransformer)
return auxGeom.boundingBox()
@@ -128,7 +147,7 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False):
geomType = layer.geometryType()
# getting whether geometry is multipart or not
# features not yet commited to layer always have SINGLE geometry
- isMulti = QgsWkbTypes.isMultiType(int(layer.wkbType())) and feature.id() > 0
+ isMulti = QgsWkbTypes.isMultiType(layer.wkbType()) and feature.id() > 0
geom = feature.geometry()
if geomType == 0:
if isMulti:
@@ -137,12 +156,12 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False):
for idx, part in enumerate(nodes):
nodes[idx] = part[::-1]
# setting flipped geometry
- flippedFeatureGeom = QgsGeometry.fromMultiPointXY(nodes)
+ flippedFeatureGeom = QgsGeometry.fromMultiPointXY(nodes)
else:
# inverting the point list
nodes = geom.asPoint()
nodes = nodes[::-1]
- flippedFeatureGeom = QgsGeometry.fromPoint(nodes)
+ flippedFeatureGeom = QgsGeometry.fromPoint(nodes)
elif geomType == 1:
if isMulti:
nodes = geom.asMultiPolyline()
@@ -155,10 +174,10 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False):
flippedFeatureGeom = QgsGeometry.fromPolylineXY(nodes)
elif geomType == 2:
if isMulti:
- nodes = geom.asMultiPolygon()
+ nodes = geom.asMultiPolygon()
for idx, part in enumerate(nodes):
nodes[idx] = part[::-1]
- flippedFeatureGeom = QgsGeometry.fromMultiPolygonXY(nodes)
+ flippedFeatureGeom = QgsGeometry.fromMultiPolygonXY(nodes)
else:
nodes = geom.asPolygon()
nodes = nodes[::-1]
@@ -170,14 +189,14 @@ def flipFeature(self, layer, feature, geomType=None, refreshCanvas=False):
if refreshCanvas:
self.iface.mapCanvas().refresh()
return [layer, feature, geomType]
-
+
# MISSING REPROJECTION
def flipFeatureList(self, featureList, debugging=False, refreshCanvas=True):
"""
Inverts the flow from all features of a given list. ALL GIVEN FEATURES ARE ALTERED.
:param featureList: list of features to be flipped ([layer, feature[, geometry_type]).
:param debugging: optional parameter to indicate whether or not a list of features that failed
- to be reversed should be returner.
+ to be reversed should be returner.
:returns: list of flipped features.
"""
reversedFeatureList = []
@@ -215,57 +234,105 @@ def isclose(self, a, b, rel_tol=None, abs_tol=None):
rel_tol = 1e-09 if rel_tol is None else rel_tol
abs_tol = 0.0 if abs_tol is None else abs_tol
return abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
-
- def getOutOfBoundsAngleInPolygon(self, feat, part, angle, outOfBoundsList, exactAngleMatch=False, angTol=None, invalidRange=None):
+
+ def getOutOfBoundsAngleInPolygon(
+ self,
+ feat,
+ part,
+ angle,
+ outOfBoundsList,
+ exactAngleMatch=False,
+ angTol=None,
+ invalidRange=None,
+ ):
angTol = 0.1 if angTol is None else angTol
if invalidRange is not None:
minAngle, maxAngle = invalidRange
for linearRing in part.asPolygon():
linearRing = self.getClockWiseList(linearRing)
- nVertex = len(linearRing)-1
+ nVertex = len(linearRing) - 1
+
def clause(x):
- return x < angle if not exactAngleMatch \
+ return (
+ x < angle
+ if not exactAngleMatch
else not self.isclose(x, angle, abs_tol=angTol)
+ )
+
clauseLambda = partial(clause)
for i in range(nVertex):
if i == 0:
- vertexAngle = (linearRing[i].azimuth(linearRing[-2]) - linearRing[i].azimuth(linearRing[i+1]) + 360)
+ vertexAngle = (
+ linearRing[i].azimuth(linearRing[-2])
+ - linearRing[i].azimuth(linearRing[i + 1])
+ + 360
+ )
else:
- vertexAngle = (linearRing[i].azimuth(linearRing[i-1]) - linearRing[i].azimuth(linearRing[i+1]) + 360)
+ vertexAngle = (
+ linearRing[i].azimuth(linearRing[i - 1])
+ - linearRing[i].azimuth(linearRing[i + 1])
+ + 360
+ )
vertexAngle = math.fmod(vertexAngle, 360)
if vertexAngle > 180:
# if angle calculated is the outter one
vertexAngle = 360 - vertexAngle
- if invalidRange is not None and (vertexAngle >= minAngle and vertexAngle <= maxAngle):
- geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(linearRing[i])}
+ if invalidRange is not None and (
+ vertexAngle >= minAngle and vertexAngle <= maxAngle
+ ):
+ geomDict = {
+ "angle": vertexAngle,
+ "feat_id": feat.id(),
+ "geom": QgsGeometry.fromPointXY(linearRing[i]),
+ }
outOfBoundsList.append(geomDict)
continue
if clauseLambda(vertexAngle):
- geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(linearRing[i])}
+ geomDict = {
+ "angle": vertexAngle,
+ "feat_id": feat.id(),
+ "geom": QgsGeometry.fromPointXY(linearRing[i]),
+ }
outOfBoundsList.append(geomDict)
-
- def getOutOfBoundsAngleInLine(self, feat, part, angle, outOfBoundsList, invalidRange=None):
+
+ def getOutOfBoundsAngleInLine(
+ self, feat, part, angle, outOfBoundsList, invalidRange=None
+ ):
if invalidRange is not None:
minAngle, maxAngle = invalidRange
line = part.asPolyline()
- nVertex = len(line)-1
- for i in range(1,nVertex):
- vertexAngle = (line[i].azimuth(line[i-1]) - line[i].azimuth(line[i+1]) + 360)
+ nVertex = len(line) - 1
+ for i in range(1, nVertex):
+ vertexAngle = (
+ line[i].azimuth(line[i - 1]) - line[i].azimuth(line[i + 1]) + 360
+ )
vertexAngle = math.fmod(vertexAngle, 360)
if vertexAngle > 180:
vertexAngle = 360 - vertexAngle
- if invalidRange is not None and (vertexAngle >= minAngle and vertexAngle <= maxAngle):
- geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(line[i])}
+ if invalidRange is not None and (
+ vertexAngle >= minAngle and vertexAngle <= maxAngle
+ ):
+ geomDict = {
+ "angle": vertexAngle,
+ "feat_id": feat.id(),
+ "geom": QgsGeometry.fromPointXY(line[i]),
+ }
outOfBoundsList.append(geomDict)
continue
if vertexAngle < angle:
- geomDict = {'angle':vertexAngle, 'feat_id':feat.id(), 'geom':QgsGeometry.fromPointXY(line[i])}
+ geomDict = {
+ "angle": vertexAngle,
+ "feat_id": feat.id(),
+ "geom": QgsGeometry.fromPointXY(line[i]),
+ }
outOfBoundsList.append(geomDict)
-
+
def getInvalidBuildingAngle(self, feat, angTol):
return self.getOutOfBoundsAngle(feat, 90, exactAngleMatch=True, angTol=angTol)
-
- def getOutOfBoundsAngle(self, feat, angle, exactAngleMatch=False, angTol=0.1, invalidRange=None):
+
+ def getOutOfBoundsAngle(
+ self, feat, angle, exactAngleMatch=False, angTol=0.1, invalidRange=None
+ ):
outOfBoundsList = []
geom = feat.geometry()
for part in geom.asGeometryCollection():
@@ -277,20 +344,17 @@ def getOutOfBoundsAngle(self, feat, angle, exactAngleMatch=False, angTol=0.1, in
outOfBoundsList,
exactAngleMatch=exactAngleMatch,
angTol=angTol,
- invalidRange=invalidRange
+ invalidRange=invalidRange,
)
if part.type() == QgsWkbTypes.LineGeometry:
- self.getOutOfBoundsAngleInLine(feat,
- part,
- angle,
- outOfBoundsList,
- invalidRange=invalidRange
- )
+ self.getOutOfBoundsAngleInLine(
+ feat, part, angle, outOfBoundsList, invalidRange=invalidRange
+ )
return outOfBoundsList
def getAngleBetweenSegments(self, part):
line = part.asPolyline()
- vertexAngle = (line[1].azimuth(line[0]) - line[1].azimuth(line[2]) + 360)
+ vertexAngle = line[1].azimuth(line[0]) - line[1].azimuth(line[2]) + 360
vertexAngle = math.fmod(vertexAngle, 360)
if vertexAngle > 180:
vertexAngle = 360 - vertexAngle
@@ -310,10 +374,16 @@ def getSegmentDict(self, lineLyr):
segmentDict = dict()
geomList = []
if lineLyr.featureCount() > 0:
- toLineAlias = lambda geom : geom.asMultiPolyline()[0] if next(lineLyr.getFeatures()).geometry().isMultipart() \
- else geom.asPolyline()
- fromLineAlias = lambda x : QgsGeometry.fromMultiPolylineXY([x]) if next(lineLyr.getFeatures()).geometry().isMultipart() \
- else QgsGeometry.fromPolyline(x[0], x[1])
+ toLineAlias = (
+ lambda geom: geom.asMultiPolyline()[0]
+ if next(lineLyr.getFeatures()).geometry().isMultipart()
+ else geom.asPolyline()
+ )
+ fromLineAlias = (
+ lambda x: QgsGeometry.fromMultiPolylineXY([x])
+ if next(lineLyr.getFeatures()).geometry().isMultipart()
+ else QgsGeometry.fromPolyline(x[0], x[1])
+ )
for feat in lineLyr.getFeatures():
geom = feat.geometry()
if geom not in geomList:
@@ -321,18 +391,24 @@ def getSegmentDict(self, lineLyr):
lineList = toLineAlias(geom)
if lineList[0] not in segmentDict:
segmentDict[lineList[0]] = []
- segmentDict[lineList[0]].append(fromLineAlias([lineList[0], lineList[1]]))
+ segmentDict[lineList[0]].append(
+ fromLineAlias([lineList[0], lineList[1]])
+ )
if lineList[-1] not in segmentDict:
segmentDict[lineList[-1]] = []
- segmentDict[lineList[-1]].append(fromLineAlias([lineList[-1], lineList[-2]]))
+ segmentDict[lineList[-1]].append(
+ fromLineAlias([lineList[-1], lineList[-2]])
+ )
return segmentDict
-
- def handleGeometry(self, geom, parameterDict = {}, coordinateTransformer = None):
+
+ def handleGeometry(self, geom, parameterDict={}, coordinateTransformer=None):
outputList = []
for geom in self.adjustGeometry(geom, parameterDict):
- outputList += [self.reprojectWithCoordinateTransformer(geom, coordinateTransformer)]
+ outputList += [
+ self.reprojectWithCoordinateTransformer(geom, coordinateTransformer)
+ ]
return outputList
-
+
def getOuterShellAndHoles(self, geom, isMulti):
outershells, donutholes = [], []
for part in geom.asGeometryCollection():
@@ -345,11 +421,11 @@ def getOuterShellAndHoles(self, geom, isMulti):
else:
donutholes.append(newGeom)
return outershells, donutholes
-
+
def getStartAndEndPointOnLine(self, geom):
lineList = geom.asMultiPolyline() if geom.isMultipart() else [geom.asPolyline()]
return lineList[0], lineList[len(lineList) - 1]
-
+
def deaggregateGeometry(self, multiGeom):
"""
Deaggregates a multi-part geometry into a its parts and returns all found parts. If no part is found,
@@ -364,7 +440,7 @@ def deaggregateGeometry(self, multiGeom):
parts = multiGeom.asGeometryCollection()
for part in parts:
if part:
- # asGeometryCollection() reads every part as single-part type geometry
+ # asGeometryCollection() reads every part as single-part type geometry
part.convertToMultiType()
geomList.append(part)
return geomList
@@ -381,28 +457,28 @@ def getFeatureNodes(self, layer, feature, geomType=None):
if not geomType:
geomType = layer.geometryType()
# getting whether geometry is multipart or not
- isMulti = QgsWkbTypes.isMultiType(int(layer.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(layer.wkbType())
geom = feature.geometry()
return self.getGeomNodes(geom, geomType, isMulti)
-
+
def getGeomNodes(self, geom, geomType, isMulti):
if geomType == 0:
if isMulti:
- nodes = geom.asMultiPoint()
+ nodes = geom.asMultiPoint()
else:
- nodes = geom.asPoint()
+ nodes = geom.asPoint()
elif geomType == 1:
if isMulti:
nodes = geom.asMultiPolyline()
else:
- nodes = geom.asPolyline()
+ nodes = geom.asPolyline()
elif geomType == 2:
if isMulti:
- nodes = geom.asMultiPolygon()
+ nodes = geom.asMultiPolygon()
else:
nodes = geom.asPolygon()
return nodes
-
+
def getFirstNode(self, lyr, feat, geomType=None):
"""
Returns the starting node of a line.
@@ -412,7 +488,7 @@ def getFirstNode(self, lyr, feat, geomType=None):
:return: starting node point (QgsPoint).
"""
n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -429,7 +505,7 @@ def getSecondNode(self, lyr, feat, geomType=None):
:return: starting node point (QgsPoint).
"""
n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
# process doesn't treat multipart features that does have more than 1 part
@@ -447,7 +523,7 @@ def getPenultNode(self, lyr, feat, geomType=None):
:return: ending node point (QgsPoint).
"""
n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -464,7 +540,7 @@ def getLastNode(self, lyr, feat, geomType=None):
:return: ending node point (QgsPoint).
"""
n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -481,7 +557,7 @@ def getFirstAndLastNode(self, lyr, feat, geomType=None):
:return: starting node point (QgsPoint).
"""
n = self.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -491,15 +567,17 @@ def getFirstAndLastNode(self, lyr, feat, geomType=None):
def calculateAngleDifferences(self, startNode, endNode):
"""
- Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over
+ Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over
starting node.
:param startNode: node (QgsPoint) reference for line and angle calculation.
:param endNode: ending node (QgsPoint) for (segment of) line of which angle is required.
:return: (float) angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over 'startNode'
"""
# the returned angle is measured regarding 'y-axis', with + counter clockwise and -, clockwise.
- # Then angle is ALWAYS 180 - ang
- return 180 - math.degrees(math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y()))
+ # Then angle is ALWAYS 180 - ang
+ return 180 - math.degrees(
+ math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y())
+ )
def calculateAzimuthFromNode(self, node, networkLayer, geomType=None):
"""
@@ -513,17 +591,19 @@ def calculateAzimuthFromNode(self, node, networkLayer, geomType=None):
geomType = networkLayer.geometryType()
nodePointDict = self.nodeDict[node]
azimuthDict = dict()
- for line in nodePointDict['start']:
+ for line in nodePointDict["start"]:
# if line starts at node, then angle calculate is already azimuth
endNode = self.getSecondNode(lyr=networkLayer, feat=line, geomType=geomType)
azimuthDict[line] = node.azimuth(endNode)
- for line in nodePointDict['end']:
+ for line in nodePointDict["end"]:
# if line ends at node, angle must be adapted in order to get azimuth
endNode = self.getPenultNode(lyr=networkLayer, feat=line, geomType=geomType)
azimuthDict[line] = node.azimuth(endNode)
return azimuthDict
- def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=None):
+ def checkLineDirectionConcordance(
+ self, line_a, line_b, networkLayer, geomType=None
+ ):
"""
Given two lines, this method checks whether lines flow to/from the same node or not.
If they do not have a common node, method returns false.
@@ -540,9 +620,11 @@ def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=N
fn_b = self.getFirstNode(lyr=networkLayer, feat=line_b, geomType=geomType)
ln_b = self.getLastNode(lyr=networkLayer, feat=line_b, geomType=geomType)
# if lines are flowing to/from the same node (they are flowing the same way)
- return (fn_a == fn_b or ln_a == ln_b)
+ return fn_a == fn_b or ln_a == ln_b
- def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomType=None):
+ def validateDeltaLinesAngV2(
+ self, node, networkLayer, connectedValidLines, geomType=None
+ ):
"""
Validates a set of lines connected to a node as for the angle formed between them.
:param node: (QgsPoint) hidrography node to be validated.
@@ -555,7 +637,9 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT
val, inval, reason = dict(), dict(), ""
if not geomType:
geomType = networkLayer.geometryType()
- azimuthDict = self.calculateAzimuthFromNode(node=node, networkLayer=networkLayer, geomType=None)
+ azimuthDict = self.calculateAzimuthFromNode(
+ node=node, networkLayer=networkLayer, geomType=None
+ )
lines = azimuthDict.keys()
for idx1, key1 in enumerate(lines):
if idx1 == len(lines):
@@ -565,14 +649,23 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT
if idx1 >= idx2:
# in order to calculate only f1 - f2, f1 - f3, f2 - f3 (for 3 features, for instance)
continue
- absAzimuthDifference = math.fmod((azimuthDict[key1] - azimuthDict[key2] + 360), 360)
+ absAzimuthDifference = math.fmod(
+ (azimuthDict[key1] - azimuthDict[key2] + 360), 360
+ )
if absAzimuthDifference > 180:
# the lesser angle should always be the one to be analyzed
- absAzimuthDifference = (360 - absAzimuthDifference)
+ absAzimuthDifference = 360 - absAzimuthDifference
if absAzimuthDifference < 90:
# if it's a 'beak', lines cannot have opposing directions (e.g. cannot flow to/from the same node)
- if not self.checkLineDirectionConcordance(line_a=key1, line_b=key2, networkLayer=networkLayer, geomType=geomType):
- reason = self.tr('Lines id={0} and id={1} have conflicting directions ({2:.2f} deg).').format(key1.id(), key2.id(), absAzimuthDifference)
+ if not self.checkLineDirectionConcordance(
+ line_a=key1,
+ line_b=key2,
+ networkLayer=networkLayer,
+ geomType=geomType,
+ ):
+ reason = self.tr(
+ "Lines id={0} and id={1} have conflicting directions ({2:.2f} deg)."
+ ).format(key1.id(), key2.id(), absAzimuthDifference)
# checks if any of connected lines are already validated by any previous iteration
if key1 not in connectedValidLines:
inval[key1.id()] = key1
@@ -584,24 +677,26 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT
continue
else:
# if lines touch each other at a right angle, then it is impossible to infer waterway direction
- reason = self.tr('Cannot infer directions for lines {0} and {1} (Right Angle)').format(key1.id(), key2.id())
+ reason = self.tr(
+ "Cannot infer directions for lines {0} and {1} (Right Angle)"
+ ).format(key1.id(), key2.id())
if key1 not in connectedValidLines:
- inval[key1.id()] = key1
+ inval[key1.id()] = key1
if key2 not in connectedValidLines:
inval[key2.id()] = key2
return val, inval, reason
if not inval:
- val = {k.id() : k for k in lines}
+ val = {k.id(): k for k in lines}
return val, inval, reason
-
- def identifyAllNodes(self, networkLayer, onlySelected = False):
+
+ def identifyAllNodes(self, networkLayer, onlySelected=False):
"""
Identifies all nodes from a given layer (or selected features of it). The result is returned as a dict of dict.
:param networkLayer: target layer to which nodes identification is required.
:return: { node_id : { start : [feature_which_starts_with_node], end : feature_which_ends_with_node } }.
"""
nodeDict = dict()
- isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType())
if onlySelected:
features = [feat for feat in networkLayer.getSelectedFeatures()]
else:
@@ -612,60 +707,60 @@ def identifyAllNodes(self, networkLayer, onlySelected = False):
if isMulti:
if len(nodes) > 1:
# if feat is multipart and has more than one part, a flag should be raised
- continue # CHANGE TO RAISE FLAG
+ continue # CHANGE TO RAISE FLAG
elif len(nodes) == 0:
# if no part is found, skip feature
continue
else:
# if feat is multipart, "nodes" is a list of list
- nodes = nodes[0]
+ nodes = nodes[0]
# initial node
pInit, pEnd = nodes[0], nodes[-1]
# filling starting node information into dictionary
if pInit not in nodeDict:
# if the point is not already started into dictionary, it creates a new item
- nodeDict[pInit] = { 'start' : [], 'end' : [] }
- if feat not in nodeDict[pInit]['start']:
- nodeDict[pInit]['start'].append(feat)
+ nodeDict[pInit] = {"start": [], "end": []}
+ if feat not in nodeDict[pInit]["start"]:
+ nodeDict[pInit]["start"].append(feat)
# filling ending node information into dictionary
if pEnd not in nodeDict:
- nodeDict[pEnd] = { 'start' : [], 'end' : [] }
- if feat not in nodeDict[pEnd]['end']:
- nodeDict[pEnd]['end'].append(feat)
+ nodeDict[pEnd] = {"start": [], "end": []}
+ if feat not in nodeDict[pEnd]["end"]:
+ nodeDict[pEnd]["end"].append(feat)
return nodeDict
-
+
def makeQgsPolygonFromBounds(self, xmin, ymin, xmax, ymax, isMulti=True):
"""
Creating a polygon for the given coordinates
"""
- dx = (xmax - xmin)/3
- dy = (ymax - ymin)/3
-
+ dx = (xmax - xmin) / 3
+ dy = (ymax - ymin) / 3
+
polyline = []
point = QgsPointXY(xmin, ymin)
polyline.append(point)
- point = QgsPointXY(xmin+dx, ymin)
+ point = QgsPointXY(xmin + dx, ymin)
polyline.append(point)
- point = QgsPointXY(xmax-dx, ymin)
+ point = QgsPointXY(xmax - dx, ymin)
polyline.append(point)
point = QgsPointXY(xmax, ymin)
polyline.append(point)
- point = QgsPointXY(xmax, ymin+dy)
+ point = QgsPointXY(xmax, ymin + dy)
polyline.append(point)
- point = QgsPointXY(xmax, ymax-dy)
+ point = QgsPointXY(xmax, ymax - dy)
polyline.append(point)
point = QgsPointXY(xmax, ymax)
polyline.append(point)
- point = QgsPointXY(xmax-dx, ymax)
+ point = QgsPointXY(xmax - dx, ymax)
polyline.append(point)
- point = QgsPointXY(xmin+dx, ymax)
+ point = QgsPointXY(xmin + dx, ymax)
polyline.append(point)
point = QgsPointXY(xmin, ymax)
polyline.append(point)
- point = QgsPointXY(xmin, ymax-dy)
+ point = QgsPointXY(xmin, ymax - dy)
polyline.append(point)
- point = QgsPointXY(xmin, ymin+dy)
+ point = QgsPointXY(xmin, ymin + dy)
polyline.append(point)
point = QgsPointXY(xmin, ymin)
polyline.append(point)
@@ -675,17 +770,23 @@ def makeQgsPolygonFromBounds(self, xmin, ymin, xmax, ymax, isMulti=True):
else:
qgsPolygon = QgsGeometry.fromPolygonXY([polyline])
return qgsPolygon
-
- def handleGeometryCollection(self, geom, geometryType, parameterDict=None, coordinateTransformer=None):
+
+ def handleGeometryCollection(
+ self, geom, geometryType, parameterDict=None, coordinateTransformer=None
+ ):
parameterDict = {} if parameterDict is None else parameterDict
outputSet = set()
for part in geom.asGeometryCollection():
if part.type() == geometryType:
- handledList = self.handleGeometry(part, parameterDict=parameterDict, coordinateTransformer=coordinateTransformer)
+ handledList = self.handleGeometry(
+ part,
+ parameterDict=parameterDict,
+ coordinateTransformer=coordinateTransformer,
+ )
for item in handledList:
outputSet.add(item)
return list(outputSet)
-
+
def getFirstAndLastNodeFromGeom(self, geom):
isMulti = geom.isMultipart()
geomType = geom.type()
@@ -704,7 +805,7 @@ def multiToSinglePart(self, geom):
:return: (list-of-QgsGeometry) list of single part geometries found.
"""
return [part for part in geom.asGeometryCollection()]
-
+
@staticmethod
def calcAzimuth(p1: QgsPoint, p2: QgsPoint) -> float:
dx = p2.x() - p1.x()
@@ -716,15 +817,15 @@ def calcAzimuth(p1: QgsPoint, p2: QgsPoint) -> float:
else:
return 180.0
- theta = math.atan(dy/dx)
+ theta = math.atan(dy / dx)
if dx < 0:
theta += math.pi
-
+
azimuth = 90.0 - math.degrees(theta)
if azimuth < 0:
azimuth += 360.0
return azimuth
-
+
@staticmethod
def addVertex(vertex: QgsPoint, geom: QgsGeometry) -> QgsGeometry:
distance, p, after, orient = geom.closestSegmentWithContext(QgsPointXY(vertex))
@@ -733,7 +834,7 @@ def addVertex(vertex: QgsPoint, geom: QgsGeometry) -> QgsGeometry:
def addVertexesToGeometry(self, vertexSet: set, geom: QgsGeometry) -> QgsGeometry:
geomVertexSet = set(QgsGeometry(i) for i in geom.vertices())
- changedGeom = QgsGeometry(geom) # deep copy
+ changedGeom = QgsGeometry(geom) # deep copy
for vertex in vertexSet:
vertexPoint = QgsPoint(vertex.asPoint())
closestVertexes = geom.closestVertex(vertex.asPoint())
@@ -743,4 +844,3 @@ def addVertexesToGeometry(self, vertexSet: set, geom: QgsGeometry) -> QgsGeometr
changedGeom = self.addVertex(vertexPoint, changedGeom)
changedGeom.removeDuplicateNodes()
return changedGeom
-
diff --git a/DsgTools/core/GeometricTools/graphHandler.py b/DsgTools/core/GeometricTools/graphHandler.py
new file mode 100644
index 000000000..47612656d
--- /dev/null
+++ b/DsgTools/core/GeometricTools/graphHandler.py
@@ -0,0 +1,166 @@
+# -*- coding: utf-8 -*-
+"""
+/***************************************************************************
+ DsgTools
+ A QGIS plugin
+ Brazilian Army Cartographic Production Tools
+ -------------------
+ begin : 2023-03-29
+ git sha : $Format:%H$
+ copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army
+ email : borba.philipe@eb.mil.br
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+"""
+
+from collections import defaultdict
+from itertools import tee
+from typing import Iterable
+from itertools import chain
+from itertools import product
+from itertools import starmap
+from functools import partial
+
+from qgis.core import QgsGeometry, QgsFeature, QgsProcessingMultiStepFeedback
+
+def fetch_connected_nodes(G, node, max_degree, seen=None, feedback=None):
+ if seen == None:
+ seen = [node]
+ for neighbor in G.neighbors(node):
+ if feedback is not None and feedback.isCanceled():
+ break
+ if G.degree(neighbor) > max_degree:
+ continue
+ if neighbor not in seen:
+ seen.append(neighbor)
+ fetch_connected_nodes(G, neighbor, max_degree, seen)
+ return seen
+
+
+def pairwise(iterable: Iterable) -> Iterable:
+ "s -> (s0,s1), (s1,s2), (s2, s3), ..."
+ a, b = tee(iterable)
+ next(b, None)
+ return zip(a, b)
+
+def flipLine(edgeDict: dict, edgeId: int) -> QgsFeature:
+ edgeFeat = edgeDict[edgeId]
+ edgeGeomAsQgsLine = edgeFeat.geometry().constGet()
+ reversedGeom = QgsGeometry(edgeGeomAsQgsLine.reversed())
+ newFeat = QgsFeature(edgeFeat)
+ newFeat.setGeometry(reversedGeom)
+ return newFeat
+
+def buildGraph(nx, hashDict, nodeDict, feedback=None, directed=False):
+ G = nx.Graph() if not directed else nx.DiGraph()
+ progressStep = 100 / len(hashDict)
+ for current, (edgeId, (wkb_1, wkb_2)) in enumerate(hashDict.items()):
+ if feedback is not None and feedback.isCanceled():
+ break
+ G.add_edge(nodeDict[wkb_1], nodeDict[wkb_2])
+ G[nodeDict[wkb_1]][nodeDict[wkb_2]]["featid"] = edgeId
+ if feedback is not None:
+ feedback.setProgress(current * progressStep)
+ return G
+
+def buildAuxStructures(nx, nodesLayer, edgesLayer, feedback=None, directed=False):
+ multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback) if feedback is not None else None
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(0)
+ edgeDict = {feat["featid"]: feat for feat in edgesLayer.getFeatures()}
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(1)
+ nodeDict = defaultdict(list)
+ nodeIdDict = defaultdict(list)
+ nodeCount = nodesLayer.featureCount()
+ stepSize = 100 / nodeCount
+ auxId = 0
+ hashDict = defaultdict(lambda: [[], []])
+ for current, nodeFeat in enumerate(nodesLayer.getFeatures()):
+ if multiStepFeedback is not None and multiStepFeedback.isCanceled():
+ break
+ geom = nodeFeat.geometry()
+ geomWkb = geom.asWkb()
+ if geomWkb not in nodeDict:
+ nodeDict[geomWkb] = auxId
+ nodeIdDict[auxId] = geomWkb
+ auxId += 1
+ hashDict[nodeFeat["featid"]][nodeFeat["vertex_pos"]] = geomWkb
+ if multiStepFeedback is not None:
+ multiStepFeedback.setProgress(current * stepSize)
+
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(2)
+ networkBidirectionalGraph = buildGraph(
+ nx, hashDict, nodeDict, feedback=multiStepFeedback, directed=directed
+ )
+ return nodeDict, nodeIdDict, edgeDict, hashDict, networkBidirectionalGraph
+
+def evaluateStreamOrder(G, feedback=None):
+ G = G.copy()
+ firstOrderNodes = set(node for node in G.nodes if G.degree(node) == 1 and len(list(G.successors(node))) > 0)
+ stepSize = 100 / len(G.edges)
+ current = 0
+ G_copy = G.copy()
+ visitedNodes = set()
+ for n0, n1 in G_copy.edges:
+ G_copy[n0][n1]["stream_order"] = 0
+ while len(firstOrderNodes) > 0:
+ if feedback is not None and feedback.isCanceled():
+ return G_copy
+ for node in firstOrderNodes:
+ if node in visitedNodes:
+ continue
+ connectedNodes = fetch_connected_nodes(G, node, 2)
+ pairs = [(a,b) for i in connectedNodes for a,b in G.out_edges(i)]
+ predOrderValueList = [G_copy[n0][node]["stream_order"] for n0 in G_copy.predecessors(node)]
+ startIdx = max(predOrderValueList) + 1 if len(predOrderValueList) > 0 else 1
+ for idx, (n0, n1) in enumerate(pairs, start=startIdx):
+ current += 1
+ if feedback is not None and feedback.isCanceled():
+ return G_copy
+ G_copy[n0][n1]["stream_order"] = idx if G_copy.degree(n0) <= 2 else max(
+ [idx] + [G_copy[i][n0]["stream_order"] + 1 for i in G_copy.predecessors(n0)]
+ )
+ G.remove_edge(n0, n1)
+ succList = list(G_copy.successors(n1))
+ if len(succList) > 1:
+ for i in G_copy.successors(n1):
+ G_copy[n1][i]["stream_order"] = idx + 1
+ G.remove_edge(n1, succList[0])
+ if feedback is not None:
+ feedback.setProgress(current * stepSize)
+ for n in connectedNodes:
+ G.remove_node(n)
+ visitedNodes.add(n)
+ # visitedNodes.add(node)
+ firstOrderNodes = set(node for node in G.nodes if G.degree(node) == 1 and len(list(G.successors(node))) > 0) - visitedNodes
+ # firstOrderNodes = [node for node in G.nodes if G.degree(node) == 1 and node not in visitedNodes]
+ return G_copy
+
+
+# def evaluateStreamOrder(nx, G, feedback=None):
+# G = G.copy()
+# firstOrderNodes = set(node for node in G.nodes if G.degree(node) == 1 and len(list(G.successors(node))) > 0)
+# stepSize = 100 / len(G.edges)
+# current = 0
+# G_copy = G.copy()
+# visitedNodes = set()
+# for n0, n1 in G_copy.edges:
+# G_copy[n0][n1]["stream_order"] = 0
+# roots = (v for v, d in G.in_degree() if d == 0)
+# leaves = (v for v, d in G.out_degree() if d == 0)
+# all_paths = partial(nx.all_simple_paths, G)
+# pathDict = defaultdict(list)
+# for path in sorted(chain.from_iterable(starmap(all_paths, product(roots, leaves))), key=lambda x: len(x), reverse=True):
+# pathDict[path[0]].append(path)
+
+
+
diff --git a/DsgTools/core/GeometricTools/layerHandler.py b/DsgTools/core/GeometricTools/layerHandler.py
index 79be2d40d..99c3311f2 100644
--- a/DsgTools/core/GeometricTools/layerHandler.py
+++ b/DsgTools/core/GeometricTools/layerHandler.py
@@ -28,6 +28,7 @@
from itertools import combinations
import os
from typing import List
+from uuid import uuid4
from processing.tools import dataobjects
@@ -36,11 +37,30 @@
from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner
from DsgTools.core.Utils.FrameTools.map_index import UtmGrid
from qgis.analysis import QgsGeometrySnapper, QgsInternalGeometrySnapper
-from qgis.core import (edit, Qgis, QgsCoordinateReferenceSystem, QgsCoordinateTransform,
- QgsExpression, QgsFeature, QgsFeatureRequest, QgsField, QgsFields, QgsGeometry, QgsMessageLog,
- QgsProcessingContext, QgsProcessingMultiStepFeedback, QgsProcessingUtils, QgsProject,
- QgsSpatialIndex, QgsVectorDataProvider, QgsVectorLayer, QgsVectorLayerUtils, QgsWkbTypes,
- QgsProcessingFeatureSourceDefinition, QgsFeatureSink)
+from qgis.core import (
+ edit,
+ Qgis,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsExpression,
+ QgsFeature,
+ QgsFeatureRequest,
+ QgsField,
+ QgsFields,
+ QgsGeometry,
+ QgsMessageLog,
+ QgsProcessingContext,
+ QgsProcessingMultiStepFeedback,
+ QgsProcessingUtils,
+ QgsProject,
+ QgsSpatialIndex,
+ QgsVectorDataProvider,
+ QgsVectorLayer,
+ QgsVectorLayerUtils,
+ QgsWkbTypes,
+ QgsProcessingFeatureSourceDefinition,
+ QgsFeatureSink,
+)
from qgis.PyQt.Qt import QObject, QVariant
from .featureHandler import FeatureHandler
@@ -58,7 +78,9 @@ def __init__(self, iface=None, parent=None):
self.geometryHandler = GeometryHandler(iface)
self.algRunner = AlgRunner()
- def getFeatureList(self, lyr, onlySelected=False, returnIterator=True, returnSize=True):
+ def getFeatureList(
+ self, lyr, onlySelected=False, returnIterator=True, returnSize=True
+ ):
"""
Gets the features from lyr acording to parameters.
:param (QgsVectorLayer) lyr: layer;
@@ -67,12 +89,16 @@ def getFeatureList(self, lyr, onlySelected=False, returnIterator=True, returnSiz
:param (bool) returnSize: if true, return the featureList and size.
"""
if onlySelected:
- featureList = lyr.getSelectedFeatures() if returnIterator else [
- i for i in lyr.getSelectedFeatures()]
+ featureList = (
+ lyr.getSelectedFeatures()
+ if returnIterator
+ else [i for i in lyr.getSelectedFeatures()]
+ )
size = lyr.selectedFeatureCount()
else:
- featureList = lyr.getFeatures() if returnIterator else [
- i for i in lyr.getFeatures()]
+ featureList = (
+ lyr.getFeatures() if returnIterator else [i for i in lyr.getFeatures()]
+ )
size = lyr.featureCount()
if returnSize:
return featureList, size
@@ -91,7 +117,8 @@ def getSelectedFeaturesFromCanvasLayers(self):
if not isinstance(lyr, QgsVectorLayer):
continue
featureList = self.getFeatureList(
- lyr, onlySelected=True, returnIterator=False)
+ lyr, onlySelected=True, returnIterator=False
+ )
if featureList:
selectedDict[lyr] = featureList
return selectedDict
@@ -104,14 +131,21 @@ def reclassifySelectedFeatures(self, destinationLayer, reclassificationDict):
parameterDict = self.getDestinationParameters(destinationLayer)
reclassifyCount = 0
destinationLayer.startEditing()
- destinationLayer.beginEditCommand(self.tr('DsgTools reclassification'))
- for lyr, featureList in [(k, v) for k, v in selectedDict.items() if len(v[0]) > 0]:
- featureList = featureList[0] if isinstance(
- featureList, tuple) else featureList
- coordinateTransformer = self.getCoordinateTransformer(
- lyr, destinationLayer)
+ destinationLayer.beginEditCommand(self.tr("DsgTools reclassification"))
+ for lyr, featureList in [
+ (k, v) for k, v in selectedDict.items() if len(v[0]) > 0
+ ]:
+ featureList = (
+ featureList[0] if isinstance(featureList, tuple) else featureList
+ )
+ coordinateTransformer = self.getCoordinateTransformer(lyr, destinationLayer)
newFeatList, deleteList = self.featureHandler.reclassifyFeatures(
- featureList, lyr, reclassificationDict, coordinateTransformer, parameterDict)
+ featureList,
+ lyr,
+ reclassificationDict,
+ coordinateTransformer,
+ parameterDict,
+ )
featuresAdded = destinationLayer.addFeatures(newFeatList)
if featuresAdded:
lyr.startEditing()
@@ -126,14 +160,11 @@ def getDestinationParameters(self, destinationLayer):
if it is a multi-geometry (isMulti)
"""
parameterDict = dict()
- parameterDict['geomType'] = destinationLayer.geometryType()
+ parameterDict["geomType"] = destinationLayer.geometryType()
# generic check (not every database is implemented as ours)
- parameterDict['hasMValues'] = QgsWkbTypes.hasM(
- int(destinationLayer.wkbType()))
- parameterDict['hasZValues'] = QgsWkbTypes.hasZ(
- int(destinationLayer.wkbType())) #
- parameterDict['isMulti'] = QgsWkbTypes.isMultiType(
- int(destinationLayer.wkbType()))
+ parameterDict["hasMValues"] = QgsWkbTypes.hasM(destinationLayer.wkbType())
+ parameterDict["hasZValues"] = QgsWkbTypes.hasZ(destinationLayer.wkbType()) #
+ parameterDict["isMulti"] = QgsWkbTypes.isMultiType(destinationLayer.wkbType())
return parameterDict
def getCoordinateTransformer(self, inputLyr, outputLyr):
@@ -148,33 +179,46 @@ def getCoordinateTransformer(self, inputLyr, outputLyr):
inputSrc = QgsCoordinateReferenceSystem(inputAuthId)
outputSrc = QgsCoordinateReferenceSystem(outputAuthId)
coordinateTransformer = QgsCoordinateTransform(
- inputSrc, outputSrc, QgsProject.instance())
+ inputSrc, outputSrc, QgsProject.instance()
+ )
return coordinateTransformer
- def createAndPopulateUnifiedVectorLayer(self, layerList, geomType=None, epsg=None, attributeTupple=False, attributeBlackList='', onlySelected=False, feedback=None):
+ def createAndPopulateUnifiedVectorLayer(
+ self,
+ layerList,
+ geomType=None,
+ epsg=None,
+ attributeTupple=False,
+ attributeBlackList="",
+ onlySelected=False,
+ feedback=None,
+ ):
if not epsg:
- epsg = layerList[0].crs().authid().split(':')[-1]
+ epsg = layerList[0].crs().authid().split(":")[-1]
if not geomType:
geomType = None
for layer in layerList:
if layer.featureCount() > 0:
- geomType = int(next(layer.getFeatures())\
- .geometry().wkbType())
+ geomType = next(layer.getFeatures()).geometry().wkbType()
break
else:
raise ValueError(
- self.tr("No layers were provided or they are all empty."))
- unified_layer = self.createUnifiedVectorLayer(geomType, epsg,
- attributeTupple=attributeTupple)
+ self.tr("No layers were provided or they are all empty.")
+ )
+ unified_layer = self.createUnifiedVectorLayer(
+ geomType, epsg, attributeTupple=attributeTupple
+ )
parameterDict = self.getDestinationParameters(unified_layer)
- featList = self.getUnifiedLayerFeatures(unified_layer, layerList,
- attributeTupple=attributeTupple,
- attributeBlackList=attributeBlackList,
- onlySelected=onlySelected,
- parameterDict=parameterDict,
- feedback=feedback)
- self.addFeaturesToLayer(unified_layer, featList,
- msg='Populating unified layer')
+ featList = self.getUnifiedLayerFeatures(
+ unified_layer,
+ layerList,
+ attributeTupple=attributeTupple,
+ attributeBlackList=attributeBlackList,
+ onlySelected=onlySelected,
+ parameterDict=parameterDict,
+ feedback=feedback,
+ )
+ self.addFeaturesToLayer(unified_layer, featList, msg="Populating unified layer")
return unified_layer
def createUnifiedVectorLayer(self, geomType, srid, attributeTupple=False):
@@ -182,8 +226,7 @@ def createUnifiedVectorLayer(self, geomType, srid, attributeTupple=False):
Creates a unified vector layer for validation purposes.
"""
fields = self.getUnifiedVectorFields(attributeTupple=attributeTupple)
- lyrUri = "{0}?crs=epsg:{1}".format(
- QgsWkbTypes.displayString(int(geomType)), srid)
+ lyrUri = "{0}?crs=epsg:{1}".format(QgsWkbTypes.displayString(geomType), srid)
lyr = QgsVectorLayer(lyrUri, "unified_layer", "memory")
lyr.startEditing()
fields = self.getUnifiedVectorFields(attributeTupple=attributeTupple)
@@ -193,25 +236,38 @@ def createUnifiedVectorLayer(self, geomType, srid, attributeTupple=False):
def getUnifiedVectorFields(self, attributeTupple=False):
if not attributeTupple:
- fields = [QgsField('featid', QVariant.Int),
- QgsField('layer', QVariant.String)
- ]
+ fields = [
+ QgsField("featid", QVariant.Int),
+ QgsField("layer", QVariant.String),
+ ]
else:
- fields = [QgsField('featid', QVariant.Int),
- QgsField('layer', QVariant.String),
- QgsField('tupple', QVariant.String),
- QgsField('blacklist', QVariant.String)
- ]
+ fields = [
+ QgsField("featid", QVariant.Int),
+ QgsField("layer", QVariant.String),
+ QgsField("tupple", QVariant.String),
+ QgsField("blacklist", QVariant.String),
+ ]
return fields
- def getUnifiedLayerFeatures(self, unifiedLyr, layerList, attributeTupple=False, attributeBlackList=None, onlySelected=False, parameterDict=None, feedback=None):
+ def getUnifiedLayerFeatures(
+ self,
+ unifiedLyr,
+ layerList,
+ attributeTupple=False,
+ attributeBlackList=None,
+ onlySelected=False,
+ parameterDict=None,
+ feedback=None,
+ ):
parameterDict = {} if parameterDict is None else parameterDict
featList = []
- blackList = attributeBlackList.split(
- ',') if attributeBlackList is not None and ',' in attributeBlackList else []
+ blackList = (
+ attributeBlackList.split(",")
+ if attributeBlackList is not None and "," in attributeBlackList
+ else []
+ )
if feedback:
- multiStepFeedback = QgsProcessingMultiStepFeedback(
- len(layerList), feedback)
+ multiStepFeedback = QgsProcessingMultiStepFeedback(len(layerList), feedback)
for i, layer in enumerate(layerList):
if feedback:
if feedback.isCanceled():
@@ -219,26 +275,30 @@ def getUnifiedLayerFeatures(self, unifiedLyr, layerList, attributeTupple=False,
multiStepFeedback.setCurrentStep(i)
# recording class name
layername = layer.name()
- coordinateTransformer = self.getCoordinateTransformer(
- unifiedLyr, layer)
+ coordinateTransformer = self.getCoordinateTransformer(unifiedLyr, layer)
iterator, size = self.getFeatureList(
- layer, onlySelected=onlySelected, returnSize=True)
+ layer, onlySelected=onlySelected, returnSize=True
+ )
for current, feature in enumerate(iterator):
if feedback:
if multiStepFeedback.isCanceled():
break
- newFeats = self.featureHandler.createUnifiedFeature(unifiedLyr, feature, layername,
- bList=blackList,
- attributeTupple=attributeTupple,
- parameterDict=parameterDict,
- coordinateTransformer=coordinateTransformer)
+ newFeats = self.featureHandler.createUnifiedFeature(
+ unifiedLyr,
+ feature,
+ layername,
+ bList=blackList,
+ attributeTupple=attributeTupple,
+ parameterDict=parameterDict,
+ coordinateTransformer=coordinateTransformer,
+ )
featList += newFeats
if feedback:
- multiStepFeedback.setProgress(current*size)
+ multiStepFeedback.setProgress(current * size)
return featList
def addFeaturesToLayer(self, lyr, featList, commitChanges=True, msg=None):
- msg = '' if msg is None else msg
+ msg = "" if msg is None else msg
lyr.startEditing()
lyr.beginEditCommand(msg)
res = lyr.addFeatures(featList)
@@ -263,97 +323,144 @@ def buildInputDict(self, inputLyr, pk=None, feedback=None, onlySelected=False):
if onlySelected:
iterator = inputLyr.getSelectedFeatures()
if feedback is not None:
- localTotal = 100/inputLyr.selectedFeatureCount() if inputLyr.selectedFeatureCount() else 0
+ localTotal = (
+ 100 / inputLyr.selectedFeatureCount()
+ if inputLyr.selectedFeatureCount()
+ else 0
+ )
else:
request = QgsFeatureRequest()
iterator = inputLyr.getFeatures(request)
if feedback is not None:
- localTotal = 100/inputLyr.featureCount() if inputLyr.featureCount() else 0
+ localTotal = (
+ 100 / inputLyr.featureCount() if inputLyr.featureCount() else 0
+ )
for current, feature in enumerate(iterator):
if feedback and feedback.isCanceled():
break
key = feature[pk] if pk else feature.id()
inputDict[key] = {
- 'featList': [],
- 'originalFeat': feature,
+ "featList": [],
+ "originalFeat": feature,
}
if feedback is not None:
- feedback.setProgress(localTotal*current)
+ feedback.setProgress(localTotal * current)
return inputDict
- def populateInputDictFeatList(self, lyr, inputDict, pk=None, request=None, feedback=None):
+ def populateInputDictFeatList(
+ self, lyr, inputDict, pk=None, request=None, feedback=None
+ ):
iterator = lyr.getFeatures(request) if request else lyr.getFeatures()
- localTotal = 100/lyr.featureCount() if lyr.featureCount() else 0
+ localTotal = 100 / lyr.featureCount() if lyr.featureCount() else 0
for current, feat in enumerate(iterator):
if feedback:
if feedback.isCanceled():
break
fid = feat[pk] if pk else feat.id()
if fid in inputDict:
- inputDict[fid]['featList'].append(feat)
+ inputDict[fid]["featList"].append(feat)
if feedback:
- feedback.setProgress(localTotal*current)
-
- def updateOriginalLayer(self, originalLayer, resultLayer, field=None, feedback=None, keepFeatures=False, onlySelected=True):
- multiStepFeedback = QgsProcessingMultiStepFeedback(
- 3, feedback) if feedback else None
+ feedback.setProgress(localTotal * current)
+
+ def updateOriginalLayer(
+ self,
+ originalLayer,
+ resultLayer,
+ field=None,
+ feedback=None,
+ keepFeatures=False,
+ onlySelected=True,
+ ):
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(3, feedback) if feedback else None
+ )
# 1- build inputDict structure to store the original state of the layer
if feedback:
multiStepFeedback.setCurrentStep(0)
inputDict = self.buildInputDict(
- originalLayer, pk=field, feedback=multiStepFeedback, onlySelected=onlySelected)
+ originalLayer,
+ pk=field,
+ feedback=multiStepFeedback,
+ onlySelected=onlySelected,
+ )
# 2- populate the inputDict with the features from the resultLayer
if feedback:
multiStepFeedback.setCurrentStep(1)
self.populateInputDictFeatList(
- resultLayer, inputDict, pk=field, feedback=multiStepFeedback)
+ resultLayer, inputDict, pk=field, feedback=multiStepFeedback
+ )
# 3- get information from originalLayer and resultLayer
if feedback:
multiStepFeedback.setCurrentStep(2)
parameterDict = self.getDestinationParameters(originalLayer)
coordinateTransformer = self.getCoordinateTransformer(
- resultLayer, originalLayer)
+ resultLayer, originalLayer
+ )
# 4- run update original layer
- self.updateOriginalLayerFeatures(originalLayer, inputDict, parameterDict=parameterDict,
- coordinateTransformer=coordinateTransformer, keepFeatures=keepFeatures, feedback=multiStepFeedback)
+ self.updateOriginalLayerFeatures(
+ originalLayer,
+ inputDict,
+ parameterDict=parameterDict,
+ coordinateTransformer=coordinateTransformer,
+ keepFeatures=keepFeatures,
+ feedback=multiStepFeedback,
+ )
- def updateOriginalLayersFromUnifiedLayer(self, lyrList, unifiedLyr, feedback=None, onlySelected=False):
+ def updateOriginalLayersFromUnifiedLayer(
+ self, lyrList, unifiedLyr, feedback=None, onlySelected=False
+ ):
"""
Updates original layers from the unified layers
"""
lenList = len(lyrList)
parameterDict = self.getDestinationParameters(unifiedLyr)
- multiStepFeedback = QgsProcessingMultiStepFeedback(
- 3*lenList, feedback) if feedback else None
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(3 * lenList, feedback) if feedback else None
+ )
for i, lyr in enumerate(lyrList):
if feedback is not None and multiStepFeedback.isCanceled():
break
- multiStepFeedback.setCurrentStep(3*i)
+ multiStepFeedback.setCurrentStep(3 * i)
multiStepFeedback.pushInfo(self.tr(f"Building {lyr.name()} input dict"))
inputDict = self.buildInputDict(
- lyr, onlySelected=onlySelected, feedback=multiStepFeedback)
+ lyr, onlySelected=onlySelected, feedback=multiStepFeedback
+ )
if multiStepFeedback is not None and multiStepFeedback.isCanceled():
break
- request = QgsFeatureRequest(QgsExpression(
- "layer = '{0}'".format(lyr.name())))
- multiStepFeedback.setCurrentStep(3*i+1)
+ request = QgsFeatureRequest(
+ QgsExpression("layer = '{0}'".format(lyr.name()))
+ )
+ multiStepFeedback.setCurrentStep(3 * i + 1)
multiStepFeedback.pushInfo(self.tr(f"Populating {lyr.name()} input dict"))
self.populateInputDictFeatList(
- unifiedLyr, inputDict, pk='featid', request=request, feedback=multiStepFeedback)
+ unifiedLyr,
+ inputDict,
+ pk="featid",
+ request=request,
+ feedback=multiStepFeedback,
+ )
if multiStepFeedback is not None and multiStepFeedback.isCanceled():
break
- coordinateTransformer = self.getCoordinateTransformer(
- unifiedLyr, lyr)
- multiStepFeedback.setCurrentStep(3*i+2)
+ coordinateTransformer = self.getCoordinateTransformer(unifiedLyr, lyr)
+ multiStepFeedback.setCurrentStep(3 * i + 2)
multiStepFeedback.pushInfo(self.tr(f"Updating {lyr.name()} features"))
- self.updateOriginalLayerFeatures(lyr, inputDict, parameterDict=parameterDict,
- coordinateTransformer=coordinateTransformer, feedback=multiStepFeedback)
+ self.updateOriginalLayerFeatures(
+ lyr,
+ inputDict,
+ parameterDict=parameterDict,
+ coordinateTransformer=coordinateTransformer,
+ feedback=multiStepFeedback,
+ )
- def updateOriginalLayerFeatures(self, lyr, inputDict,
- parameterDict=None,
- coordinateTransformer=None,
- keepFeatures=False,
- feedback=None):
+ def updateOriginalLayerFeatures(
+ self,
+ lyr,
+ inputDict,
+ parameterDict=None,
+ coordinateTransformer=None,
+ keepFeatures=False,
+ feedback=None,
+ ):
"""
Updates the layer list using the given inputDict
:param lyr: (QgsVectorLayer) layer container of features from featList.
@@ -368,27 +475,33 @@ def updateOriginalLayerFeatures(self, lyr, inputDict,
parameterDict = {} if parameterDict is None else parameterDict
idsToRemove, featuresToAdd = set(), set()
lyr.startEditing()
- lyr.beginEditCommand('Updating layer {0}'.format(lyr.name()))
- localTotal = 100/len(inputDict) if inputDict else 0
+ lyr.beginEditCommand("Updating layer {0}".format(lyr.name()))
+ nSteps = len(inputDict)
+ if nSteps == 0 or feedback.isCanceled():
+ return
+ localTotal = 100 / len(inputDict) if inputDict else 0
futures = set()
- pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1)
+ pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1)
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
+
def evaluate(id_, featDict):
idsToRemove, featuresToAdd, geometriesToChange = set(), set(), set()
if multiStepFeedback.isCanceled():
return idsToRemove, featuresToAdd, geometriesToChange
- outFeats = featDict['featList']
+ outFeats = featDict["featList"]
if len(outFeats) == 0:
idsToRemove.add(id_)
return idsToRemove, featuresToAdd, geometriesToChange
geomToUpdate, addedFeatures, deleteId = self.featureHandler.handleFeature(
outFeats,
- featDict['originalFeat'],
+ featDict["originalFeat"],
lyr,
parameterDict=parameterDict,
- coordinateTransformer=coordinateTransformer
+ coordinateTransformer=coordinateTransformer,
)
- if geomToUpdate is not None and not geomToUpdate.equals(inputDict[id_]['originalFeat'].geometry()):
+ if geomToUpdate is not None and not geomToUpdate.equals(
+ inputDict[id_]["originalFeat"].geometry()
+ ):
geometriesToChange.add((id_, geomToUpdate))
if deleteId:
idsToRemove.add(id_)
@@ -402,10 +515,12 @@ def evaluate(id_, featDict):
return
futures.add(pool.submit(evaluate, id_, featDict))
if feedback is not None:
- feedback.setProgress(localTotal*current)
+ feedback.setProgress(localTotal * current)
multiStepFeedback.setCurrentStep(1)
multiStepFeedback.pushInfo(self.tr("Evaluating results..."))
- changeGeometryLambda = lambda x: lyr.changeGeometry(x[0], x[1], skipDefaultValue=True)
+ changeGeometryLambda = lambda x: lyr.changeGeometry(
+ x[0], x[1], skipDefaultValue=True
+ )
for current, future in enumerate(concurrent.futures.as_completed(futures)):
if feedback is not None and feedback.isCanceled():
return
@@ -413,39 +528,58 @@ def evaluate(id_, featDict):
list(map(changeGeometryLambda, geometriesToChange))
featuresToAdd = featuresToAdd.union(addedFeatures)
idsToRemove = idsToRemove.union(deletedIds)
+ if current % 1000 == 0:
+ multiStepFeedback.pushInfo(
+ self.tr(f"Evaluated {current}/{nSteps} results.")
+ )
if feedback is not None:
- feedback.setProgress(localTotal*current)
+ feedback.setProgress(localTotal * current)
lyr.addFeatures(list(featuresToAdd))
if not keepFeatures:
lyr.deleteFeatures(list(idsToRemove))
lyr.endEditCommand()
- def mergeLinesOnLayer(self, lyr, onlySelected=False, feedback=None, ignoreVirtualFields=True, attributeBlackList=None, excludePrimaryKeys=True):
+ def mergeLinesOnLayer(
+ self,
+ lyr,
+ onlySelected=False,
+ feedback=None,
+ ignoreVirtualFields=True,
+ attributeBlackList=None,
+ excludePrimaryKeys=True,
+ ):
attributeBlackList = [] if attributeBlackList is None else attributeBlackList
if feedback:
localFeedback = QgsProcessingMultiStepFeedback(3, feedback)
localFeedback.setCurrentStep(0)
# build attribute dict
attributeFeatDict = self.buildAttributeFeatureDict(
- lyr, onlySelected=onlySelected, feedback=localFeedback, attributeBlackList=attributeBlackList)
+ lyr,
+ onlySelected=onlySelected,
+ feedback=localFeedback,
+ attributeBlackList=attributeBlackList,
+ )
# build network dict
if feedback:
localFeedback.setCurrentStep(1)
networkDict = self.buildInitialAndEndPointDict(
- lyr, onlySelected=onlySelected, feedback=localFeedback)
+ lyr, onlySelected=onlySelected, feedback=localFeedback
+ )
parameterDict = self.getDestinationParameters(lyr)
idsToRemove = []
if feedback:
localFeedback.setCurrentStep(2)
- localTotal = 100/(len(attributeFeatDict)
- ) if len(attributeFeatDict) != 0 else 0
+ localTotal = (
+ 100 / (len(attributeFeatDict)) if len(attributeFeatDict) != 0 else 0
+ )
mergeFeedback = QgsProcessingMultiStepFeedback(
- len(attributeFeatDict), localFeedback)
+ len(attributeFeatDict), localFeedback
+ )
lyr.startEditing()
- lyr.beginEditCommand(self.tr('Merging Lines'))
+ lyr.beginEditCommand(self.tr("Merging Lines"))
for current, (key, featList) in enumerate(attributeFeatDict.items()):
if feedback:
@@ -458,41 +592,71 @@ def mergeLinesOnLayer(self, lyr, onlySelected=False, feedback=None, ignoreVirtua
idsToRemove=idsToRemove,
parameterDict=parameterDict,
feedback=mergeFeedback,
- networkDict=networkDict
+ networkDict=networkDict,
)
lyr.deleteFeatures(idsToRemove)
lyr.endEditCommand()
- def buildAttributeFeatureDict(self, lyr, onlySelected=False, feedback=None, ignoreVirtualFields=True, attributeBlackList=None, excludePrimaryKeys=True):
+ def buildAttributeFeatureDict(
+ self,
+ lyr,
+ onlySelected=False,
+ feedback=None,
+ ignoreVirtualFields=True,
+ attributeBlackList=None,
+ excludePrimaryKeys=True,
+ ):
iterator, size = self.getFeatureList(lyr, onlySelected=onlySelected)
- localTotal = 100/size if size != 0 else 0
+ localTotal = 100 / size if size != 0 else 0
attributeFeatDict = dict()
columns = self.getAttributesFromBlackList(
- lyr, attributeBlackList=attributeBlackList, ignoreVirtualFields=ignoreVirtualFields, excludePrimaryKeys=excludePrimaryKeys)
+ lyr,
+ attributeBlackList=attributeBlackList,
+ ignoreVirtualFields=ignoreVirtualFields,
+ excludePrimaryKeys=excludePrimaryKeys,
+ )
for current, feat in enumerate(iterator):
if feedback:
if feedback.isCanceled():
break
self.appendFeatOnAttrsDict(attributeFeatDict, feat, columns)
if feedback:
- feedback.setProgress(localTotal*current)
+ feedback.setProgress(localTotal * current)
return attributeFeatDict
- def getAttributesFromBlackList(self, lyr, attributeBlackList=None, ignoreVirtualFields=True, excludePrimaryKeys=True):
+ def getAttributesFromBlackList(
+ self,
+ lyr,
+ attributeBlackList=None,
+ ignoreVirtualFields=True,
+ excludePrimaryKeys=True,
+ ):
attributeBlackList = [] if attributeBlackList is None else attributeBlackList
pkIndexes = lyr.primaryKeyAttributes() if excludePrimaryKeys else []
typeBlackList = [6] if ignoreVirtualFields else []
- columns = [field.name() for idx, field in enumerate(lyr.fields()) if idx not in pkIndexes and field.type(
- ) not in typeBlackList and field.name() not in attributeBlackList]
+ columns = [
+ field.name()
+ for idx, field in enumerate(lyr.fields())
+ if idx not in pkIndexes
+ and field.type() not in typeBlackList
+ and field.name() not in attributeBlackList
+ ]
return columns
def appendFeatOnAttrsDict(self, inputDict, feat, columns):
- attrKey = ','.join(['{}'.format(feat[column]) for column in columns])
+ attrKey = ",".join(["{}".format(feat[column]) for column in columns])
if attrKey not in inputDict:
inputDict[attrKey] = []
inputDict[attrKey].append(feat)
- def buildInitialAndEndPointDict(self, lyr, onlySelected=False, feedback=None, addFeatureToList=False, recordStepProgress=True):
+ def buildInitialAndEndPointDict(
+ self,
+ lyr,
+ onlySelected=False,
+ feedback=None,
+ addFeatureToList=False,
+ recordStepProgress=True,
+ ):
"""
Calculates initial point and end point from each line from lyr.
"""
@@ -501,7 +665,9 @@ def buildInitialAndEndPointDict(self, lyr, onlySelected=False, feedback=None, ad
# iterating over features to store start and end points
iterator = lyr.getFeatures() if not onlySelected else lyr.getSelectedFeatures()
if recordStepProgress:
- featCount = lyr.featureCount() if not onlySelected else lyr.selectedFeatureCount()
+ featCount = (
+ lyr.featureCount() if not onlySelected else lyr.selectedFeatureCount()
+ )
if featCount == 0:
return endVerticesDict
size = 100 / featCount
@@ -509,56 +675,77 @@ def buildInitialAndEndPointDict(self, lyr, onlySelected=False, feedback=None, ad
if feedback is not None and feedback.isCanceled():
break
geom = feat.geometry()
- lineList = geom.asMultiPolyline() if geom.isMultipart() else [
- geom.asPolyline()]
+ lineList = (
+ geom.asMultiPolyline() if geom.isMultipart() else [geom.asPolyline()]
+ )
for line in lineList:
self.addFeatToDict(
endVerticesDict=endVerticesDict,
line=line,
- item=feat if addFeatureToList else feat.id()
+ item=feat if addFeatureToList else feat.id(),
)
if feedback is not None and recordStepProgress:
- feedback.setProgress(size*current)
+ feedback.setProgress(size * current)
return endVerticesDict
- def getDuplicatedFeaturesDict(self, lyr, onlySelected=False, attributeBlackList=None, ignoreVirtualFields=True, excludePrimaryKeys=True, useAttributes=False, feedback=None):
+ def getDuplicatedFeaturesDict(
+ self,
+ lyr,
+ onlySelected=False,
+ attributeBlackList=None,
+ ignoreVirtualFields=True,
+ excludePrimaryKeys=True,
+ useAttributes=False,
+ feedback=None,
+ ):
"""
returns geomDict = {
'bbox_geom' : {geomKey : -list of duplicated feats-}
}
"""
geomDict = dict()
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
iterator, featCount = self.getFeatureList(
- lyr, onlySelected=onlySelected, returnIterator=True)
- size = 100/featCount if featCount else 0
+ lyr, onlySelected=onlySelected, returnIterator=True
+ )
+ size = 100 / featCount if featCount else 0
columns = self.getAttributesFromBlackList(
- lyr, attributeBlackList=attributeBlackList, ignoreVirtualFields=ignoreVirtualFields, excludePrimaryKeys=excludePrimaryKeys)
- multiStepFeedback = QgsProcessingMultiStepFeedback(
- 2, feedback) if feedback else None
+ lyr,
+ attributeBlackList=attributeBlackList,
+ ignoreVirtualFields=ignoreVirtualFields,
+ excludePrimaryKeys=excludePrimaryKeys,
+ )
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(2, feedback) if feedback else None
+ )
multiStepFeedback.setCurrentStep(0)
# builds bounding box dict to do a geos comparison for each feat in list
bbDict = self.getFeaturesWithSameBoundingBox(
- iterator, isMulti, featCount, columns=columns, feedback=feedback)
+ iterator, isMulti, featCount, columns=columns, feedback=feedback
+ )
multiStepFeedback.setCurrentStep(1)
for current, (key, featList) in enumerate(bbDict.items()):
if feedback is not None and feedback.isCanceled():
break
if len(featList) > 1:
duplicatedDict = self.searchDuplicatedFeatures(
- featList, columns=columns, useAttributes=useAttributes)
+ featList, columns=columns, useAttributes=useAttributes
+ )
geomDict.update(duplicatedDict)
if feedback is not None:
feedback.setProgress(size * current)
return geomDict
- def getFeaturesWithSameBoundingBox(self, iterator, isMulti, size, columns=None, feedback=None):
+ def getFeaturesWithSameBoundingBox(
+ self, iterator, isMulti, size, columns=None, feedback=None
+ ):
"""
- Iterates over iterator and gets
+ Iterates over iterator and gets
"""
bbDict = defaultdict(list)
if feedback is not None:
feedback.setProgressText(self.tr("Building duplicated search structure..."))
+
def _buildBBDictEntry(feat, columns):
if feedback.isCanceled():
return
@@ -566,13 +753,21 @@ def _buildBBDictEntry(feat, columns):
if isMulti and not geom.isMultipart():
geom.convertToMultiType()
geomBB_key = geom.boundingBox().asWktPolygon()
- attrKey = ','.join(['{}'.format(feat[column])
- for column in columns]) if columns is not None else ''
- return (geomBB_key, {'geom': geom, 'feat': feat, 'attrKey': attrKey})
+ attrKey = (
+ ",".join(["{}".format(feat[column]) for column in columns])
+ if columns is not None
+ else ""
+ )
+ return (geomBB_key, {"geom": geom, "feat": feat, "attrKey": attrKey})
+
futures = set()
- pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count()-1)
+ pool = concurrent.futures.ThreadPoolExecutor(os.cpu_count() - 1)
func = lambda x: _buildBBDictEntry(x, columns)
- multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) if feedback is not None else None
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(2, feedback)
+ if feedback is not None
+ else None
+ )
multiStepFeedback.setCurrentStep(0)
multiStepFeedback.pushInfo(self.tr("Submitting tasks to thread"))
for feat in iterator:
@@ -590,7 +785,7 @@ def _buildBBDictEntry(feat, columns):
multiStepFeedback.setProgress(size * current)
return bbDict
# """
- # Iterates over iterator and gets
+ # Iterates over iterator and gets
# """
# bbDict = defaultdict(list)
# for current, feat in enumerate(iterator):
@@ -616,12 +811,12 @@ def searchDuplicatedFeatures(self, featList, columns, useAttributes=False):
"""
duplicatedDict = dict()
if featList:
- fields = [f.name() for f in featList[0]['feat'].fields()]
+ fields = [f.name() for f in featList[0]["feat"].fields()]
for dict_feat1, dict_feat2 in combinations(featList, 2):
- geom1 = dict_feat1['geom']
- geom2 = dict_feat2['geom']
- feat1 = dict_feat1['feat']
- feat2 = dict_feat2['feat']
+ geom1 = dict_feat1["geom"]
+ geom2 = dict_feat2["geom"]
+ feat1 = dict_feat1["feat"]
+ feat2 = dict_feat2["feat"]
wkb1 = geom1.asWkb()
wkb2 = geom2.asWkb()
if not geom1.isGeosEqual(geom2):
@@ -633,7 +828,7 @@ def searchDuplicatedFeatures(self, featList, columns, useAttributes=False):
if attr not in columns:
continue
elif feat1[attr] != feat2[attr]:
- raise Exception('Skip outter loop')
+ raise Exception("Skip outter loop")
except:
continue
if wkb1 in duplicatedDict:
@@ -655,7 +850,7 @@ def addPointToDict(self, point, pointDict, item):
def addDissolveField(self, layer, tol, feedback=None):
# add temp field
- idField = QgsField('d_id', QVariant.Int)
+ idField = QgsField("d_id", QVariant.Int)
layer.dataProvider().addAttributes([idField])
layer.updateFields()
# small feature list
@@ -666,17 +861,20 @@ def addDissolveField(self, layer, tol, feedback=None):
else:
multiStepFeedback = None
smallFeatureList, bigFeatureList, bigFeatIndex = self.buildSizeSearchStructure(
- layer, tol, feedback=multiStepFeedback)
+ layer, tol, feedback=multiStepFeedback
+ )
if multiStepFeedback:
multiStepFeedback.setCurrentStep(1)
self.populateSizeSearchStructure(
- layer, smallFeatureList, bigFeatIndex, feedback=multiStepFeedback)
+ layer, smallFeatureList, bigFeatIndex, feedback=multiStepFeedback
+ )
if multiStepFeedback:
multiStepFeedback.setCurrentStep(2)
updateDict = self.updateFeaturesWithSize(
- layer, smallFeatureList, bigFeatureList, feedback=multiStepFeedback)
+ layer, smallFeatureList, bigFeatureList, feedback=multiStepFeedback
+ )
return layer
def getCandidates(self, idx, bbox):
@@ -699,7 +897,7 @@ def buildSizeSearchStructure(self, layer, tol, feedback=None):
if feedback:
if feedback.isCanceled():
break
- feat['d_id'] = feat['featid']
+ feat["d_id"] = feat["featid"]
if feat.geometry().area() < float(tol):
smallFeatureList.append(feat)
else:
@@ -709,7 +907,9 @@ def buildSizeSearchStructure(self, layer, tol, feedback=None):
feedback.setProgress(size * current)
return smallFeatureList, bigFeatureList, bigFeatIndex
- def populateSizeSearchStructure(self, layer, smallFeatureList, bigFeatIndex, feedback=None):
+ def populateSizeSearchStructure(
+ self, layer, smallFeatureList, bigFeatIndex, feedback=None
+ ):
# using spatial index to speed up the process
featSize = len(smallFeatureList)
size = 100 / featSize if featSize else 0
@@ -717,19 +917,28 @@ def populateSizeSearchStructure(self, layer, smallFeatureList, bigFeatIndex, fee
if feedback:
if feedback.isCanceled():
break
- candidates = bigFeatIndex.intersects(
- sfeat.geometry().boundingBox())
+ candidates = bigFeatIndex.intersects(sfeat.geometry().boundingBox())
for candidate in candidates:
- bfeat = [i for i in layer.dataProvider().getFeatures(
- QgsFeatureRequest(candidate))][0]
- if sfeat['d_id'] == sfeat['featid'] and sfeat.geometry().intersects(bfeat.geometry()) and sfeat['tupple'] == bfeat['tupple']:
- sfeat['d_id'] = bfeat['featid']
+ bfeat = [
+ i
+ for i in layer.dataProvider().getFeatures(
+ QgsFeatureRequest(candidate)
+ )
+ ][0]
+ if (
+ sfeat["d_id"] == sfeat["featid"]
+ and sfeat.geometry().intersects(bfeat.geometry())
+ and sfeat["tupple"] == bfeat["tupple"]
+ ):
+ sfeat["d_id"] = bfeat["featid"]
if feedback:
feedback.setProgress(size * current)
- def updateFeaturesWithSize(self, layer, smallFeatureList, bigFeatureList, feedback=None):
+ def updateFeaturesWithSize(
+ self, layer, smallFeatureList, bigFeatureList, feedback=None
+ ):
updateDict = dict()
- idx = layer.fieldNameIndex('tupple')
+ idx = layer.fieldNameIndex("tupple")
featList = smallFeatureList + bigFeatureList
featSize = len(featList)
size = 100 / featSize if featSize else 0
@@ -737,19 +946,19 @@ def updateFeaturesWithSize(self, layer, smallFeatureList, bigFeatureList, feedba
if feedback:
if feedback.isCanceled():
break
- newValue = u'{0},{1}'.format(feat['tupple'], feat['d_id'])
+ newValue = "{0},{1}".format(feat["tupple"], feat["d_id"])
updateDict[feat.id()] = {idx: newValue}
if feedback:
feedback.setProgress(size * current)
return updateDict
-
+
def searchDanglesOnPointDict(self, endVerticesDict, feedback):
"""
Counts the number of points on each endVerticesDict's key and returns a list of QgsPoint built from key candidate.
"""
pointList = []
nVertexes = len(endVerticesDict)
- localTotal = 100/nVertexes if nVertexes else 0
+ localTotal = 100 / nVertexes if nVertexes else 0
# actual search for dangles
for current, point in enumerate(endVerticesDict):
if feedback.isCanceled():
@@ -757,13 +966,15 @@ def searchDanglesOnPointDict(self, endVerticesDict, feedback):
# this means we only have one occurrence of point, therefore it is a dangle
if len(endVerticesDict[point]) <= 1:
pointList.append(point)
- feedback.setProgress(localTotal*current)
+ feedback.setProgress(localTotal * current)
return pointList
-
- def getSmallFirstOrderDanglesFromPointDict(self, endVerticesDict, minLength, feedback=None):
+
+ def getSmallFirstOrderDanglesFromPointDict(
+ self, endVerticesDict, minLength, feedback=None
+ ):
pointList = []
nVertexes = len(endVerticesDict)
- localTotal = 100/nVertexes if nVertexes else 0
+ localTotal = 100 / nVertexes if nVertexes else 0
for current, (point, featList) in enumerate(endVerticesDict.items()):
if feedback is not None and feedback.isCanceled():
break
@@ -772,8 +983,10 @@ def getSmallFirstOrderDanglesFromPointDict(self, endVerticesDict, minLength, fee
if feedback is not None:
feedback.setProgress(current * localTotal)
return pointList
-
- def getSmallFirstOrderDangles(self, inputLyr, minLength, onlySelected=False, feedback=None):
+
+ def getSmallFirstOrderDangles(
+ self, inputLyr, minLength, onlySelected=False, feedback=None
+ ):
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
multiStepFeedback.setProgressText(self.tr("Building aux structure"))
multiStepFeedback.setCurrentStep(0)
@@ -781,12 +994,16 @@ def getSmallFirstOrderDangles(self, inputLyr, minLength, onlySelected=False, fee
inputLyr,
onlySelected=onlySelected,
feedback=multiStepFeedback,
- addFeatureToList=True
+ addFeatureToList=True,
)
multiStepFeedback.setCurrentStep(1)
- multiStepFeedback.setProgressText(self.tr("Searching small first order dangles"))
+ multiStepFeedback.setProgressText(
+ self.tr("Searching small first order dangles")
+ )
pointList = self.getSmallFirstOrderDanglesFromPointDict(
- endVerticesDict=endVerticesDict, minLength=minLength, feedback=multiStepFeedback
+ endVerticesDict=endVerticesDict,
+ minLength=minLength,
+ feedback=multiStepFeedback,
)
return pointList
@@ -798,7 +1015,8 @@ def filterDangles(self, lyr, searchRadius, feedback=None):
else:
multiStepFeedback = None
spatialIdx, idDict = self.buildSpatialIndexAndIdDict(
- lyr, feedback=multiStepFeedback)
+ lyr, feedback=multiStepFeedback
+ )
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(1)
featSize = len(idDict)
@@ -812,13 +1030,17 @@ def filterDangles(self, lyr, searchRadius, feedback=None):
# gets candidates from spatial index
candidateIds = spatialIdx.intersects(bufferBB)
for fid in candidateIds:
- if fid != id and fid not in deleteSet and buffer.intersects(feat.geometry()):
+ if (
+ fid != id
+ and fid not in deleteSet
+ and buffer.intersects(feat.geometry())
+ ):
deleteSet.add(fid)
if feedback is not None:
multiStepFeedback.setProgress(size * current)
lyr.startEditing()
- lyr.beginEditCommand('Filter dangles')
+ lyr.beginEditCommand("Filter dangles")
lyr.deleteFeatures(list(deleteSet))
lyr.commitChanges()
@@ -831,23 +1053,32 @@ def buildSpatialIndexAndIdDict(self, inputLyr, feedback=None, featureRequest=Non
"""
spatialIdx = QgsSpatialIndex()
idDict = {}
+ if inputLyr is None:
+ return spatialIdx, idDict
featCount = inputLyr.featureCount()
- size = 100/featCount if featCount else 0
- iterator = inputLyr.getFeatures(
- ) if featureRequest is None else inputLyr.getFeatures(featureRequest)
-
- def addFeatureAlias(x): return self.addFeatureToSpatialIndex(
- current=x[0],
- feat=x[1],
- spatialIdx=spatialIdx,
- idDict=idDict,
- size=size,
- feedback=feedback
+ size = 100 / featCount if featCount else 0
+ iterator = (
+ inputLyr.getFeatures()
+ if featureRequest is None
+ else inputLyr.getFeatures(featureRequest)
)
+
+ def addFeatureAlias(x):
+ return self.addFeatureToSpatialIndex(
+ current=x[0],
+ feat=x[1],
+ spatialIdx=spatialIdx,
+ idDict=idDict,
+ size=size,
+ feedback=feedback,
+ )
+
list(map(addFeatureAlias, enumerate(iterator)))
return spatialIdx, idDict
- def addFeatureToSpatialIndex(self, current, feat, spatialIdx, idDict, size, feedback):
+ def addFeatureToSpatialIndex(
+ self, current, feat, spatialIdx, idDict, size, feedback
+ ):
"""
Adds feature to spatial index. Used along side with a python map operator
to improve performance.
@@ -879,23 +1110,24 @@ def getFrameOutterBounds(self, frameLayer, algRunner, context, feedback=None):
multiStepFeedback = None
# dissolve every feature into a single one
outputLayer = algRunner.runDissolve(
- frameLayer, context, feedback=multiStepFeedback)
+ frameLayer, context, feedback=multiStepFeedback
+ )
if feedback is not None:
multiStepFeedback.setCurrentStep(1)
boundaryLayer = algRunner.runBoundary(
- outputLayer, context, feedback=multiStepFeedback)
+ outputLayer, context, feedback=multiStepFeedback
+ )
# get all frame outter layer found
if feedback is not None:
multiStepFeedback.setCurrentStep(2)
featCount = boundaryLayer.featureCount()
- size = 100/featCount if featCount else 0
+ size = 100 / featCount if featCount else 0
for current, feat in enumerate(boundaryLayer.getFeatures()):
if feedback is not None and feedback.isCanceled():
break
geom = feat.geometry()
# deaggregate geometry, if necessary
- frameGeomList += self.geometryHandler.deaggregateGeometry(
- multiGeom=geom)
+ frameGeomList += self.geometryHandler.deaggregateGeometry(multiGeom=geom)
if feedback is not None:
multiStepFeedback.setProgress(size * current)
return frameGeomList
@@ -907,8 +1139,8 @@ def identifyAllNodes(self, networkLayer):
:return: { node_id : { start : [feature_which_starts_with_node], end : feature_which_ends_with_node } }.
"""
nodeDict = dict()
- isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType()))
- if self.parameters['Only Selected']:
+ isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType())
+ if self.parameters["Only Selected"]:
features = networkLayer.selectedFeatures()
else:
features = [feat for feat in networkLayer.getFeatures()]
@@ -930,30 +1162,35 @@ def identifyAllNodes(self, networkLayer):
# filling starting node information into dictionary
if pInit not in nodeDict:
# if the point is not already started into dictionary, it creates a new item
- nodeDict[pInit] = {'start': [], 'end': []}
- if feat not in nodeDict[pInit]['start']:
- nodeDict[pInit]['start'].append(feat)
+ nodeDict[pInit] = {"start": [], "end": []}
+ if feat not in nodeDict[pInit]["start"]:
+ nodeDict[pInit]["start"].append(feat)
# filling ending node information into dictionary
if pEnd not in nodeDict:
- nodeDict[pEnd] = {'start': [], 'end': []}
- if feat not in nodeDict[pEnd]['end']:
- nodeDict[pEnd]['end'].append(feat)
+ nodeDict[pEnd] = {"start": [], "end": []}
+ if feat not in nodeDict[pEnd]["end"]:
+ nodeDict[pEnd]["end"].append(feat)
return nodeDict
- def snapToLayer(self, inputLyr, refLyr, tol, behavior, onlySelected=False, feedback=None):
+ def snapToLayer(
+ self, inputLyr, refLyr, tol, behavior, onlySelected=False, feedback=None
+ ):
"""
Snaps and updates inpytLyr
"""
- snapper = QgsGeometrySnapper(
- refLyr) if inputLyr != refLyr and behavior != 7 else QgsInternalGeometrySnapper(tol, behavior)
- iterator, featCount = self.getFeatureList(
- inputLyr, onlySelected=onlySelected)
+ snapper = (
+ QgsGeometrySnapper(refLyr)
+ if inputLyr != refLyr and behavior != 7
+ else QgsInternalGeometrySnapper(tol, behavior)
+ )
+ iterator, featCount = self.getFeatureList(inputLyr, onlySelected=onlySelected)
if featCount == 0:
return
- size = 100/featCount
+ size = 100 / featCount
deleteSet = set()
inputLyr.startEditing()
- inputLyr.beginEditCommand('Snapping Features')
+ inputLyr.beginEditCommand("Snapping Features")
+
def evaluate(feat):
if feedback is not None and feedback.isCanceled():
return None
@@ -967,13 +1204,17 @@ def evaluate(feat):
fixedGeom = geom.makeValid()
if fixedGeom.isNull():
return None
- outputGeom = snapper.snapGeometry(fixedGeom, tol, behavior) \
- if inputLyr != refLyr and behavior != 7 else snapper.snapFeature(feat)
+ outputGeom = (
+ snapper.snapGeometry(fixedGeom, tol, behavior)
+ if inputLyr != refLyr and behavior != 7
+ else snapper.snapFeature(feat)
+ )
if geom is None:
return featid
return featid, outputGeom
+
futures = set()
- pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1)
+ pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1)
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
multiStepFeedback.setCurrentStep(0)
for current, feat in enumerate(iterator):
@@ -998,7 +1239,9 @@ def evaluate(feat):
inputLyr.deleteFeatures(list(deleteSet))
inputLyr.endEditCommand()
- def getContourLineOutOfThreshold(self, contourLyr, terrainPolygonLyr, threshold, refLyr=None, feedback=None):
+ def getContourLineOutOfThreshold(
+ self, contourLyr, terrainPolygonLyr, threshold, refLyr=None, feedback=None
+ ):
"""
todo
"""
@@ -1017,14 +1260,20 @@ def filterByExpression(self, layer, expression, context, feedback=None):
:return: (QgsVectorLayer) filtered layer.
"""
return AlgRunner().runFilterExpression(
- inputLyr=layer,
- context=context,
- expression=expression,
- feedback=feedback
+ inputLyr=layer, context=context, expression=expression, feedback=feedback
)
- def prepareConversion(self, inputLyr, context, inputExpression=None, filterLyr=None,
- behavior=None, bufferRadius=None, conversionMap=None, feedback=None):
+ def prepareConversion(
+ self,
+ inputLyr,
+ context,
+ inputExpression=None,
+ filterLyr=None,
+ behavior=None,
+ bufferRadius=None,
+ conversionMap=None,
+ feedback=None,
+ ):
bufferRadius = 0 if bufferRadius is None else bufferRadius
algRunner = AlgRunner()
if feedback is not None:
@@ -1042,14 +1291,14 @@ def prepareConversion(self, inputLyr, context, inputExpression=None, filterLyr=N
multiStepFeedback = None
localLyr = inputLyr
currentStep = 0
- if inputExpression is not None and inputExpression != '':
+ if inputExpression is not None and inputExpression != "":
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(currentStep)
localLyr = algRunner.runFilterExpression(
inputLyr=localLyr,
context=context,
expression=inputExpression,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
currentStep += 1
if filterLyr is not None:
@@ -1057,64 +1306,112 @@ def prepareConversion(self, inputLyr, context, inputExpression=None, filterLyr=N
multiStepFeedback.setCurrentStep(currentStep)
if behavior == 3:
filterLyr = algRunner.runBuffer(
- filterLyr, bufferRadius, context, feedback=multiStepFeedback)
+ filterLyr, bufferRadius, context, feedback=multiStepFeedback
+ )
currentStep += 1
localLyr = algRunner.runIntersection(
- localLyr, context, overlayLyr=filterLyr)
+ localLyr, context, overlayLyr=filterLyr
+ )
return localLyr
- def identifyAndFixInvalidGeometries(self, inputLyr, ignoreClosed=False, fixInput=False, onlySelected=False, feedback=None):
- iterator, featCount = self.getFeatureList(
- inputLyr, onlySelected=onlySelected)
+ def identifyAndFixInvalidGeometries(
+ self,
+ inputLyr,
+ ignoreClosed=False,
+ fixInput=False,
+ onlySelected=False,
+ feedback=None,
+ ):
+ iterator, featCount = self.getFeatureList(inputLyr, onlySelected=onlySelected)
parameterDict = self.getDestinationParameters(inputLyr)
geometryType = inputLyr.geometryType()
- flagDict, newFeatSet = self.identifyInvalidGeometries(iterator, featCount, inputLyr, ignoreClosed, fixInput, parameterDict, geometryType, feedback=feedback)
+ flagDict, newFeatSet = self.identifyInvalidGeometries(
+ iterator,
+ featCount,
+ inputLyr,
+ ignoreClosed,
+ fixInput,
+ parameterDict,
+ geometryType,
+ feedback=feedback,
+ )
if fixInput:
self.applyGeometryFixesOnLayer(inputLyr, newFeatSet)
return flagDict
- def identifyInvalidGeometries(self, iterator, featCount, inputLyr, ignoreClosed, fixInput, parameterDict, geometryType, feedback=None):
+ def identifyInvalidGeometries(
+ self,
+ iterator,
+ featCount,
+ inputLyr,
+ ignoreClosed,
+ fixInput,
+ parameterDict,
+ geometryType,
+ feedback=None,
+ ):
flagDict = dict()
newFeatSet = set()
- stepSize = 100/featCount if featCount else 0
+ stepSize = 100 / featCount if featCount else 0
futures = set()
- pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1)
- multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback) if feedback is not None else None
+ pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1)
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(2, feedback)
+ if feedback is not None
+ else None
+ )
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(0)
multiStepFeedback.pushInfo(self.tr("Submitting tasks to thread..."))
+
def evaluate(feat):
_newFeatSet = set()
geom = feat.geometry()
id = feat.id()
flagDict = self.checkGeomIsValid(geom, ignoreClosed, feedback)
if fixInput:
- self.fixGeometryFromInput(inputLyr, parameterDict, geometryType, _newFeatSet, feat, geom, id)
- return flagDict, _newFeatSet
+ self.fixGeometryFromInput(
+ inputLyr, parameterDict, geometryType, _newFeatSet, feat, geom, id
+ )
+ return flagDict, _newFeatSet, feat
+
for current, feat in enumerate(iterator):
if feedback is not None and feedback.isCanceled():
break
futures.add(pool.submit(evaluate, feat))
if feedback is not None:
- feedback.setProgress(stepSize*current)
+ feedback.setProgress(stepSize * current)
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(1)
multiStepFeedback.pushInfo(self.tr("Evaluating results..."))
+ pkFields = inputLyr.primaryKeyAttributes()
+ pkFieldNames = [
+ field.name()
+ for idx, field in enumerate(inputLyr.fields())
+ if idx in pkFields
+ ]
for current, future in enumerate(concurrent.futures.as_completed(futures)):
if feedback is not None and feedback.isCanceled():
break
- output, _newFeatSet = future.result()
+ output, _newFeatSet, feat = future.result()
if output:
+ featIdText = (
+ f"{feat.id()}"
+ if pkFields == []
+ else f"{','.join(feat.attribute(i) for i in pkFields)}"
+ )
+ featIdText = featIdText.replace(",)", "").replace("(", "")
for point, errorDict in output.items():
if point in flagDict:
flagDict[point]["reason"] += errorDict["reason"]
else:
flagDict[point] = errorDict
+ flagDict[point]["featid"] = featIdText
if _newFeatSet:
newFeatSet = newFeatSet.union(_newFeatSet)
if feedback is not None:
- feedback.setProgress(stepSize*current)
+ feedback.setProgress(stepSize * current)
return flagDict, newFeatSet
def checkGeomIsValid(self, geom, ignoreClosed, feedback=None):
@@ -1125,33 +1422,39 @@ def checkGeomIsValid(self, geom, ignoreClosed, feedback=None):
}.items():
if feedback is not None and feedback.isCanceled():
break
- isValid = self.check_validity(ignoreClosed, flagDict, geom, validate_type, method_parameter)
+ isValid = self.check_validity(
+ ignoreClosed, flagDict, geom, validate_type, method_parameter
+ )
if not isValid:
break
if isValid and geom.type() == QgsWkbTypes.PolygonGeometry:
self.analyze_polygon_boundary_and_holes(flagDict, geom)
return flagDict
- def fixGeometryFromInput(self, inputLyr, parameterDict, geometryType, newFeatSet, feat, geom, id):
- attrMap = {idx: feat[field.name()] for idx, field in enumerate(
- feat.fields()) if idx not in inputLyr.primaryKeyAttributes()}
- geom.removeDuplicateNodes(
- useZValues=parameterDict['hasZValues'])
+ def fixGeometryFromInput(
+ self, inputLyr, parameterDict, geometryType, newFeatSet, feat, geom, id
+ ):
+ attrMap = {
+ idx: feat[field.name()]
+ for idx, field in enumerate(feat.fields())
+ if idx not in inputLyr.primaryKeyAttributes()
+ }
+ geom.removeDuplicateNodes(useZValues=parameterDict["hasZValues"])
fixedGeom = geom.makeValid()
for idx, newGeom in enumerate(
- self.geometryHandler.handleGeometryCollection(
- fixedGeom, geometryType, parameterDict=parameterDict)
- ):
+ self.geometryHandler.handleGeometryCollection(
+ fixedGeom, geometryType, parameterDict=parameterDict
+ )
+ ):
if idx == 0:
inputLyr.changeGeometry(id, newGeom)
else:
- newFeat = QgsVectorLayerUtils.createFeature(
- inputLyr, newGeom, attrMap)
+ newFeat = QgsVectorLayerUtils.createFeature(inputLyr, newGeom, attrMap)
newFeatSet.add(newFeat)
def applyGeometryFixesOnLayer(self, inputLyr, newFeatSet):
inputLyr.startEditing()
- inputLyr.beginEditCommand('Fixing geometries')
+ inputLyr.beginEditCommand("Fixing geometries")
inputLyr.addFeatures(newFeatSet)
inputLyr.endEditCommand()
@@ -1160,31 +1463,37 @@ def analyze_polygon_boundary_and_holes(self, flagDict, geom):
for part in geom.asGeometryCollection():
if len(part.asPolygon()) <= 1:
continue
- boundary, *holeList = map(lambda x: QgsGeometry.fromPolylineXY(x), part.asPolygon())
+ boundary, *holeList = map(
+ lambda x: QgsGeometry.fromPolylineXY(x), part.asPolygon()
+ )
for intersection in map(
- lambda x: x.intersection(boundary),
- filter(lambda y: y.intersects(boundary), holeList)
- ):
- flagWktSet = flagWktSet.union(set(vertex.asWkt() for vertex in intersection.vertices()))
+ lambda x: x.intersection(boundary),
+ filter(lambda y: y.intersects(boundary), holeList),
+ ):
+ flagWktSet = flagWktSet.union(
+ set(vertex.asWkt() for vertex in intersection.vertices())
+ )
for flag in flagWktSet:
errorPointXY = QgsGeometry.fromWkt(flag).asPoint()
flagGeom = QgsGeometry.fromPointXY(errorPointXY)
if errorPointXY not in flagDict:
- flagDict[errorPointXY] = {
- 'geom': flagGeom,
- 'reason': ''
- }
- flagDict[errorPointXY]['reason'] += 'OGC invalid reason: {text}\n'.format(
- text=self.tr("Self intersection between hole and boundary")
- )
+ flagDict[errorPointXY] = {"geom": flagGeom, "reason": ""}
+ flagDict[errorPointXY]["reason"] += "OGC invalid reason: {text}\n".format(
+ text=self.tr("Self intersection between hole and boundary")
+ )
- def check_validity(self, ignoreClosed, flagDict, geom, validate_type, method_parameter):
+ def check_validity(
+ self, ignoreClosed, flagDict, geom, validate_type, method_parameter
+ ):
for error in geom.validateGeometry(method_parameter):
if error.hasWhere():
errorPointXY = error.where()
flagGeom = QgsGeometry.fromPointXY(errorPointXY)
- if geom.type() == QgsWkbTypes.LineGeometry and ignoreClosed and\
- self.isClosedAndFlagIsAtStartOrEnd(geom, flagGeom):
+ if (
+ geom.type() == QgsWkbTypes.LineGeometry
+ and ignoreClosed
+ and self.isClosedAndFlagIsAtStartOrEnd(geom, flagGeom)
+ ):
continue
self._add_flag(flagDict, validate_type, error, errorPointXY, flagGeom)
return False
@@ -1192,19 +1501,16 @@ def check_validity(self, ignoreClosed, flagDict, geom, validate_type, method_par
def _add_flag(self, flagDict, validate_type, error, errorPointXY, flagGeom):
if errorPointXY not in flagDict:
- flagDict[errorPointXY] = {
- 'geom': flagGeom,
- 'reason': ''
- }
- flagDict[errorPointXY]['reason'] += '{type} invalid reason: {text}\n'.format(
- type=validate_type,
- text=error.what()
- )
+ flagDict[errorPointXY] = {"geom": flagGeom, "reason": ""}
+ flagDict[errorPointXY]["reason"] += "{type} invalid reason: {text}\n".format(
+ type=validate_type, text=error.what()
+ )
def isClosedAndFlagIsAtStartOrEnd(self, geom, flagGeom):
for part in geom.asGeometryCollection():
startPoint, endPoint = self.geometryHandler.getFirstAndLastNodeFromGeom(
- part)
+ part
+ )
startPointGeom = QgsGeometry.fromPointXY(startPoint)
endPointGeom = QgsGeometry.fromPointXY(endPoint)
if not startPointGeom.equals(endPointGeom):
@@ -1213,7 +1519,15 @@ def isClosedAndFlagIsAtStartOrEnd(self, geom, flagGeom):
return True
return False
- def runGrassDissolve(self, inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None):
+ def runGrassDissolve(
+ self,
+ inputLyr,
+ context,
+ feedback=None,
+ column=None,
+ outputLyr=None,
+ onFinish=None,
+ ):
"""
Runs dissolve from GRASS algorithm provider.
:param inputLyr: (QgsVectorLayer) layer to be dissolved.
@@ -1224,10 +1538,20 @@ def runGrassDissolve(self, inputLyr, context, feedback=None, column=None, output
:param onFinish: (list-of-str) sequence of algs to be run after dissolve is executed, in execution order.
:return: (QgsVectorLayer) dissolved (output) layer.
"""
- return AlgRunner().runGrassDissolve(inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None)
+ return AlgRunner().runGrassDissolve(
+ inputLyr, context, feedback=None, column=None, outputLyr=None, onFinish=None
+ )
- def getVertexNearEdgeDict(self, inputLyr, tol, onlySelected=False, feedback=None,
- context=None, algRunner=None, ignoreErrorsOnSameFeat=False):
+ def getVertexNearEdgeDict(
+ self,
+ inputLyr,
+ tol,
+ onlySelected=False,
+ feedback=None,
+ context=None,
+ algRunner=None,
+ ignoreErrorsOnSameFeat=False,
+ ):
"""
Identifies vertexes that are too close to a vertex.
:param inputLyr: (QgsVectorLayer) layer to run the identification.
@@ -1236,31 +1560,32 @@ def getVertexNearEdgeDict(self, inputLyr, tol, onlySelected=False, feedback=None
:param feedback (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option.
"""
if inputLyr.geometryType() == QgsWkbTypes.PointGeometry:
- raise Exception('Vertex near edge not defined for point geometry')
+ raise Exception("Vertex near edge not defined for point geometry")
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback)
multiStepFeedback.setCurrentStep(0)
- multiStepFeedback.pushInfo(self.tr('Creating index'))
- usedInput = inputLyr if not onlySelected else QgsProcessingFeatureSourceDefinition(
- inputLyr.id(), True)
+ multiStepFeedback.pushInfo(self.tr("Creating index"))
+ usedInput = (
+ inputLyr
+ if not onlySelected
+ else QgsProcessingFeatureSourceDefinition(inputLyr.id(), True)
+ )
incrementedLayer = algRunner.runAddAutoIncrementalField(
- usedInput,
- context,
- feedback=multiStepFeedback
+ usedInput, context, feedback=multiStepFeedback
)
multiStepFeedback.setCurrentStep(1)
- multiStepFeedback.pushInfo(
- self.tr('Building auxiliar search structures'))
+ multiStepFeedback.pushInfo(self.tr("Building auxiliar search structures"))
edgeSpatialIdx, edgeIdDict = self.buildEdgesAuxStructure(
incrementedLayer,
feedback=multiStepFeedback,
algRunner=algRunner,
- context=context
+ context=context,
)
multiStepFeedback.setCurrentStep(2)
- multiStepFeedback.pushInfo(self.tr('Getting flags'))
+ multiStepFeedback.pushInfo(self.tr("Getting flags"))
vertexNearEdgeFlagDict = self.getVertexNearEdgeFlagDict(
incrementedLayer,
edgeSpatialIdx,
@@ -1269,11 +1594,13 @@ def getVertexNearEdgeDict(self, inputLyr, tol, onlySelected=False, feedback=None
feedback=multiStepFeedback,
algRunner=algRunner,
context=context,
- ignoreErrorsOnSameFeat=ignoreErrorsOnSameFeat
+ ignoreErrorsOnSameFeat=ignoreErrorsOnSameFeat,
)
return vertexNearEdgeFlagDict
- def buildEdgesAuxStructure(self, inputLyr, algRunner=None, feedback=None, context=None):
+ def buildEdgesAuxStructure(
+ self, inputLyr, algRunner=None, feedback=None, context=None
+ ):
"""
returns a spatialIndex of lines and a dict of the features
:param inputLyr: (QgsVectorLayer) layer to run build the aux structure.
@@ -1281,34 +1608,42 @@ def buildEdgesAuxStructure(self, inputLyr, algRunner=None, feedback=None, contex
"""
nSteps = 3 if inputLyr.geometryType() == QgsWkbTypes.PolygonGeometry else 2
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback)
currentStep = 0
multiStepFeedback.setCurrentStep(currentStep)
- edgeLyr = inputLyr if inputLyr.geometryType() == QgsWkbTypes.LineGeometry \
+ edgeLyr = (
+ inputLyr
+ if inputLyr.geometryType() == QgsWkbTypes.LineGeometry
else algRunner.runPolygonsToLines(
- inputLyr,
- context,
- feedback=multiStepFeedback
+ inputLyr, context, feedback=multiStepFeedback
+ )
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
explodedEdges = algRunner.runExplodeLines(
- edgeLyr,
- context,
- feedback=multiStepFeedback
+ edgeLyr, context, feedback=multiStepFeedback
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
spatialIdx, idDict = self.buildSpatialIndexAndIdDict(
- explodedEdges,
- feedback=multiStepFeedback
+ explodedEdges, feedback=multiStepFeedback
)
return spatialIdx, idDict
- def getVertexNearEdgeFlagDict(self, inputLyr, edgeSpatialIdx, edgeIdDict,
- searchRadius, feedback=None, algRunner=None, context=None, ignoreErrorsOnSameFeat=False):
+ def getVertexNearEdgeFlagDict(
+ self,
+ inputLyr,
+ edgeSpatialIdx,
+ edgeIdDict,
+ searchRadius,
+ feedback=None,
+ algRunner=None,
+ context=None,
+ ignoreErrorsOnSameFeat=False,
+ ):
"""
returns a dict in the following format:
{'featid':{
@@ -1318,40 +1653,40 @@ def getVertexNearEdgeFlagDict(self, inputLyr, edgeSpatialIdx, edgeIdDict,
}
}
- }
+ }
:param inputLyr: (QgsVectorLayer) layer to run build the aux structure.
:param edgeSpatialIdx: (QgsSpatialIndex) spatial index to perform the search
:param edgeIdDict: (dict) dictionary in the format {featid:QgsFeature}
:param searchRadius: (float) search radius
:param feedback (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option.
"""
- flagDict = defaultdict(lambda: defaultdict(lambda: {'edges': set()}))
+ flagDict = defaultdict(lambda: defaultdict(lambda: {"edges": set()}))
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
# step 1: extract vertexes
multiStepFeedback.setCurrentStep(0)
vertexLyr = algRunner.runExtractVertices(
- inputLyr,
- context,
- feedback=multiStepFeedback
+ inputLyr, context, feedback=multiStepFeedback
)
# step 2: for each vertex, get the buffer, the buffer BoundingBox and
# assess wich edge intersects the buffer. If there is any, this is a flag
multiStepFeedback.setCurrentStep(1)
iterator, size = self.getFeatureList(
- vertexLyr, returnIterator=True, onlySelected=False)
+ vertexLyr, returnIterator=True, onlySelected=False
+ )
if size == 0:
return {}
- stepSize = 100/size
+ stepSize = 100 / size
for current, pointFeat in enumerate(iterator):
if multiStepFeedback.isCanceled():
break
pointGeom = pointFeat.geometry()
buffer = pointGeom.buffer(searchRadius, -1)
bufferBB = buffer.boundingBox()
- featId = pointFeat['featid']
+ featId = pointFeat["featid"]
# pointWkt is used as a key because it is unique and hashable
pointWkt = pointGeom.asWkt()
for candidateId in edgeSpatialIdx.intersects(bufferBB):
@@ -1360,18 +1695,29 @@ def getVertexNearEdgeFlagDict(self, inputLyr, edgeSpatialIdx, edgeIdDict,
edgeGeom = edgeIdDict[candidateId].geometry()
# must ignore search within the same feature and
# must be with not adjacent edges
- if pointGeom.touches(edgeGeom) or \
- (ignoreErrorsOnSameFeat and featId == edgeIdDict[candidateId]['featid'] and
- pointFeat['layer'] == edgeIdDict[candidateId]['layer']):
+ if pointGeom.touches(edgeGeom) or (
+ ignoreErrorsOnSameFeat
+ and featId == edgeIdDict[candidateId]["featid"]
+ and pointFeat["layer"] == edgeIdDict[candidateId]["layer"]
+ ):
continue
if buffer.intersects(edgeGeom):
- flagDict[featId][pointWkt]['flagGeom'] = pointGeom
- flagDict[featId][pointWkt]['edges'].add(edgeGeom)
+ flagDict[featId][pointWkt]["flagGeom"] = pointGeom
+ flagDict[featId][pointWkt]["edges"].add(edgeGeom)
# make progress
multiStepFeedback.setProgress(current * stepSize)
return flagDict
- def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrList, searchRadius, onlySelected=False, feedback=None, context=None, algRunner=None):
+ def getUnsharedVertexOnSharedEdgesDict(
+ self,
+ inputLineLyrList,
+ inputPolygonLyrList,
+ searchRadius,
+ onlySelected=False,
+ feedback=None,
+ context=None,
+ algRunner=None,
+ ):
"""
returns a dict in the following format:
{'featid':{
@@ -1381,7 +1727,7 @@ def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrLi
}
}
- }
+ }
:param inputLineLyrList: (list of QgsVectorLayers) line layers to run build the aux structure.
:param inputPolygonLyrList: (list of QgsVectorLayers) line polygon layers to run build the aux structure.
:param searchRadius: (float) search radius
@@ -1389,20 +1735,21 @@ def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrLi
"""
inputList = inputLineLyrList
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback)
multiStepFeedback.setCurrentStep(0)
- multiStepFeedback.pushInfo(self.tr('Getting lines'))
+ multiStepFeedback.pushInfo(self.tr("Getting lines"))
linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers(
inputLineLyrList,
inputPolygonLyrList,
onlySelected=onlySelected,
feedback=multiStepFeedback,
- context=context
+ context=context,
)
multiStepFeedback.setCurrentStep(1)
- multiStepFeedback.pushInfo(self.tr('Building vertex near edge dict'))
+ multiStepFeedback.pushInfo(self.tr("Building vertex near edge dict"))
# only selected should not be filled because it was already used to build the line lyr
return self.getVertexNearEdgeDict(
linesLyr,
@@ -1410,11 +1757,19 @@ def getUnsharedVertexOnSharedEdgesDict(self, inputLineLyrList, inputPolygonLyrLi
algRunner=algRunner,
feedback=multiStepFeedback,
context=context,
- ignoreErrorsOnSameFeat=True
+ ignoreErrorsOnSameFeat=True,
)
- def getUnsharedVertexOnIntersections(self, pointLineLyrList, inputLineLyrList, inputPolygonLyrList,
- onlySelected=False, feedback=None, context=None, algRunner=None):
+ def getUnsharedVertexOnIntersections(
+ self,
+ pointLineLyrList,
+ inputLineLyrList,
+ inputPolygonLyrList,
+ onlySelected=False,
+ feedback=None,
+ context=None,
+ algRunner=None,
+ ):
"""
returns a dict in the following format:
{
@@ -1422,37 +1777,47 @@ def getUnsharedVertexOnIntersections(self, pointLineLyrList, inputLineLyrList, i
'layer1' : --layer 1 name--',
'layer2' : --layer 2 name--'
}
- }
+ }
:param inputLineLyrList: (list of QgsVectorLayers) line layers to run build the aux structure.
:param inputPolygonLyrList: (list of QgsVectorLayers) line polygon layers to run build the aux structure.
:param searchRadius: (float) search radius
:param feedback (QgsProcessingFeedback) QGIS object to keep track of progress/cancelling option.
"""
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
stepCount = 6 if pointLineLyrList else 5
multiStepFeedback = QgsProcessingMultiStepFeedback(stepCount, feedback)
currentStep = 0
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.pushInfo(self.tr('Getting lines'))
+ multiStepFeedback.pushInfo(self.tr("Getting lines"))
linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers(
inputLineLyrList,
inputPolygonLyrList,
onlySelected=onlySelected,
feedback=multiStepFeedback,
- context=context
+ context=context,
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.pushInfo(self.tr('Building point merged layer'))
- pointsLyr = algRunner.runMergeVectorLayers(pointLineLyrList, context, feedback=multiStepFeedback) if pointLineLyrList else None
+ multiStepFeedback.pushInfo(self.tr("Building point merged layer"))
+ pointsLyr = (
+ algRunner.runMergeVectorLayers(
+ pointLineLyrList, context, feedback=multiStepFeedback
+ )
+ if pointLineLyrList
+ else None
+ )
currentStep += 1
if pointsLyr is not None:
multiStepFeedback.setCurrentStep(currentStep)
pointsLyr = algRunner.runMultipartToSingleParts(
- inputLayer=pointsLyr, context=context, feedback=multiStepFeedback, outputLyr='TEMPORARY_OUTPUT'
+ inputLayer=pointsLyr,
+ context=context,
+ feedback=multiStepFeedback,
+ outputLyr="TEMPORARY_OUTPUT",
)
pointsSet = set([i for i in pointsLyr.getFeatures()])
currentStep += 1
@@ -1460,43 +1825,42 @@ def getUnsharedVertexOnIntersections(self, pointLineLyrList, inputLineLyrList, i
pointsSet = set()
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.pushInfo(self.tr('Building intersections'))
+ multiStepFeedback.pushInfo(self.tr("Building intersections"))
intersectionLyr = algRunner.runLineIntersections(
- linesLyr,
- linesLyr,
- feedback=multiStepFeedback,
- context=context
+ linesLyr, linesLyr, feedback=multiStepFeedback, context=context
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.pushInfo(self.tr('Finding vertexes'))
+ multiStepFeedback.pushInfo(self.tr("Finding vertexes"))
vertexLyr = algRunner.runExtractVertices(
- linesLyr,
- feedback=multiStepFeedback,
- context=context
+ linesLyr, feedback=multiStepFeedback, context=context
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.pushInfo(self.tr('Finding unshared vertexes'))
+ multiStepFeedback.pushInfo(self.tr("Finding unshared vertexes"))
intersectionDict = {
feat.geometry().asWkb(): feat for feat in intersectionLyr.getFeatures()
}
unsharedPointsSet = self.getUnsharedPointsSetFromPointsLyr(
- algRunner, pointsSet, linesLyr, context, multiStepFeedback)
- vertexSet = set(
- feat.geometry().asWkb() for feat in vertexLyr.getFeatures()
+ algRunner, pointsSet, linesLyr, context, multiStepFeedback
)
- return set(intersectionDict.keys()).difference(vertexSet) | unsharedPointsSet.difference(vertexSet)
-
- def getUnsharedPointsSetFromPointsLyr(self, algRunner, pointsSet, linesLyr, context, feedback):
+ vertexSet = set(feat.geometry().asWkb() for feat in vertexLyr.getFeatures())
+ return set(intersectionDict.keys()).difference(
+ vertexSet
+ ) | unsharedPointsSet.difference(vertexSet)
+
+ def getUnsharedPointsSetFromPointsLyr(
+ self, algRunner, pointsSet, linesLyr, context, feedback
+ ):
if pointsSet == set():
return set()
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
multiStepFeedback.setCurrentStep(0)
algRunner.runCreateSpatialIndex(linesLyr, context, feedback=multiStepFeedback)
multiStepFeedback.setCurrentStep(1)
+
def compute(feat):
geom = feat.geometry()
geomWkb = geom.asWkb()
@@ -1511,7 +1875,8 @@ def compute(feat):
if geom.equals(v):
return geomWkb
return None
- pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1)
+
+ pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1)
futures = set()
vertexSet = set()
for feat in pointsSet:
@@ -1520,13 +1885,21 @@ def compute(feat):
# if result is not None:
# vertexSet.add(result)
vertexSet = set(
- future.result() for future in concurrent.futures.as_completed(
- futures
- ) if future.result() is not None
+ future.result()
+ for future in concurrent.futures.as_completed(futures)
+ if future.result() is not None
)
return vertexSet
- def getLinesLayerFromPolygonsAndLinesLayers(self, inputLineLyrList, inputPolygonLyrList, algRunner=None, onlySelected=False, feedback=None, context=None):
+ def getLinesLayerFromPolygonsAndLinesLayers(
+ self,
+ inputLineLyrList,
+ inputPolygonLyrList,
+ algRunner=None,
+ onlySelected=False,
+ feedback=None,
+ context=None,
+ ):
"""
returns a merged line lyr
:param inputLineLyrList: (list of QgsVectorLayers) line layers to run build the aux structure.
@@ -1535,49 +1908,52 @@ def getLinesLayerFromPolygonsAndLinesLayers(self, inputLineLyrList, inputPolygon
"""
lineList = []
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
- nSteps = 2*len(inputLineLyrList) + 3*len(inputPolygonLyrList) + 1
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
+ nSteps = 2 * len(inputLineLyrList) + 3 * len(inputPolygonLyrList) + 1
multiStepFeedback = QgsProcessingMultiStepFeedback(
- nSteps, feedback) # set number of steps
+ nSteps, feedback
+ ) # set number of steps
currentStep = 0
- multiStepFeedback.pushInfo(self.tr('Converting lines to single part and exploding lines'))
+ multiStepFeedback.pushInfo(
+ self.tr("Converting lines to single part and exploding lines")
+ )
for lineLyr in inputLineLyrList:
multiStepFeedback.setCurrentStep(currentStep)
singlePartLyr = algRunner.runMultipartToSingleParts(
- inputLayer=lineLyr if not onlySelected \
+ inputLayer=lineLyr
+ if not onlySelected
else QgsProcessingFeatureSourceDefinition(lineLyr.id(), True),
context=context,
feedback=multiStepFeedback,
- is_child_algorithm=True
+ is_child_algorithm=True,
)
currentStep += 1
explodedLines = algRunner.runExplodeLines(
singlePartLyr,
context,
feedback=multiStepFeedback,
- is_child_algorithm=True
- )
- lineList.append(
- explodedLines
+ is_child_algorithm=True,
)
+ lineList.append(explodedLines)
currentStep += 1
- multiStepFeedback.pushInfo(self.tr('Converting polygons to single part and exploding lines'))
+ multiStepFeedback.pushInfo(
+ self.tr("Converting polygons to single part and exploding lines")
+ )
for polygonLyr in inputPolygonLyrList:
multiStepFeedback.setCurrentStep(currentStep)
usedInput = algRunner.runMultipartToSingleParts(
- inputLayer=polygonLyr if not onlySelected \
+ inputLayer=polygonLyr
+ if not onlySelected
else QgsProcessingFeatureSourceDefinition(polygonLyr.id(), True),
context=context,
feedback=multiStepFeedback,
- is_child_algorithm=True
+ is_child_algorithm=True,
)
currentStep += 1
convertedPolygons = algRunner.runPolygonsToLines(
- usedInput,
- context,
- feedback=multiStepFeedback,
- is_child_algorithm=True
+ usedInput, context, feedback=multiStepFeedback, is_child_algorithm=True
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
@@ -1585,17 +1961,21 @@ def getLinesLayerFromPolygonsAndLinesLayers(self, inputLineLyrList, inputPolygon
convertedPolygons,
context,
feedback=multiStepFeedback,
- is_child_algorithm=True
+ is_child_algorithm=True,
)
currentStep += 1
lineList.append(explodedLines)
# merge layers
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.pushInfo(self.tr('Adding exploded lines to one single layer.'))
- mergedLayer = algRunner.runMergeVectorLayers(
- lineList,
- context,
- feedback=multiStepFeedback
+ multiStepFeedback.pushInfo(
+ self.tr("Adding exploded lines to one single layer.")
+ )
+ mergedLayer = (
+ algRunner.runMergeVectorLayers(
+ lineList, context, feedback=multiStepFeedback
+ )
+ if lineList != []
+ else None
)
return mergedLayer
@@ -1610,7 +1990,14 @@ def reprojectLayer(self, layer, targetEpsg, output=None):
"""
return AlgRunner().runReprojectLayer(layer, targetEpsg, output)
- def getMergedLayer(self, inputLayerList, onlySelected=False, feedback=None, context=None, algRunner=None):
+ def getMergedLayer(
+ self,
+ inputLayerList,
+ onlySelected=False,
+ feedback=None,
+ context=None,
+ algRunner=None,
+ ):
"""
This does almost the same of createAndPopulateUnifiedVectorLayer, but it
is much faster. Maybe the implementation of createAndPopulateUnifiedVectorLayer
@@ -1618,77 +2005,84 @@ def getMergedLayer(self, inputLayerList, onlySelected=False, feedback=None, cont
"""
lyrList = []
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
nSteps = len(inputLayerList) + 1
multiStepFeedback = QgsProcessingMultiStepFeedback(
- nSteps, feedback) # set number of steps
+ nSteps, feedback
+ ) # set number of steps
currentStep = 0
for lyr in inputLayerList:
multiStepFeedback.setCurrentStep(currentStep)
lyrList.append(
- lyr if not onlySelected else algRunner.runSaveSelectedFeatures(
- lineLyr,
- context,
- feedback=multiStepFeedback
+ lyr
+ if not onlySelected
+ else algRunner.runSaveSelectedFeatures(
+ lyr, context, feedback=multiStepFeedback
)
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
return algRunner.runMergeVectorLayers(
- lyrList,
- context,
- feedback=multiStepFeedback
+ lyrList, context, feedback=multiStepFeedback
)
- def getCentroidsAndBoundariesFromPolygons(self, inputLyr, outputCenterPointSink, outputBoundarySink,
- constraintLineLyrList=None, constraintPolygonLyrList=None, context=None, feedback=None, algRunner=None):
+ def getCentroidsAndBoundariesFromPolygons(
+ self,
+ inputLyr,
+ outputCenterPointSink,
+ outputBoundarySink,
+ constraintLineLyrList=None,
+ constraintPolygonLyrList=None,
+ context=None,
+ feedback=None,
+ algRunner=None,
+ ):
"""
FILL out
"""
- constraintLineLyrList = [] if constraintLineLyrList is None else constraintLineLyrList
- constraintPolygonLyrList = [
- ] if constraintPolygonLyrList is None else constraintPolygonLyrList
+ constraintLineLyrList = (
+ [] if constraintLineLyrList is None else constraintLineLyrList
+ )
+ constraintPolygonLyrList = (
+ [] if constraintPolygonLyrList is None else constraintPolygonLyrList
+ )
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
- multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback)
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
+ )
+ multiStepFeedback = QgsProcessingMultiStepFeedback(8, feedback)
multiStepFeedback.setCurrentStep(0)
- multiStepFeedback.pushInfo(self.tr('Getting constraint lines'))
+ multiStepFeedback.pushInfo(self.tr("Getting constraint lines"))
linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers(
constraintLineLyrList,
constraintPolygonLyrList,
onlySelected=False,
feedback=multiStepFeedback,
context=context,
- algRunner=algRunner
+ algRunner=algRunner,
)
multiStepFeedback.setCurrentStep(1)
- multiStepFeedback.pushInfo(
- self.tr('Building auxiliar search structures'))
+ multiStepFeedback.pushInfo(self.tr("Building auxiliar search structures"))
constraintSpatialIdx, constraintIdDict = self.buildSpatialIndexAndIdDict(
- linesLyr,
- feedback=multiStepFeedback
+ linesLyr, feedback=multiStepFeedback
)
multiStepFeedback.setCurrentStep(2)
edgeLyr = algRunner.runPolygonsToLines(
- inputLyr,
- context,
- feedback=multiStepFeedback
+ inputLyr, context, feedback=multiStepFeedback
)
multiStepFeedback.setCurrentStep(3)
+ algRunner.runCreateSpatialIndex(edgeLyr, context, feedback=multiStepFeedback)
+ multiStepFeedback.setCurrentStep(4)
explodedEdges = algRunner.runExplodeLines(
- edgeLyr,
- context,
- feedback=multiStepFeedback
+ edgeLyr, context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(4)
+ multiStepFeedback.setCurrentStep(5)
explodedWithoutDuplicates = algRunner.runRemoveDuplicatedGeometries(
- explodedEdges,
- context,
- feedback=multiStepFeedback
+ explodedEdges, context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(5)
+ multiStepFeedback.setCurrentStep(6)
self.buildCenterPoints(
inputLyr,
outputCenterPointSink,
@@ -1696,104 +2090,231 @@ def getCentroidsAndBoundariesFromPolygons(self, inputLyr, outputCenterPointSink,
linesLyr,
feedback=multiStepFeedback,
context=context,
- algRunner=algRunner
+ algRunner=algRunner,
)
- multiStepFeedback.setCurrentStep(6)
+ multiStepFeedback.setCurrentStep(7)
self.filterEdges(
explodedWithoutDuplicates,
constraintSpatialIdx,
constraintIdDict,
outputBoundarySink,
feedback=multiStepFeedback,
- context=context
+ context=context,
)
- def buildCenterPoints(self, inputLyr, outputCenterPointSink, polygonBoundaryLyr,
- constraintLineLyr=None, context=None, feedback=None, algRunner=None):
- """
-
- """
+ def buildCenterPoints(
+ self,
+ inputLyr,
+ outputCenterPointSink,
+ context=None,
+ feedback=None,
+ algRunner=None,
+ ):
+ """ """
# 1- Merge line layers
# 2- Build polygons
# 3- Get center points from built polygons
# 4- Make spatial join of center points with original polygons to get attributes
algRunner = AlgRunner() if algRunner is None else algRunner
- context = dataobjects.createContext(
- feedback=feedback) if context is None else context
- multiStepFeedback = QgsProcessingMultiStepFeedback(6, feedback)
- multiStepFeedback.setCurrentStep(0)
- mergedLineLyr = polygonBoundaryLyr if constraintLineLyr is None\
- else algRunner.runMergeVectorLayers(
- [polygonBoundaryLyr, constraintLineLyr],
- context,
- feedback=multiStepFeedback
- )
- multiStepFeedback.setCurrentStep(1)
- splitSegmentsLyr = algRunner.runExplodeLines(
- mergedLineLyr,
- context,
- feedback=multiStepFeedback
+ context = (
+ dataobjects.createContext(feedback=feedback) if context is None else context
)
- multiStepFeedback.setCurrentStep(2)
- segmentsWithoutDuplicates = algRunner.runRemoveDuplicatedGeometries(
- splitSegmentsLyr,
- context,
- feedback=multiStepFeedback
- )
- multiStepFeedback.setCurrentStep(3)
+ multiStepFeedback = QgsProcessingMultiStepFeedback(3, feedback)
+ multiStepFeedback.setCurrentStep(0)
outputPolygonLyr = algRunner.runPolygonize(
- segmentsWithoutDuplicates,
- context,
- feedback=multiStepFeedback
+ inputLyr, context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(4)
+ multiStepFeedback.setCurrentStep(1)
centroidLyr = algRunner.runPointOnSurface(
- outputPolygonLyr,
- context,
- feedback=multiStepFeedback
+ outputPolygonLyr, context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(5)
+ multiStepFeedback.setCurrentStep(2)
centroidsWithAttributes = algRunner.runJoinAttributesByLocation(
- centroidLyr,
- inputLyr,
- context,
- feedback=multiStepFeedback
+ centroidLyr, inputLyr, context, feedback=multiStepFeedback
)
for feat in centroidsWithAttributes.getFeatures():
outputCenterPointSink.addFeature(feat, QgsFeatureSink.FastInsert)
- def filterEdges(self, inputLyr, constraintSpatialIdx, constraintIdDict,
- outputBoundarySink, context=None, feedback=None, algRunner=None):
- """
- """
+ def filterEdges(
+ self,
+ inputLyr,
+ constraintSpatialIdx,
+ constraintIdDict,
+ outputBoundarySink,
+ context=None,
+ feedback=None,
+ algRunner=None,
+ ):
+ """ """
notBoundarySet = set()
- stepSize = 100/inputLyr.featureCount()
- featList = [i for i in inputLyr.getFeatures()]
- for current, feat in enumerate(featList):
- if feedback is not None and feedback.isCanceled():
- break
+ nFeats = inputLyr.featureCount()
+ if nFeats == 0:
+ return
+ stepSize = 100 / nFeats
+ pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1)
+ futures = set()
+
+ def evaluate(feat):
+ outputSet = set()
featGeom = feat.geometry()
featBB = featGeom.boundingBox()
for candidateId in constraintSpatialIdx.intersects(featBB):
if featGeom.within(constraintIdDict[candidateId].geometry()):
- notBoundarySet.add(feat)
- break
- if feedback is not None:
- feedback.setProgress(current*stepSize)
- for feat in featList:
- if feat not in notBoundarySet:
+ outputSet.add(feat)
+ return outputSet
+ return outputSet
+
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(2, feedback)
+ if feedback is not None
+ else None
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(0)
+ multiStepFeedback.setProgressText(self.tr("Submitting tasks to thread"))
+
+ for current, feat in enumerate(inputLyr.getFeatures()):
+ if multiStepFeedback is not None and multiStepFeedback.isCanceled():
+ break
+ futures.add(pool.submit(evaluate, feat))
+ if multiStepFeedback is not None:
+ multiStepFeedback.setProgress(current * stepSize)
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(1)
+ multiStepFeedback.setProgressText(self.tr("Evaluating results"))
+ for current, future in enumerate(concurrent.futures.as_completed(futures)):
+ outputSet = future.result()
+ if outputSet == {}:
+ continue
+ for feat in outputSet:
+ if feat in notBoundarySet:
+ continue
outputBoundarySink.addFeature(feat, QgsFeatureSink.FastInsert)
+ if multiStepFeedback is not None:
+ multiStepFeedback.setProgress(current * stepSize)
+
+ def getPolygonsFromCenterPointsAndBoundariesAlt(
+ self,
+ inputCenterPointLyr,
+ constraintLineLyrList=None,
+ constraintPolygonLyrList=None,
+ attributeBlackList=None,
+ geographicBoundaryLyr=None,
+ onlySelected=False,
+ suppressPolygonWithoutCenterPointFlag=False,
+ context=None,
+ feedback=None,
+ algRunner=None,
+ ):
+ algRunner = AlgRunner() if algRunner is None else algRunner
+ constraintLineLyrList = (
+ [] if constraintLineLyrList is None else constraintLineLyrList
+ )
+ constraintPolygonList = (
+ [] if constraintPolygonLyrList is None else constraintPolygonLyrList
+ )
+ attributeBlackList = [] if attributeBlackList is None else attributeBlackList
+ constraintPolygonListWithGeoBounds = (
+ constraintPolygonList + [geographicBoundaryLyr]
+ if geographicBoundaryLyr is not None
+ else constraintPolygonList
+ )
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(8, feedback)
+ if feedback is not None
+ else None
+ )
+ currentStep = 0
+ if multiStepFeedback is not None:
+ multiStepFeedback.setProgressText(self.tr("Merging all into one layer..."))
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ constraintPolygonsAsPolygonsLyr = (
+ algRunner.runMergeVectorLayers(
+ inputList=constraintPolygonListWithGeoBounds,
+ context=context,
+ feedback=multiStepFeedback,
+ )
+ if len(constraintPolygonListWithGeoBounds) > 0
+ else None
+ )
+ currentStep += 1
+ constraintPolygonsAsLinesLyr = (
+ algRunner.runPolygonsToLines(
+ inputLyr=constraintPolygonsAsPolygonsLyr,
+ context=context,
+ feedback=multiStepFeedback,
+ )
+ if constraintPolygonsAsPolygonsLyr is not None
+ else None
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ allLinesLyr = algRunner.runMergeVectorLayers(
+ inputList=constraintLineLyrList + [constraintPolygonsAsLinesLyr]
+ if constraintPolygonsAsLinesLyr is not None
+ else constraintLineLyrList,
+ context=context,
+ feedback=multiStepFeedback,
+ )
+ currentStep += 1
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ multiStepFeedback.setProgressText(self.tr("Exploding lines..."))
+ explodedLines = algRunner.runExplodeLines(
+ inputLyr=allLinesLyr, context=context, feedback=multiStepFeedback
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ algRunner.runCreateSpatialIndex(explodedLines, context, multiStepFeedback)
+ currentStep += 1
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ multiStepFeedback.setProgressText(self.tr("Splitting lines..."))
+ splitLines = algRunner.runSplitLinesWithLines(
+ inputLyr=explodedLines,
+ linesLyr=explodedLines,
+ context=context,
+ feedback=multiStepFeedback,
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ multiStepFeedback.setProgressText(
+ self.tr("Starting the process of building polygons...")
+ )
+ builtPolygonLyr = algRunner.runPolygonize(
+ splitLines, context, feedback=multiStepFeedback
+ )
+ currentStep += 1
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ multiStepFeedback.setProgressText(
+ self.tr("Relating center points with built polygons...")
+ )
+ return self.relateCenterPointsWithPolygons(
+ inputCenterPointLyr,
+ builtPolygonLyr,
+ constraintPolygonList=constraintPolygonList,
+ geomBoundary=geographicBoundaryLyr,
+ attributeBlackList=attributeBlackList,
+ suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag,
+ context=context,
+ feedback=multiStepFeedback,
+ )
- def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr,
- constraintLineLyrList=None,
- constraintPolygonLyrList=None,
- attributeBlackList=None,
- geographicBoundaryLyr=None,
- onlySelected=False,
- suppressPolygonWithoutCenterPointFlag=False,
- context=None,
- feedback=None,
- algRunner=None):
+ def getPolygonsFromCenterPointsAndBoundaries(
+ self,
+ inputCenterPointLyr,
+ constraintLineLyrList=None,
+ constraintPolygonLyrList=None,
+ attributeBlackList=None,
+ geographicBoundaryLyr=None,
+ onlySelected=False,
+ suppressPolygonWithoutCenterPointFlag=False,
+ context=None,
+ feedback=None,
+ algRunner=None,
+ ):
"""
1. Merge Polygon lyrs into one and coerce polygons to lines
@@ -1813,12 +2334,13 @@ def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr,
:return polygonList, flagList: list of polygons (QgsFeature)
"""
algRunner = AlgRunner() if algRunner is None else algRunner
- constraintLineLyrList = [] if constraintLineLyrList is None else \
- constraintLineLyrList
- constraintPolygonList = [] if constraintPolygonLyrList is None else \
- constraintPolygonLyrList
- attributeBlackList = [] if attributeBlackList is None else \
- attributeBlackList
+ constraintLineLyrList = (
+ [] if constraintLineLyrList is None else constraintLineLyrList
+ )
+ constraintPolygonList = (
+ [] if constraintPolygonLyrList is None else constraintPolygonLyrList
+ )
+ attributeBlackList = [] if attributeBlackList is None else attributeBlackList
# Clip Points, Lines and Polygons according to geographicBoundaryLyr
# Buffer because sometimes the line stops before the boundary itself,
# making the whole algorithmn not work properly
@@ -1828,28 +2350,30 @@ def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr,
# for camada in constraintLineLyrList]
# constraintPolygonList = [algRunner.runClip(camada, limit, context)
# for camada in constraintPolygonLyrList]
- # inputCenterPointLyr = algRunner.runClip(inputCenterPointLyr, limit,
+ # inputCenterPointLyr = algRunner.runClip(inputCenterPointLyr, limit,
# context)
- constraintPolygonListWithGeoBounds = constraintPolygonList + \
- [geographicBoundaryLyr] if geographicBoundaryLyr is not None else \
- constraintPolygonList
- multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback)
+ constraintPolygonListWithGeoBounds = (
+ constraintPolygonList + [geographicBoundaryLyr]
+ if geographicBoundaryLyr is not None
+ else constraintPolygonList
+ )
+ multiStepFeedback = QgsProcessingMultiStepFeedback(8, feedback)
# 1. Merge Polygon lyrs into one
currentStep = 0
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.setProgressText(self.tr('Getting constraint lines...'))
+ multiStepFeedback.setProgressText(self.tr("Getting constraint lines..."))
linesLyr = self.getLinesLayerFromPolygonsAndLinesLayers(
constraintLineLyrList,
- constraintPolygonListWithGeoBounds,
+ constraintPolygonListWithGeoBounds,
onlySelected=onlySelected,
feedback=multiStepFeedback,
context=context,
- algRunner=algRunner
+ algRunner=algRunner,
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.setProgressText(self.tr('Exploding lines...'))
+ multiStepFeedback.setProgressText(self.tr("Exploding lines..."))
algRunner.runCreateSpatialIndex(linesLyr, context, feedback=multiStepFeedback)
currentStep += 1
@@ -1858,60 +2382,62 @@ def getPolygonsFromCenterPointsAndBoundaries(self, inputCenterPointLyr,
inputLyr=linesLyr,
linesLyr=linesLyr,
context=context,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
splitSegmentsLyr = algRunner.runExplodeLines(
- linesLyr,
- context,
- feedback=multiStepFeedback
+ linesLyr, context, feedback=multiStepFeedback
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.setProgressText(self.tr('Removing duplicated features...'))
+ multiStepFeedback.setProgressText(self.tr("Removing duplicated features..."))
segmentsWithoutDuplicates = algRunner.runRemoveDuplicatedGeometries(
- splitSegmentsLyr,
- context,
- feedback=multiStepFeedback
+ splitSegmentsLyr, context, feedback=multiStepFeedback
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.setProgressText(self.tr('Starting the process of building polygons...'))
+ multiStepFeedback.setProgressText(
+ self.tr("Starting the process of building polygons...")
+ )
builtPolygonLyr = algRunner.runPolygonize(
- segmentsWithoutDuplicates,
- context,
- feedback=multiStepFeedback
+ segmentsWithoutDuplicates, context, feedback=multiStepFeedback
)
currentStep += 1
multiStepFeedback.setCurrentStep(currentStep)
- multiStepFeedback.setProgressText(self.tr('Relating center points with built polygons...'))
+ multiStepFeedback.setProgressText(
+ self.tr("Relating center points with built polygons...")
+ )
return self.relateCenterPointsWithPolygons(
inputCenterPointLyr,
builtPolygonLyr,
constraintPolygonList=constraintPolygonList,
- geomBoundary = geographicBoundaryLyr,
+ geomBoundary=geographicBoundaryLyr,
attributeBlackList=attributeBlackList,
suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag,
context=context,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
- def relateCenterPointsWithPolygons(self,inputCenterPointLyr,
- builtPolygonLyr,context=None,
- constraintPolygonList=None,
- attributeBlackList=None,
- geomBoundary=None,
- suppressPolygonWithoutCenterPointFlag=False,
- feedback=None):
+ def relateCenterPointsWithPolygons(
+ self,
+ inputCenterPointLyr,
+ builtPolygonLyr,
+ context=None,
+ constraintPolygonList=None,
+ attributeBlackList=None,
+ geomBoundary=None,
+ suppressPolygonWithoutCenterPointFlag=False,
+ feedback=None,
+ ):
"""
1. Merge constraint polygon list;
2. Build search structure into constraint polygon list
3. Build structure relating center points to built polygons
4. Get built polygons with attributes and flags
- :params inputCenterPointLyr: (QgsVectorLayer) with Point which you
+ :params inputCenterPointLyr: (QgsVectorLayer) with Point which you
want to take the attr
:params builtPolygonLyr: (QgsVectorLayer) with the polygons
:params constraintPolygonList: (list) with the polygons, which area
@@ -1921,55 +2447,70 @@ def relateCenterPointsWithPolygons(self,inputCenterPointLyr,
:return polygonList, flagList: list of polygons (QgsFeature)
"""
nSteps = 4 if constraintPolygonList else 2
- multiStepFeedback = QgsProcessingMultiStepFeedback(nSteps, feedback)
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(nSteps, feedback)
+ if feedback is not None
+ else None
+ )
currentStep = 0
- multiStepFeedback.setCurrentStep(currentStep)
-
- # If there were no polygon list, it was breaking the method.
- # tried to solve it with this if else
+ algRunner = AlgRunner()
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+
+ # If there were no polygon list, it was breaking the method.
+ # tried to solve it with this if else
if constraintPolygonList:
- constraintPolygonLyr = self.algRunner.runMergeVectorLayers(
- constraintPolygonList,
- context,
- feedback=multiStepFeedback
+ constraintPolygonLyr = algRunner.runMergeVectorLayers(
+ constraintPolygonList, context, feedback=multiStepFeedback
)
currentStep += 1
- multiStepFeedback.setCurrentStep(currentStep)
- constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict = \
- self.buildSpatialIndexAndIdDict(
- constraintPolygonLyr,
- feedback=multiStepFeedback
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ (
+ constraintPolygonLyrSpatialIdx,
+ constraintPolygonLyrIdDict,
+ ) = self.buildSpatialIndexAndIdDict(
+ constraintPolygonLyr, feedback=multiStepFeedback
)
currentStep += 1
- else:
- constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict = \
- QgsSpatialIndex(), {}
- multiStepFeedback.setCurrentStep(currentStep)
+ else:
+ constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict = (
+ QgsSpatialIndex(),
+ {},
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
builtPolygonToCenterPointDict = self.buildCenterPolygonToCenterPointDict(
inputCenterPointLyr,
builtPolygonLyr,
attributeBlackList,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
currentStep += 1
- multiStepFeedback.setCurrentStep(currentStep)
- polygonList, flagList = \
- self.getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(currentStep)
+ (
+ polygonList,
+ flagList,
+ ) = self.getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
builtPolygonToCenterPointDict,
constraintPolygonLyrSpatialIdx,
constraintPolygonLyrIdDict,
- geomBoundary = geomBoundary,
+ geomBoundary=geomBoundary,
suppressPolygonWithoutCenterPointFlag=suppressPolygonWithoutCenterPointFlag,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
return polygonList, flagList
- def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr,
- builtPolygonLyr,
- attributeBlackList=None,
- feedback=None):
+ def buildCenterPolygonToCenterPointDict(
+ self,
+ inputCenterPointLyr,
+ builtPolygonLyr,
+ attributeBlackList=None,
+ feedback=None,
+ ):
"""
-
+
:params inputCenterPointLyr: (QgsVectorLayer) with Point which you want to take
the attr
:params builtPolygonLyr: (QgsVectorLayer) with the polygons
@@ -1982,13 +2523,14 @@ def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr,
}
"""
builtPolygonToCenterPointDict = dict()
- iterator, featCount = self.getFeatureList(
- builtPolygonLyr, onlySelected=False)
- size = 100/featCount if featCount else 0
+ iterator, featCount = self.getFeatureList(builtPolygonLyr, onlySelected=False)
+ size = 100 / featCount if featCount else 0
columns = self.getAttributesFromBlackList(
- inputCenterPointLyr, attributeBlackList=attributeBlackList)
+ inputCenterPointLyr, attributeBlackList=attributeBlackList
+ )
fields = self.getFieldsFromAttributeBlackList(
- inputCenterPointLyr, attributeBlackList)
+ inputCenterPointLyr, attributeBlackList
+ )
for current, feat in enumerate(builtPolygonLyr.getFeatures()):
if feedback is not None and feedback.isCanceled():
break
@@ -2001,11 +2543,11 @@ def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr,
request = QgsFeatureRequest().setFilterRect(featBB)
engine = QgsGeometry.createGeometryEngine(featGeom.constGet())
engine.prepareGeometry()
-
+
# for each point inside the polygon, extract attrkey and attr
- # attrkey is basically attr but in an string. therefore, if
+ # attrkey is basically attr but in an string. therefore, if
# if there two point with different attr, it will make two columns
- # with two attrkey different
+ # with two attrkey different
for pointFeat in inputCenterPointLyr.getFeatures(request):
if feedback is not None and feedback.isCanceled():
break
@@ -2019,18 +2561,16 @@ def buildCenterPolygonToCenterPointDict(self, inputCenterPointLyr,
feedback.setCurrentStep(current * size)
return builtPolygonToCenterPointDict
- def getFieldsFromAttributeBlackList(self, originalLayer,
- attributeBlackList):
+ def getFieldsFromAttributeBlackList(self, originalLayer, attributeBlackList):
"""
Create a QgsFields with only columns that are not at attributeBlackList
:params originalLayer: Layer from where will be taken the fields
- :params attributeBlackList: (list) which attr/fields should not
+ :params attributeBlackList: (list) which attr/fields should not
be considered
- :return fields: (QgsFields) with the fields necessary
+ :return fields: (QgsFields) with the fields necessary
"""
columns = self.getAttributesFromBlackList(
- originalLayer,
- attributeBlackList=attributeBlackList
+ originalLayer, attributeBlackList=attributeBlackList
)
fields = QgsFields()
for f in originalLayer.fields():
@@ -2046,15 +2586,19 @@ def getListIndexFromFields(self, originalLayer, columns):
:return listColumnAttr: (list) list of indexes
"""
listColumnAttr = []
- for column in columns:
- listColumnAttr.append(originalLayer.fields()\
- .indexFromName(column))
+ for column in columns:
+ listColumnAttr.append(originalLayer.fields().indexFromName(column))
return listColumnAttr
def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
- self, builtPolygonToCenterPointDict,
- constraintPolygonLyrSpatialIdx, constraintPolygonLyrIdDict,
- geomBoundary=False, suppressPolygonWithoutCenterPointFlag=True, feedback=None):
+ self,
+ builtPolygonToCenterPointDict,
+ constraintPolygonLyrSpatialIdx,
+ constraintPolygonLyrIdDict,
+ geomBoundary=False,
+ suppressPolygonWithoutCenterPointFlag=True,
+ feedback=None,
+ ):
"""
:params builtPolygonToCenterPointDict: (dict) in the following format:
{
@@ -2062,17 +2606,17 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
(attrKey) : [--QgsFields--]
}
}
- :params constraintPolygonLyrSpatialIdx :QgsSpatialIndex() of the
+ :params constraintPolygonLyrSpatialIdx :QgsSpatialIndex() of the
constraint polygons
- :params constraintPolygonLyrIdDict:
+ :params constraintPolygonLyrIdDict:
:params geomBoundary: (QgsVectorLayer) which delimitates the processing
:return polygonList, flagList: *list) of polygons (QgsFeature)
"""
keyCount = len(builtPolygonToCenterPointDict)
- size = 100/keyCount if keyCount else 0
+ size = 100 / keyCount if keyCount else 0
polygonList = []
flagDict = dict()
- # Create a list with geomBoundary polygons geometry
+ # Create a list with geomBoundary polygons geometry
if geomBoundary:
geoms = [f.geometry() for f in geomBoundary.getFeatures()]
for current, geomKey in enumerate(builtPolygonToCenterPointDict):
@@ -2085,15 +2629,14 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
pointOnSurfaceGeom = geom.pointOnSurface()
# only situation when boundary makes a difference is when it is
# provided and the polygon is not within any of its polygons
- isOffBoundary = geomBoundary is not None \
- and not any(
- (pointOnSurfaceGeom.intersects(boundaryGeom) \
- for boundaryGeom in geoms)
- )
+ isOffBoundary = geomBoundary is not None and not any(
+ (pointOnSurfaceGeom.intersects(boundaryGeom) for boundaryGeom in geoms)
+ )
if isOffBoundary:
continue
for candidateId in constraintPolygonLyrSpatialIdx.intersects(
- geom.boundingBox()):
+ geom.boundingBox()
+ ):
# this loop is broken by either user canceling it or built
# polygon overlapping any of the polygon constraints, which
# means that it will have its geometry ignored on the next
@@ -2103,15 +2646,16 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
break
isNotFlag = geomKey not in flagDict
isConstraintPol = pointOnSurfaceGeom.intersects(
- constraintPolygonLyrIdDict[candidateId].geometry())
+ constraintPolygonLyrIdDict[candidateId].geometry()
+ )
if isNotFlag and isConstraintPol:
break
else:
- # because builtPolygonToCenterPointDict[geomKey] is an
+ # because builtPolygonToCenterPointDict[geomKey] is an
# defaultdict, everytime that it appends a different set of
- # attr, it creates a new column. Therefore, when
+ # attr, it creates a new column. Therefore, when
# structureLen is 0, there is no attr, when is more than 1
- # it had two points with differents attr.
+ # it had two points with differents attr.
if structureLen == 1:
fields = list(builtPolygonToCenterPointDict[geomKey].values())
attr = list(builtPolygonToCenterPointDict[geomKey].keys())
@@ -2122,12 +2666,14 @@ def getPolygonListAndFlagDictFromBuiltPolygonToCenterPointDict(
else:
if structureLen == 0 and suppressPolygonWithoutCenterPointFlag:
continue
- flagText = self.tr("Polygon without center point.") \
- if structureLen == 0 \
+ flagText = (
+ self.tr("Polygon without center point.")
+ if structureLen == 0
else self.tr(
"Polygon with more than one center point with "
"conflicting attributes."
)
+ )
flagDict[geomKey] = flagText
if feedback is not None:
feedback.setCurrentStep(current * size)
@@ -2144,15 +2690,16 @@ def valueMaps(self, layer):
for field in layer.fields():
fieldName = field.name()
fieldConfig = field.editorWidgetSetup().config()
- if 'map' not in fieldConfig or fieldName in ('UseHtml', 'IsMultiline'):
+ if "map" not in fieldConfig or fieldName in ("UseHtml", "IsMultiline"):
continue
- if isinstance(fieldConfig['map'], list):
- for map_ in fieldConfig['map']:
+ if isinstance(fieldConfig["map"], list):
+ for map_ in fieldConfig["map"]:
if fieldName not in classFieldMap:
classFieldMap[fieldName] = map_
else:
classFieldMap[fieldName].update(map_)
else:
+
def intify(i):
try:
return int(i)
@@ -2161,10 +2708,10 @@ def intify(i):
def sortingMethod(item):
return intify(item[1])
+
classFieldMap[fieldName] = {
- k: intify(v) for k, v in sorted(
- fieldConfig['map'].items(), key=sortingMethod
- )
+ k: intify(v)
+ for k, v in sorted(fieldConfig["map"].items(), key=sortingMethod)
}
return classFieldMap
@@ -2186,7 +2733,8 @@ def getDefaultValues(self, layer):
return defaultValues
def getPolygonSlivers(
- self, layer, ratio, selected=False, silent=False, feedback=None):
+ self, layer, ratio, selected=False, silent=False, feedback=None
+ ):
"""
Identifies the polygon slivers for a given ratio area-perimeter
of a layer.
@@ -2204,18 +2752,16 @@ def getPolygonSlivers(
if not layer.geometryType() != QgsWkbTypes.PolygonGeometry:
Exception(self.tr("Input layer is not polygon."))
slivers = list()
- feats = list(layer.getSelectedFeatures() if selected \
- else layer.getFeatures())
+ feats = list(layer.getSelectedFeatures() if selected else layer.getFeatures())
stepSize = 100 / len(feats) if feats else 0
for step, f in enumerate(feats):
geom = f.geometry()
if geom.length() == 0 or not geom.isGeosValid():
if not silent:
- raise Exception(
- self.tr("Invalid or empty geometry found!"))
+ raise Exception(self.tr("Invalid or empty geometry found!"))
feedback.setProgress((step + 1) * stepSize)
continue
- if geom.area() / (geom.length())**2 < ratio:
+ if geom.area() / (geom.length()) ** 2 < ratio:
slivers.append(f)
if feedback is not None:
if feedback.isCanceled():
@@ -2223,7 +2769,13 @@ def getPolygonSlivers(
feedback.setProgress((step + 1) * stepSize)
return slivers
- def addVertexesToLayers(self, vertexLyr: QgsVectorLayer, layerList: List[QgsVectorLayer], searchRadius, feedback=None) -> None:
+ def addVertexesToLayers(
+ self,
+ vertexLyr: QgsVectorLayer,
+ layerList: List[QgsVectorLayer],
+ searchRadius,
+ feedback=None,
+ ) -> None:
nLayers = len(layerList)
if nLayers == 0:
return
@@ -2237,12 +2789,23 @@ def addVertexesToLayers(self, vertexLyr: QgsVectorLayer, layerList: List[QgsVect
multiStepFeedback.setCurrentStep(current)
if not vertexLyrExtent.intersects(lyr.extent()):
continue
- self.addVertexesToLayer(vertexLyr, lyr, searchRadius, feedback=multiStepFeedback)
+ self.addVertexesToLayer(
+ vertexLyr, lyr, searchRadius, feedback=multiStepFeedback
+ )
return
- def addVertexesToLayer(self, vertexLyr: QgsVectorLayer, layer: QgsVectorLayer, searchRadius, feedback=None) -> None:
- geomLambda = lambda x: self.geometryHandler.addVertexesToGeometry(vertexSet=x[0], geom=x[1])
+ def addVertexesToLayer(
+ self,
+ vertexLyr: QgsVectorLayer,
+ layer: QgsVectorLayer,
+ searchRadius,
+ feedback=None,
+ ) -> None:
+ geomLambda = lambda x: self.geometryHandler.addVertexesToGeometry(
+ vertexSet=x[0], geom=x[1]
+ )
changeGeometryLambda = lambda x: layer.changeGeometry(x.id(), x.geometry())
+
def evaluateAddVertex(feat):
if feedback.isCanceled():
return None
@@ -2260,12 +2823,13 @@ def evaluateAddVertex(feat):
newGeom = geomLambda([vertexSet, geom])
feat.setGeometry(newGeom)
return feat
+
featCount = layer.featureCount()
if featCount == 0:
return
- stepSize = 100/featCount
+ stepSize = 100 / featCount
futures = set()
- pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count()-1)
+ pool = concurrent.futures.ThreadPoolExecutor(max_workers=os.cpu_count() - 1)
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
multiStepFeedback.setCurrentStep(0)
multiStepFeedback.setCurrentStep(1)
@@ -2273,15 +2837,15 @@ def evaluateAddVertex(feat):
for current, feat in enumerate(layer.getFeatures()):
if multiStepFeedback.isCanceled():
return
- # futures.add(pool.submit(evaluateAddVertex, feat))
- # multiStepFeedback.setProgress(current * stepSize)
- # multiStepFeedback.setCurrentStep(1)
-
- # updateSet = set()
- # for current, future in enumerate(concurrent.futures.as_completed(futures)):
- # if multiStepFeedback.isCanceled():
- # return
- # outputFeat = future.result()
+ # futures.add(pool.submit(evaluateAddVertex, feat))
+ # multiStepFeedback.setProgress(current * stepSize)
+ # multiStepFeedback.setCurrentStep(1)
+
+ # updateSet = set()
+ # for current, future in enumerate(concurrent.futures.as_completed(futures)):
+ # if multiStepFeedback.isCanceled():
+ # return
+ # outputFeat = future.result()
outputFeat = evaluateAddVertex(feat)
if outputFeat is not None:
updateSet.add(outputFeat)
@@ -2290,6 +2854,45 @@ def evaluateAddVertex(feat):
if updateSet == set():
return
layer.startEditing()
- layer.beginEditCommand(self.tr('DsgTools adding missing vertexes'))
+ layer.beginEditCommand(self.tr("DsgTools adding missing vertexes"))
list(map(changeGeometryLambda, updateSet))
layer.endEditCommand()
+
+ def createMemoryLayerForEachFeature(
+ self, layer, context, returnFeature=False, feedback=None
+ ):
+ layerList = []
+ nFeats = layer.featureCount()
+ if nFeats == 0:
+ return layerList
+ stepSize = 100 / nFeats
+ for current, feat in enumerate(layer.getFeatures()):
+ if feedback is not None and feedback.isCanceled():
+ return layerList
+ temp = self.createMemoryLayerWithFeature(layer, feat, context)
+ item = (feat, temp) if returnFeature else temp
+ layerList.append(item)
+ if feedback is not None:
+ feedback.setProgress(current * stepSize)
+ return layerList
+
+ def createMemoryLayerWithFeature(self, layer, feat, context=None, isSource=False):
+ context = QgsProcessingContext() if context is None else context
+ crs = layer.crs() if not isSource else layer.sourceCrs()
+ temp_name = (
+ f"{layer.name()}-{str(uuid4())}" if not isSource else f"{str(uuid4())}"
+ )
+ temp = QgsVectorLayer(
+ f"{QgsWkbTypes.displayString(layer.wkbType())}?crs={crs.authid()}",
+ temp_name,
+ "memory",
+ )
+ temp_data = temp.dataProvider()
+ fields = layer.dataProvider().fields() if not isSource else layer.fields()
+ temp_data.addAttributes(fields.toList())
+ temp.updateFields()
+ temp_data.addFeature(feat)
+ self.algRunner.runCreateSpatialIndex(
+ inputLyr=temp, context=context, is_child_algorithm=True
+ )
+ return temp
diff --git a/DsgTools/core/GeometricTools/networkHandler.py b/DsgTools/core/GeometricTools/networkHandler.py
index c02d813eb..375a86884 100644
--- a/DsgTools/core/GeometricTools/networkHandler.py
+++ b/DsgTools/core/GeometricTools/networkHandler.py
@@ -27,20 +27,49 @@
from math import pi
from .geometryHandler import GeometryHandler
from .layerHandler import LayerHandler
-from qgis.core import QgsMessageLog, QgsVectorLayer, QgsGeometry, QgsField, \
- QgsVectorDataProvider, QgsFeatureRequest, QgsExpression, \
- QgsFeature, QgsSpatialIndex, Qgis, QgsCoordinateTransform, \
- QgsWkbTypes, QgsProject, QgsVertexId, Qgis, QgsCoordinateReferenceSystem,\
- QgsDataSourceUri, QgsFields, QgsProcessingMultiStepFeedback
+from qgis.core import (
+ QgsMessageLog,
+ QgsVectorLayer,
+ QgsGeometry,
+ QgsField,
+ QgsVectorDataProvider,
+ QgsFeatureRequest,
+ QgsExpression,
+ QgsFeature,
+ QgsSpatialIndex,
+ Qgis,
+ QgsCoordinateTransform,
+ QgsWkbTypes,
+ QgsProject,
+ QgsVertexId,
+ Qgis,
+ QgsCoordinateReferenceSystem,
+ QgsDataSourceUri,
+ QgsFields,
+ QgsProcessingMultiStepFeedback,
+)
from qgis.PyQt.Qt import QObject
from qgis.PyQt.QtCore import QVariant
+
class NetworkHandler(QObject):
- Flag, Sink, WaterwayBegin, UpHillNode, \
- DownHillNode, Confluence, Ramification, \
- AttributeChange, NodeNextToWaterBody, \
- AttributeChangeFlag, NodeOverload, DisconnectedLine, \
- DitchNode, SpillwayNode = list(range(14))
+ (
+ Flag,
+ Sink,
+ WaterwayBegin,
+ UpHillNode,
+ DownHillNode,
+ Confluence,
+ Ramification,
+ AttributeChange,
+ NodeNextToWaterBody,
+ AttributeChangeFlag,
+ NodeOverload,
+ DisconnectedLine,
+ DitchNode,
+ SpillwayNode,
+ ) = list(range(14))
+
def __init__(self):
super(NetworkHandler, self).__init__()
self.geometryHandler = GeometryHandler()
@@ -48,28 +77,32 @@ def __init__(self):
self.nodeDict = None
self.nodeTypeDict = None
self.nodeTypeNameDict = {
- NetworkHandler.Flag : self.tr("Flag"),#0
- NetworkHandler.Sink : self.tr("Sink"),#1
- NetworkHandler.WaterwayBegin : self.tr("Waterway Beginning"),#2
- NetworkHandler.UpHillNode : self.tr("Up Hill Node"),#3
- NetworkHandler.DownHillNode : self.tr("Down Hill Node"),#4
- NetworkHandler.Confluence : self.tr("Confluence"),#5
- NetworkHandler.Ramification : self.tr("Ramification"),#6
- NetworkHandler.AttributeChange : self.tr("Attribute Change Node"),#7
- NetworkHandler.NodeNextToWaterBody : self.tr("Node Next to Water Body"),#8
- NetworkHandler.AttributeChangeFlag : self.tr("Attribute Change Flag"),#9
- NetworkHandler.NodeOverload : self.tr("Overloaded Node"),#10
- NetworkHandler.DisconnectedLine : self.tr("Disconnected From Network"),#11
- NetworkHandler.DitchNode : self.tr("Node next to ditch"),#12
- NetworkHandler.SpillwayNode : self.tr("Spillway")
+ NetworkHandler.Flag: self.tr("Flag"), # 0
+ NetworkHandler.Sink: self.tr("Sink"), # 1
+ NetworkHandler.WaterwayBegin: self.tr("Waterway Beginning"), # 2
+ NetworkHandler.UpHillNode: self.tr("Up Hill Node"), # 3
+ NetworkHandler.DownHillNode: self.tr("Down Hill Node"), # 4
+ NetworkHandler.Confluence: self.tr("Confluence"), # 5
+ NetworkHandler.Ramification: self.tr("Ramification"), # 6
+ NetworkHandler.AttributeChange: self.tr("Attribute Change Node"), # 7
+ NetworkHandler.NodeNextToWaterBody: self.tr("Node Next to Water Body"), # 8
+ NetworkHandler.AttributeChangeFlag: self.tr("Attribute Change Flag"), # 9
+ NetworkHandler.NodeOverload: self.tr("Overloaded Node"), # 10
+ NetworkHandler.DisconnectedLine: self.tr("Disconnected From Network"), # 11
+ NetworkHandler.DitchNode: self.tr("Node next to ditch"), # 12
+ NetworkHandler.SpillwayNode: self.tr("Spillway"),
}
self.flagTextDict = {
- NetworkHandler.Flag : self.tr('Segments must be connected and with correct flow.'),
- NetworkHandler.AttributeChangeFlag : self.tr('Segments with same attribute set must be merged.'),
- NetworkHandler.DisconnectedLine : self.tr("Line disconnected From Network"),
- NetworkHandler.NodeOverload : self.tr("Node with flow problem")
+ NetworkHandler.Flag: self.tr(
+ "Segments must be connected and with correct flow."
+ ),
+ NetworkHandler.AttributeChangeFlag: self.tr(
+ "Segments with same attribute set must be merged."
+ ),
+ NetworkHandler.DisconnectedLine: self.tr("Line disconnected From Network"),
+ NetworkHandler.NodeOverload: self.tr("Node with flow problem"),
}
-
+
def identifyAllNodes(self, networkLayer, onlySelected=False, feedback=None):
"""
Identifies all nodes from a given layer (or selected features of it).
@@ -83,10 +116,18 @@ def identifyAllNodes(self, networkLayer, onlySelected=False, feedback=None):
}
"""
nodeDict = dict()
- isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType()))
- iterator = networkLayer.getFeatures() if not onlySelected else networkLayer.getSelectedFeatures()
- featCount = networkLayer.featureCount() if not onlySelected else networkLayer.selectedFeatureCount()
- size = 100/featCount if featCount else 0
+ isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType())
+ iterator = (
+ networkLayer.getFeatures()
+ if not onlySelected
+ else networkLayer.getSelectedFeatures()
+ )
+ featCount = (
+ networkLayer.featureCount()
+ if not onlySelected
+ else networkLayer.selectedFeatureCount()
+ )
+ size = 100 / featCount if featCount else 0
for current, feat in enumerate(iterator):
if feedback is not None and feedback.isCanceled():
break
@@ -95,26 +136,26 @@ def identifyAllNodes(self, networkLayer, onlySelected=False, feedback=None):
if isMulti:
if len(nodes) > 1:
# if feat is multipart and has more than one part, a flag should be raised
- continue # CHANGE TO RAISE FLAG
+ continue # CHANGE TO RAISE FLAG
elif len(nodes) == 0:
# if no part is found, skip feature
continue
else:
# if feat is multipart, "nodes" is a list of list
- nodes = nodes[0]
+ nodes = nodes[0]
# initial node
pInit, pEnd = nodes[0], nodes[-1]
# filling starting node information into dictionary
if pInit not in nodeDict:
# if the point is not already started into dictionary, it creates a new item
- nodeDict[pInit] = { 'start' : [], 'end' : [] }
- if feat not in nodeDict[pInit]['start']:
- nodeDict[pInit]['start'].append(feat)
+ nodeDict[pInit] = {"start": [], "end": []}
+ if feat not in nodeDict[pInit]["start"]:
+ nodeDict[pInit]["start"].append(feat)
# filling ending node information into dictionary
if pEnd not in nodeDict:
- nodeDict[pEnd] = { 'start' : [], 'end' : [] }
- if feat not in nodeDict[pEnd]['end']:
- nodeDict[pEnd]['end'].append(feat)
+ nodeDict[pEnd] = {"start": [], "end": []}
+ if feat not in nodeDict[pEnd]["end"]:
+ nodeDict[pEnd]["end"].append(feat)
if feedback is not None:
feedback.setProgress(size * current)
return nodeDict
@@ -125,12 +166,12 @@ def changeLineDict(self, nodeList, line):
identification is too costy.
:param nodeList: (list-of-QgsPoint) the list of nodes connected to have given line relation dictionary changed.
:param line: (QgsFeature) line to be flipped.
- :return: whether changing was successful for each node
+ :return: whether changing was successful for each node
"""
for node in nodeList:
# node's dicts
- startDict = self.nodeDict[node]['start']
- endDict = self.nodeDict[node]['end']
+ startDict = self.nodeDict[node]["start"]
+ endDict = self.nodeDict[node]["end"]
if line in startDict:
startDict.remove(line)
endDict.append(line)
@@ -161,24 +202,26 @@ def nodeOnFrame(self, node, frameLyrContourList, searchRadius):
return True
return False
- def nodeNextToWaterBodies(self, node, waterBodiesLayers, searchRadius, auxIndexStructure=None):
+ def nodeNextToWaterBodies(
+ self, node, waterBodiesLayers, searchRadius, auxIndexStructure=None
+ ):
"""
Identify whether or not node is next to a water body feature.
:param node: (QgsPoint) node to be identified as next to a water body feature.
:param waterBodiesLayers: (list-of-QgsVectorLayer) list of layers composing the water bodies on map.
:param searchRadius: (float) maximum distance to frame layer such that the feature is considered touching it.
:return: (bool) whether node is as close as searchRaius to a water body element.
- """
+ """
qgisPoint = QgsGeometry.fromPointXY(node)
# building a buffer around node with search radius for intersection with Layer Frame
buf = qgisPoint.buffer(searchRadius, -1)
# building bounding box around node for feature requesting
bbRect = buf.boundingBox()
# use aux spatial index if provided
- if auxIndexStructure is not None and 'waterBodiesLayers' in auxIndexStructure:
- for auxDict in auxIndexStructure['waterBodiesLayers']:
- for featid in auxDict['spatialIdx'].intersects(bbRect):
- if buf.intersects(auxDict['idDict'][featid].geometry()):
+ if auxIndexStructure is not None and "waterBodiesLayers" in auxIndexStructure:
+ for auxDict in auxIndexStructure["waterBodiesLayers"]:
+ for featid in auxDict["spatialIdx"].intersects(bbRect):
+ if buf.intersects(auxDict["idDict"][featid].geometry()):
# any feature component of a water body intersected is enough
return True
else:
@@ -192,7 +235,9 @@ def nodeNextToWaterBodies(self, node, waterBodiesLayers, searchRadius, auxIndexS
return True
return False
- def nodeIsWaterSink(self, node, waterSinkLayer, searchRadius, auxIndexStructure=None):
+ def nodeIsWaterSink(
+ self, node, waterSinkLayer, searchRadius, auxIndexStructure=None
+ ):
"""
Identify whether or not node is next to a water body feature. If no water sink layer is given, method returns False
:param node: (QgsPoint) node to be identified as coincident with a water sink feature.
@@ -205,9 +250,16 @@ def nodeIsWaterSink(self, node, waterSinkLayer, searchRadius, auxIndexStructure=
qgisPoint = QgsGeometry.fromPointXY(node)
# building bounding box around node for feature requesting
bbRect = qgisPoint.buffer(searchRadius, -1).boundingBox()
- if auxIndexStructure is not None and 'waterSinkLayer' in auxIndexStructure:
- for featid in auxIndexStructure['waterSinkLayer']['spatialIdx'].intersects(bbRect):
- if qgisPoint.distance(auxIndexStructure['waterSinkLayer']['idDict'][featid].geometry()) <= searchRadius:
+ if auxIndexStructure is not None and "waterSinkLayer" in auxIndexStructure:
+ for featid in auxIndexStructure["waterSinkLayer"]["spatialIdx"].intersects(
+ bbRect
+ ):
+ if (
+ qgisPoint.distance(
+ auxIndexStructure["waterSinkLayer"]["idDict"][featid].geometry()
+ )
+ <= searchRadius
+ ):
# any feature component of a water body intersected is enough
return True
else:
@@ -217,7 +269,7 @@ def nodeIsWaterSink(self, node, waterSinkLayer, searchRadius, auxIndexStructure=
# any feature component of a water body intersected is enough
return True
return False
-
+
def nodeIsSpillway(self, node, spillwayLayer, searchRadius, auxIndexStructure=None):
"""
Identify whether or not node is next to a water body feature. If no water sink layer is given, method returns False
@@ -231,9 +283,16 @@ def nodeIsSpillway(self, node, spillwayLayer, searchRadius, auxIndexStructure=No
qgisPoint = QgsGeometry.fromPointXY(node)
# building bounding box around node for feature requesting
bbRect = qgisPoint.buffer(searchRadius, -1).boundingBox()
- if auxIndexStructure is not None and 'spillwayLayer' in auxIndexStructure:
- for featid in auxIndexStructure['spillwayLayer']['spatialIdx'].intersects(bbRect):
- if qgisPoint.distance(auxIndexStructure['spillwayLayer']['idDict'][featid].geometry()) <= searchRadius:
+ if auxIndexStructure is not None and "spillwayLayer" in auxIndexStructure:
+ for featid in auxIndexStructure["spillwayLayer"]["spatialIdx"].intersects(
+ bbRect
+ ):
+ if (
+ qgisPoint.distance(
+ auxIndexStructure["spillwayLayer"]["idDict"][featid].geometry()
+ )
+ <= searchRadius
+ ):
# any feature component of a water body intersected is enough
return True
else:
@@ -258,7 +317,7 @@ def checkIfHasLineInsideWaterBody(self, node, waterBodiesLayers, searchRadius=No
# building bounding box around node for feature requesting
bbRect = buf.boundingBox()
# check if any wb feature inside of buffer area contains any ending line
- for line in self.nodeDict[node]['end']:
+ for line in self.nodeDict[node]["end"]:
for lyr in waterBodiesLayers:
for feat in lyr.getFeatures(QgsFeatureRequest(bbRect)):
if feat.geometry().contains(line.geometry()):
@@ -279,7 +338,7 @@ def getAttributesFromFeature(self, feature, layer, fieldList=None):
"""
# fields to be ignored
fieldList = [] if fieldList is None else fieldList
- return {field : feature[field] for field in fieldList}
+ return {field: feature[field] for field in fieldList}
def attributeChangeCheck(self, node, networkLayer, fieldList=None):
"""
@@ -289,14 +348,20 @@ def attributeChangeCheck(self, node, networkLayer, fieldList=None):
:return: (bool) if lines connected to node do change attributes.
"""
# assuming that attribute change nodes have only 1-in 1-out lines
- lineIn = self.nodeDict[node]['end'][0]
- atrLineIn = self.getAttributesFromFeature(feature=lineIn, layer=networkLayer, fieldList=fieldList)
- lineOut = self.nodeDict[node]['start'][0]
- atrLineOut = self.getAttributesFromFeature(feature=lineOut, layer=networkLayer, fieldList=fieldList)
+ lineIn = self.nodeDict[node]["end"][0]
+ atrLineIn = self.getAttributesFromFeature(
+ feature=lineIn, layer=networkLayer, fieldList=fieldList
+ )
+ lineOut = self.nodeDict[node]["start"][0]
+ atrLineOut = self.getAttributesFromFeature(
+ feature=lineOut, layer=networkLayer, fieldList=fieldList
+ )
# comparing their dictionary of attributes, it is decided whether they share the exact same set of attributes (fields and values)
return atrLineIn != atrLineOut
- def isFirstOrderDangle(self, node, networkLayer, searchRadius, auxIndexStructure=None):
+ def isFirstOrderDangle(
+ self, node, networkLayer, searchRadius, auxIndexStructure=None
+ ):
"""
Checks whether node is a dangle into network (connected to a first order line).
:param node: (QgsPoint) node to be validated.
@@ -309,13 +374,17 @@ def isFirstOrderDangle(self, node, networkLayer, searchRadius, auxIndexStructure
buf = qgisPoint.buffer(searchRadius, -1)
# building bounding box around node for feature requesting
bbRect = buf.boundingBox()
- if auxIndexStructure is not None and 'networkLayer' in auxIndexStructure:
+ if auxIndexStructure is not None and "networkLayer" in auxIndexStructure:
# check if buffer intersects features from water bodies layers
count = 0
- for featid in auxIndexStructure['networkLayer']['spatialIdx'].intersects(bbRect):
- if buf.intersects(auxIndexStructure['networkLayer']['idDict'][featid].geometry()):
+ for featid in auxIndexStructure["networkLayer"]["spatialIdx"].intersects(
+ bbRect
+ ):
+ if buf.intersects(
+ auxIndexStructure["networkLayer"]["idDict"][featid].geometry()
+ ):
count += 1
- res = (count > 1)
+ res = count > 1
if res:
# to avoid as many iterations as possible
return False
@@ -325,20 +394,22 @@ def isFirstOrderDangle(self, node, networkLayer, searchRadius, auxIndexStructure
for feat in networkLayer.getFeatures(QgsFeatureRequest(bbRect)):
if buf.intersects(feat.geometry()):
count += 1
- res = (count > 1)
+ res = count > 1
if res:
# to avoid as many iterations as possible
return False
return True
- def checkIfLineIsDisconnected(self, node, networkLayer, nodeTypeDict, geomType=None):
+ def checkIfLineIsDisconnected(
+ self, node, networkLayer, nodeTypeDict, geomType=None
+ ):
"""
Checks whether a waterway beginning node connected to a line disconnected from network.
:param node: (QgsPoint) point to be classified.
:param networkLayer: (QgsVectorLayer) network lines layer.
:param nodeTypeDict: (dict) all current classified nodes and theirs types.
:param geomType: (int) network layer geometry type code.
- :return: (bool) whether node is connected to a disconnected line
+ :return: (bool) whether node is connected to a disconnected line
"""
if not nodeTypeDict:
# if there are no classified nodes, method is ineffective
@@ -349,22 +420,24 @@ def checkIfLineIsDisconnected(self, node, networkLayer, nodeTypeDict, geomType=N
nextNodes = []
# to reduce calculation time
nodePointDict = self.nodeDict[node]
- isMulti = QgsWkbTypes.isMultiType(int(networkLayer.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(networkLayer.wkbType())
# get all other nodes connected to lines connected to "node"
- lines = nodePointDict['start'] + nodePointDict['end']
+ lines = nodePointDict["start"] + nodePointDict["end"]
if len(lines) > 1:
# if there is at least one more line connected to node, line is not disconnected
return False
# get line nodes
- n = self.geometryHandler.getFeatureNodes(layer=networkLayer, feature=lines[0], geomType=geomType)
- if nodePointDict['start']:
+ n = self.geometryHandler.getFeatureNodes(
+ layer=networkLayer, feature=lines[0], geomType=geomType
+ )
+ if nodePointDict["start"]:
# if line starts at target node, the other extremity is a final node
if isMulti:
if n is not None:
n = n[0][-1]
elif n is not None:
n = n[-1]
- elif nodePointDict['end']:
+ elif nodePointDict["end"]:
# if line starts at target node, the other extremity is a initial node
if isMulti:
if n is not None:
@@ -375,15 +448,20 @@ def checkIfLineIsDisconnected(self, node, networkLayer, nodeTypeDict, geomType=N
# validEnds = [NetworkHandler.Sink, NetworkHandler.DownHillNode, NetworkHandler.NodeNextToWaterBody]
if n in nodeTypeDict:
# if both ends are classified as waterway beginning, then both ends are 1st order dangles and line is disconnected.
- return nodeTypeDict[n] in [NetworkHandler.WaterwayBegin, NetworkHandler.DownHillNode, NetworkHandler.UpHillNode, NetworkHandler.NodeNextToWaterBody]
+ return nodeTypeDict[n] in [
+ NetworkHandler.WaterwayBegin,
+ NetworkHandler.DownHillNode,
+ NetworkHandler.UpHillNode,
+ NetworkHandler.NodeNextToWaterBody,
+ ]
# if nodeTypeDict[n] not in validEnds:
# if self.isFirstOrderDangle(node=n, networkLayer=networkLayer, searchRadius=self.parameters[self.tr('Search Radius')]):
- # # if next node is not a valid network ending node and is a dangle, line is disconnected from network
+ # # if next node is not a valid network ending node and is a dangle, line is disconnected from network
# return False
# return True
# in case next node is not yet classified, method is ineffective
return False
-
+
def isNodeNextToDitch(self, node, ditchLayer, searchRadius, auxIndexStructure=None):
"""
Checks if node is next to a ditch.
@@ -399,9 +477,13 @@ def isNodeNextToDitch(self, node, ditchLayer, searchRadius, auxIndexStructure=No
buf = qgisPoint.buffer(searchRadius, -1)
# building bounding box around node for feature requesting
bbRect = buf.boundingBox()
- if auxIndexStructure is not None and 'ditchLayer' in auxIndexStructure:
- for featid in auxIndexStructure['ditchLayer']['spatialIdx'].intersects(bbRect):
- if buf.intersects(auxIndexStructure['ditchLayer']['idDict'][featid].geometry()):
+ if auxIndexStructure is not None and "ditchLayer" in auxIndexStructure:
+ for featid in auxIndexStructure["ditchLayer"]["spatialIdx"].intersects(
+ bbRect
+ ):
+ if buf.intersects(
+ auxIndexStructure["ditchLayer"]["idDict"][featid].geometry()
+ ):
# any feature component of a water body intersected is enough
return True
else:
@@ -412,9 +494,21 @@ def isNodeNextToDitch(self, node, ditchLayer, searchRadius, auxIndexStructure=No
return True
return False
- def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLayers,\
- searchRadius, nodeTypeDict, waterSinkLayer=None, spillwayLayer=None,\
- networkLayerGeomType=None, fieldList=None, ditchLayer=None, auxIndexStructure=None):
+ def nodeType(
+ self,
+ nodePoint,
+ networkLayer,
+ frameLyrContourList,
+ waterBodiesLayers,
+ searchRadius,
+ nodeTypeDict,
+ waterSinkLayer=None,
+ spillwayLayer=None,
+ networkLayerGeomType=None,
+ fieldList=None,
+ ditchLayer=None,
+ auxIndexStructure=None,
+ ):
"""
Get the node type given all lines that flows from/to it.
:param nodePoint: (QgsPoint) point to be classified.
@@ -431,21 +525,25 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye
auxIndexStructure = {} if auxIndexStructure is None else auxIndexStructure
# to reduce calculation time in expense of memory, which is cheap
nodePointDict = self.nodeDict[nodePoint]
- sizeFlowOut = len(nodePointDict['start'])
- sizeFlowIn = len(nodePointDict['end'])
+ sizeFlowOut = len(nodePointDict["start"])
+ sizeFlowIn = len(nodePointDict["end"])
hasStartLine = bool(sizeFlowOut)
hasEndLine = bool(sizeFlowIn)
if not networkLayerGeomType:
networkLayerGeomType = networkLayer.geometryType()
# "exclusive or"
- startXORendLine = (hasStartLine != hasEndLine)
+ startXORendLine = hasStartLine != hasEndLine
# # case 5: more than 3 lines flowing through one network line (it is forbidden as of Brazilian mapping norm EDGV)
# if sizeFlowIn + sizeFlowOut > 3:
# return NetworkHandler.NodeOverload
- # case 1: all lines either flow in or out
+ # case 1: all lines either flow in or out
if startXORendLine:
# case 1.a: point is over the frame
- if self.nodeOnFrame(node=nodePoint, frameLyrContourList=frameLyrContourList, searchRadius=searchRadius):
+ if self.nodeOnFrame(
+ node=nodePoint,
+ frameLyrContourList=frameLyrContourList,
+ searchRadius=searchRadius,
+ ):
# case 1.a.i: waterway is flowing away from mapped area (point over the frame has one line ending line)
if hasEndLine:
return NetworkHandler.DownHillNode
@@ -455,41 +553,96 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye
# case 1.b: point that legitimately only flows from
elif hasEndLine:
# case 1.b.i
- if self.nodeNextToWaterBodies(node=nodePoint, waterBodiesLayers=waterBodiesLayers, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ if self.nodeNextToWaterBodies(
+ node=nodePoint,
+ waterBodiesLayers=waterBodiesLayers,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# it is considered that every free node on map is a starting node. The only valid exceptions are nodes that are
# next to water bodies and water sink holes.
if sizeFlowIn == 1:
# a node next to water has to be a lose end
return NetworkHandler.NodeNextToWaterBody
# force all lose ends to be waterway beginnings if they're not dangles (which are flags)
- elif self.isFirstOrderDangle(node=nodePoint, networkLayer=networkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
- if self.isNodeNextToDitch(node=nodePoint, ditchLayer=ditchLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ elif self.isFirstOrderDangle(
+ node=nodePoint,
+ networkLayer=networkLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
+ if self.isNodeNextToDitch(
+ node=nodePoint,
+ ditchLayer=ditchLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# if point is not disconnected and is connected to a ditch
return NetworkHandler.DitchNode
# check if node is connected to a disconnected line
- elif self.checkIfLineIsDisconnected(node=nodePoint, networkLayer=networkLayer, nodeTypeDict=nodeTypeDict, geomType=networkLayerGeomType):
+ elif self.checkIfLineIsDisconnected(
+ node=nodePoint,
+ networkLayer=networkLayer,
+ nodeTypeDict=nodeTypeDict,
+ geomType=networkLayerGeomType,
+ ):
return NetworkHandler.DisconnectedLine
# case 1.b.ii: node is in fact a water sink and should be able to take an 'in' flow
- elif self.nodeIsWaterSink(node=nodePoint, waterSinkLayer=waterSinkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ elif self.nodeIsWaterSink(
+ node=nodePoint,
+ waterSinkLayer=waterSinkLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# if a node is indeed a water sink (operator has set it to a sink)
return NetworkHandler.Sink
- elif self.nodeIsSpillway(node=nodePoint, spillwayLayer=spillwayLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ elif self.nodeIsSpillway(
+ node=nodePoint,
+ spillwayLayer=spillwayLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# if node is a spillway
return NetworkHandler.SpillwayNode
return NetworkHandler.WaterwayBegin
# case 1.c: point that legitimately only flows out
- elif hasStartLine and self.isFirstOrderDangle(node=nodePoint, networkLayer=networkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
- if self.isNodeNextToDitch(node=nodePoint, ditchLayer=ditchLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ elif hasStartLine and self.isFirstOrderDangle(
+ node=nodePoint,
+ networkLayer=networkLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
+ if self.isNodeNextToDitch(
+ node=nodePoint,
+ ditchLayer=ditchLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# if point is not disconnected and is connected to a ditch
return NetworkHandler.DitchNode
- elif self.checkIfLineIsDisconnected(node=nodePoint, networkLayer=networkLayer, nodeTypeDict=nodeTypeDict, geomType=networkLayerGeomType):
+ elif self.checkIfLineIsDisconnected(
+ node=nodePoint,
+ networkLayer=networkLayer,
+ nodeTypeDict=nodeTypeDict,
+ geomType=networkLayerGeomType,
+ ):
return NetworkHandler.DisconnectedLine
- elif self.nodeIsWaterSink(node=nodePoint, waterSinkLayer=waterSinkLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ elif self.nodeIsWaterSink(
+ node=nodePoint,
+ waterSinkLayer=waterSinkLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# in case there's a wrongly acquired line connected to a water sink
return NetworkHandler.Sink
- elif self.nodeIsSpillway(node=nodePoint, spillwayLayer=spillwayLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
- # if node is a spillway
- return NetworkHandler.SpillwayNode
+ elif self.nodeIsSpillway(
+ node=nodePoint,
+ spillwayLayer=spillwayLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
+ # if node is a spillway
+ return NetworkHandler.SpillwayNode
return NetworkHandler.WaterwayBegin
# case 1.d: points that are not supposed to have one way flow (flags)
return NetworkHandler.Flag
@@ -500,10 +653,17 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye
if sizeFlowIn > 1:
# case 4.a: there's a constant flow through node, but there are more than 1 line
return NetworkHandler.NodeOverload
- elif self.attributeChangeCheck(node=nodePoint, networkLayer=networkLayer, fieldList=fieldList):
+ elif self.attributeChangeCheck(
+ node=nodePoint, networkLayer=networkLayer, fieldList=fieldList
+ ):
# case 4.b: lines do change their attribute set. Must use fieldList due to black list items.
return NetworkHandler.AttributeChange
- elif self.isNodeNextToDitch(node=nodePoint, ditchLayer=ditchLayer, searchRadius=searchRadius, auxIndexStructure=auxIndexStructure):
+ elif self.isNodeNextToDitch(
+ node=nodePoint,
+ ditchLayer=ditchLayer,
+ searchRadius=searchRadius,
+ auxIndexStructure=auxIndexStructure,
+ ):
# case 4.c: lines next to ditches.
return NetworkHandler.DitchNode
else:
@@ -514,26 +674,42 @@ def nodeType(self, nodePoint, networkLayer, frameLyrContourList, waterBodiesLaye
# case 3 "ramification"
return NetworkHandler.Ramification
- def classifyAllNodes(self, networkLayer, frameLyrContourList, waterBodiesLayers, searchRadius, waterSinkLayer=None, spillwayLayer=None, nodeList=None, feedback=None, attributeBlackList=None, ignoreVirtualFields=True, excludePrimaryKeys=True, ditchLayer=None):
+ def classifyAllNodes(
+ self,
+ networkLayer,
+ frameLyrContourList,
+ waterBodiesLayers,
+ searchRadius,
+ waterSinkLayer=None,
+ spillwayLayer=None,
+ nodeList=None,
+ feedback=None,
+ attributeBlackList=None,
+ ignoreVirtualFields=True,
+ excludePrimaryKeys=True,
+ ditchLayer=None,
+ ):
"""
Classifies all identified nodes from the hidrography line layer.
:param networkLayer: (QgsVectorLayer) network lines layer.
:param frameLyrContourList: (list-of-QgsFeature) border line for the frame layer.
:param waterBodiesLayers: (list-of-QgsVectorLayer) list of all classes with water bodies to be compared to.
:param searchRadius: (float) maximum distance to frame layer such that the feature is considered touching it.
- :param nodeList: a list of nodes (QgsPoint) to be classified. If not given, whole dict is going
+ :param nodeList: a list of nodes (QgsPoint) to be classified. If not given, whole dict is going
to be classified. Node MUST be in dict given, if not, it'll be ignored.
:param waterSinkLayer: (QgsVectorLayer) water sink layer.
:param ditchLayer: (QgsVectorLayer) ditch layer.
- :return: a (dict) dictionary of node and its node type ( { (QgsPoint)node : (int)nodeType } ).
+ :return: a (dict) dictionary of node and its node type ( { (QgsPoint)node : (int)nodeType } ).
"""
networkLayerGeomType = networkLayer.geometryType()
nodeTypeDict = dict()
flagNodeDict = dict()
- fieldList = self.layerHandler.getAttributesFromBlackList(networkLayer, \
- attributeBlackList=attributeBlackList,\
- ignoreVirtualFields=ignoreVirtualFields,\
- excludePrimaryKeys=excludePrimaryKeys)
+ fieldList = self.layerHandler.getAttributesFromBlackList(
+ networkLayer,
+ attributeBlackList=attributeBlackList,
+ ignoreVirtualFields=ignoreVirtualFields,
+ excludePrimaryKeys=excludePrimaryKeys,
+ )
if feedback is not None:
multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
multiStepFeedback.setCurrentStep(0)
@@ -543,9 +719,10 @@ def classifyAllNodes(self, networkLayer, frameLyrContourList, waterBodiesLayers,
spillwayLayer=spillwayLayer,
waterSinkLayer=waterSinkLayer,
ditchLayer=ditchLayer,
- feedback=multiStepFeedback)
+ feedback=multiStepFeedback,
+ )
nodeCount = len(self.nodeDict)
- size = 100/nodeCount if nodeCount else 0
+ size = 100 / nodeCount if nodeCount else 0
if feedback is not None:
multiStepFeedback.setCurrentStep(1)
for current, node in enumerate(self.nodeDict):
@@ -566,16 +743,24 @@ def classifyAllNodes(self, networkLayer, frameLyrContourList, waterBodiesLayers,
networkLayerGeomType=networkLayerGeomType,
fieldList=fieldList,
ditchLayer=ditchLayer,
- auxIndexStructure=auxIndexStructure
- )
+ auxIndexStructure=auxIndexStructure,
+ )
nodeTypeDict[node] = nodeClassification
if nodeClassification in self.flagTextDict:
flagNodeDict[node] = self.flagTextDict[nodeClassification]
if multiStepFeedback is not None:
multiStepFeedback.setProgress(size * current)
return nodeTypeDict, flagNodeDict
-
- def getAuxIndexStructure(self, networkLayer, waterBodiesLayers=None, waterSinkLayer=None, spillwayLayer=None, ditchLayer=None, feedback=None):
+
+ def getAuxIndexStructure(
+ self,
+ networkLayer,
+ waterBodiesLayers=None,
+ waterSinkLayer=None,
+ spillwayLayer=None,
+ ditchLayer=None,
+ feedback=None,
+ ):
auxStructDict = dict()
steps = 1
if waterBodiesLayers is not None:
@@ -587,30 +772,48 @@ def getAuxIndexStructure(self, networkLayer, waterBodiesLayers=None, waterSinkLa
multiStepFeedback = QgsProcessingMultiStepFeedback(steps, feedback)
currStep = 0
multiStepFeedback.setCurrentStep(currStep)
- spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(networkLayer, feedback=multiStepFeedback)
- auxStructDict['networkLayer']={'spatialIdx':spatialIdx, 'idDict':idDict}
+ spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(
+ networkLayer, feedback=multiStepFeedback
+ )
+ auxStructDict["networkLayer"] = {"spatialIdx": spatialIdx, "idDict": idDict}
currStep += 1
if waterBodiesLayers is not None:
- auxStructDict['waterBodies'] = []
+ auxStructDict["waterBodies"] = []
multiStepFeedback.setCurrentStep(currStep)
for lyr in waterBodiesLayers:
- spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(lyr, feedback=multiStepFeedback)
- auxStructDict['waterBodies'].append({'spatialIdx':spatialIdx, 'idDict':idDict})
+ spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(
+ lyr, feedback=multiStepFeedback
+ )
+ auxStructDict["waterBodies"].append(
+ {"spatialIdx": spatialIdx, "idDict": idDict}
+ )
currStep += 1
if waterSinkLayer is not None:
multiStepFeedback.setCurrentStep(currStep)
- spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(waterSinkLayer, feedback=multiStepFeedback)
- auxStructDict['waterSinkLayer'] = {'spatialIdx':spatialIdx, 'idDict':idDict}
+ spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(
+ waterSinkLayer, feedback=multiStepFeedback
+ )
+ auxStructDict["waterSinkLayer"] = {
+ "spatialIdx": spatialIdx,
+ "idDict": idDict,
+ }
currStep += 1
if spillwayLayer is not None:
multiStepFeedback.setCurrentStep(currStep)
- spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(spillwayLayer, feedback=multiStepFeedback)
- auxStructDict['spillwayLayer'] = {'spatialIdx':spatialIdx, 'idDict':idDict}
+ spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(
+ spillwayLayer, feedback=multiStepFeedback
+ )
+ auxStructDict["spillwayLayer"] = {
+ "spatialIdx": spatialIdx,
+ "idDict": idDict,
+ }
currStep += 1
if ditchLayer is not None:
multiStepFeedback.setCurrentStep(currStep)
- spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(ditchLayer, feedback=multiStepFeedback)
- auxStructDict['ditchLayer'] = {'spatialIdx':spatialIdx, 'idDict':idDict}
+ spatialIdx, idDict = self.layerHandler.buildSpatialIndexAndIdDict(
+ ditchLayer, feedback=multiStepFeedback
+ )
+ auxStructDict["ditchLayer"] = {"spatialIdx": spatialIdx, "idDict": idDict}
currStep += 1
return auxStructDict
@@ -621,7 +824,7 @@ def clearHidNodeLayer(self, nodeLayer, nodeIdList=None, commitToLayer=False):
:param nodeIdList: (list-of-int) list of node IDs to be cleared from layer.
:param commitToLayer: (bool) indicates whether changes should be commited to layer.
"""
- nodeLayer.beginEditCommand('Clear Nodes')
+ nodeLayer.beginEditCommand("Clear Nodes")
if not nodeIdList:
nodeIdList = [feat.id() for feat in nodeLayer.getFeatures()]
nodeLayer.deleteFeatures(nodeIdList)
@@ -641,7 +844,7 @@ def fillNodeLayer(self, nodeLayer, networkLineLayerName, commitToLayer=False):
self.clearHidNodeLayer(nodeLayer=nodeLayer, commitToLayer=commitToLayer)
# get fields from layer in order to create new feature with the same attribute map
fields = nodeLayer.fields()
- nodeLayer.beginEditCommand('Create Nodes')
+ nodeLayer.beginEditCommand("Create Nodes")
# to avoid unnecessary calculation inside loop
nodeTypeKeys = self.nodeTypeDict.keys()
# initiate new features list
@@ -651,8 +854,10 @@ def fillNodeLayer(self, nodeLayer, networkLineLayerName, commitToLayer=False):
feat = QgsFeature(fields)
# set geometry
feat.setGeometry(QgsGeometry.fromMultiPointXY([node]))
- feat['node_type'] = self.nodeTypeDict[node] if node in nodeTypeKeys else None
- feat['layer'] = networkLineLayerName
+ feat["node_type"] = (
+ self.nodeTypeDict[node] if node in nodeTypeKeys else None
+ )
+ feat["layer"] = networkLineLayerName
featList.append(feat)
nodeLayer.addFeatures(featList)
nodeLayer.endEditCommand()
@@ -667,8 +872,10 @@ def getFirstNode(self, lyr, feat, geomType=None):
:param geomType: (int) layer geometry type (1 for lines).
:return: starting node point (QgsPoint).
"""
- n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ n = self.geometryHandler.getFeatureNodes(
+ layer=lyr, feature=feat, geomType=geomType
+ )
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -684,8 +891,10 @@ def getSecondNode(self, lyr, feat, geomType=None):
:param geomType: (int) layer geometry type (1 for lines).
:return: starting node point (QgsPoint).
"""
- n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ n = self.geometryHandler.getFeatureNodes(
+ layer=lyr, feature=feat, geomType=geomType
+ )
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
# process doesn't treat multipart features that does have more than 1 part
@@ -702,8 +911,10 @@ def getPenultNode(self, lyr, feat, geomType=None):
:param geomType: (int) layer geometry type (1 for lines).
:return: ending node point (QgsPoint).
"""
- n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ n = self.geometryHandler.getFeatureNodes(
+ layer=lyr, feature=feat, geomType=geomType
+ )
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -719,8 +930,10 @@ def getLastNode(self, lyr, feat, geomType=None):
:param geomType: (int) layer geometry type (1 for lines).
:return: ending node point (QgsPoint).
"""
- n = self.geometryHandler.getFeatureNodes(layer=lyr, feature=feat, geomType=geomType)
- isMulti = QgsWkbTypes.isMultiType(int(lyr.wkbType()))
+ n = self.geometryHandler.getFeatureNodes(
+ layer=lyr, feature=feat, geomType=geomType
+ )
+ isMulti = QgsWkbTypes.isMultiType(lyr.wkbType())
if isMulti:
if len(n) > 1:
return
@@ -730,15 +943,17 @@ def getLastNode(self, lyr, feat, geomType=None):
def calculateAngleDifferences(self, startNode, endNode):
"""
- Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over
+ Calculates the angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over
starting node.
:param startNode: node (QgsPoint) reference for line and angle calculation.
:param endNode: ending node (QgsPoint) for (segment of) line of which angle is required.
:return: (float) angle in degrees formed between line direction ('startNode' -> 'endNode') and vertical passing over 'startNode'
"""
# the returned angle is measured regarding 'y-axis', with + counter clockwise and -, clockwise.
- # Then angle is ALWAYS 180 - ang
- return 180 - math.degrees(math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y()))
+ # Then angle is ALWAYS 180 - ang
+ return 180 - math.degrees(
+ math.atan2(endNode.x() - startNode.x(), endNode.y() - startNode.y())
+ )
def calculateAzimuthFromNode(self, node, networkLayer, geomType=None):
"""
@@ -752,17 +967,19 @@ def calculateAzimuthFromNode(self, node, networkLayer, geomType=None):
geomType = networkLayer.geometryType()
nodePointDict = self.nodeDict[node]
azimuthDict = dict()
- for line in nodePointDict['start']:
+ for line in nodePointDict["start"]:
# if line starts at node, then angle calculate is already azimuth
endNode = self.getSecondNode(lyr=networkLayer, feat=line, geomType=geomType)
azimuthDict[line] = node.azimuth(endNode)
- for line in nodePointDict['end']:
+ for line in nodePointDict["end"]:
# if line ends at node, angle must be adapted in order to get azimuth
endNode = self.getPenultNode(lyr=networkLayer, feat=line, geomType=geomType)
azimuthDict[line] = node.azimuth(endNode)
return azimuthDict
- def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=None):
+ def checkLineDirectionConcordance(
+ self, line_a, line_b, networkLayer, geomType=None
+ ):
"""
Given two lines, this method checks whether lines flow to/from the same node or not.
If they do not have a common node, method returns false.
@@ -779,9 +996,11 @@ def checkLineDirectionConcordance(self, line_a, line_b, networkLayer, geomType=N
fn_b = self.getFirstNode(lyr=networkLayer, feat=line_b, geomType=geomType)
ln_b = self.getLastNode(lyr=networkLayer, feat=line_b, geomType=geomType)
# if lines are flowing to/from the same node (they are flowing the same way)
- return (fn_a == fn_b or ln_a == ln_b)
+ return fn_a == fn_b or ln_a == ln_b
- def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomType=None):
+ def validateDeltaLinesAngV2(
+ self, node, networkLayer, connectedValidLines, geomType=None
+ ):
"""
Validates a set of lines connected to a node as for the angle formed between them.
:param node: (QgsPoint) hidrography node to be validated.
@@ -794,7 +1013,9 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT
val, inval, reason = dict(), dict(), ""
if not geomType:
geomType = networkLayer.geometryType()
- azimuthDict = self.calculateAzimuthFromNode(node=node, networkLayer=networkLayer, geomType=None)
+ azimuthDict = self.calculateAzimuthFromNode(
+ node=node, networkLayer=networkLayer, geomType=None
+ )
lines = azimuthDict.keys()
for idx1, key1 in enumerate(lines):
if idx1 == len(lines):
@@ -804,14 +1025,23 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT
if idx1 >= idx2:
# in order to calculate only f1 - f2, f1 - f3, f2 - f3 (for 3 features, for instance)
continue
- absAzimuthDifference = math.fmod((azimuthDict[key1] - azimuthDict[key2] + 360), 360)
+ absAzimuthDifference = math.fmod(
+ (azimuthDict[key1] - azimuthDict[key2] + 360), 360
+ )
if absAzimuthDifference > 180:
# the lesser angle should always be the one to be analyzed
- absAzimuthDifference = (360 - absAzimuthDifference)
+ absAzimuthDifference = 360 - absAzimuthDifference
if absAzimuthDifference < 90:
# if it's a 'beak', lines cannot have opposing directions (e.g. cannot flow to/from the same node)
- if not self.checkLineDirectionConcordance(line_a=key1, line_b=key2, networkLayer=networkLayer, geomType=geomType):
- reason = self.tr('Lines id={0} and id={1} have conflicting directions ({2:.2f} deg).').format(key1.id(), key2.id(), absAzimuthDifference)
+ if not self.checkLineDirectionConcordance(
+ line_a=key1,
+ line_b=key2,
+ networkLayer=networkLayer,
+ geomType=geomType,
+ ):
+ reason = self.tr(
+ "Lines id={0} and id={1} have conflicting directions ({2:.2f} deg)."
+ ).format(key1.id(), key2.id(), absAzimuthDifference)
# checks if any of connected lines are already validated by any previous iteration
if key1 not in connectedValidLines:
inval[key1.id()] = key1
@@ -823,17 +1053,21 @@ def validateDeltaLinesAngV2(self, node, networkLayer, connectedValidLines, geomT
continue
else:
# if lines touch each other at a right angle, then it is impossible to infer waterway direction
- reason = self.tr('Cannot infer directions for lines {0} and {1} (Right Angle)').format(key1.id(), key2.id())
+ reason = self.tr(
+ "Cannot infer directions for lines {0} and {1} (Right Angle)"
+ ).format(key1.id(), key2.id())
if key1 not in connectedValidLines:
- inval[key1.id()] = key1
+ inval[key1.id()] = key1
if key2 not in connectedValidLines:
inval[key2.id()] = key2
return val, inval, reason
if not inval:
- val = {k.id() : k for k in lines}
+ val = {k.id(): k for k in lines}
return val, inval, reason
- def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomType=None):
+ def checkNodeTypeValidity(
+ self, node, connectedValidLines, networkLayer, geomType=None
+ ):
"""
Checks if lines connected to a node have their flows compatible to node type and valid lines
connected to it.
@@ -847,45 +1081,57 @@ def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomTyp
# getting flow permitions based on node type
# reference is the node (e.g. 'in' = lines are ENDING at analyzed node)
flowType = {
- NetworkHandler.Flag : None, # 0 - Flag (fim de trecho sem 'justificativa espacial')
- NetworkHandler.Sink : 'in', # 1 - Sumidouro
- NetworkHandler.WaterwayBegin : 'out', # 2 - Fonte D'Água
- NetworkHandler.DownHillNode : 'in', # 3 - Interrupção à Jusante
- NetworkHandler.UpHillNode : 'out', # 4 - Interrupção à Montante
- NetworkHandler.Confluence : 'in and out', # 5 - Confluência
- NetworkHandler.Ramification : 'in and out', # 6 - Ramificação
- NetworkHandler.AttributeChange : 'in and out', # 7 - Mudança de Atributo
- NetworkHandler.NodeNextToWaterBody : 'in or out', # 8 - Nó próximo a corpo d'água
- NetworkHandler.AttributeChangeFlag : None, # 9 - Nó de mudança de atributos conectado em linhas que não mudam de atributos
- NetworkHandler.NodeOverload : None, # 10 - Há igual número de linhas (>1 para cada fluxo) entrando e saindo do nó
- NetworkHandler.DisconnectedLine : None, # 11 - Nó conectado a uma linha perdida na rede (teria dois inícios de rede)
- NetworkHandler.DitchNode : 'in and out', # 12 - Nó de vala
- NetworkHandler.SpillwayNode : 'out' # 13 - Vertedouro
- }
+ NetworkHandler.Flag: None, # 0 - Flag (fim de trecho sem 'justificativa espacial')
+ NetworkHandler.Sink: "in", # 1 - Sumidouro
+ NetworkHandler.WaterwayBegin: "out", # 2 - Fonte D'Água
+ NetworkHandler.DownHillNode: "in", # 3 - Interrupção à Jusante
+ NetworkHandler.UpHillNode: "out", # 4 - Interrupção à Montante
+ NetworkHandler.Confluence: "in and out", # 5 - Confluência
+ NetworkHandler.Ramification: "in and out", # 6 - Ramificação
+ NetworkHandler.AttributeChange: "in and out", # 7 - Mudança de Atributo
+ NetworkHandler.NodeNextToWaterBody: "in or out", # 8 - Nó próximo a corpo d'água
+ NetworkHandler.AttributeChangeFlag: None, # 9 - Nó de mudança de atributos conectado em linhas que não mudam de atributos
+ NetworkHandler.NodeOverload: None, # 10 - Há igual número de linhas (>1 para cada fluxo) entrando e saindo do nó
+ NetworkHandler.DisconnectedLine: None, # 11 - Nó conectado a uma linha perdida na rede (teria dois inícios de rede)
+ NetworkHandler.DitchNode: "in and out", # 12 - Nó de vala
+ NetworkHandler.SpillwayNode: "out", # 13 - Vertedouro
+ }
# to avoid calculations in expense of memory
nodeType = self.nodeTypeDict[node]
# if node is introduced by operator's modification, it won't be saved to the layer
if node not in self.nodeTypeDict.keys() and not self.unclassifiedNodes:
self.unclassifiedNodes = True
- QMessageBox.warning(self.iface.mainWindow(), self.tr('Error!'), self.tr('There are unclassified nodes! Node (re)creation process is recommended before this process.'))
+ QMessageBox.warning(
+ self.iface.mainWindow(),
+ self.tr("Error!"),
+ self.tr(
+ "There are unclassified nodes! Node (re)creation process is recommended before this process."
+ ),
+ )
return None, None, None
flow = flowType[int(nodeType)]
nodePointDict = self.nodeDict[node]
# getting all connected lines to node that are not already validated
- linesNotValidated = set( nodePointDict['start'] + nodePointDict['end'] ) - set(connectedValidLines)
+ linesNotValidated = set(nodePointDict["start"] + nodePointDict["end"]) - set(
+ connectedValidLines
+ )
# starting dicts of valid and invalid lines
validLines, invalidLines = dict(), dict()
if not flow:
# flags have all lines flagged
if nodeType == NetworkHandler.Flag:
- reason = self.tr('Node was flagged upon classification (probably cannot be an ending hidrography node).')
- invalidLines = { line.id() : line for line in linesNotValidated }
+ reason = self.tr(
+ "Node was flagged upon classification (probably cannot be an ending hidrography node)."
+ )
+ invalidLines = {line.id(): line for line in linesNotValidated}
elif nodeType == NetworkHandler.AttributeChangeFlag:
- if nodePointDict['start'] and nodePointDict['end']:
+ if nodePointDict["start"] and nodePointDict["end"]:
# in case manual error is inserted, this would raise an exception
- line1, line2 = nodePointDict['start'][0], nodePointDict['end'][0]
+ line1, line2 = nodePointDict["start"][0], nodePointDict["end"][0]
id1, id2 = line1.id(), line2.id()
- reason = self.tr('Redundant node. Connected lines ({0}, {1}) share the same set of attributes.').format(id1, id2)
+ reason = self.tr(
+ "Redundant node. Connected lines ({0}, {1}) share the same set of attributes."
+ ).format(id1, id2)
if line1 in linesNotValidated:
il = line1
else:
@@ -896,54 +1142,76 @@ def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomTyp
self.nodeTypeDict[node] = NetworkHandler.Flag
# reclassify node type into layer
self.reclassifyNodeType[node] = NetworkHandler.Flag
- reason = self.tr('Node was flagged upon classification (probably cannot be an ending hidrography node).')
+ reason = self.tr(
+ "Node was flagged upon classification (probably cannot be an ending hidrography node)."
+ )
elif nodeType == NetworkHandler.DisconnectedLine:
# get line connected to node
- lines = nodePointDict['start'] + nodePointDict['end']
+ lines = nodePointDict["start"] + nodePointDict["end"]
# just in case there's a node wrong manual reclassification so code doesn't raise an error
ids = [str(line.id()) for line in lines]
- invalidLines = { line.id() : line for line in lines }
- reason = self.tr('Line {0} disconnected from network.').format(", ".join(ids))
+ invalidLines = {line.id(): line for line in lines}
+ reason = self.tr("Line {0} disconnected from network.").format(
+ ", ".join(ids)
+ )
elif nodeType == NetworkHandler.NodeOverload:
- reason = self.tr('Node is overloaded - 4 or more lines are flowing in (>= 2 lines) and out (>= 2 lines).')
- invalidLines = { line.id() : line for line in linesNotValidated }
+ reason = self.tr(
+ "Node is overloaded - 4 or more lines are flowing in (>= 2 lines) and out (>= 2 lines)."
+ )
+ invalidLines = {line.id(): line for line in linesNotValidated}
return validLines, invalidLines, reason
if not linesNotValidated:
# if there are no lines to be validated, method returns None
- return validLines, invalidLines, ''
+ return validLines, invalidLines, ""
# if 'geomType' is not given, it must be evaluated
if not geomType:
geomType = networkLayer.geometryType()
# reason message in case of invalidity
- reason = ''
+ reason = ""
for line in linesNotValidated:
# getting last and initial node from analyzed line
finalNode = self.getLastNode(lyr=networkLayer, feat=line, geomType=geomType)
- initialNode = self.getFirstNode(lyr=networkLayer, feat=line, geomType=geomType)
+ initialNode = self.getFirstNode(
+ lyr=networkLayer, feat=line, geomType=geomType
+ )
# line ID
lineID = line.id()
# comparing extreme nodes to find out if flow is compatible to node type
- if flow == 'in':
+ if flow == "in":
if node == finalNode:
if lineID not in validLines.keys():
validLines[lineID] = line
elif lineID not in invalidLines.keys():
invalidLines[lineID] = line
- reason = "".join([reason, self.tr('Line id={0} does not end at a node with IN flow type (node type is {1}). ').format(lineID, nodeType)])
- elif flow == 'out':
+ reason = "".join(
+ [
+ reason,
+ self.tr(
+ "Line id={0} does not end at a node with IN flow type (node type is {1}). "
+ ).format(lineID, nodeType),
+ ]
+ )
+ elif flow == "out":
if node == initialNode:
if lineID not in validLines.keys():
validLines[lineID] = line
elif lineID not in invalidLines.keys():
invalidLines[lineID] = line
- reason = "".join([reason, self.tr('Line id={0} does not start at a node with OUT flow type (node type is {1}). ')\
- .format(lineID, self.nodeTypeNameDict[nodeType])])
- elif flow == 'in and out':
- if bool(len(nodePointDict['start'])) != bool(len(nodePointDict['end'])):
+ reason = "".join(
+ [
+ reason,
+ self.tr(
+ "Line id={0} does not start at a node with OUT flow type (node type is {1}). "
+ ).format(lineID, self.nodeTypeNameDict[nodeType]),
+ ]
+ )
+ elif flow == "in and out":
+ if bool(len(nodePointDict["start"])) != bool(len(nodePointDict["end"])):
# if it's an 'in and out' flow and only one of dicts is filled, then there's an inconsistency
invalidLines[lineID] = line
- thisReason = self.tr('Lines are either flowing only in or out of node. Node classification is {0}.')\
- .format(self.nodeTypeNameDict[nodeType])
+ thisReason = self.tr(
+ "Lines are either flowing only in or out of node. Node classification is {0}."
+ ).format(self.nodeTypeNameDict[nodeType])
if thisReason not in reason:
reason = "".join([reason, thisReason])
elif node in [initialNode, finalNode]:
@@ -951,15 +1219,29 @@ def checkNodeTypeValidity(self, node, connectedValidLines, networkLayer, geomTyp
validLines[lineID] = line
elif lineID not in invalidLines:
invalidLines[lineID] = line
- reason = "".join([reason, self.tr('Line {0} seems to be invalid (unable to point specific reason).').format(lineID)])
- elif flow == 'in or out':
+ reason = "".join(
+ [
+ reason,
+ self.tr(
+ "Line {0} seems to be invalid (unable to point specific reason)."
+ ).format(lineID),
+ ]
+ )
+ elif flow == "in or out":
# these nodes can either be a waterway beginning or end
# No invalidation reasons were thought at this point...
if lineID not in validLines:
validLines[lineID] = line
- return validLines, invalidLines, reason
+ return validLines, invalidLines, reason
- def checkNodeValidity(self, node, connectedValidLines, networkLayer, geomType=None, deltaLinesCheckList=None):
+ def checkNodeValidity(
+ self,
+ node,
+ connectedValidLines,
+ networkLayer,
+ geomType=None,
+ deltaLinesCheckList=None,
+ ):
"""
Checks whether a node is valid or not.
:param node: (QgsPoint) node which lines connected to it are going to be verified.
@@ -969,23 +1251,35 @@ def checkNodeValidity(self, node, connectedValidLines, networkLayer, geomType=No
:param deltaLinesCheckList: (list-of-int) node types that must be checked for their connected lines angles.
:return: (str) if node is invalid, returns the invalidation reason string.
"""
-
+
if not deltaLinesCheckList:
- deltaLinesCheckList = [NetworkHandler.Confluence, NetworkHandler.Ramification] # nodes that have an unbalaced number ratio of flow in/out
+ deltaLinesCheckList = [
+ NetworkHandler.Confluence,
+ NetworkHandler.Ramification,
+ ] # nodes that have an unbalaced number ratio of flow in/out
# check coherence to node type and waterway flow
- val, inval, reason = self.checkNodeTypeValidity(node=node, connectedValidLines=connectedValidLines,\
- networkLayer=networkLayer, geomType=geomType)
+ val, inval, reason = self.checkNodeTypeValidity(
+ node=node,
+ connectedValidLines=connectedValidLines,
+ networkLayer=networkLayer,
+ geomType=geomType,
+ )
# checking angle validity
if self.nodeTypeDict[node] in deltaLinesCheckList:
# check for connected lines angles coherence
- val2, inval2, reason2 = self.validateDeltaLinesAngV2(node=node, networkLayer=networkLayer, connectedValidLines=connectedValidLines, geomType=geomType)
+ val2, inval2, reason2 = self.validateDeltaLinesAngV2(
+ node=node,
+ networkLayer=networkLayer,
+ connectedValidLines=connectedValidLines,
+ geomType=geomType,
+ )
# if any invalid line was validated on because of node type, it shall be moved to invalid dict
if reason2:
# updates reason
if reason:
reason = "; ".join([reason, reason2])
else:
- reason = reason2
+ reason = reason2
# remove any validated line in this iteration
for lineId in inval2:
val.pop(lineId, None)
@@ -996,7 +1290,7 @@ def checkNodeValidity(self, node, connectedValidLines, networkLayer, geomType=No
def getNextNodes(self, node, networkLayer, geomType=None):
"""
It returns a list of all other nodes for each line connected to target node.
- :param node: (QgsPoint) node based on which next nodes will be gathered from.
+ :param node: (QgsPoint) node based on which next nodes will be gathered from.
:param networkLayer: (QgsVectorLayer) hidrography line layer.
:return: (list-of-QgsPoint) a list of the other node of lines connected to given hidrography node.
"""
@@ -1004,15 +1298,21 @@ def getNextNodes(self, node, networkLayer, geomType=None):
geomType = networkLayer.geometryType()
nextNodes = []
nodePointDict = self.nodeDict[node]
- for line in nodePointDict['start']:
+ for line in nodePointDict["start"]:
# if line starts at target node, the other extremity is a final node
- nextNodes.append(self.getLastNode(lyr=networkLayer, feat=line, geomType=geomType))
- for line in nodePointDict['end']:
+ nextNodes.append(
+ self.getLastNode(lyr=networkLayer, feat=line, geomType=geomType)
+ )
+ for line in nodePointDict["end"]:
# if line ends at target node, the other extremity is a initial node
- nextNodes.append(self.getFirstNode(lyr=networkLayer, feat=line, geomType=geomType))
+ nextNodes.append(
+ self.getFirstNode(lyr=networkLayer, feat=line, geomType=geomType)
+ )
return nextNodes
- def checkForStartConditions(self, node, validLines, networkLayer, nodeLayer, geomType=None):
+ def checkForStartConditions(
+ self, node, validLines, networkLayer, nodeLayer, geomType=None
+ ):
"""
Checks if any of next nodes is a contour condition to directioning process.
:param node: (QgsPoint) node which needs to have its next nodes checked.
@@ -1024,11 +1324,17 @@ def checkForStartConditions(self, node, validLines, networkLayer, nodeLayer, geo
"""
# node type granted as right as start conditions
inContourConditionTypes = [NetworkHandler.DownHillNode, NetworkHandler.Sink]
- outContourConditionTypes = [NetworkHandler.UpHillNode, NetworkHandler.WaterwayBegin, NetworkHandler.SpillwayNode]
+ outContourConditionTypes = [
+ NetworkHandler.UpHillNode,
+ NetworkHandler.WaterwayBegin,
+ NetworkHandler.SpillwayNode,
+ ]
if node in inContourConditionTypes + outContourConditionTypes:
# if node IS a starting condition, method is not necessary
- return False, ''
- nodes = self.getNextNodes(node=node, networkLayer=networkLayer, geomType=geomType)
+ return False, ""
+ nodes = self.getNextNodes(
+ node=node, networkLayer=networkLayer, geomType=geomType
+ )
# for faster calculation
nodeTypeDictAlias = self.nodeTypeDict
nodeDictAlias = self.nodeDict
@@ -1049,45 +1355,73 @@ def checkForStartConditions(self, node, validLines, networkLayer, nodeLayer, geo
self.reclassifyNodeType[nn] = nodeType
if nodeType in inContourConditionTypes:
# if next node is a confirmed IN-flowing lines, no lines should start on it
- line = nodeDictAlias[nn]['start'][0] if nodeDictAlias[nn]['start'] else None
+ line = (
+ nodeDictAlias[nn]["start"][0]
+ if nodeDictAlias[nn]["start"]
+ else None
+ )
hasStartCondition = True
elif nodeType in outContourConditionTypes:
# if next node is a confirmed OUT-flowing lines, no lines should end on it
- line = nodeDictAlias[nn]['end'][0] if nodeDictAlias[nn]['end'] else None
+ line = nodeDictAlias[nn]["end"][0] if nodeDictAlias[nn]["end"] else None
hasStartCondition = True
if line:
# if line is given, then flipping it is necessary
self.flipSingleLine(line=line, layer=networkLayer, geomType=geomType)
# if a line is flipped it must be changed in self.nodeDict
- self.updateNodeDict(node=node, line=line, networkLayer=networkLayer, geomType=geomType)
+ self.updateNodeDict(
+ node=node, line=line, networkLayer=networkLayer, geomType=geomType
+ )
flippedLines.append(line)
flippedLinesIds.append(str(line.id()))
# validLines.append(line)
# for speed-up
- initialNode = lambda x : self.getFirstNode(lyr=networkLayer, feat=x, geomType=geomType)
- lastNode = lambda x : self.getLastNode(lyr=networkLayer, feat=x, geomType=geomType)
+ initialNode = lambda x: self.getFirstNode(
+ lyr=networkLayer, feat=x, geomType=geomType
+ )
+ lastNode = lambda x: self.getLastNode(
+ lyr=networkLayer, feat=x, geomType=geomType
+ )
if flippedLines:
# map is a for-loop in C
- reclassifyNodeAlias = lambda x : nodeLayer.changeAttributeValue(self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x])) \
- if self.reclassifyNode(node=x, nodeLayer=nodeLayer) \
- else False
- map(reclassifyNodeAlias, chain(map(initialNode, flippedLines), map(lastNode, flippedLines)))
+ reclassifyNodeAlias = (
+ lambda x: nodeLayer.changeAttributeValue(
+ self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x])
+ )
+ if self.reclassifyNode(node=x, nodeLayer=nodeLayer)
+ else False
+ )
+ map(
+ reclassifyNodeAlias,
+ chain(map(initialNode, flippedLines), map(lastNode, flippedLines)),
+ )
return hasStartCondition, flippedLinesIds
def directNetwork(self, networkLayer, nodeLayer, nodeList=None):
"""
For every node over the frame [or set as a line beginning], checks for network coherence regarding
- to previous node classification and its current direction. Method considers bordering points as
+ to previous node classification and its current direction. Method considers bordering points as
correctly classified.
:param networkLayer: (QgsVectorLayer) hidrography lines layer from which node are created from.
:param nodeList: a list of target node points (QgsPoint). If not given, all nodeDict will be read.
:return: (dict) flag dictionary ( { (QgsPoint) node : (str) reason } ), (dict) dictionaries ( { (int)feat_id : (QgsFeature)feat } ) of invalid and valid lines.
"""
- startingNodeTypes = [NetworkHandler.UpHillNode, NetworkHandler.WaterwayBegin, NetworkHandler.SpillwayNode] # node types that are over the frame contour and line BEGINNINGS
- deltaLinesCheckList = [NetworkHandler.Confluence, NetworkHandler.Ramification] # nodes that have an unbalaced number ratio of flow in/out
+ startingNodeTypes = [
+ NetworkHandler.UpHillNode,
+ NetworkHandler.WaterwayBegin,
+ NetworkHandler.SpillwayNode,
+ ] # node types that are over the frame contour and line BEGINNINGS
+ deltaLinesCheckList = [
+ NetworkHandler.Confluence,
+ NetworkHandler.Ramification,
+ ] # nodes that have an unbalaced number ratio of flow in/out
if not nodeList:
# 'nodeList' must start with all nodes that are on the frame (assumed to be well directed)
- nodeList = [node for node, nodeType in self.nodeTypeDict.items() if nodeType in startingNodeTypes]
+ nodeList = [
+ node
+ for node, nodeType in self.nodeTypeDict.items()
+ if nodeType in startingNodeTypes
+ ]
# if no node to start the process is found, process ends here
if not nodeList:
return None, None, self.tr("No network starting point was found")
@@ -1104,8 +1438,8 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None):
for node in nodeList:
# first thing to be done: check if there are more than one non-validated line (hence, enough information for a decision)
if node in self.nodeDict:
- startLines = self.nodeDict[node]['start']
- endLines = self.nodeDict[node]['end']
+ startLines = self.nodeDict[node]["start"]
+ endLines = self.nodeDict[node]["end"]
if node not in self.nodeTypeDict:
# in case node is not classified
self.nodeTypeDict[node] = self.classifyNode([node, nodeLayer])
@@ -1117,33 +1451,57 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None):
nodeLines = startLines + endLines
validLinesList = validLines.values()
if len(set(nodeLines) - set(validLinesList)) > 1:
- hasStartCondition, flippedLines = self.checkForStartConditions(node=node, validLines=validLinesList, networkLayer=networkLayer, nodeLayer=nodeLayer, geomType=geomType)
+ hasStartCondition, flippedLines = self.checkForStartConditions(
+ node=node,
+ validLines=validLinesList,
+ networkLayer=networkLayer,
+ nodeLayer=nodeLayer,
+ geomType=geomType,
+ )
if hasStartCondition:
flippedLinesIds |= set(flippedLines)
else:
# if it is not connected to a start condition, check if node has a valid line connected to it
- if (set(nodeLines) & set(validLinesList)):
+ if set(nodeLines) & set(validLinesList):
# if it does and, check if it is a valid node
- val, inval, reason = self.checkNodeValidity(node=node, connectedValidLines=validLinesList,\
- networkLayer=networkLayer, deltaLinesCheckList=deltaLinesCheckList, geomType=geomType)
+ val, inval, reason = self.checkNodeValidity(
+ node=node,
+ connectedValidLines=validLinesList,
+ networkLayer=networkLayer,
+ deltaLinesCheckList=deltaLinesCheckList,
+ geomType=geomType,
+ )
# if node has a valid line connected to it and it is valid, then non-validated lines are proven to be in conformity to
# start conditions, then they should be validated and node should be set as visited
if reason:
- # if there are more than 1 line not validated yet and no start conditions around it,
- # node will neither be checked nor marked as visited
+ # if there are more than 1 line not validated yet and no start conditions around it,
+ # node will neither be checked nor marked as visited
continue
# check coherence to node type and waterway flow
- val, inval, reason = self.checkNodeValidity(node=node, connectedValidLines=validLinesList,\
- networkLayer=networkLayer, deltaLinesCheckList=deltaLinesCheckList, geomType=geomType)
+ val, inval, reason = self.checkNodeValidity(
+ node=node,
+ connectedValidLines=validLinesList,
+ networkLayer=networkLayer,
+ deltaLinesCheckList=deltaLinesCheckList,
+ geomType=geomType,
+ )
# nodes to be removed from next nodes
removeNode = []
# if a reason is given, then node is invalid (even if there are no invalid lines connected to it).
if reason:
# try to fix node issues
# note that val, inval and reason MAY BE MODIFIED - and there is no problem...
- flippedLinesIds_, mergedLinesString_ = self.fixNodeFlagsNew(node=node, valDict=val, invalidDict=inval, reason=reason, \
- connectedValidLines=validLinesList, networkLayer=networkLayer, \
- nodeLayer=nodeLayer, geomType=geomType, deltaLinesCheckList=deltaLinesCheckList)
+ flippedLinesIds_, mergedLinesString_ = self.fixNodeFlagsNew(
+ node=node,
+ valDict=val,
+ invalidDict=inval,
+ reason=reason,
+ connectedValidLines=validLinesList,
+ networkLayer=networkLayer,
+ nodeLayer=nodeLayer,
+ geomType=geomType,
+ deltaLinesCheckList=deltaLinesCheckList,
+ )
# keep track of all modifications made
if flippedLinesIds_:
# IDs not registered yet will be added to final list
@@ -1155,16 +1513,20 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None):
if not mergedLinesString:
mergedLinesString = mergedLinesString_
else:
- ", ".join([mergedLinesString, mergedLinesString_])
+ ", ".join([mergedLinesString, mergedLinesString_])
# if node is still invalid, add to nodeFlagList and add/update its reason
if reason:
nodeFlags[node] = reason
# get next nodes connected to invalid lines
for line in inval.values():
if line in endLines:
- removeNode.append(self.getFirstNode(lyr=networkLayer, feat=line))
+ removeNode.append(
+ self.getFirstNode(lyr=networkLayer, feat=line)
+ )
else:
- removeNode.append(self.getLastNode(lyr=networkLayer, feat=line))
+ removeNode.append(
+ self.getLastNode(lyr=networkLayer, feat=line)
+ )
# set node as visited
if node not in visitedNodes:
visitedNodes.append(node)
@@ -1172,17 +1534,21 @@ def directNetwork(self, networkLayer, nodeLayer, nodeList=None):
validLines.update(val)
invalidLines.update(inval)
# get next iteration nodes
- newNextNodes += self.getNextNodes(node=node, networkLayer=networkLayer, geomType=geomType)
+ newNextNodes += self.getNextNodes(
+ node=node, networkLayer=networkLayer, geomType=geomType
+ )
# remove next nodes connected to invalid lines
if removeNode:
- newNextNodes = list( set(newNextNodes) - set(removeNode) )
+ newNextNodes = list(set(newNextNodes) - set(removeNode))
# remove nodes that were already visited
- newNextNodes = list( set(newNextNodes) - set(visitedNodes) )
+ newNextNodes = list(set(newNextNodes) - set(visitedNodes))
# if new nodes are detected, repeat for those
nodeList = newNextNodes
newNextNodes = []
# log all features that were merged and/or flipped
- self.logAlteredFeatures(flippedLines=flippedLinesIds, mergedLinesString=mergedLinesString)
+ self.logAlteredFeatures(
+ flippedLines=flippedLinesIds, mergedLinesString=mergedLinesString
+ )
return nodeFlags, invalidLines, validLines
# method for automatic fix
@@ -1193,12 +1559,12 @@ def getReasonType(self, reason):
:return: (int) reason type.
"""
fixableReasonExcertsDict = {
- self.tr("does not end at a node with IN flow type") : 1,
- self.tr("does not start at a node with OUT flow type") : 2,
- self.tr("have conflicting directions") : 3,
- self.tr('Redundant node.') : 4,
- self.tr('Node was flagged upon classification') : 5
- }
+ self.tr("does not end at a node with IN flow type"): 1,
+ self.tr("does not start at a node with OUT flow type"): 2,
+ self.tr("have conflicting directions"): 3,
+ self.tr("Redundant node."): 4,
+ self.tr("Node was flagged upon classification"): 5,
+ }
for r in fixableReasonExcertsDict:
if r in reason:
return fixableReasonExcertsDict[r]
@@ -1251,10 +1617,10 @@ def flipInvalidLine(self, node, networkLayer, validLines, geomType=None):
:return: (QgsFeature) flipped line.
"""
# get dictionaries for speed-up
- endDict = self.nodeDict[node]['end']
- startDict = self.nodeDict[node]['start']
+ endDict = self.nodeDict[node]["end"]
+ startDict = self.nodeDict[node]["start"]
amountLines = len(endDict + startDict)
- # it is considered that
+ # it is considered that
if endDict:
# get invalid line connected to node
invalidLine = list(set(endDict) - set(validLines))
@@ -1279,20 +1645,20 @@ def fixAttributeChangeFlag(self, node, networkLayer):
:param networkLayer: (QgsVectorLayer) network lines layer.
:return: (str) string containing which line was line the other.
"""
- line_a = self.nodeDict[node]['end'][0]
- line_b = self.nodeDict[node]['start'][0]
+ line_a = self.nodeDict[node]["end"][0]
+ line_b = self.nodeDict[node]["start"][0]
# lines have their order changed so that the deleted line is the intial one
self.mergeNetworkLines(line_a=line_b, line_b=line_a, layer=networkLayer)
# the updated feature should be updated into node dict for the NEXT NODE!
nn = self.getLastNode(lyr=networkLayer, feat=line_b, geomType=1)
- if nn in self.nodeDict: # TODO: @jpesperidiao verifica isso por favor
- for line in self.nodeDict[nn]['end']:
+ if nn in self.nodeDict: # TODO: @jpesperidiao verifica isso por favor
+ for line in self.nodeDict[nn]["end"]:
if line.id() == line_b.id():
- self.nodeDict[nn]['end'].remove(line)
- self.nodeDict[nn]['end'].append(line_b)
+ self.nodeDict[nn]["end"].remove(line)
+ self.nodeDict[nn]["end"].append(line_b)
# remove attribute change flag node (there are no lines connected to it anymore)
self.nodesToPop.append(node)
- return self.tr('{0} to {1}').format(line_a.id(), line_b.id())
+ return self.tr("{0} to {1}").format(line_a.id(), line_b.id())
def updateNodeDict(self, node, line, networkLayer, geomType=None):
"""
@@ -1310,7 +1676,12 @@ def reclassifyNode(self, node, nodeLayer):
:param node: (QgsPoint) node to be reclassified.
:return: (bool) whether point was modified.
"""
- immutableTypes = [NetworkHandler.UpHillNode, NetworkHandler.DownHillNode, NetworkHandler.WaterwayBegin, NetworkHandler.SpillwayNode]
+ immutableTypes = [
+ NetworkHandler.UpHillNode,
+ NetworkHandler.DownHillNode,
+ NetworkHandler.WaterwayBegin,
+ NetworkHandler.SpillwayNode,
+ ]
if self.nodeTypeDict[node] in immutableTypes:
# if node type is immutable, reclassification is not possible
return False
@@ -1325,7 +1696,9 @@ def reclassifyNode(self, node, nodeLayer):
self.reclassifyNodeType[node] = newType
return True
- def fixDeltaFlag(self, node, networkLayer, validLines, reason, reasonType=3, geomType=None):
+ def fixDeltaFlag(
+ self, node, networkLayer, validLines, reason, reasonType=3, geomType=None
+ ):
"""
Tries to fix nodes flagged because of their delta angles.
:param node: (QgsPoint) invalid node.
@@ -1337,7 +1710,7 @@ def fixDeltaFlag(self, node, networkLayer, validLines, reason, reasonType=3, geo
:return: (QgsFeature) line to be flipped. If no line is identified as flippable, None is returned.
"""
flipCandidates = self.getLineIdFromReason(reason=reason, reasonType=reasonType)
- for line in self.nodeDict[node]['start'] + self.nodeDict[node]['end']:
+ for line in self.nodeDict[node]["start"] + self.nodeDict[node]["end"]:
lineId = str(line.id())
if lineId in flipCandidates and line not in validLines:
# flip line that is exposed in invalidation reason and is not previously validated
@@ -1346,7 +1719,18 @@ def fixDeltaFlag(self, node, networkLayer, validLines, reason, reasonType=3, geo
# if no line attend necessary requirements for flipping
return None
- def fixNodeFlagsNew(self, node, valDict, invalidDict, reason, connectedValidLines, networkLayer, nodeLayer, geomType=None, deltaLinesCheckList=None):
+ def fixNodeFlagsNew(
+ self,
+ node,
+ valDict,
+ invalidDict,
+ reason,
+ connectedValidLines,
+ networkLayer,
+ nodeLayer,
+ geomType=None,
+ deltaLinesCheckList=None,
+ ):
"""
Tries to fix issues flagged on node
"""
@@ -1364,53 +1748,85 @@ def fixNodeFlagsNew(self, node, valDict, invalidDict, reason, connectedValidLine
# original message: self.tr('Line {0} does not end at a node with IN flow type (node type is {1}). ')
# original message: self.tr('Line {0} does not start at a node with OUT flow type (node type is {1}). ')
# get flipping candidates
- featIdFlipCandidates = self.getLineIdFromReason(reason=reason, reasonType=reasonType)
+ featIdFlipCandidates = self.getLineIdFromReason(
+ reason=reason, reasonType=reasonType
+ )
for lineId in featIdFlipCandidates:
line = invalidDict[int(lineId)]
if line not in connectedValidLines:
# only non-valid lines may be modified
- self.flipSingleLine(line=line, layer=networkLayer, geomType=geomType)
+ self.flipSingleLine(
+ line=line, layer=networkLayer, geomType=geomType
+ )
flippedLinesIds.append(lineId)
flippedLines.append(line)
elif reasonType == 3:
# original message: self.tr('Lines {0} and {1} have conflicting directions ({2:.2f} deg).')
- line = self.fixDeltaFlag(node=node, networkLayer=networkLayer, reason=reason, validLines=connectedValidLines, reasonType=reasonType)
+ line = self.fixDeltaFlag(
+ node=node,
+ networkLayer=networkLayer,
+ reason=reason,
+ validLines=connectedValidLines,
+ reasonType=reasonType,
+ )
if line:
# if a line is flipped it must be changed in self.nodeDict
- self.updateNodeDict(node=node, line=line, networkLayer=networkLayer, geomType=geomType)
+ self.updateNodeDict(
+ node=node, line=line, networkLayer=networkLayer, geomType=geomType
+ )
elif reasonType == 4:
# original message: self.tr('Redundant node. Connected lines ({0}, {1}) share the same set of attributes.')
- mergedLinesString = self.fixAttributeChangeFlag(node=node, networkLayer=networkLayer)
+ mergedLinesString = self.fixAttributeChangeFlag(
+ node=node, networkLayer=networkLayer
+ )
elif reasonType == 5:
# original message: self.tr('Node was flagged upon classification (probably cannot be an ending hidrography node).')
- line = self.flipInvalidLine(node=node, networkLayer=networkLayer, validLines=connectedValidLines, geomType=geomType)
+ line = self.flipInvalidLine(
+ node=node,
+ networkLayer=networkLayer,
+ validLines=connectedValidLines,
+ geomType=geomType,
+ )
if line:
flippedLinesIds.append(str(line.id()))
flippedLines.append(line)
# if a line is flipped it must be changed in self.nodeDict
- self.updateNodeDict(node=node, line=line, networkLayer=networkLayer, geomType=geomType)
+ self.updateNodeDict(
+ node=node, line=line, networkLayer=networkLayer, geomType=geomType
+ )
else:
# in case, for some reason, a strange value is given to reasonType
- return [], ''
+ return [], ""
# for speed-up
- initialNode = lambda x : self.getFirstNode(lyr=networkLayer, feat=x, geomType=geomType)
- lastNode = lambda x : self.getLastNode(lyr=networkLayer, feat=x, geomType=geomType)
+ initialNode = lambda x: self.getFirstNode(
+ lyr=networkLayer, feat=x, geomType=geomType
+ )
+ lastNode = lambda x: self.getLastNode(
+ lyr=networkLayer, feat=x, geomType=geomType
+ )
# reclassification re-evalution is only needed if lines were flipped
if flippedLinesIds:
# re-classify nodes connected to flipped lines before re-checking
# map is a for-loop in C
- reclassifyNodeAlias = lambda x : nodeLayer.changeAttributeValue(self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x])) \
- if self.reclassifyNode(node=x, nodeLayer=nodeLayer) \
- else None
- map(reclassifyNodeAlias, chain(map(initialNode, flippedLines), map(lastNode, flippedLines)))
+ reclassifyNodeAlias = (
+ lambda x: nodeLayer.changeAttributeValue(
+ self.nodeIdDict[x], 2, int(self.reclassifyNodeType[x])
+ )
+ if self.reclassifyNode(node=x, nodeLayer=nodeLayer)
+ else None
+ )
+ map(
+ reclassifyNodeAlias,
+ chain(map(initialNode, flippedLines), map(lastNode, flippedLines)),
+ )
# check if node is fixed and update its dictionaries and invalidation reason
valDict, invalidDict, reason = self.checkNodeValidity(
node=node,
connectedValidLines=connectedValidLines,
networkLayer=networkLayer,
geomType=geomType,
- deltaLinesCheckList=deltaLinesCheckList
- )
+ deltaLinesCheckList=deltaLinesCheckList,
+ )
return flippedLinesIds, mergedLinesString
def logAlteredFeatures(self, flippedLines, mergedLinesString, feedback=None):
@@ -1421,15 +1837,36 @@ def logAlteredFeatures(self, flippedLines, mergedLinesString, feedback=None):
:return: (bool) whether or not a message was shown.
"""
# building warning message
- warning = ''
+ warning = ""
if flippedLines:
- warning = "".join([warning, self.tr("Lines that were flipped while directioning hidrography lines: {0}\n\n").format(", ".join(flippedLines))])
+ warning = "".join(
+ [
+ warning,
+ self.tr(
+ "Lines that were flipped while directioning hidrography lines: {0}\n\n"
+ ).format(", ".join(flippedLines)),
+ ]
+ )
elif mergedLinesString:
- warning = "".join([warning, self.tr("Lines that were merged while directioning hidrography lines: {0}\n\n").format(mergedLinesString)])
+ warning = "".join(
+ [
+ warning,
+ self.tr(
+ "Lines that were merged while directioning hidrography lines: {0}\n\n"
+ ).format(mergedLinesString),
+ ]
+ )
if warning:
# warning is only raised when there were flags fixed
if feedback is not None:
- warning = "".join([self.tr('\nVerify Network Directioning: Flipped/Merged Lines\n'), warning])
+ warning = "".join(
+ [
+ self.tr(
+ "\nVerify Network Directioning: Flipped/Merged Lines\n"
+ ),
+ warning,
+ ]
+ )
feedback.pushInfo(warning)
return True
return False
@@ -1441,23 +1878,25 @@ def getNodeTypeDictFromNodeLayer(self, networkNodeLayer, feedback=None):
:return: (tuple-of-dict) node type dict and node id dict, respectively
"""
nodeTypeDict, nodeIdDict = dict(), dict()
- isMulti = QgsWkbTypes.isMultiType(int(networkNodeLayer.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(networkNodeLayer.wkbType())
featCount = networkNodeLayer.featureCount()
- size = 100/featCount if featCount else 0
+ size = 100 / featCount if featCount else 0
for current, feat in enumerate(networkNodeLayer.getFeatures()):
if feedback is not None and feedback.isCanceled():
break
if isMulti:
- node = feat.geometry().asMultiPoint()[0]
+ node = feat.geometry().asMultiPoint()[0]
else:
node = feat.geometry().asPoint()
- nodeTypeDict[node] = int(feat['node_type'])
+ nodeTypeDict[node] = int(feat["node_type"])
nodeIdDict[node] = feat.id()
if feedback is not None:
feedback.setProgress(size * current)
return nodeTypeDict, nodeIdDict
- def clearAuxiliaryLinesLayer(self, invalidLinesLayer, lineIdList=None, commitToLayer=False):
+ def clearAuxiliaryLinesLayer(
+ self, invalidLinesLayer, lineIdList=None, commitToLayer=False
+ ):
"""
Clears all (or a given list of points) invalid lines from auxiliary lines layer.
:param invalidLinesLayer: (QgsVectorLayer) invalid lines layer.
@@ -1465,14 +1904,20 @@ def clearAuxiliaryLinesLayer(self, invalidLinesLayer, lineIdList=None, commitToL
:param commitToLayer: (bool) indicates whether changes should be commited to layer.
"""
# invalid reason texts
- invalidReason = self.tr('Connected to invalid hidrography node.')
- nonVisitedReason = self.tr('Line not yet visited.')
- invalidLinesLayer.beginEditCommand('Clear Invalid Lines')
+ invalidReason = self.tr("Connected to invalid hidrography node.")
+ nonVisitedReason = self.tr("Line not yet visited.")
+ invalidLinesLayer.beginEditCommand("Clear Invalid Lines")
if lineIdList is None:
# define a function to get only feature ids for invalid lines registered in invalidLinesLayer and use it in map, for speed-up
- getInvalidLineFunc = lambda feat : feat.id() if feat['reason'] in [invalidReason, nonVisitedReason] else -9999
+ getInvalidLineFunc = (
+ lambda feat: feat.id()
+ if feat["reason"] in [invalidReason, nonVisitedReason]
+ else -9999
+ )
# list/set combination to remove possible duplicates of -9999 and avoid unnecessary calculation
- lineIdList = list(set(map(getInvalidLineFunc, invalidLinesLayer.getFeatures())))
+ lineIdList = list(
+ set(map(getInvalidLineFunc, invalidLinesLayer.getFeatures()))
+ )
if -9999 in lineIdList:
lineIdList.remove(-9999)
invalidLinesLayer.deleteFeatures(lineIdList)
@@ -1481,7 +1926,9 @@ def clearAuxiliaryLinesLayer(self, invalidLinesLayer, lineIdList=None, commitToL
if commitToLayer:
invalidLinesLayer.commitChanges()
- def getAuxiliaryLines(self, fields, invalidLinesDict, nonValidatedLines, networkLayerName):
+ def getAuxiliaryLines(
+ self, fields, invalidLinesDict, nonValidatedLines, networkLayerName
+ ):
"""
Populate from auxiliary lines layer with all invalid lines.
:param invalidLinesDict: (dict) dictionary containing all invalid lines to be displayed.
@@ -1489,13 +1936,17 @@ def getAuxiliaryLines(self, fields, invalidLinesDict, nonValidatedLines, network
:param commitToLayer: (bool) indicates whether changes should be commited to layer.
"""
# prepare generic variables that will be reused
- invalidReason = self.tr('Connected to invalid hidrography node.')
- nonVisitedReason = self.tr('Line not yet visited.')
+ invalidReason = self.tr("Connected to invalid hidrography node.")
+ nonVisitedReason = self.tr("Line not yet visited.")
# initiate new features list
featList = []
# pre-declaring method to make it faster
- newInvalidFeatFunc = lambda x : self.createNewInvalidLineFeature(feat_geom=x[0], reason=invalidReason, fields=fields)
- newNonVisitedFeatFunc = lambda x : self.createNewInvalidLineFeature(feat_geom=x[0], reason=nonVisitedReason, fields=fields)
+ newInvalidFeatFunc = lambda x: self.createNewInvalidLineFeature(
+ feat_geom=x[0], reason=invalidReason, fields=fields
+ )
+ newNonVisitedFeatFunc = lambda x: self.createNewInvalidLineFeature(
+ feat_geom=x[0], reason=nonVisitedReason, fields=fields
+ )
# add all non-validated features
for line in nonValidatedLines:
# create new feture
@@ -1503,35 +1954,57 @@ def getAuxiliaryLines(self, fields, invalidLinesDict, nonValidatedLines, network
# add it to new features list
featList.append(feat)
# add invalid lines
- for lineId, line in invalidLinesDict.items():
+ for lineId, line in invalidLinesDict.items():
# create new feture
feat = newInvalidFeatFunc([line.geometry(), lineId])
# add it to new features list
featList.append(feat)
return featList
-
- def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searchRadius, waterBodyClasses=None, waterSinkLayer=None, spillwayLayer=None, ditchLayer=None, max_amount_cycles=1, attributeBlackList=None, feedback=None, selectValid=False, excludePrimaryKeys=True, ignoreVirtualFields=True):
- fieldList = self.layerHandler.getAttributesFromBlackList(networkLayer, \
- attributeBlackList=attributeBlackList,\
- ignoreVirtualFields=ignoreVirtualFields,\
- excludePrimaryKeys=excludePrimaryKeys)
+
+ def verifyNetworkDirectioning(
+ self,
+ networkLayer,
+ networkNodeLayer,
+ frame,
+ searchRadius,
+ waterBodyClasses=None,
+ waterSinkLayer=None,
+ spillwayLayer=None,
+ ditchLayer=None,
+ max_amount_cycles=1,
+ attributeBlackList=None,
+ feedback=None,
+ selectValid=False,
+ excludePrimaryKeys=True,
+ ignoreVirtualFields=True,
+ ):
+ fieldList = self.layerHandler.getAttributesFromBlackList(
+ networkLayer,
+ attributeBlackList=attributeBlackList,
+ ignoreVirtualFields=ignoreVirtualFields,
+ excludePrimaryKeys=excludePrimaryKeys,
+ )
waterBodyClasses = [] if waterBodyClasses is None else waterBodyClasses
# update createNetworkNodesProcess object node dictionary
stepCount = 0
if feedback is not None:
- multiStepFeedback = QgsProcessingMultiStepFeedback(max_amount_cycles, feedback)
+ multiStepFeedback = QgsProcessingMultiStepFeedback(
+ max_amount_cycles, feedback
+ )
multiStepFeedback.setCurrentStep(stepCount)
else:
multiStepFeedback = None
self.nodesToPop = []
self.reclassifyNodeType = dict()
if feedback is not None:
- multiStepFeedback.pushInfo('Identifying nodes...')
+ multiStepFeedback.pushInfo("Identifying nodes...")
multiStepFeedback.setCurrentStep(stepCount)
stepCount += 1
- self.nodeDict = self.identifyAllNodes(networkLayer=networkLayer, feedback=multiStepFeedback)
+ self.nodeDict = self.identifyAllNodes(
+ networkLayer=networkLayer, feedback=multiStepFeedback
+ )
if feedback is not None:
- multiStepFeedback.pushInfo('Getting auxiliar spatial indexes...')
+ multiStepFeedback.pushInfo("Getting auxiliar spatial indexes...")
multiStepFeedback.setCurrentStep(stepCount)
stepCount += 1
auxIndexStructure = self.getAuxIndexStructure(
@@ -1540,13 +2013,13 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc
waterSinkLayer=waterSinkLayer,
spillwayLayer=spillwayLayer,
ditchLayer=ditchLayer,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
networkLayerGeomType = networkLayer.geometryType()
networkLayer.startEditing()
networkNodeLayer.startEditing()
- # declare reclassification function from createNetworkNodesProcess object - parameter is [node, nodeTypeDict]
- self.classifyNode = lambda x : self.nodeType(
+ # declare reclassification function from createNetworkNodesProcess object - parameter is [node, nodeTypeDict]
+ self.classifyNode = lambda x: self.nodeType(
nodePoint=x[0],
networkLayer=networkLayer,
frameLyrContourList=frame,
@@ -1558,13 +2031,15 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc
networkLayerGeomType=networkLayerGeomType,
ditchLayer=ditchLayer,
fieldList=fieldList,
- auxIndexStructure=auxIndexStructure
- )
+ auxIndexStructure=auxIndexStructure,
+ )
if feedback is not None:
- multiStepFeedback.pushInfo('Getting node type dictionary...')
+ multiStepFeedback.pushInfo("Getting node type dictionary...")
multiStepFeedback.setCurrentStep(stepCount)
stepCount += 1
- self.nodeTypeDict, self.nodeIdDict = self.getNodeTypeDictFromNodeLayer(networkNodeLayer=networkNodeLayer, feedback=multiStepFeedback)
+ self.nodeTypeDict, self.nodeIdDict = self.getNodeTypeDictFromNodeLayer(
+ networkNodeLayer=networkNodeLayer, feedback=multiStepFeedback
+ )
# initiate nodes, invalid/valid lines dictionaries
nodeFlags, inval, val = dict(), dict(), dict()
# cycle count start
@@ -1572,26 +2047,33 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc
max_amount_cycles = max_amount_cycles if max_amount_cycles > 0 else 1
# validation method FINALLY starts...
# to speed up modifications made to layers
- networkNodeLayer.beginEditCommand('Reclassify Nodes')
- networkLayer.beginEditCommand('Flip/Merge Lines')
+ networkNodeLayer.beginEditCommand("Reclassify Nodes")
+ networkLayer.beginEditCommand("Flip/Merge Lines")
cycleCount = 0
while True:
if feedback is not None:
- multiStepFeedback.pushInfo('Starting cycle {0}...'.format(cycleCount))
+ multiStepFeedback.pushInfo("Starting cycle {0}...".format(cycleCount))
multiStepFeedback.setCurrentStep(stepCount)
stepCount += 1
- nodeFlags_, inval_, val_ = self.directNetwork(networkLayer=networkLayer, nodeLayer=networkNodeLayer)
+ nodeFlags_, inval_, val_ = self.directNetwork(
+ networkLayer=networkLayer, nodeLayer=networkNodeLayer
+ )
cycleCount += 1
# Log amount of cycles completed
- cycleCountLog = self.tr("Cycle {0}/{1} completed.").format(cycleCount, max_amount_cycles)
+ cycleCountLog = self.tr("Cycle {0}/{1} completed.").format(
+ cycleCount, max_amount_cycles
+ )
if feedback is not None:
multiStepFeedback.pushInfo(cycleCountLog)
multiStepFeedback.setCurrentStep(cycleCount)
self.reclassifyNodeType = dict()
# stop conditions: max amount of cycles exceeded, new flags is the same as previous flags (there are no new issues) and no change
# change to valid lines list was made (meaning that the algorithm did not change network state) or no flags found
- if (cycleCount == max_amount_cycles) or (not nodeFlags_) or \
- (set(nodeFlags.keys()) == set(nodeFlags_.keys()) and val == val_):
+ if (
+ (cycleCount == max_amount_cycles)
+ or (not nodeFlags_)
+ or (set(nodeFlags.keys()) == set(nodeFlags_.keys()) and val == val_)
+ ):
# copy values to final dict
nodeFlags, inval, val = nodeFlags_, inval_, val_
# no more modifications to those layers will be done
@@ -1599,7 +2081,9 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc
networkNodeLayer.endEditCommand()
# try to load auxiliary line layer to fill it with invalid lines
featList = self.getFlagLines(networkLayer, val, inval)
- invalidLinesLog = self.tr("Invalid lines were exposed in line flags layer.")
+ invalidLinesLog = self.tr(
+ "Invalid lines were exposed in line flags layer."
+ )
if feedback is not None:
multiStepFeedback.pushInfo(invalidLinesLog)
multiStepFeedback.setCurrentStep(max_amount_cycles)
@@ -1622,16 +2106,23 @@ def verifyNetworkDirectioning(self, networkLayer, networkNodeLayer, frame, searc
if selectValid:
networkLayer.selectByIds(list(val.keys()))
if feedback is not None:
- percValid = float(len(val))*100.0/float(networkLayer.featureCount()) if networkLayer.featureCount() else 0
+ percValid = (
+ float(len(val)) * 100.0 / float(networkLayer.featureCount())
+ if networkLayer.featureCount()
+ else 0
+ )
if nodeFlags:
- msg = self.tr('{0} nodes may be invalid ({1:.2f}' + '% of network is well directed). Check flags.')\
- .format(len(nodeFlags), percValid)
+ msg = self.tr(
+ "{0} nodes may be invalid ({1:.2f}"
+ + "% of network is well directed). Check flags."
+ ).format(len(nodeFlags), percValid)
else:
- msg = self.tr('{1:.2f}' + '% of network is well directed.')\
- .format(len(nodeFlags), percValid)
+ msg = self.tr("{1:.2f}" + "% of network is well directed.").format(
+ len(nodeFlags), percValid
+ )
multiStepFeedback.pushInfo(msg)
return nodeFlags, featList, self.nodeIdDict
-
+
def getFlagLines(self, networkLayer, val, inval):
# get non-validated lines and add it to invalid lines layer as well
nonValidatedLines = set()
@@ -1641,10 +2132,14 @@ def getFlagLines(self, networkLayer, val, inval):
# ignore if line are validated
continue
nonValidatedLines.add(line)
- featList = self.getAuxiliaryLines(fields=self.getFlagFields(), invalidLinesDict=inval,\
- nonValidatedLines=nonValidatedLines, networkLayerName=networkLayer.name())
+ featList = self.getAuxiliaryLines(
+ fields=self.getFlagFields(),
+ invalidLinesDict=inval,
+ nonValidatedLines=nonValidatedLines,
+ networkLayerName=networkLayer.name(),
+ )
return featList
-
+
def mergeNetworkLines(self, line_a, line_b, layer):
"""
Merge 2 lines of the same layer (it is assumed that they share the same set od attributes - except for ID and geometry).
@@ -1655,7 +2150,7 @@ def mergeNetworkLines(self, line_a, line_b, layer):
:return: (bool) True if method runs OK or False, if lines do not touch.
"""
# check if original layer is a multipart
- isMulti = QgsWkbTypes.isMultiType(int(layer.wkbType()))
+ isMulti = QgsWkbTypes.isMultiType(layer.wkbType())
# retrieve lines geometries
geometry_a = line_a.geometry()
geometry_b = line_b.geometry()
@@ -1676,16 +2171,16 @@ def mergeNetworkLines(self, line_a, line_b, layer):
layer.updateFeature(line_a)
return True
return False
-
+
def getFlagFields(self):
fields = QgsFields()
- fields.append(QgsField('reason',QVariant.String))
+ fields.append(QgsField("reason", QVariant.String))
return fields
def createNewInvalidLineFeature(self, feat_geom, reason, fields):
"""
Creates a new feature to be added to invalid lines layer.
- :param feat_geom: (QgsGeometry)
+ :param feat_geom: (QgsGeometry)
:param reason: (str) reason of line invalidation.
:param fields: (QgsFields) object containing all fields from layer.
:return: (QgsFeature) new feature.
@@ -1694,4 +2189,4 @@ def createNewInvalidLineFeature(self, feat_geom, reason, fields):
feat = QgsFeature(fields)
# set geometry
feat.setGeometry(feat_geom)
- return feat
\ No newline at end of file
+ return feat
diff --git a/DsgTools/core/GeometricTools/spatialRelationsHandler.py b/DsgTools/core/GeometricTools/spatialRelationsHandler.py
index 87da0168e..537b1b9da 100644
--- a/DsgTools/core/GeometricTools/spatialRelationsHandler.py
+++ b/DsgTools/core/GeometricTools/spatialRelationsHandler.py
@@ -20,23 +20,24 @@
* *
***************************************************************************/
"""
-from __future__ import absolute_import
+
+import concurrent.futures
from itertools import tee, combinations
from collections import defaultdict, OrderedDict
-
-from qgis.core import (Qgis,
- QgsFeature,
- QgsProject,
- QgsGeometry,
- QgsExpression,
- QgsVectorLayer,
- QgsSpatialIndex,
- QgsFeatureRequest,
- QgsProcessingContext,
- QgsProcessingFeedback,
- QgsProcessingMultiStepFeedback)
-from qgis.analysis import QgsGeometrySnapper, QgsInternalGeometrySnapper
+import os
+
+from qgis.core import (
+ QgsProject,
+ QgsGeometry,
+ QgsExpression,
+ QgsVectorLayer,
+ QgsSpatialIndex,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
+ QgsProcessingMultiStepFeedback,
+ QgsFeatureRequest,
+)
from qgis.PyQt.Qt import QObject
from qgis.PyQt.QtCore import QRegExp, QCoreApplication
from qgis.PyQt.QtGui import QRegExpValidator
@@ -46,29 +47,48 @@
from .layerHandler import LayerHandler
from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner
+
class SpatialRelationsHandler(QObject):
__predicates = (
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "equals"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not equals"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "disjoint"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "intersects"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not intersect"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "touches"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not touch"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "crosses"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not cross"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "within"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not within"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "overlaps"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not overlap"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "contains"),
- QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not contain")
- )
- EQUALS, NOTEQUALS, DISJOINT, INTERSECTS, NOTINTERSECTS, \
- TOUCHES, NOTTOUCHES, CROSSES, NOTCROSSES, WITHIN, NOTWITHIN, OVERLAPS, \
- NOTOVERLAPS, CONTAINS, NOTCONTAINS = range(len(__predicates))
-
- def __init__(self, iface = None, parent = None):
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "equals"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not equals"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "disjoint"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "intersects"),
+ QCoreApplication.translate(
+ "EnforceSpatialRulesAlgorithm", "does not intersect"
+ ),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "touches"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not touch"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "crosses"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not cross"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "within"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "is not within"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "overlaps"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not overlap"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "contains"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "does not contain"),
+ QCoreApplication.translate("EnforceSpatialRulesAlgorithm", "de9im"),
+ )
+ (
+ EQUALS,
+ NOTEQUALS,
+ DISJOINT,
+ INTERSECTS,
+ NOTINTERSECTS,
+ TOUCHES,
+ NOTTOUCHES,
+ CROSSES,
+ NOTCROSSES,
+ WITHIN,
+ NOTWITHIN,
+ OVERLAPS,
+ NOTOVERLAPS,
+ CONTAINS,
+ NOTCONTAINS,
+ DE9IM,
+ ) = range(len(__predicates))
+
+ def __init__(self, iface=None, parent=None):
super(SpatialRelationsHandler, self).__init__()
self.parent = parent
self.iface = iface
@@ -79,75 +99,94 @@ def __init__(self, iface = None, parent = None):
self.geometryHandler = GeometryHandler(iface)
self.algRunner = AlgRunner()
- def validateTerrainModel(self, contourLyr, heightFieldName, threshold,\
- onlySelected=False, geoBoundsLyr=None, context=None, feedback=None):
+ def validateTerrainModel(
+ self,
+ contourLyr,
+ heightFieldName,
+ threshold,
+ onlySelected=False,
+ geoBoundsLyr=None,
+ context=None,
+ feedback=None,
+ ):
"""
Does several validation procedures with terrain elements.
"""
invalidDict = OrderedDict()
- multiStepFeedback = QgsProcessingMultiStepFeedback(7, feedback) #ajustar depois
- multiStepFeedback.setCurrentStep(0)
- multiStepFeedback.setProgressText(self.tr("Splitting lines..."))
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(7, feedback)
+ if feedback is not None
+ else None
+ ) # ajustar depois
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(0)
+ multiStepFeedback.setProgressText(self.tr("Splitting lines..."))
splitLinesLyr = self.algRunner.runSplitLinesWithLines(
- contourLyr,
- contourLyr,
- context=context,
- feedback=multiStepFeedback
+ contourLyr, contourLyr, context=context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(1)
- multiStepFeedback.setProgressText(self.tr("Building aux structure..."))
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(1)
+ multiStepFeedback.setProgressText(self.tr("Building aux structure..."))
(
- contourSpatialIdx, contourIdDict, contourNodeDict, heightsDict
+ contourSpatialIdx,
+ contourIdDict,
+ contourNodeDict,
+ heightsDict,
) = self.buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict(
inputLyr=splitLinesLyr,
attributeName=heightFieldName,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
- multiStepFeedback.setCurrentStep(2)
- geoBoundsGeomEngine, geoBoundsPolygonEngine = (None, None) if geoBoundsLyr is None\
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(2)
+ geoBoundsGeomEngine, geoBoundsPolygonEngine = (
+ (None, None)
+ if geoBoundsLyr is None
else self.getGeoBoundsGeomEngine(
- geoBoundsLyr,
- context=context,
- feedback=multiStepFeedback
+ geoBoundsLyr, context=context, feedback=multiStepFeedback
+ )
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(3)
+ multiStepFeedback.setProgressText(
+ self.tr("Validating contour relations...")
)
- multiStepFeedback.setCurrentStep(3)
- multiStepFeedback.setProgressText(self.tr("Validating contour relations..."))
contourFlags = self.validateContourRelations(
contourNodeDict,
heightFieldName,
geoBoundsGeomEngine=geoBoundsGeomEngine,
- geoBoundsPolygonEngine=geoBoundsPolygonEngine
+ geoBoundsPolygonEngine=geoBoundsPolygonEngine,
)
invalidDict.update(contourFlags)
- multiStepFeedback.setCurrentStep(4)
- multiStepFeedback.setProgressText(self.tr("Finding contour out of threshold..."))
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(4)
+ multiStepFeedback.setProgressText(
+ self.tr("Finding contour out of threshold...")
+ )
contourOutOfThresholdDict = self.findContourOutOfThreshold(
- heightsDict,
- threshold,
- feedback=multiStepFeedback
+ heightsDict, threshold, feedback=multiStepFeedback
)
invalidDict.update(contourOutOfThresholdDict)
if len(invalidDict) > 0:
return invalidDict
- multiStepFeedback.setCurrentStep(5)
- multiStepFeedback.setProgressText(self.tr("Building contour area dict.."))
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(5)
+ multiStepFeedback.setProgressText(self.tr("Building contour area dict.."))
contourAreaDict = self.buildContourAreaDict(
inputLyr=splitLinesLyr,
geoBoundsLyr=geoBoundsLyr,
attributeName=heightFieldName,
contourSpatialIdx=contourSpatialIdx,
contourIdDict=contourIdDict,
- depressionExpression=None,#TODO
+ depressionExpression=None, # TODO
context=context,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
- multiStepFeedback.setCurrentStep(6)
- multiStepFeedback.setProgressText(self.tr("Finding missing contours..."))
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(6)
+ multiStepFeedback.setProgressText(self.tr("Finding missing contours..."))
misingContourDict = self.findMissingContours(
- contourAreaDict,
- threshold,
- context=context,
- feedback=multiStepFeedback
+ contourAreaDict, threshold, context=context, feedback=multiStepFeedback
)
invalidDict.update(misingContourDict)
return invalidDict
@@ -158,25 +197,33 @@ def getGeoBoundsGeomEngine(self, geoBoundsLyr, context=None, feedback=None):
"""
if geoBoundsLyr is None:
return None, None
- multiStepFeedback = QgsProcessingMultiStepFeedback(2, feedback)
- multiStepFeedback.setCurrentStep(0)
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(2, feedback)
+ if feedback is not None
+ else None
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(0)
mergedPolygonLyr = self.algRunner.runAggregate(
- geoBoundsLyr,
- context=context,
- feedback=multiStepFeedback
+ geoBoundsLyr, context=context, feedback=multiStepFeedback
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(1)
+ mergedPolygonGeom = (
+ [i for i in mergedPolygonLyr.getFeatures()][0].geometry()
+ if mergedPolygonLyr.featureCount() != 0
+ else None
)
- multiStepFeedback.setCurrentStep(1)
- mergedPolygonGeom = [i for i in mergedPolygonLyr.getFeatures()][0].geometry() \
- if mergedPolygonLyr.featureCount() != 0 else None
if mergedPolygonGeom is None:
return None, None
polygonBoundary = self.algRunner.runBoundary(
- mergedPolygonLyr,
- context=context,
- feedback=multiStepFeedback
+ mergedPolygonLyr, context=context, feedback=multiStepFeedback
+ )
+ mergedGeom = (
+ [i for i in polygonBoundary.getFeatures()][0].geometry()
+ if polygonBoundary.featureCount() != 0
+ else None
)
- mergedGeom = [i for i in polygonBoundary.getFeatures()][0].geometry()\
- if polygonBoundary.featureCount() != 0 else None
if mergedGeom is None:
return None, None
polygonEngine = QgsGeometry.createGeometryEngine(mergedPolygonGeom.constGet())
@@ -185,9 +232,17 @@ def getGeoBoundsGeomEngine(self, geoBoundsLyr, context=None, feedback=None):
engine.prepareGeometry()
return engine, polygonEngine
- def buildContourAreaDict(self, inputLyr, geoBoundsLyr, attributeName,\
- contourSpatialIdx, contourIdDict, depressionExpression=None,\
- context=None, feedback=None):
+ def buildContourAreaDict(
+ self,
+ inputLyr,
+ geoBoundsLyr,
+ attributeName,
+ contourSpatialIdx,
+ contourIdDict,
+ depressionExpression=None,
+ context=None,
+ feedback=None,
+ ):
"""
Builds a dict in the following format:
{
@@ -197,29 +252,37 @@ def buildContourAreaDict(self, inputLyr, geoBoundsLyr, attributeName,\
}
"""
contourAreaDict = {
- 'areaSpatialIdx' : QgsSpatialIndex(),
- 'areaIdDict' : {},
- 'areaContourRelations' : {}
+ "areaSpatialIdx": QgsSpatialIndex(),
+ "areaIdDict": {},
+ "areaContourRelations": {},
}
- multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback)
- multiStepFeedback.setCurrentStep(0)
- boundsLineLyr = self.algRunner.runPolygonsToLines(
- geoBoundsLyr, context, feedback=multiStepFeedback
- ) if geoBoundsLyr is not None else None
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(4, feedback)
+ if feedback is not None
+ else None
+ )
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(0)
+ boundsLineLyr = (
+ self.algRunner.runPolygonsToLines(
+ geoBoundsLyr, context, feedback=multiStepFeedback
+ )
+ if geoBoundsLyr is not None
+ else None
+ )
lineLyrList = [inputLyr] if boundsLineLyr is None else [inputLyr, boundsLineLyr]
- multiStepFeedback.setCurrentStep(1)
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(1)
linesLyr = self.algRunner.runMergeVectorLayers(
- lineLyrList,
- context,
- feedback=multiStepFeedback
+ lineLyrList, context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(2)
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(2)
polygonLyr = self.algRunner.runPolygonize(
- linesLyr,
- context,
- feedback=multiStepFeedback
+ linesLyr, context, feedback=multiStepFeedback
)
- multiStepFeedback.setCurrentStep(3)
+ if multiStepFeedback is not None:
+ multiStepFeedback.setCurrentStep(3)
self.populateContourAreaDict(
polygonLyr,
geoBoundsLyr,
@@ -227,80 +290,104 @@ def buildContourAreaDict(self, inputLyr, geoBoundsLyr, attributeName,\
contourAreaDict,
contourSpatialIdx,
contourIdDict,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
return contourAreaDict
-
- def populateContourAreaDict(self, polygonLyr, geoBoundsLyr, attributeName,
- contourAreaDict, contourSpatialIdx, contourIdDict, feedback=None):
- boundsGeom = [i for i in geoBoundsLyr.getFeatures()][0].geometry() if geoBoundsLyr is not None else None
+
+ def populateContourAreaDict(
+ self,
+ polygonLyr,
+ geoBoundsLyr,
+ attributeName,
+ contourAreaDict,
+ contourSpatialIdx,
+ contourIdDict,
+ feedback=None,
+ ):
+ boundsGeom = (
+ [i for i in geoBoundsLyr.getFeatures()][0].geometry()
+ if geoBoundsLyr is not None
+ else None
+ )
nPolygons = polygonLyr.featureCount()
- size = 100/nPolygons if nPolygons else 0
+ size = 100 / nPolygons if nPolygons else 0
for current, feat in enumerate(polygonLyr.getFeatures()):
if feedback is not None and feedback.isCanceled():
break
featId = feat.id()
geom = feat.geometry()
featBB = geom.boundingBox()
- contourAreaDict['areaSpatialIdx'].addFeature(feat)
- contourAreaDict['areaIdDict'][featId] = feat
- if featId not in contourAreaDict['areaContourRelations']:
- contourAreaDict['areaContourRelations'][featId] = defaultdict(list)
+ contourAreaDict["areaSpatialIdx"].addFeature(feat)
+ contourAreaDict["areaIdDict"][featId] = feat
+ if featId not in contourAreaDict["areaContourRelations"]:
+ contourAreaDict["areaContourRelations"][featId] = defaultdict(list)
for contourId in contourSpatialIdx.intersects(featBB):
if feedback is not None and feedback.isCanceled():
break
candidateContourFeat = contourIdDict[contourId]
if candidateContourFeat.geometry().intersects(geom):
contourValue = candidateContourFeat[attributeName]
- candidateContourGeom = candidateContourFeat.geometry()\
- if boundsGeom is not None and\
- not candidateContourFeat.geometry().intersects(boundsGeom)\
+ candidateContourGeom = (
+ candidateContourFeat.geometry()
+ if boundsGeom is not None
+ and not candidateContourFeat.geometry().intersects(boundsGeom)
else candidateContourFeat.geometry().intersection(boundsGeom)
- contourAreaDict['areaContourRelations'][featId][contourValue].append(candidateContourGeom)
+ )
+ contourAreaDict["areaContourRelations"][featId][
+ contourValue
+ ].append(candidateContourGeom)
if feedback is not None:
feedback.setProgress(current * size)
def findContourOutOfThreshold(self, heightsDict, threshold, feedback=None):
contourOutOfThresholdDict = OrderedDict()
- size = 100/len(heightsDict) if len(heightsDict) else 0
- for current, (k,valueSet) in enumerate(heightsDict.items()):
+ size = 100 / len(heightsDict) if len(heightsDict) else 0
+ for current, (k, valueSet) in enumerate(heightsDict.items()):
if feedback is not None and feedback.isCanceled():
break
for i in valueSet:
if feedback is not None and feedback.isCanceled():
break
if k % threshold != 0:
- contourOutOfThresholdDict[i.asWkb()] = self.tr('Contour out of threshold.')
+ contourOutOfThresholdDict[i.asWkb()] = self.tr(
+ "Contour out of threshold."
+ )
if feedback is not None:
feedback.setProgress(current * size)
return contourOutOfThresholdDict
- def findMissingContours(self, contourAreaDict, threshold, context=None, feedback=None):
+ def findMissingContours(
+ self, contourAreaDict, threshold, context=None, feedback=None
+ ):
"""
Can be more efficient, the first draft will be of several for inside for.
"""
- relationCount = len(contourAreaDict['areaContourRelations'])
+ relationCount = len(contourAreaDict["areaContourRelations"])
size = 100 / relationCount if relationCount else 0
missingContourFlagDict = dict()
- for current, (areaId, heightDict) in enumerate(contourAreaDict['areaContourRelations'].items()):
+ for current, (areaId, heightDict) in enumerate(
+ contourAreaDict["areaContourRelations"].items()
+ ):
if feedback is not None and feedback.isCanceled():
break
if len(heightDict) < 2:
continue
for h1, h2 in combinations(heightDict.keys(), 2):
- if abs(h1-h2) <= threshold:
+ if abs(h1 - h2) <= threshold:
continue
- min_h12 = min(h1, h2) #done to fix the way flags are built.
+ min_h12 = min(h1, h2) # done to fix the way flags are built.
max_h12 = max(h1, h2)
for geom in heightDict[h1]:
if feedback is not None and feedback.isCanceled():
break
- shortestLineGeomList = [geom.shortestLine(i) for i in heightDict[h2]]
+ shortestLineGeomList = [
+ geom.shortestLine(i) for i in heightDict[h2]
+ ]
shortestLine = min(shortestLineGeomList, key=lambda x: x.length())
missingContourFlagDict.update(
{
- shortestLine.asWkb() : self.tr(
- 'Missing contour between contour lines of values {v1} and {v2}'
+ shortestLine.asWkb(): self.tr(
+ "Missing contour between contour lines of values {v1} and {v2}"
).format(v1=min_h12, v2=max_h12)
}
)
@@ -308,7 +395,16 @@ def findMissingContours(self, contourAreaDict, threshold, context=None, feedback
feedback.setProgress(current * size)
return missingContourFlagDict
- def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, heightFieldName, threshold, topologyRadius, feedback=None):
+ def relateDrainagesWithContours(
+ self,
+ drainageLyr,
+ contourLyr,
+ frameLinesLyr,
+ heightFieldName,
+ threshold,
+ topologyRadius,
+ feedback=None,
+ ):
"""
Checks the conformity between directed drainages and contours.
Drainages must be propperly directed.
@@ -331,20 +427,27 @@ def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, he
4- After relating everything,
"""
maxSteps = 4
- multiStepFeedback = QgsProcessingMultiStepFeedback(maxSteps, feedback) if feedback is not None else None
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(maxSteps, feedback)
+ if feedback is not None
+ else None
+ )
currentStep = 0
if multiStepFeedback is not None:
if multiStepFeedback.isCanceled():
return []
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
- multiStepFeedback.pushInfo(
- self.tr('Building contour structures...')
- )
- contourSpatialIdx, contourIdDict, contourNodeDict, heightsDict = self.buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict(
+ multiStepFeedback.pushInfo(self.tr("Building contour structures..."))
+ (
+ contourSpatialIdx,
+ contourIdDict,
+ contourNodeDict,
+ heightsDict,
+ ) = self.buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict(
inputLyr=contourLyr,
attributeName=heightFieldName,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
if multiStepFeedback is not None:
if multiStepFeedback.isCanceled():
@@ -352,14 +455,13 @@ def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, he
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
multiStepFeedback.pushInfo(
- self.tr('Validating contour structures. Check 1/4...')
- )
- invalidDict = self.validateContourRelations(
- contourNodeDict,
- feedback=multiStepFeedback
+ self.tr("Validating contour structures. Check 1/4...")
)
+ invalidDict = self.validateContourRelations(
+ contourNodeDict, feedback=multiStepFeedback
+ )
if invalidDict:
- multiStepFeedback.setCurrentStep(maxSteps-1)
+ multiStepFeedback.setCurrentStep(maxSteps - 1)
return invalidDict
if multiStepFeedback is not None:
@@ -367,31 +469,31 @@ def relateDrainagesWithContours(self, drainageLyr, contourLyr, frameLinesLyr, he
return []
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
- multiStepFeedback.pushInfo(
- self.tr('Building drainage spatial index...')
- )
- drainageSpatialIdx, drainageIdDict, drainageNodeDict = self.buildSpatialIndexAndIdDictAndRelateNodes(
- inputLyr=drainageLyr,
- feedback=multiStepFeedback
+ multiStepFeedback.pushInfo(self.tr("Building drainage spatial index..."))
+ (
+ drainageSpatialIdx,
+ drainageIdDict,
+ drainageNodeDict,
+ ) = self.buildSpatialIndexAndIdDictAndRelateNodes(
+ inputLyr=drainageLyr, feedback=multiStepFeedback
)
if multiStepFeedback is not None:
if multiStepFeedback.isCanceled():
return []
multiStepFeedback.setCurrentStep(currentStep)
currentStep += 1
- multiStepFeedback.pushInfo(
- self.tr('Relating contours with drainages...')
- )
+ multiStepFeedback.pushInfo(self.tr("Relating contours with drainages..."))
intersectionDict = self.buildIntersectionDict(
drainageLyr,
drainageIdDict,
drainageSpatialIdx,
contourIdDict,
- contourIdDict
- )
+ contourIdDict,
+ )
- def buildSpatialIndexAndIdDictAndRelateNodes(self, inputLyr, feedback=None,\
- featureRequest=None):
+ def buildSpatialIndexAndIdDictAndRelateNodes(
+ self, inputLyr, feedback=None, featureRequest=None
+ ):
"""
creates a spatial index for the input layer
:param inputLyr: (QgsVectorLayer) input layer;
@@ -402,13 +504,16 @@ def buildSpatialIndexAndIdDictAndRelateNodes(self, inputLyr, feedback=None,\
idDict = {}
nodeDict = defaultdict(list)
featCount = inputLyr.featureCount()
- size = 100/featCount if featCount else 0
- iterator = inputLyr.getFeatures() if featureRequest is None \
+ size = 100 / featCount if featCount else 0
+ iterator = (
+ inputLyr.getFeatures()
+ if featureRequest is None
else inputLyr.getFeatures(featureRequest)
- firstAndLastNode = lambda x:self.geometryHandler.getFirstAndLastNode(
+ )
+ firstAndLastNode = lambda x: self.geometryHandler.getFirstAndLastNode(
inputLyr, x
)
- addFeatureAlias = lambda x : self.addFeatureToSpatialIndexAndNodeDict(
+ addFeatureAlias = lambda x: self.addFeatureToSpatialIndexAndNodeDict(
current=x[0],
feat=x[1],
spatialIdx=spatialIdx,
@@ -416,13 +521,14 @@ def buildSpatialIndexAndIdDictAndRelateNodes(self, inputLyr, feedback=None,\
nodeDict=nodeDict,
size=size,
firstAndLastNode=firstAndLastNode,
- feedback=feedback
+ feedback=feedback,
)
list(map(addFeatureAlias, enumerate(iterator)))
return spatialIdx, idDict, nodeDict
- def addFeatureToSpatialIndexAndNodeDict(self, current, feat, spatialIdx,\
- idDict, nodeDict, size, feedback):
+ def addFeatureToSpatialIndexAndNodeDict(
+ self, current, feat, spatialIdx, idDict, nodeDict, size, feedback
+ ):
"""
Adds feature to spatial index. Used along side with a python map
operator to improve performance.
@@ -445,43 +551,52 @@ def addFeatureToSpatialIndexAndNodeDict(self, current, feat, spatialIdx,\
nodeDict[firstNode] += [feat]
nodeDict[lastNode] += [feat]
self.layerHandler.addFeatureToSpatialIndex(
- current,
- feat,
- spatialIdx,
- idDict,
- size,
- feedback
+ current, feat, spatialIdx, idDict, size, feedback
)
- def buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict(self, inputLyr,\
- attributeName, feedback=None, featureRequest=None):
- """
-
- """
+ def buildSpatialIndexAndIdDictRelateNodesAndAttributeGroupDict(
+ self, inputLyr, attributeName, feedback=None, featureRequest=None
+ ):
+ """ """
spatialIdx = QgsSpatialIndex()
idDict = {}
nodeDict = defaultdict(list)
attributeGroupDict = {}
featCount = inputLyr.featureCount()
- size = 100/featCount if featCount else 0
- iterator = inputLyr.getFeatures() if featureRequest is None else inputLyr.getFeatures(featureRequest)
- addFeatureAlias = lambda x : self.addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(
- current=x[0],
- feat=x[1],
- spatialIdx=spatialIdx,
- idDict=idDict,
- nodeDict=nodeDict,
- size=size,
- attributeGroupDict=attributeGroupDict,
- attributeName=attributeName,
- feedback=feedback
+ size = 100 / featCount if featCount else 0
+ iterator = (
+ inputLyr.getFeatures()
+ if featureRequest is None
+ else inputLyr.getFeatures(featureRequest)
+ )
+ addFeatureAlias = (
+ lambda x: self.addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(
+ current=x[0],
+ feat=x[1],
+ spatialIdx=spatialIdx,
+ idDict=idDict,
+ nodeDict=nodeDict,
+ size=size,
+ attributeGroupDict=attributeGroupDict,
+ attributeName=attributeName,
+ feedback=feedback,
+ )
)
list(map(addFeatureAlias, enumerate(iterator)))
return spatialIdx, idDict, nodeDict, attributeGroupDict
-
- def addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(self, current, feat,\
- spatialIdx, idDict, nodeDict, size, attributeGroupDict,\
- attributeName, feedback):
+
+ def addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(
+ self,
+ current,
+ feat,
+ spatialIdx,
+ idDict,
+ nodeDict,
+ size,
+ attributeGroupDict,
+ attributeName,
+ feedback,
+ ):
"""
Adds feature to spatial index. Used along side with a python map operator
to improve performance.
@@ -498,17 +613,17 @@ def addFeatureToSpatialIndexNodeDictAndAttributeGroupDict(self, current, feat,\
attributeGroupDict[attrValue] = set()
attributeGroupDict[attrValue].add(feat.geometry())
self.addFeatureToSpatialIndexAndNodeDict(
- current,
- feat,
- spatialIdx,
- idDict,
- nodeDict,
- size,
- feedback
+ current, feat, spatialIdx, idDict, nodeDict, size, feedback
)
-
- def validateContourRelations(self, contourNodeDict, heightFieldName,\
- geoBoundsGeomEngine=None, geoBoundsPolygonEngine=None, feedback=None):
+
+ def validateContourRelations(
+ self,
+ contourNodeDict,
+ heightFieldName,
+ geoBoundsGeomEngine=None,
+ geoBoundsPolygonEngine=None,
+ feedback=None,
+ ):
"""
param: contourNodeDict: (dict) dictionary with contour nodes
Invalid contours:
@@ -518,35 +633,42 @@ def validateContourRelations(self, contourNodeDict, heightFieldName,\
"""
invalidDict = dict()
contoursNumber = len(contourNodeDict)
- step = 100/contoursNumber if contoursNumber else 0
+ step = 100 / contoursNumber if contoursNumber else 0
for current, (node, contourList) in enumerate(contourNodeDict.items()):
nodeGeom = QgsGeometry.fromPointXY(node)
nodeWkb = nodeGeom.asWkb()
if feedback is not None and feedback.isCanceled():
break
- if geoBoundsPolygonEngine is not None and \
- not geoBoundsPolygonEngine.intersects(nodeGeom.constGet()):
+ if (
+ geoBoundsPolygonEngine is not None
+ and not geoBoundsPolygonEngine.intersects(nodeGeom.constGet())
+ ):
continue
- if len(contourList) == 1 and \
- (geoBoundsGeomEngine is not None and not (
- geoBoundsGeomEngine.intersects(nodeGeom.constGet()) or \
- geoBoundsGeomEngine.distance(nodeGeom.constGet()) < 10**-9
- )):
+ if len(contourList) == 1 and (
+ geoBoundsGeomEngine is not None
+ and not (
+ geoBoundsGeomEngine.intersects(nodeGeom.constGet())
+ or geoBoundsGeomEngine.distance(nodeGeom.constGet()) < 10**-9
+ )
+ ):
invalidDict[nodeWkb] = self.tr(
- 'Contour lines must be closed or intersect the geographic boundary.'
- )
- if len(contourList) == 2 and contourList[0][heightFieldName] != contourList[1][heightFieldName]:
+ "Contour lines must be closed or intersect the geographic boundary."
+ )
+ if (
+ len(contourList) == 2
+ and contourList[0][heightFieldName] != contourList[1][heightFieldName]
+ ):
invalidDict[nodeWkb] = self.tr(
- 'Contour lines touch each other and have different height values.'
- )
+ "Contour lines touch each other and have different height values."
+ )
if len(contourList) > 2:
invalidDict[nodeWkb] = self.tr(
- 'Contour lines intersect each other. Contour lines must touch itself or only one other with same height value.'
- )
+ "Contour lines intersect each other. Contour lines must touch itself or only one other with same height value."
+ )
if feedback is not None:
feedback.setProgress(step * current)
return invalidDict
-
+
def isDangle(self, point, featureDict, spatialIdx, searchRadius=10**-15):
"""
:param point: (QgsPointXY) node tested as dangle;
@@ -559,75 +681,105 @@ def isDangle(self, point, featureDict, spatialIdx, searchRadius=10**-15):
buffer = qgisPoint.buffer(searchRadius, -1)
bufferBB = buffer.boundingBox()
for featid in spatialIdx.intersects(bufferBB):
- if buffer.intersects(featureDict[featid].geometry()) and \
- qgisPoint.distance(featureDict[featid].geometry()) < 10**-9:
+ if (
+ buffer.intersects(featureDict[featid].geometry())
+ and qgisPoint.distance(featureDict[featid].geometry()) < 10**-9
+ ):
return True
return False
- def buildIntersectionDict(self, drainageLyr, drainageIdDict, drainageSpatialIdx, contourIdDict, contourSpatialIdx, feedback=None):
+ def buildIntersectionDict(
+ self,
+ drainageLyr,
+ drainageIdDict,
+ drainageSpatialIdx,
+ contourIdDict,
+ contourSpatialIdx,
+ feedback=None,
+ ):
intersectionDict = dict()
flagDict = dict()
- firstNode = lambda x:self.geometryHandler.getFirstNode(drainageLyr, x)
- lastNode = lambda x:self.geometryHandler.getLastNode(drainageLyr, x)
- addItemsToIntersectionDict = lambda x:self.addItemsToIntersectionDict(
+ firstNode = lambda x: self.geometryHandler.getFirstNode(drainageLyr, x)
+ lastNode = lambda x: self.geometryHandler.getLastNode(drainageLyr, x)
+ addItemsToIntersectionDict = lambda x: self.addItemsToIntersectionDict(
dictItem=x,
contourSpatialIdx=contourSpatialIdx,
contourIdDict=contourIdDict,
intersectionDict=intersectionDict,
firstNode=firstNode,
lastNode=lastNode,
- flagDict=flagDict
+ flagDict=flagDict,
)
# map for, this means: for item in drainageIdDict.items() ...
list(map(addItemsToIntersectionDict, drainageIdDict.items()))
return intersectionDict
-
- def addItemsToIntersectionDict(self, dictItem, contourSpatialIdx, contourIdDict, intersectionDict, firstNode, lastNode, flagDict):
+
+ def addItemsToIntersectionDict(
+ self,
+ dictItem,
+ contourSpatialIdx,
+ contourIdDict,
+ intersectionDict,
+ firstNode,
+ lastNode,
+ flagDict,
+ ):
gid, feat = dictItem
featBB = feat.geometry().boundingBox()
featid = feat.id()
featGeom = feat.geometry()
intersectionDict[featid] = {
- 'start_point':firstNode(featGeom),
- 'end_point':lastNode(featGeom),
- 'intersection_list':[]
- }
+ "start_point": firstNode(featGeom),
+ "end_point": lastNode(featGeom),
+ "intersection_list": [],
+ }
for candidateId in contourSpatialIdx.intersects(featBB):
candidate = contourIdDict[candidateId]
candidateGeom = candidate.geometry()
- if candidateGeom.intersects(featGeom): #add intersection
+ if candidateGeom.intersects(featGeom): # add intersection
intersectionGeom = candidateGeom.intersection(featGeom)
- intersectionList += [intersectionGeom.asPoint()] if not intersectionGeom.asMultiPoint() else intersectionGeom.asMultiPoint()
+ intersectionList += (
+ [intersectionGeom.asPoint()]
+ if not intersectionGeom.asMultiPoint()
+ else intersectionGeom.asMultiPoint()
+ )
flagFeature = True if len(intersectionList) > 1 else False
for inter in intersectionList:
if flagFeature:
- flagDict[inter] = self.tr('Contour id={c_id} intersects drainage id={d_id} in more than one point').format(
- c_id=candidateId,
- d_id=gid
- )
+ flagDict[inter] = self.tr(
+ "Contour id={c_id} intersects drainage id={d_id} in more than one point"
+ ).format(c_id=candidateId, d_id=gid)
newIntersection = {
- 'contour_id' : candidateId,
- 'intersection_point' : inter
+ "contour_id": candidateId,
+ "intersection_point": inter,
}
- intersectionDict[featid]['intersection_list'].append(newIntersection)
-
+ intersectionDict[featid]["intersection_list"].append(
+ newIntersection
+ )
+
def validateIntersections(self, intersectionDict, heightFieldName, threshold):
"""
1- Sort list
- 2-
+ 2-
"""
validatedIdsDict = dict()
invalidatedIdsDict = dict()
for id, values in intersectionDict.items():
- interList = values['intersection_list']
+ interList = values["intersection_list"]
if len(interList) <= 1:
continue
- #sort list by distance from start point
- interList.sort(key=lambda x: x['intersection_point'].geometry().distance(values['start_point']))
+ # sort list by distance from start point
+ interList.sort(
+ key=lambda x: x["intersection_point"]
+ .geometry()
+ .distance(values["start_point"])
+ )
referenceElement = interList[0]
for idx, elem in enumerate(interList[1::], start=1):
elemen_id = elem.id()
- if int(elem[heightFieldName]) != threshold*idx + int(referenceElement[heightFieldName]):
+ if int(elem[heightFieldName]) != threshold * idx + int(
+ referenceElement[heightFieldName]
+ ):
invalidatedIdsDict[elemen_id] = elem
else:
if elemen_id not in invalidatedIdsDict:
@@ -636,41 +788,47 @@ def validateIntersections(self, intersectionDict, heightFieldName, threshold):
if id in invalidatedIdsDict:
validatedIdsDict.pop(id)
return validatedIdsDict, invalidatedIdsDict
-
- def validateContourPolygons(self, contourPolygonDict, contourPolygonIdx, threshold, heightFieldName, depressionValueDict=None):
- hilltopDict = self.buildHilltopDict(
- contourPolygonDict,
- contourPolygonIdx
- )
+
+ def validateContourPolygons(
+ self,
+ contourPolygonDict,
+ contourPolygonIdx,
+ threshold,
+ heightFieldName,
+ depressionValueDict=None,
+ ):
+ hilltopDict = self.buildHilltopDict(contourPolygonDict, contourPolygonIdx)
invalidDict = dict()
for hilltopGeom, hilltop in hilltopDict.items():
localFlagList = []
- polygonList = hilltop['downhill']
- feat = hilltop['feat']
+ polygonList = hilltop["downhill"]
+ feat = hilltop["feat"]
if len(polygonList) < 2:
break
# sort polygons by area, from minimum to max
polygonList.sort(key=lambda x: x.geometry().area())
- #pair comparison
- a, b = tee([feat]+polygonList)
+ # pair comparison
+ a, b = tee([feat] + polygonList)
next(b, None)
for elem1, elem2 in zip(a, b):
- if abs(elem1[heightFieldName]-elem2[heightFieldName]) != threshold:
+ if abs(elem1[heightFieldName] - elem2[heightFieldName]) != threshold:
elem1GeomKey = elem1.geometry().asWkb()
if elem1GeomKey not in invalidDict:
invalidDict[elem1GeomKey] = []
- invalidDict[elem1GeomKey] += [self.tr(
- 'Difference between contour with values {id1} \
+ invalidDict[elem1GeomKey] += [
+ self.tr(
+ "Difference between contour with values {id1} \
and {id2} do not match equidistance {equidistance}.\
Probably one contour is \
- missing or one of the contours have wrong value.\n'
- ).format(
- id1=elem1[heightFieldName],
- id2=elem2[heightFieldName],
- equidistance=threshold
- )]
+ missing or one of the contours have wrong value.\n"
+ ).format(
+ id1=elem1[heightFieldName],
+ id2=elem2[heightFieldName],
+ equidistance=threshold,
+ )
+ ]
return invalidDict
-
+
def buildHilltopDict(self, contourPolygonDict, contourPolygonIdx):
hilltopDict = dict()
buildDictAlias = lambda x: self.initiateHilltopDict(x, hilltopDict)
@@ -687,17 +845,17 @@ def buildHilltopDict(self, contourPolygonDict, contourPolygonIdx):
if candId != idx and candGeom.within(geom):
hilltopDict.pop(geomWkb.asWkb())
break
- if candId != idx and candGeom.contains(geom) \
- and candFeat not in hilltopDict[geomWkb]['donwhill']:
- hilltopDict[geomWkb]['donwhill'].append(candFeat)
+ if (
+ candId != idx
+ and candGeom.contains(geom)
+ and candFeat not in hilltopDict[geomWkb]["donwhill"]
+ ):
+ hilltopDict[geomWkb]["donwhill"].append(candFeat)
return hilltopDict
-
+
def initiateHilltopDict(self, feat, hilltopDict):
- hilltopDict[feat.geometry().asWkb()] = {
- 'feat' : feat,
- 'downhill': []
- }
-
+ hilltopDict[feat.geometry().asWkb()] = {"feat": feat, "downhill": []}
+
def buildTerrainPolygons(self, featList):
pass
@@ -709,30 +867,42 @@ def validateContourLines(self, contourLyr, contourAttrName, refLyr, feedback=Non
4. Validate contours.
"""
pass
-
- def validateSpatialRelations(self, ruleList, createSpatialIndex=True, feedback=None):
+
+ def validateSpatialRelations(
+ self, ruleList, createSpatialIndex=True, feedback=None
+ ):
"""
1. iterate over rule list and get all layers.
2. build spatial index
3. test rule
"""
- multiStepFeedback = QgsProcessingMultiStepFeedback(4, feedback) if feedback is not None else None
+ multiStepFeedback = (
+ QgsProcessingMultiStepFeedback(4, feedback)
+ if feedback is not None
+ else None
+ )
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(0)
- spatialDict = self.buildSpatialDictFromRuleList(ruleList, feedback=multiStepFeedback)
+ spatialDict = self.buildSpatialDictFromRuleList(
+ ruleList, feedback=multiStepFeedback
+ )
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(1)
- spatialRuleDict = self.buildSpatialRuleDict(ruleList, feedback=multiStepFeedback)
+ spatialRuleDict = self.buildSpatialRuleDict(
+ ruleList, feedback=multiStepFeedback
+ )
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(2)
self.buildSpatialRelationDictOnSpatialRuleDict(
spatialDict=spatialDict,
spatialRuleDict=spatialRuleDict,
- feedback=multiStepFeedback
+ feedback=multiStepFeedback,
)
if multiStepFeedback is not None:
multiStepFeedback.setCurrentStep(3)
- flagList = self.identifyInvalidRelations(spatialDict, spatialRuleDict, feedback=multiStepFeedback)
+ flagList = self.identifyInvalidRelations(
+ spatialDict, spatialRuleDict, feedback=multiStepFeedback
+ )
return flagList
def buildSpatialDictFromRuleList(self, ruleList, feedback=None):
@@ -746,23 +916,28 @@ def buildSpatialDictFromRuleList(self, ruleList, feedback=None):
}
}
"""
- progressStep = 100/len(ruleList) if ruleList else 0
+ progressStep = 100 / len(ruleList) if ruleList else 0
spatialDict = defaultdict(dict)
for current, rule in enumerate(ruleList):
if feedback is not None and feedback.isCanceled():
break
- inputKey = '_'.join(rule['input_layer'].name(), rule['input_layer_filter'])
- candidateKey = '_'.join(rule['candidate_layer'].name(), rule['candidate_layer_filter'])
+ inputKey = "_".join(rule["input_layer"].name(), rule["input_layer_filter"])
+ candidateKey = "_".join(
+ rule["candidate_layer"].name(), rule["candidate_layer_filter"]
+ )
for key in [inputKey, candidateKey]:
if key not in spatialDict:
- spatialDict[key]['spatial_index'], spatialDict[key]['feature_id_dict'] = self.layerHandler.buildSpatialIndexAndIdDict(
- inputLyr=rule['input_layer'],
- featureRequest=rule['input_layer_filter']
+ (
+ spatialDict[key]["spatial_index"],
+ spatialDict[key]["feature_id_dict"],
+ ) = self.layerHandler.buildSpatialIndexAndIdDict(
+ inputLyr=rule["input_layer"],
+ featureRequest=rule["input_layer_filter"],
)
if feedback is not None:
feedback.setProgress(current * progressStep)
return spatialDict
-
+
def buildSpatialRuleDict(self, ruleList, feedback=None):
"""
ruleList comes from the ui
@@ -798,27 +973,25 @@ def buildSpatialRuleDict(self, ruleList, feedback=None):
}
"""
spatialRuleDict = defaultdict(
- lambda : {
- 'input_layer' : None,
- 'input_layer_filter' : '',
- 'rule_list' : []
- }
+ lambda: {"input_layer": None, "input_layer_filter": "", "rule_list": []}
)
- progressStep = 100/len(ruleList) if ruleList else 0
+ progressStep = 100 / len(ruleList) if ruleList else 0
for current, rule in enumerate(ruleList):
if feedback is not None and feedback.isCanceled():
break
- key = '_'.join(rule['input_layer'].name(), rule['input_layer_filter'])
- spatialRuleDict[key]['input_layer'] = rule['input_layer']
- spatialRuleDict[key]['input_layer_filter'] = rule['input_layer_filter']
- spatialRuleDict[key]['rule_list'].append(
- {k:v for k, v in rule.items() if 'input' not in k}
+ key = "_".join(rule["input_layer"].name(), rule["input_layer_filter"])
+ spatialRuleDict[key]["input_layer"] = rule["input_layer"]
+ spatialRuleDict[key]["input_layer_filter"] = rule["input_layer_filter"]
+ spatialRuleDict[key]["rule_list"].append(
+ {k: v for k, v in rule.items() if "input" not in k}
)
if feedback is not None:
feedback.setProgress(current * progressStep)
return spatialRuleDict
- def buildSpatialRelationDictOnSpatialRuleDict(self, spatialDict, spatialRuleDict, feedback=None):
+ def buildSpatialRelationDictOnSpatialRuleDict(
+ self, spatialDict, spatialRuleDict, feedback=None
+ ):
"""
layerFeatureDict = {
'layer_name' = {
@@ -845,41 +1018,45 @@ def buildSpatialRelationDictOnSpatialRuleDict(self, spatialDict, spatialRuleDict
"""
totalSteps = self.countSteps(spatialRuleDict, spatialDict)
- progressStep = 100/totalSteps if totalSteps else 0
+ progressStep = 100 / totalSteps if totalSteps else 0
counter = 0
for inputKey, inputDict in spatialRuleDict.items():
if feedback is not None and feedback.isCanceled():
break
- keyRuleList = ['_'.join(i['candidate_layer'], i['candidate_layer_filter']) for i in inputDict['rule_list']]
- for featId, feat in spatialDict[inputKey]['feature_id_dict']:
+ keyRuleList = [
+ "_".join(i["candidate_layer"], i["candidate_layer_filter"])
+ for i in inputDict["rule_list"]
+ ]
+ for featId, feat in spatialDict[inputKey]["feature_id_dict"]:
if feedback is not None and feedback.isCanceled():
break
- for idx, rule in enumerate(inputDict['rule_list']):
+ for idx, rule in enumerate(inputDict["rule_list"]):
if feedback is not None and feedback.isCanceled():
break
- rule['feat_relation_list'].append(
+ rule["feat_relation_list"].append(
(
- featId, self.relateFeatureAccordingToPredicate(
+ featId,
+ self.relateFeatureAccordingToPredicate(
feat=feat,
rule=rule,
key=keyRuleList[idx],
- predicate=rule['predicate'],
- spatialDict=spatialDict
- )
+ predicate=rule["predicate"],
+ spatialDict=spatialDict,
+ ),
)
)
- counter+=1
+ counter += 1
if feedback is not None:
feedback.setProgress(counter * progressStep)
-
+
def countSteps(self, spatialRuleDict, spatialDict):
"""
Counts the number of steps of execution.
"""
steps = len(spatialRuleDict)
- for k,v in spatialRuleDict.items():
- steps += len(v['rule_list'])
- steps += len(spatialDict[k]['feature_id_dict'])
+ for k, v in spatialRuleDict.items():
+ steps += len(v["rule_list"])
+ steps += len(spatialDict[k]["feature_id_dict"])
return steps
def identifyInvalidRelations(self, spatialDict, spatialRuleDict, feedback=None):
@@ -887,60 +1064,64 @@ def identifyInvalidRelations(self, spatialDict, spatialRuleDict, feedback=None):
Identifies invalid spatial relations and returns a list with flags to be raised.
"""
totalSteps = self.countSteps(spatialRuleDict, spatialDict)
- progressStep = 100/totalSteps if totalSteps else 0
+ progressStep = 100 / totalSteps if totalSteps else 0
counter = 0
invalidFlagList = []
for inputKey, inputDict in spatialRuleDict:
if feedback is not None and feedback.isCanceled():
- break
- inputLyrName = inputDict['input_layer']
- for rule in inputDict['rule_list']:
+ break
+ inputLyrName = inputDict["input_layer"]
+ for rule in inputDict["rule_list"]:
if feedback is not None and feedback.isCanceled():
- break
- candidateLyrName = inputDict['candidate_layer']
- candidateKey = '_'.join(candidateLyrName, inputDict['candidate_layer_filter'])
+ break
+ candidateLyrName = inputDict["candidate_layer"]
+ candidateKey = "_".join(
+ candidateLyrName, inputDict["candidate_layer_filter"]
+ )
sameLayer = True if inputKey == candidateKey else False
lambdaCompair = self.parseCardinalityAndGetLambdaToIdentifyProblems(
- cardinality=rule['cardinality'],
- necessity=rule['necessity'],
- isSameLayer=sameLayer
+ cardinality=rule["cardinality"],
+ necessity=rule["necessity"],
+ isSameLayer=sameLayer,
)
- for featId, relatedFeatures in rule['feat_relation_list']:
+ for featId, relatedFeatures in rule["feat_relation_list"]:
if feedback is not None and feedback.isCanceled():
break
- inputFeature=spatialDict[inputKey][featId]
+ inputFeature = spatialDict[inputKey][featId]
if lambdaCompair(relatedFeatures):
- if inputLyrName == candidateLyrName and inputFeature in relatedFeatures:
+ if (
+ inputLyrName == candidateLyrName
+ and inputFeature in relatedFeatures
+ ):
relatedFeatures.pop(inputFeature)
invalidFlagList += self.buildSpatialFlags(
inputFeature=inputFeature,
relatedFeatures=relatedFeatures,
- flagText=rule['flag_text']
+ flagText=rule["flag_text"],
)
if feedback is not None:
feedback.setProgress(counter * progressStep)
counter += 1
return invalidFlagList
-
- def buildSpatialFlags(self, inputLyrName, inputFeature, candidateLyrName, relatedFeatures, flagText):
+
+ def buildSpatialFlags(
+ self, inputLyrName, inputFeature, candidateLyrName, relatedFeatures, flagText
+ ):
input_id = inputFeature.id()
inputGeom = inputFeature.geometry()
spatialFlags = []
for feat in relatedFeatures:
flagGeom = inputGeom.intersection(feat.geometry().constGet())
- flagText = self.tr('Feature from {input} with id {input_id} violates the following predicate with feature from {candidate} with id {candidate_id}: {predicate_text}').format(
+ flagText = self.tr(
+ "Feature from {input} with id {input_id} violates the following predicate with feature from {candidate} with id {candidate_id}: {predicate_text}"
+ ).format(
input=inputLyrName,
input_id=input_id,
candidate=candidateLyrName,
candidate_id=feat.id(),
- predicate_text=flagText
- )
- spatialFlags.append(
- {
- 'flagGeom' : flagGeom,
- 'flagText' : flagText
- }
+ predicate_text=flagText,
)
+ spatialFlags.append({"flagGeom": flagGeom, "flagText": flagText})
return spatialFlags
def availablePredicates(self):
@@ -960,14 +1141,14 @@ def getCardinalityTest(self, cardinality=None):
if cardinality is None:
# default is "1..*"
return lambda x: len(x) > 0
- min_card, max_card = cardinality.split('..')
- if max_card == '*':
+ min_card, max_card = cardinality.split("..")
+ if max_card == "*":
return lambda x: len(x) >= int(min_card)
elif min_card == max_card:
return lambda x: len(x) == int(min_card)
else:
return lambda x: len(x) >= int(min_card) and len(x) <= int(max_card)
-
+
def testPredicate(self, predicate, engine, targetGeometries):
"""
Applies a predicate test to a given feature from a list of features.
@@ -978,20 +1159,20 @@ def testPredicate(self, predicate, engine, targetGeometries):
that will be tested.
:param cardinality: (str) cardinality string to be tested against.
:return: (set-of-int) feature IDs for those that the geometries do
- comply with given predicate/cardinality.
+ comply with given predicate/cardinality.
"""
# negatives are disregarded. method simply apply the predicate comparison
positives = set()
negatives = set()
methods = {
- self.EQUALS : "isEqual",
- self.DISJOINT : "disjoint",
- self.INTERSECTS : "intersects",
- self.TOUCHES : "touches",
- self.CROSSES : "crosses",
- self.WITHIN : "within",
- self.OVERLAPS : "overlaps",
- self.CONTAINS : "contains"
+ self.EQUALS: "isEqual",
+ self.DISJOINT: "disjoint",
+ self.INTERSECTS: "intersects",
+ self.TOUCHES: "touches",
+ self.CROSSES: "crosses",
+ self.WITHIN: "within",
+ self.OVERLAPS: "overlaps",
+ self.CONTAINS: "contains",
}
if predicate not in methods:
raise NotImplementedError(
@@ -1003,8 +1184,9 @@ def testPredicate(self, predicate, engine, targetGeometries):
positives.add(test_fid)
return positives
- def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None,
- feedback=None):
+ def checkPredicate(
+ self, layerA, layerB, predicate, cardinality, ctx=None, feedback=None
+ ):
"""
Checks if a duo of layers comply with a spatial predicate at a given
cardinality.
@@ -1033,29 +1215,31 @@ def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None,
self.NOTCROSSES,
self.NOTWITHIN,
self.NOTOVERLAPS,
- self.NOTCONTAINS
+ self.NOTCONTAINS,
]
if predicate in denials:
- # denials always follow the "affirmitives" (contains = 14
+ # denials always follow the "affirmitives" (contains = 14
# -> notcontains = 15), hence -1.
# denials are ALWAYS absolute (cardinality is not applicable)
predicate -= 1
cardinality = "0..0"
if predicate == self.DISJOINT:
- predicateFlagText = self.tr("feature ID {{fid_a}} from {layer_a} "
- "id not {pred} to {{size}} features of"
- " {layer_b}")\
- .format(layer_a=layerA.name(),
- pred=predicates[predicate],
- layer_b=layerB.name())
+ predicateFlagText = self.tr(
+ "feature ID {{fid_a}} from {layer_a} "
+ "id not {pred} to {{size}} features of"
+ " {layer_b}"
+ ).format(
+ layer_a=layerA.name(), pred=predicates[predicate], layer_b=layerB.name()
+ )
cardinality = "0..0"
else:
- predicateFlagText = self.tr("feature ID {{fid_a}} from {layer_a} "
- "{pred} {{size}} features of "
- "{layer_b}")\
- .format(layer_a=layerA.name(),
- pred=predicates[predicate],
- layer_b=layerB.name())
+ predicateFlagText = self.tr(
+ "feature ID {{fid_a}} from {layer_a} "
+ "{pred} {{size}} features of "
+ "{layer_b}"
+ ).format(
+ layer_a=layerA.name(), pred=predicates[predicate], layer_b=layerB.name()
+ )
if predicate in (self.EQUALS, self.WITHIN):
getFlagGeometryMethod = lambda geom, _: geom
else:
@@ -1068,8 +1252,7 @@ def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None,
engine = QgsGeometry.createGeometryEngine(geomA.constGet())
engine.prepareGeometry()
geometriesB = {
- f.id(): f.geometry() \
- for f in layerB.getFeatures(geomA.boundingBox())
+ f.id(): f.geometry() for f in layerB.getFeatures(geomA.boundingBox())
}
positives = self.testPredicate(predicate, engine, geometriesB)
if predicate == self.DISJOINT:
@@ -1079,28 +1262,32 @@ def checkPredicate(self, layerA, layerB, predicate, cardinality, ctx=None,
fidA = featA.id()
size = len(positives)
if not size:
- flags[fidA].append({
- "text": predicateFlagText.format(fid_a=fidA, size=0),
- "geom": geomA
- })
+ flags[fidA].append(
+ {
+ "text": predicateFlagText.format(fid_a=fidA, size=0),
+ "geom": geomA,
+ }
+ )
continue
if size > 1:
- predicateFlagText_ = "{0} (IDs {1})"\
- .format(predicateFlagText, ", ".join(map(str, positives)))
+ predicateFlagText_ = "{0} (IDs {1})".format(
+ predicateFlagText, ", ".join(map(str, positives))
+ )
elif size == 1:
- predicateFlagText_ = "{0} (ID {1})"\
- .format(predicateFlagText, str(set(positives).pop()))
+ predicateFlagText_ = "{0} (ID {1})".format(
+ predicateFlagText, str(set(positives).pop())
+ )
for fidB in positives:
- flags[fidA].append({
- "text": predicateFlagText_\
- .format(fid_a=fidA, size=size),
- "geom": getFlagGeometryMethod(geomA, geometriesB[fidB])
- })
+ flags[fidA].append(
+ {
+ "text": predicateFlagText_.format(fid_a=fidA, size=size),
+ "geom": getFlagGeometryMethod(geomA, geometriesB[fidB]),
+ }
+ )
feedback.setProgress(stepSize * (step + 1))
return {fid: flag for fid, flag in flags.items() if flag}
- def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None,
- feedback=None):
+ def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None, feedback=None):
"""
Applies a DE-9IM mask to compare the features of between and checks
whether the occurrence limits are respected.
@@ -1121,16 +1308,17 @@ def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None,
testingMethod = self.getCardinalityTest(cardinality)
candidates = defaultdict(list)
flags = defaultdict(list)
- predicateFlagText = self.tr("feature ID {{fid_a}} from {layer_a} "
- "has {{size}} occurrences using the "
- "DE-9IM mask '{mask}' when compared to"
- " layer {layer_b}")\
- .format(layer_a=layerA.name(),
- mask=mask,
- layer_b=layerB.name())
+ predicateFlagText = self.tr(
+ "feature ID {{fid_a}} from {layer_a} "
+ "has {{size}} occurrences using the "
+ "DE-9IM mask '{mask}' when compared to"
+ " layer {layer_b}"
+ ).format(layer_a=layerA.name(), mask=mask, layer_b=layerB.name())
size = layerA.featureCount()
stepSize = 100 / size if size else 0
- iteratorA = layerA.getFeatures() if isinstance(layerA, QgsVectorLayer) else layerA
+ iteratorA = (
+ layerA.getFeatures() if isinstance(layerA, QgsVectorLayer) else layerA
+ )
for step, featA in enumerate(iteratorA):
if feedback.isCanceled():
break
@@ -1144,26 +1332,28 @@ def checkDE9IM(self, layerA, layerB, mask, cardinality, ctx=None,
# if the mask has an 'invalid' count of occurrences, it is a flag!
size = len(candidates[fidA])
if not size:
- flags[fidA].append({
- "text": predicateFlagText.format(fid_a=fidA, size=0),
- "geom": geomA
- })
+ flags[fidA].append(
+ {
+ "text": predicateFlagText.format(fid_a=fidA, size=0),
+ "geom": geomA,
+ }
+ )
continue
if size > 1:
predicateFlagText_ = "{0} (IDs {1})".format(
- predicateFlagText,
- ", ".join(map(str, candidates[fidA]))
+ predicateFlagText, ", ".join(map(str, candidates[fidA]))
)
elif size == 1:
predicateFlagText_ = "{0} (ID {1})".format(
predicateFlagText.replace("occurrences", "occurrence"),
- str(set(candidates[fidA]).pop())
+ str(set(candidates[fidA]).pop()),
)
- flags[fidA].append({
- "text": predicateFlagText_\
- .format(fid_a=fidA, size=size),
- "geom": geomA
- })
+ flags[fidA].append(
+ {
+ "text": predicateFlagText_.format(fid_a=fidA, size=size),
+ "geom": geomA,
+ }
+ )
feedback.setProgress(stepSize * (step + 1))
return flags
@@ -1181,9 +1371,7 @@ def setupLayer(self, layerName, exp, ctx=None, feedback=None):
lh = LayerHandler()
ctx = ctx or QgsProcessingContext()
if exp:
- layer = lh.filterByExpression(
- layerName, exp, ctx, feedback
- )
+ layer = lh.filterByExpression(layerName, exp, ctx, feedback)
# filter expression is an output is from another algo
# it is the temp output -> its name is not the same as the input
layer.setName(layerName)
@@ -1246,9 +1434,9 @@ def enforceRules(self, ruleList, ctx=None, feedback=None):
)
if not rule.isValid():
multiStepFeedback.pushInfo(
- self.tr('Rule {0} is invalid and will be skipped. '
- 'Error: {1}').format(
- ruleName, rule.validate(checkLoaded=True))
+ self.tr(
+ "Rule {0} is invalid and will be skipped. " "Error: {1}"
+ ).format(ruleName, rule.validate(checkLoaded=True))
)
continue
flags = self.enforceRule(rule, ctx, multiStepFeedback)
@@ -1263,14 +1451,11 @@ def enforceRules(self, ruleList, ctx=None, feedback=None):
else:
out[ruleName] = flags
multiStepFeedback.reportError(
- self.tr('Rule "{0}" raised flags\n').format(
- ruleName, idx + 1, size
- )
+ self.tr('Rule "{0}" raised flags\n').format(ruleName, idx + 1, size)
)
else:
multiStepFeedback.pushDebugInfo(
- self.tr('Rule "{0}" did not raise any flags\n')
- .format(ruleName)
+ self.tr('Rule "{0}" did not raise any flags\n').format(ruleName)
)
multiStepFeedback.setCurrentStep(idx + 1)
return out
@@ -1282,17 +1467,19 @@ class SpatialRule(QObject):
the attributes and verifies its validity.
"""
- def __init__(self,
- name=None,
- layer_a=None,
- filter_a=None,
- predicate=None,
- de9im_predicate=None,
- layer_b=None,
- filter_b=None,
- cardinality=None,
- useDE9IM=False,
- checkLoadedLayer=True):
+ def __init__(
+ self,
+ name=None,
+ layer_a=None,
+ filter_a=None,
+ predicate=None,
+ de9im_predicate=None,
+ layer_b=None,
+ filter_b=None,
+ cardinality=None,
+ useDE9IM=False,
+ checkLoadedLayer=True,
+ ):
"""
Initiates an instance of SpatialRule.
:param name: (str) display name for the spatial rule.
@@ -1432,7 +1619,7 @@ def layerA(self):
:return: (str) layer A's name.
"""
return str(self._attr.get("layer_a", ""))
-
+
def validateFilterExpression(self, exp):
"""
Checks whether a filtering expression is syntactically valid.
@@ -1441,7 +1628,7 @@ def validateFilterExpression(self, exp):
"""
# empty filters are allowed
return exp == "" or QgsExpression(exp.replace("\\", "")).isValid()
-
+
def _setFilterExpression(self, exp, key):
"""
Private method used to route filter expression's updates to the correct
@@ -1514,8 +1701,10 @@ def validatePredicate(self, pred, useDE9IM):
if useDE9IM:
regex = QRegExp("[FfTt012\*]{9}")
acceptable = QRegExpValidator.Acceptable
- return isinstance(pred, str) and \
- QRegExpValidator(regex).validate(pred, 9)[0] == acceptable
+ return (
+ isinstance(pred, str)
+ and QRegExpValidator(regex).validate(pred, 9)[0] == acceptable
+ )
else:
return pred in SpatialRelationsHandler().availablePredicates()
@@ -1527,8 +1716,11 @@ def predicateIsValid(self):
true in cases that "active" predicate is valid and the other isn't.
:return: (bool) property's value validity.
"""
- return self.predicateDE9IMIsValid() if self.useDE9IM() \
+ return (
+ self.predicateDE9IMIsValid()
+ if self.useDE9IM()
else self.predicateEnumIsValid()
+ )
def setPredicate(self, pred):
"""
@@ -1540,8 +1732,11 @@ def setPredicate(self, pred):
mask to be set.
:return: (bool) whether the property was updated.
"""
- return self.setPredicateDE9IM(pred) if self.useDE9IM() \
+ return (
+ self.setPredicateDE9IM(pred)
+ if self.useDE9IM()
else self.setPredicateEnum(pred)
+ )
def predicate(self):
"""
@@ -1591,7 +1786,7 @@ def setPredicateDE9IM(self, pred):
Updates the value of the DE-9IM mask set for the spatial rule. If the
value is invalid, the property is not updated.
:param pred: (str) the DE-9IM mask linearized as a string to be set.
- :return: (bool) whether the property was updated.
+ :return: (bool) whether the property was updated.
"""
if not self.validatePredicate(pred, useDE9IM=True):
return False
@@ -1668,8 +1863,10 @@ def validateCardinality(self, card):
"""
regex = QRegExp("[0-9\*]\.\.[0-9\*]")
acceptable = QRegExpValidator.Acceptable
- return isinstance(card, str) and \
- QRegExpValidator(regex).validate(card, 9)[0] == acceptable
+ return (
+ isinstance(card, str)
+ and QRegExpValidator(regex).validate(card, 9)[0] == acceptable
+ )
def cardinalityIsValid(self):
"""
@@ -1713,7 +1910,7 @@ def validate(self, checkLoaded=False):
# "de9im_predicate": self.predicateDE9IM,
"layer_b": lambda: self.layerBIsValid(checkLoaded),
"filter_b": self.filterBIsValid,
- "cardinality": self.cardinalityIsValid
+ "cardinality": self.cardinalityIsValid,
}
valueMethodMap = {
"name": self.ruleName,
@@ -1721,7 +1918,7 @@ def validate(self, checkLoaded=False):
"filter_a": self.filterA,
"layer_b": self.layerB,
"filter_b": self.filterB,
- "cardinality": self.cardinality
+ "cardinality": self.cardinality,
}
for prop, validationMethod in methodMap.items():
if not validationMethod():
@@ -1742,15 +1939,17 @@ def isValid(self, checkLoaded=False):
that it is not selected to be used (either mask or enumerator).
:param checkLoaded: (bool) whether canvas availability should be
considered.
- :return: (bool) whether spatial rule may be enforced.
- """
- return self.ruleNameIsValid() \
- and self.layerAIsValid(checkLoaded) \
- and self.filterAIsValid() \
- and self.predicateIsValid() \
- and self.layerBIsValid(checkLoaded) \
- and self.filterBIsValid() \
+ :return: (bool) whether spatial rule may be enforced.
+ """
+ return (
+ self.ruleNameIsValid()
+ and self.layerAIsValid(checkLoaded)
+ and self.filterAIsValid()
+ and self.predicateIsValid()
+ and self.layerBIsValid(checkLoaded)
+ and self.filterBIsValid()
and self.cardinalityIsValid()
+ )
def asDict(self):
"""
@@ -1769,5 +1968,5 @@ def asDict(self):
"layer_b": self.layerB(),
"filter_b": self.filterB(),
"cardinality": self.cardinality(),
- "useDE9IM": self.useDE9IM()
+ "useDE9IM": self.useDE9IM(),
}
diff --git a/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py b/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py
index c405eb011..c751277d8 100755
--- a/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py
+++ b/DsgTools/core/LayerTools/CustomFormTools/customFormGenerator.py
@@ -24,16 +24,14 @@
import os
from qgis import core
+
class CustomFormGenerator(object):
def __init__(self):
super(CustomFormGenerator, self).__init__()
- self.lenColumnDict = {
- 1 : u'length_otf',
- 2 : u'area_otf'
- }
+ self.lenColumnDict = {1: "length_otf", 2: "area_otf"}
def get_form_template(self):
- return u'''
+ return """
Dialog
@@ -127,10 +125,10 @@ def get_form_template(self):
- '''
+ """
- def get_le_template(self, field, alias, row, readOnly=''):
- return '''
+ def get_le_template(self, field, alias, row, readOnly=""):
+ return """{alias}
@@ -142,10 +140,12 @@ def get_le_template(self, field, alias, row, readOnly=''):
{readOnly}
- '''.format(alias=alias, field=field, row=row, readOnly=readOnly)
+ """.format(
+ alias=alias, field=field, row=row, readOnly=readOnly
+ )
def get_cb_template(self, field, alias, row):
- return '''
+ return """{alias}
@@ -154,65 +154,52 @@ def get_cb_template(self, field, alias, row):
- '''.format(alias=alias, field=field, row=row)
+ """.format(
+ alias=alias, field=field, row=row
+ )
def create_cb(self, field, alias, row):
return self.get_cb_template(field, alias, row)
def create_le(self, field, alias, row, setReadOnly=False):
- """ if setReadOnly:
+ """if setReadOnly:
readOnly =u'''true'''
- return self.get_le_template(field, row, readOnly)
- else: """
+ return self.get_le_template(field, row, readOnly)
+ else:"""
return self.get_le_template(field, alias, row)
def create(self, vlayer, layerData):
- form_path = os.path.join(
- os.path.dirname(__file__),
- u"forms",
- vlayer.name()
- )
+ form_path = os.path.join(os.path.dirname(__file__), "forms", vlayer.name())
with open(form_path, "w") as formFile:
form = self.get_form_template()
- layerData = layerData['layer_fields']
- all_items = u""
+ layerData = layerData["layer_fields"]
+ all_items = ""
rowAttr = 1
for field in vlayer.fields():
field_name = field.name()
field_alias = field.alias()
- if field in [u'id', u'controle_id', u'ultimo_usuario', u'data_modificacao']:
+ if field in ["id", "controle_id", "ultimo_usuario", "data_modificacao"]:
all_items += self.create_le(
field_name, field_alias, rowAttr, setReadOnly=True
)
- elif field_name == u'tipo':
- if u'filter' in layerData:
- all_items += self.create_cb(
- u'filter', u'filter', rowAttr
- )
- all_items += self.create_cb(
- field_name, field_alias, rowAttr
- )
+ elif field_name == "tipo":
+ if "filter" in layerData:
+ all_items += self.create_cb("filter", "filter", rowAttr)
+ all_items += self.create_cb(field_name, field_alias, rowAttr)
rowAttr += 1
elif (field_name in layerData) and layerData[field]:
- all_items += self.create_cb(
- field_name, field_alias, rowAttr
- )
- elif (field_name in layerData):
- all_items += self.create_le(
- field_name, field_alias, rowAttr
- )
+ all_items += self.create_cb(field_name, field_alias, rowAttr)
+ elif field_name in layerData:
+ all_items += self.create_le(field_name, field_alias, rowAttr)
rowAttr += 1
if vlayer.geometryType() in self.lenColumnDict:
all_items += self.create_le(
self.lenColumnDict[vlayer.geometryType()],
self.lenColumnDict[vlayer.geometryType()],
- rowAttr + 1
+ rowAttr + 1,
)
- form = form.format(
- items=unicode(all_items),
- row_btn=rowAttr+1
- )
+ form = form.format(items=unicode(all_items), row_btn=rowAttr + 1)
formFile.write(form)
- return form_path
\ No newline at end of file
+ return form_path
diff --git a/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py b/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py
index d9ac67b41..d9a9bb3dd 100755
--- a/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py
+++ b/DsgTools/core/LayerTools/CustomFormTools/customInitCodeGenerator.py
@@ -24,47 +24,28 @@
import json
import os
+
class CustomInitCodeGenerator(object):
def __init__(self):
# contrutor
- super(CustomInitCodeGenerator, self).__init__()
+ super(CustomInitCodeGenerator, self).__init__()
def getInitCodeWithFilter(self, tableFilter, rules):
optFilter = self.formatOptionFilter(tableFilter)
tableFilterFormated = self.formatTableFilter(tableFilter)
initCode = self.getTemplateInitCodeWithFilter()
initCode = initCode.replace(
- '{optfilter}',
- json.dumps(
- optFilter,
- ensure_ascii=False
- )
- )
- initCode = initCode.replace(
- '{filter}',
- json.dumps(
- tableFilterFormated,
- ensure_ascii=False
- )
+ "{optfilter}", json.dumps(optFilter, ensure_ascii=False)
)
initCode = initCode.replace(
- '{rules}',
- json.dumps(
- rules,
- ensure_ascii=False
- )
+ "{filter}", json.dumps(tableFilterFormated, ensure_ascii=False)
)
+ initCode = initCode.replace("{rules}", json.dumps(rules, ensure_ascii=False))
return initCode
def getInitCodeWithoutFilter(self, rules):
initCode = self.getTemplateInitCodeNotFilter()
- initCode = initCode.replace(
- '{rules}',
- json.dumps(
- rules,
- ensure_ascii=False
- )
- )
+ initCode = initCode.replace("{rules}", json.dumps(rules, ensure_ascii=False))
return initCode
def formatTableFilter(self, tableFilter):
@@ -72,33 +53,31 @@ def formatTableFilter(self, tableFilter):
for line in tableFilter:
tableFilterFormated[line[1]] = line[0]
return tableFilterFormated
-
+
def formatOptionFilter(self, tableFilter):
optFilter = {}
for line in tableFilter:
- optFilter[unicode(line[2])] = ((line[0]-(line[0]%100))/100)
+ optFilter[unicode(line[2])] = (line[0] - (line[0] % 100)) / 100
return optFilter
def getTemplateInitCodeNotFilter(self):
- initCodeTemplate = u""
+ initCodeTemplate = ""
pathCode = os.path.join(
- os.path.dirname(__file__),
- 'formInitCodeWithoutFilterTemplate.txt'
+ os.path.dirname(__file__), "formInitCodeWithoutFilterTemplate.txt"
)
codeFile = open(pathCode, "r")
for line in codeFile.readlines():
- initCodeTemplate += line#.decode("utf-8")
+ initCodeTemplate += line # .decode("utf-8")
codeFile.close()
return initCodeTemplate
def getTemplateInitCodeWithFilter(self):
- initCodeTemplate = u""
+ initCodeTemplate = ""
pathCode = os.path.join(
- os.path.dirname(__file__),
- 'formInitCodeWithFilterTemplate.txt'
+ os.path.dirname(__file__), "formInitCodeWithFilterTemplate.txt"
)
codeFile = open(pathCode, "r")
for line in codeFile.readlines():
- initCodeTemplate += line#.decode("utf-8")
+ initCodeTemplate += line # .decode("utf-8")
codeFile.close()
return initCodeTemplate
diff --git a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate
index 32c039f7a..83f7cbee5 100755
--- a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate
+++ b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithFilterTemplate
@@ -8,12 +8,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = {rules}
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -25,7 +25,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -56,7 +56,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -122,14 +122,14 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def filterTypeField(self):
value = self.filterField.currentText()
itemsFiltered = self.getItemsFiltered(value)
self.typeField.clear()
for k, v in sorted(itemsFiltered.items()):
self.typeField.addItem(k, v)
-
+
def getItemsFiltered(self, value):
result = {}
if value == "Filtro":
@@ -143,19 +143,19 @@ class ManagerForm(QtCore.QObject):
result.update({'A SER PREENCHIDO' : '999'})
return result
return result
-
+
def finishedForm(self):
idx_field = self.lyr.fields().indexOf('tipo')
setup = core.QgsEditorWidgetSetup( 'ValueMap', {
'map': self.mapValue
}
- )
+ )
self.lyr.setEditorWidgetSetup(idx_field, setup)
-
+
def formOpen(dialog, layer, featureid):
try:
global a
a = ManagerForm(dialog, layer, featureid)
except:
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate
index 059d4721c..26ac35af1 100755
--- a/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate
+++ b/DsgTools/core/LayerTools/CustomFormTools/formInitCodeWithoutFilterTemplate
@@ -8,12 +8,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = {rules}
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -25,7 +25,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -56,7 +56,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -88,12 +88,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -109,7 +109,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
@@ -118,4 +118,4 @@ def formOpen(dialog, layer, featureid):
global a
a = ManagerForm(dialog, layer, featureid)
except:
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/core/Misc/QGIS_Models/enhancer.model b/DsgTools/core/Misc/QGIS_Models/enhancer.model
index cea4c0c10..869898566 100644
--- a/DsgTools/core/Misc/QGIS_Models/enhancer.model
+++ b/DsgTools/core/Misc/QGIS_Models/enhancer.model
@@ -5,176 +5,176 @@
"values": {
"pos": {
"values": {
- "y": 60.0,
+ "y": 60.0,
"x": 123.0
- },
+ },
"class": "point"
- },
+ },
"param": {
"values": {
- "isAdvanced": false,
- "name": "RASTERLAYER_LOWERRESOLUTIONPCTIMAGE",
- "showSublayersDialog": true,
- "value": null,
- "exported": null,
- "hidden": false,
- "optional": false,
+ "isAdvanced": false,
+ "name": "RASTERLAYER_LOWERRESOLUTIONPCTIMAGE",
+ "showSublayersDialog": true,
+ "value": null,
+ "exported": null,
+ "hidden": false,
+ "optional": false,
"description": "Lower Resolution (PCT Image)"
- },
+ },
"class": "processing.core.parameters.ParameterRaster"
}
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ModelerParameter"
- },
+ },
"RASTERLAYER_HIGHERRESOLUTION": {
"values": {
"pos": {
"values": {
- "y": 128.0,
+ "y": 128.0,
"x": 125.0
- },
+ },
"class": "point"
- },
+ },
"param": {
"values": {
- "isAdvanced": false,
- "name": "RASTERLAYER_HIGHERRESOLUTION",
- "showSublayersDialog": true,
- "value": null,
- "exported": null,
- "hidden": false,
- "optional": false,
+ "isAdvanced": false,
+ "name": "RASTERLAYER_HIGHERRESOLUTION",
+ "showSublayersDialog": true,
+ "value": null,
+ "exported": null,
+ "hidden": false,
+ "optional": false,
"description": "Higher Resolution"
- },
+ },
"class": "processing.core.parameters.ParameterRaster"
}
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ModelerParameter"
}
- },
- "helpContent": {},
- "group": "DSG",
- "name": "enhancer",
+ },
+ "helpContent": {},
+ "group": "DSG",
+ "name": "enhancer",
"algs": {
"SCRIPTHSVFUSION_1": {
"values": {
- "name": "SCRIPTHSVFUSION_1",
- "paramsFolded": true,
+ "name": "SCRIPTHSVFUSION_1",
+ "paramsFolded": true,
"outputs": {
"Pansharpened": {
"values": {
- "description": "pansharpened",
+ "description": "pansharpened",
"pos": {
"values": {
- "y": 353.0,
+ "y": 353.0,
"x": 431.0
- },
+ },
"class": "point"
}
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ModelerOutput"
}
- },
- "outputsFolded": true,
+ },
+ "outputsFolded": true,
"pos": {
"values": {
- "y": 265.0,
+ "y": 265.0,
"x": 430.0
- },
+ },
"class": "point"
- },
- "dependencies": [],
+ },
+ "dependencies": [],
"params": {
"RGB_Layer": {
"values": {
- "alg": "OTBSUPERIMPOSESENSOR_1",
+ "alg": "OTBSUPERIMPOSESENSOR_1",
"output": "-out"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ValueFromOutput"
- },
+ },
"Pan_Layer": {
"values": {
"name": "RASTERLAYER_HIGHERRESOLUTION"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ValueFromInput"
}
- },
- "active": true,
- "consoleName": "script:hsvfusion",
+ },
+ "active": true,
+ "consoleName": "script:hsvfusion",
"description": "HSV fusion"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.Algorithm"
- },
+ },
"OTBSUPERIMPOSESENSOR_1": {
"values": {
- "name": "OTBSUPERIMPOSESENSOR_1",
- "paramsFolded": true,
- "outputs": {},
- "outputsFolded": true,
+ "name": "OTBSUPERIMPOSESENSOR_1",
+ "paramsFolded": true,
+ "outputs": {},
+ "outputsFolded": true,
"pos": {
"values": {
- "y": 154.0,
+ "y": 154.0,
"x": 425.0
- },
+ },
"class": "point"
- },
- "dependencies": [],
+ },
+ "dependencies": [],
"params": {
- "-interpolator": 0,
+ "-interpolator": 0,
"-inm": {
"values": {
- "alg": "GDALOGRPCTTORGB_1",
+ "alg": "GDALOGRPCTTORGB_1",
"output": "OUTPUT"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ValueFromOutput"
- },
- "-ram": 512.0,
- "-interpolator.bco.radius": 2.0,
- "-lms": 4.0,
+ },
+ "-ram": 512.0,
+ "-interpolator.bco.radius": 2.0,
+ "-lms": 4.0,
"-inr": {
"values": {
"name": "RASTERLAYER_HIGHERRESOLUTION"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ValueFromInput"
- },
+ },
"-elev.default": 0.0
- },
- "active": true,
- "consoleName": "otb:superimposesensor",
+ },
+ "active": true,
+ "consoleName": "otb:superimposesensor",
"description": "Superimpose sensor"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.Algorithm"
- },
+ },
"GDALOGRPCTTORGB_1": {
"values": {
- "name": "GDALOGRPCTTORGB_1",
- "paramsFolded": true,
- "outputs": {},
- "outputsFolded": true,
+ "name": "GDALOGRPCTTORGB_1",
+ "paramsFolded": true,
+ "outputs": {},
+ "outputsFolded": true,
"pos": {
"values": {
- "y": 60.0,
+ "y": 60.0,
"x": 423.0
- },
+ },
"class": "point"
- },
- "dependencies": [],
+ },
+ "dependencies": [],
"params": {
"INPUT": {
"values": {
"name": "RASTERLAYER_LOWERRESOLUTIONPCTIMAGE"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ValueFromInput"
- },
+ },
"NBAND": 0
- },
- "active": true,
- "consoleName": "gdalogr:pcttorgb",
+ },
+ "active": true,
+ "consoleName": "gdalogr:pcttorgb",
"description": "PCT to RGB"
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.Algorithm"
}
}
- },
+ },
"class": "processing.modeler.ModelerAlgorithm.ModelerAlgorithm"
-}
\ No newline at end of file
+}
diff --git a/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py b/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py
index 6c77fdd87..353b5f710 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py
+++ b/DsgTools/core/Misc/QGIS_Scripts/HSV_fusion.py
@@ -34,6 +34,7 @@
import colorsys
import numpy
+
class RasterProcess(object):
def __init__(self):
"""
@@ -50,7 +51,7 @@ def openRaster(self, file):
raster = gdal.Open(file)
except RuntimeError as e:
# fix_print_with_import
- print('Unable to open image')
+ print("Unable to open image")
# fix_print_with_import
print(e)
@@ -69,7 +70,7 @@ def getBandAsArray(self, raster, bandnumber):
except RuntimeError as e:
# for example, try GetRasterBand(10)
# fix_print_with_import
- print('Band ( %i ) not found' % bandnumber)
+ print("Band ( %i ) not found" % bandnumber)
# fix_print_with_import
print(e)
sys.exit(1)
@@ -79,7 +80,7 @@ def getBandAsArray(self, raster, bandnumber):
def getGeoreferenceInfo(self, raster):
"""
Gets georeference information
- raster: raster file
+ raster: raster file
"""
# Get raster georeference info
transform = raster.GetGeoTransform()
@@ -109,7 +110,7 @@ def createRasterFromRGBbands(self, srcraster, red, green, blue, destfile):
destfile: destination file
"""
outRaster = self.createRaster(srcraster, destfile)
-
+
outRaster.GetRasterBand(1).WriteArray(red)
outRaster.GetRasterBand(2).WriteArray(green)
outRaster.GetRasterBand(3).WriteArray(blue)
@@ -124,16 +125,18 @@ def createRaster(self, srcraster, destfile, pixelType):
cols = srcraster.RasterXSize
rows = srcraster.RasterYSize
- (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo(srcraster)
+ (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo(
+ srcraster
+ )
targetSR = self.getCRS(srcraster)
- driver = gdal.GetDriverByName('GTiff')
+ driver = gdal.GetDriverByName("GTiff")
outRaster = driver.Create(destfile, cols, rows, 3, pixelType)
outRaster.SetGeoTransform((xOrigin, pixelWidth, 0, yOrigin, 0, pixelHeight))
outRaster.SetProjection(targetSR.ExportToWkt())
-
+
return outRaster
def pansharpenImage(self, rgbfile, panfile, destfile):
@@ -150,10 +153,10 @@ def pansharpenImage(self, rgbfile, panfile, destfile):
panraster = self.openRaster(panfile)
pan = panraster.GetRasterBand(1)
-
+
rgb_to_hsv = numpy.vectorize(colorsys.rgb_to_hsv)
hsv_to_rgb = numpy.vectorize(colorsys.hsv_to_rgb)
-
+
if red.DataType > pan.DataType:
pixelType = red.DataType
else:
@@ -165,7 +168,7 @@ def pansharpenImage(self, rgbfile, panfile, destfile):
outB = outRaster.GetRasterBand(3)
sizeX = pan.XSize
- sizeY = pan.YSize
+ sizeY = pan.YSize
p = 0
progress.setPercentage(p)
@@ -188,23 +191,23 @@ def pansharpenImage(self, rgbfile, panfile, destfile):
self.writeBlock(outG, g, sizeX, lines, row, pixelType)
self.writeBlock(outB, b, sizeX, lines, row, pixelType)
- if int(float(row)/sizeY*100) != p:
- p = int(float(row)/sizeY*100)
+ if int(float(row) / sizeY * 100) != p:
+ p = int(float(row) / sizeY * 100)
progress.setPercentage(p)
rgb = None
panraster = None
outRaster = None
-
+
def normalize(self, arr):
"""
Function to normalize an input array to 0-1
"""
arr_min = arr.min()
arr_max = arr.max()
- return [(arr - arr_min) / (arr_max - arr_min)]*255
-
- def readBlock(self, band, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte):
+ return [(arr - arr_min) / (arr_max - arr_min)] * 255
+
+ def readBlock(self, band, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte):
"""
Reads image block
band: band used
@@ -215,12 +218,14 @@ def readBlock(self, band, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_By
"""
numpytype = self.getNumpyType(pixelType)
- bandscanline =band.ReadRaster( 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType )
- pixelArray=numpy.fromstring(bandscanline, dtype=numpytype)
-
+ bandscanline = band.ReadRaster(
+ 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType
+ )
+ pixelArray = numpy.fromstring(bandscanline, dtype=numpytype)
+
return pixelArray
-
- def getNumpyType(self, pixelType = gdal.GDT_Byte):
+
+ def getNumpyType(self, pixelType=gdal.GDT_Byte):
"""
Translates the gdal raster type to numpy type
pixelType: gdal raster type
@@ -239,8 +244,10 @@ def getNumpyType(self, pixelType = gdal.GDT_Byte):
return numpy.float32
elif pixelType == gdal.GDT_Float64:
return numpy.float64
-
- def writeBlock(self, band, block, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte):
+
+ def writeBlock(
+ self, band, block, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte
+ ):
"""
Writes image block
band: band used
@@ -253,7 +260,6 @@ def writeBlock(self, band, block, sizeX, sizeY = 1, offsetY = 0, pixelType = gda
band.WriteRaster(0, offsetY, sizeX, sizeY, block.astype(numpytype).tostring())
+
obj = RasterProcess()
-obj.pansharpenImage(RGB_Layer,
- Pan_Layer,
- Pansharpened)
+obj.pansharpenImage(RGB_Layer, Pan_Layer, Pansharpened)
diff --git a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py
index ce430f194..033c40cbf 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py
+++ b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py
@@ -3,10 +3,13 @@
##Dados_SIGEF=output table
from builtins import str
-from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
+from processing.core.GeoAlgorithmExecutionException import (
+ GeoAlgorithmExecutionException,
+)
from qgis.core import *
import csv
+
def dd2dms_sigef(dd):
"""
Converts decimal degrees to degree, minute, second
@@ -15,19 +18,20 @@ def dd2dms_sigef(dd):
"""
# calculos com numeros
d = int(dd)
- m = abs(int(60*(dd-int(dd))))
- s = abs((dd-d-m/60)*60)
+ m = abs(int(60 * (dd - int(dd))))
+ s = abs((dd - d - m / 60) * 60)
s_int = int(s)
s_d = s - s_int
# fazendo as strings
d = str(d).zfill(2)
m = str(m).zfill(2)
s_int = str(s_int).zfill(2)
- s_d = str(s_d).split('.')[-1]
+ s_d = str(s_d).split(".")[-1]
# fazendo o retorno
- dms_sigef = d+','+m+s_int+'%0.3s'%s_d
+ dms_sigef = d + "," + m + s_int + "%0.3s" % s_d
return dms_sigef
-
+
+
def createCSV(input, output):
"""
Creates the output CSV file
@@ -38,33 +42,36 @@ def createCSV(input, output):
layer = processing.getObject(input)
features = layer.selectedFeatures()
if len(features) != 1:
- raise GeoAlgorithmExecutionException('Selecione uma e somente uma geometria!')
-
- csvfile = open(output, 'wb')
+ raise GeoAlgorithmExecutionException("Selecione uma e somente uma geometria!")
+
+ csvfile = open(output, "wb")
outwriter = csv.writer(csvfile)
- outwriter.writerow(['id', 'Long', 'Lat'])
+ outwriter.writerow(["id", "Long", "Lat"])
feature = features[0]
geom = feature.geometry()
polygon = geom.asPolygon()
outring = polygon[0]
-
+
crsDest = QgsCoordinateReferenceSystem(4674)
coordinateTransformer = QgsCoordinateTransform(layer.crs(), crsDest)
count = 0
size = len(outring)
p = 0
- progress.setPercentage(p)
+ progress.setPercentage(p)
for point in outring:
sirgasPt = coordinateTransformer.transform(point)
- outwriter.writerow([str(count), dd2dms_sigef(sirgasPt[0]), dd2dms_sigef(sirgasPt[1])])
+ outwriter.writerow(
+ [str(count), dd2dms_sigef(sirgasPt[0]), dd2dms_sigef(sirgasPt[1])]
+ )
count += 1
- if int(float(count)/size*100) != p:
- p = int(float(count)/size*100)
+ if int(float(count) / size * 100) != p:
+ p = int(float(count) / size * 100)
progress.setPercentage(p)
-
+
csvfile.close()
-
-createCSV(Perimetro, Dados_SIGEF)
\ No newline at end of file
+
+
+createCSV(Perimetro, Dados_SIGEF)
diff --git a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help
index 87a273ed6..f894324e8 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help
+++ b/DsgTools/core/Misc/QGIS_Scripts/Sigef.py.help
@@ -1 +1 @@
-{"ALG_DESC": "Algoritmo que cria um arquivo CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal). Os dados de origem ser\u00e3o convertidos para SIRGAS2000 no formato grau decimal.", "ALG_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "ALG_VERSION": "1.0", "ALG_HELP_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "Dados_SIGEF": "CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal)", "Perimetro": "Camada vetorial com coordenadas no CRS SIRGAS 2000."}
\ No newline at end of file
+{"ALG_DESC": "Algoritmo que cria um arquivo CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal). Os dados de origem ser\u00e3o convertidos para SIRGAS2000 no formato grau decimal.", "ALG_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "ALG_VERSION": "1.0", "ALG_HELP_CREATOR": "Luiz Claudio Oliveira de Andrade\nEngenheiro Cartogr\u00e1fo - DSG", "Dados_SIGEF": "CSV com dados de Latitude Longitude para inser\u00e7\u00e3o na planilha do SIGEF (grau, minuto e segundo no formato decimal)", "Perimetro": "Camada vetorial com coordenadas no CRS SIRGAS 2000."}
diff --git a/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py b/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py
index 27edeec36..cbe6a9a09 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py
+++ b/DsgTools/core/Misc/QGIS_Scripts/edgv_checker.py
@@ -5,13 +5,14 @@
import csv, os
from osgeo import ogr
+
def edgv_checker(folder, output):
"""
Checks if a spatialite is a dsgtools database
"""
- csvfile = open(output, 'wb')
+ csvfile = open(output, "wb")
outwriter = csv.writer(csvfile)
- outwriter.writerow(['arquivo', 'edgv'])
+ outwriter.writerow(["arquivo", "edgv"])
for root, dirs, files in os.walk(folder):
count = 0
@@ -19,20 +20,21 @@ def edgv_checker(folder, output):
p = 0
progress.setPercentage(p)
for file in files:
- if '.sqlite' not in file:
+ if ".sqlite" not in file:
continue
- file = os.path.join(root,file)
+ file = os.path.join(root, file)
ogrSrc = ogr.Open(file)
isEdgv = False
if ogrSrc:
- layer = ogrSrc.GetLayerByName('cb_adm_area_pub_civil_a')
+ layer = ogrSrc.GetLayerByName("cb_adm_area_pub_civil_a")
isEdgv = True if layer else False
outwriter.writerow([file, isEdgv])
- if int(float(count)/size*100) != p:
- p = int(float(count)/size*100)
+ if int(float(count) / size * 100) != p:
+ p = int(float(count) / size * 100)
progress.setPercentage(p)
csvfile.close()
-edgv_checker(Pasta_de_Busca, Relatorio)
\ No newline at end of file
+
+edgv_checker(Pasta_de_Busca, Relatorio)
diff --git a/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py b/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py
index 6244971fe..d7a1b4828 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py
+++ b/DsgTools/core/Misc/QGIS_Scripts/reverse_geocode.py
@@ -4,47 +4,50 @@
from future import standard_library
+
standard_library.install_aliases()
import urllib.request, urllib.error, urllib.parse, csv
-from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
+from processing.core.GeoAlgorithmExecutionException import (
+ GeoAlgorithmExecutionException,
+)
+
def rev_geocode(long, lat):
latitude = lat
longitude = int
- sensor = 'true'
+ sensor = "true"
base = "http://maps.googleapis.com/maps/api/geocode/json?"
params = "latlng={lat},{lon}&sensor={sen}".format(
- lat=latitude,
- lon=longitude,
- sen=sensor
+ lat=latitude, lon=longitude, sen=sensor
)
url = "{base}{params}".format(base=base, params=params)
response = urllib.request.urlopen(url)
return eval(response.read())
-
-output = open(addresses_txt, 'wb')
+
+
+output = open(addresses_txt, "wb")
csvwriter = csv.writer(output)
-with open(coordinates_csv, 'rb') as csvfile:
+with open(coordinates_csv, "rb") as csvfile:
coords = csv.reader(csvfile)
count = 0
- size = sum(1 for row in coords)
+ size = sum(1 for row in coords)
p = 0
progress.setPercentage(p)
-
+
csvfile.seek(0)
- csvwriter.writerow(['lat', 'long', 'address'])
+ csvwriter.writerow(["lat", "long", "address"])
for coord in coords:
long = coord[1]
lat = coord[0]
address = rev_geocode(int, lat)
- if address['status'] == 'OK':
- csvwriter.writerow( [lat, int, address['results'][0]['formatted_address']])
+ if address["status"] == "OK":
+ csvwriter.writerow([lat, int, address["results"][0]["formatted_address"]])
- if int(float(count)/size*100) != p:
- p = int(float(count)/size*100)
+ if int(float(count) / size * 100) != p:
+ p = int(float(count) / size * 100)
progress.setPercentage(p)
-output.close()
\ No newline at end of file
+output.close()
diff --git a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py
index 3767c41b3..83c11fcc7 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py
+++ b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster.py
@@ -26,27 +26,38 @@
##Pasta=folder
import processing
-from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
-from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsSpatialIndex, QgsFeatureRequest, QgsCoordinateTransform, QgsFeature
+from processing.core.GeoAlgorithmExecutionException import (
+ GeoAlgorithmExecutionException,
+)
+from qgis.core import (
+ QgsVectorLayer,
+ QgsRasterLayer,
+ QgsSpatialIndex,
+ QgsFeatureRequest,
+ QgsCoordinateTransform,
+ QgsFeature,
+)
import os
import shutil, stat
-#script methods
+# script methods
def createReprojectedLayer(layer, crs):
"""
Creates a reprojected layer
layer: layer used
crs: crs used
"""
- temp = QgsVectorLayer('%s?crs=%s'% ('Multipolygon', crs.authid()), 'temp', 'memory')
+ temp = QgsVectorLayer(
+ "%s?crs=%s" % ("Multipolygon", crs.authid()), "temp", "memory"
+ )
if not layer.isValid():
- raise GeoAlgorithmExecutionException('Problema ao criar camada reprojetada!')
+ raise GeoAlgorithmExecutionException("Problema ao criar camada reprojetada!")
return None
-
+
provider = temp.dataProvider()
provider.addAttributes(layer.dataProvider().fields().toList())
temp.updateFields()
-
+
coordinateTransformer = QgsCoordinateTransform(layer.crs(), crs)
features = []
for feature in layer.getFeatures():
@@ -55,11 +66,12 @@ def createReprojectedLayer(layer, crs):
geom.transform(coordinateTransformer)
feat.setGeometry(geom)
features.append(feat)
-
+
provider.addFeatures(features)
-
+
return temp
+
def reprojectLayer(fromLayer, toLayer):
"""
Reprojects all features fromLayer crs to toLayer crs
@@ -74,13 +86,15 @@ def reprojectLayer(fromLayer, toLayer):
ret.append(f)
return ret
+
def populateIndex(idx, layer):
"""
Populates the layer index
"""
for feat in layer.getFeatures():
idx.addFeature(feat)
-
+
+
def getCandidates(idx, layer, bbox):
"""
Gets candidates to be processed using the index to speedup the process
@@ -90,20 +104,22 @@ def getCandidates(idx, layer, bbox):
for id in ids:
candidates.append(next(layer.getFeatures(QgsFeatureRequest().setFilterFid(id))))
return candidates
-
+
+
def makeVrtDict(candidates, camada):
"""
Makes a VRT dictionary
"""
vrt = dict()
for candidate in candidates:
- map_index = candidate['map_index']
+ map_index = candidate["map_index"]
vrt[map_index] = []
for feat in camada.getFeatures():
if candidate.geometry().intersects(feat.geometry()):
vrt[map_index].append(feat)
- return vrt
-
+ return vrt
+
+
def createVrt(vrt):
"""
Creates a VRT file
@@ -111,30 +127,33 @@ def createVrt(vrt):
count = 0
size = len(list(vrt.keys()))
p = 0
- progress.setPercentage(p)
+ progress.setPercentage(p)
for key in list(vrt.keys()):
- vrtfilename = os.path.join(Pasta, key, key+'.vrt')
+ vrtfilename = os.path.join(Pasta, key, key + ".vrt")
features = vrt[key]
rasterList = []
for feat in features:
- filename = feat['fileName']
+ filename = feat["fileName"]
newfilename = copyFileSet(Pasta, key, filename)
raster = QgsRasterLayer(newfilename, newfilename)
rasterList.append(raster)
- ovr = newfilename+'.ovr'
+ ovr = newfilename + ".ovr"
if not os.path.isfile(ovr):
- progress.setText('Fazendo Pirâmides...')
- #('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr))
- processing.runalg('gdalogr:overviews', raster, '4 8 32 128', True, 0, 1)
-
- if int(float(count)/size*100) != p:
- p = int(float(count)/size*100)
- progress.setPercentage(p)
+ progress.setText("Fazendo Pirâmides...")
+ # ('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr))
+ processing.runalg("gdalogr:overviews", raster, "4 8 32 128", True, 0, 1)
+
+ if int(float(count) / size * 100) != p:
+ p = int(float(count) / size * 100)
+ progress.setPercentage(p)
count += 1
-
- progress.setText('Fazendo raster virtual...')
- processing.runalg('gdalogr:buildvirtualraster', rasterList, 0, False, False, vrtfilename)
-
+
+ progress.setText("Fazendo raster virtual...")
+ processing.runalg(
+ "gdalogr:buildvirtualraster", rasterList, 0, False, False, vrtfilename
+ )
+
+
def copyFileSet(parent, folder, filename):
"""
Copy files to the destination folder
@@ -144,57 +163,58 @@ def copyFileSet(parent, folder, filename):
"""
path = os.path.dirname(filename)
basename = os.path.basename(filename)
- texto = 'Copiando %s e arquivos relacionados...' % basename
+ texto = "Copiando %s e arquivos relacionados..." % basename
progress.setText(texto)
-
+
destination = os.path.join(parent, folder)
if not os.path.exists(destination):
os.makedirs(destination)
-
+
for root, dirs, files in os.walk(path):
for file in files:
- if basename.split('.')[0] in file:
+ if basename.split(".")[0] in file:
try:
- dir = os.path.join(destination, 'imagens')
+ dir = os.path.join(destination, "imagens")
if not os.path.exists(dir):
os.makedirs(dir)
f = os.path.join(root, file)
- newf = os.path.join(parent, folder, 'imagens', file)
+ newf = os.path.join(parent, folder, "imagens", file)
shutil.copy2(f, newf)
except:
- raise GeoAlgorithmExecutionException('Problema ao copiar arquivos!')
- return os.path.join(parent, folder, 'imagens', basename)
-
-#end of script methods
-
-#Making the actual work
-#Camada de inventario
+ raise GeoAlgorithmExecutionException("Problema ao copiar arquivos!")
+ return os.path.join(parent, folder, "imagens", basename)
+
+
+# end of script methods
+
+# Making the actual work
+# Camada de inventario
inventario = processing.getObject(Inventario)
-#Camada de moldura
+# Camada de moldura
frame = processing.getObject(Moldura)
-#Indice espacial
+# Indice espacial
frameidx = QgsSpatialIndex()
-#Populating a spatial index
+# Populating a spatial index
populateIndex(frameidx, frame)
-#checking crs's, if different, reproject
+# checking crs's, if different, reproject
destCrs = frame.crs()
srcCrs = inventario.crs()
if srcCrs.authid() != destCrs.authid():
- progress.setText('CRS diferentes, reprojetando...')
+ progress.setText("CRS diferentes, reprojetando...")
camada = createReprojectedLayer(inventario, frame.crs())
else:
camada = inventario
-
-#Obtaining candidates
+
+# Obtaining candidates
candidates = getCandidates(frameidx, frame, camada.extent())
-#making vrt dict
+# making vrt dict
vrt = makeVrtDict(candidates, camada)
-#creating vrt files
+# creating vrt files
createVrt(vrt)
-#ending the actual work
\ No newline at end of file
+# ending the actual work
diff --git a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py
index e1e08d463..daa627932 100644
--- a/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py
+++ b/DsgTools/core/Misc/QGIS_Scripts/virtual_raster_inloco.py
@@ -28,49 +28,65 @@
import processing
-from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
-from qgis.core import QgsVectorLayer, QgsRasterLayer, QgsSpatialIndex, QgsFeatureRequest, QgsCoordinateTransform, QgsFeature, QgsCoordinateReferenceSystem
+from processing.core.GeoAlgorithmExecutionException import (
+ GeoAlgorithmExecutionException,
+)
+from qgis.core import (
+ QgsVectorLayer,
+ QgsRasterLayer,
+ QgsSpatialIndex,
+ QgsFeatureRequest,
+ QgsCoordinateTransform,
+ QgsFeature,
+ QgsCoordinateReferenceSystem,
+)
from qgis.PyQt.QtCore import QSettings
import os
-#script methods
+# script methods
def createVrt(inventario, vrt):
- #Camada de inventario
+ # Camada de inventario
layer = processing.getObject(Inventario)
-
+
count = 0
size = layer.featureCount()
p = 0
- progress.setPercentage(p)
+ progress.setPercentage(p)
rasterList = []
for feature in layer.getFeatures():
- filename = feature['fileName']
-
+ filename = feature["fileName"]
+
raster = QgsRasterLayer(filename, filename)
if Override_CRS:
- raster.setCrs( QgsCoordinateReferenceSystem(int(CRS.split(':')[-1]), QgsCoordinateReferenceSystem.EpsgCrsId) )
-
+ raster.setCrs(
+ QgsCoordinateReferenceSystem(
+ int(CRS.split(":")[-1]), QgsCoordinateReferenceSystem.EpsgCrsId
+ )
+ )
+
rasterList.append(raster)
- ovr = filename+'.ovr'
+ ovr = filename + ".ovr"
if not os.path.isfile(ovr):
- progress.setText('Fazendo Pirâmides...')
- #('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr))
- processing.runalg('gdalogr:overviews', raster, '4 8 32 128', True, 0, 1)
+ progress.setText("Fazendo Pirâmides...")
+ # ('gdalogr:overviews', input, levels=8, clean=False, resampling_method=0(nearest), format=1(Gtiff .ovr))
+ processing.runalg("gdalogr:overviews", raster, "4 8 32 128", True, 0, 1)
- if int(float(count)/size*100) != p:
- p = int(float(count)/size*100)
- progress.setPercentage(p)
+ if int(float(count) / size * 100) != p:
+ p = int(float(count) / size * 100)
+ progress.setPercentage(p)
count += 1
- progress.setText('Fazendo raster virtual...')
- processing.runalg('gdalogr:buildvirtualraster', rasterList, 0, False, False, VRT)
-#end of script methods
-
-#Making the actual work
+ progress.setText("Fazendo raster virtual...")
+ processing.runalg("gdalogr:buildvirtualraster", rasterList, 0, False, False, VRT)
+
+
+# end of script methods
+
+# Making the actual work
s = QSettings()
-oldValidation = s.value( "/Projections/defaultBehaviour")
-s.setValue( "/Projections/defaultBehaviour", "useGlobal" )
+oldValidation = s.value("/Projections/defaultBehaviour")
+s.setValue("/Projections/defaultBehaviour", "useGlobal")
createVrt(Inventario, VRT)
-s.setValue( "/Projections/defaultBehaviour", oldValidation )
-#ending the actual work
\ No newline at end of file
+s.setValue("/Projections/defaultBehaviour", oldValidation)
+# ending the actual work
diff --git a/DsgTools/core/Misc/QmlTools/qmlParser.py b/DsgTools/core/Misc/QmlTools/qmlParser.py
index 2b9263a56..f6e63745c 100644
--- a/DsgTools/core/Misc/QmlTools/qmlParser.py
+++ b/DsgTools/core/Misc/QmlTools/qmlParser.py
@@ -24,6 +24,7 @@
from builtins import object
from qgis.PyQt.QtXml import QDomDocument
+
class QmlParser(object):
def __init__(self, fileName):
"""
@@ -40,7 +41,7 @@ def loadFileContent(self):
"""
Loads QML data
"""
- qml = open(self.fileName, 'r')
+ qml = open(self.fileName, "r")
data = qml.read()
loaded = self.qml.setContent(data)
qml.close()
@@ -78,9 +79,9 @@ def readEdittypeElement(self, edittypeElement):
for i in range(len(values)):
value = values.item(i).toElement()
keyText = value.attribute("key")
- #print 'key: '+keyText
+ # print 'key: '+keyText
valueText = value.attribute("value")
- #print 'value: '+valueText
+ # print 'value: '+valueText
valueMapDict[keyText] = valueText
self.domainDict[name] = valueMapDict
elif type == "ValueRelation":
@@ -99,7 +100,13 @@ def getDomainDict(self):
self.domainDict.clear()
if not self.loadFileContent():
- QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("QML file not loaded properly. Enum values won't be available."))
+ QMessageBox.warning(
+ self.iface.mainWindow(),
+ self.tr("Warning!"),
+ self.tr(
+ "QML file not loaded properly. Enum values won't be available."
+ ),
+ )
return
self.readQGISElement()
diff --git a/DsgTools/core/Misc/QmlTools/qml_creator.py b/DsgTools/core/Misc/QmlTools/qml_creator.py
index 727db00ea..21d33458a 100644
--- a/DsgTools/core/Misc/QmlTools/qml_creator.py
+++ b/DsgTools/core/Misc/QmlTools/qml_creator.py
@@ -1,92 +1,94 @@
# -*- coding: utf-8 -*-
from qgis.PyQt.QtCore import QFile, QIODevice
+
def generateQml(filename, attrs, codelists):
xmlWriter = QXmlStreamWriter()
xmlFile = QFile(filename)
- if (xmlFile.open(QIODevice.WriteOnly) == False):
+ if xmlFile.open(QIODevice.WriteOnly) == False:
QMessageBox.warning(0, "Error!", "Error opening file")
- else :
+ else:
xmlWriter.setDevice(xmlFile)
- #starting xml file
+ # starting xml file
xmlWriter.writeStartDocument()
- #starting QGIS element
+ # starting QGIS element
xmlWriter.writeStartElement("qgis")
- xmlWriter.writeAttribute("version","2.6.0-Brighton")
- xmlWriter.writeAttribute("minimumScale","1")
- xmlWriter.writeAttribute("maximumScale","1")
- xmlWriter.writeAttribute("simplifyDrawingHints","0")
- xmlWriter.writeAttribute("minLabelScale","0")
- xmlWriter.writeAttribute("maxLabelScale","1e+08")
- xmlWriter.writeAttribute("simplifyDrawingTol","1")
- xmlWriter.writeAttribute("simplifyMaxScale","1")
- xmlWriter.writeAttribute("hasScaleBasedVisibilityFlag","0")
- xmlWriter.writeAttribute("simplifyLocal","1")
- xmlWriter.writeAttribute("scaleBasedLabelVisibilityFlag","0")
-
- #starting edittypes element
+ xmlWriter.writeAttribute("version", "2.6.0-Brighton")
+ xmlWriter.writeAttribute("minimumScale", "1")
+ xmlWriter.writeAttribute("maximumScale", "1")
+ xmlWriter.writeAttribute("simplifyDrawingHints", "0")
+ xmlWriter.writeAttribute("minLabelScale", "0")
+ xmlWriter.writeAttribute("maxLabelScale", "1e+08")
+ xmlWriter.writeAttribute("simplifyDrawingTol", "1")
+ xmlWriter.writeAttribute("simplifyMaxScale", "1")
+ xmlWriter.writeAttribute("hasScaleBasedVisibilityFlag", "0")
+ xmlWriter.writeAttribute("simplifyLocal", "1")
+ xmlWriter.writeAttribute("scaleBasedLabelVisibilityFlag", "0")
+
+ # starting edittypes element
xmlWriter.writeStartElement("edittypes")
- #satrting edittype elements
+ # satrting edittype elements
for attr in attrs:
- #starting edittype
+ # starting edittype
xmlWriter.writeStartElement("edittype")
- xmlWriter.writeAttribute("widgetv2type","TextEdit")
- xmlWriter.writeAttribute("name",attr)
+ xmlWriter.writeAttribute("widgetv2type", "TextEdit")
+ xmlWriter.writeAttribute("name", attr)
- #starting widgetv2config
+ # starting widgetv2config
xmlWriter.writeStartElement("widgetv2config")
- xmlWriter.writeAttribute("IsMultiline","0")
- xmlWriter.writeAttribute("fieldEditable","0")
- xmlWriter.writeAttribute("UseHtml","0")
- xmlWriter.writeAttribute("labelOnTop","0")
- #closing widgetv2config
+ xmlWriter.writeAttribute("IsMultiline", "0")
+ xmlWriter.writeAttribute("fieldEditable", "0")
+ xmlWriter.writeAttribute("UseHtml", "0")
+ xmlWriter.writeAttribute("labelOnTop", "0")
+ # closing widgetv2config
xmlWriter.writeEndElement()
- #closing edittype
+ # closing edittype
xmlWriter.writeEndElement()
for key in list(codelists.keys()):
- #starting edittype
+ # starting edittype
xmlWriter.writeStartElement("edittype")
- xmlWriter.writeAttribute("widgetv2type","ValueMap")
- xmlWriter.writeAttribute("name",key)
+ xmlWriter.writeAttribute("widgetv2type", "ValueMap")
+ xmlWriter.writeAttribute("name", key)
- #starting widgetv2config
+ # starting widgetv2config
xmlWriter.writeStartElement("widgetv2config")
- xmlWriter.writeAttribute("fieldEditable","1")
- xmlWriter.writeAttribute("labelOnTop","0")
+ xmlWriter.writeAttribute("fieldEditable", "1")
+ xmlWriter.writeAttribute("labelOnTop", "0")
- #Writing pair key-value
+ # Writing pair key-value
codelist = codelists[key]
for codeValue in list(codelist.keys()):
code = codelist[codeValue]
- #starting value
+ # starting value
xmlWriter.writeStartElement("value")
- xmlWriter.writeAttribute("key",codeValue)
- xmlWriter.writeAttribute("value",code)
- #closing value
+ xmlWriter.writeAttribute("key", codeValue)
+ xmlWriter.writeAttribute("value", code)
+ # closing value
xmlWriter.writeEndElement()
- #closing widgetv2config
+ # closing widgetv2config
xmlWriter.writeEndElement()
- #closing edittype
+ # closing edittype
xmlWriter.writeEndElement()
- #closing edittypes
+ # closing edittypes
xmlWriter.writeEndElement()
- #closing QGIS
+ # closing QGIS
xmlWriter.writeEndElement()
- #closing xml file
+ # closing xml file
xmlWriter.writeEndDocument()
-if __name__ == '__main__':
+
+if __name__ == "__main__":
attrs = list()
attrs.append("a")
attrs.append("b")
@@ -101,12 +103,14 @@ def generateQml(filename, attrs, codelists):
codelists["d"] = codelist
generateQml("teste.qml", attrs, codelists)
-
+
qml = open("teste.qml", "r")
fileData = qml.read()
- qml.close()
- newData = fileData.replace("", "")
+ qml.close()
+ newData = fileData.replace(
+ '',
+ "",
+ )
qml = open("teste.qml", "w")
qml.write(newData)
qml.close()
-
diff --git a/DsgTools/core/NetworkTools/BDGExRequestHandler.py b/DsgTools/core/NetworkTools/BDGExRequestHandler.py
index 5dcaa9603..63b227d8f 100644
--- a/DsgTools/core/NetworkTools/BDGExRequestHandler.py
+++ b/DsgTools/core/NetworkTools/BDGExRequestHandler.py
@@ -25,6 +25,7 @@
"""
from future import standard_library
+
standard_library.install_aliases()
import urllib.request, urllib.error, urllib.parse
from xml.dom.minidom import parseString, Element
@@ -35,44 +36,45 @@
from DsgTools.core.Utils.utils import MessageRaiser
+
class BDGExRequestHandler(QObject):
- def __init__(self,parent=None):
+ def __init__(self, parent=None):
"""
Constructor
"""
super(BDGExRequestHandler, self).__init__()
self.availableServicesDict = {
- 'mapcache' : {
- 'url' : 'https://bdgex.eb.mil.br/mapcache',
- 'services' : {
- 'WMS' : dict()
- }
+ "mapcache": {
+ "url": "http://bdgex.eb.mil.br/mapcache",
+ "services": {"WMS": dict()},
},
- 'mapindex' : {
- 'url' : 'https://bdgex.eb.mil.br/cgi-bin/mapaindice',
- 'services': {
- 'WMS' : dict(),
- 'WFS' : dict()
- }
+ "mapindex": {
+ "url": "http://bdgex.eb.mil.br/cgi-bin/mapaindice",
+ "services": {"WMS": dict(), "WFS": dict()},
+ },
+ "auxlayers": {
+ "url": "http://bdgex.eb.mil.br/cgi-bin/geoportal",
+ "services": {"WMS": dict(), "WFS": dict()},
},
- 'auxlayers' : {
- 'url' : 'https://bdgex.eb.mil.br/cgi-bin/geoportal',
- 'services' : {
- 'WMS' : dict(),
- 'WFS' : dict()
- }
- }
}
def __del__(self):
pass
-
+
def setUrllibProxy(self, url):
"""
Sets the proxy
"""
- (enabled, host, port, user, password, type, urlsList) = self.getProxyConfiguration()
- if enabled == 'false' or type != 'HttpProxy':
+ (
+ enabled,
+ host,
+ port,
+ user,
+ password,
+ type,
+ urlsList,
+ ) = self.getProxyConfiguration()
+ if enabled == "false" or type != "HttpProxy":
return
for address in urlsList:
if address in url:
@@ -80,13 +82,8 @@ def setUrllibProxy(self, url):
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
urllib.request.install_opener(opener)
return
- proxyStr = 'http://'+user+':'+password+'@'+host+':'+port
- proxy = urllib.request.ProxyHandler(
- {
- 'http': proxyStr,
- 'https': proxyStr
- }
- )
+ proxyStr = "http://" + user + ":" + password + "@" + host + ":" + port
+ proxy = urllib.request.ProxyHandler({"http": proxyStr, "https": proxyStr})
opener = urllib.request.build_opener(proxy, urllib.request.HTTPHandler)
urllib.request.install_opener(opener)
@@ -95,18 +92,18 @@ def getProxyConfiguration(self):
Gets the proxy configuration from QSettings
"""
settings = QSettings()
- settings.beginGroup('proxy')
- enabled = settings.value('proxyEnabled')
- host = settings.value('proxyHost')
- port = settings.value('proxyPort')
- user = settings.value('proxyUser')
- password = settings.value('proxyPassword')
- type = settings.value('proxyType')
+ settings.beginGroup("proxy")
+ enabled = settings.value("proxyEnabled")
+ host = settings.value("proxyHost")
+ port = settings.value("proxyPort")
+ user = settings.value("proxyUser")
+ password = settings.value("proxyPassword")
+ type = settings.value("proxyType")
excludedUrls = list()
- if settings.value('proxyExcludedUrls'):
- excludedUrls = settings.value('proxyExcludedUrls')
- if settings.value('noProxyUrls'):
- excludedUrls += settings.value('noProxyUrls')
+ if settings.value("proxyExcludedUrls"):
+ excludedUrls = settings.value("proxyExcludedUrls")
+ if settings.value("noProxyUrls"):
+ excludedUrls += settings.value("noProxyUrls")
# try:
# urlsList = excludedUrls.split('|')
# except:
@@ -119,41 +116,40 @@ def get_url_string(self, service, layerList, serviceType):
Returns QGIS url service string.
"""
if service not in self.availableServicesDict:
- raise Exception('Service {service} not available'.format(service=service))
- if serviceType not in self.availableServicesDict[service]['services']:
+ raise Exception("Service {service} not available".format(service=service))
+ if serviceType not in self.availableServicesDict[service]["services"]:
raise Exception(
- 'Invalid request {service_type} for service {service}'.format(
- service=service,
- service_type=serviceType
- )
+ "Invalid request {service_type} for service {service}".format(
+ service=service, service_type=serviceType
)
- url = self.availableServicesDict[service]['url']
- if not self.availableServicesDict[service]['services'][serviceType]:
- self.availableServicesDict[service]['services'][serviceType] = self.getCapabilitiesDict(service, url, service_type=serviceType)
- layers = self.availableServicesDict[service]['services'][serviceType]
+ )
+ url = self.availableServicesDict[service]["url"]
+ if not self.availableServicesDict[service]["services"][serviceType]:
+ self.availableServicesDict[service]["services"][
+ serviceType
+ ] = self.getCapabilitiesDict(service, url, service_type=serviceType)
+ layers = self.availableServicesDict[service]["services"][serviceType]
if layers is not None:
- layer = layers.get(layerList[0], None) \
- or layers.get("ms:{0}".format(layerList[0]), None)
+ layer = layers.get(layerList[0], None) or layers.get(
+ "ms:{0}".format(layerList[0]), None
+ )
if layer:
- return self.getRequestString(
- layerList,
- url,
- layer,
- serviceType
- )
+ return self.getRequestString(layerList, url, layer, serviceType)
def getCapabilitiesDict(self, service, url, service_type=None):
- service_type = service_type or 'WMS'
- capabilities_url = "{url}?service={service_type}&request=GetCapabilities".format(
- url=self.availableServicesDict[service]['url'],
- service_type=service_type
+ service_type = service_type or "WMS"
+ capabilities_url = (
+ "{url}?service={service_type}&request=GetCapabilities".format(
+ url=self.availableServicesDict[service]["url"],
+ service_type=service_type,
+ )
)
myDom = self.requestGetCapabilitiesXML(capabilities_url)
if not myDom:
return {}
- if service_type == 'WMS':
+ if service_type == "WMS":
return self.parseCapabilitiesXML(myDom)
- elif service_type == 'WFS':
+ elif service_type == "WFS":
return self.parse_wfs_capabilities(myDom)
else:
return {}
@@ -163,23 +159,25 @@ def requestGetCapabilitiesXML(self, url):
Gets url capabilities
"""
self.setUrllibProxy(url)
- getCapa = urllib.request.Request(url, headers={'User-Agent' : "Magic Browser"})
+ getCapa = urllib.request.Request(url, headers={"User-Agent": "Magic Browser"})
try:
resp = urllib.request.urlopen(getCapa)
except Exception as e:
title = self.tr("BDGEx layers (DSGTools)")
- msg = self.tr("Unable to provide requested layer. Please check "
- "your network settings (proxy and exceptions too, if"
- " necessary).")
+ msg = self.tr(
+ "Unable to provide requested layer. Please check "
+ "your network settings (proxy and exceptions too, if"
+ " necessary)."
+ )
MessageRaiser().raiseIfaceMessage(title, msg, Qgis.Warning, 5)
return ""
response = resp.read()
try:
myDom = parseString(response)
except:
- raise Exception('Parse Error')
+ raise Exception("Parse Error")
return myDom
-
+
def parseCapabilitiesXML(self, capabilitiesDom):
"""
Parses GetCapabilities to get info.
@@ -202,62 +200,61 @@ def parseCapabilitiesXML(self, capabilitiesDom):
tagName = tag.tagName
if tag.childNodes:
newItem[tagName] = tag.childNodes[0].nodeValue
- jsonDict[newItem['Name']] = newItem
- #parse to add format to jsonDict
+ jsonDict[newItem["Name"]] = newItem
+ # parse to add format to jsonDict
for tile in capabilitiesDom.getElementsByTagName("TileSet"):
- itemName = tile.getElementsByTagName('Layers')[0].childNodes[0].nodeValue
- imgFormat = tile.getElementsByTagName('Format')[0].childNodes[0].nodeValue
- jsonDict[itemName]['Format'] = imgFormat
+ itemName = tile.getElementsByTagName("Layers")[0].childNodes[0].nodeValue
+ imgFormat = tile.getElementsByTagName("Format")[0].childNodes[0].nodeValue
+ jsonDict[itemName]["Format"] = imgFormat
for key, dictItem in jsonDict.items():
- if 'Format' not in dictItem:
- jsonDict[key]['Format'] = 'image/png'
- if 'SRS' not in dictItem:
- jsonDict[key]['SRS'] = 'EPSG:4326'
+ if "Format" not in dictItem:
+ jsonDict[key]["Format"] = "image/png"
+ if "SRS" not in dictItem:
+ jsonDict[key]["SRS"] = "EPSG:4326"
return jsonDict
-
+
def parse_wfs_capabilities(self, capabilitiesDom):
jsonDict = dict()
- for node in capabilitiesDom.getElementsByTagName('FeatureType'):
+ for node in capabilitiesDom.getElementsByTagName("FeatureType"):
newItem = dict()
- name = node.getElementsByTagName('Name')[0].childNodes[0].nodeValue
- crsNode = node.getElementsByTagName('DefaultSRS') or node.getElementsByTagName('DefaultCRS')
+ name = node.getElementsByTagName("Name")[0].childNodes[0].nodeValue
+ crsNode = node.getElementsByTagName(
+ "DefaultSRS"
+ ) or node.getElementsByTagName("DefaultCRS")
epsg = crsNode[0].childNodes[0].nodeValue
newItem = {
- 'Name' : name,
- 'SRS' : 'EPSG:{code}'.format(code=epsg.split('::')[-1])
+ "Name": name,
+ "SRS": "EPSG:{code}".format(code=epsg.split("::")[-1]),
}
jsonDict[name] = newItem
return jsonDict
-
def getRequestString(self, layerList, url, infoDict, serviceType):
"""
Makes the requisition to the tile cache service
"""
if layerList == []:
- raise Exception('Invalid name request')
+ raise Exception("Invalid name request")
elif len(layerList) > 1:
# ctmList = [i for i in capabilitiesDict.keys() if 'ctm' in i]
# ctmList.sort(key = lambda x : int(x.replace('ctm','')))
- layer_tag = 'layers='+'&layers='.join(layerList)
- styles_tag = '&'.join(['styles']*len(layerList))
+ layer_tag = "layers=" + "&layers=".join(layerList)
+ styles_tag = "&".join(["styles"] * len(layerList))
else:
- layer_tag = 'layers={layer_name}'.format(layer_name=layerList[0])
- styles_tag = 'styles'
- if serviceType == 'WMS':
+ layer_tag = "layers={layer_name}".format(layer_name=layerList[0])
+ styles_tag = "styles"
+ if serviceType == "WMS":
requestString = "crs={epsg}&dpiMode=7&featureCount=10&format={img_format}&{layer_tag}&{styles_tag}&url={url}".format(
- epsg=infoDict['SRS'],
- img_format=infoDict['Format'],
+ epsg=infoDict["SRS"],
+ img_format=infoDict["Format"],
layer_tag=layer_tag,
styles_tag=styles_tag,
- url=url
+ url=url,
)
- elif serviceType == 'WFS':
+ elif serviceType == "WFS":
requestString = """pagingEnabled='true' restrictToRequestBBOX='1' srsname='{epsg}' typename='{layer_name}' url='{url}' version='auto' table="" sql=""".format(
- epsg=infoDict['SRS'],
- layer_name=infoDict['Name'],
- url=url
+ epsg=infoDict["SRS"], layer_name=infoDict["Name"], url=url
)
else:
- requestString == ''
- return requestString
\ No newline at end of file
+ requestString == ""
+ return requestString
diff --git a/DsgTools/core/NetworkTools/ExternalFilesHandler.py b/DsgTools/core/NetworkTools/ExternalFilesHandler.py
index d6badc9e5..6c1ef28bb 100644
--- a/DsgTools/core/NetworkTools/ExternalFilesHandler.py
+++ b/DsgTools/core/NetworkTools/ExternalFilesHandler.py
@@ -31,54 +31,68 @@
import processing
+
@dataclass
class ExternalFileHandlerConfig(ABC):
url: str = MISSING
file_name: str = MISSING
output_folder: str = MISSING
+
class ExternalFileDownloadProcessor(QObject):
-
def __init__(self, parent=None):
super(ExternalFileDownloadProcessor, self).__init__()
self.parent = parent
-
+
def getFullPath(self, config: ExternalFileHandlerConfig):
return os.path.join(config.output_folder, config.file_name)
-
+
def isFileDownloaded(self, config: ExternalFileHandlerConfig) -> bool:
"""
Checks if the file is already downloaded.
"""
return os.path.isfile(self.getFullPath(config))
- def promptForDownload(self, externalFileConfigList: List[ExternalFileHandlerConfig]) -> bool:
+ def promptForDownload(
+ self, externalFileConfigList: List[ExternalFileHandlerConfig]
+ ) -> bool:
"""
Prompts the user to download the file if it is not already downloaded.
"""
- fileName =''
+ fileName = ""
for file in externalFileConfigList:
- if len(fileName)>100:
- fileName = fileName + ' and others'
- if fileName=='':
- fileName=file.file_name
+ if len(fileName) > 100:
+ fileName = fileName + " and others"
+ if fileName == "":
+ fileName = file.file_name
else:
- fileName = fileName + ', ' + file.file_name
+ fileName = fileName + ", " + file.file_name
reply = QMessageBox.question(
self.parent,
- self.tr('Download Files'),
- self.tr('The following files: {} are not downloaded. Do you want to download them?'.format(fileName)),
- QMessageBox.Yes | QMessageBox.No, QMessageBox.No
+ self.tr("Download Files"),
+ self.tr(
+ "The following files: {} are not downloaded. Do you want to download them?".format(
+ fileName
+ )
+ ),
+ QMessageBox.Yes | QMessageBox.No,
+ QMessageBox.No,
)
if reply == QMessageBox.No:
- return False
+ return False
return True
- def process(self, fileConfigList: List[ExternalFileHandlerConfig], prompt=True) -> int:
+ def process(
+ self, fileConfigList: List[ExternalFileHandlerConfig], prompt=True
+ ) -> int:
"""
Processes the list of files.
"""
- downloadList = [i for i in fileConfigList if not self.isFileDownloaded(i)] if prompt else fileConfigList
+ downloadList = (
+ [i for i in fileConfigList if not self.isFileDownloaded(i)]
+ if prompt
+ else fileConfigList
+ )
if len(downloadList) == 0:
return 1
reply = self.promptForDownload(fileConfigList)
@@ -93,15 +107,15 @@ def process(self, fileConfigList: List[ExternalFileHandlerConfig], prompt=True)
processing.run(
"native:filedownloader",
{
- 'URL': fileConfig.url,
- 'OUTPUT': self.getFullPath(fileConfig),
- }
+ "URL": fileConfig.url,
+ "OUTPUT": self.getFullPath(fileConfig),
+ },
)
except Exception as e:
QMessageBox.critical(
self.parent,
- self.tr('Error'),
- self.tr('Could not download the following files: {}'.format(e))
+ self.tr("Error"),
+ self.tr("Could not download the following files: {}".format(e)),
)
QApplication.restoreOverrideCursor()
return 2
diff --git a/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py b/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py
index 0519ecba6..e69de29bb 100644
--- a/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py
+++ b/DsgTools/core/Qmls/qgis_26/edgv_3_pro/__init__.py
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml
index 40c468ac1..b870defda 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/aquisicao_limite_vegetacao_l.qml
@@ -240,12 +240,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -257,7 +257,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -288,7 +288,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -320,12 +320,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -341,7 +341,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml
index cfd145834..470bb6035 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/cobter_corpo_dagua_a.qml
@@ -327,12 +327,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -344,7 +344,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -375,7 +375,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -407,12 +407,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -428,7 +428,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml
index 3c8e8be2b..904412c0e 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/infra_via_deslocamento_l.qml
@@ -1784,12 +1784,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -1801,7 +1801,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -1832,7 +1832,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -1864,12 +1864,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -1885,7 +1885,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml
index 8d43a1de5..18f571220 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/llp_delimitacao_fisica_l.qml
@@ -280,12 +280,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -297,7 +297,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -328,7 +328,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -360,12 +360,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -381,7 +381,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml
index aab7fe9a9..a243c3bb8 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_hidrografia_p.qml
@@ -471,12 +471,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -488,7 +488,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -519,7 +519,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml
index df4d4b088..7514a1a3b 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/rev_vegetacao_p.qml
@@ -471,12 +471,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -488,7 +488,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -519,7 +519,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml
index 0db0a28c4..ed9423cc9 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml
+++ b/DsgTools/core/Qmls/qgis_37/edgv_213_pro/val_transportes_a.qml
@@ -282,12 +282,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -299,7 +299,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -330,7 +330,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -362,12 +362,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -383,7 +383,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py b/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py
index 0519ecba6..e69de29bb 100644
--- a/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py
+++ b/DsgTools/core/Qmls/qgis_37/edgv_3_pro/__init__.py
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml
index 40c468ac1..b870defda 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/aquisicao_limite_vegetacao_l.qml
@@ -240,12 +240,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -257,7 +257,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -288,7 +288,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -320,12 +320,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -341,7 +341,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml
index cfd145834..470bb6035 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/cobter_corpo_dagua_a.qml
@@ -327,12 +327,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -344,7 +344,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -375,7 +375,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -407,12 +407,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -428,7 +428,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml
index 3c8e8be2b..904412c0e 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/infra_via_deslocamento_l.qml
@@ -1784,12 +1784,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -1801,7 +1801,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -1832,7 +1832,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -1864,12 +1864,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -1885,7 +1885,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml
index 8d43a1de5..18f571220 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/llp_delimitacao_fisica_l.qml
@@ -280,12 +280,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -297,7 +297,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -328,7 +328,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -360,12 +360,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -381,7 +381,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml
index aab7fe9a9..a243c3bb8 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_hidrografia_p.qml
@@ -471,12 +471,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -488,7 +488,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -519,7 +519,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml
index df4d4b088..7514a1a3b 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/rev_vegetacao_p.qml
@@ -471,12 +471,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -488,7 +488,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -519,7 +519,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -551,12 +551,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -572,7 +572,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml
index 0db0a28c4..ed9423cc9 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_213_pro/val_transportes_a.qml
@@ -282,12 +282,12 @@ global a
class ValidateForm:
def __init__(self, layer, formValues, logBrowser):
- self.layer = layer
+ self.layer = layer
self.formValues = formValues
self.rules = []
self.logBrowser = logBrowser
self.validateForm()
-
+
def calculateExpression(self, exp):
for field in self.formValues:
if field != 'filter':
@@ -299,7 +299,7 @@ class ValidateForm:
exp = exp.replace("'NULL'".format(field), "NULL")
r = QgsExpression(exp)
return r.evaluate()
-
+
def validateForm(self):
self.cleanRulesOnForm()
logText = ""
@@ -330,7 +330,7 @@ class ValidateForm:
def cleanRulesOnForm(self):
for field in self.formValues:
if len(self.formValues[field]) == 3:
- self.formValues[field][2].setStyleSheet("")
+ self.formValues[field][2].setStyleSheet("")
else:
self.formValues[field][1].setStyleSheet("")
@@ -362,12 +362,12 @@ class ManagerForm(QtCore.QObject):
self.logFrame.show()
else:
self.logFrame.hide()
-
+
def eventFilter(self, o, event):
if event.type() in [7, 10, 11, 100]:
self.validateLayerByRules()
return False
-
+
def validateLayerByRules(self):
formValues = {}
for cb in self.myDialog.findChildren(QComboBox):
@@ -383,7 +383,7 @@ class ManagerForm(QtCore.QObject):
le
]
self.validadeForm = ValidateForm(self.lyr, formValues, self.logBrowser)
-
+
def finishedForm(self):
pass
diff --git a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py
index 0519ecba6..e69de29bb 100644
--- a/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py
+++ b/DsgTools/core/Qmls/qgis_37_impl_2/edgv_3_pro/__init__.py
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/DsgTools/core/ServerManagementTools/attributeRulesManager.py b/DsgTools/core/ServerManagementTools/attributeRulesManager.py
index b3eb2b7eb..5e2aec86b 100644
--- a/DsgTools/core/ServerManagementTools/attributeRulesManager.py
+++ b/DsgTools/core/ServerManagementTools/attributeRulesManager.py
@@ -20,25 +20,29 @@
* *
***************************************************************************/
"""
-#General imports
+# General imports
from osgeo import ogr
from uuid import uuid4
import codecs, os, json, binascii
-#DSG Tools imports
-from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
+# DSG Tools imports
+from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager
from DsgTools.core.Utils.utils import Utils
-#qgis.PyQt imports
+# qgis.PyQt imports
from qgis.PyQt.Qt import QObject
+
class AttributeRulesManager(GenericDbManager):
"""
This class manages the customizations on dsgtools databases.
"""
- def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
- super(AttributeRulesManager,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None)
+
+ def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None):
+ super(AttributeRulesManager, self).__init__(
+ serverAbstractDb, dbDict, edgvVersion, parentWidget=None
+ )
def validateJsonProfile(self, inputJsonDict):
"""
@@ -47,5 +51,5 @@ def validateJsonProfile(self, inputJsonDict):
3. If one piece of json is not valid, returns False.
This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile.
"""
- #TODO
+ # TODO
return True
diff --git a/DsgTools/core/ServerManagementTools/customizationManager.py b/DsgTools/core/ServerManagementTools/customizationManager.py
index 690c58b6a..8cf143b3f 100644
--- a/DsgTools/core/ServerManagementTools/customizationManager.py
+++ b/DsgTools/core/ServerManagementTools/customizationManager.py
@@ -20,26 +20,30 @@
* *
***************************************************************************/
"""
-#General imports
+# General imports
from osgeo import ogr
from uuid import uuid4
import codecs, os, json, binascii
-#DSG Tools imports
-from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
+# DSG Tools imports
+from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager
from DsgTools.core.Utils.utils import Utils
-#qgis.PyQt imports
+# qgis.PyQt imports
from qgis.PyQt.Qt import QObject
+
class CustomizationManager(GenericDbManager):
"""
This class manages the customizations on dsgtools databases.
"""
- def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
- super(self.__class__,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None)
-
+
+ def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None):
+ super(self.__class__, self).__init__(
+ serverAbstractDb, dbDict, edgvVersion, parentWidget=None
+ )
+
def installCustomization(self, customizationName):
"""
1. Get customization from dsgtools_admindb;
@@ -48,7 +52,7 @@ def installCustomization(self, customizationName):
4. If custom applied, save it on customization table on db and on dsgtools_admindb;
"""
pass
-
+
def removeCustomization(self, customizationName):
pass
@@ -62,9 +66,9 @@ def validateJsonProfile(self, inputJsonDict):
3. If one piece of json is not valid, returns False.
This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile.
"""
- #TODO
+ # TODO
return True
-
+
def getPropertyPerspectiveDict(self, viewType):
"""
Gets a dict in the format:
@@ -79,14 +83,16 @@ def materializeIntoDatabase(self, abstractDb, propertyDict):
"""
pass
- def undoMaterializationFromDatabase(self, abstractDb, configName, settingType, edgvVersion):
+ def undoMaterializationFromDatabase(
+ self, abstractDb, configName, settingType, edgvVersion
+ ):
"""
Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure
"""
pass
-
+
def hasStructuralChanges(self, dbNameList):
"""
Method that is reimplemented in each child
"""
- return []
\ No newline at end of file
+ return []
diff --git a/DsgTools/core/ServerManagementTools/earthCoverageManager.py b/DsgTools/core/ServerManagementTools/earthCoverageManager.py
index 662952946..5fff03347 100644
--- a/DsgTools/core/ServerManagementTools/earthCoverageManager.py
+++ b/DsgTools/core/ServerManagementTools/earthCoverageManager.py
@@ -20,48 +20,66 @@
* *
***************************************************************************/
"""
-#General imports
+# General imports
from osgeo import ogr
from uuid import uuid4
import codecs, os, json, binascii
-#DSG Tools imports
-from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
+# DSG Tools imports
+from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager
from DsgTools.core.Utils.utils import Utils
-#qgis.PyQt imports
+# qgis.PyQt imports
from qgis.PyQt.Qt import QObject
+
class EarthCoverageManager(GenericDbManager):
"""
This class manages the customizations on dsgtools databases.
"""
- def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
- super(self.__class__,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None)
+
+ def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None):
+ super(self.__class__, self).__init__(
+ serverAbstractDb, dbDict, edgvVersion, parentWidget=None
+ )
def materializeIntoDatabase(self, abstractDb, propertyDict):
"""
Method that is reimplemented in each child when installing a property involves changing any sort of database structure
"""
- jsonDict = self.utils.instantiateJsonDict(propertyDict['jsondict'])
- abstractDb.createCentroidAuxStruct(list(jsonDict['earthCoverageDict'].keys()), useTransaction = False)
+ jsonDict = self.utils.instantiateJsonDict(propertyDict["jsondict"])
+ abstractDb.createCentroidAuxStruct(
+ list(jsonDict["earthCoverageDict"].keys()), useTransaction=False
+ )
- def updateMaterializationFromDatabase(self, abstractDb, propertyDict, oldPropertyDict):
+ def updateMaterializationFromDatabase(
+ self, abstractDb, propertyDict, oldPropertyDict
+ ):
"""
Method that is reimplemented in each child when updating a property involves changing any sort of database structure
"""
- newJsonDict = self.utils.instantiateJsonDict(propertyDict['jsondict'])
- oldJsonDict = self.utils.instantiateJsonDict(oldPropertyDict['jsondict'])
- abstractDb.updateEarthCoverageDict(newJsonDict, oldJsonDict, useTransaction = True)
-
- def undoMaterializationFromDatabase(self, abstractDb, propertyName, settingType, edgvVersion):
+ newJsonDict = self.utils.instantiateJsonDict(propertyDict["jsondict"])
+ oldJsonDict = self.utils.instantiateJsonDict(oldPropertyDict["jsondict"])
+ abstractDb.updateEarthCoverageDict(
+ newJsonDict, oldJsonDict, useTransaction=True
+ )
+
+ def undoMaterializationFromDatabase(
+ self, abstractDb, propertyName, settingType, edgvVersion
+ ):
"""
Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure
"""
- jsonDict = self.utils.instantiateJsonDict(abstractDb.getRecordFromAdminDb(settingType, propertyName, edgvVersion)['jsondict'])
- abstractDb.dropCentroids(list(jsonDict['earthCoverageDict'].keys()), useTransaction = False)
-
+ jsonDict = self.utils.instantiateJsonDict(
+ abstractDb.getRecordFromAdminDb(settingType, propertyName, edgvVersion)[
+ "jsondict"
+ ]
+ )
+ abstractDb.dropCentroids(
+ list(jsonDict["earthCoverageDict"].keys()), useTransaction=False
+ )
+
def hasStructuralChanges(self, dbNameList):
"""
Method that is reimplemented in each child
diff --git a/DsgTools/core/ServerManagementTools/genericDbManager.py b/DsgTools/core/ServerManagementTools/genericDbManager.py
index 914cbeef7..d6e1f6084 100644
--- a/DsgTools/core/ServerManagementTools/genericDbManager.py
+++ b/DsgTools/core/ServerManagementTools/genericDbManager.py
@@ -20,51 +20,62 @@
* *
***************************************************************************/
"""
-#General imports
+# General imports
from builtins import str
from osgeo import ogr
from uuid import uuid4
import codecs, os, json, binascii
-#DSG Tools imports
-from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
+# DSG Tools imports
+from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
-#qgis.PyQt imports
+# qgis.PyQt imports
from qgis.PyQt.Qt import QObject
+
class GenericDbManager(QObject):
"""
This class manages the permissions on dsgtools databases.
"""
- def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
- super(GenericDbManager,self).__init__()
+
+ def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None):
+ super(GenericDbManager, self).__init__()
self.parentWidget = parentWidget
self.dbDict = dbDict
self.serverAbstractDb = serverAbstractDb
self.adminDb = self.instantiateAdminDb(serverAbstractDb)
self.utils = Utils()
- self.extensionDict = {'EarthCoverage':'.dsgearthcov',
- 'Customization':'.dsgcustom',
- 'Style':'.dsgstyle',
- 'ValidationConfig':'.dsgvalidcfg',
- 'Permission':'.dsgperm',
- 'AttributeRules':'.dsgattrrul',
- 'SpatialRules':'.dsgspatrul',
- 'ValidationWorkspace':'.dsgworksp'}
+ self.extensionDict = {
+ "EarthCoverage": ".dsgearthcov",
+ "Customization": ".dsgcustom",
+ "Style": ".dsgstyle",
+ "ValidationConfig": ".dsgvalidcfg",
+ "Permission": ".dsgperm",
+ "AttributeRules": ".dsgattrrul",
+ "SpatialRules": ".dsgspatrul",
+ "ValidationWorkspace": ".dsgworksp",
+ }
self.edgvVersion = edgvVersion
self.createPropertyTable()
def getManagerType(self):
- return str(self.__class__).split('.')[-1].replace('\'>', '').replace('Manager','')
+ return (
+ str(self.__class__).split(".")[-1].replace("'>", "").replace("Manager", "")
+ )
def instantiateAbstractDb(self, dbName):
"""
Instantiates an abstractDb.
"""
if dbName not in list(self.dbDict.keys()):
- (host, port, user, password) = self.serverAbstractDb.getParamsFromConectedDb()
+ (
+ host,
+ port,
+ user,
+ password,
+ ) = self.serverAbstractDb.getParamsFromConectedDb()
abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS)
abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password)
else:
@@ -73,22 +84,26 @@ def instantiateAbstractDb(self, dbName):
def instantiateAdminDb(self, serverAbstractDb):
"""
- Instantiates dsgtools_admindb in the same server as serverAbstractDb.
+ Instantiates dsgtools_admindb in the same server as serverAbstractDb.
If dsgtools_admindb does not exists, instantiateAdminDb calls createAdminDb
"""
(host, port, user, password) = serverAbstractDb.getParamsFromConectedDb()
adminDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS)
if not serverAbstractDb.hasAdminDb():
- return self.createAdminDb(serverAbstractDb, adminDb, host, port, user, password)
- adminDb.connectDatabaseWithParameters(host, port, 'dsgtools_admindb', user, password)
+ return self.createAdminDb(
+ serverAbstractDb, adminDb, host, port, user, password
+ )
+ adminDb.connectDatabaseWithParameters(
+ host, port, "dsgtools_admindb", user, password
+ )
managerType = self.getManagerType()
if not adminDb.checkIfExistsConfigTable(managerType):
- adminDb.createPropertyTable(managerType, isAdminDb = True)
+ adminDb.createPropertyTable(managerType, isAdminDb=True)
return adminDb
-
+
def instantiateTemplateDb(self, edgvVersion):
"""
- Instantiates a templateDb in the same server as serverAbstractDb.
+ Instantiates a templateDb in the same server as serverAbstractDb.
If template does not exists, instantiateAdminDb calls createTemplate
"""
templateName = self.serverAbstractDb.getTemplateName(edgvVersion)
@@ -97,7 +112,7 @@ def instantiateTemplateDb(self, edgvVersion):
self.serverAbstractDb.createTemplateDatabase(edgvVersion)
templateDb = self.instantiateAbstractDb(templateName)
templateDb.setStructureFromSql(edgvVersion, 4674)
- templateDb.setDbAsTemplate(version = edgvVersion)
+ templateDb.setDbAsTemplate(version=edgvVersion)
else:
templateDb = self.instantiateAbstractDb(templateName)
return templateDb
@@ -107,8 +122,10 @@ def createAdminDb(self, serverAbstractDb, adminDb, host, port, user, password):
Creates dsgtools_admindb
"""
serverAbstractDb.createAdminDb()
- adminDb.connectDatabaseWithParameters(host, port, 'dsgtools_admindb', user, password)
- sqlPath = adminDb.getCreationSqlPath('admin')
+ adminDb.connectDatabaseWithParameters(
+ host, port, "dsgtools_admindb", user, password
+ )
+ sqlPath = adminDb.getCreationSqlPath("admin")
adminDb.runSqlFromFile(sqlPath)
return adminDb
@@ -124,9 +141,15 @@ def getSetting(self, name, edgvVersion):
Get setting from corresponding table on dsgtools_admindb
"""
settingType = self.getManagerType()
- settingDict = json.loads(self.adminDb.getSettingFromAdminDb(settingType, name, edgvVersion))
+ settingDict = json.loads(
+ self.adminDb.getSettingFromAdminDb(settingType, name, edgvVersion)
+ )
if not settingDict:
- raise Exception(self.tr("Setting ")+ settingType +self.tr(" not found on dsgtools_admindb!"))
+ raise Exception(
+ self.tr("Setting ")
+ + settingType
+ + self.tr(" not found on dsgtools_admindb!")
+ )
return settingDict
def createSetting(self, settingName, edgvVersion, jsonDict):
@@ -134,21 +157,25 @@ def createSetting(self, settingName, edgvVersion, jsonDict):
Creates setting on dsgtools_admindb.
"""
settingType = self.getManagerType()
- if isinstance(jsonDict,dict):
- jsonDict = json.dumps(jsonDict,sort_keys=True, indent=4)
- self.adminDb.insertSettingIntoAdminDb(settingType, settingName, jsonDict, edgvVersion)
+ if isinstance(jsonDict, dict):
+ jsonDict = json.dumps(jsonDict, sort_keys=True, indent=4)
+ self.adminDb.insertSettingIntoAdminDb(
+ settingType, settingName, jsonDict, edgvVersion
+ )
- def updateSetting(self, settingName, newJsonDict, edgvVersion = None):
+ def updateSetting(self, settingName, newJsonDict, edgvVersion=None):
"""
Generic update. Can be reimplenented in child methods.
- 1. Get property dict from adminDb
+ 1. Get property dict from adminDb
"""
if not edgvVersion:
edgvVersion = self.edgvVersion
errorDict = dict()
successList = []
settingType = self.getManagerType()
- propertyDict = self.adminDb.getPropertyPerspectiveDict(settingType, DsgEnums.Property, versionFilter = edgvVersion)
+ propertyDict = self.adminDb.getPropertyPerspectiveDict(
+ settingType, DsgEnums.Property, versionFilter=edgvVersion
+ )
if settingName in list(propertyDict.keys()):
rollbackList = []
self.adminDb.db.transaction()
@@ -157,9 +184,13 @@ def updateSetting(self, settingName, newJsonDict, edgvVersion = None):
abstractDb = self.instantiateAbstractDb(dbName)
abstractDb.db.transaction()
rollbackList.append(abstractDb)
- self.updateMaterializationFromDatabase(abstractDb,propertyDict)
- abstractDb.updateRecordFromPropertyTable(settingType, settingName, edgvVersion, newJsonDict)
- self.adminDb.updateRecordFromPropertyTable(settingType, settingName, edgvVersion, newJsonDict)
+ self.updateMaterializationFromDatabase(abstractDb, propertyDict)
+ abstractDb.updateRecordFromPropertyTable(
+ settingType, settingName, edgvVersion, newJsonDict
+ )
+ self.adminDb.updateRecordFromPropertyTable(
+ settingType, settingName, edgvVersion, newJsonDict
+ )
for abstractDb in rollbackList:
abstractDb.db.commit()
self.adminDb.db.commit()
@@ -168,7 +199,7 @@ def updateSetting(self, settingName, newJsonDict, edgvVersion = None):
for abstractDb in rollbackList:
abstractDb.db.rollback()
self.adminDb.db.rollback()
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
return (successList, errorDict)
def importSetting(self, fullFilePath):
@@ -178,23 +209,30 @@ def importSetting(self, fullFilePath):
2. Validates inputPermissionDict;
3. Tries to insert into database, if there is an error, abstractDb raises an error which is also raised by importProfile
"""
- #getting profile name
- settingName = os.path.basename(fullFilePath).split('.')[0]
- #getting json
- inputJsonDict, inputJson = self.utils.readJsonFile(fullFilePath, returnFileAndDict = True)
- #error handling and json validation
+ # getting profile name
+ settingName = os.path.basename(fullFilePath).split(".")[0]
+ # getting json
+ inputJsonDict, inputJson = self.utils.readJsonFile(
+ fullFilePath, returnFileAndDict=True
+ )
+ # error handling and json validation
if inputJsonDict == dict():
raise Exception(self.tr("Not valid DsgTools property file!"))
if not self.validateJsonSetting(inputJsonDict):
raise Exception(self.tr("Not valid DsgTools property file!"))
- if 'version' in list(inputJsonDict.keys()):
- edgvVersion = inputJsonDict['version']
+ if "version" in list(inputJsonDict.keys()):
+ edgvVersion = inputJsonDict["version"]
else:
- edgvVersion = list(inputJsonDict.keys())[0].split('_')[-1]
+ edgvVersion = list(inputJsonDict.keys())[0].split("_")[-1]
try:
self.createSetting(settingName, edgvVersion, inputJson)
except Exception as e:
- raise Exception(self.tr("Error importing setting ") + settingName +': '+':'.join(e.args))
+ raise Exception(
+ self.tr("Error importing setting ")
+ + settingName
+ + ": "
+ + ":".join(e.args)
+ )
def batchImportSettings(self, profilesDir):
"""
@@ -204,7 +242,7 @@ def batchImportSettings(self, profilesDir):
importList = []
for profile in next(os.walk(profilesDir))[2]:
if self.extensionDict[self.getManagerType()] in os.path.basename(profile):
- importList.append(os.path.join(profilesDir,profile))
+ importList.append(os.path.join(profilesDir, profile))
for profileFile in importList:
self.importSetting(profileFile)
@@ -216,10 +254,12 @@ def exportSetting(self, profileName, edgvVersion, outputPath):
jsonDict = self.getSetting(profileName, edgvVersion)
if not os.path.exists(outputPath):
os.makedirs(outputPath)
- outputFile = os.path.join(outputPath, profileName+self.extensionDict[self.getManagerType()])
- with open(outputFile, 'w') as outfile:
+ outputFile = os.path.join(
+ outputPath, profileName + self.extensionDict[self.getManagerType()]
+ )
+ with open(outputFile, "w") as outfile:
json.dump(jsonDict, outfile, sort_keys=True, indent=4)
-
+
def batchExportSettings(self, outputDir):
"""
1. Get all settings from corresponding table in dsgtools_admindb;
@@ -227,40 +267,44 @@ def batchExportSettings(self, outputDir):
"""
settingDict = self.getSettings()
for edgvVersion in list(settingDict.keys()):
- outputPath = os.path.join(outputDir,edgvVersion)
+ outputPath = os.path.join(outputDir, edgvVersion)
if not os.path.exists(outputPath):
os.makedirs(outputPath)
for profileName in settingDict[edgvVersion]:
self.exportSetting(profileName, edgvVersion, outputPath)
- def getPropertyPerspectiveDict(self, viewType = DsgEnums.Property, versionFilter = None):
+ def getPropertyPerspectiveDict(
+ self, viewType=DsgEnums.Property, versionFilter=None
+ ):
"""
Gets a dict in the format:
if viewType == 'customization': {customizationName: ['-list of databases with customization']}
if viewType == 'database': {databaseName: ['-list of customizations with customization']}
"""
settingType = self.getManagerType()
- return self.adminDb.getPropertyPerspectiveDict(settingType, viewType, versionFilter = versionFilter)
-
+ return self.adminDb.getPropertyPerspectiveDict(
+ settingType, viewType, versionFilter=versionFilter
+ )
+
def getSettingVersion(self, settingName):
settingType = self.getManagerType()
return self.adminDb.getSettingVersion(settingType, settingName)
-
+
def validateJsonSetting(self, inputJsonDict):
"""
reimplemented in each child
"""
return True
-
+
def getRecordFromAdminDb(self, propertyName, edgvVersion):
settingType = self.getManagerType()
return self.adminDb.getRecordFromAdminDb(settingType, propertyName, edgvVersion)
- def createAndInstall(self, configName, newJsonDict, edgvVersion, dbList = []):
+ def createAndInstall(self, configName, newJsonDict, edgvVersion, dbList=[]):
self.createSetting(configName, edgvVersion, newJsonDict)
- return self.installSetting(configName,dbNameList = dbList)
+ return self.installSetting(configName, dbNameList=dbList)
- def installSetting(self, configName, dbNameList = []):
+ def installSetting(self, configName, dbNameList=[]):
"""
Generic install. Can be reimplenented in child methods.
"""
@@ -274,70 +318,88 @@ def installSetting(self, configName, dbNameList = []):
abstractDb = self.instantiateAbstractDb(dbName)
edgvVersion = abstractDb.getDatabaseVersion()
if edgvVersion != configEdgvVersion:
- errorDict[dbName] = self.tr('Database version missmatch.')
+ errorDict[dbName] = self.tr("Database version missmatch.")
continue
- recDict = self.adminDb.getRecordFromAdminDb(settingType, configName, edgvVersion)
+ recDict = self.adminDb.getRecordFromAdminDb(
+ settingType, configName, edgvVersion
+ )
try:
if not abstractDb.checkIfExistsConfigTable(settingType):
- abstractDb.createPropertyTable(settingType, useTransaction = True)
+ abstractDb.createPropertyTable(settingType, useTransaction=True)
except Exception as e:
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
continue
try:
abstractDb.db.transaction()
self.adminDb.db.transaction()
- self.materializeIntoDatabase(abstractDb, recDict) #step done when property management involves changing database structure
- abstractDb.insertRecordInsidePropertyTable(settingType, recDict, edgvVersion)
+ self.materializeIntoDatabase(
+ abstractDb, recDict
+ ) # step done when property management involves changing database structure
+ abstractDb.insertRecordInsidePropertyTable(
+ settingType, recDict, edgvVersion
+ )
dbOid = abstractDb.getDbOID()
- self.adminDb.insertInstalledRecordIntoAdminDb(settingType, recDict, dbOid)
+ self.adminDb.insertInstalledRecordIntoAdminDb(
+ settingType, recDict, dbOid
+ )
abstractDb.db.commit()
self.adminDb.db.commit()
except Exception as e:
abstractDb.db.rollback()
self.adminDb.db.rollback()
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
successList.append(dbName)
return (successList, errorDict)
-
- def deleteSetting(self, configName, dbNameList = []):
+
+ def deleteSetting(self, configName, dbNameList=[]):
"""
Generic remove. Can be reimplenented in child methods.
- 1. Get property dict from adminDb
+ 1. Get property dict from adminDb
"""
errorDict = dict()
successList = []
settingType = self.getManagerType()
- propertyDict = self.adminDb.getPropertyPerspectiveDict(settingType, DsgEnums.Property)
+ propertyDict = self.adminDb.getPropertyPerspectiveDict(
+ settingType, DsgEnums.Property
+ )
if configName in list(propertyDict.keys()):
for dbName in propertyDict[configName]:
if not dbName:
try:
self.adminDb.db.transaction()
- self.adminDb.removeRecordFromPropertyTable(settingType, configName, None)
+ self.adminDb.removeRecordFromPropertyTable(
+ settingType, configName, None
+ )
self.adminDb.db.commit()
successList.append(dbName)
except Exception as e:
self.adminDb.db.rollback()
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
else:
abstractDb = self.instantiateAbstractDb(dbName)
edgvVersion = abstractDb.getDatabaseVersion()
try:
abstractDb.db.transaction()
self.adminDb.db.transaction()
- self.undoMaterializationFromDatabase(abstractDb, configName, settingType, edgvVersion) #step done when property management involves changing database structure
- abstractDb.removeRecordFromPropertyTable(settingType, configName, edgvVersion)
- self.adminDb.removeRecordFromPropertyTable(settingType, configName, edgvVersion)
+ self.undoMaterializationFromDatabase(
+ abstractDb, configName, settingType, edgvVersion
+ ) # step done when property management involves changing database structure
+ abstractDb.removeRecordFromPropertyTable(
+ settingType, configName, edgvVersion
+ )
+ self.adminDb.removeRecordFromPropertyTable(
+ settingType, configName, edgvVersion
+ )
abstractDb.db.commit()
self.adminDb.db.commit()
successList.append(dbName)
except Exception as e:
abstractDb.db.rollback()
self.adminDb.db.rollback()
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
return (successList, errorDict)
- def uninstallSetting(self, configName, dbNameList = []):
+ def uninstallSetting(self, configName, dbNameList=[]):
"""
Generic uninstall. Can be reimplenented in child methods.
This can uninstall setting on a list of databases or in all databases (if dbNameList == [])
@@ -345,11 +407,15 @@ def uninstallSetting(self, configName, dbNameList = []):
errorDict = dict()
successList = []
settingType = self.getManagerType()
- propertyDict = self.adminDb.getPropertyPerspectiveDict(settingType, DsgEnums.Property)
+ propertyDict = self.adminDb.getPropertyPerspectiveDict(
+ settingType, DsgEnums.Property
+ )
if configName in list(propertyDict.keys()):
- if dbNameList == []: #builds filter dbList to uninstall in all installed databases
+ if (
+ dbNameList == []
+ ): # builds filter dbList to uninstall in all installed databases
dbList = propertyDict[configName]
- else: #builds filter dbList to uninstall in databases in dbNameList
+ else: # builds filter dbList to uninstall in databases in dbNameList
dbList = [i for i in propertyDict[configName] if i in dbNameList]
for dbName in dbList:
abstractDb = self.instantiateAbstractDb(dbName)
@@ -357,42 +423,50 @@ def uninstallSetting(self, configName, dbNameList = []):
try:
abstractDb.db.transaction()
self.adminDb.db.transaction()
- self.undoMaterializationFromDatabase(abstractDb, configName, settingType, edgvVersion) #step done when property management involves changing database structure
- abstractDb.removeRecordFromPropertyTable(settingType, configName, edgvVersion)
- self.adminDb.uninstallPropertyOnAdminDb(settingType, configName, edgvVersion, dbName = dbName)
+ self.undoMaterializationFromDatabase(
+ abstractDb, configName, settingType, edgvVersion
+ ) # step done when property management involves changing database structure
+ abstractDb.removeRecordFromPropertyTable(
+ settingType, configName, edgvVersion
+ )
+ self.adminDb.uninstallPropertyOnAdminDb(
+ settingType, configName, edgvVersion, dbName=dbName
+ )
abstractDb.db.commit()
self.adminDb.db.commit()
except Exception as e:
abstractDb.db.rollback()
self.adminDb.db.rollback()
- errorDict[dbName] = ':'.join(e.args)
+ errorDict[dbName] = ":".join(e.args)
successList.append(dbName)
return (successList, errorDict)
-
+
def materializeIntoDatabase(self, abstractDb, propertyDict):
"""
Method that is reimplemented in each child when installing a property involves changing any sort of database structure
"""
pass
- def undoMaterializationFromDatabase(self, abstractDb, configName, settingType, edgvVersion):
+ def undoMaterializationFromDatabase(
+ self, abstractDb, configName, settingType, edgvVersion
+ ):
"""
Method that is reimplemented in each child when uninstalling a property involves changing any sort of database structure
"""
pass
-
+
def hasStructuralChanges(self, dbNameList):
"""
Method that is reimplemented in each child
"""
return []
-
+
def createPropertyTable(self):
settingType = self.getManagerType()
for dbName in list(self.dbDict.keys()):
abstractDb = self.instantiateAbstractDb(dbName)
if not abstractDb.checkIfExistsConfigTable(settingType):
- abstractDb.createPropertyTable(settingType, useTransaction = True)
-
+ abstractDb.createPropertyTable(settingType, useTransaction=True)
+
def updateMaterializationFromDatabase(self, abstractDb, propertyDict):
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/core/ServerManagementTools/permissionManager.py b/DsgTools/core/ServerManagementTools/permissionManager.py
index 0978b9869..804851cc9 100644
--- a/DsgTools/core/ServerManagementTools/permissionManager.py
+++ b/DsgTools/core/ServerManagementTools/permissionManager.py
@@ -20,49 +20,53 @@
* *
***************************************************************************/
"""
-#General imports
+# General imports
from osgeo import ogr
from uuid import uuid4
import codecs, os, json, binascii
-#DSG Tools imports
-from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
+# DSG Tools imports
+from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager
from DsgTools.core.Utils.utils import Utils
-#qgis.PyQt imports
+# qgis.PyQt imports
from qgis.PyQt.Qt import QObject
+
class PermissionManager(GenericDbManager):
- '''
+ """
This class manages the permissions on dsgtools databases.
- '''
- def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
- super(self.__class__,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None)
-
+ """
+
+ def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None):
+ super(self.__class__, self).__init__(
+ serverAbstractDb, dbDict, edgvVersion, parentWidget=None
+ )
+
def getRolesInformation(self):
- '''
+ """
Builds two dicts:
dbRolesDict = { 'dbname':[-list of roles-] }
rolesDict = { 'profileName': { 'dbname' : [-list of roles with uuid on it-] } }
- '''
+ """
dbRolesDict = self.adminDb.getRolesDict()
rolesDict = dict()
for db in list(dbRolesDict.keys()):
for role in dbRolesDict[db]:
- profileName = '_'.join(role.split('_')[0:-5])
+ profileName = "_".join(role.split("_")[0:-5])
if profileName not in list(rolesDict.keys()):
rolesDict[profileName] = dict()
if db not in list(rolesDict[profileName].keys()):
rolesDict[profileName][db] = []
rolesDict[profileName][db].append(role)
return dbRolesDict, rolesDict
-
+
def getDatabasePerspectiveDict(self):
- '''
+ """
Gets a dict in the format: {dbName: {roleName :[-list of users-]}}
- The dbs are from dbDict
- '''
+ The dbs are from dbDict
+ """
(dbRolesDict, rolesDict) = self.getRolesInformation()
profiles = self.getSettings()
grantedRoleDict = self.adminDb.getGrantedRolesDict()
@@ -80,20 +84,25 @@ def getDatabasePerspectiveDict(self):
for role in rolesDict[profile][dbName]:
if role in list(grantedRoleDict.keys()):
for user in grantedRoleDict[role]:
- if user not in dbPerspectiveDict[dbName][profile]:
- dbPerspectiveDict[dbName][profile].append(user)
+ if (
+ user
+ not in dbPerspectiveDict[dbName][profile]
+ ):
+ dbPerspectiveDict[dbName][profile].append(
+ user
+ )
return dbPerspectiveDict
-
+
def getUserPerspectiveDict(self):
- '''
+ """
Gets a dict in the format: {userName: {dbName : ['-list of roles']}
- '''
+ """
dbPerspectiveDict = self.getDatabasePerspectiveDict()
userPerspectiveDict = dict()
userList = [i[0] for i in self.adminDb.getUsersFromServer()]
for user in userList:
userPerspectiveDict[user] = dict()
-
+
for dbName in list(dbPerspectiveDict.keys()):
for profile in dbPerspectiveDict[dbName]:
for user in dbPerspectiveDict[dbName][profile]:
@@ -102,65 +111,87 @@ def getUserPerspectiveDict(self):
if profile not in userPerspectiveDict[user][dbName]:
userPerspectiveDict[user][dbName].append(profile)
return userPerspectiveDict
-
+
def grantPermission(self, dbName, permissionName, edgvVersion, userName):
- '''
+ """
Grants permission on a db to a user using a profile.
1. Gets profile from public.permission_profile;
2. Checks if profile exists on db, if it does not, installs it;
3. Grants profile to user on db.
- '''
+ """
profileDict = self.getSetting(permissionName, edgvVersion)
- self.grantPermissionWithProfileDict(dbName, permissionName, userName, profileDict)
-
- def grantPermissionWithProfileDict(self, dbName, permissionName, userName, profileDict, updatePermission = False):
- '''
+ self.grantPermissionWithProfileDict(
+ dbName, permissionName, userName, profileDict
+ )
+
+ def grantPermissionWithProfileDict(
+ self, dbName, permissionName, userName, profileDict, updatePermission=False
+ ):
+ """
Grants permission on a db using profileDict
- '''
+ """
if updatePermission:
- role = self.dbDict[dbName].createRole(permissionName, profileDict, permissionManager = True)
+ role = self.dbDict[dbName].createRole(
+ permissionName, profileDict, permissionManager=True
+ )
self.dbDict[dbName].grantRole(userName, role)
else:
- if not self.isPermissionInstalled(self.dbDict[dbName], dbName, permissionName):
- self.dbDict[dbName].createRole(permissionName, profileDict) #creates profile in db
- (dbRolesDict, rolesDict) = self.getRolesInformation() #done to refresh dicts due to new permission
+ if not self.isPermissionInstalled(
+ self.dbDict[dbName], dbName, permissionName
+ ):
+ self.dbDict[dbName].createRole(
+ permissionName, profileDict
+ ) # creates profile in db
+ (
+ dbRolesDict,
+ rolesDict,
+ ) = (
+ self.getRolesInformation()
+ ) # done to refresh dicts due to new permission
for role in rolesDict[permissionName][dbName]:
self.dbDict[dbName].grantRole(userName, role)
-
+
def revokePermission(self, dbName, permissionName, userName):
- '''
+ """
Revokes permission on a db from permissionName.
- '''
+ """
(dbRolesDict, rolesDict) = self.getRolesInformation()
for realRoleName in rolesDict[permissionName][dbName]:
try:
self.dbDict[dbName].revokeRole(userName, realRoleName)
except Exception as e:
- raise Exception(self.tr('Problem revoking role ') + permissionName + self.tr(' on database ') + dbName +':\n' + ':'.join(e.args))
-
+ raise Exception(
+ self.tr("Problem revoking role ")
+ + permissionName
+ + self.tr(" on database ")
+ + dbName
+ + ":\n"
+ + ":".join(e.args)
+ )
+
def isPermissionInstalled(self, abstractDb, dbName, permissionName):
- '''
+ """
Checks if permission is already installed;
Returns True if it is installed and False otherwise.
- '''
+ """
(dbRolesDict, rolesDict) = self.getRolesInformation()
if permissionName not in list(rolesDict.keys()):
return False
if dbName not in list(rolesDict[permissionName].keys()):
return False
return True
-
+
def updateSetting(self, settingName, edgvVersion, newProfileDict):
- '''
+ """
1. Gets all roles from all databases that have the same settingName;
2. For each role, get users that are granted to them;
3. Drop role, create a new one and grant it to previous users;
4. Updates public.permission_profile on dsgtools_admindb with the newJsonDict.
- '''
+ """
abstractDbsToRollBack = []
try:
abstractDbsToRollBack.append(self.adminDb)
- self.adminDb.db.transaction() #done to rollback in case of trouble
+ self.adminDb.db.transaction() # done to rollback in case of trouble
(dbRolesDict, rolesDict) = self.getRolesInformation()
grantedRoleDict = self.adminDb.getGrantedRolesDict()
if settingName in list(rolesDict.keys()):
@@ -170,7 +201,7 @@ def updateSetting(self, settingName, edgvVersion, newProfileDict):
abstractDb = self.instantiateAbstractDb(dbName)
else:
abstractDb = self.dbDict[dbName]
- #prepairs to rollback in case of exception
+ # prepairs to rollback in case of exception
abstractDbsToRollBack.append(abstractDb)
abstractDb.db.transaction()
usersToBeGranted = []
@@ -178,26 +209,39 @@ def updateSetting(self, settingName, edgvVersion, newProfileDict):
usersToBeGranted = grantedRoleDict[roleName]
abstractDb.dropRoleOnDatabase(roleName)
for userName in usersToBeGranted:
- self.grantPermissionWithProfileDict(dbName, settingName, userName, newProfileDict, updatePermission = True)
+ self.grantPermissionWithProfileDict(
+ dbName,
+ settingName,
+ userName,
+ newProfileDict,
+ updatePermission=True,
+ )
newjsonprofile = json.dumps(newProfileDict, sort_keys=True, indent=4)
- self.adminDb.updatePermissionProfile(settingName, edgvVersion, newjsonprofile)
+ self.adminDb.updatePermissionProfile(
+ settingName, edgvVersion, newjsonprofile
+ )
for abstractDb in abstractDbsToRollBack:
abstractDb.db.commit()
except Exception as e:
for abstractDb in abstractDbsToRollBack:
abstractDb.db.rollback()
- raise Exception(self.tr('Unable to update profile ') + settingName +': ' +':'.join(e.args))
-
+ raise Exception(
+ self.tr("Unable to update profile ")
+ + settingName
+ + ": "
+ + ":".join(e.args)
+ )
+
def deleteSetting(self, settingName, edgvVersion):
- '''
+ """
1. Get roles with the same definition of permissionName and delete them.
2. Delete permission profile from public.permission_profile on dsgtools_admindb;
- '''
- #first step, delete roles with the same definition of selected profile
+ """
+ # first step, delete roles with the same definition of selected profile
abstractDbsToRollBack = []
try:
abstractDbsToRollBack.append(self.adminDb)
- self.adminDb.db.transaction() #done to rollback in case of trouble
+ self.adminDb.db.transaction() # done to rollback in case of trouble
(dbRolesDict, rolesDict) = self.getRolesInformation()
if settingName in list(rolesDict.keys()):
for dbName in list(rolesDict[settingName].keys()):
@@ -206,43 +250,55 @@ def deleteSetting(self, settingName, edgvVersion):
abstractDb = self.instantiateAbstractDb(dbName)
else:
abstractDb = self.dbDict[dbName]
- #prepairs to rollback in case of exception
+ # prepairs to rollback in case of exception
abstractDbsToRollBack.append(abstractDb)
abstractDb.db.transaction()
abstractDb.dropRoleOnDatabase(roleName)
- #after deletion, delete permission profile from public.permission_profile
- self.adminDb.removeRecordFromPropertyTable('Permission',settingName, edgvVersion)
+ # after deletion, delete permission profile from public.permission_profile
+ self.adminDb.removeRecordFromPropertyTable(
+ "Permission", settingName, edgvVersion
+ )
for abstractDb in abstractDbsToRollBack:
abstractDb.db.commit()
except Exception as e:
for abstractDb in abstractDbsToRollBack:
abstractDb.db.rollback()
- raise Exception(self.tr('Problem deleting permission: ')+':'.join(e.args))
-
+ raise Exception(self.tr("Problem deleting permission: ") + ":".join(e.args))
+
def validateJsonProfile(self, inputJsonDict):
- '''
+ """
1. Validates each key and value in inputJsonDict;
2. If input is ok, returns True;
3. If one piece of json is not valid, returns False.
This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile.
- '''
+ """
for key1 in list(inputJsonDict.keys()):
if not isinstance(inputJsonDict[key1], dict):
return False
- if key1 not in ['database_2.1.3', 'database_2.1.3_pro', 'database_3.0', 'database_FTer_2a_Ed','database_Non_EDGV']:
+ if key1 not in [
+ "database_2.1.3",
+ "database_2.1.3_pro",
+ "database_3.0",
+ "database_FTer_2a_Ed",
+ "database_Non_EDGV",
+ ]:
return False
for key2 in list(inputJsonDict[key1].keys()):
- if not isinstance(inputJsonDict[key1][key2],dict):
+ if not isinstance(inputJsonDict[key1][key2], dict):
return False
for key3 in list(inputJsonDict[key1][key2].keys()):
- if not isinstance(inputJsonDict[key1][key2][key3],dict):
+ if not isinstance(inputJsonDict[key1][key2][key3], dict):
return False
for key4 in list(inputJsonDict[key1][key2][key3].keys()):
- if not isinstance(inputJsonDict[key1][key2][key3][key4],dict):
+ if not isinstance(inputJsonDict[key1][key2][key3][key4], dict):
return False
for key5 in list(inputJsonDict[key1][key2][key3][key4].keys()):
if key5 not in ["read", "write"]:
return False
- if inputJsonDict[key1][key2][key3][key4][key5] not in ["0","1","2"]:
+ if inputJsonDict[key1][key2][key3][key4][key5] not in [
+ "0",
+ "1",
+ "2",
+ ]:
return False
return True
diff --git a/DsgTools/core/ServerManagementTools/validationWorkflowManager.py b/DsgTools/core/ServerManagementTools/validationWorkflowManager.py
index e94274fa0..1bc979c3c 100644
--- a/DsgTools/core/ServerManagementTools/validationWorkflowManager.py
+++ b/DsgTools/core/ServerManagementTools/validationWorkflowManager.py
@@ -20,25 +20,29 @@
* *
***************************************************************************/
"""
-#General imports
+# General imports
from osgeo import ogr
from uuid import uuid4
import codecs, os, json, binascii
-#DSG Tools imports
-from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
+# DSG Tools imports
+from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.ServerManagementTools.genericDbManager import GenericDbManager
from DsgTools.core.Utils.utils import Utils
-#qgis.PyQt imports
+# qgis.PyQt imports
from qgis.PyQt.Qt import QObject
+
class ValidationWorkflowManager(GenericDbManager):
"""
This class manages the customizations on dsgtools databases.
"""
- def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget = None):
- super(ValidationWorkflowManager,self).__init__(serverAbstractDb, dbDict, edgvVersion, parentWidget = None)
+
+ def __init__(self, serverAbstractDb, dbDict, edgvVersion, parentWidget=None):
+ super(ValidationWorkflowManager, self).__init__(
+ serverAbstractDb, dbDict, edgvVersion, parentWidget=None
+ )
def validateJsonProfile(self, inputJsonDict):
"""
@@ -47,5 +51,5 @@ def validateJsonProfile(self, inputJsonDict):
3. If one piece of json is not valid, returns False.
This validator does not validate the name of classes or names of categories. It only checks the format of dsgtools json profile.
"""
- #TODO
+ # TODO
return True
diff --git a/DsgTools/core/Utils/FrameTools/map_index.py b/DsgTools/core/Utils/FrameTools/map_index.py
index 40442dfb9..5cc724d61 100644
--- a/DsgTools/core/Utils/FrameTools/map_index.py
+++ b/DsgTools/core/Utils/FrameTools/map_index.py
@@ -28,201 +28,208 @@
import string, os, math, itertools, csv
from qgis.PyQt.QtCore import QObject
+
class UtmGrid(QObject):
def __init__(self):
"""Constructor."""
- super(UtmGrid,self).__init__()
- self.scales=[1000,500,250,100,50,25,10,5,2,1]
- nomen1000=['Nao Recorta']
- nomen500=[['V','X'],['Y','Z']]
- nomen250=[['A','B'],['C','D']]
- nomen100=[['I','II','III'],['IV','V','VI']]
- nomen50=[['1','2'],['3','4']]
- nomen25=[['NO','NE'],['SO','SE']]
- nomen10=[['A','B'],['C','D'],['E','F']]
- nomen5=[['I','II'],['III','IV']]
- nomen2=[['1', '2', '3'], ['4', '5', '6']]
- nomen1=[['A','B'],['C','D']]
- self.scaleText=[nomen1000,nomen500,nomen250,nomen100,nomen50,nomen25,nomen10,nomen5,nomen2,nomen1]
- self.matrizRecorte=[]
- self.spacingX=[]
- self.spacingY=[]
- self.stepsDone=0
- self.stepsTotal=0
- self.featureBuffer=[]
- self.MIdict=[]
- self.MIRdict=[]
-
+ super(UtmGrid, self).__init__()
+ self.scales = [1000, 500, 250, 100, 50, 25, 10, 5, 2, 1]
+ nomen1000 = ["Nao Recorta"]
+ nomen500 = [["V", "X"], ["Y", "Z"]]
+ nomen250 = [["A", "B"], ["C", "D"]]
+ nomen100 = [["I", "II", "III"], ["IV", "V", "VI"]]
+ nomen50 = [["1", "2"], ["3", "4"]]
+ nomen25 = [["NO", "NE"], ["SO", "SE"]]
+ nomen10 = [["A", "B"], ["C", "D"], ["E", "F"]]
+ nomen5 = [["I", "II"], ["III", "IV"]]
+ nomen2 = [["1", "2", "3"], ["4", "5", "6"]]
+ nomen1 = [["A", "B"], ["C", "D"]]
+ self.scaleText = [
+ nomen1000,
+ nomen500,
+ nomen250,
+ nomen100,
+ nomen50,
+ nomen25,
+ nomen10,
+ nomen5,
+ nomen2,
+ nomen1,
+ ]
+ self.matrizRecorte = []
+ self.spacingX = []
+ self.spacingY = []
+ self.stepsDone = 0
+ self.stepsTotal = 0
+ self.featureBuffer = []
+ self.MIdict = []
+ self.MIRdict = []
+
def __del__(self):
"""Destructor."""
pass
-
- def findScaleText(self,scaleText,scaleId):
- """Get the scale matrix for the given scaleText and scaleId
- """
- j=-1
- for j,row in enumerate(self.scaleText[scaleId]):
- if (scaleText in row):
- i=row.index(scaleText)
+
+ def findScaleText(self, scaleText, scaleId):
+ """Get the scale matrix for the given scaleText and scaleId"""
+ j = -1
+ for j, row in enumerate(self.scaleText[scaleId]):
+ if scaleText in row:
+ i = row.index(scaleText)
break
- return (i,len(self.scaleText[scaleId])-j-1)
-
+ return (i, len(self.scaleText[scaleId]) - j - 1)
+
def getScale(self, inomen):
- """Get scale for the given map index
- """
- return self.scales[ self.getScaleIdFromiNomen(inomen) ]
-
+ """Get scale for the given map index"""
+ return self.scales[self.getScaleIdFromiNomen(inomen)]
+
def getScaleIdFromiNomen(self, inomen):
- """Get scale index in self.scales object for the given map index
- """
- id = len(inomen.split('-')) - 2
+ """Get scale index in self.scales object for the given map index"""
+ id = len(inomen.split("-")) - 2
return id
-
+
def getScaleIdFromScale(self, scale):
- """Get scale if for the given scale (e.g. 1, 2, 25, 250)
- """
+ """Get scale if for the given scale (e.g. 1, 2, 25, 250)"""
return self.scales.index(scale)
- def getSpacingX(self,scale):
- """Get X spacing for the given scale
- """
- scaleId=self.scales.index(scale)
- if (scaleId<0): return 0
- if (len(self.spacingX)==0):
- dx=6
- self.spacingX=[dx]
- for i in range(1,len(self.scaleText)):
- subdivisions=len(self.scaleText[i][0])
- dx/=float(subdivisions)
+ def getSpacingX(self, scale):
+ """Get X spacing for the given scale"""
+ scaleId = self.scales.index(scale)
+ if scaleId < 0:
+ return 0
+ if len(self.spacingX) == 0:
+ dx = 6
+ self.spacingX = [dx]
+ for i in range(1, len(self.scaleText)):
+ subdivisions = len(self.scaleText[i][0])
+ dx /= float(subdivisions)
self.spacingX.append(dx)
return self.spacingX[scaleId]
-
- def getSpacingY(self,scale):
- """Get Y spacing for the given scale
- """
- scaleId=self.scales.index(scale)
- if (scaleId<0): return 0
- if (len(self.spacingY)==0):
- dy=4
- self.spacingY=[dy]
- for i in range(1,len(self.scaleText)):
- subdivisions=len(self.scaleText[i])
- dy/=float(subdivisions)
+
+ def getSpacingY(self, scale):
+ """Get Y spacing for the given scale"""
+ scaleId = self.scales.index(scale)
+ if scaleId < 0:
+ return 0
+ if len(self.spacingY) == 0:
+ dy = 4
+ self.spacingY = [dy]
+ for i in range(1, len(self.scaleText)):
+ subdivisions = len(self.scaleText[i])
+ dy /= float(subdivisions)
self.spacingY.append(dy)
return self.spacingY[scaleId]
-
+
def makeQgsPolygon(self, xmin, ymin, xmax, ymax, xSubdivisions=3, ySubdivisions=3):
- """Creating a polygon for the given coordinates
- """
+ """Creating a polygon for the given coordinates"""
polyline = []
- polyline += self.createHorizontalSegment(xmin, xmax, ymin, nSubdivisions=xSubdivisions)
- polyline += self.createVerticalSegment(xmax, ymin, ymax, nSubdivisions=ySubdivisions)
- polyline += self.createHorizontalSegment(xmax, xmin, ymax, nSubdivisions=xSubdivisions)
- polyline += self.createVerticalSegment(xmin, ymax, ymin, nSubdivisions=ySubdivisions)
+ polyline += self.createHorizontalSegment(
+ xmin, xmax, ymin, nSubdivisions=xSubdivisions
+ )
+ polyline += self.createVerticalSegment(
+ xmax, ymin, ymax, nSubdivisions=ySubdivisions
+ )
+ polyline += self.createHorizontalSegment(
+ xmax, xmin, ymax, nSubdivisions=xSubdivisions
+ )
+ polyline += self.createVerticalSegment(
+ xmin, ymax, ymin, nSubdivisions=ySubdivisions
+ )
qgsPolygon = QgsGeometry.fromMultiPolygonXY([[polyline]])
return qgsPolygon
-
+
def createHorizontalSegment(self, xmin, xmax, y, nSubdivisions=3):
- dx = (xmax-xmin)/nSubdivisions
- segment = [
- QgsPointXY(xmin + i*dx, y) for i in range(nSubdivisions)
- ]
- segment.append(QgsPointXY(xmax,y))
+ dx = (xmax - xmin) / nSubdivisions
+ segment = [QgsPointXY(xmin + i * dx, y) for i in range(nSubdivisions)]
+ segment.append(QgsPointXY(xmax, y))
return segment
def createVerticalSegment(self, x, ymin, ymax, nSubdivisions=3):
- dy = (ymax-ymin)/nSubdivisions
- segment = [
- QgsPointXY(x, ymin + i*dy) for i in range(nSubdivisions)
- ]
+ dy = (ymax - ymin) / nSubdivisions
+ segment = [QgsPointXY(x, ymin + i * dy) for i in range(nSubdivisions)]
segment.append(QgsPointXY(x, ymax))
return segment
-
- def getHemisphereMultiplier(self,inomen):
- """Check the hemisphere
- """
- if (len(inomen) > 1):
+
+ def getHemisphereMultiplier(self, inomen):
+ """Check the hemisphere"""
+ if len(inomen) > 1:
h = inomen[0].upper()
- if (h=='S'):
+ if h == "S":
return -1
else:
return 1
- def getLLCornerLatitude1kk(self,inomen):
- """Get lower left Latitude for 1:1.000.000 scale
- """
+ def getLLCornerLatitude1kk(self, inomen):
+ """Get lower left Latitude for 1:1.000.000 scale"""
try:
- l=inomen[1].upper()
+ l = inomen[1].upper()
y = 0.0
- operator=self.getHemisphereMultiplier(inomen)
- verticalPosition=string.ascii_uppercase.index(l)
- y=(y+4*verticalPosition)*operator
- if (operator<0): y-=4
+ operator = self.getHemisphereMultiplier(inomen)
+ verticalPosition = string.ascii_uppercase.index(l)
+ y = (y + 4 * verticalPosition) * operator
+ if operator < 0:
+ y -= 4
except:
- raise Exception(self.tr('Invalid inomen parameter!'))
+ raise Exception(self.tr("Invalid inomen parameter!"))
return y
- def getLLCornerLongitude1kk(self,inomen):
- """Get lower left Longitude for 1:1.000.000 scale
- """
+ def getLLCornerLongitude1kk(self, inomen):
+ """Get lower left Longitude for 1:1.000.000 scale"""
try:
- fuso=int(inomen[3:5])
- x=0
- if((fuso > 0) and (fuso <= 60)):
- x = (((fuso - 30)*6.0)-6.0)
+ fuso = int(inomen[3:5])
+ x = 0
+ if (fuso > 0) and (fuso <= 60):
+ x = ((fuso - 30) * 6.0) - 6.0
return x
except:
- raise Exception(self.tr('Invalid inomen parameter!'))
-
- def getLLCorner(self,inomen):
- """Get lower left coordinates for scale determined by the given map index
- """
+ raise Exception(self.tr("Invalid inomen parameter!"))
+
+ def getLLCorner(self, inomen):
+ """Get lower left coordinates for scale determined by the given map index"""
try:
- x=self.getLLCornerLongitude1kk(inomen)
- y=self.getLLCornerLatitude1kk(inomen)
- inomenParts=inomen.upper().split('-')
- #Escala de 500.00
- for partId in range(2,len(inomenParts)):
- scaleId=partId-1
- dx=self.getSpacingX(self.scales[scaleId])
- dy=self.getSpacingY(self.scales[scaleId])
- scaleText=inomenParts[partId]
- i,j=self.findScaleText(scaleText, partId-1)
- x+=i*dx
- y+=j*dy
- return (x,y)
+ x = self.getLLCornerLongitude1kk(inomen)
+ y = self.getLLCornerLatitude1kk(inomen)
+ inomenParts = inomen.upper().split("-")
+ # Escala de 500.00
+ for partId in range(2, len(inomenParts)):
+ scaleId = partId - 1
+ dx = self.getSpacingX(self.scales[scaleId])
+ dy = self.getSpacingY(self.scales[scaleId])
+ scaleText = inomenParts[partId]
+ i, j = self.findScaleText(scaleText, partId - 1)
+ x += i * dx
+ y += j * dy
+ return (x, y)
except:
- raise Exception(self.tr('Invalid inomen parameter!'))
-
- def computeNumberOfSteps(self,startScaleId,stopScaleId):
- """Compute the number of steps to build a progress
- """
- steps=1
- for i in range(startScaleId+1,stopScaleId+1):
- steps*=len(self.scaleText[i])*len(self.scaleText[i][0])
+ raise Exception(self.tr("Invalid inomen parameter!"))
+
+ def computeNumberOfSteps(self, startScaleId, stopScaleId):
+ """Compute the number of steps to build a progress"""
+ steps = 1
+ for i in range(startScaleId + 1, stopScaleId + 1):
+ steps *= len(self.scaleText[i]) * len(self.scaleText[i][0])
return steps
-
+
def createFrame(self, map_index, layer):
stopScale = self.getScale(map_index)
-
+
# Enter in edit mode
layer.startEditing()
self.populateQgsLayer(map_index, stopScale, layer)
- # Commiting changes
- layer.commitChanges()
-
+ # Commiting changes
+ layer.commitChanges()
+
def createFrame(self, map_index, layer, stopScale):
# Enter in edit mode
layer.startEditing()
self.populateQgsLayer(map_index, stopScale, layer)
- # Commiting changes
+ # Commiting changes
layer.commitChanges()
-
+
def getQgsPolygonFrame(self, map_index, xSubdivisions, ySubdivisions):
"""Particular case used to create frame polygon for the given
map_index
@@ -237,44 +244,45 @@ def getQgsPolygonFrame(self, map_index, xSubdivisions, ySubdivisions):
x + dx,
y + dy,
xSubdivisions=xSubdivisions,
- ySubdivisions=ySubdivisions
+ ySubdivisions=ySubdivisions,
)
return poly
-
+
def populateQgsLayer(self, iNomen, stopScale, layer):
"""Generic recursive method to create frame polygon for the given
stopScale within the given map index (iNomen)
"""
- scale = self.getScale(iNomen)
- #first run
- if (self.stepsTotal==0):
- self.stepsTotal=self.computeNumberOfSteps(self.getScaleIdFromScale(scale), self.getScaleIdFromScale(stopScale))
- self.stepsDone=0
+ scale = self.getScale(iNomen)
+ # first run
+ if self.stepsTotal == 0:
+ self.stepsTotal = self.computeNumberOfSteps(
+ self.getScaleIdFromScale(scale), self.getScaleIdFromScale(stopScale)
+ )
+ self.stepsDone = 0
if scale == stopScale:
(x, y) = self.getLLCorner(iNomen)
dx = self.getSpacingX(stopScale)
dy = self.getSpacingY(stopScale)
poly = self.makeQgsPolygon(x, y, x + dx, y + dy)
-
+
self.insertFrameIntoQgsLayer(layer, poly, iNomen)
-
- self.stepsDone+=1
+
+ self.stepsDone += 1
else:
scaleId = self.getScaleIdFromiNomen(iNomen)
- matrix = self.scaleText[ scaleId+1 ]
-
+ matrix = self.scaleText[scaleId + 1]
+
for i in range(len(matrix)):
line = matrix[i]
for j in range(len(line)):
- inomen2 = iNomen + '-' + line[j]
+ inomen2 = iNomen + "-" + line[j]
self.populateQgsLayer(inomen2, stopScale, layer)
-
+
def insertFrameIntoQgsLayer(self, layer, poly, map_index):
- """Inserts the poly into layer
- """
+ """Inserts the poly into layer"""
provider = layer.dataProvider()
- #Creating the feature
+ # Creating the feature
feature = QgsFeature()
feature.initAttributes(1)
feature.setAttribute(0, map_index)
@@ -282,26 +290,26 @@ def insertFrameIntoQgsLayer(self, layer, poly, map_index):
# Adding the feature into the file
provider.addFeatures([feature])
-
+
def getMIdict(self):
if not self.MIdict:
self.MIdict = self.getDict("MI100.csv")
return self.MIdict
-
+
def getMIRdict(self):
if not self.MIRdict:
self.MIRdict = self.getDict("MIR250.csv")
- return self.MIRdict
-
- def getDict(self, file_name):
- csvFile = open(os.path.join(os.path.dirname(__file__),file_name))
+ return self.MIRdict
+
+ def getDict(self, file_name):
+ csvFile = open(os.path.join(os.path.dirname(__file__), file_name))
data = csvFile.readlines()
csvFile.close()
- l1 = [(x.strip()).split(';') for x in data]
- dicionario = dict((a[1],a[0]) for a in l1)
+ l1 = [(x.strip()).split(";") for x in data]
+ dicionario = dict((a[1], a[0]) for a in l1)
return dicionario
- def getINomenFromMI(self,mi):
+ def getINomenFromMI(self, mi):
mi = self.checkLeftPadding(mi, 4)
inom = self.getINomen(self.getMIdict(), mi)
exceptions = self.getMIexceptions()
@@ -309,49 +317,49 @@ def getINomenFromMI(self,mi):
return None
return inom
- def getINomenFromMIR(self,mir):
+ def getINomenFromMIR(self, mir):
mir = self.checkLeftPadding(mir, 3)
inom = self.getINomen(self.getMIRdict(), mir)
exceptions = self.getMIexceptions()
if inom in exceptions or self.checkContainedUpperLevel(inom, exceptions):
return None
return inom
-
+
def getINomen(self, dict, index):
- key = index.split('-')[0]
- otherParts = index.split('-')[1:]
- if (key in dict):
- if len(otherParts)==0:
+ key = index.split("-")[0]
+ otherParts = index.split("-")[1:]
+ if key in dict:
+ if len(otherParts) == 0:
return dict[key]
else:
- return dict[key]+'-'+'-'.join(otherParts)
+ return dict[key] + "-" + "-".join(otherParts)
else:
return None
-
- def getMIfromInom(self,inom):
- return self.getMI(self.getMIdict(),inom)
-
+
+ def getMIfromInom(self, inom):
+ return self.getMI(self.getMIdict(), inom)
+
def getMI(self, miDict, inom):
- parts = inom.split('-')
- hundredInom = '-'.join(parts[0:5])
+ parts = inom.split("-")
+ hundredInom = "-".join(parts[0:5])
remains = parts[5::]
- for k,v in miDict.items():
+ for k, v in miDict.items():
if v == hundredInom:
- return '-'.join([k]+remains)
-
+ return "-".join([k] + remains)
+
def getMIR(self, miDict, inom):
- parts = inom.split('-')
- hundredInom = '-'.join(parts[0:4])
+ parts = inom.split("-")
+ hundredInom = "-".join(parts[0:4])
remains = parts[4::]
- for k,v in miDict.items():
+ for k, v in miDict.items():
if v == hundredInom:
- return '-'.join([k]+remains)
-
+ return "-".join([k] + remains)
+
def get_MI_MIR_from_inom(self, inom):
exceptions = self.getMIexceptions()
if inom in exceptions or self.checkContainedUpperLevel(inom, exceptions):
return None
- if len(inom.split('-')) > 4:
+ if len(inom.split("-")) > 4:
return self.getMIfromInom(inom)
else:
return self.getMIR(self.getMIRdict(), inom)
@@ -360,14 +368,14 @@ def get_INOM_from_lat_lon(self, lon, lat):
"""
Returns Inom with the nearest lower left lon lat.
"""
- INOM = 'N' if lat >= 0 else 'S'
- INOM += string.ascii_uppercase[math.floor(abs(lat/4.)) % 26] + '-'
- utm_zone = math.floor(31 + lon/6)
- return INOM+str(utm_zone)
-
+ INOM = "N" if lat >= 0 else "S"
+ INOM += string.ascii_uppercase[math.floor(abs(lat / 4.0)) % 26] + "-"
+ utm_zone = math.floor(31 + lon / 6)
+ return INOM + str(utm_zone)
+
def get_INOM_range_from_BB(self, xmin, ymin, xmax, ymax):
"""
- Returns a set of INOM that intersect bbRect formed by
+ Returns a set of INOM that intersect bbRect formed by
xmin, xmax, ymin, ymax
"""
minInom = self.get_INOM_from_lat_lon(xmin, ymin)
@@ -375,46 +383,52 @@ def get_INOM_range_from_BB(self, xmin, ymin, xmax, ymax):
if minInom == maxInom:
return list([minInom])
return self.get_INOM_range_from_min_max_inom(minInom, maxInom)
-
+
def get_INOM_range_from_min_max_inom(self, minInom, maxInom):
- minFuse = int(minInom.split('-')[-1])
- maxFuse = int(maxInom.split('-')[-1])
- fuseRange = map(str, range(minFuse,maxFuse+2,1))
+ minFuse = int(minInom.split("-")[-1])
+ maxFuse = int(maxInom.split("-")[-1])
+ fuseRange = map(str, range(minFuse, maxFuse + 2, 1))
letterRange = self.get_letter_range(minInom, maxInom)
- return list(
- '-'.join(i) for i in itertools.product(letterRange, fuseRange)
- )
+ return list("-".join(i) for i in itertools.product(letterRange, fuseRange))
def get_letter_range(self, minInom, maxInom):
- if minInom[0] == 'S' and maxInom[0] == 'N':
- return self.get_letter_range('SA-XX', minInom) + self.get_letter_range('NA-XX', maxInom)
+ if minInom[0] == "S" and maxInom[0] == "N":
+ return self.get_letter_range("SA-XX", minInom) + self.get_letter_range(
+ "NA-XX", maxInom
+ )
else:
startIndex = string.ascii_uppercase.index(minInom[1])
endIndex = string.ascii_uppercase.index(maxInom[1])
- multiplier = 1 if minInom[0] == 'N' else -1
+ multiplier = 1 if minInom[0] == "N" else -1
return list(
map(
- lambda x: minInom[0]+x,
- string.ascii_uppercase[min(startIndex, endIndex):max(startIndex, endIndex)+3:1]
+ lambda x: minInom[0] + x,
+ string.ascii_uppercase[
+ min(startIndex, endIndex) : max(startIndex, endIndex) + 3 : 1
+ ],
)
)[::multiplier]
-
+
@staticmethod
def getMIexceptions():
- '''
+ """
Returns a set of INOMs that don't have MI
- '''
- pathCsvExceptions25k = os.path.join(os.path.dirname(__file__),'exclusionList25k.csv')
- pathCsvExceptions50k = os.path.join(os.path.dirname(__file__),'exclusionList50k.csv')
- with open(pathCsvExceptions25k, 'r') as file:
+ """
+ pathCsvExceptions25k = os.path.join(
+ os.path.dirname(__file__), "exclusionList25k.csv"
+ )
+ pathCsvExceptions50k = os.path.join(
+ os.path.dirname(__file__), "exclusionList50k.csv"
+ )
+ with open(pathCsvExceptions25k, "r") as file:
exceptions25k = [x[0] for x in csv.reader(file)]
- with open(pathCsvExceptions50k, 'r') as file:
+ with open(pathCsvExceptions50k, "r") as file:
exceptions50k = [x[0] for x in csv.reader(file)]
return set((*exceptions25k, *exceptions50k))
@staticmethod
def checkLeftPadding(mi, zeroes):
- leftPart = mi.split('-')[0]
+ leftPart = mi.split("-")[0]
if len(leftPart) < zeroes:
return f'{"".join("0" for _ in range(zeroes-len(leftPart)))}{mi}'
return mi
@@ -422,13 +436,17 @@ def checkLeftPadding(mi, zeroes):
@staticmethod
def checkContainedUpperLevel(inom, exceptions):
if isinstance(inom, str):
- if '-'.join(inom.split('-')[:-1]) in exceptions:
+ if "-".join(inom.split("-")[:-1]) in exceptions:
return True
+
if __name__ == "__main__":
x = UtmGrid()
- print(x.get_INOM_range_from_min_max_inom('SE-17','NC-22'))
- print(x.get_INOM_range_from_min_max_inom('SC-17','SA-22'))
+ print(x.get_INOM_range_from_min_max_inom("SE-17", "NC-22"))
+ print(x.get_INOM_range_from_min_max_inom("SC-17", "SA-22"))
print(x.get_INOM_range_from_BB(-83, -19, -49, 9))
- print(x.get_INOM_range_from_min_max_inom('SE-17','NC-22') == x.get_INOM_range_from_BB(-83, -19, -49, 9) )
- print(x.get_MI_MIR_from_inom('NB-20-Z-D-I-1'))
+ print(
+ x.get_INOM_range_from_min_max_inom("SE-17", "NC-22")
+ == x.get_INOM_range_from_BB(-83, -19, -49, 9)
+ )
+ print(x.get_MI_MIR_from_inom("NB-20-Z-D-I-1"))
diff --git a/DsgTools/core/Utils/threadingTools.py b/DsgTools/core/Utils/threadingTools.py
new file mode 100644
index 000000000..d60c4c57d
--- /dev/null
+++ b/DsgTools/core/Utils/threadingTools.py
@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+"""
+/***************************************************************************
+ DsgTools
+ A QGIS plugin
+ Brazilian Army Cartographic Production Tools
+ -------------------
+ begin : 2023-04-17
+ git sha : $Format:%H$
+ copyright : (C) 2023 by Philipe Borba - Cartographic Engineer @ Brazilian Army
+ email : borba.philipe@eb.mil.br
+ ***************************************************************************/
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+"""
+
+import itertools
+
+import concurrent.futures
+import itertools
+
+
+def concurrently(handler, inputs, *, max_concurrency=5):
+ """
+ Calls the function ``handler`` on the values ``inputs``.
+
+ ``handler`` should be a function that takes a single input, which is the
+ individual values in the iterable ``inputs``.
+
+ Generates (input, output) tuples as the calls to ``handler`` complete.
+
+ See https://alexwlchan.net/2019/10/adventures-with-concurrent-futures/ for an explanation
+ of how this function works.
+
+ """
+ # Make sure we get a consistent iterator throughout, rather than
+ # getting the first element repeatedly.
+ handler_inputs = iter(inputs)
+
+ with concurrent.futures.ThreadPoolExecutor() as executor:
+ futures = {
+ executor.submit(handler, input): input
+ for input in itertools.islice(handler_inputs, max_concurrency)
+ }
+
+ while futures:
+ done, _ = concurrent.futures.wait(
+ futures, return_when=concurrent.futures.FIRST_COMPLETED
+ )
+
+ for fut in done:
+ original_input = futures.pop(fut)
+ yield fut.result()
+
+ for input in itertools.islice(handler_inputs, len(done)):
+ fut = executor.submit(handler, input)
+ futures[fut] = input
diff --git a/DsgTools/core/Utils/tools.py b/DsgTools/core/Utils/tools.py
index 7504d5904..0ca38893a 100644
--- a/DsgTools/core/Utils/tools.py
+++ b/DsgTools/core/Utils/tools.py
@@ -24,7 +24,7 @@
"""
Module designed to centralize the access to DSGTools tools.
This module CANNOT be imported at the beginning of modules and must be called
-from within methods that are NOT the __init__!
+from within methods that are NOT the __init__!
"""
from DsgTools import dsgTools
@@ -33,6 +33,7 @@
toolBoxManager = dsgTools.guiManager.productionToolsGuiManager.toolBoxesGuiManager
toolBarManager = dsgTools.guiManager.productionToolsGuiManager.toolbarsGuiManager
+
def mapToolsNames():
"""
Lists all non-i18n names for DSGTools map tools.
@@ -45,9 +46,10 @@ def mapToolsNames():
"freeHandAcquisiton",
"freeHandReshape",
"labelTool",
- "shortcutsTool"
+ "shortcutsTool",
]
+
def mapTools():
"""
Lists all available map tools provided by DSGTools plugin.
@@ -55,6 +57,7 @@ def mapTools():
"""
return [getattr(mapToolManager, tn) for tn in mapToolsNames()]
+
def mapTool(name):
"""
Provides the map tool from DSGTools plugin through its non-i18n name.
@@ -63,6 +66,7 @@ def mapTool(name):
"""
return getattr(mapToolManager, name)
+
def toolBarsNames():
"""
Lists all non-i18n names for DSGTools tool bars.
@@ -73,9 +77,10 @@ def toolBarsNames():
"inspectFeaturesTool",
"styleManagerTool",
"rasterInfoTool",
- "dataValidationTool"
+ "dataValidationTool",
]
+
def toolBars():
"""
Lists all available tool bars provided by DSGTools plugin.
@@ -83,6 +88,7 @@ def toolBars():
"""
return [getattr(toolBarManager, tn) for tn in toolBarsNames()]
+
def toolBar(name):
"""
Provides the tool bar from DSGTools plugin through its non-i18n name.
@@ -91,18 +97,14 @@ def toolBar(name):
"""
return getattr(toolBarManager, name)
+
def toolBoxesNames():
"""
Lists all non-i18n names for DSGTools tool boxes.
:return: (list-of-str) list of non-i18n of all available tool boxes.
"""
- return [
- "qaToolBox",
- "cfToolbox",
- "calcContour",
- "codeList",
- "complexWindow"
- ]
+ return ["qaToolBox", "cfToolbox", "calcContour", "codeList", "complexWindow"]
+
def toolBoxes():
"""
@@ -111,6 +113,7 @@ def toolBoxes():
"""
return [getattr(toolBoxManager, tn) for tn in toolBoxesNames()]
+
def toolBox(name):
"""
Provides the tool bar from DSGTools plugin through its non-i18n name.
@@ -119,6 +122,7 @@ def toolBox(name):
"""
return getattr(toolBoxManager, name)
+
def toolsNames():
"""
Lists all non-i18n names for DSGTools tools.
@@ -126,6 +130,7 @@ def toolsNames():
"""
return mapToolsNames() + toolBarsNames() + toolBoxesNames()
+
def tools():
"""
List of all available DSGTools tools.
@@ -133,6 +138,7 @@ def tools():
"""
return mapTools() + toolBars() + toolBoxes()
+
def toolByName(name):
"""
Retrieve any of DSGTools its name.
@@ -146,6 +152,7 @@ def toolByName(name):
else:
return toolBox(name)
+
def actions():
"""
Retrieves all registered action on GuiManager.
diff --git a/DsgTools/core/Utils/utils.py b/DsgTools/core/Utils/utils.py
index 8b2ae31ed..30b24df67 100644
--- a/DsgTools/core/Utils/utils.py
+++ b/DsgTools/core/Utils/utils.py
@@ -36,7 +36,6 @@
class Utils(object):
-
def mergeDict(self, dictionary1, dictionary2):
"""
Merges two dictionaries
@@ -55,11 +54,11 @@ def mergeDict(self, dictionary1, dictionary2):
for i in value:
if i not in output[item]:
output[item].append(i)
- output[item].extend(self.mergeDict(
- value, dictionary2.pop(item)))
+ output[item].extend(
+ self.mergeDict(value, dictionary2.pop(item))
+ )
else:
- output[item] = self.mergeDict(
- value, dictionary2.pop(item))
+ output[item] = self.mergeDict(value, dictionary2.pop(item))
else:
if type(value) == list:
if item not in list(output.keys()):
@@ -100,7 +99,8 @@ def buildOneNestedDict(self, inputDict, keyList, value):
if len(list(inputDict.values())) == 0:
inputDict[keyList[0]] = dict()
inputDict[keyList[0]] = self.buildOneNestedDict(
- inputDict[keyList[0]], keyList[1::], value)
+ inputDict[keyList[0]], keyList[1::], value
+ )
return inputDict
def buildNestedDict(self, inputDict, keyList, value):
@@ -118,7 +118,7 @@ def readJsonFile(self, filename, returnFileAndDict=False):
Reads a json file and makes a dictionary
"""
try:
- file = open(filename, 'r')
+ file = open(filename, "r")
data = file.read()
fileDict = json.loads(data)
file.close()
@@ -131,19 +131,19 @@ def readJsonFile(self, filename, returnFileAndDict=False):
def parseStyle(self, qml):
qml = qml.replace("''", "'")
- if '.qml' in qml:
+ if ".qml" in qml:
doc = parse(qml)
else:
try:
doc = parseString(qml)
except:
- doc = parseString(qml.encode('utf-8'))
- forbiddenList = doc.getElementsByTagName('edittypes')
+ doc = parseString(qml.encode("utf-8"))
+ forbiddenList = doc.getElementsByTagName("edittypes")
if len(forbiddenList) > 0:
forbiddenNode = forbiddenList[0]
- qgisNode = doc.getElementsByTagName('qgis')[0]
+ qgisNode = doc.getElementsByTagName("qgis")[0]
qgisNode.removeChild(forbiddenNode)
- return doc.toxml().replace('', '')
+ return doc.toxml().replace('', "")
def parseMultiQml(self, qmlPath, lyrList):
"""
@@ -152,14 +152,18 @@ def parseMultiQml(self, qmlPath, lyrList):
refDict = dict()
for lyr in lyrList:
try:
- qml = os.path.join(qmlPath, lyr + '.qml')
+ qml = os.path.join(qmlPath, lyr + ".qml")
doc = parse(qml)
refDict[lyr] = dict()
- for node in doc.getElementsByTagName('edittype'):
- if node.getAttribute('widgetv2type') in ('ValueMap', 'ValueRelation'):
- attrName = node.getAttribute('name')
+ for node in doc.getElementsByTagName("edittype"):
+ if node.getAttribute("widgetv2type") in (
+ "ValueMap",
+ "ValueRelation",
+ ):
+ attrName = node.getAttribute("name")
refDict[lyr][attrName] = node.getElementsByTagName(
- 'widgetv2config')[0].getAttribute('Layer')
+ "widgetv2config"
+ )[0].getAttribute("Layer")
except:
pass
return refDict
@@ -175,13 +179,14 @@ def parseMultiFromDb(self, qmlRecordDict, lyrList):
try:
doc = parseString(qml)
except:
- doc = parseString(qml.encode('utf-8'))
+ doc = parseString(qml.encode("utf-8"))
refDict[lyr] = dict()
- for node in doc.getElementsByTagName('edittype'):
- if node.getAttribute('widgetv2type') == 'ValueRelation':
- attrName = node.getAttribute('name')
+ for node in doc.getElementsByTagName("edittype"):
+ if node.getAttribute("widgetv2type") == "ValueRelation":
+ attrName = node.getAttribute("name")
refDict[lyr][attrName] = node.getElementsByTagName(
- 'widgetv2config')[0].getAttribute('Layer')
+ "widgetv2config"
+ )[0].getAttribute("Layer")
except:
pass
return refDict
@@ -198,8 +203,7 @@ def getRecursiveInheritanceTreeDict(self, parent, resultDict, inhDict):
resultDict[parent] = dict()
if parent in list(inhDict.keys()):
for child in inhDict[parent]:
- self.getRecursiveInheritanceTreeDict(
- child, resultDict[parent], inhDict)
+ self.getRecursiveInheritanceTreeDict(child, resultDict[parent], inhDict)
def find_all_paths(self, graph, start, end, path=[]):
path = path + [start]
@@ -235,21 +239,20 @@ def createWidgetItem(self, parent, text, column=None):
def createTreeWidgetFromDict(self, parentNode, inputDict, treeWidget, column):
for key in list(inputDict.keys()):
item = self.createWidgetItem(parentNode, key, column)
- self.createTreeWidgetFromDict(
- item, inputDict[key], treeWidget, column)
+ self.createTreeWidgetFromDict(item, inputDict[key], treeWidget, column)
def getTreeBranchFromNode(self, startNode, inputDict):
- if 'root' not in list(inputDict.keys()):
- graph = {'root': inputDict}
+ if "root" not in list(inputDict.keys()):
+ graph = {"root": inputDict}
else:
graph = inputDict
- path = self.find_all_paths(graph, 'root', startNode)[0]
+ path = self.find_all_paths(graph, "root", startNode)[0]
for node in path:
graph = graph[node]
return {startNode: graph}
def getNodeLineage(self, node, inputDict):
- return self.find_all_paths(inputDict, 'root', node)[0][1::]
+ return self.find_all_paths(inputDict, "root", node)[0][1::]
def instantiateJsonDict(self, jsonDict):
if isinstance(jsonDict, dict):
@@ -262,7 +265,7 @@ def deleteQml(self, tempQml):
Deletes a file from a given dir, if it's a QML file.
"""
try:
- if tempQml[-4:].lower() == '.qml':
+ if tempQml[-4:].lower() == ".qml":
try:
os.remove(tempQml)
except:
@@ -274,7 +277,7 @@ def deleteQml(self, tempQml):
return False
def get_proxy_config(self):
- """ Get proxy config from QSettings and builds proxy parameters
+ """Get proxy config from QSettings and builds proxy parameters
:return: dictionary of transfer protocols mapped to addresses, also authentication if set in QSettings
:rtype: (dict, requests.auth.HTTPProxyAuth) or (dict, None)
"""
@@ -282,31 +285,34 @@ def get_proxy_config(self):
proxy_dict = {}
if enabled and host:
- port_str = str(port) if port else ''
- for protocol in ['http', 'https', 'ftp']:
- proxy_dict[protocol] = '{}://{}:{}'.format(
- protocol, host, port_str)
+ port_str = str(port) if port else ""
+ for protocol in ["http", "https", "ftp"]:
+ proxy_dict[protocol] = "{}://{}:{}".format(protocol, host, port_str)
- auth = requests.auth.HTTPProxyAuth(
- user, password) if enabled and user and password else None
+ auth = (
+ requests.auth.HTTPProxyAuth(user, password)
+ if enabled and user and password
+ else None
+ )
return proxy_dict, auth
@staticmethod
def get_proxy_from_qsettings():
- """ Gets the proxy configuration from QSettings
+ """Gets the proxy configuration from QSettings
:return: Proxy settings: flag specifying if proxy is enabled, host, port, user and password
:rtype: tuple(str)
"""
settings = QSettings()
- settings.beginGroup('proxy')
- enabled = str(settings.value('proxyEnabled')).lower(
- ) == 'true' # to be compatible with QGIS 2 and 3
+ settings.beginGroup("proxy")
+ enabled = (
+ str(settings.value("proxyEnabled")).lower() == "true"
+ ) # to be compatible with QGIS 2 and 3
# proxy_type = settings.value("proxyType")
- host = settings.value('proxyHost')
- port = settings.value('proxyPort')
- user = settings.value('proxyUser')
- password = settings.value('proxyPassword')
+ host = settings.value("proxyHost")
+ port = settings.value("proxyPort")
+ user = settings.value("proxyUser")
+ password = settings.value("proxyPassword")
settings.endGroup()
return enabled, host, port, user, password
@@ -375,11 +381,7 @@ def fieldIsInt(self, field):
:param field: (QgsField) field to be checked.
:return: (bool) if data is a whole number.
"""
- intTypes = [
- QVariant.Int,
- QVariant.UInt,
- QVariant.LongLong,
- QVariant.ULongLong]
+ intTypes = [QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong]
return field.type() in intTypes
def fieldIsNumeric(self, field):
@@ -419,8 +421,7 @@ def raiseIfaceMessage(self, title, msg, level=None, duration=None):
"""
level = Qgis.Info if level is None else level
duration = 3 if duration is None else duration
- iface.messageBar().pushMessage(
- title, msg, level=level, duration=duration)
+ iface.messageBar().pushMessage(title, msg, level=level, duration=duration)
def logMessage(self, msg, level=None):
"""
@@ -429,7 +430,7 @@ def logMessage(self, msg, level=None):
:param level: (int) level code (warning, critical, etc).
"""
level = Qgis.Info if level is None else level
- QgsMessageLog.logMessage(msg, 'DSGTools Plugin', level)
+ QgsMessageLog.logMessage(msg, "DSGTools Plugin", level)
def confirmAction(self, parent, msg, title=None, showNo=True):
"""
@@ -441,15 +442,20 @@ def confirmAction(self, parent, msg, title=None, showNo=True):
"""
title = title or self.tr("Confirm action")
if showNo:
- return QMessageBox.question(
- parent, title, msg, QMessageBox.Yes | QMessageBox.No
- ) == QMessageBox.Yes
+ return (
+ QMessageBox.question(
+ parent, title, msg, QMessageBox.Yes | QMessageBox.No
+ )
+ == QMessageBox.Yes
+ )
else:
- return QMessageBox.question(
- parent, title, msg, QMessageBox.Ok) == QMessageBox.Ok
+ return (
+ QMessageBox.question(parent, title, msg, QMessageBox.Ok)
+ == QMessageBox.Ok
+ )
-class ValidateImportedDataMethods():
+class ValidateImportedDataMethods:
"""
Docstring.
"""
@@ -462,7 +468,7 @@ def validateQColor(self, colorToEvaluate):
This method receives a string and evaluate if its an valid QColor.
"""
- colorStrWithoutSpaces = re.sub(r'\s', '', str(colorToEvaluate))
+ colorStrWithoutSpaces = re.sub(r"\s", "", str(colorToEvaluate))
hexColor = re.search(r"^#[0-9a-fA-F]{3,6}$", colorStrWithoutSpaces)
listColor = re.search(r"\d{1,3},\d{1,3},\d{1,3}", colorStrWithoutSpaces)
@@ -472,7 +478,7 @@ def validateQColor(self, colorToEvaluate):
return True
elif listColor is not None:
color = listColor[0].split(",")
- rgb = QColor(int(color[0]),int(color[1]),int(color[2]))
+ rgb = QColor(int(color[0]), int(color[1]), int(color[2]))
if rgb.isValid():
return True
return False
@@ -518,13 +524,16 @@ def showLoadingMsg(self, lyrList=None, msgType=None):
if lyrList and msgType == "invalid":
msg.setIcon(QMessageBox.Critical)
msg.setText("Some rules has invalid itens!")
- msg.setInformativeText("If you ignore, the invalid rules may not be loaded.")
+ msg.setInformativeText(
+ "If you ignore, the invalid rules may not be loaded."
+ )
textLyrList = sorted(set(lyrList))
formatedLyrList = ["{}" for item in textLyrList]
msgString = ",".join(formatedLyrList).replace(",", "\n")
- formatedMsgString = "The following rules are not valid:\n" + \
- msgString.format(*textLyrList)
+ formatedMsgString = (
+ "The following rules are not valid:\n" + msgString.format(*textLyrList)
+ )
msg.setDetailedText(formatedMsgString)
msg.setStandardButtons(QMessageBox.Ignore | QMessageBox.Cancel)
diff --git a/DsgTools/core/dsgEnums.py b/DsgTools/core/dsgEnums.py
index 1d5542c51..959260815 100644
--- a/DsgTools/core/dsgEnums.py
+++ b/DsgTools/core/dsgEnums.py
@@ -22,18 +22,56 @@
"""
from builtins import range
from builtins import object
+
+
class DsgEnums(object):
- #generic manager and database enumerate
+ # generic manager and database enumerate
Property, Database = list(range(2))
- #generic validation property
+ # generic validation property
ProcessName, ClassName = list(range(2))
- #property enum
- PermissionProperty, FieldToolboxProperty, EarthCoverageProperty, AttributeRuleProperty, SpatialRuleProperty, ValidationWorkflowProperty = list(range(6))
+ # property enum
+ (
+ PermissionProperty,
+ FieldToolboxProperty,
+ EarthCoverageProperty,
+ AttributeRuleProperty,
+ SpatialRuleProperty,
+ ValidationWorkflowProperty,
+ ) = list(range(6))
# datasource selection widgets enum
- NoDriver, PostGIS, NewPostGIS, SpatiaLite, NewSpatiaLite, Shapefile, NewShapefile, Geopackage, NewGeopackage = list(range(9))
+ (
+ NoDriver,
+ PostGIS,
+ NewPostGIS,
+ SpatiaLite,
+ NewSpatiaLite,
+ Shapefile,
+ NewShapefile,
+ Geopackage,
+ NewGeopackage,
+ ) = list(range(9))
# node types enum
- Flag, Sink, WaterwayBegin, UpHillNode, DownHillNode, Confluence, Ramification, AttributeChange, NodeNextToWaterBody, AttributeChangeFlag, NodeOverload, DisconnectedLine = list(range(12))
+ (
+ Flag,
+ Sink,
+ WaterwayBegin,
+ UpHillNode,
+ DownHillNode,
+ Confluence,
+ Ramification,
+ AttributeChange,
+ NodeNextToWaterBody,
+ AttributeChangeFlag,
+ NodeOverload,
+ DisconnectedLine,
+ ) = list(range(12))
# available drivers enum
- DriverPostGIS, DriverSpatiaLite, DriverGeopackage, DriverShapefile, DriverOthers = list(range(5))
+ (
+ DriverPostGIS,
+ DriverSpatiaLite,
+ DriverGeopackage,
+ DriverShapefile,
+ DriverOthers,
+ ) = list(range(5))
# conversion modes available in Conversion Dataset Tool
FlexibleConversion, StrictConversion = 1, 2
diff --git a/DsgTools/dsg_tools.py b/DsgTools/dsg_tools.py
index a1c1e3ea4..0bafa1906 100644
--- a/DsgTools/dsg_tools.py
+++ b/DsgTools/dsg_tools.py
@@ -39,9 +39,12 @@
from qgis.core import QgsApplication
from .gui.guiManager import GuiManager
-from .core.DSGToolsProcessingAlgs.dsgtoolsProcessingAlgorithmProvider import DSGToolsProcessingAlgorithmProvider
+from .core.DSGToolsProcessingAlgs.dsgtoolsProcessingAlgorithmProvider import (
+ DSGToolsProcessingAlgorithmProvider,
+)
from .Modules.acquisitionMenu.controllers.acquisitionMenuCtrl import AcquisitionMenuCtrl
+
class DsgTools(object):
"""QGIS Plugin Implementation."""
@@ -56,25 +59,24 @@ def __init__(self, iface):
# initialize plugin directory
self.plugin_dir = os.path.dirname(__file__)
# initialize locale
- locale = QSettings().value('locale/userLocale')[0:2]
+ locale = QSettings().value("locale/userLocale")[0:2]
locale_path = os.path.join(
- self.plugin_dir,
- 'i18n',
- 'DsgTools_{}.qm'.format(locale))
+ self.plugin_dir, "i18n", "DsgTools_{}.qm".format(locale)
+ )
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
- if qVersion() > '4.3.3':
+ if qVersion() > "4.3.3":
QCoreApplication.installTranslator(self.translator)
# Create the dialog (after translation) and keep reference
# Declare instance attributes
self.actions = []
- self.menu = '&DSGTools'
- self.toolbar = self.iface.addToolBar(u'DsgTools')
- self.toolbar.setObjectName(u'DsgTools')
+ self.menu = "&DSGTools"
+ self.toolbar = self.iface.addToolBar("DsgTools")
+ self.toolbar.setObjectName("DsgTools")
self.dsgTools = None
self.menuBar = self.iface.mainWindow().menuBar()
@@ -90,7 +92,7 @@ def tr(self, message):
:rtype: QString
"""
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
- return QCoreApplication.translate('DsgTools', message)
+ return QCoreApplication.translate("DsgTools", message)
def unload(self):
"""
@@ -98,9 +100,7 @@ def unload(self):
"""
self.guiManager.unload()
for action in self.actions:
- self.iface.removePluginMenu(
- '&DSGTools',
- action)
+ self.iface.removePluginMenu("&DSGTools", action)
self.iface.removeToolBarIcon(action)
self.iface.unregisterMainWindowAction(action)
@@ -117,14 +117,18 @@ def initGui(self):
"""
self.dsgTools = QMenu(self.iface.mainWindow())
- self.dsgTools.setObjectName(u'DsgTools')
- self.dsgTools.setTitle(u'DSGTools')
- self.menuBar.insertMenu(self.iface.firstRightStandardMenu().menuAction(), self.dsgTools)
- #GuiManager
- self.guiManager = GuiManager(self.iface, parentMenu = self.dsgTools, toolbar = self.toolbar)
+ self.dsgTools.setObjectName("DsgTools")
+ self.dsgTools.setTitle("DSGTools")
+ self.menuBar.insertMenu(
+ self.iface.firstRightStandardMenu().menuAction(), self.dsgTools
+ )
+ # GuiManager
+ self.guiManager = GuiManager(
+ self.iface, parentMenu=self.dsgTools, toolbar=self.toolbar
+ )
self.guiManager.initGui()
- #provider
+ # provider
QgsApplication.processingRegistry().addProvider(self.provider)
def getAcquisitionMenu(self):
- return AcquisitionMenuCtrl()
\ No newline at end of file
+ return AcquisitionMenuCtrl()
diff --git a/DsgTools/gui/AboutAndFurtherInfo/Options/options.py b/DsgTools/gui/AboutAndFurtherInfo/Options/options.py
index e6bdb9e9b..983c63352 100644
--- a/DsgTools/gui/AboutAndFurtherInfo/Options/options.py
+++ b/DsgTools/gui/AboutAndFurtherInfo/Options/options.py
@@ -23,8 +23,13 @@
from builtins import range
import os
from os.path import expanduser
-from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import PalavrasFileConfig, WordDatasetPtBRFileConfig
-from DsgTools.core.NetworkTools.ExternalFilesHandler import ExternalFileDownloadProcessor
+from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import (
+ PalavrasFileConfig,
+ WordDatasetPtBRFileConfig,
+)
+from DsgTools.core.NetworkTools.ExternalFilesHandler import (
+ ExternalFileDownloadProcessor,
+)
from processing.modeler.ModelerUtils import ModelerUtils
from qgis.PyQt import uic
@@ -33,19 +38,21 @@
from qgis.utils import iface
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'options.ui'))
+FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "options.ui"))
+
class Options(QDialog, FORM_CLASS):
- __dsgToolsModelPath__ = os.path.abspath(os.path.join(
- os.path.dirname(__file__), "..", "..", "..", "core", "Misc", "QGIS_Models"
- ))
+ __dsgToolsModelPath__ = os.path.abspath(
+ os.path.join(
+ os.path.dirname(__file__), "..", "..", "..", "core", "Misc", "QGIS_Models"
+ )
+ )
__qgisModelPath__ = ModelerUtils.modelsFolders()[0]
# # some options signals
# modelPathChanged = pyqtSignal()
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""Constructor."""
super(Options, self).__init__(parent)
self.setupUi(self)
@@ -57,17 +64,24 @@ def __init__(self, parent = None):
@pyqtSlot(bool)
def on_addPushButton_clicked(self):
newValue = self.addParameterLineEdit.text()
- valueList = [self.blackListWidget.itemAt(i,0).text() for i in range(self.blackListWidget.count())]
- if newValue == '':
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Fill in a value before adding!'))
+ valueList = [
+ self.blackListWidget.itemAt(i, 0).text()
+ for i in range(self.blackListWidget.count())
+ ]
+ if newValue == "":
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Fill in a value before adding!")
+ )
return
if newValue in valueList:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Value already in black list!'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Value already in black list!")
+ )
return
self.blackListWidget.addItem(newValue)
self.blackListWidget.sortItems(order=Qt.AscendingOrder)
- self.addParameterLineEdit.setText('')
-
+ self.addParameterLineEdit.setText("")
+
def getParameters(self):
freeHandTolerance = self.toleranceQgsDoubleSpinBox.value()
freeHandSmoothIterations = self.smoothIterationsQgsSpinBox.value()
@@ -75,32 +89,70 @@ def getParameters(self):
algIterations = self.algIterationsQgsSpinBox.value()
minSegmentDistance = self.minSegmentDistanceQgsSpinBox.value()
rightAngleDecimals = self.rightAngleDecimalsQgsSpinBox.value()
- valueList = [self.blackListWidget.item(i).text() for i in range(self.blackListWidget.count())]
+ valueList = [
+ self.blackListWidget.item(i).text()
+ for i in range(self.blackListWidget.count())
+ ]
undoPoints = self.undoQgsSpinBox.value()
decimals = self.decimalQgsSpinBox.value()
freeHandFinalSimplifyTolerance = self.finalToleranceQgsDoubleSpinBox.value()
- return (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance)
+ return (
+ freeHandTolerance,
+ freeHandSmoothIterations,
+ freeHandSmoothOffset,
+ algIterations,
+ minSegmentDistance,
+ rightAngleDecimals,
+ valueList,
+ undoPoints,
+ decimals,
+ freeHandFinalSimplifyTolerance,
+ )
def loadParametersFromConfig(self):
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- freeHandTolerance = settings.value('freeHandTolerance')
- freeHandSmoothIterations = settings.value('freeHandSmoothIterations')
- freeHandSmoothOffset = settings.value('freeHandSmoothOffset')
- algIterations = settings.value('algIterations')
- minSegmentDistance = settings.value('minSegmentDistance')
- rightAngleDecimals = settings.value('rightAngleDecimals')
- valueList = settings.value('valueList')
- undoPoints = settings.value('undoPoints')
- decimals = settings.value('decimals')
- freeHandFinalSimplifyTolerance = settings.value('freeHandFinalSimplifyTolerance')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ freeHandTolerance = settings.value("freeHandTolerance")
+ freeHandSmoothIterations = settings.value("freeHandSmoothIterations")
+ freeHandSmoothOffset = settings.value("freeHandSmoothOffset")
+ algIterations = settings.value("algIterations")
+ minSegmentDistance = settings.value("minSegmentDistance")
+ rightAngleDecimals = settings.value("rightAngleDecimals")
+ valueList = settings.value("valueList")
+ undoPoints = settings.value("undoPoints")
+ decimals = settings.value("decimals")
+ freeHandFinalSimplifyTolerance = settings.value(
+ "freeHandFinalSimplifyTolerance"
+ )
if valueList:
- valueList = valueList.split(';')
+ valueList = valueList.split(";")
settings.endGroup()
- return (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance)
-
+ return (
+ freeHandTolerance,
+ freeHandSmoothIterations,
+ freeHandSmoothOffset,
+ algIterations,
+ minSegmentDistance,
+ rightAngleDecimals,
+ valueList,
+ undoPoints,
+ decimals,
+ freeHandFinalSimplifyTolerance,
+ )
+
def setInterfaceWithParametersFromConfig(self):
- (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) = self.loadParametersFromConfig()
+ (
+ freeHandTolerance,
+ freeHandSmoothIterations,
+ freeHandSmoothOffset,
+ algIterations,
+ minSegmentDistance,
+ rightAngleDecimals,
+ valueList,
+ undoPoints,
+ decimals,
+ freeHandFinalSimplifyTolerance,
+ ) = self.loadParametersFromConfig()
if freeHandTolerance:
self.toleranceQgsDoubleSpinBox.setValue(float(freeHandTolerance))
if freeHandSmoothIterations:
@@ -116,36 +168,51 @@ def setInterfaceWithParametersFromConfig(self):
if valueList:
self.blackListWidget.clear()
self.blackListWidget.addItems(valueList)
- self.blackListWidget.sortItems(order = Qt.AscendingOrder)
+ self.blackListWidget.sortItems(order=Qt.AscendingOrder)
if undoPoints:
self.undoQgsSpinBox.setValue(int(undoPoints))
if decimals:
self.decimalQgsSpinBox.setValue(int(decimals))
if freeHandFinalSimplifyTolerance:
- self.finalToleranceQgsDoubleSpinBox.setValue(float(freeHandFinalSimplifyTolerance))
-
+ self.finalToleranceQgsDoubleSpinBox.setValue(
+ float(freeHandFinalSimplifyTolerance)
+ )
+
def storeParametersInConfig(self):
- (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) = self.getParameters()
+ (
+ freeHandTolerance,
+ freeHandSmoothIterations,
+ freeHandSmoothOffset,
+ algIterations,
+ minSegmentDistance,
+ rightAngleDecimals,
+ valueList,
+ undoPoints,
+ decimals,
+ freeHandFinalSimplifyTolerance,
+ ) = self.getParameters()
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- settings.setValue('freeHandTolerance', freeHandTolerance)
- settings.setValue('freeHandSmoothIterations', freeHandSmoothIterations)
- settings.setValue('freeHandSmoothOffset', freeHandSmoothOffset)
- settings.setValue('algIterations', algIterations)
- settings.setValue('minSegmentDistance', minSegmentDistance)
- settings.setValue('rightAngleDecimals', rightAngleDecimals)
- settings.setValue('valueList', ';'.join(valueList))
- settings.setValue('undoPoints', undoPoints)
- settings.setValue('decimals', decimals)
- settings.setValue('freeHandFinalSimplifyTolerance', freeHandFinalSimplifyTolerance)
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ settings.setValue("freeHandTolerance", freeHandTolerance)
+ settings.setValue("freeHandSmoothIterations", freeHandSmoothIterations)
+ settings.setValue("freeHandSmoothOffset", freeHandSmoothOffset)
+ settings.setValue("algIterations", algIterations)
+ settings.setValue("minSegmentDistance", minSegmentDistance)
+ settings.setValue("rightAngleDecimals", rightAngleDecimals)
+ settings.setValue("valueList", ";".join(valueList))
+ settings.setValue("undoPoints", undoPoints)
+ settings.setValue("decimals", decimals)
+ settings.setValue(
+ "freeHandFinalSimplifyTolerance", freeHandFinalSimplifyTolerance
+ )
settings.endGroup()
-
+
@pyqtSlot()
def on_buttonBox_accepted(self):
self.storeParametersInConfig()
self.updateValidationToolbarConfig()
self.close()
-
+
@pyqtSlot(bool)
def on_removePushButton_clicked(self):
selectedItems = self.blackListWidget.selectedItems()
@@ -156,10 +223,30 @@ def on_removePushButton_clicked(self):
idxList.sort(reverse=True)
for i in idxList:
self.blackListWidget.takeItem(i)
-
+
def firstTimeConfig(self):
- (freeHandTolerance, freeHandSmoothIterations, freeHandSmoothOffset, algIterations, minSegmentDistance, rightAngleDecimals, valueList, undoPoints, decimals, freeHandFinalSimplifyTolerance) = self.loadParametersFromConfig()
- if not (freeHandTolerance and freeHandSmoothIterations and freeHandSmoothOffset and algIterations and valueList and undoPoints and decimals is not None and freeHandFinalSimplifyTolerance is not None):
+ (
+ freeHandTolerance,
+ freeHandSmoothIterations,
+ freeHandSmoothOffset,
+ algIterations,
+ minSegmentDistance,
+ rightAngleDecimals,
+ valueList,
+ undoPoints,
+ decimals,
+ freeHandFinalSimplifyTolerance,
+ ) = self.loadParametersFromConfig()
+ if not (
+ freeHandTolerance
+ and freeHandSmoothIterations
+ and freeHandSmoothOffset
+ and algIterations
+ and valueList
+ and undoPoints
+ and decimals is not None
+ and freeHandFinalSimplifyTolerance is not None
+ ):
self.storeParametersInConfig()
def setupModelPath(self):
@@ -167,10 +254,9 @@ def setupModelPath(self):
Clears all model paths and leaves the default options.
"""
self.modelPathComboBox.clear()
- self.modelPathComboBox.addItems([
- self.__dsgToolsModelPath__,
- self.__qgisModelPath__
- ])
+ self.modelPathComboBox.addItems(
+ [self.__dsgToolsModelPath__, self.__qgisModelPath__]
+ )
def setupValidationToolbarConfig(self):
"""
@@ -179,26 +265,34 @@ def setupValidationToolbarConfig(self):
# reset combo box to default as well
self.setupModelPath()
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- if settings.value('loadModelOutput') is None:
- settings.setValue('loadModelOutput', True)
- self.loadModelOutputCheckBox.setChecked(settings.value('loadModelOutput') in (True, "true"))
- if settings.value('checkBeforeRunModel') is None:
- settings.setValue('checkBeforeRunModel', True)
- self.checkBeforeRunModelCheckBox.setChecked(settings.value('checkBeforeRunModel') in (True, "true"))
- if settings.value('removeModelsOnExit') is None:
- settings.setValue('', False)
- self.resetModelsCheckBox.setChecked(settings.value('removeModelsOnExit') in (True, "true"))
- if settings.value('removeModelsOnNewProject') is None:
- settings.setValue('removeModelsOnNewProject', False)
- self.removeModelsProjectCheckBox.setChecked(settings.value('removeModelsOnNewProject') in (True, "true"))
- if settings.value('defaultModelPath') is None:
- settings.setValue('defaultModelPath', self.modelPathComboBox.currentText())
- idx = self.modelPathComboBox.findText(settings.value('defaultModelPath'))
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ if settings.value("loadModelOutput") is None:
+ settings.setValue("loadModelOutput", True)
+ self.loadModelOutputCheckBox.setChecked(
+ settings.value("loadModelOutput") in (True, "true")
+ )
+ if settings.value("checkBeforeRunModel") is None:
+ settings.setValue("checkBeforeRunModel", True)
+ self.checkBeforeRunModelCheckBox.setChecked(
+ settings.value("checkBeforeRunModel") in (True, "true")
+ )
+ if settings.value("removeModelsOnExit") is None:
+ settings.setValue("", False)
+ self.resetModelsCheckBox.setChecked(
+ settings.value("removeModelsOnExit") in (True, "true")
+ )
+ if settings.value("removeModelsOnNewProject") is None:
+ settings.setValue("removeModelsOnNewProject", False)
+ self.removeModelsProjectCheckBox.setChecked(
+ settings.value("removeModelsOnNewProject") in (True, "true")
+ )
+ if settings.value("defaultModelPath") is None:
+ settings.setValue("defaultModelPath", self.modelPathComboBox.currentText())
+ idx = self.modelPathComboBox.findText(settings.value("defaultModelPath"))
if idx < 0:
- self.modelPathComboBox.addItem(settings.value('defaultModelPath'))
- self.modelPathComboBox.setCurrentText(settings.value('defaultModelPath'))
- settings.endGroup()
+ self.modelPathComboBox.addItem(settings.value("defaultModelPath"))
+ self.modelPathComboBox.setCurrentText(settings.value("defaultModelPath"))
+ settings.endGroup()
def validationToolbarConfig(self):
"""
@@ -206,19 +300,19 @@ def validationToolbarConfig(self):
:return: (dict) set of parameters for Validation Toolbar.
"""
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- loadModelOutput = settings.value('loadModelOutput')
- checkBeforeRunModel = settings.value('checkBeforeRunModel')
- removeModelsOnExit = settings.value('removeModelsOnExit')
- removeModelsOnNewProject = settings.value('removeModelsOnNewProject')
- defaultModelPath = settings.value('defaultModelPath')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ loadModelOutput = settings.value("loadModelOutput")
+ checkBeforeRunModel = settings.value("checkBeforeRunModel")
+ removeModelsOnExit = settings.value("removeModelsOnExit")
+ removeModelsOnNewProject = settings.value("removeModelsOnNewProject")
+ defaultModelPath = settings.value("defaultModelPath")
settings.endGroup()
return {
- "loadModelOutput" : loadModelOutput in (True, "true"),
- "checkBeforeRunModel" : checkBeforeRunModel in (True, "true"),
- "removeModelsOnExit" : removeModelsOnExit in (True, "true"),
- "removeModelsOnNewProject" : removeModelsOnNewProject in (True, "true"),
- "defaultModelPath" : defaultModelPath
+ "loadModelOutput": loadModelOutput in (True, "true"),
+ "checkBeforeRunModel": checkBeforeRunModel in (True, "true"),
+ "removeModelsOnExit": removeModelsOnExit in (True, "true"),
+ "removeModelsOnNewProject": removeModelsOnNewProject in (True, "true"),
+ "defaultModelPath": defaultModelPath,
}
def updateValidationToolbarConfig(self):
@@ -226,14 +320,18 @@ def updateValidationToolbarConfig(self):
Updates current Validation Toolbar parameter values from GUI.
"""
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- settings.setValue('loadModelOutput', self.loadModelOutputCheckBox.isChecked())
- settings.setValue('checkBeforeRunModel', self.checkBeforeRunModelCheckBox.isChecked())
- settings.setValue('removeModelsOnExit', self.resetModelsCheckBox.isChecked())
- settings.setValue('removeModelsOnNewProject', self.removeModelsProjectCheckBox.isChecked())
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ settings.setValue("loadModelOutput", self.loadModelOutputCheckBox.isChecked())
+ settings.setValue(
+ "checkBeforeRunModel", self.checkBeforeRunModelCheckBox.isChecked()
+ )
+ settings.setValue("removeModelsOnExit", self.resetModelsCheckBox.isChecked())
+ settings.setValue(
+ "removeModelsOnNewProject", self.removeModelsProjectCheckBox.isChecked()
+ )
# oldModelPath = settings.value('defaultModelPath')
# newModelPath = self.modelPathComboBox.currentText()
- settings.setValue('defaultModelPath', self.modelPathComboBox.currentText())
+ settings.setValue("defaultModelPath", self.modelPathComboBox.currentText())
settings.endGroup()
# if oldModelPath != newModelPath:
# self.modelPathChanged.emit()
@@ -245,7 +343,10 @@ def addNewModelPath(self, modelPath, setAsDefault=True):
:param setAsDefault: (bool) whether current selection should be updated to new model path.
:return: (int) index for new model path on its selection combo box.
"""
- if not os.path.exists(modelPath) or self.modelPathComboBox.findText(modelPath) >= 0:
+ if (
+ not os.path.exists(modelPath)
+ or self.modelPathComboBox.findText(modelPath) >= 0
+ ):
return -1
self.modelPathComboBox.addItem(modelPath)
idx = self.modelPathComboBox.findText(modelPath)
@@ -260,10 +361,14 @@ def setCustomModelPath(self):
"""
fd = QFileDialog()
newModelPath = fd.getExistingDirectory(
- caption=self.tr('Select a directory for DSGTools Validation'
- ' Toolbar to look for QGIS Processing models')
+ caption=self.tr(
+ "Select a directory for DSGTools Validation"
+ " Toolbar to look for QGIS Processing models"
+ )
+ )
+ newModelPath = (
+ newModelPath[0] if isinstance(newModelPath, tuple) else newModelPath
)
- newModelPath = newModelPath[0] if isinstance(newModelPath, tuple) else newModelPath
if not newModelPath:
return
- self.addNewModelPath(newModelPath)
\ No newline at end of file
+ self.addNewModelPath(newModelPath)
diff --git a/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py b/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py
index 9541bfa19..221499867 100644
--- a/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py
+++ b/DsgTools/gui/AboutAndFurtherInfo/aboutAndFurtherInfoGuiManager.py
@@ -21,8 +21,13 @@
"""
from __future__ import absolute_import
-from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import PalavrasFileConfig, WordDatasetPtBRFileConfig
-from DsgTools.core.NetworkTools.ExternalFilesHandler import ExternalFileDownloadProcessor
+from DsgTools.core.DSGToolsProcessingAlgs.Algs.LayerManagementAlgs.spellChecker.datasets.ptBR import (
+ PalavrasFileConfig,
+ WordDatasetPtBRFileConfig,
+)
+from DsgTools.core.NetworkTools.ExternalFilesHandler import (
+ ExternalFileDownloadProcessor,
+)
from qgis.PyQt.QtCore import QObject
from qgis.PyQt.QtWidgets import QToolButton, QMenu, QAction
@@ -30,9 +35,9 @@
from .Options.options import Options
from .aboutdialog import AboutDialog
-class AboutAndFurtherInfoGuiManager(QObject):
- def __init__(self, manager, iface, parentMenu = None, toolbar = None):
+class AboutAndFurtherInfoGuiManager(QObject):
+ def __init__(self, manager, iface, parentMenu=None, toolbar=None):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
@@ -45,66 +50,69 @@ def __init__(self, manager, iface, parentMenu = None, toolbar = None):
self.iface = iface
self.parentMenu = parentMenu
self.toolbar = toolbar
- self.iconBasePath = ':/plugins/DsgTools/icons/'
+ self.iconBasePath = ":/plugins/DsgTools/icons/"
self.options = Options()
self.options.firstTimeConfig()
-
+
def initGui(self):
action = self.manager.add_action(
- self.iconBasePath + 'custom_tools.png',
+ self.iconBasePath + "custom_tools.png",
text=self.tr("DSGTools' Options"),
callback=self.showOptions,
parent=self.iface.mainWindow(),
- parentMenu = self.parentMenu,
+ parentMenu=self.parentMenu,
add_to_menu=False,
add_to_toolbar=False,
- withShortcut = True
+ withShortcut=True,
)
action = self.manager.add_action(
- self.iconBasePath + 'import.png',
+ self.iconBasePath + "import.png",
text=self.tr("Download external data"),
callback=self.checkExternalDownloads,
parent=self.iface.mainWindow(),
- parentMenu = self.parentMenu,
+ parentMenu=self.parentMenu,
add_to_menu=False,
add_to_toolbar=False,
- withShortcut = False
+ withShortcut=False,
)
# self.parentMenu.addAction(action)
- icon_path = self.iconBasePath + 'bug.png'
+ icon_path = self.iconBasePath + "bug.png"
action = self.manager.add_action(
icon_path,
- text=self.tr('Report bug / Suggest features'),
+ text=self.tr("Report bug / Suggest features"),
callback=self.showBugTracker,
parent=self.parentMenu,
add_to_menu=True,
add_to_toolbar=False,
- withShortcut = True)
+ withShortcut=True,
+ )
- icon_path = self.iconBasePath + 'help.png'
+ icon_path = self.iconBasePath + "help.png"
action = self.manager.add_action(
icon_path,
- text=self.tr('Help'),
+ text=self.tr("Help"),
callback=self.showHelp,
parent=self.parentMenu,
add_to_menu=True,
add_to_toolbar=False,
- withShortcut = False)
-
- icon_path = self.iconBasePath + 'dsg.png'
+ withShortcut=False,
+ )
+
+ icon_path = self.iconBasePath + "dsg.png"
self.manager.add_action(
icon_path,
- text=self.tr('About DSGTools'),
+ text=self.tr("About DSGTools"),
callback=self.showAbout,
parent=self.parentMenu,
add_to_menu=True,
add_to_toolbar=False,
- withShortcut = False)
-
+ withShortcut=False,
+ )
+
def unload(self):
pass
-
+
def showOptions(self):
"""
Shows the options
@@ -113,9 +121,11 @@ def showOptions(self):
self.options.setInterfaceWithParametersFromConfig()
self.checkExternalDownloads()
result = self.options.exec_()
-
+
def checkExternalDownloads(self):
- downloadProcessor = ExternalFileDownloadProcessor(parent=self.iface.mainWindow())
+ downloadProcessor = ExternalFileDownloadProcessor(
+ parent=self.iface.mainWindow()
+ )
output = downloadProcessor.process(
fileConfigList=[
WordDatasetPtBRFileConfig,
@@ -123,13 +133,15 @@ def checkExternalDownloads(self):
]
)
if output:
- message = self.tr('Everyting up to date') if output==1 else self.tr('External files updated')
+ message = (
+ self.tr("Everyting up to date")
+ if output == 1
+ else self.tr("External files updated")
+ )
self.iface.messageBar().pushMessage(
- self.tr('Info'),
- message,
- level=Qgis.Info
+ self.tr("Info"), message, level=Qgis.Info
)
-
+
def showHelp(self):
"""
Shows the help
@@ -141,11 +153,11 @@ def showBugTracker(self):
Shows the bug tracker
"""
self.iface.openURL("https://github.com/dsgoficial/DsgTools/issues", False)
-
+
def showAbout(self):
"""
Shows the about dialog
"""
dlg = AboutDialog()
dlg.show()
- dlg.exec_()
\ No newline at end of file
+ dlg.exec_()
diff --git a/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py b/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py
index a6b3e8185..791edeeed 100644
--- a/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py
+++ b/DsgTools/gui/AboutAndFurtherInfo/aboutdialog.py
@@ -25,9 +25,15 @@
from qgis.PyQt.QtWidgets import QDialog
# replace version from metada file
-with open(os.path.join(os.path.dirname(__file__), 'ui_about.ui'), 'r', encoding="utf-8") as about, \
- open(os.path.join(os.path.dirname(__file__), '..', '..', 'metadata.txt'), 'r', encoding="utf-8") as meta, \
- open(os.path.join(os.path.dirname(__file__), 'ui_about_.ui'), 'w') as filledUi:
+with open(
+ os.path.join(os.path.dirname(__file__), "ui_about.ui"), "r", encoding="utf-8"
+) as about, open(
+ os.path.join(os.path.dirname(__file__), "..", "..", "metadata.txt"),
+ "r",
+ encoding="utf-8",
+) as meta, open(
+ os.path.join(os.path.dirname(__file__), "ui_about_.ui"), "w"
+) as filledUi:
t = Template(about.read())
for line in meta.readlines():
if line.strip().startswith("version="):
@@ -36,13 +42,13 @@
t = t.safe_substitute(version=version)
filledUi.write(t)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'ui_about_.ui'))
+FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), "ui_about_.ui"))
+
class AboutDialog(QDialog, FORM_CLASS):
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""
Constructor
"""
super(AboutDialog, self).__init__(parent)
self.setupUi(self)
-
diff --git a/DsgTools/gui/BDGExTools/bdgexGuiManager.py b/DsgTools/gui/BDGExTools/bdgexGuiManager.py
index 08ee6faba..4bcb9c988 100644
--- a/DsgTools/gui/BDGExTools/bdgexGuiManager.py
+++ b/DsgTools/gui/BDGExTools/bdgexGuiManager.py
@@ -24,14 +24,14 @@
from functools import partial
from qgis.core import Qgis, QgsProject, QgsVectorLayer
-from qgis.PyQt.QtCore import QObject
+from qgis.PyQt.QtCore import QObject
from DsgTools.core.Utils.utils import MessageRaiser
from DsgTools.core.NetworkTools.BDGExRequestHandler import BDGExRequestHandler
-class BDGExGuiManager(QObject):
- def __init__(self, manager, iface, parentMenu = None, toolbar = None):
+class BDGExGuiManager(QObject):
+ def __init__(self, manager, iface, parentMenu=None, toolbar=None):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
@@ -45,345 +45,325 @@ def __init__(self, manager, iface, parentMenu = None, toolbar = None):
self.parentMenu = parentMenu
self.toolbar = toolbar
self.BDGExRequestHandler = BDGExRequestHandler()
- self.menu = self.manager.addMenu(u'bdgex', self.tr('BDGEx'),'eb.png')
- self.iconBasePath = ':/plugins/DsgTools/icons/'
+ self.menu = self.manager.addMenu("bdgex", self.tr("BDGEx"), "eb.png")
+ self.iconBasePath = ":/plugins/DsgTools/icons/"
self.availableServices = {
- 'topocharts' : [
+ "topocharts": [
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Multi scale mosaic'),
- 'layers' : [
- 'ctm25',
- 'ctm50',
- 'ctm100',
- 'ctm250'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS',
- 'separator' : True
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Multi scale mosaic"),
+ "layers": ["ctm25", "ctm50", "ctm100", "ctm250"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ "separator": True,
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:250,000'),
- 'layers' : [
- 'ctm250'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:250,000"),
+ "layers": ["ctm250"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:100,000'),
- 'layers' : [
- 'ctm100'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:100,000"),
+ "layers": ["ctm100"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:50,000'),
- 'layers' : [
- 'ctm50'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:50,000"),
+ "layers": ["ctm50"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:25,000'),
- 'layers' : [
- 'ctm25'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
- }
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:25,000"),
+ "layers": ["ctm25"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ },
],
- 'coverage' : [
+ "coverage": [
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Rapideye Imagery (2013 mosaic)'),
- 'layers' : [
- 'rapideye'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Rapideye Imagery (2013 mosaic)"),
+ "layers": ["rapideye"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Landsat 7 Imagery (2000 mosaic)'),
- 'layers' : [
- 'landsat7'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Landsat 7 Imagery (2000 mosaic)"),
+ "layers": ["landsat7"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Orthorectified True Color Imagery compatible with 1:25,000 scale'),
- 'layers' : [
- 'ortoimagem_scn25'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Orthorectified True Color Imagery compatible with 1:25,000 scale"
+ ),
+ "layers": ["ortoimagem_scn25"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Artificial SAR Imagery compatible with 1:50,000 scale'),
- 'layers' : [
- 'ram_colorimetria_50'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Artificial SAR Imagery compatible with 1:50,000 scale"
+ ),
+ "layers": ["ram_colorimetria_50"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Artificial SAR Imagery compatible with 1:25,000 scale'),
- 'layers' : [
- 'ram_colorimetria_25'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
- }
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Artificial SAR Imagery compatible with 1:25,000 scale"
+ ),
+ "layers": ["ram_colorimetria_25"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ },
],
- 'terrain' : [
+ "terrain": [
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Surface Digital Model compatible with scale 1:25,000'),
- 'layers' : [
- 'mds25'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Surface Digital Model compatible with scale 1:25,000"
+ ),
+ "layers": ["mds25"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Contour lines compatible with scale 1:25,000'),
- 'layers' : [
- 'curva_nivel25'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS',
- 'separator' : True
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Contour lines compatible with scale 1:25,000"
+ ),
+ "layers": ["curva_nivel25"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ "separator": True,
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Surface Digital Model compatible with scale 1:50,000'),
- 'layers' : [
- 'mds50'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Surface Digital Model compatible with scale 1:50,000"
+ ),
+ "layers": ["mds50"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Contour lines compatible with scale 1:50,000'),
- 'layers' : [
- 'curva_nivel50'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS',
- 'separator' : True
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Contour lines compatible with scale 1:50,000"
+ ),
+ "layers": ["curva_nivel50"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ "separator": True,
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Contour lines compatible with scale 1:100,000'),
- 'layers' : [
- 'curva_nivel100'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Contour lines compatible with scale 1:100,000"
+ ),
+ "layers": ["curva_nivel100"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Surface Digital Model compatible with scale 1:250,000 (SRTM)'),
- 'layers' : [
- 'mds250'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Surface Digital Model compatible with scale 1:250,000 (SRTM)"
+ ),
+ "layers": ["mds250"],
+ "service": "mapcache",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Contour lines compatible with scale 1:250,000'),
- 'layers' : [
- 'curva_nivel250'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS'
- }
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr(
+ "Contour lines compatible with scale 1:250,000"
+ ),
+ "layers": ["curva_nivel250"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ },
],
- 'aux_layers' : [
+ "aux_layers": [
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Brazilian Political Information'),
- 'layers' : [
- 'municipios',
- 'estados',
- 'capitais'
- ],
- 'service' : 'mapcache',
- 'service_type' : 'WMS',
- 'separator' : True
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Brazilian Political Information"),
+ "layers": ["municipios", "estados", "capitais"],
+ "service": "mapcache",
+ "service_type": "WMS",
+ "separator": True,
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Brazilian Cities'),
- 'layers' : [
- 'municipios'
- ],
- 'service' : 'auxlayers',
- 'service_type' : 'WFS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Brazilian Cities"),
+ "layers": ["municipios"],
+ "service": "auxlayers",
+ "service_type": "WFS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Brazilian States'),
- 'layers' : [
- 'estados'
- ],
- 'service' : 'auxlayers',
- 'service_type' : 'WFS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Brazilian States"),
+ "layers": ["estados"],
+ "service": "auxlayers",
+ "service_type": "WFS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('Brazilian State Capitals'),
- 'layers' : [
- 'capitais'
- ],
- 'service' : 'auxlayers',
- 'service_type' : 'WFS'
- }
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("Brazilian State Capitals"),
+ "layers": ["capitais"],
+ "service": "auxlayers",
+ "service_type": "WFS",
+ },
],
- 'raster_mapindex' : [
+ "raster_mapindex": [
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:250,000'),
- 'layers' : [
- 'F250_WGS84_MATRICIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:250,000"),
+ "layers": ["F250_WGS84_MATRICIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:100,000'),
- 'layers' : [
- 'F100_WGS84_MATRICIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:100,000"),
+ "layers": ["F100_WGS84_MATRICIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:50,000'),
- 'layers' : [
- 'F50_WGS84_MATRICIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:50,000"),
+ "layers": ["F50_WGS84_MATRICIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:25,000'),
- 'layers' : [
- 'F25_WGS84_MATRICIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
- }
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:25,000"),
+ "layers": ["F25_WGS84_MATRICIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
+ },
],
- 'vector_mapindex' : [
+ "vector_mapindex": [
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:250,000'),
- 'layers' : [
- 'F250_WGS84_VETORIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:250,000"),
+ "layers": ["F250_WGS84_VETORIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:100,000'),
- 'layers' : [
- 'F100_WGS84_VETORIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:100,000"),
+ "layers": ["F100_WGS84_VETORIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:50,000'),
- 'layers' : [
- 'F50_WGS84_VETORIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:50,000"),
+ "layers": ["F50_WGS84_VETORIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
},
{
- 'icon' : ':/plugins/DsgTools/icons/eb.png',
- 'menu_entry' : self.tr('1:25,000'),
- 'layers' : [
- 'F25_WGS84_VETORIAL'
- ],
- 'service' : 'mapindex',
- 'service_type' : 'WMS'
- }
- ]
+ "icon": ":/plugins/DsgTools/icons/eb.png",
+ "menu_entry": self.tr("1:25,000"),
+ "layers": ["F25_WGS84_VETORIAL"],
+ "service": "mapindex",
+ "service_type": "WMS",
+ },
+ ],
}
-
def initGui(self):
- self.topocharts = self.manager.addMenu(u'topocharts', self.tr('Topographic Charts'),'eb.png', parentMenu = self.menu)
- self.load_menus('topocharts', self.topocharts)
- self.coverageLyr = self.manager.addMenu(u'coverageLyr', self.tr('Coverage Layers'),'eb.png', parentMenu = self.menu)
- self.load_menus('coverage', self.coverageLyr)
- self.terrainLyr = self.manager.addMenu(u'terrainLyr', self.tr('Terrain Information'),'eb.png', parentMenu = self.menu)
- self.load_menus('terrain', self.terrainLyr)
- self.auxLyr = self.manager.addMenu(u'auxLyr', self.tr('Auxiliar Information'),'eb.png', parentMenu = self.menu)
- self.load_menus('aux_layers', self.auxLyr)
- self.indexes = self.manager.addMenu(u'indexes', self.tr('Product Indexes'),'eb.png', parentMenu = self.menu)
- self.rasterIndex = self.manager.addMenu(u'rasterindex', self.tr('Topographic Charts'),'eb.png', parentMenu = self.indexes)
- self.load_menus('raster_mapindex', self.rasterIndex)
- self.vectorIndex = self.manager.addMenu(u'vectorindex', self.tr('Vectorial Charts'),'eb.png', parentMenu = self.indexes)
- self.load_menus('vector_mapindex', self.vectorIndex)
+ self.topocharts = self.manager.addMenu(
+ "topocharts", self.tr("Topographic Charts"), "eb.png", parentMenu=self.menu
+ )
+ self.load_menus("topocharts", self.topocharts)
+ self.coverageLyr = self.manager.addMenu(
+ "coverageLyr", self.tr("Coverage Layers"), "eb.png", parentMenu=self.menu
+ )
+ self.load_menus("coverage", self.coverageLyr)
+ self.terrainLyr = self.manager.addMenu(
+ "terrainLyr", self.tr("Terrain Information"), "eb.png", parentMenu=self.menu
+ )
+ self.load_menus("terrain", self.terrainLyr)
+ self.auxLyr = self.manager.addMenu(
+ "auxLyr", self.tr("Auxiliar Information"), "eb.png", parentMenu=self.menu
+ )
+ self.load_menus("aux_layers", self.auxLyr)
+ self.indexes = self.manager.addMenu(
+ "indexes", self.tr("Product Indexes"), "eb.png", parentMenu=self.menu
+ )
+ self.rasterIndex = self.manager.addMenu(
+ "rasterindex",
+ self.tr("Topographic Charts"),
+ "eb.png",
+ parentMenu=self.indexes,
+ )
+ self.load_menus("raster_mapindex", self.rasterIndex)
+ self.vectorIndex = self.manager.addMenu(
+ "vectorindex",
+ self.tr("Vectorial Charts"),
+ "eb.png",
+ parentMenu=self.indexes,
+ )
+ self.load_menus("vector_mapindex", self.vectorIndex)
- def loadServiceLayer(self, legendName, service, layerList, serviceType='WMS'):
- urlWithParams = self.BDGExRequestHandler.get_url_string(service, layerList, serviceType)
+ def loadServiceLayer(self, legendName, service, layerList, serviceType="WMS"):
+ urlWithParams = self.BDGExRequestHandler.get_url_string(
+ service, layerList, serviceType
+ )
if not urlWithParams:
return
- if serviceType == 'WMS':
+ if serviceType == "WMS":
self.iface.addRasterLayer(urlWithParams, legendName, serviceType.lower())
- if serviceType == 'WFS':
+ if serviceType == "WFS":
vlayer = QgsVectorLayer(urlWithParams, legendName, serviceType)
if not vlayer.isValid():
title = self.tr("BDGEx layers (DSGTools)")
- msg = self.tr("Unable to provide requested layer. Please check"
- " your network settings (proxy and exceptions "
- "too, if necessary).")
+ msg = self.tr(
+ "Unable to provide requested layer. Please check"
+ " your network settings (proxy and exceptions "
+ "too, if necessary)."
+ )
MessageRaiser().raiseIfaceMessage(title, msg, Qgis.Warning, 5)
else:
QgsProject.instance().addMapLayer(vlayer)
-
+
def load_menus(self, menu_type, parentMenu):
for serviceDict in self.availableServices[menu_type]:
callback = partial(
self.loadServiceLayer,
- legendName=serviceDict['menu_entry'],
- service=serviceDict['service'],
- layerList=serviceDict['layers'],
- serviceType=serviceDict['service_type']
- )
+ legendName=serviceDict["menu_entry"],
+ service=serviceDict["service"],
+ layerList=serviceDict["layers"],
+ serviceType=serviceDict["service_type"],
+ )
action = self.manager.add_action(
- icon_path=serviceDict['icon'],
- text=serviceDict['menu_entry'],
- callback= callback,
+ icon_path=serviceDict["icon"],
+ text=serviceDict["menu_entry"],
+ callback=callback,
parent=parentMenu,
add_to_menu=False,
- add_to_toolbar=False
- )
+ add_to_toolbar=False,
+ )
parentMenu.addAction(action)
- if 'separator' in serviceDict and serviceDict['separator']:
+ if "separator" in serviceDict and serviceDict["separator"]:
parentMenu.addSeparator()
def unload(self):
diff --git a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py
index 20f898af3..c94bbad7c 100644
--- a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py
+++ b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/auxLayerSelector.py
@@ -24,13 +24,16 @@
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import QWidget, QFormLayout, QLabel
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import DsgCustomComboBox
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import (
+ DsgCustomComboBox,
+)
+
class AuxLayerSelector(QWidget):
def __init__(self, parent=None):
super(AuxLayerSelector, self).__init__(parent)
self.layout = QFormLayout()
-
+
def setInitialState(self, initDict):
"""
Sets widget interface with initDict entries. Keys are labels and values are list of items for each combobox corresponding to each key.
@@ -41,14 +44,14 @@ def setInitialState(self, initDict):
widget.addItems(value)
self.layout.addRow(label, widget)
self.setLayout(self.layout)
-
+
def resetLayout(self):
"""
Resets current widget layout.
"""
self.layout = QFormLayout()
self.setLayout(self.layout)
-
+
def getParameters(self):
"""
Gets current values fom each widget as a dictionary.
@@ -58,4 +61,4 @@ def getParameters(self):
key = self.layout.itemAt(i, QFormLayout.LabelRole).text()
value = self.layout.itemAt(i, QFormLayout.FieldRole).currentText()
returnDict[key] = value
- return returnDict
\ No newline at end of file
+ return returnDict
diff --git a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py
index dae6c7d4d..e573bea16 100644
--- a/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py
+++ b/DsgTools/gui/CustomWidgets/AdvancedInterfaceWidgets/customFeatureForm.py
@@ -26,23 +26,27 @@
from qgis.gui import QgsMessageBar
from qgis.PyQt.QtCore import Qt, QSize, pyqtSlot
from qgis.PyQt.QtGui import QIcon
-from qgis.PyQt.QtWidgets import (QLabel,
- QDialog,
- QSpinBox,
- QLineEdit,
- QComboBox,
- QCheckBox,
- QGridLayout,
- QSpacerItem,
- QSizePolicy,
- QDoubleSpinBox)
+from qgis.PyQt.QtWidgets import (
+ QLabel,
+ QDialog,
+ QSpinBox,
+ QLineEdit,
+ QComboBox,
+ QCheckBox,
+ QGridLayout,
+ QSpacerItem,
+ QSizePolicy,
+ QDoubleSpinBox,
+)
from qgis.PyQt import uic, QtWidgets, QtGui
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.GeometricTools.layerHandler import LayerHandler
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'customFeatureForm.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "customFeatureForm.ui")
+)
+
class CustomFeatureForm(QDialog, FORM_CLASS):
"""
@@ -50,6 +54,7 @@ class CustomFeatureForm(QDialog, FORM_CLASS):
Feature Tool Box. This form was copied from `Ferramentas de Produção` and
modified for the DSGTools plugin.
"""
+
def __init__(self, layer, layerMap, attributeMap=None, valueMaps=None):
"""
Class constructor.
@@ -61,7 +66,7 @@ def __init__(self, layer, layerMap, attributeMap=None, valueMaps=None):
(reclassified) value.
:param valueMaps: (dict) map of all value/relations maps set to layer's
fields. These maps will be used for domain checking
- operations.
+ operations.
"""
super(CustomFeatureForm, self).__init__()
self.setupUi(self)
@@ -86,7 +91,7 @@ def resizeEvent(self, e):
self.messageBar.resize(
QSize(
self.geometry().size().width(),
- 40 # this felt nicer than the original height (30)
+ 40, # this felt nicer than the original height (30)
)
)
@@ -133,17 +138,21 @@ def getFieldComboBox(self, field):
inverseDomain = {v: k for k, v in domain.items()}
if not domain:
raise ValueError(
- self.tr("Field {0} does not have a value/relations map")\
- .format(field.name())
+ self.tr("Field {0} does not have a value/relations map").format(
+ field.name()
+ )
)
cb.addItems(list(domain.keys()))
+
def setValue(val):
"""val: field's real value"""
if val not in domain.values():
return
cb.setCurrentText(inverseDomain[val])
+
def value():
return domain[cb.currentText()]
+
cb.setValue = setValue
cb.value = value
return cb
@@ -162,7 +171,7 @@ def setupFields(self):
map.
"""
utils = Utils()
- row = 0 # in case no fields are provided
+ row = 0 # in case no fields are provided
for row, f in enumerate(self.layer().fields()):
fName = f.name()
fMap = self.attributeMap.get(fName, None)
@@ -178,8 +187,10 @@ def setupFields(self):
enabled = fMap["editable"]
if fMap["isPk"]:
# visually identify primary key attributes
- text = '
{0}
'.format(fName)
+ text = (
+ '
{0}
'.format(fName)
+ )
else:
text = fName
else:
@@ -215,10 +226,12 @@ def setupFields(self):
self.widgetsLayout.addWidget(label, row, 0)
self.widgetsLayout.addWidget(w, row, 1)
self.widgetsLayout.addItem(
- QSpacerItem(
- 20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding
- ), row + 1, 1, 1, 2
- ) # row, col, rowSpan, colSpan
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Expanding),
+ row + 1,
+ 1,
+ 1,
+ 2,
+ ) # row, col, rowSpan, colSpan
def updateAttributeMap(self):
"""
@@ -286,8 +299,8 @@ def on_okPushButton_clicked(self):
self.done(1)
else:
self.messageBar.pushMessage(
- self.tr('Invalid layer selection'),
+ self.tr("Invalid layer selection"),
self.tr("select at least one layer for reclassification!"),
level=Qgis.Warning,
- duration=5
+ duration=5,
)
diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py
index 2e2459f24..e01699f83 100644
--- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py
+++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeConditionWidget.py
@@ -28,17 +28,24 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "attributeConditionWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'attributeConditionWidget.ui'))
class AttributeConditionWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
# Set up the user interface from Designer.
@@ -47,5 +54,3 @@ def __init__(self, parent = None):
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
-
-
diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py
index 2bb9239ab..2908507fe 100644
--- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py
+++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleTypeWidget.py
@@ -29,28 +29,36 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'attributeRuleTypeWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "attributeRuleTypeWidget.ui")
+)
+
class AttributeRuleTypeWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, parameterDict = {}, parent = None):
+ def __init__(self, parameterDict={}, parent=None):
"""Constructor."""
- super(AttributeRuleTypeWidget, self).__init__(parent = parent)
+ super(AttributeRuleTypeWidget, self).__init__(parent=parent)
self.setupUi(self)
- self.validKeys = ['attributeRuleType', 'ruleColor', 'rank']
+ self.validKeys = ["attributeRuleType", "ruleColor", "rank"]
if isinstance(parameterDict, dict) and parameterDict != {}:
self.populateInterface(parameterDict)
-
+
def clearAll(self):
"""
Clears all widget information
"""
pass
-
+
def getParameterDict(self):
"""
Components:
@@ -62,9 +70,11 @@ def getParameterDict(self):
if not self.validate():
raise Exception(self.invalidatedReason())
parameterDict = dict()
- parameterDict['attributeRuleType'] = self.attributeRuleTypeLineEdit.text()
- parameterDict['ruleColor'] = ','.join(map(str,self.mColorButton.color().getRgb()))
- parameterDict['rank'] = self.rankSpinBox.value()
+ parameterDict["attributeRuleType"] = self.attributeRuleTypeLineEdit.text()
+ parameterDict["ruleColor"] = ",".join(
+ map(str, self.mColorButton.color().getRgb())
+ )
+ parameterDict["rank"] = self.rankSpinBox.value()
return parameterDict
def populateInterface(self, parameterDict):
@@ -73,13 +83,17 @@ def populateInterface(self, parameterDict):
"""
if parameterDict:
if not self.validateJson(parameterDict):
- raise Exception(self.tr('Invalid Attribute Rule Type Widget json config!'))
- #set layer combo
- self.attributeRuleTypeLineEdit.setText(parameterDict['attributeRuleType'])
- R,G,B = list(map(int,parameterDict['ruleColor'].split(','))) #QColor only accepts int values
- self.mColorButton.setColor(QColor(R,G,B))
- self.rankSpinBox.setValue(parameterDict['rank'])
-
+ raise Exception(
+ self.tr("Invalid Attribute Rule Type Widget json config!")
+ )
+ # set layer combo
+ self.attributeRuleTypeLineEdit.setText(parameterDict["attributeRuleType"])
+ R, G, B = list(
+ map(int, parameterDict["ruleColor"].split(","))
+ ) # QColor only accepts int values
+ self.mColorButton.setColor(QColor(R, G, B))
+ self.rankSpinBox.setValue(parameterDict["rank"])
+
def validateJson(self, inputJson):
"""
Validates input json
@@ -95,15 +109,15 @@ def validate(self):
"""
Validates fields. Returns True if all information are filled correctly.
"""
- if self.attributeRuleTypeLineEdit.text() == '':
+ if self.attributeRuleTypeLineEdit.text() == "":
return False
return True
-
+
def invalidatedReason(self):
"""
Error reason
"""
- msg = ''
- if self.attributeRuleTypeLineEdit.text() == '':
- msg += self.tr('Invalid rule name!\n')
- return msg
\ No newline at end of file
+ msg = ""
+ if self.attributeRuleTypeLineEdit.text() == "":
+ msg += self.tr("Invalid rule name!\n")
+ return msg
diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py
index eef0b72ca..72f274525 100644
--- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py
+++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/attributeRuleWidget.py
@@ -28,28 +28,36 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'attributeRuleWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "attributeRuleWidget.ui")
+)
+
class AttributeRuleWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, layerDict, parameterDict = {}, parent = None):
+ def __init__(self, layerDict, parameterDict={}, parent=None):
"""Constructor."""
- super(AttributeRuleWidget, self).__init__(parent = parent)
+ super(AttributeRuleWidget, self).__init__(parent=parent)
self.setupUi(self)
self.layerDict = layerDict
- self.layerComboBox.addItem(self.tr('Select a layer'))
+ self.layerComboBox.addItem(self.tr("Select a layer"))
layerNames = list(layerDict.keys())
layerNames.sort()
self.layerComboBox.addItems(layerNames)
self.setComponentsEnabled(False)
- self.validKeys = ['attributeName', 'attributeRule', 'description', 'layerName']
+ self.validKeys = ["attributeName", "attributeRule", "description", "layerName"]
if parameterDict != {}:
self.populateInterface(parameterDict)
-
+
def clearAll(self):
"""
Clears all widget information
@@ -57,7 +65,7 @@ def clearAll(self):
self.attributeComboBox.clear()
self.mFieldExpressionWidget.setRow(-1)
self.descriptionLineEdit.clear()
-
+
def setComponentsEnabled(self, enabled):
"""
Sets all components enabled.
@@ -65,24 +73,24 @@ def setComponentsEnabled(self, enabled):
self.attributeComboBox.setEnabled(enabled)
self.mFieldExpressionWidget.setEnabled(enabled)
self.descriptionLineEdit.setEnabled(enabled)
-
- @pyqtSlot(int, name = 'on_layerComboBox_currentIndexChanged')
+
+ @pyqtSlot(int, name="on_layerComboBox_currentIndexChanged")
def filterAttributeCombo(self, idx):
self.clearAll()
if idx > 0:
key = self.layerComboBox.currentText()
- self.attributeComboBox.addItem(self.tr('Select attribute'))
- #get attribute names
+ self.attributeComboBox.addItem(self.tr("Select attribute"))
+ # get attribute names
attrNames = [i.name() for i in self.layerDict[key].fields()]
- #add items to combo box
+ # add items to combo box
self.attributeComboBox.addItems(attrNames)
- #after everything is ok, set components enabled
+ # after everything is ok, set components enabled
self.setComponentsEnabled(True)
- #set layer on mFieldExpressionWidget
+ # set layer on mFieldExpressionWidget
self.mFieldExpressionWidget.setLayer(self.layerDict[key])
else:
self.setComponentsEnabled(False)
-
+
def getParameterDict(self):
"""
Components:
@@ -94,10 +102,10 @@ def getParameterDict(self):
if not self.validate():
raise Exception(self.invalidatedReason())
parameterDict = dict()
- parameterDict['layerName'] = self.layerComboBox.currentText()
- parameterDict['attributeName'] = self.attributeComboBox.currentText()
- parameterDict['attributeRule'] = self.mFieldExpressionWidget.currentText()
- parameterDict['description'] = self.descriptionLineEdit.text()
+ parameterDict["layerName"] = self.layerComboBox.currentText()
+ parameterDict["attributeName"] = self.attributeComboBox.currentText()
+ parameterDict["attributeRule"] = self.mFieldExpressionWidget.currentText()
+ parameterDict["description"] = self.descriptionLineEdit.text()
return parameterDict
def populateInterface(self, parameterDict):
@@ -106,19 +114,23 @@ def populateInterface(self, parameterDict):
"""
if parameterDict:
if not self.validateJson(parameterDict):
- raise Exception(self.tr('Invalid Attribute Rule Widget json config!'))
- #set layer combo
- idx = self.layerComboBox.findText(parameterDict['layerName'], flags = Qt.MatchExactly)
+ raise Exception(self.tr("Invalid Attribute Rule Widget json config!"))
+ # set layer combo
+ idx = self.layerComboBox.findText(
+ parameterDict["layerName"], flags=Qt.MatchExactly
+ )
self.layerComboBox.setCurrentIndex(idx)
- #set attr combo
- idx = self.attributeComboBox.findText(parameterDict['attributeName'], flags = Qt.MatchExactly)
+ # set attr combo
+ idx = self.attributeComboBox.findText(
+ parameterDict["attributeName"], flags=Qt.MatchExactly
+ )
self.attributeComboBox.setCurrentIndex(idx)
- #set rule
- self.mFieldExpressionWidget.setExpression(parameterDict['attributeRule'])
- #set description
- if parameterDict['description'] != '':
- self.descriptionLineEdit.setText(parameterDict['description'])
-
+ # set rule
+ self.mFieldExpressionWidget.setExpression(parameterDict["attributeRule"])
+ # set description
+ if parameterDict["description"] != "":
+ self.descriptionLineEdit.setText(parameterDict["description"])
+
def validateJson(self, inputJson):
"""
Validates input json
@@ -138,21 +150,29 @@ def validate(self):
return False
if self.attributeComboBox.currentIndex() < 1:
return False
- if self.mFieldExpressionWidget.currentText() == '' or \
- not self.mFieldExpressionWidget.isValidExpression(self.mFieldExpressionWidget.currentText()):
+ if (
+ self.mFieldExpressionWidget.currentText() == ""
+ or not self.mFieldExpressionWidget.isValidExpression(
+ self.mFieldExpressionWidget.currentText()
+ )
+ ):
return False
return True
-
+
def invalidatedReason(self):
"""
Error reason
"""
- msg = ''
+ msg = ""
if self.layerComboBox.currentIndex() < 1:
- msg += self.tr('Invalid layer!\n')
+ msg += self.tr("Invalid layer!\n")
if self.attributeComboBox.currentIndex() < 1:
- msg += self.tr('Invalid attribute!\n')
- if self.mFieldExpressionWidget.currentText() == '' or \
- not self.mFieldExpressionWidget.isValidExpression(self.mFieldExpressionWidget.currentText()):
- msg += self.tr('Invalid rule!\n')
- return msg
\ No newline at end of file
+ msg += self.tr("Invalid attribute!\n")
+ if (
+ self.mFieldExpressionWidget.currentText() == ""
+ or not self.mFieldExpressionWidget.isValidExpression(
+ self.mFieldExpressionWidget.currentText()
+ )
+ ):
+ msg += self.tr("Invalid rule!\n")
+ return msg
diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py
index 04db0ab25..c29d89b98 100644
--- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/listManagerWidget.py
@@ -27,17 +27,24 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "listManagerWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'listManagerWidget.ui'))
class ListManagerWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
# Set up the user interface from Designer.
@@ -46,5 +53,3 @@ def __init__(self, parent = None):
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
-
-
diff --git a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py
index 6beeaddbf..4f2d770cf 100644
--- a/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py
+++ b/DsgTools/gui/CustomWidgets/AttributeValidityWidgets/newAttributeRuleBuilderWidget.py
@@ -28,17 +28,24 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newAttributeRuleBuilderWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'newAttributeRuleBuilderWidget.ui'))
class NewAttributeRuleBuilderWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, parent = None):
+ def __init__(self, abstractDb, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
# Set up the user interface from Designer.
@@ -47,5 +54,3 @@ def __init__(self, abstractDb, parent = None):
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
-
-
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py
index 071f690fe..321f67ea6 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonPropWidget.py
@@ -29,29 +29,37 @@
from qgis.PyQt import uic
from qgis.PyQt.QtGui import QIcon, QColor, QKeySequence
from qgis.PyQt.QtCore import Qt, QSize, pyqtSlot, QSettings, pyqtSignal
-from qgis.PyQt.QtWidgets import (QWidget,
- QSpinBox,
- QLineEdit,
- QCheckBox,
- QComboBox,
- QPushButton,
- QHBoxLayout,
- QMessageBox,
- QDoubleSpinBox)
+from qgis.PyQt.QtWidgets import (
+ QWidget,
+ QSpinBox,
+ QLineEdit,
+ QCheckBox,
+ QComboBox,
+ QPushButton,
+ QHBoxLayout,
+ QMessageBox,
+ QDoubleSpinBox,
+)
from DsgTools.core.Utils.utils import Utils, MessageRaiser
from DsgTools.core.GeometricTools.layerHandler import LayerHandler
-from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import CustomButtonSetup, CustomFeatureButton
+from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import (
+ CustomButtonSetup,
+ CustomFeatureButton,
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'buttonPropWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "buttonPropWidget.ui")
+)
utils = Utils()
+
class ButtonPropWidget(QWidget, FORM_CLASS):
# col enum
COL_COUNT = 5
ATTR_COL, VAL_COL, PK_COL, EDIT_COL, IGNORED_COL = range(COL_COUNT)
+
def __init__(self, parent=None, button=None):
"""
Class constructor.
@@ -61,8 +69,7 @@ def __init__(self, parent=None, button=None):
super(ButtonPropWidget, self).__init__(parent)
self.setupUi(self)
self.mMapLayerComboBox.setFilters(
- QgsMapLayerProxyModel.HasGeometry|
- QgsMapLayerProxyModel.WritableLayer
+ QgsMapLayerProxyModel.HasGeometry | QgsMapLayerProxyModel.WritableLayer
)
self.button = button or CustomFeatureButton()
self.fillToolComboBox()
@@ -72,10 +79,15 @@ def __init__(self, parent=None, button=None):
self.keywordCheckBox.toggled.connect(self.keywordLineEdit.setEnabled)
self.shortcutCheckBox.toggled.connect(self.shortcutWidget.setEnabled)
self.mMapLayerComboBox.layerChanged.connect(self.updateFieldTable)
- self.attributeTableWidget.setHorizontalHeaderLabels([
- self.tr("Attribute"), self.tr("Value"), self.tr("PK"),
- self.tr("Editable"), self.tr("Ignored")
- ])
+ self.attributeTableWidget.setHorizontalHeaderLabels(
+ [
+ self.tr("Attribute"),
+ self.tr("Value"),
+ self.tr("PK"),
+ self.tr("Editable"),
+ self.tr("Ignored"),
+ ]
+ )
header = self.attributeTableWidget.verticalHeader()
header.setSectionResizeMode(header.ResizeToContents)
self.updateFieldTable()
@@ -90,12 +102,14 @@ def confirmAction(self, msg, title=None, showNo=True):
mb = QMessageBox()
title = title or self.tr("Confirm action")
if showNo:
- return QMessageBox.question(
- self, title, msg, QMessageBox.Yes | QMessageBox.No
- ) == QMessageBox.Yes
+ return (
+ QMessageBox.question(self, title, msg, QMessageBox.Yes | QMessageBox.No)
+ == QMessageBox.Yes
+ )
else:
- return QMessageBox.question(
- self, title, msg, QMessageBox.Ok) == QMessageBox.Ok
+ return (
+ QMessageBox.question(self, title, msg, QMessageBox.Ok) == QMessageBox.Ok
+ )
def fillToolComboBox(self):
"""
@@ -106,12 +120,15 @@ def fillToolComboBox(self):
# method, from CustomFeatureButton
tools = {
self.tr("QGIS default feature extraction tool"): QIcon(""),
- self.tr("DSGTools: Free Hand Acquisition"): \
- QIcon(':/plugins/DsgTools/icons/free_hand.png'),
- self.tr("QGIS Circle extraction tool"): \
- QIcon(':/plugins/DsgTools/icons/circle.png'),
- self.tr("DSGTools: Right Degree Angle Digitizing"): \
- QIcon(':/plugins/DsgTools/icons/home.png')
+ self.tr("DSGTools: Free Hand Acquisition"): QIcon(
+ ":/plugins/DsgTools/icons/free_hand.png"
+ ),
+ self.tr("QGIS Circle extraction tool"): QIcon(
+ ":/plugins/DsgTools/icons/circle.png"
+ ),
+ self.tr("DSGTools: Right Degree Angle Digitizing"): QIcon(
+ ":/plugins/DsgTools/icons/home.png"
+ ),
}
for idx, (tool, icon) in enumerate(tools.items()):
self.toolComboBox.insertItem(idx, tool)
@@ -131,7 +148,7 @@ def buttonName(self):
:return: (str) button name read from GUI.
"""
return self.nameLineEdit.text().strip()
-
+
def setDigitizingTool(self, tool):
"""
Sets button's digitizing tool to GUI.
@@ -145,8 +162,7 @@ def digitizingTool(self):
Reads current digitizing tool.
:return: (str) current digitizing tool.
"""
- tools = {v: k for k, v in \
- CustomFeatureButton().supportedTools().items()}
+ tools = {v: k for k, v in CustomFeatureButton().supportedTools().items()}
return tools[self.toolComboBox.currentText()]
def setUseColor(self, useColor):
@@ -291,8 +307,10 @@ def checkShortcut(self, s):
if s == "":
return ""
for m in dir(iface):
- if m.startswith("action") and \
- getattr(iface, m)().shortcut().toString().lower() == s.lower():
+ if (
+ m.startswith("action")
+ and getattr(iface, m)().shortcut().toString().lower() == s.lower()
+ ):
return getattr(iface, m)().text()
return ""
@@ -306,8 +324,10 @@ def setShortcurt(self, s, autoReplace=True):
s = s.replace(" ", "")
action = self.checkShortcut(s)
if not autoReplace and action != "":
- txt = self.tr("Shortcut {s} is already assigned to {a}, would you "
- "like to replace it?").format(s=s, a=action)
+ txt = self.tr(
+ "Shortcut {s} is already assigned to {a}, would you "
+ "like to replace it?"
+ ).format(s=s, a=action)
if not self.confirmAction(txt, self.tr("Replace shortcut")):
return
self.shortcutWidget.setShortcut(QKeySequence.fromString(s))
@@ -339,7 +359,7 @@ def openForm(self):
def setAttributeMap(self, attrMap):
"""
Sets the attribute value map for current button to GUI.
- :param attrMap: (dict) a map from each field and its value to be set.
+ :param attrMap: (dict) a map from each field and its value to be set.
"""
self.updateFieldTable()
table = self.attributeTableWidget
@@ -350,18 +370,21 @@ def setAttributeMap(self, attrMap):
if vl is not None:
for fName, vMap in LayerHandler().valueMaps(vl).items():
valueMaps[fName] = {v: k for k, v in vMap.items()}
+
def setMappedValue(cb, field, value):
if value is None:
return
if not (value in valueMaps[field]):
- msg = self.tr("'{0}' is an invalid value for field {1}. (Is "
- "the layer style generated from the current data"
- " model?")\
- .format(value, field)
+ msg = self.tr(
+ "'{0}' is an invalid value for field {1}. (Is "
+ "the layer style generated from the current data"
+ " model?"
+ ).format(value, field)
title = self.tr("DSGTools Custom Feature Tool Box")
MessageRaiser().raiseIfaceMessage(title, msg, Qgis.Warning, 5)
value = None
cb.setCurrentText(valueMaps[field][value])
+
pkIdxList = vl.primaryKeyAttributes() if vl else []
for row in range(table.rowCount()):
attr = table.cellWidget(row, self.ATTR_COL).text().replace("&", "")
@@ -371,23 +394,26 @@ def setMappedValue(cb, field, value):
attrMap[attr] = {
"value": None,
"editable": False,
- "ignored": isPk, # default is False unless it's a PK attr
- "isPk": isPk
+ "ignored": isPk, # default is False unless it's a PK attr
+ "isPk": isPk,
}
{
QWidget: lambda v: valueWidget.cb.setChecked(v or False),
QLineEdit: lambda v: valueWidget.setText(v or ""),
QSpinBox: lambda v: valueWidget.setValue(v or 0),
QDoubleSpinBox: lambda v: valueWidget.setValue(v or 0.0),
- QComboBox: lambda v: setMappedValue(valueWidget, attr, v)
+ QComboBox: lambda v: setMappedValue(valueWidget, attr, v),
}[type(valueWidget)](attrMap[attr]["value"])
valueWidget.setEnabled(not attrMap[attr]["ignored"])
table.cellWidget(row, self.EDIT_COL).cb.setChecked(
- attrMap[attr]["editable"])
+ attrMap[attr]["editable"]
+ )
table.cellWidget(row, self.IGNORED_COL).cb.setChecked(
- attrMap[attr]["ignored"])
- table.setCellWidget(row, self.PK_COL,
- self.pkWidget() if isPk else QWidget())
+ attrMap[attr]["ignored"]
+ )
+ table.setCellWidget(
+ row, self.PK_COL, self.pkWidget() if isPk else QWidget()
+ )
def attributeMap(self):
"""
@@ -396,26 +422,30 @@ def attributeMap(self):
"""
attrMap = dict()
table = self.attributeTableWidget
- vMaps = LayerHandler().valueMaps(self.vectorLayer()) \
- if self.vectorLayer() else {}
+ vMaps = (
+ LayerHandler().valueMaps(self.vectorLayer()) if self.vectorLayer() else {}
+ )
for row in range(table.rowCount()):
attr = table.cellWidget(row, self.ATTR_COL).text().replace("&", "")
attrMap[attr] = dict()
valueWidget = table.cellWidget(row, self.VAL_COL)
- attrMap[attr]["ignored"] = table.cellWidget(row, self.IGNORED_COL)\
- .cb.isChecked()
+ attrMap[attr]["ignored"] = table.cellWidget(
+ row, self.IGNORED_COL
+ ).cb.isChecked()
# "ignored" still allows the value to be set as last priority
attrMap[attr]["value"] = {
QWidget: lambda: valueWidget.cb.isChecked(),
QLineEdit: lambda: valueWidget.text(),
QSpinBox: lambda: valueWidget.value(),
QDoubleSpinBox: lambda: valueWidget.value(),
- QComboBox: lambda: vMaps[attr][valueWidget.currentText()]
+ QComboBox: lambda: vMaps[attr][valueWidget.currentText()],
}[type(valueWidget)]()
attrMap[attr]["isPk"] = isinstance(
- table.cellWidget(row, self.PK_COL), QPushButton)
- attrMap[attr]["editable"] = table.cellWidget(row, self.EDIT_COL)\
- .cb.isChecked()
+ table.cellWidget(row, self.PK_COL), QPushButton
+ )
+ attrMap[attr]["editable"] = table.cellWidget(
+ row, self.EDIT_COL
+ ).cb.isChecked()
return attrMap
def setLayer(self, layer):
@@ -463,7 +493,7 @@ def pkWidget(self):
used on rows associated with primary key attributes.
"""
pb = QPushButton()
- pb.setIcon(QIcon(':/plugins/DsgTools/icons/key.png'))
+ pb.setIcon(QIcon(":/plugins/DsgTools/icons/key.png"))
pb.setFlat(True)
pb.blockSignals(True)
pb.setObjectName("pkWidget")
@@ -483,7 +513,7 @@ def attributeNameWidget(self, fieldName, isNotNull):
pb.setEnabled(False)
if isNotNull:
pb.setStyleSheet(
- "*{ color:rgb(150, 10, 25); "\
+ "*{ color:rgb(150, 10, 25); "
"background-color:rgba(255, 88, 116, 1.00); }"
)
pb.setToolTip(self.tr("Field cannot be empty"))
@@ -519,7 +549,8 @@ def valueWidget(self, field, data):
else:
vWidget = QLineEdit()
vWidget.setPlaceholderText(
- self.tr("Type the value for {0}").format(field.name()))
+ self.tr("Type the value for {0}").format(field.name())
+ )
if data is not None:
vWidget.setText(data)
return vWidget
@@ -551,8 +582,10 @@ def updateFieldTable(self, layer=None):
if fields.fieldOrigin(idx) == fields.OriginExpression:
virtualFields.append(f.name())
self.attributeTableWidget.setRowCount(len(fields) - len(virtualFields))
+
def setDisabled(w, status):
w.setEnabled(not status)
+
for row, field in enumerate(fields):
fName = field.name()
if fName in virtualFields:
@@ -561,13 +594,14 @@ def setDisabled(w, status):
isPk = row in pkIdxList
notNull = not utils.fieldIsNullable(field)
self.attributeTableWidget.setCellWidget(
- row, self.ATTR_COL, self.attributeNameWidget(fName, notNull))
+ row, self.ATTR_COL, self.attributeNameWidget(fName, notNull)
+ )
if fName not in attrMap:
attrMap[fName] = {
"value": None,
"editable": False,
- "ignored": isPk, # default is False unless it's a PK attr
- "isPk": isPk
+ "ignored": isPk, # default is False unless it's a PK attr
+ "isPk": isPk,
}
value = attrMap[fName]["value"]
if fName in valueMaps:
@@ -583,13 +617,12 @@ def setDisabled(w, status):
self.attributeTableWidget.setCellWidget(row, self.VAL_COL, vWidget)
ccbEdit = self.centeredCheckBox()
ccbEdit.cb.setChecked(attrMap[fName]["editable"])
- self.attributeTableWidget.setCellWidget(
- row, self.EDIT_COL, ccbEdit)
+ self.attributeTableWidget.setCellWidget(row, self.EDIT_COL, ccbEdit)
ccbIgnore = self.centeredCheckBox()
ccbIgnore.cb.setChecked(attrMap[fName]["ignored"])
ccbIgnore.cb.toggled.connect(partial(setDisabled, vWidget))
- self.attributeTableWidget.setCellWidget(
- row, self.IGNORED_COL, ccbIgnore)
+ self.attributeTableWidget.setCellWidget(row, self.IGNORED_COL, ccbIgnore)
+
def checkExclusiveCB(ccb1, ccb2):
"""
Method to make two CB to be mutually exclusive (like radio buttons.
@@ -603,13 +636,15 @@ def checkExclusiveCB(ccb1, ccb2):
ccb1 = cb
if ccb1.cb.isChecked() and ccb2.cb.isChecked():
ccb2.cb.setChecked(False)
+
exclusiveCb = partial(checkExclusiveCB, ccbEdit, ccbIgnore)
ccbIgnore.cb.toggled.connect(exclusiveCb)
ccbEdit.cb.toggled.connect(exclusiveCb)
ccbIgnore.cb.toggled.emit(ccbEdit.cb.isChecked())
# since row is from an enum of fields, field idx = row
- self.attributeTableWidget.setCellWidget(row, self.PK_COL,
- self.pkWidget() if isPk else QWidget())
+ self.attributeTableWidget.setCellWidget(
+ row, self.PK_COL, self.pkWidget() if isPk else QWidget()
+ )
def setButton(self, button):
"""
@@ -665,7 +700,7 @@ def currentButtonName(self):
:return: (CustomFeatureButton) button read from the setup object.
"""
return self.button.name()
-
+
def currentButton(self):
"""
Retrieves currently SAVED button.
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py
index 9ce622e41..dd4bf536c 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/buttonSetupWidget.py
@@ -26,26 +26,29 @@
from qgis.core import Qgis, QgsMessageLog, QgsApplication
from qgis.gui import QgsMessageBar
from qgis.PyQt import uic
-from qgis.PyQt.QtCore import (Qt,
- QSize,
- pyqtSlot,
- QSettings,
- pyqtSignal)
+from qgis.PyQt.QtCore import Qt, QSize, pyqtSlot, QSettings, pyqtSignal
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtSql import QSqlQuery
-from qgis.PyQt.QtWidgets import (QDialog,
- QFileDialog,
- QMessageBox,
- QHeaderView,
- QRadioButton,
- QAbstractItemView)
-
-from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import CustomButtonSetup, CustomFeatureButton
-
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'buttonSetupWidget.ui'))
+from qgis.PyQt.QtWidgets import (
+ QDialog,
+ QFileDialog,
+ QMessageBox,
+ QHeaderView,
+ QRadioButton,
+ QAbstractItemView,
+)
+
+from DsgTools.gui.ProductionTools.Toolboxes.CustomFeatureToolBox.customButtonSetup import (
+ CustomButtonSetup,
+ CustomFeatureButton,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "buttonSetupWidget.ui")
+)
app = QgsApplication.instance()
+
class ButtonSetupWidget(QDialog, FORM_CLASS):
def __init__(self, parent=None, buttonSetup=None):
"""
@@ -61,13 +64,16 @@ def __init__(self, parent=None, buttonSetup=None):
if buttonSetup:
self.setSetup(buttonSetup)
self.buttonComboBox.addItem(self.tr("No button selected"))
- self.tableWidget.itemSelectionChanged.connect(
- self._setButtonFromRow)
+ self.tableWidget.itemSelectionChanged.connect(self._setButtonFromRow)
bEnabled = self.buttonComboBox.currentIndex() > 0
- for w in ("savePushButton", "undoPushButton", "removePushButton",
- "buttonPropWidget"):
+ for w in (
+ "savePushButton",
+ "undoPushButton",
+ "removePushButton",
+ "buttonPropWidget",
+ ):
getattr(self, w).setEnabled(bEnabled)
-
+
# making the button selection to stand out a little bit
if "Night Mapping" in app.activeThemePath():
ss = """QHeaderView::section:checked
@@ -87,11 +93,13 @@ def raiseWarning(self, msg, title=None, lvl=None, duration=None):
:param duration: (int) warning message display time.
"""
self.messageBar.pushMessage(
- title or self.tr('Invalid workflow'), msg,
- level=lvl or Qgis.Warning, duration=duration or 5
+ title or self.tr("Invalid workflow"),
+ msg,
+ level=lvl or Qgis.Warning,
+ duration=duration or 5,
)
# msg = self.tr("Buttons setup definion invalid: {m}").format(m=msg)
- QgsMessageLog.logMessage(msg, 'DSGTools Plugin', Qgis.Warning)
+ QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Warning)
def resizeEvent(self, e):
"""
@@ -103,7 +111,7 @@ def resizeEvent(self, e):
self.messageBar.resize(
QSize(
self.geometry().size().width(),
- 40 # this felt nicer than the original height (30)
+ 40, # this felt nicer than the original height (30)
)
)
@@ -218,7 +226,7 @@ def readSetup(self):
def setSetup(self, newSetup):
"""
Imports buttons setup definitions from another buttons setup.
- :param newSetup: (CustomButtonSetup) setup to be imported.
+ :param newSetup: (CustomButtonSetup) setup to be imported.
"""
self.buttonComboBox.blockSignals(True)
self.setSetupName(newSetup.name())
@@ -439,14 +447,14 @@ def openForm(self):
def setAttributeMap(self, attrMap):
"""
Sets the attribute value map for current button to GUI.
- :param attrMap: (dict) a map from each field and its value to be set.
+ :param attrMap: (dict) a map from each field and its value to be set.
"""
self.buttonPropWidget.setAttributeMap(attrMap)
def attributeMap(self):
"""
Reads the field map data and set it to a button attribute map format.
- :return: (dict) read attribute map.
+ :return: (dict) read attribute map.
"""
return self.buttonPropWidget.attributeMap()
@@ -462,7 +470,7 @@ def layer(self):
Reads current layer selection from GUI.
:return: (str) name for the selected layer.
"""
- self.buttonPropWidget.layer()
+ self.buttonPropWidget.layer()
def currentButton(self):
"""
@@ -551,8 +559,12 @@ def setCurrentButton(self, button):
pass
self.buttonComboBox.setCurrentText(button.name())
bEnabled = self.buttonComboBox.currentIndex() > 0
- for w in ("savePushButton", "undoPushButton", "removePushButton",
- "buttonPropWidget"):
+ for w in (
+ "savePushButton",
+ "undoPushButton",
+ "removePushButton",
+ "buttonPropWidget",
+ ):
getattr(self, w).setEnabled(bEnabled)
self.buttonPropWidget.setButton(button)
@@ -601,10 +613,10 @@ def addButton(self, button=None):
if button is not None and not isinstance(button, bool):
buttonName = button.name()
if buttonName in self.registeredButtonNames():
- msg = self.tr("Button {b} already exists. Would you like to "
- "replace it?").format(b=buttonName)
- cnf = self.confirmAction(msg,
- self.tr("Replace existing button"))
+ msg = self.tr(
+ "Button {b} already exists. Would you like to " "replace it?"
+ ).format(b=buttonName)
+ cnf = self.confirmAction(msg, self.tr("Replace existing button"))
if not cnf:
return self.getButtonByName(buttonName)
self.updateButton(buttonName, button.properties())
@@ -689,11 +701,10 @@ def addButtonToTable(self, button):
self.tableWidget.setCellWidget(row, 0, w)
# button instances on this widget are never the same as the original
# and so, modifying the properties below won't modify anything outside
- # the scope of this dialog
+ # the scope of this dialog
button.setCheckable(False)
# button.setEnabled(False)
- button.setCallback(
- lambda: self.setCurrentButton(button), ignoreEnabled=True)
+ button.setCallback(lambda: self.setCurrentButton(button), ignoreEnabled=True)
def removeButtonFromTable(self, button):
"""
@@ -721,9 +732,7 @@ def readButtonTable(self):
count = self.tableWidget.rowCount()
if count > 0:
for row in range(count):
- buttons.append(
- self.buttonFromRow(row).name()
- )
+ buttons.append(self.buttonFromRow(row).name())
return buttons
def buttonsOrder(self):
@@ -759,8 +768,7 @@ def selectedColumns(self, reverseOrder=False):
:return: (list-of-int) ordered list of selected columns' indexes.
"""
return sorted(
- set(i.column() for i in self.selectedIndexes()),
- reverse=reverseOrder
+ set(i.column() for i in self.selectedIndexes()), reverse=reverseOrder
)
def selectRow(self, row):
@@ -882,8 +890,10 @@ def on_okPushButton_clicked(self):
msg = self.tr("Invalid input data: {r}").format(r=self.validate())
self.raiseWarning(msg)
return
- msg = self.tr("Current button has been modified and not saved. Would "
- "you like to save it?")
+ msg = self.tr(
+ "Current button has been modified and not saved. Would "
+ "you like to save it?"
+ )
title = self.tr("Unsaved modifications")
if self.buttonIsModified() and self.confirmAction(msg, title):
self.updateCurrentButton()
@@ -910,10 +920,7 @@ def state(self):
for idx, props in enumerate(state["buttons"]):
kws = props["keywords"]
state["buttons"][idx]["keywords"] = tuple(kws)
- return {
- "state": state,
- "order": self.buttonsOrder()
- }
+ return {"state": state, "order": self.buttonsOrder()}
def setState(self, state):
"""
@@ -930,15 +937,14 @@ def importSetup(self):
fd = QFileDialog()
filename = fd.getOpenFileName(
caption=self.tr("Import a DSGTools Button Setup (set of buttons)"),
- filter=self.tr("DSGTools Buttons Setup (*.setup)")
+ filter=self.tr("DSGTools Buttons Setup (*.setup)"),
)
filename = filename[0] if isinstance(filename, tuple) else filename
if not filename:
return
with open(filename, "r", encoding="utf-8") as fp:
state = json.load(fp)
- order = [b[0] for b in \
- sorted(state["order"].items(), key=lambda i: i[1])]
+ order = [b[0] for b in sorted(state["order"].items(), key=lambda i: i[1])]
state = state["state"]
# buttons' keywords are stored as tuple in order to be seriallizable
for idx, props in enumerate(state["buttons"]):
@@ -963,10 +969,10 @@ def importSetup(self):
self.setSetupName(self.setup.name())
self.setDescription(self.setup.description())
self.setDynamicShortcut(self.setup.dynamicShortcut())
- msg = self.tr('Setup "{0}" imported from "{1}"')\
- .format(self.setup.name(), filename)
- self.raiseWarning(
- msg, title=self.tr("Imported workflow"), lvl=Qgis.Success)
+ msg = self.tr('Setup "{0}" imported from "{1}"').format(
+ self.setup.name(), filename
+ )
+ self.raiseWarning(msg, title=self.tr("Imported workflow"), lvl=Qgis.Success)
@pyqtSlot(bool, name="on_exportPushButton_clicked")
def exportSetup(self):
@@ -983,7 +989,7 @@ def exportSetup(self):
fd = QFileDialog()
filename = fd.getSaveFileName(
caption=self.tr("Export setup - {0}").format(s.name()),
- filter=self.tr("DSGTools Buttons Setup (*.setup)")
+ filter=self.tr("DSGTools Buttons Setup (*.setup)"),
)
filename = filename[0] if isinstance(filename, tuple) else filename
if not filename:
@@ -992,8 +998,6 @@ def exportSetup(self):
fp.write(json.dumps(self.state(), sort_keys=True, indent=4))
res = os.path.exists(filename)
if res:
- msg = self.tr('Setup "{0}" exported to "{1}"')\
- .format(s.name(), filename)
- self.raiseWarning(
- msg, title=self.tr("Exported workflow"), lvl=Qgis.Success)
+ msg = self.tr('Setup "{0}" exported to "{1}"').format(s.name(), filename)
+ self.raiseWarning(msg, title=self.tr("Exported workflow"), lvl=Qgis.Success)
return res
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py
index e98d1cbd8..8cc2e6037 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/colorSelectorWidget.py
@@ -27,8 +27,9 @@
from qgis.PyQt.QtGui import QColor
from qgis.PyQt.QtWidgets import QWidget, QLineEdit
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), "colorSelectorWidget.ui"))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "colorSelectorWidget.ui")
+)
class ColorSelectorWidget(QWidget, FORM_CLASS):
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py
index b60634fcf..020721052 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/dsgCustomComboBox.py
@@ -25,9 +25,10 @@
from qgis.PyQt.QtWidgets import QCompleter, QComboBox
from qgis.PyQt.QtCore import QSortFilterProxyModel
+
class DsgCustomComboBox(QComboBox):
def __init__(self, parent=None):
- super(DsgCustomComboBox, self).__init__(parent = parent)
+ super(DsgCustomComboBox, self).__init__(parent=parent)
self.setFocusPolicy(Qt.StrongFocus)
self.setEditable(True)
@@ -47,23 +48,20 @@ def __init__(self, parent=None):
self.lineEdit().textEdited[str].connect(self.pFilterModel.setFilterFixedString)
self.completer.activated.connect(self.on_completer_activated)
-
- # on selection of an item from the completer, select the corresponding item from combobox
+ # on selection of an item from the completer, select the corresponding item from combobox
def on_completer_activated(self, text):
if text:
index = self.findText(text)
self.setCurrentIndex(index)
-
- # on model change, update the models of the filter and completer as well
+ # on model change, update the models of the filter and completer as well
def setModel(self, model):
super(DsgCustomComboBox, self).setModel(model)
self.pFilterModel.setSourceModel(model)
self.completer.setModel(self.pFilterModel)
-
# on model column change, update the model column of the filter and completer as well
def setModelColumn(self, column):
self.completer.setCompletionColumn(column)
self.pFilterModel.setFilterKeyColumn(column)
- super(DsgCustomComboBox, self).setModelColumn(column)
\ No newline at end of file
+ super(DsgCustomComboBox, self).setModelColumn(column)
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py
index 520976fd2..dbdd2c013 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/genericDialogLayout.py
@@ -25,13 +25,16 @@
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'genericDialogLayout.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "genericDialogLayout.ui")
+)
+
class GenericDialogLayout(QtWidgets.QDialog, FORM_CLASS):
"""
- Widget composed by an empty layout. It is supposed to be used as based for dynamic GUI.
+ Widget composed by an empty layout. It is supposed to be used as based for dynamic GUI.
"""
+
def __init__(self, parent=None):
"""
Class constructor.
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py
index a091aad4d..d5c3020f3 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/layerAndFieldSelectorWidget.py
@@ -26,8 +26,9 @@
from qgis.PyQt.QtCore import QSize
from qgis.PyQt.QtWidgets import QWidget
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), "layerAndFieldSelectorWidget.ui"))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "layerAndFieldSelectorWidget.ui")
+)
class LayerAndFieldSelectorWidget(QWidget, FORM_CLASS):
@@ -148,6 +149,5 @@ def resizeWidget(self):
mMapLayerComboBoxSize = self.mMapLayerComboBox.size()
mFieldComboBoxSize = self.mFieldComboBox.size()
minW = mMapLayerComboBoxSize.width() + mFieldComboBoxSize.width() + 5
- minH = (mMapLayerComboBoxSize.height() +
- mFieldComboBoxSize.height()) // 2
+ minH = (mMapLayerComboBoxSize.height() + mFieldComboBoxSize.height()) // 2
self.setMinimumSize(QSize(minW, minH))
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py
index 80784de34..5bac24671 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/progressWidget.py
@@ -27,8 +27,9 @@
from qgis.PyQt.QtWidgets import QProgressBar, QSizePolicy
import time
+
class ProgressWidget(QgsMessageBar):
- def __init__(self, min, max, message, parent=None, timeout = 1.5):
+ def __init__(self, min, max, message, parent=None, timeout=1.5):
"""
Constructs a progress widget
"""
@@ -37,24 +38,31 @@ def __init__(self, min, max, message, parent=None, timeout = 1.5):
self.max = max
sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)
if parent:
- self.setMinimumSize(parent.width(),40)
+ self.setMinimumSize(parent.width(), 40)
else:
- self.setMinimumSize(766,40)
+ self.setMinimumSize(766, 40)
self.setSizePolicy(sizePolicy)
self.progressBar = QProgressBar()
self.progressBar.setMinimum(min)
self.progressBar.setMaximum(max)
self.parent = parent
- self.msgBarItem = QgsMessageBarItem(self.tr("INFO: "), message, self.progressBar, level=Qgis.Info, duration=timeout, parent = self.parent)
+ self.msgBarItem = QgsMessageBarItem(
+ self.tr("INFO: "),
+ message,
+ self.progressBar,
+ level=Qgis.Info,
+ duration=timeout,
+ parent=self.parent,
+ )
self.pushItem(self.msgBarItem)
self.parent.repaint()
-
+
def initBar(self):
"""
Initializes the progress bar
"""
self.progressBar.setValue(0)
-
+
def step(self):
"""
Increments the progress bar
@@ -63,4 +71,4 @@ def step(self):
self.progressBar.setValue(value)
if value == self.max:
time.sleep(1)
- self.close()
\ No newline at end of file
+ self.close()
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py
index 047c8e24b..de5d0e8b2 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/shortcutChooserWidget.py
@@ -21,16 +21,20 @@
***************************************************************************/
"""
import os
+
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtGui import QKeySequence
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'shortcutChooserWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "shortcutChooserWidget.ui")
+)
+
class ShortcutChooserWidget(QtWidgets.QWidget, FORM_CLASS):
keyPressed = pyqtSignal()
+
def __init__(self, parent=None):
"""
Initializates ShortcutChooserWidget
@@ -38,14 +42,14 @@ def __init__(self, parent=None):
super(ShortcutChooserWidget, self).__init__(parent)
self.resetVariables()
self.setupUi(self)
-
+
@pyqtSlot(bool)
def on_assignShortcutPushButton_clicked(self):
"""
After button is clicked, focus is needed to use keyPressEvent and keyReleaseEvent
"""
self.setFocus()
-
+
@pyqtSlot(bool)
def on_assignShortcutPushButton_toggled(self, toggled):
"""
@@ -53,17 +57,17 @@ def on_assignShortcutPushButton_toggled(self, toggled):
"""
if toggled:
self.resetVariables()
- self.assignShortcutPushButton.setText(self.tr('Enter Value'))
-
- @pyqtSlot(bool, name = 'on_clearPushButton_clicked')
+ self.assignShortcutPushButton.setText(self.tr("Enter Value"))
+
+ @pyqtSlot(bool, name="on_clearPushButton_clicked")
def clearAll(self):
"""
Clears push button and also resets self.modifiers and self.keys
"""
self.assignShortcutPushButton.setChecked(False)
- self.assignShortcutPushButton.setText(self.tr('Assign Shortcut'))
+ self.assignShortcutPushButton.setText(self.tr("Assign Shortcut"))
self.resetVariables()
-
+
def resetVariables(self):
"""
Resets self.modifiers, self.key and self.keySequence to 0
@@ -73,8 +77,7 @@ def resetVariables(self):
self.keySequence = 0
def keyPressEvent(self, event):
- """
- """
+ """ """
if not self.assignShortcutPushButton.isChecked():
super(ShortcutChooserWidget, self).keyPressEvent(event)
return
@@ -121,7 +124,7 @@ def keyReleaseEvent(self, event):
self.assignShortcutPushButton.setChecked(False)
self.updateShortcutText()
self.setShortcut(self.keySequence)
-
+
def setEnabled(self, enabled):
if not enabled:
self.clearAll()
@@ -130,15 +133,21 @@ def setEnabled(self, enabled):
def setShortcut(self, shortcut):
self.keySequence = QKeySequence(shortcut)
self.assignShortcutPushButton.setChecked(False)
- self.assignShortcutPushButton.setText(self.keySequence.toString(format = QKeySequence.NativeText))
-
- def getShortcut(self, asQKeySequence = False):
+ self.assignShortcutPushButton.setText(
+ self.keySequence.toString(format=QKeySequence.NativeText)
+ )
+
+ def getShortcut(self, asQKeySequence=False):
if asQKeySequence:
return self.keySequence
else:
return int(self.keySequence)
def updateShortcutText(self):
- self.keySequence = QKeySequence(self.modifiers+self.key)
- #this uses QKeySequence.NativeText to show in the interface. To store data, no filter should be provided
- self.assignShortcutPushButton.setText(self.tr('Input: {0}').format(self.keySequence.toString(format = QKeySequence.NativeText)))
\ No newline at end of file
+ self.keySequence = QKeySequence(self.modifiers + self.key)
+ # this uses QKeySequence.NativeText to show in the interface. To store data, no filter should be provided
+ self.assignShortcutPushButton.setText(
+ self.tr("Input: {0}").format(
+ self.keySequence.toString(format=QKeySequence.NativeText)
+ )
+ )
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py
index d9f6c7117..2ee4874bb 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapChooserWidget.py
@@ -28,29 +28,37 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'snapChooserWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "snapChooserWidget.ui")
+)
+
class SnapChooserWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, layerList, parameterDict = {}, parent = None):
+ def __init__(self, layerList, parameterDict={}, parent=None):
"""Constructor."""
- super(SnapChooserWidget, self).__init__(parent = parent)
+ super(SnapChooserWidget, self).__init__(parent=parent)
self.setupUi(self)
self.layerList = layerList
self.layerList.sort()
- self.layerComboBox.addItem(self.tr('Select a layer'))
+ self.layerComboBox.addItem(self.tr("Select a layer"))
self.layerComboBox.addItems(self.layerList)
- self.validKeys = ['layerName', 'snap']
+ self.validKeys = ["layerName", "snap"]
self.snapDoubleSpinBox.setDecimals(20)
self.snapDoubleSpinBox.setMaximum(1000000)
self.snapDoubleSpinBox.setMinimum(0.00000000000000001)
if parameterDict != {}:
self.populateInterface(parameterDict)
-
+
def refresh(self, blackList):
currentText = self.layerComboBox.currentText()
refreshList = [i for i in self.layerList if i not in blackList]
@@ -58,24 +66,24 @@ def refresh(self, blackList):
refreshList.append(currentText)
refreshList.sort()
self.layerComboBox.clear()
- self.layerComboBox.addItem(self.tr('Select a layer'))
+ self.layerComboBox.addItem(self.tr("Select a layer"))
self.layerComboBox.addItems(refreshList)
- idx = self.layerComboBox.findText(currentText, flags = Qt.MatchExactly)
+ idx = self.layerComboBox.findText(currentText, flags=Qt.MatchExactly)
self.layerComboBox.setCurrentIndex(idx)
-
+
def getSelectedItem(self):
if self.layerComboBox.currentIndex() > 0:
return self.layerComboBox.currentText()
else:
return None
-
+
def clearAll(self):
"""
Clears all widget information
"""
self.layerComboBox.clear()
self.snapDoubleSpinBox.setValue(1.0)
-
+
def getParameterDict(self):
"""
Components:
@@ -85,8 +93,8 @@ def getParameterDict(self):
if not self.validate():
raise Exception(self.invalidatedReason())
parameterDict = dict()
- parameterDict['layerName'] = self.layerComboBox.currentText()
- parameterDict['snap'] = self.snapDoubleSpinBox.value()
+ parameterDict["layerName"] = self.layerComboBox.currentText()
+ parameterDict["snap"] = self.snapDoubleSpinBox.value()
return parameterDict
def populateInterface(self, parameterDict):
@@ -95,14 +103,15 @@ def populateInterface(self, parameterDict):
"""
if parameterDict:
if not self.validateJson(parameterDict):
- raise Exception(self.tr('Invalid Snap Chooser Widget json config!'))
- #set layer combo
- idx = self.layerComboBox.findText(parameterDict['layerName'], flags = Qt.MatchExactly)
+ raise Exception(self.tr("Invalid Snap Chooser Widget json config!"))
+ # set layer combo
+ idx = self.layerComboBox.findText(
+ parameterDict["layerName"], flags=Qt.MatchExactly
+ )
self.layerComboBox.setCurrentIndex(idx)
- #set snap double spin box
- self.snapDoubleSpinBox.setValue(parameterDict['snap'])
-
-
+ # set snap double spin box
+ self.snapDoubleSpinBox.setValue(parameterDict["snap"])
+
def validateJson(self, inputJson):
"""
Validates input json
@@ -123,14 +132,14 @@ def validate(self):
if self.snapDoubleSpinBox.value() <= 0:
return False
return True
-
+
def invalidatedReason(self):
"""
Error reason
"""
- msg = ''
+ msg = ""
if self.layerComboBox.currentIndex() < 1:
- msg += self.tr('Invalid layer!\n')
+ msg += self.tr("Invalid layer!\n")
if self.snapDoubleSpinBox.value() <= 0:
- msg += self.tr('Invalid snap value!\n')
- return msg
\ No newline at end of file
+ msg += self.tr("Invalid snap value!\n")
+ return msg
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py
index 770af325e..f3e5efd19 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/snapWithLayerChooserWidget.py
@@ -31,11 +31,18 @@
from qgis.PyQt.QtCore import QSettings, Qt, pyqtSlot
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
-from qgis.PyQt.QtWidgets import (QApplication, QFileDialog, QListWidgetItem,
- QMenu, QMessageBox)
+from qgis.PyQt.QtWidgets import (
+ QApplication,
+ QFileDialog,
+ QListWidgetItem,
+ QMenu,
+ QMessageBox,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "snapWithLayerChooserWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'snapWithLayerChooserWidget.ui'))
class SnapWithLayerChooserWidget(QtWidgets.QWidget, FORM_CLASS):
def __init__(self, parameterDict={}, blackList=None, parent=None):
@@ -44,14 +51,13 @@ def __init__(self, parameterDict={}, blackList=None, parent=None):
self.parent = parent
self.setupUi(self)
self.project = QgsProject.instance()
- self.validKeys = ['layer', 'layerName', 'snap']
+ self.validKeys = ["layer", "layerName", "snap"]
self.snapDoubleSpinBox.setDecimals(20)
self.snapDoubleSpinBox.setMaximum(1000000)
self.snapDoubleSpinBox.setMinimum(0.00000000000000001)
self.layerComboBox.setFilters(
- QgsMapLayerProxyModel.HasGeometry |
- QgsMapLayerProxyModel.VectorLayer
- )
+ QgsMapLayerProxyModel.HasGeometry | QgsMapLayerProxyModel.VectorLayer
+ )
if blackList is not None:
self.layerComboBox.setExceptedLayerList(blackList)
if parameterDict != {}:
@@ -82,9 +88,9 @@ def getParameterDict(self):
if not self.validate():
raise Exception(self.invalidatedReason())
parameterDict = dict()
- parameterDict['layer'] = self.layerComboBox.currentLayer()
- parameterDict['layerName'] = self.layerComboBox.currentLayer().name()
- parameterDict['snap'] = self.snapDoubleSpinBox.value()
+ parameterDict["layer"] = self.layerComboBox.currentLayer()
+ parameterDict["layerName"] = self.layerComboBox.currentLayer().name()
+ parameterDict["snap"] = self.snapDoubleSpinBox.value()
return parameterDict
def populateInterface(self, parameterDict):
@@ -93,17 +99,14 @@ def populateInterface(self, parameterDict):
"""
if parameterDict:
if not self.validateJson(parameterDict):
- raise Exception(
- self.tr('Invalid Snap Chooser Widget json config!')
- )
- #set layer combo
+ raise Exception(self.tr("Invalid Snap Chooser Widget json config!"))
+ # set layer combo
idx = self.layerComboBox.findText(
- parameterDict['layerName'],
- flags=Qt.MatchExactly
- )
+ parameterDict["layerName"], flags=Qt.MatchExactly
+ )
self.layerComboBox.setCurrentIndex(idx)
- #set snap double spin box
- self.snapDoubleSpinBox.setValue(parameterDict['snap'])
+ # set snap double spin box
+ self.snapDoubleSpinBox.setValue(parameterDict["snap"])
def validateJson(self, inputJson):
"""
@@ -125,14 +128,14 @@ def validate(self):
# if self.snapDoubleSpinBox.value() <= 0:
# return False
return True
-
+
def invalidatedReason(self):
"""
Error reason
"""
- msg = ''
+ msg = ""
if self.layerComboBox.currentIndex() < 1:
- msg += self.tr('Invalid layer!\n')
+ msg += self.tr("Invalid layer!\n")
if self.snapDoubleSpinBox.value() <= 0:
- msg += self.tr('Invalid snap value!\n')
+ msg += self.tr("Invalid snap value!\n")
return msg
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py
index 627aa5e0e..d555fa3bc 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/switchButton.py
@@ -27,12 +27,14 @@
from qgis.PyQt.QtCore import Qt, pyqtSlot, pyqtSignal
from qgis.PyQt.QtWidgets import QLabel, QWidget, QSlider, QHBoxLayout
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'switchButton.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "switchButton.ui")
+)
+
class SwitchButton(QWidget, FORM_CLASS):
stateChanged = pyqtSignal(int)
-
+
def __init__(self, parent=None, stateA=None, stateB=None):
"""
Class constructor.
@@ -53,15 +55,15 @@ def __init__(self, parent=None, stateA=None, stateB=None):
def setStateAName(self, name):
"""
- Updates the name for state A.
+ Updates the name for state A.
:param name: (str) state A's name
"""
self.stateA = name
self.stateALabel.setText(name)
-
+
def setStateBName(self, name):
"""
- Updates the name for state B.
+ Updates the name for state B.
:param name: (str) state B's name
"""
self.stateB = name
@@ -72,7 +74,7 @@ def currentState(self):
Reads state defined by current slider position - read from GUI.
:return: (int) current state (0 for A, 1 for B).
"""
- return int(self.slider.value() >= (self.min_ + self.max_)/2)
+ return int(self.slider.value() >= (self.min_ + self.max_) / 2)
def state(self):
"""
@@ -87,10 +89,7 @@ def setState(self, state):
:return: (int) state to be set (0 for A, 1 for B).
"""
self._state = state
- self.slider.setValue({
- 0: self.min_,
- 1: self.max_
- }[state])
+ self.slider.setValue({0: self.min_, 1: self.max_}[state])
def toggleState(self):
"""
@@ -98,16 +97,13 @@ def toggleState(self):
"""
self._state = self.state() ^ 1
self.setState(self._state)
-
+
def stateName(self):
"""
Retrieves the name for current defined state.
:return: (str) defined state's name (exposed text on GUI).
"""
- return {
- 0: self.stateA,
- 1: self.stateB
- }[self.state()]
+ return {0: self.stateA, 1: self.stateB}[self.state()]
@pyqtSlot()
def updateState(self):
@@ -120,7 +116,7 @@ def updateState(self):
self.setState(newState)
if prevState != newState:
self.stateChanged.emit(newState)
-
+
@pyqtSlot(int)
def valueChanged(self, value):
"""
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py
index 3a2192546..933980625 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/textBrowserDialog.py
@@ -27,8 +27,10 @@
from qgis.PyQt.QtCore import pyqtSlot
from qgis.PyQt.QtWidgets import QDialog, QFileDialog
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'textBrowserDialog.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "textBrowserDialog.ui")
+)
+
class TextBrowserDialog(QDialog, FORM_CLASS):
def __init__(self, html="", parent=None):
@@ -62,7 +64,7 @@ def clearHtml(self):
"""
self.textBrowser.setHtml("")
- @pyqtSlot(bool, name='on_savePushButton_clicked')
+ @pyqtSlot(bool, name="on_savePushButton_clicked")
def saveHtml(self):
"""
Exports text.
@@ -70,16 +72,19 @@ def saveHtml(self):
"""
html = self.textBrowser.toHtml()
fd = QFileDialog()
- filename = fd.getSaveFileName(caption=self.tr('Select a Path to Log'),filter=self.tr('HTML Files (*.html)'))
+ filename = fd.getSaveFileName(
+ caption=self.tr("Select a Path to Log"),
+ filter=self.tr("HTML Files (*.html)"),
+ )
filename = filename[0] if isinstance(filename, tuple) else filename
if filename:
- with open(filename, 'w', encoding='utf-8') as f:
+ with open(filename, "w", encoding="utf-8") as f:
f.write(html)
return filename
- @pyqtSlot(bool, name='on_closePushButton_clicked')
+ @pyqtSlot(bool, name="on_closePushButton_clicked")
def exit(self):
"""
Closes dialog.
"""
- self.close()
\ No newline at end of file
+ self.close()
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton
index 6747a049f..0b9d3c04d 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton
@@ -103,4 +103,4 @@ class Toggle(QCheckBox):
@pulse_radius.setter
def pulse_radius(self, pos):
self._pulse_radius = pos
- self.update()
\ No newline at end of file
+ self.update()
diff --git a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py
index 1b2b0a0ab..23677eff1 100644
--- a/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py
+++ b/DsgTools/gui/CustomWidgets/BasicInterfaceWidgets/toggleButton.py
@@ -1,16 +1,19 @@
-from qgis.PyQt.QtCore import (Qt,
- QSize,
- QPoint,
- QRectF,
- QPointF,
- pyqtSlot,
- QEasingCurve,
- pyqtProperty,
- QPropertyAnimation,
- QSequentialAnimationGroup)
+from qgis.PyQt.QtCore import (
+ Qt,
+ QSize,
+ QPoint,
+ QRectF,
+ QPointF,
+ pyqtSlot,
+ QEasingCurve,
+ pyqtProperty,
+ QPropertyAnimation,
+ QSequentialAnimationGroup,
+)
from qgis.PyQt.QtWidgets import QCheckBox
from qgis.PyQt.QtGui import QPen, QColor, QBrush, QPainter, QPaintEvent
+
class Toggle(QCheckBox):
# This widget was originally implemented by Martin Fitzpatrick
# @ https://github.com/learnpyqt/python-qtwidgets
@@ -18,12 +21,14 @@ class Toggle(QCheckBox):
_transparent_pen = QPen(Qt.transparent)
_light_grey_pen = QPen(Qt.lightGray)
- def __init__(self,
- parent=None,
- bar_color=Qt.gray,
- checked_color="#00B0FF",
- handle_color=Qt.white,
- labels=None):
+ def __init__(
+ self,
+ parent=None,
+ bar_color=Qt.gray,
+ checked_color="#00B0FF",
+ handle_color=Qt.white,
+ labels=None,
+ ):
super().__init__(parent)
self.setLabels(labels)
# Save our properties on the object via self, so we can access them later
@@ -62,7 +67,7 @@ def getLabel(self, state: bool):
"""
Gets the label to be displyed on the button accordingly to its state.
:param state: (bool) whether this button is toggle (checked).
- :return: (str) label to be displayed
+ :return: (str) label to be displayed
"""
if self._labels is None:
return ""
@@ -78,8 +83,7 @@ def paintEvent(self, e: QPaintEvent):
p.setPen(self._transparent_pen)
barRect = QRectF(
- 0, 0,
- contRect.width() - handleRadius, 0.40 * contRect.height()
+ 0, 0, contRect.width() - handleRadius, 0.40 * contRect.height()
)
barRect.moveCenter(contRect.center())
rounding = barRect.height() / 2
@@ -100,9 +104,7 @@ def paintEvent(self, e: QPaintEvent):
p.setPen(self._light_grey_pen)
p.setBrush(self._handle_brush)
- p.drawEllipse(
- QPointF(xPos, barRect.center().y()),
- handleRadius, handleRadius)
+ p.drawEllipse(QPointF(xPos, barRect.center().y()), handleRadius, handleRadius)
p.end()
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py
index 6c2654154..2c21f5f18 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/connectionComboBox.py
@@ -27,20 +27,28 @@
from qgis.PyQt.QtGui import QCursor
from qgis.core import QgsMessageLog, Qgis
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import DsgCustomComboBox
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.dsgCustomComboBox import (
+ DsgCustomComboBox,
+)
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import DatasourceInfoTable
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import (
+ DatasourceInfoTable,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'connectionComboBox.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "connectionComboBox.ui")
+)
+
+
class ConnectionComboBox(QtWidgets.QWidget, FORM_CLASS):
connectionChanged = pyqtSignal()
dbChanged = pyqtSignal(AbstractDb)
problemOccurred = pyqtSignal(str)
+
def __init__(self, parent=None, isStatic=False):
"""
Class constructor.
@@ -53,19 +61,27 @@ def __init__(self, parent=None, isStatic=False):
self.abstractDb = None
self.abstractDbFactory = DbFactory()
self.serverAbstractDb = None
- self.displayDict = {'2.1.3':'EDGV 2.1.3', '2.1.3 Pro':'EDGV 2.1.3 Pro','FTer_2a_Ed':'EDGV FTer 2a Ed', 'Non_EDGV':self.tr('Other database model'), '3.0':'EDGV 3.0'}
+ self.displayDict = {
+ "2.1.3": "EDGV 2.1.3",
+ "2.1.3 Pro": "EDGV 2.1.3 Pro",
+ "FTer_2a_Ed": "EDGV FTer 2a Ed",
+ "Non_EDGV": self.tr("Other database model"),
+ "3.0": "EDGV 3.0",
+ }
self.instantiateAbstractDb = False
self.isStatic = isStatic
if self.isStatic:
from DsgTools.gui.ServerTools.viewServers import ViewServersStatic
+
self.viewServers = ViewServersStatic()
else:
from DsgTools.gui.ServerTools.viewServers import ViewServers
+
self.viewServers = ViewServers()
self.viewServers.defaultChanged.connect(self.loadServerAbstractDb)
- self.connectionSelectorComboBox.addItem(self.tr('Select database'))
+ self.connectionSelectorComboBox.addItem(self.tr("Select database"))
self.loadServerAbstractDb()
-
+
def __del__(self):
"""
Destructor
@@ -73,7 +89,7 @@ def __del__(self):
if self.serverAbstractDb is not None:
self.serverAbstractDb.closeDatabase()
del self
-
+
def loadServerAbstractDb(self):
"""
Checks if there is a default db in self.viewServers . If there isn't one, disables connection combo
@@ -82,12 +98,22 @@ def loadServerAbstractDb(self):
self.connectionSelectorComboBox.setEnabled(False)
else:
self.connectionSelectorComboBox.setEnabled(True)
- (_, host, port, user, password) = self.viewServers.getDefaultConnectionParameters()
- serverAbstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS)
- serverAbstractDb.connectDatabaseWithParameters(host, port, 'postgres', user, password)
+ (
+ _,
+ host,
+ port,
+ user,
+ password,
+ ) = self.viewServers.getDefaultConnectionParameters()
+ serverAbstractDb = self.abstractDbFactory.createDbFactory(
+ DsgEnums.DriverPostGIS
+ )
+ serverAbstractDb.connectDatabaseWithParameters(
+ host, port, "postgres", user, password
+ )
self.setServerDb(serverAbstractDb)
serverAbstractDb.closeDatabase()
-
+
def closeDatabase(self):
if self.abstractDb is not None:
self.abstractDb.closeDatabase()
@@ -95,16 +121,18 @@ def closeDatabase(self):
def clear(self):
self.connectionSelectorComboBox.clear()
self.closeDatabase()
-
+
def setServerDb(self, serverAbstractDb):
self.serverAbstractDb = serverAbstractDb
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
if self.serverAbstractDb:
- dbList = self.serverAbstractDb.getEDGVDbsFromServer(parentWidget = self.parent, getDatabaseVersions = False)
+ dbList = self.serverAbstractDb.getEDGVDbsFromServer(
+ parentWidget=self.parent, getDatabaseVersions=False
+ )
dbList.sort()
self.clear()
- self.connectionSelectorComboBox.addItem(self.tr('Select Database'))
+ self.connectionSelectorComboBox.addItem(self.tr("Select Database"))
self.addItems(dbList)
else:
self.clear()
@@ -113,9 +141,9 @@ def setServerDb(self, serverAbstractDb):
return
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
QApplication.restoreOverrideCursor()
-
+
def addItems(self, items):
itemList = []
if items == []:
@@ -126,19 +154,19 @@ def addItems(self, items):
version = item[1]
else:
version = self.displayDict[item[1]]
- newText = item[0] + ' ({0})'.format(version)
+ newText = item[0] + " ({0})".format(version)
itemList.append(newText)
if itemList == []:
itemList = items
self.connectionSelectorComboBox.addItems(itemList)
-
+
def currentDb(self):
if self.connectionSelectorComboBox.currentIndex() == 0:
- return ''
+ return ""
else:
- return self.connectionSelectorComboBox.currentText().split(' (')[0]
-
- @pyqtSlot(int, name = 'on_connectionSelectorComboBox_currentIndexChanged')
+ return self.connectionSelectorComboBox.currentText().split(" (")[0]
+
+ @pyqtSlot(int, name="on_connectionSelectorComboBox_currentIndexChanged")
def loadDatabase(self, idx):
"""
Loads the selected database
@@ -148,18 +176,31 @@ def loadDatabase(self, idx):
self.closeDatabase()
if self.serverAbstractDb is not None and idx > 0:
if not self.instantiateAbstractDb:
- self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS)
- (host, port, user, password) = self.serverAbstractDb.getDatabaseParameters()
- dbName = self.connectionSelectorComboBox.itemText(idx).split(' (')[0]
- self.abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password)
+ self.abstractDb = self.abstractDbFactory.createDbFactory(
+ DsgEnums.DriverPostGIS
+ )
+ (
+ host,
+ port,
+ user,
+ password,
+ ) = self.serverAbstractDb.getDatabaseParameters()
+ dbName = self.connectionSelectorComboBox.itemText(idx).split(" (")[
+ 0
+ ]
+ self.abstractDb.connectDatabaseWithParameters(
+ host, port, dbName, user, password
+ )
self.abstractDb.checkAndOpenDb()
self.dbChanged.emit(self.abstractDb)
self.connectionChanged.emit()
except Exception as e:
self.closeDatabase()
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
-
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
+
@pyqtSlot(bool)
def on_serverPushButton_clicked(self):
self.viewServers.exec_()
@@ -178,7 +219,13 @@ def databaseExists(self):
"""
# for files, it is only necessary to check if file exists and is not empty.
if self.abstractDb:
- _, host, port, user, password = self.viewServers.getDefaultConnectionParameters()
+ (
+ _,
+ host,
+ port,
+ user,
+ password,
+ ) = self.viewServers.getDefaultConnectionParameters()
database = self.currentDb()
return self.abstractDb.testCredentials(host, port, database, user, password)
return False
@@ -193,23 +240,23 @@ def validate(self):
# check a valid server name
# check if datasource is a valid name and if it already exists into selected server
if not self.currentDb() or not self.abstractDb:
- return self.tr('Invalid datasource.')
+ return self.tr("Invalid datasource.")
else:
# check if the connection is a valid connection
if not self.serverIsValid():
- return self.tr('Invalid connection to server.')
+ return self.tr("Invalid connection to server.")
# check if it exists
if not self.databaseExists():
- return self.tr('Database {0} does not exist.').format(self.currentDb())
+ return self.tr("Database {0} does not exist.").format(self.currentDb())
# if all tests were positive, widget has a valid selection
- return ''
+ return ""
def isValid(self):
"""
Validates selection.
:return: (bool) validation status.
"""
- return self.validate() == ''
+ return self.validate() == ""
# msg = self.validate()
# if msg:
# # if an invalidation reason was given, warn user and nothing else.
@@ -229,5 +276,5 @@ def setHost(self, hostname):
Sets a hostname as selected from its name.
:param serverName: (str) host to be set as selected.
"""
- # method needs to be ported to 'non-static' view server!
+ # method needs to be ported to 'non-static' view server!
self.viewServers.setHost(hostname)
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py
index 53b00c704..dfd00186b 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/databaseFileLineEdit.py
@@ -31,10 +31,14 @@
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb
from DsgTools.core.dsgEnums import DsgEnums
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import DatasourceInfoTable
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceInfoTable import (
+ DatasourceInfoTable,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "databaseFileLineEdit.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'databaseFileLineEdit.ui'))
class DatabaseFileLineEdit(QtWidgets.QWidget, FORM_CLASS):
connectionChanged = pyqtSignal()
@@ -53,9 +57,15 @@ def __init__(self, parent=None):
self.abstractDb = None
self.abstractDbFactory = DbFactory()
self.serverAbstractDb = None
- self.displayDict = {'2.1.3':'EDGV 2.1.3', '2.1.3 Pro':'EDGV 2.1.3 Pro', 'FTer_2a_Ed':'EDGV FTer 2a Ed', 'Non_EDGV':self.tr('Other database model'), '3.0':'EDGV 3.0'}
+ self.displayDict = {
+ "2.1.3": "EDGV 2.1.3",
+ "2.1.3 Pro": "EDGV 2.1.3 Pro",
+ "FTer_2a_Ed": "EDGV FTer 2a Ed",
+ "Non_EDGV": self.tr("Other database model"),
+ "3.0": "EDGV 3.0",
+ }
self.instantiateAbstractDb = False
- self.connectionSelectorLineEdit.lineEdit.setText(self.tr('Select datasource'))
+ self.connectionSelectorLineEdit.lineEdit.setText(self.tr("Select datasource"))
self.connectionSelectorLineEdit.lineEdit.setReadOnly(True)
def closeDatabase(self):
@@ -70,20 +80,20 @@ def clear(self):
Unsets any selected database and clears db directory, if necessary.
"""
self.connectionSelectorLineEdit.lineEdit.clear()
- self.connectionSelectorLineEdit.lineEdit.setText(self.tr('Select datasource'))
+ self.connectionSelectorLineEdit.lineEdit.setText(self.tr("Select datasource"))
self.closeDatabase()
-
+
def currentDb(self):
"""
Returns current loaded datasource name, if any.
:return: (str) current loaded datasource name; an empty string if no ds is selected.
"""
text = self.connectionSelectorLineEdit.lineEdit.text()
- if text == self.tr('Select datasource'):
+ if text == self.tr("Select datasource"):
return None
else:
- dirSplit = '/' if '/' in text else '\\'
- text = text.split(dirSplit)[-1].split('.')[0] if text else ''
+ dirSplit = "/" if "/" in text else "\\"
+ text = text.split(dirSplit)[-1].split(".")[0] if text else ""
return text
def serverIsValid(self):
@@ -100,7 +110,7 @@ def databaseExists(self):
# for files, it is only necessary to check if file exists and is not empty.
return bool(self.abstractDb)
- @pyqtSlot(str, name = 'on_lineEdit_textChanged')
+ @pyqtSlot(str, name="on_lineEdit_textChanged")
def loadDatabase(self, currentText):
"""
Loads the selected database
@@ -117,8 +127,10 @@ def loadDatabase(self, currentText):
self.connectionChanged.emit()
except Exception as e:
self.closeDatabase()
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
def validate(self):
"""
@@ -130,23 +142,23 @@ def validate(self):
# check a valid server name
# check if datasource is a valid name and if it already exists into selected server
if not self.currentDb() or not self.abstractDb:
- return self.tr('Invalid datasource.')
+ return self.tr("Invalid datasource.")
else:
# check if the connection is a valid connection
if not self.serverIsValid():
- return self.tr('Invalid connection to server.')
+ return self.tr("Invalid connection to server.")
# check if it exists
if not self.databaseExists():
- return self.tr('Database {0} does not exist.').format(self.currentDb())
+ return self.tr("Database {0} does not exist.").format(self.currentDb())
# if all tests were positive, widget has a valid selection
- return ''
+ return ""
def isValid(self):
"""
Validates selection.
:return: (bool) validation status.
"""
- return self.validate() == ''
+ return self.validate() == ""
@pyqtSlot(bool)
def on_infoPushButton_clicked(self):
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py
index 087e248c0..82d2a1403 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newConnectionLineEdit.py
@@ -24,6 +24,7 @@
from qgis.PyQt.QtWidgets import QWidget, QFileDialog
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal
from qgis.PyQt import uic
+
# from qgis.utils import iface
from qgis.core import Qgis, QgsMessageLog
@@ -33,14 +34,18 @@
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'newConnectionLineEdit.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newConnectionLineEdit.ui")
+)
+
class NewConnectionLineEdit(QWidget, FORM_CLASS):
"""
Class designed to control generic behaviors of a widget able to
retrieve parameters for a PostGIS database creation.
"""
- # signals to keep
+
+ # signals to keep
connectionChanged = pyqtSignal()
dbChanged = pyqtSignal(AbstractDb)
problemOccurred = pyqtSignal(str)
@@ -56,9 +61,11 @@ def __init__(self, parent=None, isStatic=False):
self.isStatic = isStatic
if self.isStatic:
from DsgTools.gui.ServerTools.viewServers import ViewServersStatic
+
self.viewServers = ViewServersStatic()
else:
from DsgTools.gui.ServerTools.viewServers import ViewServers
+
self.viewServers = ViewServers()
self.fillEdgvVersions()
self.reset()
@@ -68,13 +75,13 @@ def connectSignals(self):
Connects all signals.
"""
self.dsLineEdit.textChanged.connect(self.loadDatabase)
- dsChangedAlias = lambda : self.dbChanged.emit(None)
+ dsChangedAlias = lambda: self.dbChanged.emit(None)
self.edgvComboBox.currentIndexChanged.connect(dsChangedAlias)
self.mQgsProjectionSelectionWidget.crsChanged.connect(dsChangedAlias)
def fillEdgvVersions(self):
"""
- Populates EDGV combo box with available versions.
+ Populates EDGV combo box with available versions.
"""
versions = [
self.tr("EDGV Version..."),
@@ -82,7 +89,7 @@ def fillEdgvVersions(self):
"EDGV 2.1.3 F Ter",
"EDGV 2.1.3 Pro",
"EDGV 3.0",
- "EDGV 3.0 Pro"
+ "EDGV 3.0 Pro",
]
self.edgvComboBox.addItems(versions)
@@ -92,7 +99,7 @@ def currentDb(self):
:return: (str) datasource path.
"""
ds = self.dsLineEdit.text()
- return ds if not ds is None and ds != self.tr("New Database") else ''
+ return ds if not ds is None and ds != self.tr("New Database") else ""
def edgvVersion(self):
"""
@@ -100,7 +107,7 @@ def edgvVersion(self):
:return: (str) EDGV version.
"""
edgv = self.edgvComboBox.currentText()
- return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else ''
+ return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else ""
def authId(self):
"""
@@ -108,7 +115,7 @@ def authId(self):
:return: (str) EDGV version.
"""
crs = self.crs()
- return crs.authid() if not crs is None and crs.isValid() else ''
+ return crs.authid() if not crs is None and crs.isValid() else ""
def crs(self):
"""
@@ -120,7 +127,7 @@ def crs(self):
def reset(self):
"""
- Clears all GUI selections.
+ Clears all GUI selections.
"""
self.dsLineEdit.setText(self.tr("New Database"))
self.edgvComboBox.setCurrentIndex(0)
@@ -146,7 +153,13 @@ def databaseExists(self):
"""
Checks if database exists.
"""
- _, host, port, user, password = self.viewServers.getDefaultConnectionParameters()
+ (
+ _,
+ host,
+ port,
+ user,
+ password,
+ ) = self.viewServers.getDefaultConnectionParameters()
database = self.currentDb()
# get a PostGIS database instance to check if database exists
abstractDb = DbFactory().createDbFactory(DsgEnums.DriverPostGIS)
@@ -167,8 +180,10 @@ def loadDatabase(self, currentText):
# if msg:
# raise Exception(msg)
except Exception as e:
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
def validate(self):
"""
@@ -182,22 +197,24 @@ def validate(self):
# check a valid server name
# check if datasource is a valid name and if it already exists into selected server
if not self.currentDb() or " " in self.currentDb():
- return self.tr('Invalid datasource (is there a blank space on it?).')
+ return self.tr("Invalid datasource (is there a blank space on it?).")
else:
# check if the connection is a valid connection
if not self.serverIsValid():
- return self.tr('Invalid connection to server.')
+ return self.tr("Invalid connection to server.")
# check if it exists
if self.databaseExists():
- return self.tr('Database {0} already exists into selected server.').format(self.currentDb())
+ return self.tr(
+ "Database {0} already exists into selected server."
+ ).format(self.currentDb())
# check if a valid EDGV version was selected
if not self.edgvVersion():
- return self.tr('Invalid EDGV version.')
+ return self.tr("Invalid EDGV version.")
# check if a valid projection was selected
- if not self.crs() or 'EPSG' not in self.authId():
- return self.tr('Invalid CRS.')
+ if not self.crs() or "EPSG" not in self.authId():
+ return self.tr("Invalid CRS.")
# if all tests were positive, widget has a valid selection
- return ''
+ return ""
def isValid(self):
"""
@@ -209,7 +226,7 @@ def isValid(self):
# if msg:
# # if an invalidation reason was given, warn user and nothing else.
# iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5)
- return msg == ''
+ return msg == ""
def selectDatasource(self):
"""
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py
index ce4ad9c71..428cb4974 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/AdvancedConnectionWidgets/newDatabaseLineEdit.py
@@ -24,6 +24,7 @@
from qgis.PyQt.QtWidgets import QWidget, QFileDialog
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QDir
from qgis.PyQt import uic
+
# from qgis.utils import iface
from qgis.core import Qgis, QgsMessageLog
@@ -31,14 +32,18 @@
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'newDatabaseLineEdit.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newDatabaseLineEdit.ui")
+)
+
class NewDatabaseLineEdit(QWidget, FORM_CLASS):
"""
Class designed to control generic behaviors of a widget able to
retrieve parameters for a PostGIS database creation.
"""
- # signals to keep
+
+ # signals to keep
connectionChanged = pyqtSignal()
dbChanged = pyqtSignal(AbstractDb)
problemOccurred = pyqtSignal(str)
@@ -49,8 +54,8 @@ def __init__(self, parent=None):
"""
super(NewDatabaseLineEdit, self).__init__()
self.setupUi(self)
- self.caption = ''
- self.filter = ''
+ self.caption = ""
+ self.filter = ""
self.fillEdgvVersions()
self.connectSignals()
self.reset()
@@ -64,7 +69,7 @@ def connectSignals(self):
def fillEdgvVersions(self):
"""
- Populates EDGV combo box with available versions.
+ Populates EDGV combo box with available versions.
"""
versions = [
self.tr("EDGV Version..."),
@@ -72,7 +77,7 @@ def fillEdgvVersions(self):
"EDGV 2.1.3 F Ter",
"EDGV 2.1.3 Pro",
"EDGV 3.0",
- "EDGV 3.0 Pro"
+ "EDGV 3.0 Pro",
]
self.edgvComboBox.addItems(versions)
@@ -82,7 +87,7 @@ def currentDb(self):
:return: (str) datasource path.
"""
ds = self.dsLineEdit.text()
- return ds if not ds is None and ds != self.tr("New Database") else ''
+ return ds if not ds is None and ds != self.tr("New Database") else ""
def edgvVersion(self):
"""
@@ -90,7 +95,7 @@ def edgvVersion(self):
:return: (str) EDGV version.
"""
edgv = self.edgvComboBox.currentText()
- return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else ''
+ return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else ""
def authId(self):
"""
@@ -98,7 +103,7 @@ def authId(self):
:return: (str) EDGV version.
"""
crs = self.crs()
- return crs.authid() if not crs is None and crs.isValid() else ''
+ return crs.authid() if not crs is None and crs.isValid() else ""
def crs(self):
"""
@@ -110,7 +115,7 @@ def crs(self):
def reset(self):
"""
- Clears all GUI selections.
+ Clears all GUI selections.
"""
self.dsLineEdit.setText(self.tr("New Database"))
self.edgvComboBox.setCurrentIndex(0)
@@ -137,7 +142,7 @@ def databaseExists(self):
# for files, it is only necessary to check if file exists and is not empty.
ds = self.currentDb()
try:
- with open(ds, 'rb') as f:
+ with open(ds, "rb") as f:
# read paths
l = f.readlines()
return bool(l)
@@ -149,7 +154,7 @@ def databaseExists(self):
# if directory is not empty, check if there are shapefiles in it
for f in os.listdir(ds):
if len(f) > 4:
- if '.shp' == f[-4:].lower():
+ if ".shp" == f[-4:].lower():
return True
return False
@@ -169,8 +174,10 @@ def loadDatabase(self, currentText):
# if msg:
# raise Exception(msg)
except Exception as e:
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
def validate(self):
"""
@@ -184,23 +191,23 @@ def validate(self):
# check a valid server name
# check if datasource is a valid name and if it already exists into selected server
if not self.currentDb():
- return self.tr('Invalid datasource.')
+ return self.tr("Invalid datasource.")
else:
# check if the connection is a valid connection
if not self.serverIsValid():
- return self.tr('Invalid connection to server.')
+ return self.tr("Invalid connection to server.")
# check if it exists
if self.databaseExists():
- return self.tr('Database {0} already exists.').format(self.currentDb())
+ return self.tr("Database {0} already exists.").format(self.currentDb())
pass
# check if a valid EDGV version was selected
if not self.edgvVersion():
- return self.tr('Invalid EDGV version.')
+ return self.tr("Invalid EDGV version.")
# check if a valid projection was selected
- if not self.crs() or 'EPSG' not in self.authId():
- return self.tr('Invalid CRS.')
+ if not self.crs() or "EPSG" not in self.authId():
+ return self.tr("Invalid CRS.")
# if all tests were positive, widget has a valid selection
- return ''
+ return ""
def isValid(self):
"""
@@ -212,7 +219,7 @@ def isValid(self):
# if msg:
# # if an invalidation reason was given, warn user and nothing else.
# iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5)
- return msg == ''
+ return msg == ""
def selectDatasource(self):
"""
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py
index 6e7ae6369..38d134f1e 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/customServerConnectionWidget.py
@@ -232,7 +232,9 @@ def populateSpatialiteSelector(self):
version = auxAbstractDb.getDatabaseVersion()
dbimplversion = auxAbstractDb.getImplementationVersion()
dbList.append((dbName, version, dbimplversion))
- self.spatialiteDict[self.getDisplayString(dbName, version, dbimplversion)] = dbPath
+ self.spatialiteDict[
+ self.getDisplayString(dbName, version, dbimplversion)
+ ] = dbPath
except Exception as e:
QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.clearSpatialiteTab()
@@ -254,6 +256,7 @@ def clearSpatialiteTab(self):
self.edgvType = None
self.selectedDbsDict = dict()
self.resetAll.emit()
+
def clearPostgisTab(self):
"""
Clears the spatialite tab, returning it to the original state
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py
index 8f09bfb4a..ed51b4d80 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/ServerConnectionWidgets/exploreServerWidget.py
@@ -38,14 +38,17 @@
from ....CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
from DsgTools.core.dsgEnums import DsgEnums
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'exploreServerWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "exploreServerWidget.ui")
+)
+
class ExploreServerWidget(QtWidgets.QWidget, FORM_CLASS):
abstractDbLoaded = pyqtSignal()
serverAbstractDbLoaded = pyqtSignal(AbstractDb)
clearWidgets = pyqtSignal()
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""Constructor."""
super(ExploreServerWidget, self).__init__(parent)
self.setupUi(self)
@@ -60,26 +63,26 @@ def getServers(self):
Gets server from QSettings
"""
settings = QSettings()
- settings.beginGroup('PostgreSQL/servers')
+ settings.beginGroup("PostgreSQL/servers")
currentConnections = settings.childGroups()
settings.endGroup()
return currentConnections
-
+
def getServerConfiguration(self, name):
"""
Gets server configuration
- name: server name
+ name: server name
"""
settings = QSettings()
- settings.beginGroup('PostgreSQL/servers/'+name)
- host = settings.value('host')
- port = settings.value('port')
- user = settings.value('username')
- password = settings.value('password')
+ settings.beginGroup("PostgreSQL/servers/" + name)
+ host = settings.value("host")
+ port = settings.value("port")
+ user = settings.value("username")
+ password = settings.value("password")
settings.endGroup()
-
+
return (host, port, user, password)
-
+
def browseServer(self, dbList, host, port, user, password):
"""
Browses server for EDGV databases
@@ -96,21 +99,40 @@ def browseServer(self, dbList, host, port, user, password):
if self.serverWidget.abstractDb.checkSuperUser():
canLoad = True
else:
- QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection refused. Connect with a super user to inspect server.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Info!"),
+ self.tr(
+ "Connection refused. Connect with a super user to inspect server."
+ ),
+ )
return []
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
if canLoad:
- progress = ProgressWidget(1,len(dbList),self.tr('Loading databases from server... '), parent = self)
+ progress = ProgressWidget(
+ 1,
+ len(dbList),
+ self.tr("Loading databases from server... "),
+ parent=self,
+ )
progress.initBar()
gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS)
edvgDbList = []
for database in dbList:
postgisDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS)
- postgisDb.connectDatabaseWithParameters(host, port, database, user, password)
+ postgisDb.connectDatabaseWithParameters(
+ host, port, database, user, password
+ )
if not postgisDb.db.open():
- qgis.utils.iface.messageBar().pushMessage('DB :'+database+'| msg: '+postgisDb.db.lastError().databaseText(), level=Qgis.Critical)
-
+ qgis.utils.iface.messageBar().pushMessage(
+ "DB :"
+ + database
+ + "| msg: "
+ + postgisDb.db.lastError().databaseText(),
+ level=Qgis.Critical,
+ )
+
query = QSqlQuery(postgisDb.db)
if query.exec_(gen.getEDGVVersion()):
while query.next():
@@ -119,34 +141,44 @@ def browseServer(self, dbList, host, port, user, password):
edvgDbList.append((database, version))
progress.step()
return edvgDbList
-
+
def getDbsFromServer(self, name):
"""
Gets server databases
name: server name
"""
gen = self.factory.createSqlGenerator(driver=DsgEnums.DriverPostGIS)
-
+
(host, port, user, password) = self.getServerConfiguration(name)
- database = 'postgres'
+ database = "postgres"
postgisDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS)
postgisDb.connectDatabaseWithParameters(host, port, database, user, password)
if not postgisDb.db.open():
- QgsMessageLog.logMessage(db.lastError().text(), "DSGTools Plugin", Qgis.Critical)
- QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.'))
-
+ QgsMessageLog.logMessage(
+ db.lastError().text(), "DSGTools Plugin", Qgis.Critical
+ )
+ QMessageBox.critical(
+ self.iface.mainWindow(),
+ self.tr("Critical"),
+ self.tr("A problem occurred! Check log for details."),
+ )
+
query = QSqlQuery(gen.getDatabasesFromServer(), postgisDb.db)
if not query.isActive():
- QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr("Problem executing query: ")+query.lastError().text())
-
+ QMessageBox.critical(
+ self.iface.mainWindow(),
+ self.tr("Critical"),
+ self.tr("Problem executing query: ") + query.lastError().text(),
+ )
+
dbList = []
while query.next():
dbList.append(query.value(0))
postgisDb.closeDatabase()
return self.browseServer(dbList, host, port, user, password)
-
+
@pyqtSlot(bool)
- def on_createNewServerPushButton_clicked(self):
+ def on_createNewServerPushButton_clicked(self):
"""
Opens the View Server dialog
"""
@@ -159,12 +191,14 @@ def populateServersCombo(self):
Populates the server name combo box
"""
self.serversCombo.clear()
- self.serversCombo.addItem(self.tr('Select Server'))
+ self.serversCombo.addItem(self.tr("Select Server"))
currentConnections = self.getServers()
for connection in currentConnections:
(host, port, user, password) = self.getServerConfiguration(connection)
- self.serversCombo.addItem('{3} ({0}@{1}:{2})'.format(user, host, port, connection))
-
+ self.serversCombo.addItem(
+ "{3} ({0}@{1}:{2})".format(user, host, port, connection)
+ )
+
@pyqtSlot(int)
def on_serversCombo_currentIndexChanged(self):
"""
@@ -174,19 +208,35 @@ def on_serversCombo_currentIndexChanged(self):
if self.serversCombo.currentIndex() > 0:
self.abstractDb = self.dbFactory.createDbFactory(DsgEnums.DriverPostGIS)
if not self.abstractDb:
- QMessageBox.critical(self.iface.mainWindow(), self.tr('Critical'), self.tr('A problem occurred! Check log for details.'))
+ QMessageBox.critical(
+ self.iface.mainWindow(),
+ self.tr("Critical"),
+ self.tr("A problem occurred! Check log for details."),
+ )
return
- (host, port, user, password) = self.abstractDb.getServerConfiguration(self.serversCombo.currentText().split('(')[0][0:-1])
+ (host, port, user, password) = self.abstractDb.getServerConfiguration(
+ self.serversCombo.currentText().split("(")[0][0:-1]
+ )
if host or port or user:
- self.abstractDb.connectDatabaseWithParameters(host, port, 'postgres', user, password)
+ self.abstractDb.connectDatabaseWithParameters(
+ host, port, "postgres", user, password
+ )
if self.superNeeded:
try:
if not self.abstractDb.checkSuperUser():
- QMessageBox.warning(self, self.tr('Info!'), self.tr('Connection refused. Connect with a super user to inspect server.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Info!"),
+ self.tr(
+ "Connection refused. Connect with a super user to inspect server."
+ ),
+ )
self.serversCombo.setCurrentIndex(0)
return
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), ":".join(e.args)
+ )
self.abstractDbLoaded.emit()
else:
try:
@@ -196,16 +246,18 @@ def on_serversCombo_currentIndexChanged(self):
except:
pass
self.serverAbstractDbLoaded.emit(self.abstractDb)
-
+
def getServerParameters(self):
"""
Gets postgis server parameters
"""
if self.serversCombo.currentIndex() != 0:
- return self.abstractDb.getServerConfiguration(self.serversCombo.currentText().split('(')[0][0:-1])
+ return self.abstractDb.getServerConfiguration(
+ self.serversCombo.currentText().split("(")[0][0:-1]
+ )
else:
return (None, None, None, None)
-
+
def clearAll(self):
"""
Resets the widget
@@ -217,4 +269,3 @@ def clearAll(self):
except:
pass
self.serversCombo.setCurrentIndex(0)
-
diff --git a/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py b/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py
index 3169f1b4a..ed5e79e32 100644
--- a/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py
+++ b/DsgTools/gui/CustomWidgets/ConnectionWidgets/connectionWidget.py
@@ -22,7 +22,7 @@
"""
import os
-from qgis.core import QgsCoordinateReferenceSystem,QgsMessageLog
+from qgis.core import QgsCoordinateReferenceSystem, QgsMessageLog
from qgis.core import Qgis
from qgis.PyQt import QtWidgets, uic
@@ -37,15 +37,18 @@
from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb
from DsgTools.core.dsgEnums import DsgEnums
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'connectionWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "connectionWidget.ui")
+)
+
class ConnectionWidget(QtWidgets.QWidget, FORM_CLASS):
connectionChanged = pyqtSignal()
problemOccurred = pyqtSignal(str)
dbChanged = pyqtSignal(AbstractDb)
styleChanged = pyqtSignal(dict)
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""Constructor."""
super(ConnectionWidget, self).__init__(parent)
# Set up the user interface from Designer.
@@ -58,8 +61,7 @@ def __init__(self, parent = None):
self.serverWidget.populateServersCombo()
self.serverWidget.abstractDbLoaded.connect(self.getDatabasesFromServer)
self.serverWidget.clearWidgets.connect(self.clearAll)
-
-
+
def __del__(self):
"""
Closes the database
@@ -73,38 +75,38 @@ def closeDatabase(self):
if self.abstractDb:
del self.abstractDb
self.abstractDb = None
-
+
def clearAll(self):
"""
Resets the initial state
"""
- self.filename = ''
+ self.filename = ""
self.dbLoaded = False
self.epsg = 0
self.crs = None
-
+
self.abstractDb = None
self.isSpatialite = False
self.abstractDbFactory = DbFactory()
self.utils = Utils()
- #populating the postgis combobox
+ # populating the postgis combobox
self.comboBoxPostgis.clear()
- self.spatialiteFileEdit.setReadOnly(True)
+ self.spatialiteFileEdit.setReadOnly(True)
self.postGISCrsEdit.setReadOnly(True)
- self.spatialiteCrsEdit.setReadOnly(True)
+ self.spatialiteCrsEdit.setReadOnly(True)
self.edgvSpatialiteVersionEdit.setReadOnly(True)
- self.edgvPostgisVersionEdit.setReadOnly(True)
+ self.edgvPostgisVersionEdit.setReadOnly(True)
def setInitialState(self):
"""
Sets the initial state
"""
- self.filename = ''
+ self.filename = ""
self.dbLoaded = False
self.epsg = 0
self.crs = None
-
+
self.abstractDb = None
self.isSpatialite = False
self.tabWidget.setCurrentIndex(0)
@@ -112,13 +114,13 @@ def setInitialState(self):
self.utils = Utils()
self.serverWidget.serversCombo.setCurrentIndex(0)
- #populating the postgis combobox
+ # populating the postgis combobox
self.comboBoxPostgis.clear()
- self.spatialiteFileEdit.setReadOnly(True)
+ self.spatialiteFileEdit.setReadOnly(True)
self.postGISCrsEdit.setReadOnly(True)
- self.spatialiteCrsEdit.setReadOnly(True)
+ self.spatialiteCrsEdit.setReadOnly(True)
self.edgvSpatialiteVersionEdit.setReadOnly(True)
- self.edgvPostgisVersionEdit.setReadOnly(True)
+ self.edgvPostgisVersionEdit.setReadOnly(True)
@pyqtSlot(int)
def on_comboBoxPostgis_currentIndexChanged(self):
@@ -126,47 +128,47 @@ def on_comboBoxPostgis_currentIndexChanged(self):
Updates database information when the combo box changes
"""
if self.comboBoxPostgis.currentIndex() > 0:
- self.postGISCrsEdit.setText('')
+ self.postGISCrsEdit.setText("")
self.postGISCrsEdit.setReadOnly(True)
- self.edgvPostgisVersionEdit.setText('')
- self.edgvPostgisVersionEdit.setReadOnly(True)
+ self.edgvPostgisVersionEdit.setText("")
+ self.edgvPostgisVersionEdit.setReadOnly(True)
self.loadDatabase()
self.connectionChanged.emit()
-
+
@pyqtSlot(bool)
- def on_pushButtonOpenFile_clicked(self):
+ def on_pushButtonOpenFile_clicked(self):
"""
Loads a spatialite database
"""
self.loadDatabase()
if self.isDBConnected():
self.connectionChanged.emit()
-
+
@pyqtSlot(int)
def on_tabWidget_currentChanged(self):
"""
Changes the tab to work with spatialite or postgis databases
"""
- self.filename = ''
+ self.filename = ""
self.comboBoxPostgis.clear()
self.dbLoaded = False
self.epsg = 0
self.crs = None
- self.dbVersion = ''
+ self.dbVersion = ""
self.serverWidget.serversCombo.setCurrentIndex(0)
self.spatialiteFileEdit.setReadOnly(True)
self.spatialiteFileEdit.setText(self.filename)
- self.postGISCrsEdit.setText('')
+ self.postGISCrsEdit.setText("")
self.postGISCrsEdit.setReadOnly(True)
- self.spatialiteCrsEdit.setText('')
- self.spatialiteCrsEdit.setReadOnly(True)
- self.edgvSpatialiteVersionEdit.setText('')
+ self.spatialiteCrsEdit.setText("")
+ self.spatialiteCrsEdit.setReadOnly(True)
+ self.edgvSpatialiteVersionEdit.setText("")
self.edgvSpatialiteVersionEdit.setReadOnly(True)
- self.edgvPostgisVersionEdit.setText('')
+ self.edgvPostgisVersionEdit.setText("")
self.edgvPostgisVersionEdit.setReadOnly(True)
- self.mGroupBox.setTitle(self.tr('Database connection'))
-
- #Setting the database type
+ self.mGroupBox.setTitle(self.tr("Database connection"))
+
+ # Setting the database type
if self.tabWidget.currentIndex() == 1:
self.isSpatialite = True
else:
@@ -179,19 +181,29 @@ def loadDatabase(self):
self.closeDatabase()
try:
if self.isSpatialite:
- self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverSpatiaLite)
+ self.abstractDb = self.abstractDbFactory.createDbFactory(
+ DsgEnums.DriverSpatiaLite
+ )
self.abstractDb.connectDatabase()
self.spatialiteFileEdit.setText(self.abstractDb.db.databaseName())
- self.edgvSpatialiteVersionEdit.setText(self.abstractDb.getDatabaseVersion())
-
+ self.edgvSpatialiteVersionEdit.setText(
+ self.abstractDb.getDatabaseVersion()
+ )
+
else:
- self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverPostGIS)
+ self.abstractDb = self.abstractDbFactory.createDbFactory(
+ DsgEnums.DriverPostGIS
+ )
(host, port, user, password) = self.serverWidget.getServerParameters()
dbName = self.comboBoxPostgis.currentText()
- self.abstractDb.connectDatabaseWithParameters(host, port, dbName, user, password)
- self.edgvPostgisVersionEdit.setText(self.abstractDb.getDatabaseVersion())
+ self.abstractDb.connectDatabaseWithParameters(
+ host, port, dbName, user, password
+ )
+ self.edgvPostgisVersionEdit.setText(
+ self.abstractDb.getDatabaseVersion()
+ )
serverName = self.serverWidget.serversCombo.currentText()
- newText = dbName + self.tr(' on ') + serverName
+ newText = dbName + self.tr(" on ") + serverName
self.mGroupBox.setToolTip(newText)
# self.mGroupBox.setTitle(newText)
@@ -202,13 +214,17 @@ def loadDatabase(self):
self.styles = self.abstractDb.getStyleDict(self.dbVersion)
self.styleChanged.emit(self.styles)
self.dbChanged.emit(self.abstractDb)
- if self.dbVersion == '-1':
- self.problemOccurred.emit(self.tr('This is not a valid DsgTools database!'))
+ if self.dbVersion == "-1":
+ self.problemOccurred.emit(
+ self.tr("This is not a valid DsgTools database!")
+ )
else:
self.setCRS()
except Exception as e:
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
def setCRS(self):
"""
@@ -217,9 +233,13 @@ def setCRS(self):
try:
self.epsg = self.abstractDb.findEPSG()
if self.epsg == -1:
- self.problemOccurred.emit(self.tr('Coordinate Reference System not set or invalid!'))
+ self.problemOccurred.emit(
+ self.tr("Coordinate Reference System not set or invalid!")
+ )
else:
- self.crs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
+ self.crs = QgsCoordinateReferenceSystem(
+ self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId
+ )
if self.isSpatialite:
self.spatialiteCrsEdit.setText(self.crs.description())
self.spatialiteCrsEdit.setReadOnly(True)
@@ -227,60 +247,67 @@ def setCRS(self):
self.postGISCrsEdit.setText(self.crs.description())
self.postGISCrsEdit.setReadOnly(True)
except Exception as e:
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
-
def isDBConnected(self):
"""
Checks if the database is already loaded
"""
return self.dbLoaded
-
+
def getDBVersion(self):
"""
Gets the database version
"""
- ret = ''
+ ret = ""
try:
ret = self.abstractDb.getDatabaseVersion()
except Exception as e:
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return ret
-
+
def getQmlPath(self):
"""
Gets the QML path
"""
- ret = ''
+ ret = ""
try:
ret = self.abstractDb.getQmlDir()
except Exception as e:
- self.problemOccurred.emit(self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.problemOccurred.emit(
+ self.tr("A problem occurred! Check log for details.")
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return ret
-
+
def getDatabasesFromServer(self):
"""
Gets databases from server
- """
+ """
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
try:
if self.serverWidget.abstractDb:
- dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(parentWidget = self)
+ dbList = self.serverWidget.abstractDb.getEDGVDbsFromServer(
+ parentWidget=self
+ )
dbList.sort()
self.comboBoxPostgis.clear()
- self.comboBoxPostgis.addItem(self.tr('Select Database'))
+ self.comboBoxPostgis.addItem(self.tr("Select Database"))
for db, version in dbList:
self.comboBoxPostgis.addItem(db)
-
+
else:
self.setInitialState()
QApplication.restoreOverrideCursor()
return
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.setInitialState()
- QApplication.restoreOverrideCursor()
\ No newline at end of file
+ QApplication.restoreOverrideCursor()
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py
index 7d7f7f65d..c940faf7e 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/addAttributeWidget.py
@@ -33,25 +33,31 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.domainSetter import DomainSetter
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.domainSetter import (
+ DomainSetter,
+)
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "addAttributeWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'addAttributeWidget.ui'))
class AddAttributeWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
self.setupUi(self)
- regex = QtCore.QRegExp('[a-z]*')
+ regex = QtCore.QRegExp("[a-z]*")
validator = QtGui.QRegExpValidator(regex, self.nameLineEdit)
self.nameLineEdit.setValidator(validator)
self.domainSetter = None
self.jsonBuilder = CustomJSONBuilder()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
populates ui from uiParameterJsonDict with the following keys:
@@ -64,16 +70,22 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- self.nameLineEdit.setText(uiParameterJsonDict['nameLineEdit'])
- if uiParameterJsonDict['references']:
- idx = self.typeComboBox.findText(self.tr('EDGV Domain'), flags = Qt.MatchExactly)
+ self.nameLineEdit.setText(uiParameterJsonDict["nameLineEdit"])
+ if uiParameterJsonDict["references"]:
+ idx = self.typeComboBox.findText(
+ self.tr("EDGV Domain"), flags=Qt.MatchExactly
+ )
self.typeComboBox.setCurrentIndex(idx)
- self.instantiateDomainSetter(uiParameterJsonDict['references'])
+ self.instantiateDomainSetter(uiParameterJsonDict["references"])
else:
- self.typeComboBox.setCurrentIndex(int(uiParameterJsonDict['typeComboBox']))
- if uiParameterJsonDict['notNullcheckBox']:
+ self.typeComboBox.setCurrentIndex(
+ int(uiParameterJsonDict["typeComboBox"])
+ )
+ if uiParameterJsonDict["notNullcheckBox"]:
self.notNullcheckBox.setCheckState(2)
- idx = self.defaultComboBox.findText(uiParameterJsonDict['defaultComboBox'], flags = Qt.MatchExactly)
+ idx = self.defaultComboBox.findText(
+ uiParameterJsonDict["defaultComboBox"], flags=Qt.MatchExactly
+ )
self.defaultComboBox.setCurrentIndex(idx)
def enableItems(self, enabled):
@@ -82,18 +94,20 @@ def enableItems(self, enabled):
self.referencesPushButton.setEnabled(enabled)
self.defaultLabel.setEnabled(enabled)
self.defaultComboBox.setEnabled(enabled)
-
+
@pyqtSlot(int)
def on_typeComboBox_currentIndexChanged(self, idx):
- edgvDomainIdx = self.typeComboBox.findText(self.tr('EDGV Domain'), flags = Qt.MatchExactly)
+ edgvDomainIdx = self.typeComboBox.findText(
+ self.tr("EDGV Domain"), flags=Qt.MatchExactly
+ )
if idx == edgvDomainIdx:
self.enableItems(True)
else:
self.enableItems(False)
- self.referencesLineEdit.setText('')
+ self.referencesLineEdit.setText("")
self.defaultComboBox.clear()
self.domainSetter = None
-
+
@pyqtSlot(bool)
def on_referencesPushButton_clicked(self):
if not self.domainSetter:
@@ -101,7 +115,7 @@ def on_referencesPushButton_clicked(self):
else:
self.domainSetter.show()
- def instantiateDomainSetter(self, uiParameterJsonDict = None):
+ def instantiateDomainSetter(self, uiParameterJsonDict=None):
self.domainSetter = DomainSetter(self.abstractDb, uiParameterJsonDict)
self.domainSetter.domainChanged.connect(self.populateDefaultCombo)
if not uiParameterJsonDict:
@@ -113,9 +127,9 @@ def instantiateDomainSetter(self, uiParameterJsonDict = None):
def populateDefaultCombo(self, domainName, domainDict, filterClause):
self.referencesLineEdit.setText(domainName)
self.defaultComboBox.clear()
- addList = ['']
+ addList = [""]
for domain in list(domainDict.keys()):
- if filterClause == dict():
+ if filterClause == dict():
if domain not in addList:
addList.append(domain)
elif domain in list(filterClause.keys()):
@@ -123,24 +137,24 @@ def populateDefaultCombo(self, domainName, domainDict, filterClause):
addList.append(domain)
for item in addList:
self.defaultComboBox.addItem(item)
-
+
def getChildWidgets(self):
return self.domainSetter
def validate(self):
invalidatedList = []
- if self.nameLineEdit.text() == '':
+ if self.nameLineEdit.text() == "":
return False
if self.typeComboBox.currentIndex() == 0:
return False
return True
-
+
def validateDiagnosis(self):
- invalidatedReason = ''
- if self.nameLineEdit.text() == '':
- invalidatedReason += self.tr('Attribute must have a name.\n')
+ invalidatedReason = ""
+ if self.nameLineEdit.text() == "":
+ invalidatedReason += self.tr("Attribute must have a name.\n")
if self.typeComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('Attribute must have a type.\n')
+ invalidatedReason += self.tr("Attribute must have a type.\n")
return invalidatedReason
def getJSONTag(self):
@@ -148,8 +162,8 @@ def getJSONTag(self):
raise Exception(self.validateDiagnosis())
attrName = self.nameLineEdit.text()
attrType = self.typeComboBox.currentText()
- if attrType == self.tr('EDGV Domain'):
- attrType = 'smallint'
+ if attrType == self.tr("EDGV Domain"):
+ attrType = "smallint"
isPk = False
if self.notNullcheckBox.isChecked():
isNullable = False
@@ -157,16 +171,28 @@ def getJSONTag(self):
isNullable = True
defaultComboCurrentText = self.defaultComboBox.currentText()
if not self.domainSetter:
- return self.jsonBuilder.buildAttributeElement(attrName, attrType, isPk, isNullable)
+ return self.jsonBuilder.buildAttributeElement(
+ attrName, attrType, isPk, isNullable
+ )
else:
- if defaultComboCurrentText == '':
+ if defaultComboCurrentText == "":
defaultValue = None
else:
defaultValue = self.domainSetter.domainDict[defaultComboCurrentText]
references = self.domainSetter.domainName
filter = list(self.domainSetter.filterClause.values())
- return [self.jsonBuilder.buildAttributeElement(attrName, attrType, isPk, isNullable, defaultValue, references, filter)]
-
+ return [
+ self.jsonBuilder.buildAttributeElement(
+ attrName,
+ attrType,
+ isPk,
+ isNullable,
+ defaultValue,
+ references,
+ filter,
+ )
+ ]
+
def getUiParameterJsonDict(self):
"""
builds a dict with the following format:
@@ -179,11 +205,13 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['nameLineEdit'] = self.nameLineEdit.text()
- uiParameterJsonDict['typeComboBox'] = self.typeComboBox.currentText()
- uiParameterJsonDict['notNullcheckBox'] = self.notNullcheckBox.isChecked()
- uiParameterJsonDict['defaultComboBox'] = self.defaultComboBox.currentText()
- uiParameterJsonDict['references'] = None
+ uiParameterJsonDict["nameLineEdit"] = self.nameLineEdit.text()
+ uiParameterJsonDict["typeComboBox"] = self.typeComboBox.currentText()
+ uiParameterJsonDict["notNullcheckBox"] = self.notNullcheckBox.isChecked()
+ uiParameterJsonDict["defaultComboBox"] = self.defaultComboBox.currentText()
+ uiParameterJsonDict["references"] = None
if self.domainSetter:
- uiParameterJsonDict['references'] = self.domainSetter.getUiParameterJsonDict()
- return uiParameterJsonDict
\ No newline at end of file
+ uiParameterJsonDict[
+ "references"
+ ] = self.domainSetter.getUiParameterJsonDict()
+ return uiParameterJsonDict
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py
index bb0694b37..622352c4f 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/alterDefaultWidget.py
@@ -30,15 +30,20 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtGui import QCursor
+
# DSGTools imports
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
from DsgTools.core.Utils.utils import Utils
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'alterDefaultWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "alterDefaultWidget.ui")
+)
+
class AlterDefaultWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
@@ -50,7 +55,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.domainDict = self.abstractDb.getDbDomainDict(geomDict)
self.utils = Utils()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
builds a dict with the following format:
@@ -64,27 +69,35 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- if uiParameterJsonDict['allTablesCheckBox']:
+ if uiParameterJsonDict["allTablesCheckBox"]:
self.allTablesCheckBox.setCheckState(Qt.Checked)
else:
- schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly)
+ schemaIdx = self.schemaComboBox.findText(
+ uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly
+ )
self.schemaComboBox.setCurrentIndex(schemaIdx)
- tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly)
+ tableIdx = self.tableComboBox.findText(
+ uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly
+ )
self.tableComboBox.setCurrentIndex(tableIdx)
- if uiParameterJsonDict['allAttributesCheckBox']:
+ if uiParameterJsonDict["allAttributesCheckBox"]:
self.allAttributesCheckBox.setCheckState(Qt.Checked)
else:
- attributeIdx = self.attributeComboBox.findText(uiParameterJsonDict['attributeComboBox'], flags = Qt.MatchExactly)
+ attributeIdx = self.attributeComboBox.findText(
+ uiParameterJsonDict["attributeComboBox"], flags=Qt.MatchExactly
+ )
self.attributeComboBox.setCurrentIndex(attributeIdx)
- idx = self.singleValueComboBox.findText(uiParameterJsonDict['singleValueComboBox'], flags = Qt.MatchExactly)
+ idx = self.singleValueComboBox.findText(
+ uiParameterJsonDict["singleValueComboBox"], flags=Qt.MatchExactly
+ )
self.singleValueComboBox.setCurrentIndex(idx)
def populateSchemaCombo(self):
self.schemaComboBox.clear()
- self.schemaComboBox.addItem(self.tr('Select a schema'))
+ self.schemaComboBox.addItem(self.tr("Select a schema"))
schemaList = self.abstractDb.getGeometricSchemaList()
for schema in schemaList:
- if schema not in ['views', 'validation']:
+ if schema not in ["views", "validation"]:
self.schemaComboBox.addItem(schema)
@pyqtSlot(int)
@@ -99,7 +112,7 @@ def on_schemaComboBox_currentIndexChanged(self, idx):
schema = self.schemaComboBox.currentText()
self.tableComboBox.setEnabled(True)
self.tableComboBox.clear()
- self.tableComboBox.addItem(self.tr('Select a table'))
+ self.tableComboBox.addItem(self.tr("Select a table"))
tableList = self.abstractDb.getGeometricTableListFromSchema(schema)
for table in tableList:
self.tableComboBox.addItem(table)
@@ -114,22 +127,26 @@ def on_tableComboBox_currentIndexChanged(self, idx):
tableName = self.tableComboBox.currentText()
self.attributeComboBox.setEnabled(True)
self.attributeComboBox.clear()
- self.attributeComboBox.addItem(self.tr('Select an attribute'))
+ self.attributeComboBox.addItem(self.tr("Select an attribute"))
if tableName in list(self.domainDict.keys()):
- attributeList = list(self.domainDict[tableName]['columns'].keys())
+ attributeList = list(self.domainDict[tableName]["columns"].keys())
for attribute in attributeList:
self.attributeComboBox.addItem(attribute)
self.singleValueComboBox.clear()
-
- @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged')
- @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged')
+
+ @pyqtSlot(int, name="on_schemaComboBox_currentIndexChanged")
+ @pyqtSlot(int, name="on_tableComboBox_currentIndexChanged")
def populateOnSelectAll(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
- if self.allTablesCheckBox.checkState() == 2 or (self.allAttributesCheckBox.checkState() == 2 and self.schemaComboBox.currentIndex() != 0 and self.tableComboBox.currentIndex() != 0):
+ if self.allTablesCheckBox.checkState() == 2 or (
+ self.allAttributesCheckBox.checkState() == 2
+ and self.schemaComboBox.currentIndex() != 0
+ and self.tableComboBox.currentIndex() != 0
+ ):
self.attributeComboBox.clear()
self.attributeComboBox.setEnabled(False)
self.singleValueComboBox.clear()
- self.singleValueComboBox.addItem(self.tr('Select a value to alter'))
+ self.singleValueComboBox.addItem(self.tr("Select a value to alter"))
if self.allAttributesCheckBox.checkState() == 2:
tableList = [self.tableComboBox.currentText()]
else:
@@ -137,15 +154,23 @@ def populateOnSelectAll(self):
allValueList = []
idxList = []
for tableName in tableList:
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
- for code in self.domainDict[tableName]['columns'][attrName]['values']:
- value = self.domainDict[tableName]['columns'][attrName]['values'][code]
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
+ for code in self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ]:
+ value = self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ][code]
if value not in allValueList:
allValueList.append(value)
for value in allValueList:
for tableName in tableList:
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
- if value not in list(self.domainDict[tableName]['columns'][attrName]['values'].values()):
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
+ if value not in list(
+ self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ].values()
+ ):
idx = allValueList.index(value)
if idx not in idxList:
idxList.append(idx)
@@ -155,7 +180,7 @@ def populateOnSelectAll(self):
for value in allValueList:
self.singleValueComboBox.addItem(value)
QApplication.restoreOverrideCursor()
-
+
@pyqtSlot(int)
def on_attributeComboBox_currentIndexChanged(self, idx):
if idx == 0:
@@ -167,23 +192,38 @@ def on_attributeComboBox_currentIndexChanged(self, idx):
tableFilter = []
filterToList = []
self.singleValueComboBox.clear()
- self.singleValueComboBox.addItem(self.tr('Select a value to alter'))
+ self.singleValueComboBox.addItem(self.tr("Select a value to alter"))
tableName = self.tableComboBox.currentText()
attributeName = self.attributeComboBox.currentText()
if tableName in list(self.domainDict.keys()):
- if attributeName in list(self.domainDict[tableName]['columns'].keys()):
- attrDomainDict = self.domainDict[tableName]['columns'][attributeName]['values']
+ if attributeName in list(self.domainDict[tableName]["columns"].keys()):
+ attrDomainDict = self.domainDict[tableName]["columns"][attributeName][
+ "values"
+ ]
for value in list(attrDomainDict.values()):
self.singleValueComboBox.addItem(value)
- defaultCode = self.abstractDb.getDefaultFromDb(self.schemaComboBox.currentText(),tableName,attributeName)
+ defaultCode = self.abstractDb.getDefaultFromDb(
+ self.schemaComboBox.currentText(), tableName, attributeName
+ )
if defaultCode:
- if 'ARRAY' in defaultCode or '@' in defaultCode:
- #done to extract value from multi array
- defaultCodeInt = int(defaultCode.replace('ARRAY','').replace('(','').replace(')','').replace(']','').replace('[','').replace('@','').replace('<','').split(':')[0])
+ if "ARRAY" in defaultCode or "@" in defaultCode:
+ # done to extract value from multi array
+ defaultCodeInt = int(
+ defaultCode.replace("ARRAY", "")
+ .replace("(", "")
+ .replace(")", "")
+ .replace("]", "")
+ .replace("[", "")
+ .replace("@", "")
+ .replace("<", "")
+ .split(":")[0]
+ )
else:
defaultCodeInt = int(defaultCode)
if defaultCodeInt in list(attrDomainDict.keys()):
- comboItem = self.singleValueComboBox.findText(attrDomainDict[defaultCodeInt], flags = Qt.MatchExactly)
+ comboItem = self.singleValueComboBox.findText(
+ attrDomainDict[defaultCodeInt], flags=Qt.MatchExactly
+ )
self.singleValueComboBox.setCurrentIndex(comboItem)
QApplication.restoreOverrideCursor()
@@ -224,18 +264,18 @@ def setTitle(self, title):
def validate(self):
if self.allTablesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- return False
+ if self.singleValueComboBox.currentIndex() == 0:
+ return False
elif self.allAttributesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- return False
- if self.schemaComboBox.currentIndex() == 0:
- return False
- if self.tableComboBox.currentIndex() == 0:
- return False
+ if self.singleValueComboBox.currentIndex() == 0:
+ return False
+ if self.schemaComboBox.currentIndex() == 0:
+ return False
+ if self.tableComboBox.currentIndex() == 0:
+ return False
else:
if self.singleValueComboBox.currentIndex() == 0:
- return False
+ return False
if self.schemaComboBox.currentIndex() == 0:
return False
if self.tableComboBox.currentIndex() == 0:
@@ -245,43 +285,48 @@ def validate(self):
return True
def validateDiagnosis(self):
- invalidatedReason = ''
+ invalidatedReason = ""
if self.allTablesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A value must be chosen.\n')
+ if self.singleValueComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A value must be chosen.\n")
elif self.allAttributesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A value must be chosen.\n')
- if self.schemaComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A schema must be chosen.\n')
- if self.tableComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A table must be chosen.\n')
- else:
if self.singleValueComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A value must be chosen.\n')
+ invalidatedReason += self.tr("A value must be chosen.\n")
+ if self.schemaComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A schema must be chosen.\n")
+ if self.tableComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A table must be chosen.\n")
+ else:
+ if self.singleValueComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A value must be chosen.\n")
if self.schemaComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A schema must be chosen.\n')
+ invalidatedReason += self.tr("A schema must be chosen.\n")
if self.tableComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A table must be chosen.\n')
+ invalidatedReason += self.tr("A table must be chosen.\n")
if self.attributeComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An attribute must be chosen.\n')
+ invalidatedReason += self.tr("An attribute must be chosen.\n")
return invalidatedReason
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in default customization ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in default customization ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
jsonList = []
inhConstrDict = self.abstractDb.getInheritanceConstraintDict()
if self.allAttributesCheckBox.checkState() == 2:
tableName = self.tableComboBox.currentText()
schema = self.schemaComboBox.currentText()
if tableName in list(self.domainDict.keys()):
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList)
elif self.allTablesCheckBox.checkState() == 2:
for tableName in list(self.domainDict.keys()):
schema = self.abstractDb.getTableSchemaFromDb(tableName)
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList)
else:
tableName = self.tableComboBox.currentText()
@@ -292,22 +337,43 @@ def getJSONTag(self):
def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList):
if tableName in list(self.domainDict.keys()):
- if attrName in list(self.domainDict[tableName]['columns'].keys()):
- attrDomainDict = self.domainDict[tableName]['columns'][attrName]['values']
- oldDefaultText = self.abstractDb.getDefaultFromDb(self.schemaComboBox.currentText(),tableName,attrName)
+ if attrName in list(self.domainDict[tableName]["columns"].keys()):
+ attrDomainDict = self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ]
+ oldDefaultText = self.abstractDb.getDefaultFromDb(
+ self.schemaComboBox.currentText(), tableName, attrName
+ )
if oldDefaultText:
- if 'ARRAY' in oldDefaultText or '@' in oldDefaultText:
- #done to build multi array
- oldDefaultInt = int(oldDefaultText.replace('ARRAY','').replace('(','').replace(')','').replace(']','').replace('[','').replace('@','').replace('<','').split(':')[0])
+ if "ARRAY" in oldDefaultText or "@" in oldDefaultText:
+ # done to build multi array
+ oldDefaultInt = int(
+ oldDefaultText.replace("ARRAY", "")
+ .replace("(", "")
+ .replace(")", "")
+ .replace("]", "")
+ .replace("[", "")
+ .replace("@", "")
+ .replace("<", "")
+ .split(":")[0]
+ )
else:
oldDefaultInt = int(oldDefaultText)
newDefaultText = self.singleValueComboBox.currentText()
- newDefaultInt = [i for i in list(attrDomainDict.keys()) if attrDomainDict[i] == newDefaultText][0]
+ newDefaultInt = [
+ i
+ for i in list(attrDomainDict.keys())
+ if attrDomainDict[i] == newDefaultText
+ ][0]
if oldDefaultText:
- newDefault = oldDefaultText.replace(str(oldDefaultInt),str(newDefaultInt))
+ newDefault = oldDefaultText.replace(
+ str(oldDefaultInt), str(newDefaultInt)
+ )
else:
newDefault = str(newDefaultInt)
- newElement = self.jsonBuilder.buildChangeDefaultElement(schema,tableName, attrName, oldDefaultText, newDefault)
+ newElement = self.jsonBuilder.buildChangeDefaultElement(
+ schema, tableName, attrName, oldDefaultText, newDefault
+ )
if newElement not in jsonList:
jsonList.append(newElement)
@@ -324,10 +390,14 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText()
- uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText()
- uiParameterJsonDict['allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked()
- uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked()
- uiParameterJsonDict['attributeComboBox'] = self.attributeComboBox.currentText()
- uiParameterJsonDict['singleValueComboBox'] = self.singleValueComboBox.currentText()
- return uiParameterJsonDict
\ No newline at end of file
+ uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText()
+ uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText()
+ uiParameterJsonDict[
+ "allAttributesCheckBox"
+ ] = self.allAttributesCheckBox.isChecked()
+ uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked()
+ uiParameterJsonDict["attributeComboBox"] = self.attributeComboBox.currentText()
+ uiParameterJsonDict[
+ "singleValueComboBox"
+ ] = self.singleValueComboBox.currentText()
+ return uiParameterJsonDict
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py
index 33b41062d..096cfba0c 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeFilterWidget.py
@@ -29,26 +29,34 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtGui import QCursor
+
# DSGTools imports
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
from DsgTools.core.Utils.utils import Utils
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'changeFilterWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "changeFilterWidget.ui")
+)
+
class ChangeFilterWidget(QtWidgets.QWidget, FORM_CLASS):
populateSingleValue = pyqtSignal()
populateListValue = pyqtSignal()
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
self.setupUi(self)
self.jsonBuilder = CustomJSONBuilder()
self.populateSchemaCombo()
- self.hideWidgetList([self.singleValueLabel, self.singleValueComboBox, self.actionComboBox])
+ self.hideWidgetList(
+ [self.singleValueLabel, self.singleValueComboBox, self.actionComboBox]
+ )
self.singleAttribute = True
- self.filterCustomSelectorWidget.setTitle(self.tr('Select filter values'))
+ self.filterCustomSelectorWidget.setTitle(self.tr("Select filter values"))
self.populateSingleValue.connect(self.populateWidgetWithSingleValue)
self.populateListValue.connect(self.populateWidgetWithListValue)
geomTypeDict = self.abstractDb.getGeomTypeDict()
@@ -56,9 +64,13 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.domainDict = self.abstractDb.getDbDomainDict(geomDict)
self.inhTree = self.abstractDb.getInheritanceTreeDict()
self.utils = Utils()
- self.actionDict = {self.tr('Add to Filter (Leave empty if filter is empty)'):'addEmpty', self.tr('Add to Filter (Add value to empty filter)'):'add',self.tr('Remove from Filter'):'remove'}
+ self.actionDict = {
+ self.tr("Add to Filter (Leave empty if filter is empty)"): "addEmpty",
+ self.tr("Add to Filter (Add value to empty filter)"): "add",
+ self.tr("Remove from Filter"): "remove",
+ }
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
{
@@ -73,41 +85,68 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- if uiParameterJsonDict['allTablesCheckBox']:
+ if uiParameterJsonDict["allTablesCheckBox"]:
self.allTablesCheckBox.setCheckState(Qt.Checked)
- singleValueIdx = self.singleValueComboBox.findText(uiParameterJsonDict['singleValueComboBox'], flags = Qt.MatchExactly)
+ singleValueIdx = self.singleValueComboBox.findText(
+ uiParameterJsonDict["singleValueComboBox"], flags=Qt.MatchExactly
+ )
self.singleValueComboBox.setCurrentIndex(singleValueIdx)
- self.actionComboBox.setCurrentIndex(uiParameterJsonDict['actionComboBoxIdx'])
+ self.actionComboBox.setCurrentIndex(
+ uiParameterJsonDict["actionComboBoxIdx"]
+ )
else:
- schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly)
+ schemaIdx = self.schemaComboBox.findText(
+ uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly
+ )
self.schemaComboBox.setCurrentIndex(schemaIdx)
- tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly)
+ tableIdx = self.tableComboBox.findText(
+ uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly
+ )
self.tableComboBox.setCurrentIndex(tableIdx)
- if uiParameterJsonDict['allAttributesCheckBox']:
+ if uiParameterJsonDict["allAttributesCheckBox"]:
self.allAttributesCheckBox.setCheckState(Qt.Checked)
- singleValueIdx = self.singleValueComboBox.findText(uiParameterJsonDict['singleValueComboBox'], flags = Qt.MatchExactly)
+ singleValueIdx = self.singleValueComboBox.findText(
+ uiParameterJsonDict["singleValueComboBox"],
+ flags=Qt.MatchExactly,
+ )
self.singleValueComboBox.setCurrentIndex(singleValueIdx)
- self.actionComboBox.setCurrentIndex(uiParameterJsonDict['actionComboBoxIdx'])
+ self.actionComboBox.setCurrentIndex(
+ uiParameterJsonDict["actionComboBoxIdx"]
+ )
else:
- attributeIdx = self.attributeComboBox.findText(uiParameterJsonDict['attributeComboBox'], flags = Qt.MatchExactly)
+ attributeIdx = self.attributeComboBox.findText(
+ uiParameterJsonDict["attributeComboBox"], flags=Qt.MatchExactly
+ )
self.attributeComboBox.setCurrentIndex(attributeIdx)
- self.filterCustomSelectorWidget.selectItems(True, selectedItems=uiParameterJsonDict['filterCustomSelectorWidgetToList'])
+ self.filterCustomSelectorWidget.selectItems(
+ True,
+ selectedItems=uiParameterJsonDict[
+ "filterCustomSelectorWidgetToList"
+ ],
+ )
def populateInheritanceTree(self, nodeList):
self.treeWidget.clear()
rootNode = self.treeWidget.invisibleRootItem()
for node in nodeList:
- firstNonRootNode = self.utils.find_all_paths(self.inhTree, 'root', node)[0][1]
- self.utils.createTreeWidgetFromDict(rootNode, {firstNonRootNode:self.inhTree['root'][firstNonRootNode]}, self.treeWidget, 0)
+ firstNonRootNode = self.utils.find_all_paths(self.inhTree, "root", node)[0][
+ 1
+ ]
+ self.utils.createTreeWidgetFromDict(
+ rootNode,
+ {firstNonRootNode: self.inhTree["root"][firstNonRootNode]},
+ self.treeWidget,
+ 0,
+ )
self.treeWidget.sortItems(0, Qt.AscendingOrder)
self.treeWidget.expandAll()
def populateSchemaCombo(self):
self.schemaComboBox.clear()
- self.schemaComboBox.addItem(self.tr('Select a schema'))
+ self.schemaComboBox.addItem(self.tr("Select a schema"))
schemaList = self.abstractDb.getGeometricSchemaList()
for schema in schemaList:
- if schema not in ['views', 'validation']:
+ if schema not in ["views", "validation"]:
self.schemaComboBox.addItem(schema)
def hideWidgetList(self, widgetList):
@@ -129,7 +168,7 @@ def on_schemaComboBox_currentIndexChanged(self, idx):
schema = self.schemaComboBox.currentText()
self.tableComboBox.setEnabled(True)
self.tableComboBox.clear()
- self.tableComboBox.addItem(self.tr('Select a table'))
+ self.tableComboBox.addItem(self.tr("Select a table"))
tableList = self.abstractDb.getGeometricTableListFromSchema(schema)
for table in tableList:
self.tableComboBox.addItem(table)
@@ -144,22 +183,26 @@ def on_tableComboBox_currentIndexChanged(self, idx):
tableName = self.tableComboBox.currentText()
self.attributeComboBox.setEnabled(True)
self.attributeComboBox.clear()
- self.attributeComboBox.addItem(self.tr('Select an attribute'))
+ self.attributeComboBox.addItem(self.tr("Select an attribute"))
if tableName in list(self.domainDict.keys()):
- attributeList = list(self.domainDict[tableName]['columns'].keys())
+ attributeList = list(self.domainDict[tableName]["columns"].keys())
for attribute in attributeList:
self.attributeComboBox.addItem(attribute)
- @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged')
- @pyqtSlot(int, name='on_attributeComboBox_currentIndexChanged')
- @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged')
+ @pyqtSlot(int, name="on_schemaComboBox_currentIndexChanged")
+ @pyqtSlot(int, name="on_attributeComboBox_currentIndexChanged")
+ @pyqtSlot(int, name="on_tableComboBox_currentIndexChanged")
def populateWidgetWithSingleValue(self):
- if self.allTablesCheckBox.checkState() == 2 or (self.allAttributesCheckBox.checkState() == 2 and self.schemaComboBox.currentIndex() != 0 and self.tableComboBox.currentIndex() != 0):
+ if self.allTablesCheckBox.checkState() == 2 or (
+ self.allAttributesCheckBox.checkState() == 2
+ and self.schemaComboBox.currentIndex() != 0
+ and self.tableComboBox.currentIndex() != 0
+ ):
self.attributeComboBox.clear()
self.attributeComboBox.setEnabled(False)
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.singleValueComboBox.clear()
- self.singleValueComboBox.addItem(self.tr('Select a value to alter'))
+ self.singleValueComboBox.addItem(self.tr("Select a value to alter"))
if self.allAttributesCheckBox.checkState() == 2:
tableList = [self.tableComboBox.currentText()]
else:
@@ -167,16 +210,24 @@ def populateWidgetWithSingleValue(self):
allValueList = []
idxList = []
for tableName in tableList:
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
- for code in self.domainDict[tableName]['columns'][attrName]['values']:
- value = self.domainDict[tableName]['columns'][attrName]['values'][code]
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
+ for code in self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ]:
+ value = self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ][code]
if value not in allValueList:
allValueList.append(value)
for value in allValueList:
for tableName in tableList:
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
- if value not in list(self.domainDict[tableName]['columns'][attrName]['values'].values()):
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
+ if value not in list(
+ self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ].values()
+ ):
idx = allValueList.index(value)
if idx not in idxList:
idxList.append(idx)
@@ -188,12 +239,15 @@ def populateWidgetWithSingleValue(self):
self.populateInheritanceTree(tableList)
QApplication.restoreOverrideCursor()
- @pyqtSlot(int, name='on_schemaComboBox_currentIndexChanged')
- @pyqtSlot(int, name='on_attributeComboBox_currentIndexChanged')
- @pyqtSlot(int, name='on_tableComboBox_currentIndexChanged')
+ @pyqtSlot(int, name="on_schemaComboBox_currentIndexChanged")
+ @pyqtSlot(int, name="on_attributeComboBox_currentIndexChanged")
+ @pyqtSlot(int, name="on_tableComboBox_currentIndexChanged")
def populateWidgetWithListValue(self):
self.filterCustomSelectorWidget.clearAll()
- if self.allTablesCheckBox.checkState() == 2 or self.allAttributesCheckBox.checkState() == 2:
+ if (
+ self.allTablesCheckBox.checkState() == 2
+ or self.allAttributesCheckBox.checkState() == 2
+ ):
return
if self.schemaComboBox.currentIndex() == 0:
return
@@ -209,11 +263,17 @@ def populateWidgetWithListValue(self):
tableFilter = []
filterToList = []
if tableName in list(self.domainDict.keys()):
- if attributeName in list(self.domainDict[tableName]['columns'].keys()):
- attrDomainDict = self.domainDict[tableName]['columns'][attributeName]['values']
- tableFilter = self.domainDict[tableName]['columns'][attributeName]['constraintList']
+ if attributeName in list(self.domainDict[tableName]["columns"].keys()):
+ attrDomainDict = self.domainDict[tableName]["columns"][attributeName][
+ "values"
+ ]
+ tableFilter = self.domainDict[tableName]["columns"][attributeName][
+ "constraintList"
+ ]
filterToList = [attrDomainDict[i] for i in tableFilter]
- filterFromList = [i for i in list(attrDomainDict.values()) if i not in filterToList]
+ filterFromList = [
+ i for i in list(attrDomainDict.values()) if i not in filterToList
+ ]
self.filterCustomSelectorWidget.setFromList(filterFromList, unique=True)
self.filterCustomSelectorWidget.setToList(filterToList)
@@ -243,7 +303,10 @@ def on_allAttributesCheckBox_stateChanged(self, state):
self.hideOrShowWidgets()
def hideOrShowWidgets(self):
- if self.allAttributesCheckBox.checkState() == 2 or self.allTablesCheckBox.checkState() == 2:
+ if (
+ self.allAttributesCheckBox.checkState() == 2
+ or self.allTablesCheckBox.checkState() == 2
+ ):
self.filterCustomSelectorWidget.hide()
self.singleValueLabel.show()
self.singleValueComboBox.show()
@@ -254,7 +317,9 @@ def hideOrShowWidgets(self):
self.singleValueLabel.hide()
self.singleValueComboBox.hide()
self.actionComboBox.hide()
- self.tableComboBox.currentIndexChanged.emit(self.tableComboBox.currentIndex())
+ self.tableComboBox.currentIndexChanged.emit(
+ self.tableComboBox.currentIndex()
+ )
self.populateListValue.emit()
def getTitle(self):
@@ -265,56 +330,61 @@ def setTitle(self, title):
def validate(self):
if self.allTablesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- return False
- if self.actionComboBox.currentIndex() == 0:
- return False
+ if self.singleValueComboBox.currentIndex() == 0:
+ return False
+ if self.actionComboBox.currentIndex() == 0:
+ return False
elif self.allAttributesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- return False
- if self.actionComboBox.currentIndex() == 0:
- return False
- if self.schemaComboBox.currentIndex() == 0:
- return False
- if self.tableComboBox.currentIndex() == 0:
- return False
+ if self.singleValueComboBox.currentIndex() == 0:
+ return False
+ if self.actionComboBox.currentIndex() == 0:
+ return False
+ if self.schemaComboBox.currentIndex() == 0:
+ return False
+ if self.tableComboBox.currentIndex() == 0:
+ return False
else:
- if self.schemaComboBox.currentIndex() == 0:
- return False
- if self.tableComboBox.currentIndex() == 0:
- return False
- if self.attributeComboBox.currentIndex() == 0:
- return False
+ if self.schemaComboBox.currentIndex() == 0:
+ return False
+ if self.tableComboBox.currentIndex() == 0:
+ return False
+ if self.attributeComboBox.currentIndex() == 0:
+ return False
return True
def validateDiagnosis(self):
- invalidatedReason = ''
+ invalidatedReason = ""
if self.allTablesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A value must be chosen.\n')
- if self.actionComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An action must be chosen.\n')
+ if self.singleValueComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A value must be chosen.\n")
+ if self.actionComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("An action must be chosen.\n")
elif self.allAttributesCheckBox.checkState() == 2:
- if self.singleValueComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A value must be chosen.\n')
- if self.actionComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An action must be chosen.\n')
- if self.schemaComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A schema must be chosen.\n')
- if self.tableComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A table must be chosen.\n')
+ if self.singleValueComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A value must be chosen.\n")
+ if self.actionComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("An action must be chosen.\n")
+ if self.schemaComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A schema must be chosen.\n")
+ if self.tableComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A table must be chosen.\n")
else:
- if self.schemaComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A schema must be chosen.\n')
- if self.tableComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A table must be chosen.\n')
- if self.attributeComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An attribute must be chosen.\n')
+ if self.schemaComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A schema must be chosen.\n")
+ if self.tableComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("A table must be chosen.\n")
+ if self.attributeComboBox.currentIndex() == 0:
+ invalidatedReason += self.tr("An attribute must be chosen.\n")
return invalidatedReason
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in change filter customization ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in change filter customization ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
jsonList = []
inhConstrDict = self.abstractDb.getInheritanceConstraintDict()
if self.allAttributesCheckBox.checkState() == 2:
@@ -322,7 +392,7 @@ def getJSONTag(self):
schema = self.schemaComboBox.currentText()
self.batchGetJsonTag(schema, tableName, jsonList, inhConstrDict)
elif self.allTablesCheckBox.checkState() == 2:
- tableList = list(self.inhTree['root'].keys())
+ tableList = list(self.inhTree["root"].keys())
for tableName in tableList:
schema = self.abstractDb.getTableSchemaFromDb(tableName)
self.batchGetJsonTag(schema, tableName, jsonList, inhConstrDict)
@@ -331,39 +401,76 @@ def getJSONTag(self):
schema = self.schemaComboBox.currentText()
attrName = self.attributeComboBox.currentText()
if tableName in list(self.domainDict.keys()):
- if attrName in list(self.domainDict[tableName]['columns'].keys()):
- attrDomainDict = self.domainDict[tableName]['columns'][attrName]['values']
- isMulti = self.domainDict[tableName]['columns'][attrName]['isMulti']
- newFilter = [i for i in list(attrDomainDict.keys()) if attrDomainDict[i] in self.filterCustomSelectorWidget.toLs]
- self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti)
+ if attrName in list(self.domainDict[tableName]["columns"].keys()):
+ attrDomainDict = self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ]
+ isMulti = self.domainDict[tableName]["columns"][attrName]["isMulti"]
+ newFilter = [
+ i
+ for i in list(attrDomainDict.keys())
+ if attrDomainDict[i] in self.filterCustomSelectorWidget.toLs
+ ]
+ self.getJsonTagFromOneTable(
+ schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti
+ )
return jsonList
def batchGetJsonTag(self, schema, tableName, jsonList, inhConstrDict):
if tableName in list(self.domainDict.keys()):
- for attrName in list(self.domainDict[tableName]['columns'].keys()):
- attrDomainDict = self.domainDict[tableName]['columns'][attrName]['values']
- isMulti = self.domainDict[tableName]['columns'][attrName]['isMulti']
- newFilter = self.domainDict[tableName]['columns'][attrName]['constraintList']
+ for attrName in list(self.domainDict[tableName]["columns"].keys()):
+ attrDomainDict = self.domainDict[tableName]["columns"][attrName][
+ "values"
+ ]
+ isMulti = self.domainDict[tableName]["columns"][attrName]["isMulti"]
+ newFilter = self.domainDict[tableName]["columns"][attrName][
+ "constraintList"
+ ]
valueText = self.singleValueComboBox.currentText()
- code = [i for i in list(attrDomainDict.keys()) if attrDomainDict[i] == valueText][0]
- if self.actionDict[self.actionComboBox.currentText()] == 'add':
- if code not in newFilter: newFilter.append(code)
- elif self.actionDict[self.actionComboBox.currentText()] == 'addEmpty':
+ code = [
+ i
+ for i in list(attrDomainDict.keys())
+ if attrDomainDict[i] == valueText
+ ][0]
+ if self.actionDict[self.actionComboBox.currentText()] == "add":
+ if code not in newFilter:
+ newFilter.append(code)
+ elif self.actionDict[self.actionComboBox.currentText()] == "addEmpty":
if newFilter == []:
continue
else:
- if code in newFilter: newFilter.pop(code)
- self.getJsonTagFromOneTable(schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti)
+ if code in newFilter:
+ newFilter.pop(code)
+ self.getJsonTagFromOneTable(
+ schema,
+ tableName,
+ attrName,
+ jsonList,
+ inhConstrDict,
+ newFilter,
+ isMulti,
+ )
- def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti):
+ def getJsonTagFromOneTable(
+ self, schema, tableName, attrName, jsonList, inhConstrDict, newFilter, isMulti
+ ):
originalFilterList = []
if tableName in list(inhConstrDict.keys()):
if attrName in list(inhConstrDict[tableName].keys()):
originalFilterList = inhConstrDict[tableName][attrName]
- if originalFilterList == newFilter: return
+ if originalFilterList == newFilter:
+ return
elif originalFilterList != []:
for item in originalFilterList:
- newElement = self.jsonBuilder.alterFilterElement(item['schema'], item['tableName'], attrName, item['constraintName'], item['filter'], newFilter, isMulti)
+ newElement = self.jsonBuilder.alterFilterElement(
+ item["schema"],
+ item["tableName"],
+ attrName,
+ item["constraintName"],
+ item["filter"],
+ newFilter,
+ isMulti,
+ )
if newElement not in jsonList:
jsonList.append(newElement)
else:
@@ -371,7 +478,7 @@ def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList, inhConst
firstInLineage = None
for node in nodeLineage:
if node in list(self.domainDict.keys()):
- if attrName in list(self.domainDict[node]['columns'].keys()):
+ if attrName in list(self.domainDict[node]["columns"].keys()):
firstInLineage = node
break
else:
@@ -379,7 +486,15 @@ def getJsonTagFromOneTable(self, schema, tableName, attrName, jsonList, inhConst
if node in self.abstractDb.getAttributeListFromTable(schema, node):
firstInLineage = node
break
- newElement = self.jsonBuilder.alterFilterElement(schema, firstInLineage, attrName, '_'.join([firstInLineage,attrName,'ks']), [], newFilter, isMulti)
+ newElement = self.jsonBuilder.alterFilterElement(
+ schema,
+ firstInLineage,
+ attrName,
+ "_".join([firstInLineage, attrName, "ks"]),
+ [],
+ newFilter,
+ isMulti,
+ )
if newElement not in jsonList:
jsonList.append(newElement)
@@ -398,13 +513,18 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText()
- uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText()
- uiParameterJsonDict['attributeComboBox'] = self.attributeComboBox.currentText()
- uiParameterJsonDict['allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked()
- uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked()
- uiParameterJsonDict['filterCustomSelectorWidgetToList'] = self.filterCustomSelectorWidget.toLs
- uiParameterJsonDict['singleValueComboBox'] = self.singleValueComboBox.currentText()
- uiParameterJsonDict['actionComboBoxIdx'] = self.actionComboBox.currentIndex()
+ uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText()
+ uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText()
+ uiParameterJsonDict["attributeComboBox"] = self.attributeComboBox.currentText()
+ uiParameterJsonDict[
+ "allAttributesCheckBox"
+ ] = self.allAttributesCheckBox.isChecked()
+ uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked()
+ uiParameterJsonDict[
+ "filterCustomSelectorWidgetToList"
+ ] = self.filterCustomSelectorWidget.toLs
+ uiParameterJsonDict[
+ "singleValueComboBox"
+ ] = self.singleValueComboBox.currentText()
+ uiParameterJsonDict["actionComboBoxIdx"] = self.actionComboBox.currentIndex()
return uiParameterJsonDict
-
\ No newline at end of file
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py
index 4ca9c5e1e..9482d6d94 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/changeNullityWidget.py
@@ -30,13 +30,17 @@
from qgis.PyQt.QtSql import QSqlQuery
# DSGTools imports
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "changeNullityWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'changeNullityWidget.ui'))
class ChangeNullityWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
@@ -44,7 +48,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.jsonBuilder = CustomJSONBuilder()
self.populateSchemaCombo()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
builds a dict with the following format:
@@ -58,26 +62,34 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- if uiParameterJsonDict['allTablesCheckBox']:
+ if uiParameterJsonDict["allTablesCheckBox"]:
self.allTablesCheckBox.setCheckState(Qt.Checked)
else:
- schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly)
+ schemaIdx = self.schemaComboBox.findText(
+ uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly
+ )
self.schemaComboBox.setCurrentIndex(schemaIdx)
- tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly)
+ tableIdx = self.tableComboBox.findText(
+ uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly
+ )
self.tableComboBox.setCurrentIndex(tableIdx)
- if uiParameterJsonDict['allAttributesCheckBox']:
+ if uiParameterJsonDict["allAttributesCheckBox"]:
self.allAttributesCheckBox.setCheckState(Qt.Checked)
else:
- attributeIdx = self.attributeComboBox.findText(uiParameterJsonDict['attributeComboBox'], flags = Qt.MatchExactly)
+ attributeIdx = self.attributeComboBox.findText(
+ uiParameterJsonDict["attributeComboBox"], flags=Qt.MatchExactly
+ )
self.attributeComboBox.setCurrentIndex(attributeIdx)
- self.actionComboBox.setCurrentIndex(uiParameterJsonDict['actionComboBoxIdx'])
-
+ self.actionComboBox.setCurrentIndex(
+ uiParameterJsonDict["actionComboBoxIdx"]
+ )
+
def populateSchemaCombo(self):
self.schemaComboBox.clear()
- self.schemaComboBox.addItem(self.tr('Select a schema'))
+ self.schemaComboBox.addItem(self.tr("Select a schema"))
schemaList = self.abstractDb.getGeometricSchemaList()
for schema in schemaList:
- if schema not in ['views', 'validation']:
+ if schema not in ["views", "validation"]:
self.schemaComboBox.addItem(schema)
@pyqtSlot(int)
@@ -91,11 +103,11 @@ def on_schemaComboBox_currentIndexChanged(self, idx):
schema = self.schemaComboBox.currentText()
self.tableComboBox.setEnabled(True)
self.tableComboBox.clear()
- self.tableComboBox.addItem(self.tr('Select a table'))
+ self.tableComboBox.addItem(self.tr("Select a table"))
tableList = self.abstractDb.getGeometricTableListFromSchema(schema)
for table in tableList:
self.tableComboBox.addItem(table)
-
+
@pyqtSlot(int)
def on_tableComboBox_currentIndexChanged(self, idx):
if idx == 0:
@@ -106,11 +118,11 @@ def on_tableComboBox_currentIndexChanged(self, idx):
tableName = self.tableComboBox.currentText()
self.attributeComboBox.setEnabled(True)
self.attributeComboBox.clear()
- self.attributeComboBox.addItem(self.tr('Select an attribute'))
+ self.attributeComboBox.addItem(self.tr("Select an attribute"))
attributeList = self.abstractDb.getAttributeListFromTable(schema, tableName)
for attribute in attributeList:
self.attributeComboBox.addItem(attribute)
-
+
@pyqtSlot(int)
def on_allTablesCheckBox_stateChanged(self, state):
if state == 0:
@@ -122,8 +134,7 @@ def on_allTablesCheckBox_stateChanged(self, state):
self.allAttributesCheckBox.setCheckState(0)
self.schemaComboBox.setCurrentIndex(0)
self.schemaComboBox.setEnabled(False)
-
-
+
@pyqtSlot(int)
def on_allAttributesCheckBox_stateChanged(self, state):
if state == 2:
@@ -134,13 +145,13 @@ def on_allAttributesCheckBox_stateChanged(self, state):
if state == 0:
self.allTablesCheckBox.setEnabled(True)
self.attributeComboBox.setEnabled(True)
-
+
def getTitle(self):
return self.title
-
+
def setTitle(self, title):
self.title = title
-
+
def validate(self):
if self.actionComboBox.currentIndex() == 0:
return False
@@ -157,20 +168,28 @@ def validate(self):
return True
def validateDiagnosis(self):
- invalidatedReason = ''
+ invalidatedReason = ""
if self.schemaComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A schema must be chosen.\n')
+ invalidatedReason += self.tr("A schema must be chosen.\n")
if self.tableComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A table must be chosen.\n')
+ invalidatedReason += self.tr("A table must be chosen.\n")
if self.actionComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An action be chosen.\n')
- if self.allAttributesCheckBox.checkState() != 2 and self.attributeComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An attribute must be chosen.\n')
+ invalidatedReason += self.tr("An action be chosen.\n")
+ if (
+ self.allAttributesCheckBox.checkState() != 2
+ and self.attributeComboBox.currentIndex() == 0
+ ):
+ invalidatedReason += self.tr("An attribute must be chosen.\n")
return invalidatedReason
-
+
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in change nullity customization ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in change nullity customization ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
if self.actionComboBox.currentIndex() == 1:
notNull = True
elif self.actionComboBox.currentIndex() == 2:
@@ -179,20 +198,32 @@ def getJSONTag(self):
if self.allTablesCheckBox.checkState() == 2:
attributeJsonList = self.abstractDb.getAttributeJsonFromDb()
for attributeJson in attributeJsonList:
- schema = attributeJson['table_schema']
- table = attributeJson['table_name']
- for attrName in attributeJson['attributelist']:
- jsonList.append(self.jsonBuilder.buildChangeNullityElement(schema, table, attrName, notNull))
+ schema = attributeJson["table_schema"]
+ table = attributeJson["table_name"]
+ for attrName in attributeJson["attributelist"]:
+ jsonList.append(
+ self.jsonBuilder.buildChangeNullityElement(
+ schema, table, attrName, notNull
+ )
+ )
else:
schema = self.schemaComboBox.currentText()
table = self.tableComboBox.currentText()
if self.allAttributesCheckBox.checkState() == 2:
attrList = self.abstractDb.getAttributeListFromTable(schema, table)
for attrName in attrList:
- jsonList.append(self.jsonBuilder.buildChangeNullityElement(schema, table, attrName, notNull))
+ jsonList.append(
+ self.jsonBuilder.buildChangeNullityElement(
+ schema, table, attrName, notNull
+ )
+ )
else:
attrName = self.attributeComboBox.currentText()
- jsonList.append(self.jsonBuilder.buildChangeNullityElement(schema, table, attrName, notNull))
+ jsonList.append(
+ self.jsonBuilder.buildChangeNullityElement(
+ schema, table, attrName, notNull
+ )
+ )
return jsonList
def getUiParameterJsonDict(self):
@@ -208,10 +239,12 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText()
- uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText()
- uiParameterJsonDict['allAttributesCheckBox'] = self.allAttributesCheckBox.isChecked()
- uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked()
- uiParameterJsonDict['attributeComboBox'] = self.attributeComboBox.currentText()
- uiParameterJsonDict['actionComboBoxIdx'] = self.actionComboBox.currentIndex()
- return uiParameterJsonDict
\ No newline at end of file
+ uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText()
+ uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText()
+ uiParameterJsonDict[
+ "allAttributesCheckBox"
+ ] = self.allAttributesCheckBox.isChecked()
+ uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked()
+ uiParameterJsonDict["attributeComboBox"] = self.attributeComboBox.currentText()
+ uiParameterJsonDict["actionComboBoxIdx"] = self.actionComboBox.currentIndex()
+ return uiParameterJsonDict
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py
index 6576ff32b..34f09b99c 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/codeNameCustomizationWidget.py
@@ -33,13 +33,17 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "codeNameCustomizationWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'codeNameCustomizationWidget.ui'))
class CodeNameCustomizationWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
@@ -48,7 +52,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.domainDict = dict()
self.populateDomainCombo()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
builds ui from uiParameterJsonDict
@@ -59,33 +63,37 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- domainIdx = self.domainComboBox.findText(uiParameterJsonDict['domainComboBox'], flags = Qt.MatchExactly)
+ domainIdx = self.domainComboBox.findText(
+ uiParameterJsonDict["domainComboBox"], flags=Qt.MatchExactly
+ )
self.domainComboBox.setCurrentIndex(domainIdx)
- oldIdx = self.oldCodeNameComboBox.findText(uiParameterJsonDict['oldCodeNameComboBox'], flags = Qt.MatchExactly)
+ oldIdx = self.oldCodeNameComboBox.findText(
+ uiParameterJsonDict["oldCodeNameComboBox"], flags=Qt.MatchExactly
+ )
self.oldCodeNameComboBox.setCurrentIndex(oldIdx)
- self.newCodeNameLineEdit.setText(uiParameterJsonDict['newCodeNameLineEdit'])
+ self.newCodeNameLineEdit.setText(uiParameterJsonDict["newCodeNameLineEdit"])
def getTitle(self):
return self.title
-
+
def setTitle(self, title):
self.title = title
-
+
def populateDomainCombo(self):
self.domainComboBox.clear()
- self.domainComboBox.addItem(self.tr('Choose a domain'))
+ self.domainComboBox.addItem(self.tr("Choose a domain"))
domainList = self.abstractDb.getDomainTables()
for domain in domainList:
self.domainComboBox.addItem(domain)
-
+
@pyqtSlot(int)
def on_domainComboBox_currentIndexChanged(self, idx):
if idx != 0:
domainName = self.domainComboBox.currentText()
self.oldCodeNameComboBox.setEnabled(True)
self.oldCodeNameComboBox.clear()
- self.oldCodeNameComboBox.addItem('Choose a code name')
- self.domainDict = self.abstractDb.getDomainDictV2('dominios.'+domainName)
+ self.oldCodeNameComboBox.addItem("Choose a code name")
+ self.domainDict = self.abstractDb.getDomainDictV2("dominios." + domainName)
for codeName in list(self.domainDict.keys()):
self.oldCodeNameComboBox.addItem(codeName)
self.newCodeNameLineEdit.setEnabled(True)
@@ -95,41 +103,50 @@ def on_domainComboBox_currentIndexChanged(self, idx):
self.newCodeNameLineEdit.clear()
self.oldCodeNameComboBox.setEnabled(False)
self.oldCodeNameComboBox.clear()
-
+
@pyqtSlot(int)
def on_oldCodeNameComboBox_currentIndexChanged(self, idx):
self.newCodeNameLineEdit.setEnabled(True)
self.newCodeNameLineEdit.clear()
-
+
def validate(self):
if self.domainComboBox.currentIndex() == 0:
return False
if self.oldCodeNameComboBox.currentIndex() == 0:
return False
- if self.newCodeNameLineEdit.text() == '':
+ if self.newCodeNameLineEdit.text() == "":
return False
return True
def validateDiagnosis(self):
- invalidatedReason = ''
+ invalidatedReason = ""
if self.domainComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A domain table must be chosen.\n')
+ invalidatedReason += self.tr("A domain table must be chosen.\n")
if self.oldCodeNameComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('An old code name value must be chosen.\n')
- if self.newCodeNameLineEdit.text() == '':
- invalidatedReason += self.tr('A new code name value must be chosen.\n')
+ invalidatedReason += self.tr("An old code name value must be chosen.\n")
+ if self.newCodeNameLineEdit.text() == "":
+ invalidatedReason += self.tr("A new code name value must be chosen.\n")
invalidatedReason += self.addAttributeWidget.validateDiagnosis()
return invalidatedReason
-
+
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in code name customization ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in code name customization ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
domainTable = self.domainComboBox.currentText()
oldCodeName = self.oldCodeNameComboBox.currentText()
newCodeName = self.newCodeNameLineEdit.text()
codeValue = self.domainDict[oldCodeName]
- return [self.jsonBuilder.buildCodeNameToChangeElement(domainTable, codeValue, oldCodeName, newCodeName)]
-
+ return [
+ self.jsonBuilder.buildCodeNameToChangeElement(
+ domainTable, codeValue, oldCodeName, newCodeName
+ )
+ ]
+
def getUiParameterJsonDict(self):
"""
builds a dict with the following format:
@@ -140,8 +157,9 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['domainComboBox'] = self.domainComboBox.currentText()
- uiParameterJsonDict['oldCodeNameComboBox'] = self.oldCodeNameComboBox.currentText()
- uiParameterJsonDict['newCodeNameLineEdit'] = self.newCodeNameLineEdit.text()
+ uiParameterJsonDict["domainComboBox"] = self.domainComboBox.currentText()
+ uiParameterJsonDict[
+ "oldCodeNameComboBox"
+ ] = self.oldCodeNameComboBox.currentText()
+ uiParameterJsonDict["newCodeNameLineEdit"] = self.newCodeNameLineEdit.text()
return uiParameterJsonDict
-
\ No newline at end of file
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py
index 6eacfde6d..fb02e7722 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/domainSetter.py
@@ -35,14 +35,19 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "domainSetter.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'domainSetter.ui'))
class DomainSetter(QtWidgets.QDialog, FORM_CLASS):
domainChanged = pyqtSignal(str, dict, dict)
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
@@ -53,7 +58,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.filterClause = dict()
self.jsonBuilder = CustomJSONBuilder()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
populates ui from uiParameterJsonDict with the following keys:
@@ -64,15 +69,19 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- item = self.domainListWidget.findItems(uiParameterJsonDict['domainListWidget'], Qt.MatchExactly)
- if isinstance(item,list):
+ item = self.domainListWidget.findItems(
+ uiParameterJsonDict["domainListWidget"], Qt.MatchExactly
+ )
+ if isinstance(item, list):
item = item[0]
self.domainListWidget.setCurrentItem(item)
- if uiParameterJsonDict['filterCheckBox']:
+ if uiParameterJsonDict["filterCheckBox"]:
self.filterCheckBox.setCheckState(QtCore.Qt.Checked)
- for codeName in uiParameterJsonDict['filterListWidgetCheckedItems']:
- codeNameItem = self.filterListWidget.findItems(codeName, Qt.MatchExactly)
- if isinstance(codeNameItem,list):
+ for codeName in uiParameterJsonDict["filterListWidgetCheckedItems"]:
+ codeNameItem = self.filterListWidget.findItems(
+ codeName, Qt.MatchExactly
+ )
+ if isinstance(codeNameItem, list):
codeNameItem = codeNameItem[0]
else:
codeNameItem = codeNameItem
@@ -84,7 +93,7 @@ def populateDomainList(self):
self.domainListWidget.clear()
for domain in self.domainTableList:
self.domainListWidget.addItem(domain)
-
+
def clearAll(self):
self.filterLineEdit.clear()
self.filterListWidget.clear()
@@ -96,12 +105,12 @@ def clearAll(self):
def enableItems(self, enabled):
self.filterListWidget.setEnabled(enabled)
-
+
def clearCheckableItems(self):
for idx in range(self.filterListWidget.__len__()):
item = self.filterListWidget.item(idx)
item.setCheckState(QtCore.Qt.Unchecked)
-
+
@pyqtSlot(int)
def on_filterCheckBox_stateChanged(self, idx):
if idx == 2:
@@ -110,49 +119,57 @@ def on_filterCheckBox_stateChanged(self, idx):
state = False
self.clearCheckableItems()
self.enableItems(state)
-
+
def getSelectedDomain(self):
return self.domainListWidget.selectedItems()[0].data()
-
+
@pyqtSlot(int)
def on_domainListWidget_currentRowChanged(self, idx):
curItem = self.domainListWidget.item(idx)
self.filterListWidget.clear()
if curItem:
self.domainName = curItem.data(0)
- self.domainDict = self.abstractDb.getDomainDictV2('dominios.'+self.domainName)
+ self.domainDict = self.abstractDb.getDomainDictV2(
+ "dominios." + self.domainName
+ )
for codeName in list(self.domainDict.keys()):
newItem = QListWidgetItem(codeName)
- newItem.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable)
+ newItem.setFlags(
+ QtCore.Qt.ItemIsEnabled
+ | QtCore.Qt.ItemIsTristate
+ | QtCore.Qt.ItemIsUserCheckable
+ )
newItem.setCheckState(QtCore.Qt.Unchecked)
self.filterListWidget.addItem(newItem)
-
+
def on_filterLineEdit_textChanged(self, text):
- '''
+ """
Filters the items to make it easier to spot and select them
- '''
- classes = [edgvDomain for edgvDomain in self.domainTableList if text in edgvDomain]
+ """
+ classes = [
+ edgvDomain for edgvDomain in self.domainTableList if text in edgvDomain
+ ]
self.domainListWidget.clear()
self.domainListWidget.addItems(classes)
self.domainListWidget.sortItems()
-
+
@pyqtSlot()
def on_buttonBox_rejected(self):
self.clearAll()
- @pyqtSlot(name='on_buttonBox_accepted')
+ @pyqtSlot(name="on_buttonBox_accepted")
def applyChanges(self):
for idx in range(self.filterListWidget.__len__()):
item = self.filterListWidget.item(idx)
if item.checkState() == 2:
- codeName = item.data(0)
+ codeName = item.data(0)
if codeName not in list(self.filterClause.keys()):
self.filterClause[codeName] = self.domainDict[codeName]
self.domainChanged.emit(self.domainName, self.domainDict, self.filterClause)
-
+
def getChildWidgets(self):
return None
-
+
def getUiParameterJsonDict(self):
"""
builds a dict with the following format:
@@ -163,11 +180,13 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['domainListWidget'] = self.domainListWidget.currentItem().data(0)
- uiParameterJsonDict['filterCheckBox'] = self.filterCheckBox.isChecked()
- uiParameterJsonDict['filterListWidgetCheckedItems'] = []
+ uiParameterJsonDict[
+ "domainListWidget"
+ ] = self.domainListWidget.currentItem().data(0)
+ uiParameterJsonDict["filterCheckBox"] = self.filterCheckBox.isChecked()
+ uiParameterJsonDict["filterListWidgetCheckedItems"] = []
for idx in range(self.filterListWidget.__len__()):
item = self.filterListWidget.item(idx)
if item.checkState() == 2:
- uiParameterJsonDict['filterListWidgetCheckedItems'].append(item.data(0))
- return uiParameterJsonDict
\ No newline at end of file
+ uiParameterJsonDict["filterListWidgetCheckedItems"].append(item.data(0))
+ return uiParameterJsonDict
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py
index b630dd299..4b0f4a5bf 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newAttributeWidget.py
@@ -33,13 +33,17 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newAttributeWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'newAttributeWidget.ui'))
class NewAttributeWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
@@ -48,7 +52,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.jsonBuilder = CustomJSONBuilder()
self.populateSchemaCombo()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
{
@@ -59,29 +63,35 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- if uiParameterJsonDict['allTablesCheckBox']:
+ if uiParameterJsonDict["allTablesCheckBox"]:
self.allTablesCheckBox.setCheckState(Qt.Checked)
else:
- schemaIdx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly)
+ schemaIdx = self.schemaComboBox.findText(
+ uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly
+ )
self.schemaComboBox.setCurrentIndex(schemaIdx)
- tableIdx = self.tableComboBox.findText(uiParameterJsonDict['tableComboBox'], flags = Qt.MatchExactly)
+ tableIdx = self.tableComboBox.findText(
+ uiParameterJsonDict["tableComboBox"], flags=Qt.MatchExactly
+ )
self.tableComboBox.setCurrentIndex(tableIdx)
- self.addAttributeWidget.populateFromUiParameterJsonDict(uiParameterJsonDict['attrWidget'])
-
+ self.addAttributeWidget.populateFromUiParameterJsonDict(
+ uiParameterJsonDict["attrWidget"]
+ )
+
def getTitle(self):
return self.title
-
+
def setTitle(self, title):
self.title = title
-
+
def populateSchemaCombo(self):
self.schemaComboBox.clear()
- self.schemaComboBox.addItem(self.tr('Select a schema'))
+ self.schemaComboBox.addItem(self.tr("Select a schema"))
schemaList = self.abstractDb.getGeometricSchemaList()
for schema in schemaList:
- if schema not in ['views', 'validation']:
+ if schema not in ["views", "validation"]:
self.schemaComboBox.addItem(schema)
-
+
@pyqtSlot(int)
def on_schemaComboBox_currentIndexChanged(self, idx):
if idx == 0:
@@ -91,13 +101,13 @@ def on_schemaComboBox_currentIndexChanged(self, idx):
schema = self.schemaComboBox.currentText()
self.tableComboBox.setEnabled(True)
self.tableComboBox.clear()
- self.tableComboBox.addItem(self.tr('Select a table'))
+ self.tableComboBox.addItem(self.tr("Select a table"))
tableList = self.abstractDb.getGeometricTableListFromSchema(schema)
for table in tableList:
self.tableComboBox.addItem(table)
-
+
@pyqtSlot(int)
- def on_allTablesCheckBox_stateChanged(self,idx):
+ def on_allTablesCheckBox_stateChanged(self, idx):
if idx == 2:
self.tableComboBox.clear()
self.tableComboBox.setEnabled(False)
@@ -106,43 +116,64 @@ def on_allTablesCheckBox_stateChanged(self,idx):
else:
self.schemaComboBox.setEnabled(True)
self.populateSchemaCombo()
-
+
def validate(self):
if not self.allTablesCheckBox.isChecked():
- if self.tableComboBox.currentText() == '':
+ if self.tableComboBox.currentText() == "":
return False
- if self.schemaComboBox.currentText() == '':
+ if self.schemaComboBox.currentText() == "":
return False
return self.addAttributeWidget.validate()
def validateDiagnosis(self):
- invalidatedReason = ''
+ invalidatedReason = ""
if self.tableComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A table name must be chosen.\n')
+ invalidatedReason += self.tr("A table name must be chosen.\n")
if self.schemaComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('A schema must be chosen.\n')
+ invalidatedReason += self.tr("A schema must be chosen.\n")
invalidatedReason += self.addAttributeWidget.validateDiagnosis()
return invalidatedReason
-
+
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in attribute ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in attribute ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
schema = self.schemaComboBox.currentText()
tableName = self.tableComboBox.currentText()
attrList = [self.addAttributeWidget.getJSONTag()]
if not self.allTablesCheckBox.isChecked():
- bloodLine = [i for i in self.abstractDb.getInheritanceBloodLine(tableName) if i != tableName]
- return [self.jsonBuilder.buildNewAttributeElement(schema, tableName, attrList, childrenToAlter = bloodLine)]
+ bloodLine = [
+ i
+ for i in self.abstractDb.getInheritanceBloodLine(tableName)
+ if i != tableName
+ ]
+ return [
+ self.jsonBuilder.buildNewAttributeElement(
+ schema, tableName, attrList, childrenToAlter=bloodLine
+ )
+ ]
else:
attrModList = []
- classTuppleList = self.abstractDb.getParentGeomTables(getTupple = True)
+ classTuppleList = self.abstractDb.getParentGeomTables(getTupple=True)
for tupple in classTuppleList:
schema, tableName = tupple
- if schema not in ('views', 'validation'):
- bloodLine = [i for i in self.abstractDb.getInheritanceBloodLine(tableName) if i != tableName]
- attrModList.append(self.jsonBuilder.buildNewAttributeElement(schema, tableName, attrList, childrenToAlter = bloodLine))
+ if schema not in ("views", "validation"):
+ bloodLine = [
+ i
+ for i in self.abstractDb.getInheritanceBloodLine(tableName)
+ if i != tableName
+ ]
+ attrModList.append(
+ self.jsonBuilder.buildNewAttributeElement(
+ schema, tableName, attrList, childrenToAlter=bloodLine
+ )
+ )
return attrModList
-
+
def getUiParameterJsonDict(self):
"""
builds a dict with the following format:
@@ -154,8 +185,10 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText()
- uiParameterJsonDict['tableComboBox'] = self.tableComboBox.currentText()
- uiParameterJsonDict['allTablesCheckBox'] = self.allTablesCheckBox.isChecked()
- uiParameterJsonDict['attrWidget'] = self.addAttributeWidget.getUiParameterJsonDict()
- return uiParameterJsonDict
\ No newline at end of file
+ uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText()
+ uiParameterJsonDict["tableComboBox"] = self.tableComboBox.currentText()
+ uiParameterJsonDict["allTablesCheckBox"] = self.allTablesCheckBox.isChecked()
+ uiParameterJsonDict[
+ "attrWidget"
+ ] = self.addAttributeWidget.getUiParameterJsonDict()
+ return uiParameterJsonDict
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py
index f91e1030b..a873affd5 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newClassWidget.py
@@ -34,31 +34,41 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import AddAttributeWidget
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import (
+ AddAttributeWidget,
+)
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newClassWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'newClassWidget.ui'))
class NewClassWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
- self.geomUiDict = {self.tr('Point'):{'sufix':'p','type':'MULTIPOINT([epsg])'}, self.tr('Line'):{'sufix':'l','type':'MULTILINESTRING([epsg])'}, self.tr('Area'):{'sufix':'a','type':'MULTIPOLYGON([epsg])'}}
+ self.geomUiDict = {
+ self.tr("Point"): {"sufix": "p", "type": "MULTIPOINT([epsg])"},
+ self.tr("Line"): {"sufix": "l", "type": "MULTILINESTRING([epsg])"},
+ self.tr("Area"): {"sufix": "a", "type": "MULTIPOLYGON([epsg])"},
+ }
header = self.tableWidget.horizontalHeader()
header.setStretchLastSection(True)
- regex = QtCore.QRegExp('[a-z][a-z\_]*')
+ regex = QtCore.QRegExp("[a-z][a-z\_]*")
validator = QtGui.QRegExpValidator(regex, self.classNameLineEdit)
self.classNameLineEdit.setValidator(validator)
- regex2 = QtCore.QRegExp('[a-z]*')
+ regex2 = QtCore.QRegExp("[a-z]*")
validator2 = QtGui.QRegExpValidator(regex2, self.categoryLineEdit)
self.categoryLineEdit.setValidator(validator2)
self.abstractDb = abstractDb
self.populateSchemaCombo()
self.jsonBuilder = CustomJSONBuilder()
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
populates ui from uiParameterJsonDict with the following keys:
@@ -71,40 +81,46 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- idx = self.schemaComboBox.findText(uiParameterJsonDict['schemaComboBox'], flags = Qt.MatchExactly)
+ idx = self.schemaComboBox.findText(
+ uiParameterJsonDict["schemaComboBox"], flags=Qt.MatchExactly
+ )
self.schemaComboBox.setCurrentIndex(idx)
- self.categoryLineEdit.setText(uiParameterJsonDict['categoryLineEdit'])
- self.classNameLineEdit.setText(uiParameterJsonDict['classNameLineEdit'])
- self.geomComboBox.setCurrentIndex(int(uiParameterJsonDict['geomComboBoxIdx']))
- for attr in uiParameterJsonDict['attrWidgetList']:
+ self.categoryLineEdit.setText(uiParameterJsonDict["categoryLineEdit"])
+ self.classNameLineEdit.setText(uiParameterJsonDict["classNameLineEdit"])
+ self.geomComboBox.setCurrentIndex(
+ int(uiParameterJsonDict["geomComboBoxIdx"])
+ )
+ for attr in uiParameterJsonDict["attrWidgetList"]:
self.addCellWidget(uiParameterJsonDict=attr)
-
+
def populateSchemaCombo(self):
self.schemaComboBox.clear()
schemaList = self.abstractDb.getGeometricSchemaList()
for schema in schemaList:
- if schema not in ['views', 'validation']:
+ if schema not in ["views", "validation"]:
self.schemaComboBox.addItem(schema)
-
+
@pyqtSlot()
def on_classNameLineEdit_editingFinished(self):
text = self.classNameLineEdit.text()
- while text[-1] == '_':
+ while text[-1] == "_":
self.classNameLineEdit.setText(text[0:-1])
text = text[0:-1]
-
+
@pyqtSlot(str)
def on_classNameLineEdit_textEdited(self, newText):
if len(newText) > 1:
- if newText[-1] == '_' and newText[-2] == '_':
- self.classNameLineEdit.setText(newText[0:-1])
-
- @pyqtSlot(bool, name='on_addAttributePushButton_clicked')
- def addCellWidget(self, uiParameterJsonDict = None):
+ if newText[-1] == "_" and newText[-2] == "_":
+ self.classNameLineEdit.setText(newText[0:-1])
+
+ @pyqtSlot(bool, name="on_addAttributePushButton_clicked")
+ def addCellWidget(self, uiParameterJsonDict=None):
index = self.tableWidget.rowCount()
self.tableWidget.insertRow(index)
- newAttribute = AddAttributeWidget(self.abstractDb, uiParameterJsonDict = uiParameterJsonDict)
- self.tableWidget.setCellWidget(index,0,newAttribute)
+ newAttribute = AddAttributeWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.tableWidget.setCellWidget(index, 0, newAttribute)
@pyqtSlot(bool)
def on_removePushButton_clicked(self):
@@ -113,61 +129,77 @@ def on_removePushButton_clicked(self):
rowList.sort(reverse=True)
for row in rowList:
self.tableWidget.removeRow(row)
-
+
def getTitle(self):
return self.title
-
+
def setTitle(self, title):
self.title = title
-
+
def getChildWidgetList(self):
childWidgetList = []
for i in range(self.tableWidget.rowCount()):
- childWidgetList.append(self.tableWidget.cellWidget(i,0))
+ childWidgetList.append(self.tableWidget.cellWidget(i, 0))
return childWidgetList
-
+
def validate(self):
- if self.categoryLineEdit.text() == '':
+ if self.categoryLineEdit.text() == "":
return False
- if self.classNameLineEdit.text() == '':
+ if self.classNameLineEdit.text() == "":
return False
if self.geomComboBox.currentIndex() == 0:
return False
- #TODO: validate attributes
+ # TODO: validate attributes
return True
def validateDiagnosis(self):
- invalidatedReason = ''
- if self.categoryLineEdit.text() == '':
- invalidatedReason += self.tr('Class must have a category.\n')
- if self.classNameLineEdit.text() == '':
- invalidatedReason += self.tr('Class must have a name.\n')
+ invalidatedReason = ""
+ if self.categoryLineEdit.text() == "":
+ invalidatedReason += self.tr("Class must have a category.\n")
+ if self.classNameLineEdit.text() == "":
+ invalidatedReason += self.tr("Class must have a name.\n")
if self.geomComboBox.currentIndex() == 0:
- invalidatedReason += self.tr('Class must have a geometric primitive.\n')
- #TODO: validate attributes
+ invalidatedReason += self.tr("Class must have a geometric primitive.\n")
+ # TODO: validate attributes
return invalidatedReason
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in class ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in class ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
schema = self.schemaComboBox.currentText()
- name = '_'.join([ self.categoryLineEdit.text(), self.classNameLineEdit.text(), self.geomUiDict[self.geomComboBox.currentText()]['sufix'] ])
+ name = "_".join(
+ [
+ self.categoryLineEdit.text(),
+ self.classNameLineEdit.text(),
+ self.geomUiDict[self.geomComboBox.currentText()]["sufix"],
+ ]
+ )
widgetList = self.getChildWidgetList()
attrList = []
- #create pk attr
- pkItem = self.jsonBuilder.buildAttributeElement('id', 'serial', True, False)
+ # create pk attr
+ pkItem = self.jsonBuilder.buildAttributeElement("id", "serial", True, False)
attrList.append(pkItem)
- #create geom attr
- geomItem = self.jsonBuilder.buildAttributeElement('geom', self.geomUiDict[self.geomComboBox.currentText()]['type'], False, False)
+ # create geom attr
+ geomItem = self.jsonBuilder.buildAttributeElement(
+ "geom",
+ self.geomUiDict[self.geomComboBox.currentText()]["type"],
+ False,
+ False,
+ )
attrList.append(geomItem)
for widget in widgetList:
newAttrJson = widget.getJSONTag()
- if isinstance(newAttrJson,list):
+ if isinstance(newAttrJson, list):
for i in newAttrJson:
attrList.append(i)
else:
attrList.append(newAttrJson)
- return [self.jsonBuilder.buildClassElement(schema,name,attrList)]
+ return [self.jsonBuilder.buildClassElement(schema, name, attrList)]
def getUiParameterJsonDict(self):
"""
@@ -181,14 +213,14 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['schemaComboBox'] = self.schemaComboBox.currentText()
- uiParameterJsonDict['categoryLineEdit'] = self.categoryLineEdit.text()
- uiParameterJsonDict['classNameLineEdit'] = self.classNameLineEdit.text()
- uiParameterJsonDict['geomComboBoxIdx'] = self.geomComboBox.currentIndex()
- uiParameterJsonDict['attrWidgetList'] = []
+ uiParameterJsonDict["schemaComboBox"] = self.schemaComboBox.currentText()
+ uiParameterJsonDict["categoryLineEdit"] = self.categoryLineEdit.text()
+ uiParameterJsonDict["classNameLineEdit"] = self.classNameLineEdit.text()
+ uiParameterJsonDict["geomComboBoxIdx"] = self.geomComboBox.currentIndex()
+ uiParameterJsonDict["attrWidgetList"] = []
widgetList = self.getChildWidgetList()
for widget in widgetList:
- uiParameterJsonDict['attrWidgetList'].append(widget.getUiParameterJsonDict())
+ uiParameterJsonDict["attrWidgetList"].append(
+ widget.getUiParameterJsonDict()
+ )
return uiParameterJsonDict
-
-
\ No newline at end of file
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py
index 86377a8ca..0273167da 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainValueWidget.py
@@ -33,24 +33,28 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newDomainValueWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'newDomainValueWidget.ui'))
class NewDomainValueWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.abstractDb = abstractDb
self.setupUi(self)
self.jsonBuilder = CustomJSONBuilder()
self.populateDomainCombo()
- regex = QtCore.QRegExp('[0-9]*')
+ regex = QtCore.QRegExp("[0-9]*")
validator = QtGui.QRegExpValidator(regex, self.codeLineEdit)
self.codeLineEdit.setValidator(validator)
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
builds ui from uiParameterJsonDict
@@ -62,21 +66,23 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- if uiParameterJsonDict['allDomainCheckBox']:
+ if uiParameterJsonDict["allDomainCheckBox"]:
self.allDomainCheckBox.setCheckState(Qt.Checked)
else:
- domainIdx = self.domainComboBox.findText(uiParameterJsonDict['domainComboBox'], flags = Qt.MatchExactly)
+ domainIdx = self.domainComboBox.findText(
+ uiParameterJsonDict["domainComboBox"], flags=Qt.MatchExactly
+ )
self.domainComboBox.setCurrentIndex(domainIdx)
- self.codeLineEdit.setText(uiParameterJsonDict['codeLineEdit'])
- self.codeNameLineEdit.setText(uiParameterJsonDict['codeNameLineEdit'])
-
+ self.codeLineEdit.setText(uiParameterJsonDict["codeLineEdit"])
+ self.codeNameLineEdit.setText(uiParameterJsonDict["codeNameLineEdit"])
+
def populateDomainCombo(self):
self.domainTableList = self.abstractDb.getDomainTables()
self.domainComboBox.clear()
- self.domainComboBox.addItem(self.tr('Select a domain'))
+ self.domainComboBox.addItem(self.tr("Select a domain"))
for domain in self.domainTableList:
self.domainComboBox.addItem(domain)
-
+
@pyqtSlot(int)
def on_domainComboBox_currentIndexChanged(self, idx):
if idx == 0:
@@ -88,7 +94,7 @@ def on_domainComboBox_currentIndexChanged(self, idx):
self.codeLineEdit.setEnabled(True)
self.codeNameLineEdit.setEnabled(True)
self.codeLineEdit.editingFinished.emit()
-
+
@pyqtSlot(int)
def on_allDomainCheckBox_stateChanged(self, state):
if state == 2:
@@ -96,38 +102,42 @@ def on_allDomainCheckBox_stateChanged(self, state):
else:
self.populateDomainCombo()
self.codeLineEdit.editingFinished.emit()
-
+
@pyqtSlot()
def on_codeLineEdit_editingFinished(self):
if self.domainComboBox.currentIndex() == 0:
- self.codeLineEdit.setStyleSheet('')
- self.codeLineEdit.setToolTip('')
+ self.codeLineEdit.setStyleSheet("")
+ self.codeLineEdit.setToolTip("")
return
if self.allDomainCheckBox.checkState() == 2:
domainValues = self.abstractDb.getAllDomainValues()
else:
- domainValues = self.abstractDb.getAllDomainValues(domainTableList = [self.domainComboBox.currentText()])
+ domainValues = self.abstractDb.getAllDomainValues(
+ domainTableList=[self.domainComboBox.currentText()]
+ )
currentValue = self.codeLineEdit.text()
- if currentValue == '':
- self.codeLineEdit.setStyleSheet('')
- self.codeLineEdit.setToolTip('')
+ if currentValue == "":
+ self.codeLineEdit.setStyleSheet("")
+ self.codeLineEdit.setToolTip("")
elif int(currentValue) in domainValues:
self.codeLineEdit.setStyleSheet("border: 1px solid red;")
- self.codeLineEdit.setToolTip(self.tr('Code value already exists, choose another.'))
+ self.codeLineEdit.setToolTip(
+ self.tr("Code value already exists, choose another.")
+ )
else:
- self.codeLineEdit.setStyleSheet('')
- self.codeLineEdit.setToolTip('')
+ self.codeLineEdit.setStyleSheet("")
+ self.codeLineEdit.setToolTip("")
def getTitle(self):
return self.title
-
+
def setTitle(self, title):
self.title = title
def validate(self):
- if self.codeLineEdit.text() == '':
+ if self.codeLineEdit.text() == "":
return False
- if self.codeNameLineEdit.text() == '':
+ if self.codeNameLineEdit.text() == "":
return False
if self.allDomainCheckBox.checkState() == 2:
return True
@@ -137,27 +147,39 @@ def validate(self):
return True
def validateDiagnosis(self):
- invalidatedReason = ''
- if self.codeLineEdit.text() == '':
- invalidatedReason += self.tr('A code value must be entered.\n')
- if self.codeNameLineEdit.text() == '':
- invalidatedReason += self.tr('A code name value must be entered.\n')
- if self.domainComboBox.currentIndex() == 0 and self.allDomainCheckBox.checkState() != 2:
- invalidatedReason += self.tr('A domain table must be chosen.\n')
+ invalidatedReason = ""
+ if self.codeLineEdit.text() == "":
+ invalidatedReason += self.tr("A code value must be entered.\n")
+ if self.codeNameLineEdit.text() == "":
+ invalidatedReason += self.tr("A code name value must be entered.\n")
+ if (
+ self.domainComboBox.currentIndex() == 0
+ and self.allDomainCheckBox.checkState() != 2
+ ):
+ invalidatedReason += self.tr("A domain table must be chosen.\n")
return invalidatedReason
-
+
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in new domain value ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in new domain value ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
code = self.codeLineEdit.text()
codeName = self.codeNameLineEdit.text()
jsonList = []
if self.allDomainCheckBox.checkState() != 2:
domainName = self.domainComboBox.currentText()
- jsonList.append(self.jsonBuilder.addDomainValueElement(domainName, code, codeName))
+ jsonList.append(
+ self.jsonBuilder.addDomainValueElement(domainName, code, codeName)
+ )
else:
for domainName in self.domainTableList:
- jsonList.append(self.jsonBuilder.addDomainValueElement(domainName, code, codeName))
+ jsonList.append(
+ self.jsonBuilder.addDomainValueElement(domainName, code, codeName)
+ )
return jsonList
def getUiParameterJsonDict(self):
@@ -171,9 +193,8 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['domainComboBox'] = self.domainComboBox.currentText()
- uiParameterJsonDict['allDomainCheckBox'] = self.allDomainCheckBox.isChecked()
- uiParameterJsonDict['codeLineEdit'] = self.codeLineEdit.text()
- uiParameterJsonDict['codeNameLineEdit'] = self.codeNameLineEdit.text()
+ uiParameterJsonDict["domainComboBox"] = self.domainComboBox.currentText()
+ uiParameterJsonDict["allDomainCheckBox"] = self.allDomainCheckBox.isChecked()
+ uiParameterJsonDict["codeLineEdit"] = self.codeLineEdit.text()
+ uiParameterJsonDict["codeNameLineEdit"] = self.codeNameLineEdit.text()
return uiParameterJsonDict
-
\ No newline at end of file
diff --git a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py
index 9b9a22421..fee16f0cb 100644
--- a/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py
+++ b/DsgTools/gui/CustomWidgets/CustomDbManagementWidgets/newDomainWidget.py
@@ -35,36 +35,43 @@
from DsgTools.gui.ServerTools.viewServers import ViewServers
from DsgTools.core.Factories.SqlFactory.sqlGeneratorFactory import SqlGeneratorFactory
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import AddAttributeWidget
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import CustomJSONBuilder
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.addAttributeWidget import (
+ AddAttributeWidget,
+)
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONBuilder import (
+ CustomJSONBuilder,
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'newDomainWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "newDomainWidget.ui")
+)
+
class ValidatedItemDelegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, widget, option, index):
if not index.isValid():
return 0
- if index.column() == 0: #only on the cells in the first column
+ if index.column() == 0: # only on the cells in the first column
editor = QtGui.QLineEdit(widget)
validator = QtGui.QRegExpValidator(QtCore.QRegExp("[0-9]*"), editor)
editor.setValidator(validator)
return editor
elif index.column() == 1:
editor = QtGui.QLineEdit(widget)
- editor.setPlaceholderText(self.tr('Enter a value.'))
+ editor.setPlaceholderText(self.tr("Enter a value."))
return editor
return super(ValidatedItemDelegate, self).createEditor(widget, option, index)
+
class NewDomainWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
+ def __init__(self, abstractDb, uiParameterJsonDict=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
- self.setupUi(self)
+ self.setupUi(self)
header = self.tableWidget.horizontalHeader()
header.setStretchLastSection(True)
- regex = QtCore.QRegExp('[a-z][a-z\_]*')
+ regex = QtCore.QRegExp("[a-z][a-z\_]*")
validator = QtGui.QRegExpValidator(regex, self.domainNameLineEdit)
self.domainNameLineEdit.setValidator(validator)
self.abstractDb = abstractDb
@@ -72,7 +79,7 @@ def __init__(self, abstractDb, uiParameterJsonDict = None, parent = None):
self.tableWidget.setItemDelegate(ValidatedItemDelegate())
self.oldBackground = None
self.populateFromUiParameterJsonDict(uiParameterJsonDict)
-
+
def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
"""
populates ui from uiParameterJsonDict with the following keys:
@@ -82,34 +89,36 @@ def populateFromUiParameterJsonDict(self, uiParameterJsonDict):
}
"""
if uiParameterJsonDict:
- self.domainNameLineEdit.setText(uiParameterJsonDict['domainNameLineEdit'])
- for domainItem in uiParameterJsonDict['tableWidget']:
- self.addItemInTableWidget(codeText = domainItem[0], valueText = domainItem[1])
-
+ self.domainNameLineEdit.setText(uiParameterJsonDict["domainNameLineEdit"])
+ for domainItem in uiParameterJsonDict["tableWidget"]:
+ self.addItemInTableWidget(
+ codeText=domainItem[0], valueText=domainItem[1]
+ )
+
@pyqtSlot()
def on_domainNameLineEdit_editingFinished(self):
text = self.domainNameLineEdit.text()
- while text[-1] == '_':
+ while text[-1] == "_":
self.domainNameLineEdit.setText(text[0:-1])
text = text[0:-1]
-
+
@pyqtSlot(str)
def on_domainNameLineEdit_textEdited(self, newText):
if len(newText) > 1:
- if newText[-1] == '_' and newText[-2] == '_':
- self.domainNameLineEdit.setText(newText[0:-1])
-
- @pyqtSlot(bool, name='on_addValuePushButton_clicked')
- def addItemInTableWidget(self, codeText = '', valueText = ''):
+ if newText[-1] == "_" and newText[-2] == "_":
+ self.domainNameLineEdit.setText(newText[0:-1])
+
+ @pyqtSlot(bool, name="on_addValuePushButton_clicked")
+ def addItemInTableWidget(self, codeText="", valueText=""):
index = self.tableWidget.rowCount()
self.tableWidget.insertRow(index)
codeItem = QtGui.QTableWidgetItem(codeText)
valueItem = QtGui.QTableWidgetItem(valueText)
- self.tableWidget.setItem(self.tableWidget.rowCount()-1, 0, codeItem)
- self.tableWidget.setItem(self.tableWidget.rowCount()-1, 1, valueItem)
+ self.tableWidget.setItem(self.tableWidget.rowCount() - 1, 0, codeItem)
+ self.tableWidget.setItem(self.tableWidget.rowCount() - 1, 1, valueItem)
if index == 0:
- self.oldBackground = self.tableWidget.item(0,0).background()
-
+ self.oldBackground = self.tableWidget.item(0, 0).background()
+
@pyqtSlot(bool)
def on_removeValuePushButton_clicked(self):
selected = self.tableWidget.selectedIndexes()
@@ -117,74 +126,74 @@ def on_removeValuePushButton_clicked(self):
rowList.sort(reverse=True)
for row in rowList:
self.tableWidget.removeRow(row)
-
+
@pyqtSlot(QTableWidgetItem)
def on_tableWidget_itemChanged(self, widgetItem):
if self.checkNull(widgetItem):
return
if self.tableWidget.currentColumn() == 0:
self.checkUnique(widgetItem)
-
+
def checkNull(self, widgetItem):
- if widgetItem.text() == '':
- widgetItem.setToolTip(self.tr('Enter a value!'))
+ if widgetItem.text() == "":
+ widgetItem.setToolTip(self.tr("Enter a value!"))
return True
else:
- widgetItem.setToolTip('')
+ widgetItem.setToolTip("")
return False
-
+
def checkUnique(self, widgetItem):
- currentValue = widgetItem.text()
+ currentValue = widgetItem.text()
itemList = []
for i in range(self.tableWidget.rowCount()):
if i != widgetItem.row():
curItem = self.tableWidget.item(i, 0)
itemList.append(curItem.text())
if currentValue in itemList:
- widgetItem.setBackground(QtGui.QColor(230,124,127))
+ widgetItem.setBackground(QtGui.QColor(230, 124, 127))
self.tableWidget.setCurrentCell(widgetItem.row(), 0)
- widgetItem.setToolTip(self.tr('Code value already entered.'))
+ widgetItem.setToolTip(self.tr("Code value already entered."))
else:
if self.oldBackground:
widgetItem.setBackground(self.oldBackground)
- widgetItem.setToolTip('')
-
+ widgetItem.setToolTip("")
+
def getTitle(self):
return self.title
-
+
def setTitle(self, title):
self.title = title
-
+
def validate(self):
- if self.domainNameLineEdit.text() == '':
+ if self.domainNameLineEdit.text() == "":
return False
if self.tableHasEmptyValue():
return False
if self.tableHasDuplicatedCode():
- return False
+ return False
return True
def validateDiagnosis(self):
- invalidatedReason = ''
- if self.domainNameLineEdit.text() == '':
- invalidatedReason += self.tr('A domain name must be chosen.\n')
+ invalidatedReason = ""
+ if self.domainNameLineEdit.text() == "":
+ invalidatedReason += self.tr("A domain name must be chosen.\n")
if self.tableHasEmptyValue():
- invalidatedReason += self.tr('There must be no empty codes or values.\n')
+ invalidatedReason += self.tr("There must be no empty codes or values.\n")
if self.tableHasEmptyValue():
- invalidatedReason += self.tr('Codes must be unique.\n')
+ invalidatedReason += self.tr("Codes must be unique.\n")
return invalidatedReason
def tableHasEmptyValue(self):
for row in range(self.tableWidget.rowCount()):
for column in range(self.tableWidget.columnCount()):
- if self.tableWidget.item(row,column).text() == '':
+ if self.tableWidget.item(row, column).text() == "":
return True
return False
-
+
def tableHasDuplicatedCode(self):
listOfCodes = []
for row in range(self.tableWidget.rowCount()):
- code = self.tableWidget.item(row,0)
+ code = self.tableWidget.item(row, 0)
if code not in listOfCodes:
listOfCodes.append(code)
else:
@@ -193,12 +202,17 @@ def tableHasDuplicatedCode(self):
def getJSONTag(self):
if not self.validate():
- raise Exception(self.tr('Error in domain ')+ self.title + ' : ' + self.validateDiagnosis())
+ raise Exception(
+ self.tr("Error in domain ")
+ + self.title
+ + " : "
+ + self.validateDiagnosis()
+ )
domainName = self.domainNameLineEdit.text()
valueDict = dict()
for row in range(self.tableWidget.rowCount()):
- code = self.tableWidget.item(row,0).text()
- value = self.tableWidget.item(row,1).text()
+ code = self.tableWidget.item(row, 0).text()
+ value = self.tableWidget.item(row, 1).text()
valueDict[code] = value
return [self.jsonBuilder.addDomainTableElement(domainName, valueDict)]
@@ -211,10 +225,10 @@ def getUiParameterJsonDict(self):
}
"""
uiParameterJsonDict = dict()
- uiParameterJsonDict['domainNameLineEdit'] = self.domainNameLineEdit.text()
- uiParameterJsonDict['tableWidget'] = []
+ uiParameterJsonDict["domainNameLineEdit"] = self.domainNameLineEdit.text()
+ uiParameterJsonDict["tableWidget"] = []
for row in range(self.tableWidget.rowCount()):
- code = self.tableWidget.item(row,0).text()
- value = self.tableWidget.item(row,1).text()
- uiParameterJsonDict['tableWidget'].append((code,value))
- return uiParameterJsonDict
\ No newline at end of file
+ code = self.tableWidget.item(row, 0).text()
+ value = self.tableWidget.item(row, 1).text()
+ uiParameterJsonDict["tableWidget"].append((code, value))
+ return uiParameterJsonDict
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py
index 8d1c8b69c..e69de29bb 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/__init__.py
@@ -1 +0,0 @@
-
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py
index b5ad16451..a0377f29e 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/abstractMultiDsSelectorWidget.py
@@ -1,4 +1,3 @@
-
# -*- coding: utf-8 -*-
"""
/***************************************************************************
@@ -24,11 +23,13 @@
from qgis.PyQt.QtCore import QObject
+
class AbstractMultiDsSelectorWidget(QObject):
"""
Class containing minimum structure for multiple datasource selection.
- Particularities from each driver are settled within its own class (child from this).
+ Particularities from each driver are settled within its own class (child from this).
"""
+
def __init__(self, parent=None):
"""
Class constructor.
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py
index 38fabae3a..0d164c994 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiGeopackageSelectorWidget.py
@@ -29,10 +29,12 @@
import os
+
class MultiGeopackageSelectorWidget(AbstractMultiDsSelectorWidget):
"""
Class designed to retrieve a Geopackage database list.
"""
+
def __init__(self, parent=None):
"""
Class constructor.
@@ -60,8 +62,10 @@ def exec_(self):
"""
# clear datasources
self.datasources = {}
- dbList = self.selector.getOpenFileNames(caption=self.tr("Select Geopackage Databases"), \
- filter=self.tr('Geopackage Databases (*.gpkg)'))[0]
+ dbList = self.selector.getOpenFileNames(
+ caption=self.tr("Select Geopackage Databases"),
+ filter=self.tr("Geopackage Databases (*.gpkg)"),
+ )[0]
for db in dbList:
self.datasources[db] = os.path.dirname(db)
- return int(not self.datasources) # execution code
+ return int(not self.datasources) # execution code
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py
index 3b0eb109a..32fa3fa74 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiNewDsSelector.py
@@ -29,19 +29,23 @@
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'multiNewDsSelector.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "multiNewDsSelector.ui")
+)
+
class MultiNewDsSelector(QDialog, FORM_CLASS):
"""
Class designed to control multiple (new) datasource selection widget.
"""
+
def __init__(self, parent=None):
"""
Class constructor
"""
super(MultiNewDsSelector, self).__init__(parent)
self.setupUi(self)
- self.edgv = ''
+ self.edgv = ""
self.crs = None
self.numberOfDs = 0
self.fillEdgvVersions()
@@ -50,15 +54,14 @@ def __init__(self, parent=None):
def fillEdgvVersions(self):
"""
- Populates EDGV combo box with available versions.
+ Populates EDGV combo box with available versions.
"""
versions = [
self.tr("EDGV Version..."),
"EDGV 2.1.3",
- "EDGV 2.1.3 F Ter"
- "EDGV 2.1.3 Pro",
+ "EDGV 2.1.3 F Ter" "EDGV 2.1.3 Pro",
"EDGV 3.0",
- "EDGV 3.0 Pro"
+ "EDGV 3.0 Pro",
]
self.edgvComboBox.addItems(versions)
@@ -75,7 +78,7 @@ def edgvVersion(self):
:return: (str) EDGV version.
"""
edgv = self.edgvComboBox.currentText()
- return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else ''
+ return edgv if not edgv is None and edgv != self.tr("EDGV Version...") else ""
def authId(self):
"""
@@ -83,7 +86,7 @@ def authId(self):
:return: (str) EDGV version.
"""
crs = self.getCrs()
- return crs.authid() if not crs is None and crs.isValid() else ''
+ return crs.authid() if not crs is None and crs.isValid() else ""
def getCrs(self):
"""
@@ -105,10 +108,10 @@ def on_okPushButton_clicked(self):
for i in range(self.amount()):
# add an entry for each desired datasource
# in here, we may change for an automatic datasource name to be passed on as dict key
- self.datasources[i] = { 'edgv' : self.edgvVersion(), 'crs' : self.getCrs() }
+ self.datasources[i] = {"edgv": self.edgvVersion(), "crs": self.getCrs()}
self.close()
return 0
- QMessageBox.warning(self, self.tr('Warning!'), self.validate())
+ QMessageBox.warning(self, self.tr("Warning!"), self.validate())
return 1
@pyqtSlot(bool)
@@ -130,15 +133,15 @@ def validate(self):
"""
# check amount of servers selection
if self.amount() == 0:
- return self.tr('Select the amount of datasources to be created.')
+ return self.tr("Select the amount of datasources to be created.")
# check if a valid EDGV version was selected
if not self.edgvVersion():
- return self.tr('Invalid EDGV version.')
+ return self.tr("Invalid EDGV version.")
# check if a valid projection was selected
- if not self.getCrs() or 'EPSG' not in self.authId():
- return self.tr('Invalid CRS.')
+ if not self.getCrs() or "EPSG" not in self.authId():
+ return self.tr("Invalid CRS.")
# if all tests were positive, widget has a valid selection
- return ''
+ return ""
def isValid(self):
"""
@@ -146,4 +149,4 @@ def isValid(self):
:return: (bool) invalidation status.
"""
msg = self.validate()
- return msg == ''
+ return msg == ""
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py
index 43c0cb272..f6e692516 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiPostgisSelectorWidget.py
@@ -1,4 +1,3 @@
-
# -*- coding: utf-8 -*-
"""
/***************************************************************************
@@ -27,29 +26,37 @@
from qgis.PyQt.QtWidgets import QWidget, QCheckBox, QDialog
from .abstractMultiDsSelectorWidget import AbstractMultiDsSelectorWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.ServerConnectionWidgets.exploreServerWidget import ExploreServerWidget
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.ServerConnectionWidgets.exploreServerWidget import (
+ ExploreServerWidget,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
from operator import itemgetter
-FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'multiPostgisSelectorWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "multiPostgisSelectorWidget.ui")
+)
+
class MultiPostgisSelector(QDialog, FORM_CLASS):
"""
Class designed to manipulate just the driver selection behavior. Handles reading and inserting data into GUI.
"""
+
def __init__(self, parent=None):
"""
Class constructor.
"""
super(MultiPostgisSelector, self).__init__(parent)
self.setupUi(self)
- self.serverName = ''
+ self.serverName = ""
self.dbList = []
- self.exploreServerWidget.serversCombo.currentIndexChanged.connect(self.serverUpdated)
+ self.exploreServerWidget.serversCombo.currentIndexChanged.connect(
+ self.serverUpdated
+ )
self.updateDbList()
- self.groupBox.setTitle(self.tr('Available Databases'))
+ self.groupBox.setTitle(self.tr("Available Databases"))
def clearGridLayout(self):
"""
@@ -73,13 +80,17 @@ def getDbsFromServer(self, name):
def updateDbList(self):
"""
- Fills
+ Fills
"""
# remove all present widgets
self.clearGridLayout()
# get selected server
serverName = self.exploreServerWidget.serversCombo.currentText()
- serverName = serverName.split(' ')[0] if self.exploreServerWidget.serversCombo.currentIndex() != 0 else ''
+ serverName = (
+ serverName.split(" ")[0]
+ if self.exploreServerWidget.serversCombo.currentIndex() != 0
+ else ""
+ )
# get available databases
if serverName:
dbList = self.getDbsFromServer(name=serverName)
@@ -147,7 +158,11 @@ def on_okPushButton_clicked(self):
"""
# update server name attribute
self.serverName = self.exploreServerWidget.serversCombo.currentText()
- self.serverName = self.serverName.split(' ')[0] if self.serverName != self.tr('Select Server') else ''
+ self.serverName = (
+ self.serverName.split(" ")[0]
+ if self.serverName != self.tr("Select Server")
+ else ""
+ )
for row in range(self.gridLayout.rowCount()):
# get checkbox
item = self.gridLayout.itemAtPosition(row, 0)
@@ -155,14 +170,18 @@ def on_okPushButton_clicked(self):
checkbox = self.gridLayout.itemAtPosition(row, 0).widget()
# update dbList
if checkbox.isChecked():
- self.dbList.append(checkbox.text().split(' ')[0].replace('&', '')) # again, no idea why an '&' got in there...
+ self.dbList.append(
+ checkbox.text().split(" ")[0].replace("&", "")
+ ) # again, no idea why an '&' got in there...
self.close()
+
class MultiPostgisSelectorWidget(AbstractMultiDsSelectorWidget):
"""
Class designed to integrate the datasource selector widget to the abstract multi datasource selector widget.
Handles data manipulation to be delivered to the next conversion step.
"""
+
def __init__(self, parent=None):
"""
Class constructor.
@@ -205,7 +224,7 @@ def getDbListServerInfo(self, dbList):
dbList = self.getAvailableDb(serverName=self.selector.serverName)
serverInfo = list(self.getDbServerInfo(serverName=self.selector.serverName))
serverInfo.insert(0, self.selector.serverName)
- return { dbname : serverInfo for dbname in dbList }
+ return {dbname: serverInfo for dbname in dbList}
def exec_(self):
"""
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py
index 3ddcc42f3..3dbda5a36 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiShapefileSelectorWidget.py
@@ -29,10 +29,12 @@
import os
+
class MultiShapefileSelectorWidget(AbstractMultiDsSelectorWidget):
"""
Class designed to retrieve a Shapefile database list (list of folders containing shapefiles).
"""
+
def __init__(self, parent=None):
"""
Class constructor.
@@ -60,8 +62,10 @@ def exec_(self):
"""
# clear datasources
self.datasources = {}
- dbList = self.selector.getOpenFileNames(caption=self.tr("Select Folders with Shapefiles"), \
- filter=self.tr('Shapefiles (*.shp)'))[0]
+ dbList = self.selector.getOpenFileNames(
+ caption=self.tr("Select Folders with Shapefiles"),
+ filter=self.tr("Shapefiles (*.shp)"),
+ )[0]
for db in dbList:
self.datasources[db] = os.path.dirname(db)
- return int(not self.datasources) # execution code
+ return int(not self.datasources) # execution code
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py
index 79909ed81..26c62ab47 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/SupportedDrivers/multiSpatialiteSelectorWidget.py
@@ -29,10 +29,12 @@
import os
+
class MultiSpatialiteSelectorWidget(AbstractMultiDsSelectorWidget):
"""
Class designed to retrieve a SpatiaLite database list.
"""
+
def __init__(self, parent=None):
"""
Class constructor.
@@ -60,8 +62,10 @@ def exec_(self):
"""
# clear datasources
self.datasources = {}
- dbList = self.selector.getOpenFileNames(caption=self.tr("Select SpatiaLite Datasources"), \
- filter=self.tr('SpatiaLite Databases (*.sqlite)'))[0]
+ dbList = self.selector.getOpenFileNames(
+ caption=self.tr("Select SpatiaLite Datasources"),
+ filter=self.tr("SpatiaLite Databases (*.sqlite)"),
+ )[0]
for db in dbList:
self.datasources[self.getDatabaseName(datasourcePath=db)] = db
- return int(not self.datasources) # execution code
+ return int(not self.datasources) # execution code
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py
index 8d1c8b69c..e69de29bb 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/__init__.py
@@ -1 +0,0 @@
-
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py
index b7fecbe92..9e17ed290 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/MultiDsSelectorWidgets/multiDsWidgetFactory.py
@@ -1,4 +1,3 @@
-
# -*- coding: utf-8 -*-
"""
/***************************************************************************
@@ -23,30 +22,36 @@
"""
from .SupportedDrivers.multiPostgisSelectorWidget import MultiPostgisSelectorWidget
-from .SupportedDrivers.multiSpatialiteSelectorWidget import MultiSpatialiteSelectorWidget
+from .SupportedDrivers.multiSpatialiteSelectorWidget import (
+ MultiSpatialiteSelectorWidget,
+)
from .SupportedDrivers.multiShapefileSelectorWidget import MultiShapefileSelectorWidget
-from .SupportedDrivers.multiGeopackageSelectorWidget import MultiGeopackageSelectorWidget
+from .SupportedDrivers.multiGeopackageSelectorWidget import (
+ MultiGeopackageSelectorWidget,
+)
from .SupportedDrivers.multiNewDsSelector import MultiNewDsSelector
from DsgTools.core.dsgEnums import DsgEnums
+
class MultiDsWidgetFactory:
"""
Class to produce multiple datasource dialalogs.
"""
+
def getMultiDsSelector(driver):
"""
Gets the dialog to be used for selecting multiple datasources of a given driver.
- :param driver: (int) driver enum.
+ :param driver: (int) driver enum.
"""
dialogDict = {
- DsgEnums.NoDriver : lambda : None,
- DsgEnums.PostGIS : lambda : MultiPostgisSelectorWidget(),
- DsgEnums.NewPostGIS : lambda : MultiNewDsSelector(),
- DsgEnums.SpatiaLite : lambda : MultiSpatialiteSelectorWidget(),
- DsgEnums.NewSpatiaLite : lambda : MultiNewDsSelector(),
- DsgEnums.Shapefile : lambda : MultiShapefileSelectorWidget(),
- DsgEnums.NewShapefile : lambda : MultiNewDsSelector(),
- DsgEnums.Geopackage : lambda : MultiGeopackageSelectorWidget(),
- DsgEnums.NewGeopackage : lambda : MultiNewDsSelector()
+ DsgEnums.NoDriver: lambda: None,
+ DsgEnums.PostGIS: lambda: MultiPostgisSelectorWidget(),
+ DsgEnums.NewPostGIS: lambda: MultiNewDsSelector(),
+ DsgEnums.SpatiaLite: lambda: MultiSpatialiteSelectorWidget(),
+ DsgEnums.NewSpatiaLite: lambda: MultiNewDsSelector(),
+ DsgEnums.Shapefile: lambda: MultiShapefileSelectorWidget(),
+ DsgEnums.NewShapefile: lambda: MultiNewDsSelector(),
+ DsgEnums.Geopackage: lambda: MultiGeopackageSelectorWidget(),
+ DsgEnums.NewGeopackage: lambda: MultiNewDsSelector(),
}
return dialogDict[driver]()
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py
index be827ac74..1c706a2cd 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/abstractSelectionWidget.py
@@ -25,7 +25,10 @@
from qgis.utils import iface
from DsgTools.core.dsgEnums import DsgEnums
-from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory
+from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import (
+ LayerLoaderFactory,
+)
+
class AbstractSelectionWidget(QObject):
"""
@@ -34,6 +37,7 @@ class AbstractSelectionWidget(QObject):
1- Define common methods to all manageable drivers
2- Set and define generic behavior method for reimplementation in all children.
"""
+
def __init__(self, parent=None):
"""
Class constructor.
@@ -41,13 +45,11 @@ def __init__(self, parent=None):
:param source: (str) driver codename to have its widget produced.
"""
super(AbstractSelectionWidget, self).__init__()
- self.source = ''
+ self.source = ""
self.selectionWidget = None
def __del__(self):
- """
-
- """
+ """ """
abstractDb = self.getDatasource()
if abstractDb is not None:
abstractDb.closeDatabase()
@@ -61,17 +63,17 @@ def getSelectionWidgetName(self, source=None):
:return: (str) selection widget user-friendly name for selected driver.
"""
if not source:
- return self.tr('No database selected.')
+ return self.tr("No database selected.")
sourceNameDict = {
- DsgEnums.NoDriver : self.tr('Select a datasource driver'),
- DsgEnums.PostGIS : 'PostGIS',
- DsgEnums.NewPostGIS : self.tr('PostGIS (create new database)'),
- DsgEnums.SpatiaLite : 'SpatiaLite',
- DsgEnums.NewSpatiaLite : self.tr('SpatiaLite (create new database)'),
- DsgEnums.Shapefile : 'Shapefile',
- DsgEnums.NewShapefile : self.tr('Shapefile (create new database)'),
- #DsgEnums.Geopackage : 'Geopackage',
- #DsgEnums.NewGeopackage : self.tr('Geopackage (create new database)')
+ DsgEnums.NoDriver: self.tr("Select a datasource driver"),
+ DsgEnums.PostGIS: "PostGIS",
+ DsgEnums.NewPostGIS: self.tr("PostGIS (create new database)"),
+ DsgEnums.SpatiaLite: "SpatiaLite",
+ DsgEnums.NewSpatiaLite: self.tr("SpatiaLite (create new database)"),
+ DsgEnums.Shapefile: "Shapefile",
+ DsgEnums.NewShapefile: self.tr("Shapefile (create new database)"),
+ # DsgEnums.Geopackage : 'Geopackage',
+ # DsgEnums.NewGeopackage : self.tr('Geopackage (create new database)')
}
return sourceNameDict[source]
@@ -81,7 +83,7 @@ def getDatasourceConnectionName(self):
:return: (str) datasource connection name.
"""
# to be reimplemented
- return ''
+ return ""
def getDatasourcePath(self):
"""
@@ -89,7 +91,7 @@ def getDatasourcePath(self):
:return: (str) datasource path.
"""
# to be reimplemented
- return ''
+ return ""
def getNewSelectionWidget(self):
"""
@@ -106,15 +108,15 @@ def setDatasource(self, newDatasource):
"""
# implementation for new datasources, but may be reimplemented into ALL children classes
# for new datasources, entry is always { int : { 'edgv' : (str)edgv, 'crs' : (QgsCoordinateReferenceSystem)crs } }
- edgv = list(newDatasource.values())[0]['edgv']
- crs = list(newDatasource.values())[0]['crs']
+ edgv = list(newDatasource.values())[0]["edgv"]
+ crs = list(newDatasource.values())[0]["crs"]
self.selectionWidget.edgvComboBox.setCurrentText(edgv)
self.selectionWidget.mQgsProjectionSelectionWidget.setCrs(crs)
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according.
+ :return: (AbstractDb) the object representing the target datasource according.
"""
# to be reimplemented
pass
@@ -125,7 +127,7 @@ def getDatasourceEdgvVersion(self):
:return: (str) current EDGV version.
"""
abstracDb = self.getDatasource()
- return abstracDb.getDatabaseVersion() if abstracDb else ''
+ return abstracDb.getDatabaseVersion() if abstracDb else ""
def getLayerLoader(self):
"""
@@ -133,7 +135,11 @@ def getLayerLoader(self):
:return: (EDGVLayerLoader) layer loader.
"""
abstracDb = self.getDatasource()
- return LayerLoaderFactory().makeLoader(iface=iface, abstractDb=abstracDb) if abstracDb else None
+ return (
+ LayerLoaderFactory().makeLoader(iface=iface, abstractDb=abstracDb)
+ if abstracDb
+ else None
+ )
def getLayerByName(self, layer):
"""
@@ -169,7 +175,9 @@ def getLayersCrs(self):
if abstracDb:
layerLoader = self.getLayerLoader()
# alias for retrieving layer CRS and inserting it to out dict
- getCrsAlias = lambda x : crs.update({ x : layerLoader.getLayerByName(layer=x).crs().description() })
+ getCrsAlias = lambda x: crs.update(
+ {x: layerLoader.getLayerByName(layer=x).crs().description()}
+ )
# update crs dict
list(map(getCrsAlias, self.getLayersDict()))
return crs
@@ -181,7 +189,9 @@ def getLayersDict(self):
"""
abstracDb = self.getDatasource()
if abstracDb:
- return abstracDb.listClassesWithElementsFromDatabase(useComplex=False, primitiveFilter=[])
+ return abstracDb.listClassesWithElementsFromDatabase(
+ useComplex=False, primitiveFilter=[]
+ )
return {}
def getComplexDict(self):
@@ -200,7 +210,11 @@ def validate(self):
Validates selection widgets contents.
:return: (str) invalidation reason.
"""
- return self.selectionWidget.validate() if self.selectionWidget else self.tr('Selection widget not available.')
+ return (
+ self.selectionWidget.validate()
+ if self.selectionWidget
+ else self.tr("Selection widget not available.")
+ )
def isValid(self):
"""
@@ -208,4 +222,4 @@ def isValid(self):
:return: (bool) invalidation status.
"""
msg = self.validate()
- return msg == ''
\ No newline at end of file
+ return msg == ""
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py
index 0cf7e8c35..17a0452de 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/geopackageWidget.py
@@ -21,12 +21,17 @@
***************************************************************************/
"""
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import DatabaseFileLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import (
+ DatabaseFileLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class GeopackageWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -43,8 +48,12 @@ def __init__(self, parent=None):
# initiate new instance of actual class widget
self.selectionWidget = self.getNewSelectionWidget(parent=parent)
self.selectionWidget.driver = DsgEnums.DriverGeopackage
- self.selectionWidget.connectionSelectorLineEdit.caption = self.tr('Select a Geopackage Database')
- self.selectionWidget.connectionSelectorLineEdit.filter = self.tr('Geopackage Database (*.gpkg)')
+ self.selectionWidget.connectionSelectorLineEdit.caption = self.tr(
+ "Select a Geopackage Database"
+ )
+ self.selectionWidget.connectionSelectorLineEdit.filter = self.tr(
+ "Geopackage Database (*.gpkg)"
+ )
def getNewSelectionWidget(self, parent=None):
"""
@@ -61,8 +70,8 @@ def getDatasourceConnectionName(self):
"""
n = self.selectionWidget.connectionSelectorLineEdit.lineEdit.text()
# n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite
- splitChar = '/' if '/' in n else '\\'
- ret = n.split(splitChar)[-1].split('.')[0] if n else ''
+ splitChar = "/" if "/" in n else "\\"
+ ret = n.split(splitChar)[-1].split(".")[0] if n else ""
return ret
def getDatasourcePath(self):
@@ -72,8 +81,10 @@ def getDatasourcePath(self):
"""
if self.getDatasource():
# just return a datasource path if a valid one was loaded
- return "gpkg:{0}".format(self.selectionWidget.connectionSelectorLineEdit.lineEdit.text())
- return ''
+ return "gpkg:{0}".format(
+ self.selectionWidget.connectionSelectorLineEdit.lineEdit.text()
+ )
+ return ""
def setDatasource(self, newDatasource):
"""
@@ -81,11 +92,13 @@ def setDatasource(self, newDatasource):
:param newDatasource: (dict) containing datasource name and its path.
"""
if newDatasource:
- self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText((list(newDatasource.values())[0]))
+ self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText(
+ (list(newDatasource.values())[0])
+ )
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return self.selectionWidget.abstractDb
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py
index 952e6628e..36e15f7c7 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newGeopackageWidget.py
@@ -21,12 +21,17 @@
***************************************************************************/
"""
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import NewDatabaseLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import (
+ NewDatabaseLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class NewGeopackageWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -42,8 +47,8 @@ def __init__(self, parent=None):
self.source = DsgEnums.NewGeopackage
# initiate new instance of actual class widget
self.selectionWidget = self.getNewSelectionWidget(parent=parent)
- self.selectionWidget.caption = self.tr('Create a Geopackage Database')
- self.selectionWidget.filter = self.tr('Geopackage Database (*.gpkg)')
+ self.selectionWidget.caption = self.tr("Create a Geopackage Database")
+ self.selectionWidget.filter = self.tr("Geopackage Database (*.gpkg)")
def getNewSelectionWidget(self, parent=None):
"""
@@ -60,8 +65,8 @@ def getDatasourceConnectionName(self):
"""
n = self.selectionWidget.dsLineEdit.text()
# n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite
- splitChar = '/' if '/' in n else '\\'
- ret = n.split(splitChar)[-1].split('.')[0] if n else ''
+ splitChar = "/" if "/" in n else "\\"
+ ret = n.split(splitChar)[-1].split(".")[0] if n else ""
return ret
def getDatasourcePath(self):
@@ -80,6 +85,6 @@ def getDatasourceEdgvVersion(self):
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return None
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py
index b924c6e3d..734d72976 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newPostgisWidget.py
@@ -21,12 +21,17 @@
***************************************************************************/
"""
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newConnectionLineEdit import NewConnectionLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newConnectionLineEdit import (
+ NewConnectionLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class NewPostgisWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -57,7 +62,7 @@ def getDatasourceConnectionName(self):
Gets the datasource connection name.
:return: (str) datasource connection name.
"""
- return self.selectionWidget.currentDb() if self.selectionWidget else ''
+ return self.selectionWidget.currentDb() if self.selectionWidget else ""
def getDatasourcePath(self):
"""
@@ -65,9 +70,17 @@ def getDatasourcePath(self):
:return: (str) datasource connection name.
"""
if self.selectionWidget:
- _, host, port, user, _ = self.selectionWidget.viewServers.getDefaultConnectionParameters()
- return 'pg:{2}@{0}:{1}.{3}'.format(host, port, user, self.getDatasourceConnectionName())
- return ''
+ (
+ _,
+ host,
+ port,
+ user,
+ _,
+ ) = self.selectionWidget.viewServers.getDefaultConnectionParameters()
+ return "pg:{2}@{0}:{1}.{3}".format(
+ host, port, user, self.getDatasourceConnectionName()
+ )
+ return ""
def getDatasourceEdgvVersion(self):
"""
@@ -78,6 +91,6 @@ def getDatasourceEdgvVersion(self):
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return None
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py
index b55ce298b..fa4ecff46 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newShapefileWidget.py
@@ -25,12 +25,17 @@
from qgis.PyQt.QtWidgets import QFileDialog
from qgis.PyQt.QtCore import pyqtSlot
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import NewDatabaseLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import (
+ NewDatabaseLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class NewShapefileWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -46,10 +51,14 @@ def __init__(self, parent=None):
self.source = DsgEnums.NewShapefile
# initiate new instance of actual class widget
self.selectionWidget = self.getNewSelectionWidget(parent=parent)
- self.selectionWidget.caption = self.tr('Select a Directory for Shapes to be Saved At')
- self.selectionWidget.filter = self.tr('Shapefile Database')
+ self.selectionWidget.caption = self.tr(
+ "Select a Directory for Shapes to be Saved At"
+ )
+ self.selectionWidget.filter = self.tr("Shapefile Database")
# connect datasource selection to this ones
- self.selectionWidget.selectFilePushButton.clicked.disconnect(self.selectionWidget.selectDatasource)
+ self.selectionWidget.selectFilePushButton.clicked.disconnect(
+ self.selectionWidget.selectDatasource
+ )
self.selectionWidget.selectFilePushButton.clicked.connect(self.selectDatasource)
def getNewSelectionWidget(self, parent=None):
@@ -68,11 +77,15 @@ def getDatasourceConnectionName(self):
ret = self.selectionWidget.dsLineEdit.text()
if ret:
# path is something like /PATH/TO/datasource/***.shp or C:\PATH\TO\datasource\***.shp
- splitChar = '/' if '/' in ret else '\\'
+ splitChar = "/" if "/" in ret else "\\"
if len(ret) > 4:
# datasource connection name for a shape 'database' is its parent folder
- ret = ret.split(splitChar)[-1] if ret[-4:].lower() != '.shp' else ret.split(splitChar)[:-4]
- ret = ret if ret != self.tr("New Database") else ''
+ ret = (
+ ret.split(splitChar)[-1]
+ if ret[-4:].lower() != ".shp"
+ else ret.split(splitChar)[:-4]
+ )
+ ret = ret if ret != self.tr("New Database") else ""
return ret
def getDatasourcePath(self):
@@ -85,7 +98,7 @@ def getDatasourcePath(self):
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return None
@@ -107,7 +120,9 @@ def selectDatasource(self):
if directory:
if len(directory) > 4:
# datasource connection name for a shape 'database' is its parent folder
- directory = directory if directory[-4:].lower() != '.shp' else directory[:-4]
+ directory = (
+ directory if directory[-4:].lower() != ".shp" else directory[:-4]
+ )
# set only directories as line text
self.selectionWidget.dsLineEdit.setText(directory)
self.selectionWidget.loadDatabase(currentText=directory)
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py
index 40b6cab0b..92b2fb142 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/newSpatialiteWidget.py
@@ -24,12 +24,17 @@
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import NewDatabaseLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.newDatabaseLineEdit import (
+ NewDatabaseLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class NewSpatialiteWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -45,8 +50,8 @@ def __init__(self, parent=None):
self.source = DsgEnums.NewSpatiaLite
# initiate new instance of actual class widget
self.selectionWidget = self.getNewSelectionWidget(parent=parent)
- self.selectionWidget.caption = self.tr('Create a SpatiaLite Database')
- self.selectionWidget.filter = self.tr('SpatiaLite Database (*.sqlite)')
+ self.selectionWidget.caption = self.tr("Create a SpatiaLite Database")
+ self.selectionWidget.filter = self.tr("SpatiaLite Database (*.sqlite)")
def getNewSelectionWidget(self, parent=None):
"""
@@ -63,8 +68,8 @@ def getDatasourceConnectionName(self):
"""
n = self.selectionWidget.dsLineEdit.text()
# n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite
- splitChar = '/' if '/' in n else '\\'
- ret = n.split(splitChar)[-1].split('.')[0] if n else ''
+ splitChar = "/" if "/" in n else "\\"
+ ret = n.split(splitChar)[-1].split(".")[0] if n else ""
return ret
def getDatasourcePath(self):
@@ -83,6 +88,6 @@ def getDatasourceEdgvVersion(self):
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return None
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py
index 448034c34..fa0a207b8 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/postgisWidget.py
@@ -21,12 +21,17 @@
***************************************************************************/
"""
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.connectionComboBox import ConnectionComboBox
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.connectionComboBox import (
+ ConnectionComboBox,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class PostgisWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -57,7 +62,11 @@ def getDatasourceConnectionName(self):
Gets the datasource connection name.
:return: (str) datasource connection name.
"""
- return self.selectionWidget.connectionSelectorComboBox.currentText() if self.selectionWidget else ''
+ return (
+ self.selectionWidget.connectionSelectorComboBox.currentText()
+ if self.selectionWidget
+ else ""
+ )
def getDatasourcePath(self):
"""
@@ -67,8 +76,10 @@ def getDatasourcePath(self):
abstractDb = self.getDatasource()
if abstractDb:
host, port, username, _ = abstractDb.getDatabaseParameters()
- return 'pg:{2}@{0}:{1}.{3}'.format(host, port, username, self.getDatasourceConnectionName())
- return ''
+ return "pg:{2}@{0}:{1}.{3}".format(
+ host, port, username, self.getDatasourceConnectionName()
+ )
+ return ""
def setDatasource(self, newDatasource):
"""
@@ -77,16 +88,22 @@ def setDatasource(self, newDatasource):
"""
# the input parameter is a dict due to a standard behavior on the other widgets (keep parallel)
if self.selectionWidget:
- for db, (serverName, host, port, username, password) in newDatasource.items():
+ for db, (
+ serverName,
+ host,
+ port,
+ username,
+ password,
+ ) in newDatasource.items():
self.selectionWidget.setHost(serverName)
self.selectionWidget.connectionSelectorComboBox.setCurrentIndex(
self.selectionWidget.connectionSelectorComboBox.findText(db)
)
- return # first item will be set (if more than one is given)
+ return # first item will be set (if more than one is given)
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return self.selectionWidget.abstractDb
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py
index 615448714..8b20ebe13 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/shapefileWidget.py
@@ -23,12 +23,17 @@
from qgis.PyQt.QtWidgets import QFileDialog
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import DatabaseFileLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import (
+ DatabaseFileLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class ShapefileWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -44,15 +49,22 @@ def __init__(self, parent=None):
self.source = DsgEnums.Shapefile
# initiate new instance of actual class widget
self.selectionWidget = self.getNewSelectionWidget(parent=parent)
- self.selectionWidget.connectionSelectorLineEdit.caption = self.tr('Select a Directory Containing Shapefiles')
- self.selectionWidget.connectionSelectorLineEdit.filter = self.tr('Shapefile Database')
+ self.selectionWidget.connectionSelectorLineEdit.caption = self.tr(
+ "Select a Directory Containing Shapefiles"
+ )
+ self.selectionWidget.connectionSelectorLineEdit.filter = self.tr(
+ "Shapefile Database"
+ )
# initiate driver for abstract db setting
self.selectionWidget.driver = DsgEnums.DriverShapefile
# connect datasource selection to this ones - this part is not great, sucks actually;
# a refactory should be be executed in here...
- self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.disconnect(\
- self.selectionWidget.connectionSelectorLineEdit.on_selectFilePushButton_clicked)
- self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.connect(self.selectDatasource)
+ self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.disconnect(
+ self.selectionWidget.connectionSelectorLineEdit.on_selectFilePushButton_clicked
+ )
+ self.selectionWidget.connectionSelectorLineEdit.selectFilePushButton.clicked.connect(
+ self.selectDatasource
+ )
def getNewSelectionWidget(self, parent=None):
"""
@@ -68,7 +80,7 @@ def getDatasourceConnectionName(self):
:return: (str) datasource connection name.
"""
abstractDb = self.getDatasource()
- return abstractDb.getDatabaseName() if abstractDb else ''
+ return abstractDb.getDatabaseName() if abstractDb else ""
def setDatasource(self, newDatasource):
"""
@@ -81,7 +93,7 @@ def setDatasource(self, newDatasource):
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return self.selectionWidget.abstractDb
@@ -91,7 +103,7 @@ def getDatasourcePath(self):
:return: (str) datasource connection name.
"""
abstractDb = self.getDatasource()
- return "shp:{0}".format(abstractDb.databaseName()) if abstractDb else ''
+ return "shp:{0}".format(abstractDb.databaseName()) if abstractDb else ""
def selectDatasource(self):
"""
@@ -101,11 +113,15 @@ def selectDatasource(self):
fd = QFileDialog()
fd.setFileMode(QFileDialog.Directory)
fd.setOption(QFileDialog.ShowDirsOnly, True)
- directory = fd.getExistingDirectory(caption=self.selectionWidget.connectionSelectorLineEdit.caption)
+ directory = fd.getExistingDirectory(
+ caption=self.selectionWidget.connectionSelectorLineEdit.caption
+ )
if directory:
if len(directory) > 4:
# datasource connection name for a shape 'database' is its parent folder
- directory = directory if directory[-4:].lower() != '.shp' else directory[:-4]
+ directory = (
+ directory if directory[-4:].lower() != ".shp" else directory[:-4]
+ )
# set only directories as line text
self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText(directory)
self.selectionWidget.loadDatabase(currentText=directory)
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py
index 4e7b78042..eed685954 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/SupportedDrivers/spatialiteWidget.py
@@ -24,12 +24,17 @@
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSignal, pyqtSlot
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import AbstractSelectionWidget
-from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import DatabaseFileLineEdit
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.abstractSelectionWidget import (
+ AbstractSelectionWidget,
+)
+from DsgTools.gui.CustomWidgets.ConnectionWidgets.AdvancedConnectionWidgets.databaseFileLineEdit import (
+ DatabaseFileLineEdit,
+)
from DsgTools.core.dsgEnums import DsgEnums
import os
+
class SpatialiteWidget(AbstractSelectionWidget):
"""
Widget resposinble for adequating GUI to chosen data driver.
@@ -46,8 +51,12 @@ def __init__(self, parent=None):
# initiate new instance of actual class widget
self.selectionWidget = self.getNewSelectionWidget(parent=parent)
self.selectionWidget.driver = DsgEnums.DriverSpatiaLite
- self.selectionWidget.connectionSelectorLineEdit.caption = self.tr('Select a SpatiaLite Database')
- self.selectionWidget.connectionSelectorLineEdit.filter = self.tr('SpatiaLite Database (*.sqlite)')
+ self.selectionWidget.connectionSelectorLineEdit.caption = self.tr(
+ "Select a SpatiaLite Database"
+ )
+ self.selectionWidget.connectionSelectorLineEdit.filter = self.tr(
+ "SpatiaLite Database (*.sqlite)"
+ )
def getNewSelectionWidget(self, parent=None):
"""
@@ -64,8 +73,8 @@ def getDatasourceConnectionName(self):
"""
n = self.selectionWidget.connectionSelectorLineEdit.lineEdit.text()
# n is a path and so it'll be something like /PATH/TO/datasource.sqlite or C:\PATH\TO\datasource.sqlite
- splitChar = '/' if '/' in n else '\\'
- ret = n.split(splitChar)[-1].split('.')[0] if n else ''
+ splitChar = "/" if "/" in n else "\\"
+ ret = n.split(splitChar)[-1].split(".")[0] if n else ""
return ret
def getDatasourcePath(self):
@@ -75,8 +84,10 @@ def getDatasourcePath(self):
"""
if self.getDatasource():
# just return a datasource path if a valid one was loaded
- return "sqlite:{0}".format(self.selectionWidget.connectionSelectorLineEdit.lineEdit.text())
- return ''
+ return "sqlite:{0}".format(
+ self.selectionWidget.connectionSelectorLineEdit.lineEdit.text()
+ )
+ return ""
def setDatasource(self, newDatasource):
"""
@@ -84,11 +95,13 @@ def setDatasource(self, newDatasource):
:param newDatasource: (dict) containing datasource name and its path.
"""
if newDatasource:
- self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText((list(newDatasource.values())[0]))
+ self.selectionWidget.connectionSelectorLineEdit.lineEdit.setText(
+ (list(newDatasource.values())[0])
+ )
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (AbstractDb) the object representing the target datasource according to its driver.
+ :return: (AbstractDb) the object representing the target datasource according to its driver.
"""
return self.selectionWidget.abstractDb
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py
index d4863f285..2a5aea7f3 100755
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceContainerWidget.py
@@ -27,19 +27,28 @@
from qgis.utils import iface
from qgis.core import QgsProject
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import GenericDialogLayout
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.filterDialog import FilterDialog
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceSelectionWidgetFactory import DatasourceSelectionWidgetFactory
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import (
+ GenericDialogLayout,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.filterDialog import (
+ FilterDialog,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceSelectionWidgetFactory import (
+ DatasourceSelectionWidgetFactory,
+)
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'datasourceContainerWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "datasourceContainerWidget.ui")
+)
+
class DatasourceContainerWidget(QtWidgets.QWidget, FORM_CLASS):
"""
Widget resposinble for adequating GUI to chosen data driver.
"""
+
# signal to be emitted when deletion button is clicked - emits itself (QWidget)
removeWidget = pyqtSignal(QtWidgets.QWidget)
# signal emitted to advise about filtering options change
@@ -61,24 +70,30 @@ def __init__(self, source, isInput, parent=None):
self.filterPushButton.hide()
# set filtering config
self.filterDlg = None
- self.filterPushButton.setToolTip(self.tr('Click to set datasource filter options'))
- self.removePushButton.setToolTip(self.tr('Remove this datasource widget'))
+ self.filterPushButton.setToolTip(
+ self.tr("Click to set datasource filter options")
+ )
+ self.removePushButton.setToolTip(self.tr("Remove this datasource widget"))
def setGroupWidgetName(self, name=None):
"""
Sets the name to the group added.
:param name: (str) name for the group.
"""
- self.groupBox.setTitle('{0}'.format(name))
+ self.groupBox.setTitle("{0}".format(name))
def addDatasourceSelectionWidget(self):
"""
Adds the widget according to selected datasource on datasource combobox on first page.
"""
# in case a valid driver is selected, add its widget to the interface
- self.connectionWidget = DatasourceSelectionWidgetFactory.getSelectionWidget(source=self.source)
+ self.connectionWidget = DatasourceSelectionWidgetFactory.getSelectionWidget(
+ source=self.source
+ )
self.driverLayout.addWidget(self.connectionWidget.selectionWidget)
- self.connectionWidget.selectionWidget.dbChanged.connect(lambda : self.refreshFilterDialog)
+ self.connectionWidget.selectionWidget.dbChanged.connect(
+ lambda: self.refreshFilterDialog
+ )
def getDatasourceConnectionName(self):
"""
@@ -91,7 +106,7 @@ def getDatasourceConnectionName(self):
def getDatasource(self):
"""
Gets the datasource selected on current widget.
- :return: (object) the object representing the target datasource according to its driver.
+ :return: (object) the object representing the target datasource according to its driver.
"""
return self.connectionWidget.getDatasource() if self.connectionWidget else None
@@ -122,16 +137,28 @@ def refreshFilterDialog(self):
del self.filterDlg
self.filterDlg = None
self.filterDlg = FilterDialog(
- {l : {'layer' : self.connectionWidget.getLayerByName(l), 'featureCount' : fc} for l, fc in self.connectionWidget.getLayersDict().items()},
- {l : {'layer' : self.connectionWidget.getComplexLayerByName(l), 'featureCount' : fc} for l, fc in self.connectionWidget.getComplexDict().items()},
- self.connectionWidget.getDatasource(),
- )
+ {
+ l: {
+ "layer": self.connectionWidget.getLayerByName(l),
+ "featureCount": fc,
+ }
+ for l, fc in self.connectionWidget.getLayersDict().items()
+ },
+ {
+ l: {
+ "layer": self.connectionWidget.getComplexLayerByName(l),
+ "featureCount": fc,
+ }
+ for l, fc in self.connectionWidget.getComplexDict().items()
+ },
+ self.connectionWidget.getDatasource(),
+ )
self.filterDlg.setWindowTitle(
- '{0}: {2} ({1})'.format(
- self.groupBox.title(),
- self.connectionWidget.getDatasourcePath(),
- self.connectionWidget.getDatasourceConnectionName()
- )
+ "{0}: {2} ({1})".format(
+ self.groupBox.title(),
+ self.connectionWidget.getDatasourcePath(),
+ self.connectionWidget.getDatasourceConnectionName(),
+ )
)
@pyqtSlot(bool)
@@ -139,7 +166,7 @@ def on_filterPushButton_clicked(self):
"""
Opens filter dialog. Filters are updated as Ok push button on this dialog is clicked. If cancel is pressed,
no update to filters contents will be made. This dialog is repopulated as filter push button from container
- is pressed.
+ is pressed.
"""
# filter dialog is only built on the first execution
if self.filterDlg is None:
@@ -163,8 +190,11 @@ def filters(self):
is returned.
:return: (dict) a map to current filters applied.
"""
- return self.filterDlg.filters() if self.filterDlg is not None \
- else {'layer_filter' : dict(), 'spatial_filter' : dict()}
+ return (
+ self.filterDlg.filters()
+ if self.filterDlg is not None
+ else {"layer_filter": dict(), "spatial_filter": dict()}
+ )
def driver(self):
"""
@@ -193,4 +223,4 @@ def isValid(self):
Validates selection widgets contents.
:return: (bool) invalidation status.
"""
- return self.validate() == ''
+ return self.validate() == ""
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py
index 10cdc5edf..22b4d99f0 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceInfoTable.py
@@ -26,8 +26,10 @@
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'datasourceInfoTable.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "datasourceInfoTable.ui")
+)
+
class DatasourceInfoTable(QtWidgets.QDialog, FORM_CLASS):
# create enum to manipulate headers order
@@ -54,14 +56,14 @@ def orderByColumn(self, col):
"""
# TO DO
headers = {
- self.Schema : self.tr("Schema"),
- self.Layer : self.tr("Layer"),
- self.GeomCol : self.tr("Geometry Column"),
- self.GeomType : self.tr("Geometry Type"),
- self.Srid : self.tr("SRID")
+ self.Schema: self.tr("Schema"),
+ self.Layer: self.tr("Layer"),
+ self.GeomCol: self.tr("Geometry Column"),
+ self.GeomType: self.tr("Geometry Type"),
+ self.Srid: self.tr("SRID"),
}
if col in headers:
- print('Just consider it ordered by {0}, ok?'.format(headers[col]))
+ print("Just consider it ordered by {0}, ok?".format(headers[col]))
@pyqtSlot(bool)
def on_closePushButton_clicked(self):
@@ -79,19 +81,24 @@ def createTable(self):
self.tableWidget.removeRow(row)
self.tableWidget.setRowCount(0)
headers = {
- self.Schema : self.tr("Schema"),
- self.Layer : self.tr("Layer"),
- self.GeomCol : self.tr("Geometry Column"),
- self.GeomType : self.tr("Geometry Type"),
- self.Srid : self.tr("SRID")
+ self.Schema: self.tr("Schema"),
+ self.Layer: self.tr("Layer"),
+ self.GeomCol: self.tr("Geometry Column"),
+ self.GeomType: self.tr("Geometry Type"),
+ self.Srid: self.tr("SRID"),
}
# set column count
self.tableWidget.setColumnCount(self.COLUMN_COUNT)
header = self.tableWidget.horizontalHeader()
# set column names - makes sure the order is defined by enum's order
- self.tableWidget.setHorizontalHeaderLabels([headers[i] for i in range(self.COLUMN_COUNT)])
+ self.tableWidget.setHorizontalHeaderLabels(
+ [headers[i] for i in range(self.COLUMN_COUNT)]
+ )
# set resize policy for each column
- [header.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents) for i in range(self.COLUMN_COUNT)]
+ [
+ header.setSectionResizeMode(i, QtWidgets.QHeaderView.ResizeToContents)
+ for i in range(self.COLUMN_COUNT)
+ ]
# connect header double click signal to order by that column
header.sectionDoubleClicked.connect(self.orderByColumn)
@@ -105,7 +112,7 @@ def addItem(self, row, col, text):
"""
item = QtWidgets.QTableWidgetItem()
item.setText(text)
- item.setFlags(Qt.ItemIsEditable) # not editable
+ item.setFlags(Qt.ItemIsEditable) # not editable
self.tableWidget.setItem(row, col, item)
return item
@@ -115,11 +122,11 @@ def addRow(self, row, content):
:param row: (int) row index to be added.
:param content: (dict) contents to be displayed in the selected row.
"""
- self.addItem(row=row, col=self.Schema, text=content['schema'])
- self.addItem(row=row, col=self.Layer, text=content['layer'])
- self.addItem(row=row, col=self.GeomCol, text=content['geomCol'])
- self.addItem(row=row, col=self.GeomType, text=content['geomType'])
- self.addItem(row=row, col=self.Srid, text=content['srid'])
+ self.addItem(row=row, col=self.Schema, text=content["schema"])
+ self.addItem(row=row, col=self.Layer, text=content["layer"])
+ self.addItem(row=row, col=self.GeomCol, text=content["geomCol"])
+ self.addItem(row=row, col=self.GeomType, text=content["geomType"])
+ self.addItem(row=row, col=self.Srid, text=content["srid"])
def setTable(self, contents):
"""
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py
index 71285d292..833d16e48 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceManagementWidget.py
@@ -24,16 +24,22 @@
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSignal
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceContainerWidget import DatasourceContainerWidget
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.datasourceContainerWidget import (
+ DatasourceContainerWidget,
+)
from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb
from DsgTools.core.dsgEnums import DsgEnums
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.MultiDsSelectorWidgets.multiDsWidgetFactory import MultiDsWidgetFactory
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.MultiDsSelectorWidgets.multiDsWidgetFactory import (
+ MultiDsWidgetFactory,
+)
import os
from functools import partial
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'datasourceManagementWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "datasourceManagementWidget.ui")
+)
+
class DatasourceManagementWidget(QtWidgets.QWizardPage, FORM_CLASS):
"""
@@ -42,6 +48,7 @@ class DatasourceManagementWidget(QtWidgets.QWizardPage, FORM_CLASS):
2- prepare the conversion mapping structure using the table as a means to translate user's intentions; and
3- read filtering info to be applied to data.
"""
+
# setting signal to alert conversion tool about any active widgets change
activeWidgetAdded = pyqtSignal(DatasourceContainerWidget)
activeWidgetRemoved = pyqtSignal(DatasourceContainerWidget)
@@ -50,7 +57,7 @@ class DatasourceManagementWidget(QtWidgets.QWizardPage, FORM_CLASS):
widgetUpdated = pyqtSignal(DatasourceContainerWidget)
# filtering settings from widget container has changed signal
containerFilterSettingsChanged = pyqtSignal(DatasourceContainerWidget)
-
+
def __init__(self, parent=None):
"""
Class constructor.
@@ -59,11 +66,11 @@ def __init__(self, parent=None):
super(DatasourceManagementWidget, self).__init__()
# define mapping from GUI to enum
self.sourceNameDict = {
- self.tr('Select a datasource driver') : DsgEnums.NoDriver,
- 'PostGIS' : DsgEnums.PostGIS,
- self.tr('PostGIS (create new database)') : DsgEnums.NewPostGIS,
- 'SpatiaLite' : DsgEnums.SpatiaLite,
- self.tr('SpatiaLite (create new database)') : DsgEnums.NewSpatiaLite,
+ self.tr("Select a datasource driver"): DsgEnums.NoDriver,
+ "PostGIS": DsgEnums.PostGIS,
+ self.tr("PostGIS (create new database)"): DsgEnums.NewPostGIS,
+ "SpatiaLite": DsgEnums.SpatiaLite,
+ self.tr("SpatiaLite (create new database)"): DsgEnums.NewSpatiaLite,
# 'Shapefile' : DsgEnums.Shapefile,
# self.tr('Shapefile (create new database)') : DsgEnums.NewShapefile,
# 'Geopackage' : DsgEnums.Geopackage,
@@ -74,8 +81,8 @@ def __init__(self, parent=None):
self.fillSupportedDatasources()
# keep track of all (in)active widgets on input/output GUI
self.activeDrivers = dict()
- self.addSourcePushButton.setToolTip(self.tr('Add single datasource'))
- self.addMultiSourcePushButton.setToolTip(self.tr('Add multiple datasource'))
+ self.addSourcePushButton.setToolTip(self.tr("Add single datasource"))
+ self.addMultiSourcePushButton.setToolTip(self.tr("Add multiple datasource"))
# centralize all tool signals in order to keep track of all non-standard signals used
self.connectClassSignals()
@@ -99,7 +106,7 @@ def fillSupportedDatasources(self, inputPage=True):
# if it's an input page, items should not include the option for a new datasource
items = []
for ds in self.sourceNameDict:
- if self.tr('new') in ds:
+ if self.tr("new") in ds:
continue
else:
items.append(ds)
@@ -133,7 +140,7 @@ def addDatasourceWidget(self):
# get current text on datasource techonology selection combobox
currentDbSource = self.datasourceComboBox.currentText()
# identify if it's an input or output page call
- inputPage = (self.objectName() == 'datasourceManagementWidgetIn')
+ inputPage = self.objectName() == "datasourceManagementWidgetIn"
if currentDbSource:
# in case a valid driver is selected, add its widget to the interface
source = self.sourceNameDict[currentDbSource]
@@ -142,19 +149,26 @@ def addDatasourceWidget(self):
# connect removal widget signal to new widget
container.removeWidget.connect(self.removeWidget)
# connect datasource change signal to this class datasource signal change
- emitWidgetAlias = lambda newAbstract : self.datasourceChanged(
- newAbstract=newAbstract,
- containerWidget=container
- )
- container.connectionWidget.selectionWidget.dbChanged.connect(emitWidgetAlias)
+ emitWidgetAlias = lambda newAbstract: self.datasourceChanged(
+ newAbstract=newAbstract, containerWidget=container
+ )
+ container.connectionWidget.selectionWidget.dbChanged.connect(
+ emitWidgetAlias
+ )
# connect datasource change signal to its filters reset method
- container.connectionWidget.selectionWidget.dbChanged.connect(container.clearFilters)
+ container.connectionWidget.selectionWidget.dbChanged.connect(
+ container.clearFilters
+ )
# connect filtering settings changed signal to this class signal on filtering settings change
- container.filterSettingsChanged.connect(self.containerFilterSettingsChanged)
- # add new driver container to GUI
+ container.filterSettingsChanged.connect(
+ self.containerFilterSettingsChanged
+ )
+ # add new driver container to GUI
self.datasourceLayout.addWidget(container)
# update dict of active widgets
- self.addElementToDict(k=currentDbSource, e=container, d=self.activeDrivers)
+ self.addElementToDict(
+ k=currentDbSource, e=container, d=self.activeDrivers
+ )
# reset all driver's groupboxes names
self.resetWidgetsTitle()
# emit active widget that has been added
@@ -177,13 +191,13 @@ def addMultiDatasourceWidgets(self):
# add new widget container for it
container = self.addDatasourceWidget()
# set datasource to it
- container.setDatasource({ds : dsPath})
+ container.setDatasource({ds: dsPath})
def resetWidgetsTitle(self):
"""
Resets all widgets containers titles.
"""
- hideAlias = lambda w : w.hide()
+ hideAlias = lambda w: w.hide()
for driverName, widgetList in self.activeDrivers.items():
if not widgetList:
# if there are no active widgets for current driver, there's nothing to be updated
@@ -192,12 +206,12 @@ def resetWidgetsTitle(self):
for idx, w in enumerate(widgetList):
# if there are widgets from chosen driver, reset it's group box name
w.show()
- w.setGroupWidgetName(name='{0} #{1}'.format(driverName, idx + 1))
+ w.setGroupWidgetName(name="{0} #{1}".format(driverName, idx + 1))
def removeWidget(self, w):
"""
Removes driver widget from GUI.
- :param w: (QWidget) driver container widget to be removed.
+ :param w: (QWidget) driver container widget to be removed.
"""
# disconnect all widget connected signals
w.blockSignals(True)
@@ -229,16 +243,18 @@ def validate(self):
Validates container GUI parameters.
:return: (str) invalidation reason.
"""
- if self.objectName() == 'datasourceManagementWidgetIn':
- pageError = self.tr('Input Error!')
+ if self.objectName() == "datasourceManagementWidgetIn":
+ pageError = self.tr("Input Error!")
else:
- pageError = self.tr('Output Error!')
+ pageError = self.tr("Output Error!")
for containers in self.activeDrivers.values():
for container in containers:
if not container.isValid():
- return '{0} {1}: {2}'.format(pageError, container.groupBox.title(), container.validate())
+ return "{0} {1}: {2}".format(
+ pageError, container.groupBox.title(), container.validate()
+ )
# validate selection widget
- return ''
+ return ""
def isValid(self):
"""
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py
index 009038f86..bf7bf2cc1 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/datasourceSelectionWidgetFactory.py
@@ -23,17 +23,34 @@
from qgis.PyQt.QtWidgets import QWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.postgisWidget import PostgisWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newPostgisWidget import NewPostgisWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.spatialiteWidget import SpatialiteWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newSpatialiteWidget import NewSpatialiteWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.shapefileWidget import ShapefileWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newShapefileWidget import NewShapefileWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.geopackageWidget import GeopackageWidget
-from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newGeopackageWidget import NewGeopackageWidget
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.postgisWidget import (
+ PostgisWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newPostgisWidget import (
+ NewPostgisWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.spatialiteWidget import (
+ SpatialiteWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newSpatialiteWidget import (
+ NewSpatialiteWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.shapefileWidget import (
+ ShapefileWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newShapefileWidget import (
+ NewShapefileWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.geopackageWidget import (
+ GeopackageWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabaseConversionWidgets.SupportedDrivers.newGeopackageWidget import (
+ NewGeopackageWidget,
+)
from DsgTools.core.dsgEnums import DsgEnums
-class DatasourceSelectionWidgetFactory():
+
+class DatasourceSelectionWidgetFactory:
"""
Class designed to prepare each selection widget to be added to a widget container.
"""
@@ -46,14 +63,14 @@ def getSelectionWidget(source, parent=None):
:return: (QWidget) selection widget for selected driver.
"""
sourceDict = {
- DsgEnums.NoDriver : lambda : QWidget(), # returns a parent class empty object, to minimize standard distorsion
- DsgEnums.PostGIS : lambda : PostgisWidget(parent=parent),
- DsgEnums.NewPostGIS : lambda : NewPostgisWidget(parent=parent),
- DsgEnums.SpatiaLite : lambda : SpatialiteWidget(parent=parent),
- DsgEnums.NewSpatiaLite : lambda : NewSpatialiteWidget(parent=parent),
- DsgEnums.Shapefile : lambda : ShapefileWidget(parent=parent),
- DsgEnums.NewShapefile : lambda : NewShapefileWidget(parent=parent),
- DsgEnums.Geopackage : lambda : GeopackageWidget(parent=parent),
- DsgEnums.NewGeopackage : lambda : NewGeopackageWidget(parent=parent)
+ DsgEnums.NoDriver: lambda: QWidget(), # returns a parent class empty object, to minimize standard distorsion
+ DsgEnums.PostGIS: lambda: PostgisWidget(parent=parent),
+ DsgEnums.NewPostGIS: lambda: NewPostgisWidget(parent=parent),
+ DsgEnums.SpatiaLite: lambda: SpatialiteWidget(parent=parent),
+ DsgEnums.NewSpatiaLite: lambda: NewSpatialiteWidget(parent=parent),
+ DsgEnums.Shapefile: lambda: ShapefileWidget(parent=parent),
+ DsgEnums.NewShapefile: lambda: NewShapefileWidget(parent=parent),
+ DsgEnums.Geopackage: lambda: GeopackageWidget(parent=parent),
+ DsgEnums.NewGeopackage: lambda: NewGeopackageWidget(parent=parent),
}
return sourceDict[source]()
diff --git a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py
index 993365406..6abb29d7c 100755
--- a/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseConversionWidgets/filterDialog.py
@@ -31,8 +31,10 @@
from qgis.PyQt.QtCore import pyqtSlot, Qt
from qgis.PyQt.QtWidgets import QDialog, QCheckBox
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'filterDialog.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "filterDialog.ui")
+)
+
class FilterDialog(QDialog, FORM_CLASS):
def __init__(self, spatialLayers, complexLayers, abstractDb, parent=None):
@@ -41,7 +43,7 @@ def __init__(self, spatialLayers, complexLayers, abstractDb, parent=None):
:param spatialLayers: (list-of-QgsVectorLayer) list of spatial layers.
:param complexLayers: (list-of-QgsVectorLayer) list of complex layers.
:param complexLayers: (AbstractDb) database object for data handling.
- :param parent: (QtWidgets) any widget that should be parent to newly
+ :param parent: (QtWidgets) any widget that should be parent to newly
instantiated object.
"""
super(FilterDialog, self).__init__(parent)
@@ -71,7 +73,7 @@ def layerNamesFromCanvas(self):
def layerFromLayerName(self, layerName):
"""
Gets vector layer object from its name.
- :param layerName: (str)
+ :param layerName: (str)
:return: (QgsVectorLayer) map cointaing layer name to vector layer object.
"""
l = QgsProject.instance().mapLayersByName(layerName)
@@ -87,7 +89,7 @@ def fillSpatialFilterLayers(self):
[self.tr("Select a layer...")] + self.layerNamesFromCanvas()
)
- @pyqtSlot(int, name='on_spatialComboBox_currentIndexChanged')
+ @pyqtSlot(int, name="on_spatialComboBox_currentIndexChanged")
def setSpatialFilterLayer(self):
"""
Sets spatial layer to its filter expression widget.
@@ -102,7 +104,7 @@ def fillPredicates(self):
"""
self.predicateComboBox.clear()
self.predicateComboBox.addItems(
- sorted([self.tr('Clip'), self.tr('Buffer'), self.tr('Intersects')])
+ sorted([self.tr("Clip"), self.tr("Buffer"), self.tr("Intersects")])
)
def fillClipOptions(self):
@@ -110,13 +112,15 @@ def fillClipOptions(self):
Clip options are given by choosing the area to be kept.
"""
self.comboBox.clear()
- self.comboBox.addItems([
- self.tr('Choose a region...'),
- self.tr('Inside Features'),
- self.tr('Outside Features')
- ])
+ self.comboBox.addItems(
+ [
+ self.tr("Choose a region..."),
+ self.tr("Inside Features"),
+ self.tr("Outside Features"),
+ ]
+ )
- @pyqtSlot(int, name='on_predicateComboBox_currentIndexChanged')
+ @pyqtSlot(int, name="on_predicateComboBox_currentIndexChanged")
def setPredicateWidget(self):
"""
Sets the widget for capturing the topological relationship comparison parameter.
@@ -150,7 +154,7 @@ def clearSelection(self):
Clears the dict to its initial state.
"""
self._currentSelection = {}
-
+
def setupLayerFilters(self):
"""
Sets all layers to GUI.
@@ -170,26 +174,27 @@ def fetchSpatialParameter(self, predicate):
:return: (tuple) spatial filter settings.
"""
return {
- self.tr('Clip') : self.comboBox.currentText() if self.comboBox.currentIndex() > 0 else None,
- self.tr('Buffer') : self.doubleSpinBox.value(),
- self.tr('Intersects') : None,
- '' : None
+ self.tr("Clip"): self.comboBox.currentText()
+ if self.comboBox.currentIndex() > 0
+ else None,
+ self.tr("Buffer"): self.doubleSpinBox.value(),
+ self.tr("Intersects"): None,
+ "": None,
}[predicate]
def setPredicateParameter(self, predicate, parameter):
"""
Sets given parameter to the GUI.
:param predicate: (str) predicate to which the parameter refers to.
- :param parameter: (obj) parameter value to be filled.
+ :param parameter: (obj) parameter value to be filled.
"""
actionMap = {
- self.tr('Clip') : self.comboBox.setCurrentText,
- self.tr('Buffer') : self.doubleSpinBox.setValue,
- self.tr('Intersects') : lambda : None
+ self.tr("Clip"): self.comboBox.setCurrentText,
+ self.tr("Buffer"): self.doubleSpinBox.setValue,
+ self.tr("Intersects"): lambda: None,
}
return actionMap[predicate](parameter) if parameter in actionMap else None
-
def setupGroupBoxFilters(self, isSpatial=True):
"""
Sets up the part the spatial/complex layers' GUI part. It does not handle selection (e.g.
@@ -200,15 +205,24 @@ def setupGroupBoxFilters(self, isSpatial=True):
layers = self.spatialLayers if isSpatial else self.complexLayers
layout = self.spatialGridLayout if isSpatial else self.complexGridLayout
for row, (layerName, layerFcMap) in enumerate(layers.items()):
- checkBoxWidget, fieldExpressionWidget = QCheckBox(), QgsFieldExpressionWidget()
+ checkBoxWidget, fieldExpressionWidget = (
+ QCheckBox(),
+ QgsFieldExpressionWidget(),
+ )
_, layer = self._abstractDb.getTableSchema(layerName)
checkBoxWidget.setChecked(True)
# allow filtering option only when layer is marked to be filtered
checkBoxWidget.toggled.connect(fieldExpressionWidget.setEnabled)
- checkBoxWidget.toggled.connect(partial(fieldExpressionWidget.setExpression, ""))
- msg = self.tr('{0} ({1} features)') if layerFcMap['featureCount'] > 1 else self.tr('{0} ({1} feature)')
- checkBoxWidget.setText(msg.format(layer, layerFcMap['featureCount']))
- fieldExpressionWidget.setLayer(layerFcMap['layer'])
+ checkBoxWidget.toggled.connect(
+ partial(fieldExpressionWidget.setExpression, "")
+ )
+ msg = (
+ self.tr("{0} ({1} features)")
+ if layerFcMap["featureCount"] > 1
+ else self.tr("{0} ({1} feature)")
+ )
+ checkBoxWidget.setText(msg.format(layer, layerFcMap["featureCount"]))
+ fieldExpressionWidget.setLayer(layerFcMap["layer"])
layout.addWidget(checkBoxWidget, row, 0)
layout.addWidget(fieldExpressionWidget, row, 1)
@@ -222,7 +236,7 @@ def validateSpatialFilter(self, layer, expression, predicate, parameter=None):
:return: (bool) whether the set of spatial filter settings may be applied to the dataset.
"""
if predicate == self.tr("Clip"):
- return parameter is not None and parameter != self.tr('Choose a region...')
+ return parameter is not None and parameter != self.tr("Choose a region...")
elif predicate == self.tr("Buffer"):
return parameter is not None
return True
@@ -245,25 +259,34 @@ def readFilters(self):
checkBox = layout.itemAtPosition(row, 0).widget()
if checkBox is None or not checkBox.isChecked():
continue
- label = checkBox.text().replace('&', '') # still no idea why the '&' got in there...
- layer = label.split(' (')[0]
+ label = checkBox.text().replace(
+ "&", ""
+ ) # still no idea why the '&' got in there...
+ layer = label.split(" (")[0]
fieldExpressionWidget = layout.itemAtPosition(row, 1).widget()
layerFilters[layer] = dict()
- layerFilters[layer]['featureCount'] = int(label.split(' (')[1].split(' ')[0])
- layerFilters[layer]['expression'] = fieldExpressionWidget.currentText()
+ layerFilters[layer]["featureCount"] = int(
+ label.split(" (")[1].split(" ")[0]
+ )
+ layerFilters[layer]["expression"] = fieldExpressionWidget.currentText()
# read spatial filtering options
spatialFilters = dict()
- spatialFilters['layer'] = self.spatialComboBox.currentText() \
- if self.spatialComboBox.currentIndex() else ""
- spatialFilters['expression'] = self.mFieldExpressionWidget.currentText()
- spatialFilters['predicate'] = self.predicateComboBox.currentText()
- spatialFilters['parameter'] = self.fetchSpatialParameter(spatialFilters['predicate'])
- return {'layer_filter' : layerFilters, 'spatial_filter' : spatialFilters}
+ spatialFilters["layer"] = (
+ self.spatialComboBox.currentText()
+ if self.spatialComboBox.currentIndex()
+ else ""
+ )
+ spatialFilters["expression"] = self.mFieldExpressionWidget.currentText()
+ spatialFilters["predicate"] = self.predicateComboBox.currentText()
+ spatialFilters["parameter"] = self.fetchSpatialParameter(
+ spatialFilters["predicate"]
+ )
+ return {"layer_filter": layerFilters, "spatial_filter": spatialFilters}
@staticmethod
def setWidgetToReadOnly(widget, readOnly):
"""
- Sets (or removes) a widget to read only mode.
+ Sets (or removes) a widget to read only mode.
:param readOnly: (bool) whether widget will be read only mode.
"""
widget.setAttribute(Qt.WA_TransparentForMouseEvents, readOnly)
@@ -287,9 +310,16 @@ def enableEdition(self, enabled):
if checkBox is None:
continue
FilterDialog.setWidgetToReadOnly(checkBox, not enabled)
- FilterDialog.setWidgetToReadOnly(layout.itemAtPosition(row, 1).widget(), not enabled)
- for w in [self.spatialComboBox, self.mFieldExpressionWidget, self.predicateComboBox,\
- self.comboBox, self.doubleSpinBox]:
+ FilterDialog.setWidgetToReadOnly(
+ layout.itemAtPosition(row, 1).widget(), not enabled
+ )
+ for w in [
+ self.spatialComboBox,
+ self.mFieldExpressionWidget,
+ self.predicateComboBox,
+ self.comboBox,
+ self.doubleSpinBox,
+ ]:
FilterDialog.setWidgetToReadOnly(w, not enabled)
def resetSelection(self):
@@ -297,7 +327,7 @@ def resetSelection(self):
Resets layer selection to last state preserved into the private attribute holding current
layer selection.
"""
- prevLayerFilter = self._currentSelection['layer_filter']
+ prevLayerFilter = self._currentSelection["layer_filter"]
for layout in [self.spatialGridLayout, self.complexGridLayout]:
for row in range(layout.rowCount()):
if row == 0:
@@ -310,18 +340,30 @@ def resetSelection(self):
if not checkBox:
continue
fieldExpressionWidget = layout.itemAtPosition(row, 1).widget()
- label = checkBox.text().replace('&', '') # still no idea why the '&' got in there...
- layer = label.split(' (')[0]
+ label = checkBox.text().replace(
+ "&", ""
+ ) # still no idea why the '&' got in there...
+ layer = label.split(" (")[0]
checkBox.setChecked(layer in prevLayerFilter)
- exp = prevLayerFilter[layer]['expression'] if layer in prevLayerFilter else ""
+ exp = (
+ prevLayerFilter[layer]["expression"]
+ if layer in prevLayerFilter
+ else ""
+ )
fieldExpressionWidget.setExpression(exp)
# reset spatial filters
- self.spatialComboBox.setCurrentText(self._currentSelection['spatial_filter']['layer'])
- self.mFieldExpressionWidget.setExpression(self._currentSelection['spatial_filter']['expression'])
- self.predicateComboBox.setCurrentText(self._currentSelection['spatial_filter']['predicate'])
+ self.spatialComboBox.setCurrentText(
+ self._currentSelection["spatial_filter"]["layer"]
+ )
+ self.mFieldExpressionWidget.setExpression(
+ self._currentSelection["spatial_filter"]["expression"]
+ )
+ self.predicateComboBox.setCurrentText(
+ self._currentSelection["spatial_filter"]["predicate"]
+ )
self.setPredicateParameter(
- self._currentSelection['spatial_filter']['predicate'],
- self._currentSelection['spatial_filter']['parameter']
+ self._currentSelection["spatial_filter"]["predicate"],
+ self._currentSelection["spatial_filter"]["parameter"],
)
def on_okPushButton_clicked(self):
diff --git a/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py
index a9449e9e5..753018165 100644
--- a/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabaseCustomizationWidgets/customizationManagerWidget.py
@@ -28,67 +28,116 @@
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
-from DsgTools.core.ServerManagementTools.customizationManager import CustomizationManager
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter
-from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import CreateDatabaseCustomization
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import GenericManagerWidget
+# DsgTools imports
+from DsgTools.core.ServerManagementTools.customizationManager import (
+ CustomizationManager,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import (
+ GenericParameterSetter,
+)
+from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import (
+ CreateDatabaseCustomization,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import (
+ GenericManagerWidget,
+)
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
from qgis.core import QgsMessageLog
import json
+
class CustomizationManagerWidget(GenericManagerWidget):
- def __init__(self, manager = None, parent = None):
+ def __init__(self, manager=None, parent=None):
"""
Constructor
"""
- super(CustomizationManagerWidget, self).__init__(genericDbManager = manager, parent = parent)
+ super(CustomizationManagerWidget, self).__init__(
+ genericDbManager=manager, parent=parent
+ )
- def setParameters(self, serverAbstractDb, edgvVersion, dbsDict = {}):
+ def setParameters(self, serverAbstractDb, edgvVersion, dbsDict={}):
if serverAbstractDb:
self.setComponentsEnabled(True)
self.serverAbstractDb = serverAbstractDb
- self.genericDbManager = CustomizationManager(serverAbstractDb, dbsDict, edgvVersion)
+ self.genericDbManager = CustomizationManager(
+ serverAbstractDb, dbsDict, edgvVersion
+ )
self.refresh()
else:
self.setComponentsEnabled(False)
@pyqtSlot(bool)
def on_createPushButton_clicked(self):
- '''
+ """
Slot that opens the create profile dialog
- '''
+ """
paramDlg = GenericParameterSetter()
if not paramDlg.exec_():
return
templateDb, propertyName, edgvVersion = paramDlg.getParameters()
- if edgvVersion == self.tr('Select EDGV Version'):
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter a EDGV Version'))
+ if edgvVersion == self.tr("Select EDGV Version"):
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Warning! Enter a EDGV Version")
+ )
return
- if propertyName == '':
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter an Earth Coverage Name!'))
+ if propertyName == "":
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Enter an Earth Coverage Name!"),
+ )
return
- if propertyName in list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()):
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Earth Coverage Name already exists!'))
+ if propertyName in list(
+ self.genericDbManager.getPropertyPerspectiveDict(
+ viewType=DsgEnums.Property
+ ).keys()
+ ):
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Earth Coverage Name already exists!"),
+ )
return
- dlg = CreateDatabaseCustomization(propertyName, templateDb, edgvVersion, self.genericDbManager)
+ dlg = CreateDatabaseCustomization(
+ propertyName, templateDb, edgvVersion, self.genericDbManager
+ )
dlg.exec_()
-
+
@pyqtSlot(bool)
def on_deleteCustomizationPushButton_clicked(self):
- #TODO: Reimplement
+ # TODO: Reimplement
customizationName = self.customizationListWidget.currentItem().text()
edgvVersion = self.versionSelectionComboBox.currentText()
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to delete customization ')+customizationName+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to delete customization ")
+ + customizationName
+ + "?",
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.genericDbManager.deleteCustomization(customizationName, edgvVersion)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Customization ') + customizationName + self.tr(' successfully deleted.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Success!"),
+ self.tr("Customization ")
+ + customizationName
+ + self.tr(" successfully deleted."),
+ )
self.refreshProfileList()
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem deleting customization: ') + ':'.join(e.args))
\ No newline at end of file
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem deleting customization: ") + ":".join(e.args),
+ )
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py
index 50f453869..a6680d1bc 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/databaseParameterWidget.py
@@ -33,13 +33,16 @@
from qgis.PyQt.QtWidgets import QFileDialog, QMessageBox, QRadioButton
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'databaseParameterWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "databaseParameterWidget.ui")
+)
+
class DatabaseParameterWidget(QtWidgets.QWidget, FORM_CLASS):
filesSelected = pyqtSignal()
changeSize = pyqtSignal()
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
@@ -47,36 +50,52 @@ def __init__(self, parent = None):
self.selectedAbstractDb = None
self.setInitialState()
self.useFrame = True
-
- @pyqtSlot(AbstractDb, name = 'on_comboBoxPostgis_dbChanged') #check this out luiz! hahahahaha
+
+ @pyqtSlot(
+ AbstractDb, name="on_comboBoxPostgis_dbChanged"
+ ) # check this out luiz! hahahahaha
def populateSelectedAbstractDb(self, abstractDb):
self.selectedAbstractDb = abstractDb
if self.useFrame:
self.populateFrameComboBox()
-
+
def populateFrameComboBox(self):
if self.selectedAbstractDb:
- areaDict = self.selectedAbstractDb.getGeomColumnDictV2(primitiveFilter=['a'], excludeValidation = True)
+ areaDict = self.selectedAbstractDb.getGeomColumnDictV2(
+ primitiveFilter=["a"], excludeValidation=True
+ )
self.frameComboBox.clear()
- self.frameComboBox.addItem(self.tr('Select a table from database'))
+ self.frameComboBox.addItem(self.tr("Select a table from database"))
self.tableDict = dict()
sortedKeys = list(areaDict.keys())
sortedKeys.sort()
for key in sortedKeys:
- tableKey = '{0}.{1}:{2}'.format(areaDict[key]['tableSchema'], areaDict[key]['tableName'], areaDict[key]['geom'])
+ tableKey = "{0}.{1}:{2}".format(
+ areaDict[key]["tableSchema"],
+ areaDict[key]["tableName"],
+ areaDict[key]["geom"],
+ )
self.tableDict[tableKey] = areaDict[key]
self.frameComboBox.addItem(tableKey)
-
- @pyqtSlot(int, name = 'on_frameComboBox_currentIndexChanged')
+
+ @pyqtSlot(int, name="on_frameComboBox_currentIndexChanged")
def populateCombos(self, idx):
if self.selectedAbstractDb:
if idx > 0:
self.indexComboBox.clear()
self.inomComboBox.clear()
- self.indexComboBox.addItem(self.tr('Select an attribute from selected table'))
- self.inomComboBox.addItem(self.tr('Select an attribute from selected table'))
+ self.indexComboBox.addItem(
+ self.tr("Select an attribute from selected table")
+ )
+ self.inomComboBox.addItem(
+ self.tr("Select an attribute from selected table")
+ )
selected = self.tableDict[self.frameComboBox.currentText()]
- attributeList = self.selectedAbstractDb.getAttributesFromTable(selected['tableSchema'], selected['tableName'], typeFilter = ['character', 'character varying', 'text'])
+ attributeList = self.selectedAbstractDb.getAttributesFromTable(
+ selected["tableSchema"],
+ selected["tableName"],
+ typeFilter=["character", "character varying", "text"],
+ )
for attr in attributeList:
self.indexComboBox.addItem(attr)
self.inomComboBox.addItem(attr)
@@ -85,7 +104,7 @@ def setServerDb(self, abstractDb):
self.serverAbstractDb = abstractDb
self.dbTemplateRadioButton.setEnabled(True)
self.comboBoxPostgis.setServerDb(self.serverAbstractDb)
-
+
def setInitialState(self):
"""
Sets the initial state
@@ -96,69 +115,69 @@ def setInitialState(self):
self.frameGroupBox.hide()
if not self.serverAbstractDb:
self.dbTemplateRadioButton.setEnabled(False)
-
+
def setPrefixVisible(self, visible):
"""
Sets if the database prefix should be visible
"""
- if isinstance(visible,bool):
+ if isinstance(visible, bool):
self.prefixLineEdit.setVisible(visible)
self.prefixLabel.setVisible(visible)
self.prefixVisible = visible
-
+
def setSufixVisible(self, visible):
"""
Sets if the database sufix should be visible
"""
- if isinstance(visible,bool):
+ if isinstance(visible, bool):
self.sufixLineEdit.setVisible(visible)
self.sufixLabel.setVisible(visible)
self.sufixVisible = visible
-
+
def setDbNameVisible(self, visible):
"""
Sets if the database name should be visible
"""
- if isinstance(visible,bool):
+ if isinstance(visible, bool):
self.dbNameLineEdit.setVisible(visible)
self.dbNameLabel.setVisible(visible)
self.dbNameVisible = visible
-
+
def getVersion(self):
"""
Get the database version
"""
return self.versionComboBox.currentText()
-
+
def validate(self):
"""
Validate database name
"""
- errorMsg = ''
+ errorMsg = ""
if self.dbNameVisible:
- if self.dbNameLineEdit.text() == '':
- errorMsg += self.tr('Enter a database name!\n')
- if self.mQgsProjectionSelectionWidget.crs().authid() == '':
- errorMsg += self.tr('Select a coordinate reference system!\n')
+ if self.dbNameLineEdit.text() == "":
+ errorMsg += self.tr("Enter a database name!\n")
+ if self.mQgsProjectionSelectionWidget.crs().authid() == "":
+ errorMsg += self.tr("Select a coordinate reference system!\n")
if not self.edgvTemplateRadioButton.isChecked():
if not self.comboBoxPostgis.currentDb():
- errorMsg += self.tr('Select a template database!\n')
+ errorMsg += self.tr("Select a template database!\n")
if self.useFrame:
if self.frameComboBox.currentIndex() == 0:
- errorMsg += self.tr('Select a frame layer!\n')
+ errorMsg += self.tr("Select a frame layer!\n")
if self.indexComboBox.currentIndex() == 0:
- errorMsg += self.tr('Select an index attribute!\n')
+ errorMsg += self.tr("Select an index attribute!\n")
if self.inomComboBox.currentIndex() == 0:
- errorMsg += self.tr('Select an INOM attribute!\n')
-
- if errorMsg != '':
- QMessageBox.critical(self, self.tr('Critical!'), errorMsg)
+ errorMsg += self.tr("Select an INOM attribute!\n")
+
+ if errorMsg != "":
+ QMessageBox.critical(self, self.tr("Critical!"), errorMsg)
return False
else:
return True
-
- @pyqtSlot(bool, name = 'on_edgvTemplateRadioButton_toggled')
- def changeInterfaceState(self, edgvTemplateToggled, hideInterface = True):
+
+ @pyqtSlot(bool, name="on_edgvTemplateRadioButton_toggled")
+ def changeInterfaceState(self, edgvTemplateToggled, hideInterface=True):
if edgvTemplateToggled:
self.comboBoxPostgis.setEnabled(False)
self.frameComboBox.setEnabled(False)
@@ -178,34 +197,33 @@ def changeInterfaceState(self, edgvTemplateToggled, hideInterface = True):
else:
self.comboBoxPostgis.show()
self.dbTemplateRadioButton.show()
-
+
def getTemplateName(self):
if self.edgvTemplateRadioButton.isChecked():
return None
else:
return self.comboBoxPostgis.currentDb()
-
+
def getTemplateParameters(self):
if self.edgvTemplateRadioButton.isChecked():
paramDict = dict()
if self.serverAbstractDb:
- paramDict['templateName'] = self.serverAbstractDb.getTemplateName(self.versionComboBox.currentText())
- paramDict['version'] = self.versionComboBox.currentText()
- paramDict['isTemplateEdgv'] = True
- return paramDict
+ paramDict["templateName"] = self.serverAbstractDb.getTemplateName(
+ self.versionComboBox.currentText()
+ )
+ paramDict["version"] = self.versionComboBox.currentText()
+ paramDict["isTemplateEdgv"] = True
+ return paramDict
else:
paramDict = dict()
- paramDict['templateName'] = self.comboBoxPostgis.currentDb()
- paramDict['isTemplateEdgv'] = False
+ paramDict["templateName"] = self.comboBoxPostgis.currentDb()
+ paramDict["isTemplateEdgv"] = False
if self.useFrame:
selected = self.tableDict[self.frameComboBox.currentText()]
- paramDict['tableSchema'] = selected['tableSchema']
- paramDict['tableName'] = selected['tableName']
- paramDict['geom'] = selected['geom']
- paramDict['miAttr'] = self.indexComboBox.currentText()
- paramDict['inomAttr'] = self.inomComboBox.currentText()
- paramDict['geomType'] = selected['geomType']
+ paramDict["tableSchema"] = selected["tableSchema"]
+ paramDict["tableName"] = selected["tableName"]
+ paramDict["geom"] = selected["geom"]
+ paramDict["miAttr"] = self.indexComboBox.currentText()
+ paramDict["inomAttr"] = self.inomComboBox.currentText()
+ paramDict["geomType"] = selected["geomType"]
return paramDict
-
-
-
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py
index 39595f7f3..7f52d11c2 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageManagerWidget.py
@@ -28,98 +28,136 @@
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
-from DsgTools.core.ServerManagementTools.earthCoverageManager import EarthCoverageManager
-from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import CreateDatabaseCustomization
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import GenericManagerWidget
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.setupEarthCoverage import SetupEarthCoverage
+# DsgTools imports
+from DsgTools.core.ServerManagementTools.earthCoverageManager import (
+ EarthCoverageManager,
+)
+from DsgTools.gui.Misc.PostgisCustomization.createDatabaseCustomization import (
+ CreateDatabaseCustomization,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import (
+ GenericParameterSetter,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import (
+ GenericManagerWidget,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.setupEarthCoverage import (
+ SetupEarthCoverage,
+)
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
from qgis.core import QgsMessageLog
import json
+
class EarthCoverageManagerWidget(GenericManagerWidget):
- def __init__(self, manager = None, parent = None):
+ def __init__(self, manager=None, parent=None):
"""
Constructor
"""
- super(self.__class__, self).__init__(genericDbManager = manager, parent = parent)
+ super(self.__class__, self).__init__(genericDbManager=manager, parent=parent)
- def setParameters(self, serverAbstractDb, edgvVersion, dbsDict = {}):
+ def setParameters(self, serverAbstractDb, edgvVersion, dbsDict={}):
if serverAbstractDb:
self.setComponentsEnabled(True)
self.serverAbstractDb = serverAbstractDb
- self.genericDbManager = EarthCoverageManager(serverAbstractDb, dbsDict, edgvVersion)
+ self.genericDbManager = EarthCoverageManager(
+ serverAbstractDb, dbsDict, edgvVersion
+ )
self.refresh()
else:
self.setComponentsEnabled(False)
@pyqtSlot(bool)
def on_createPushButton_clicked(self):
- '''
+ """
Slot that opens the create profile dialog
- '''
+ """
dlg = GenericParameterSetter()
if not dlg.exec_():
return
templateDb, propertyName, edgvVersion = dlg.getParameters()
- if edgvVersion == self.tr('Select EDGV Version'):
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter a EDGV Version'))
+ if edgvVersion == self.tr("Select EDGV Version"):
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Warning! Enter a EDGV Version")
+ )
return
- if propertyName == '':
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter an Earth Coverage Name!'))
+ if propertyName == "":
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Enter an Earth Coverage Name!"),
+ )
return
- if propertyName in list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()):
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Earth Coverage Name already exists!'))
+ if propertyName in list(
+ self.genericDbManager.getPropertyPerspectiveDict(
+ viewType=DsgEnums.Property
+ ).keys()
+ ):
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Earth Coverage Name already exists!"),
+ )
return
- fieldSetupDict = self.populateConfigInterface(templateDb, propertyName = propertyName)
+ fieldSetupDict = self.populateConfigInterface(
+ templateDb, propertyName=propertyName
+ )
if fieldSetupDict:
- self.genericDbManager.createSetting(propertyName, edgvVersion, fieldSetupDict)
+ self.genericDbManager.createSetting(
+ propertyName, edgvVersion, fieldSetupDict
+ )
self.refresh()
- QMessageBox.information(self, self.tr('Success!'), self.tr('Field Toolbox Configuration ') + propertyName + self.tr(' created successfuly!'))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.tr("Field Toolbox Configuration ")
+ + propertyName
+ + self.tr(" created successfuly!"),
+ )
-
- def populateConfigInterface(self, templateDb, jsonDict = None, propertyName = None):
- '''
+ def populateConfigInterface(self, templateDb, jsonDict=None, propertyName=None):
+ """
Must be reimplemented in each child
- '''
- areas = templateDb.getParentGeomTables(getFullName = True, primitiveFilter = ['a'])
- lines = templateDb.getParentGeomTables(getFullName = True, primitiveFilter = ['l'])
+ """
+ areas = templateDb.getParentGeomTables(getFullName=True, primitiveFilter=["a"])
+ lines = templateDb.getParentGeomTables(getFullName=True, primitiveFilter=["l"])
edgvVersion = templateDb.getDatabaseVersion()
settings = self.genericDbManager.getSettings()
if edgvVersion in list(settings.keys()):
propertyList = settings
else:
propertyList = []
- dlg = SetupEarthCoverage(edgvVersion, areas, lines, jsonDict, propertyList, propertyName = propertyName)
+ dlg = SetupEarthCoverage(
+ edgvVersion, areas, lines, jsonDict, propertyList, propertyName=propertyName
+ )
if dlg.exec_():
return dlg.configDict
else:
return None
-
+
def getUpdateSelectedSettingHeader(self):
- header = self.tr('Update Earth Coverage configuration complete. \n')
- operation = self.tr('earth coverage configuration')
+ header = self.tr("Update Earth Coverage configuration complete. \n")
+ operation = self.tr("earth coverage configuration")
return header, operation
def getUninstallSelectedSettingHeader(self):
- header = self.tr('Uninstall Earth Coverage configuration complete. \n')
- operation = self.tr('earth coverage configuration')
+ header = self.tr("Uninstall Earth Coverage configuration complete. \n")
+ operation = self.tr("earth coverage configuration")
return header, operation
def getApplyHeader(self):
- header = self.tr('Install Earth Coverage configuration complete. \n')
- operation = self.tr('earth coverage configurations')
+ header = self.tr("Install Earth Coverage configuration complete. \n")
+ operation = self.tr("earth coverage configurations")
return header, operation
-
+
def getDeleteHeader(self):
- header = self.tr('Delete Earth Coverage configuration complete. \n')
- operation = self.tr('earth coverage configurations')
+ header = self.tr("Delete Earth Coverage configuration complete. \n")
+ operation = self.tr("earth coverage configurations")
return header, operation
-
+
def getUninstallFromSelected(self):
- header = self.tr('Uninstall Earth Coverage configuration complete. \n')
- operation = self.tr('earth coverage configurations')
- return header, operation
\ No newline at end of file
+ header = self.tr("Uninstall Earth Coverage configuration complete. \n")
+ operation = self.tr("earth coverage configurations")
+ return header, operation
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py
index 4e62f05d8..38efa0e81 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/earthCoverageWidget.py
@@ -27,15 +27,19 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal
from qgis.PyQt.QtWidgets import QTreeWidgetItem, QMessageBox
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'earthCoverageWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "earthCoverageWidget.ui")
+)
from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from qgis.core import QgsMessageLog
-from DsgTools.core.ServerManagementTools.earthCoverageManager import EarthCoverageManager
+from DsgTools.core.ServerManagementTools.earthCoverageManager import (
+ EarthCoverageManager,
+)
from DsgTools.core.dsgEnums import DsgEnums
+
class EarthCoverageWidget(QtWidgets.QWidget, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
@@ -68,14 +72,18 @@ def clearTree(self):
self.earthCoverageTreeWidget.invisibleRootItem().takeChildren()
def getEarthCoverageDict(self):
- if self.abstractDb.checkIfExistsConfigTable('EarthCoverage'):
+ if self.abstractDb.checkIfExistsConfigTable("EarthCoverage"):
edgvVersion = self.abstractDb.getDatabaseVersion()
- propertyDict = self.abstractDb.getAllSettingsFromAdminDb('EarthCoverage')
+ propertyDict = self.abstractDb.getAllSettingsFromAdminDb("EarthCoverage")
if edgvVersion in list(propertyDict.keys()):
propertyName = propertyDict[edgvVersion][0]
dbName = self.abstractDb.db.databaseName()
- self.settingDict = json.loads(self.abstractDb.getSettingFromAdminDb('EarthCoverage', propertyName, edgvVersion))
- self.earthCoverageDict = self.settingDict['earthCoverageDict']
+ self.settingDict = json.loads(
+ self.abstractDb.getSettingFromAdminDb(
+ "EarthCoverage", propertyName, edgvVersion
+ )
+ )
+ self.earthCoverageDict = self.settingDict["earthCoverageDict"]
def loadEarthCoverage(self):
"""
@@ -86,14 +94,19 @@ def loadEarthCoverage(self):
if self.earthCoverageDict == dict():
self.getEarthCoverageDict()
rootItem = self.earthCoverageTreeWidget.invisibleRootItem()
- #database item
+ # database item
for key in list(self.earthCoverageDict.keys()):
item = QTreeWidgetItem(rootItem)
- item.setText(0,key)
+ item.setText(0, key)
item.setExpanded(True)
for cl in self.earthCoverageDict[key]:
covItem = QTreeWidgetItem(item)
- covItem.setText(1,cl)
+ covItem.setText(1, cl)
covItem.setExpanded(True)
except Exception as e:
- QgsMessageLog.logMessage(self.tr('Earth Coverage not loaded! Check log for details.')+':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
\ No newline at end of file
+ QgsMessageLog.logMessage(
+ self.tr("Earth Coverage not loaded! Check log for details.")
+ + ":".join(e.args),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py
index de535199e..a733be16b 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericManagerWidget.py
@@ -27,10 +27,16 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic, QtCore
from qgis.PyQt.QtCore import pyqtSlot, Qt, pyqtSignal
-from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog, QMenu, QHeaderView
+from qgis.PyQt.QtWidgets import (
+ QMessageBox,
+ QApplication,
+ QFileDialog,
+ QMenu,
+ QHeaderView,
+)
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
+# DsgTools imports
from DsgTools.gui.CustomWidgets.SelectionWidgets.listSelector import ListSelector
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
@@ -38,39 +44,54 @@
from qgis.core import QgsMessageLog, Qgis
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'genericManagerWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "genericManagerWidget.ui")
+)
+
class GenericManagerWidget(QtWidgets.QWidget, FORM_CLASS):
Install, Delete, Uninstall, Update, Create = list(range(5))
- def __init__(self, genericDbManager = None, parent = None):
+
+ def __init__(self, genericDbManager=None, parent=None):
"""
Constructor
"""
super(GenericManagerWidget, self).__init__(parent)
self.setupUi(self)
self.genericDbManager = genericDbManager
- self.textDict = {'EarthCoverage':self.tr('Earth Coverage'),
- 'Customization':self.tr('Customization'),
- 'Style':self.tr('Style'),
- 'ValidationConfig':self.tr('Validation'),
- 'Permission':self.tr('Permissions'),
- 'AttributeRules':self.tr('Attribute Rule Configuration'),
- 'SpatialRuleConfig':self.tr('Spatial Rule Configuration')}
- self.captionDict = {'EarthCoverage':self.tr('Earth Coverage'),
- 'Customization':self.tr('Customization'),
- 'Style':self.tr('Style'),
- 'ValidationConfig':self.tr('Validation'),
- 'Permission':self.tr('Select a dsgtools permission profile'),
- 'AttributeRules':self.tr('Attribute Rule Configuration file'),
- 'SpatialRuleConfig':self.tr('Spatial Rule Configuration file')}
- self.filterDict = {'EarthCoverage':self.tr('Earth Coverage Setup File (*.dsgearthcov)'),
- 'Customization':self.tr('DsgTools Customization File (*.dsgcustom)'),
- 'Style':self.tr('DsgTools Styles File (*.dsgstyle)'),
- 'ValidationConfig':self.tr('DsgTools Validation Configuration File (*.dsgvalidcfg)'),
- 'Permission':self.tr('DsgTools Permission Profile File (*.dsgperm)'),
- 'AttributeRules':self.tr('Attribute Rule Configuration file (*.dsgattrrul)'),
- 'SpatialRuleConfig':self.tr('Spatial Rule Configuration file (*.dsgspatrul)')}
+ self.textDict = {
+ "EarthCoverage": self.tr("Earth Coverage"),
+ "Customization": self.tr("Customization"),
+ "Style": self.tr("Style"),
+ "ValidationConfig": self.tr("Validation"),
+ "Permission": self.tr("Permissions"),
+ "AttributeRules": self.tr("Attribute Rule Configuration"),
+ "SpatialRuleConfig": self.tr("Spatial Rule Configuration"),
+ }
+ self.captionDict = {
+ "EarthCoverage": self.tr("Earth Coverage"),
+ "Customization": self.tr("Customization"),
+ "Style": self.tr("Style"),
+ "ValidationConfig": self.tr("Validation"),
+ "Permission": self.tr("Select a dsgtools permission profile"),
+ "AttributeRules": self.tr("Attribute Rule Configuration file"),
+ "SpatialRuleConfig": self.tr("Spatial Rule Configuration file"),
+ }
+ self.filterDict = {
+ "EarthCoverage": self.tr("Earth Coverage Setup File (*.dsgearthcov)"),
+ "Customization": self.tr("DsgTools Customization File (*.dsgcustom)"),
+ "Style": self.tr("DsgTools Styles File (*.dsgstyle)"),
+ "ValidationConfig": self.tr(
+ "DsgTools Validation Configuration File (*.dsgvalidcfg)"
+ ),
+ "Permission": self.tr("DsgTools Permission Profile File (*.dsgperm)"),
+ "AttributeRules": self.tr(
+ "Attribute Rule Configuration file (*.dsgattrrul)"
+ ),
+ "SpatialRuleConfig": self.tr(
+ "Spatial Rule Configuration file (*.dsgspatrul)"
+ ),
+ }
self.widgetName = self.textDict[self.getWhoAmI()]
self.genericDict = None
self.setComponentsEnabled(False)
@@ -79,30 +100,39 @@ def __init__(self, genericDbManager = None, parent = None):
self.setButtons()
self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeWidget.customContextMenuRequested.connect(self.createMenuAssigned)
-
+
def setButtons(self):
createText = self.createPushButton.text()
- self.createPushButton.setText(createText.replace(self.tr('Setting'),self.widgetName))
+ self.createPushButton.setText(
+ createText.replace(self.tr("Setting"), self.widgetName)
+ )
deleteText = self.deletePushButton.text()
- self.deletePushButton.setText(deleteText.replace(self.tr('Setting'),self.widgetName))
-
+ self.deletePushButton.setText(
+ deleteText.replace(self.tr("Setting"), self.widgetName)
+ )
+
def setHeaders(self):
viewType = self.getViewType()
if viewType == DsgEnums.Database:
- self.treeWidget.setHeaderLabels([self.tr('Database'), self.widgetName])
+ self.treeWidget.setHeaderLabels([self.tr("Database"), self.widgetName])
else:
- self.treeWidget.setHeaderLabels([self.widgetName, self.tr('Database')])
+ self.treeWidget.setHeaderLabels([self.widgetName, self.tr("Database")])
return viewType
-
+
def getWhoAmI(self):
- return str(self.__class__).split('.')[-1].replace('\'>', '').replace('ManagerWidget','')
-
+ return (
+ str(self.__class__)
+ .split(".")[-1]
+ .replace("'>", "")
+ .replace("ManagerWidget", "")
+ )
+
def setChildParameter(self):
"""
Reimplement in each child
"""
pass
-
+
def setComponentsEnabled(self, enabled):
"""
Changes states of all components of the widget, according to the boolean parameter enabled.
@@ -115,17 +145,19 @@ def setComponentsEnabled(self, enabled):
self.databasePerspectivePushButton.setEnabled(enabled)
self.propertyPerspectivePushButton.setEnabled(enabled)
- def populateConfigInterface(self, templateDb, jsonDict = None):
+ def populateConfigInterface(self, templateDb, jsonDict=None):
"""
Must be reimplemented in each child
"""
- pass
+ pass
def readJsonFromDatabase(self, propertyName, edgvVersion):
"""
Reads the profile file, gets a dictionary of it and builds the tree widget
"""
- self.genericDict = self.genericDbManager.getCustomization(propertyName, edgvVersion)
+ self.genericDict = self.genericDbManager.getCustomization(
+ propertyName, edgvVersion
+ )
@pyqtSlot(bool)
def on_importPushButton_clicked(self):
@@ -134,21 +166,34 @@ def on_importPushButton_clicked(self):
"""
fd = QFileDialog()
widgetType = self.getWhoAmI()
- filename = fd.getOpenFileName(caption=self.captionDict[widgetType],filter=self.filterDict[widgetType])[0]
+ filename = fd.getOpenFileName(
+ caption=self.captionDict[widgetType], filter=self.filterDict[widgetType]
+ )[0]
filename = filename[0] if isinstance(filename, tuple) else filename
- if filename == '':
+ if filename == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a file to import!'))
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.genericDbManager.importSetting(filename)
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully imported.'))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.widgetName + self.tr(" successfully imported."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem importing ') +self.widgetName + ': ' + ':'.join(e.args))
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem importing ")
+ + self.widgetName
+ + ": "
+ + ":".join(e.args),
+ )
self.refresh()
-
+
@pyqtSlot(bool)
def on_exportPushButton_clicked(self):
"""
@@ -159,12 +204,16 @@ def on_exportPushButton_clicked(self):
# user cancelled
return
if exportPropertyList == []:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a profile to export!'))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Select a profile to export!"),
+ )
return
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output'))
+ folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output"))
folder = folder[0] if isinstance(folder, tuple) else folder
- if folder == '':
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!'))
return
edgvVersion = self.genericDbManager.edgvVersion
@@ -173,55 +222,92 @@ def on_exportPushButton_clicked(self):
for exportProperty in exportPropertyList:
self.genericDbManager.exportSetting(exportProperty, edgvVersion, folder)
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully exported.'))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.widgetName + self.tr(" successfully exported."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem exporting ') + self.widgetName + ': ' + ':'.join(e.args))
-
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem exporting ")
+ + self.widgetName
+ + ": "
+ + ":".join(e.args),
+ )
+
@pyqtSlot(bool)
def on_batchExportPushButton_clicked(self):
"""
Exports all configs from dsgtools_admindb.
"""
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output'))
+ folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output"))
folder = folder[0] if isinstance(folder, tuple) else folder
- if folder == '':
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!'))
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.genericDbManager.batchExportSettings(folder)
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully exported.'))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.widgetName + self.tr(" successfully exported."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem exporting ') + self.widgetName + ': ' + ':'.join(e.args))
-
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem exporting ")
+ + self.widgetName
+ + ": "
+ + ":".join(e.args),
+ )
+
@pyqtSlot(bool)
def on_batchImportPushButton_clicked(self):
"""
Imports all config files from a folder into dsgtools_admindb. It only works for a single type of config per time.
"""
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder with json files: '))
- if folder == '':
+ folder = fd.getExistingDirectory(
+ caption=self.tr("Select a folder with json files: ")
+ )
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a input folder!'))
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.genericDbManager.batchImportSettings(folder)
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Success!'), self.widgetName + self.tr(' successfully imported.'))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.widgetName + self.tr(" successfully imported."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem importing ') + self.widgetName + ': ' + ':'.join(e.args))
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem importing ")
+ + self.widgetName
+ + ": "
+ + ":".join(e.args),
+ )
@pyqtSlot(bool)
def on_applyPushButton_clicked(self):
dbList = list(self.genericDbManager.dbDict.keys())
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Install, dbList = dbList)
- if successDict == {} and exceptionDict == {}:
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Install, dbList=dbList
+ )
+ if successDict == {} and exceptionDict == {}:
return
header, operation = self.getApplyHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
@@ -229,7 +315,7 @@ def on_applyPushButton_clicked(self):
@pyqtSlot(bool)
def on_deletePushButton_clicked(self):
successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Delete)
- if successDict == {} and exceptionDict == {}:
+ if successDict == {} and exceptionDict == {}:
return
header, operation = self.getDeleteHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
@@ -237,8 +323,10 @@ def on_deletePushButton_clicked(self):
@pyqtSlot(bool)
def on_uninstallFromSelectedPushButton_clicked(self):
dbList = []
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, dbList)
- if successDict == {} and exceptionDict == {}:
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Uninstall, dbList
+ )
+ if successDict == {} and exceptionDict == {}:
return
header, operation = self.getUninstallFromSelected()
self.outputMessage(operation, header, successDict, exceptionDict)
@@ -249,11 +337,13 @@ def getViewType(self):
else:
return DsgEnums.Property
- @pyqtSlot(bool, name='on_databasePerspectivePushButton_clicked')
- @pyqtSlot(bool, name='on_propertyPerspectivePushButton_clicked')
+ @pyqtSlot(bool, name="on_databasePerspectivePushButton_clicked")
+ @pyqtSlot(bool, name="on_propertyPerspectivePushButton_clicked")
def refresh(self):
viewType = self.setHeaders()
- propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(viewType)
+ propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(
+ viewType
+ )
self.treeWidget.clear()
rootNode = self.treeWidget.invisibleRootItem()
if viewType == DsgEnums.Database:
@@ -264,13 +354,15 @@ def refresh(self):
parentCustomItem = self.utils.createWidgetItem(rootNode, key, 0)
if key in list(propertyPerspectiveDict.keys()):
for item in propertyPerspectiveDict[key]:
- if item and item != '':
+ if item and item != "":
dbItem = self.utils.createWidgetItem(parentCustomItem, item, 1)
self.treeWidget.sortItems(0, Qt.AscendingOrder)
self.treeWidget.expandAll()
- self.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
+ self.treeWidget.header().setSectionResizeMode(
+ QtWidgets.QHeaderView.ResizeToContents
+ )
self.treeWidget.header().setStretchLastSection(False)
-
+
def outputMessage(self, operation, header, successDict, exceptionDict):
"""
successDict = {configName: [--list of successful databases--]}
@@ -281,48 +373,65 @@ def outputMessage(self, operation, header, successDict, exceptionDict):
for setting in list(successDict.keys()):
successList = successDict[setting]
if len(successDict[setting]) > 0:
- msg += self.tr('\nSuccessful ')
- msg += operation + ' : '
+ msg += self.tr("\nSuccessful ")
+ msg += operation + " : "
msg += setting
if successList:
if len(successList) > 0:
try:
- msg += self.tr(' on databases ') + ', '.join(successList)
- except: #none type case, just add .
- msg += '.'
+ msg += self.tr(" on databases ") + ", ".join(successList)
+ except: # none type case, just add .
+ msg += "."
msg += self.logInternalError(exceptionDict)
- QMessageBox.warning(self, self.tr('Operation Complete!'), msg)
-
+ QMessageBox.warning(self, self.tr("Operation Complete!"), msg)
+
def logInternalError(self, exceptionDict):
"""
exceptionDict = {configName: {dbName: errorText}}
"""
- msg = ''
+ msg = ""
configList = list(exceptionDict.keys())
if len(configList) > 0:
- msg += self.tr('\nConfig with error:') + ','.join(configList)
- msg+= self.tr('\nError messages for each config and database were output in qgis log.')
+ msg += self.tr("\nConfig with error:") + ",".join(configList)
+ msg += self.tr(
+ "\nError messages for each config and database were output in qgis log."
+ )
for config in configList:
for dbName in list(exceptionDict[config].keys()):
if exceptionDict[config][dbName] != dict():
- QgsMessageLog.logMessage(self.tr('Error for config ')+ config + ' in database ' +dbName+' : '+exceptionDict[config][dbName], "DSGTools Plugin", Qgis.Critical)
- return msg
+ QgsMessageLog.logMessage(
+ self.tr("Error for config ")
+ + config
+ + " in database "
+ + dbName
+ + " : "
+ + exceptionDict[config][dbName],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ return msg
- def manageSetting(self, config, manageType, dbList = [], parameterDict = dict()):
+ def manageSetting(self, config, manageType, dbList=[], parameterDict=dict()):
if manageType == GenericManagerWidget.Install:
- return self.genericDbManager.installSetting(config, dbNameList = dbList)
+ return self.genericDbManager.installSetting(config, dbNameList=dbList)
elif manageType == GenericManagerWidget.Delete:
return self.genericDbManager.deleteSetting(config)
elif manageType == GenericManagerWidget.Uninstall:
- return self.genericDbManager.uninstallSetting(config, dbNameList = dbList)
+ return self.genericDbManager.uninstallSetting(config, dbNameList=dbList)
elif manageType == GenericManagerWidget.Update:
- return self.genericDbManager.updateSetting(config, parameterDict['newJsonDict'])
+ return self.genericDbManager.updateSetting(
+ config, parameterDict["newJsonDict"]
+ )
elif manageType == GenericManagerWidget.Create:
- return self.genericDbManager.createSetting(config, parameterDict['newJsonDict'])
-
+ return self.genericDbManager.createSetting(
+ config, parameterDict["newJsonDict"]
+ )
+
def selectConfig(self):
- availableConfig = list(self.genericDbManager.getPropertyPerspectiveDict().keys())
- dlg = ListSelector(availableConfig,[])
+ availableConfig = list(
+ self.genericDbManager.getPropertyPerspectiveDict().keys()
+ )
+ dlg = ListSelector(availableConfig, [])
res = dlg.exec_()
if res == 0:
# to identify when user presses Cancel
@@ -330,7 +439,9 @@ def selectConfig(self):
selectedConfig = dlg.getSelected()
return selectedConfig
- def manageSettings(self, manageType, dbList=None, selectedConfig=None, parameterDict = dict()):
+ def manageSettings(
+ self, manageType, dbList=None, selectedConfig=None, parameterDict=dict()
+ ):
"""
Executes the setting work according to manageType
successDict = {configName: [--list of successful databases--]}
@@ -343,15 +454,21 @@ def manageSettings(self, manageType, dbList=None, selectedConfig=None, parameter
# user cancelled
return dict(), dict()
if selectedConfig == []:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one configuration!'))
- return (dict(),dict())
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Select at least one configuration!"),
+ )
+ return (dict(), dict())
successDict = dict()
exceptionDict = dict()
dbList = [] if dbList is None else dbList
- if self.lookAndPromptForStructuralChanges(dbList = dbList):
+ if self.lookAndPromptForStructuralChanges(dbList=dbList):
for config in selectedConfig:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
- sucessList, errorDict = self.manageSetting(config, manageType, dbList = dbList, parameterDict = parameterDict)
+ sucessList, errorDict = self.manageSetting(
+ config, manageType, dbList=dbList, parameterDict=parameterDict
+ )
QApplication.restoreOverrideCursor()
successDict[config] = sucessList
if errorDict != dict():
@@ -359,9 +476,11 @@ def manageSettings(self, manageType, dbList=None, selectedConfig=None, parameter
self.refresh()
return successDict, exceptionDict
else:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Operation canceled by user!'))
- return (dict(),dict())
-
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Operation canceled by user!")
+ )
+ return (dict(), dict())
+
def createMenuAssigned(self, position):
"""
Creates a pop up menu
@@ -376,31 +495,61 @@ def createDbPerspectiveContextMenu(self, position):
menu = QMenu()
item = self.treeWidget.itemAt(position)
if item:
- if item.text(0) != '':
- menu.addAction(self.tr('Uninstall all settings from selected database'), self.uninstallSettings)
- menu.addAction(self.tr('Manage settings from selected database'), self.manageDbSettings)
- elif item.text(1) != '':
- menu.addAction(self.tr('Update selected setting'), self.updateSelectedSetting)
- menu.addAction(self.tr('Clone selected setting'), self.cloneSelectedSetting)
- menu.addAction(self.tr('Uninstall selected setting'), self.uninstallSettings)
- menu.addAction(self.tr('Delete selected setting'), self.deleteSelectedSetting)
+ if item.text(0) != "":
+ menu.addAction(
+ self.tr("Uninstall all settings from selected database"),
+ self.uninstallSettings,
+ )
+ menu.addAction(
+ self.tr("Manage settings from selected database"),
+ self.manageDbSettings,
+ )
+ elif item.text(1) != "":
+ menu.addAction(
+ self.tr("Update selected setting"), self.updateSelectedSetting
+ )
+ menu.addAction(
+ self.tr("Clone selected setting"), self.cloneSelectedSetting
+ )
+ menu.addAction(
+ self.tr("Uninstall selected setting"), self.uninstallSettings
+ )
+ menu.addAction(
+ self.tr("Delete selected setting"), self.deleteSelectedSetting
+ )
menu.exec_(self.treeWidget.viewport().mapToGlobal(position))
-
+
def createPropertyPerspectiveContextMenu(self, position):
menu = QMenu()
item = self.treeWidget.itemAt(position)
if item:
- if item.text(0) != '':
- menu.addAction(self.tr('Update selected setting'), self.updateSelectedSetting)
- menu.addAction(self.tr('Clone selected setting'), self.cloneSelectedSetting)
- menu.addAction(self.tr('Manage selected setting'), self.manageSelectedSetting)
- menu.addAction(self.tr('Uninstall selected setting on all databases'), self.uninstallSettings)
- menu.addAction(self.tr('Delete selected setting'), self.deleteSelectedSetting)
- elif item.text(1) != '':
- menu.addAction(self.tr('Manage Settings on database'), self.manageDbSettings)
- menu.addAction(self.tr('Uninstall selected setting on selected database'), self.uninstallSettings)
+ if item.text(0) != "":
+ menu.addAction(
+ self.tr("Update selected setting"), self.updateSelectedSetting
+ )
+ menu.addAction(
+ self.tr("Clone selected setting"), self.cloneSelectedSetting
+ )
+ menu.addAction(
+ self.tr("Manage selected setting"), self.manageSelectedSetting
+ )
+ menu.addAction(
+ self.tr("Uninstall selected setting on all databases"),
+ self.uninstallSettings,
+ )
+ menu.addAction(
+ self.tr("Delete selected setting"), self.deleteSelectedSetting
+ )
+ elif item.text(1) != "":
+ menu.addAction(
+ self.tr("Manage Settings on database"), self.manageDbSettings
+ )
+ menu.addAction(
+ self.tr("Uninstall selected setting on selected database"),
+ self.uninstallSettings,
+ )
menu.exec_(self.treeWidget.viewport().mapToGlobal(position))
-
+
def manageDbSettings(self):
"""
1. get installed profiles and available profiles
@@ -409,25 +558,41 @@ def manageDbSettings(self):
"""
uiParameterDict = self.getParametersFromInterface()
propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict()
- availableConfig = [i for i in list(propertyPerspectiveDict.keys()) if i not in uiParameterDict['parameterList']]
- dlg = ListSelector(availableConfig,uiParameterDict['parameterList'])
+ availableConfig = [
+ i
+ for i in list(propertyPerspectiveDict.keys())
+ if i not in uiParameterDict["parameterList"]
+ ]
+ dlg = ListSelector(availableConfig, uiParameterDict["parameterList"])
dlg.exec_()
fromLs, toLs = dlg.getInputAndOutputLists()
- #build install list: elements from toLs that were not in uiParameterDict['parameterList']
- installList = [i for i in toLs if i not in uiParameterDict['parameterList']]
- #build uninstall list: : elements fromLs that were not in availableConfig
- uninstallList = [i for i in fromLs if i in uiParameterDict['parameterList']]
- if (installList == [] and uninstallList == []):
- QMessageBox.warning(self, self.tr('Error!'), self.tr('Select at least one configuration to manage!'))
+ # build install list: elements from toLs that were not in uiParameterDict['parameterList']
+ installList = [i for i in toLs if i not in uiParameterDict["parameterList"]]
+ # build uninstall list: : elements fromLs that were not in availableConfig
+ uninstallList = [i for i in fromLs if i in uiParameterDict["parameterList"]]
+ if installList == [] and uninstallList == []:
+ QMessageBox.warning(
+ self,
+ self.tr("Error!"),
+ self.tr("Select at least one configuration to manage!"),
+ )
return
if installList != []:
- #install:
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Install, selectedConfig = installList, dbList = uiParameterDict['databaseList'])
+ # install:
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Install,
+ selectedConfig=installList,
+ dbList=uiParameterDict["databaseList"],
+ )
header, operation = self.getApplyHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
if uninstallList != []:
- #uninstall:
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, selectedConfig = uninstallList, dbList = uiParameterDict['databaseList'])
+ # uninstall:
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Uninstall,
+ selectedConfig=uninstallList,
+ dbList=uiParameterDict["databaseList"],
+ )
header, operation = self.getUninstallSelectedSettingHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
@@ -438,26 +603,44 @@ def manageSelectedSetting(self):
3. get final lists and uninstall items and them install items
"""
uiParameterDict = self.getParametersFromInterface()
- propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Database)
- availableDb = [i for i in list(propertyPerspectiveDict.keys()) if i not in uiParameterDict['databaseList']]
- dlg = ListSelector(availableDb,uiParameterDict['databaseList'])
+ propertyPerspectiveDict = self.genericDbManager.getPropertyPerspectiveDict(
+ viewType=DsgEnums.Database
+ )
+ availableDb = [
+ i
+ for i in list(propertyPerspectiveDict.keys())
+ if i not in uiParameterDict["databaseList"]
+ ]
+ dlg = ListSelector(availableDb, uiParameterDict["databaseList"])
dlg.exec_()
fromLs, toLs = dlg.getInputAndOutputLists()
- #build install list: elements from toLs that were not in uiParameterDict['parameterList']
- installList = [i for i in toLs if i not in uiParameterDict['databaseList']]
- #build uninstall list: : elements fromLs that were not in availableConfig
- uninstallList = [i for i in fromLs if i in uiParameterDict['databaseList']]
- if (installList == [] and uninstallList == []):
- QMessageBox.warning(self, self.tr('Error!'), self.tr('Select at least one configuration database to manage!'))
+ # build install list: elements from toLs that were not in uiParameterDict['parameterList']
+ installList = [i for i in toLs if i not in uiParameterDict["databaseList"]]
+ # build uninstall list: : elements fromLs that were not in availableConfig
+ uninstallList = [i for i in fromLs if i in uiParameterDict["databaseList"]]
+ if installList == [] and uninstallList == []:
+ QMessageBox.warning(
+ self,
+ self.tr("Error!"),
+ self.tr("Select at least one configuration database to manage!"),
+ )
return
if installList != []:
- #install:
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Install, selectedConfig = uiParameterDict['parameterList'], dbList = installList)
+ # install:
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Install,
+ selectedConfig=uiParameterDict["parameterList"],
+ dbList=installList,
+ )
header, operation = self.getApplyHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
if uninstallList != []:
- #uninstall:
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, selectedConfig = uiParameterDict['parameterList'], dbList = uninstallList)
+ # uninstall:
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Uninstall,
+ selectedConfig=uiParameterDict["parameterList"],
+ dbList=uninstallList,
+ )
header, operation = self.getUninstallSelectedSettingHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
@@ -475,12 +658,16 @@ def updateSelectedSetting(self):
edgvVersion = self.genericDbManager.edgvVersion
templateDb = self.genericDbManager.instantiateTemplateDb(edgvVersion)
originalDict = self.genericDbManager.getSetting(settingName, edgvVersion)
- newDict = self.populateConfigInterface(templateDb, jsonDict = originalDict)
+ newDict = self.populateConfigInterface(templateDb, jsonDict=originalDict)
if newDict:
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Update, selectedConfig = [settingName], parameterDict = {'newJsonDict':newDict})
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Update,
+ selectedConfig=[settingName],
+ parameterDict={"newJsonDict": newDict},
+ )
header, operation = self.getUpdateSelectedSettingHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
-
+
def cloneSelectedSetting(self):
currItem = self.treeWidget.currentItem()
if self.getViewType() == DsgEnums.Database:
@@ -490,28 +677,32 @@ def cloneSelectedSetting(self):
edgvVersion = self.genericDbManager.edgvVersion
templateDb = self.genericDbManager.instantiateTemplateDb(edgvVersion)
originalDict = self.genericDbManager.getSetting(settingName, edgvVersion)
- newDict = self.populateConfigInterface(templateDb, jsonDict = originalDict)
+ newDict = self.populateConfigInterface(templateDb, jsonDict=originalDict)
if newDict:
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Create, selectedConfig = [settingName], parameterDict = {'newJsonDict':newDict})
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Create,
+ selectedConfig=[settingName],
+ parameterDict={"newJsonDict": newDict},
+ )
header, operation = self.getUpdateSelectedSettingHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
def getParametersFromInterface(self):
"""
- Gets selected database and selected property.
+ Gets selected database and selected property.
Returns {'databaseList':dbList, 'parameterList':parameterList}
"""
currItem = self.treeWidget.currentItem()
if self.getViewType() == DsgEnums.Database:
- #2 possibilities: leaf (if first column is '') or parent (if first column != '')
- if currItem.text(0) == '':
- #leaf -> must get
+ # 2 possibilities: leaf (if first column is '') or parent (if first column != '')
+ if currItem.text(0) == "":
+ # leaf -> must get
parentNode = currItem.parent()
dbName = parentNode.text(0)
parameter = currItem.text(1)
- return {'databaseList':[dbName], 'parameterList':[parameter]}
+ return {"databaseList": [dbName], "parameterList": [parameter]}
else:
- #parent
+ # parent
dbName = currItem.text(0)
childCount = currItem.childCount()
parameterList = []
@@ -520,16 +711,16 @@ def getParametersFromInterface(self):
parameterName = childNode.text(1)
if parameterName not in parameterList:
parameterList.append(parameterName)
- return {'databaseList':[dbName], 'parameterList':parameterList}
+ return {"databaseList": [dbName], "parameterList": parameterList}
else:
- if currItem.text(0) == '':
- #leaf
+ if currItem.text(0) == "":
+ # leaf
parentNode = currItem.parent()
parameter = parentNode.text(0)
dbName = currItem.text(1)
- return {'databaseList':[dbName], 'parameterList':[parameter]}
+ return {"databaseList": [dbName], "parameterList": [parameter]}
else:
- #parent
+ # parent
parameter = currItem.text(0)
childCount = currItem.childCount()
dbList = []
@@ -538,33 +729,58 @@ def getParametersFromInterface(self):
dbName = childNode.text(1)
if dbName not in dbList:
dbList.append(dbName)
- return {'databaseList':dbList, 'parameterList':[parameter]}
+ return {"databaseList": dbList, "parameterList": [parameter]}
def uninstallSettings(self):
edgvVersion = self.genericDbManager.edgvVersion
uiParameterDict = self.getParametersFromInterface()
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Uninstall, dbList = uiParameterDict['databaseList'], selectedConfig = uiParameterDict['parameterList'])
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Uninstall,
+ dbList=uiParameterDict["databaseList"],
+ selectedConfig=uiParameterDict["parameterList"],
+ )
header, operation = self.getUninstallSelectedSettingHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
-
+
def deleteSelectedSetting(self):
edgvVersion = self.genericDbManager.edgvVersion
uiParameterDict = self.getParametersFromInterface()
- settingTextList = ', '.join(uiParameterDict['parameterList'])
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to delete ')+settingTextList+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ settingTextList = ", ".join(uiParameterDict["parameterList"])
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to delete ") + settingTextList + "?",
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
- successDict, exceptionDict = self.manageSettings(GenericManagerWidget.Delete, selectedConfig = uiParameterDict['parameterList'])
+ successDict, exceptionDict = self.manageSettings(
+ GenericManagerWidget.Delete, selectedConfig=uiParameterDict["parameterList"]
+ )
header, operation = self.getDeleteHeader()
self.outputMessage(operation, header, successDict, exceptionDict)
-
- def lookAndPromptForStructuralChanges(self, dbList = []):
- '''
+
+ def lookAndPromptForStructuralChanges(self, dbList=[]):
+ """
Returns True if user accepts the process
- '''
+ """
structuralChanges = self.genericDbManager.hasStructuralChanges(dbList)
if structuralChanges != []:
- dbChangeList = ', '.join(structuralChanges)
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to apply selected operation on ')+dbChangeList+'?'+self.tr(' (Data may be lost in the process)'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ dbChangeList = ", ".join(structuralChanges)
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to apply selected operation on ")
+ + dbChangeList
+ + "?"
+ + self.tr(" (Data may be lost in the process)"),
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return False
else:
return True
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py
index 440809adf..1e55c3690 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/genericParameterSetter.py
@@ -28,11 +28,13 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'genericParameterSetter.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "genericParameterSetter.ui")
+)
+
class GenericParameterSetter(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, parent = None, nameList = None, hideDbUi = False):
+ def __init__(self, parent=None, nameList=None, hideDbUi=False):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.nameList = nameList
@@ -42,12 +44,12 @@ def __init__(self, parent = None, nameList = None, hideDbUi = False):
self.connectionWidget.hide()
else:
self.connectionWidget.tabWidget.removeTab(1)
- regex = QtCore.QRegExp('[a-z][a-z\_0-9]*')
+ regex = QtCore.QRegExp("[a-z][a-z\_0-9]*")
validator = QtGui.QRegExpValidator(regex, self.customNameLineEdit)
self.customNameLineEdit.setValidator(validator)
-
+
def validateUi(self):
- if self.customNameLineEdit.text() == '':
+ if self.customNameLineEdit.text() == "":
return False
if self.nameList:
if self.customNameLineEdit.text() in self.nameList:
@@ -56,33 +58,39 @@ def validateUi(self):
if self.connectionWidget.abstractDb == None:
return False
return True
-
+
def validateUiReason(self):
- validateReason = ''
- if self.customNameLineEdit.text() == '':
- validateReason += self.tr('Enter a parameter name!\n')
+ validateReason = ""
+ if self.customNameLineEdit.text() == "":
+ validateReason += self.tr("Enter a parameter name!\n")
if self.nameList:
if self.customNameLineEdit.text() in self.nameList:
- validateReason += self.tr('Parameter already exists! Choose another name!\n')
+ validateReason += self.tr(
+ "Parameter already exists! Choose another name!\n"
+ )
if not self.isHidden:
if self.connectionWidget.abstractDb == None:
- validateReason += self.tr('Select a template database!\n')
+ validateReason += self.tr("Select a template database!\n")
return validateReason
-
+
@pyqtSlot(bool)
def on_okPushButton_clicked(self):
if not self.validateUi():
reason = self.validateUiReason()
- QMessageBox.warning(self, self.tr('Warning!'), reason)
+ QMessageBox.warning(self, self.tr("Warning!"), reason)
else:
self.done(1)
-
+
@pyqtSlot(bool)
- def on_cancelPushButton_clicked(self):
+ def on_cancelPushButton_clicked(self):
self.done(0)
def getParameters(self):
if self.isHidden:
return self.customNameLineEdit.text()
else:
- return (self.connectionWidget.abstractDb , self.customNameLineEdit.text(), self.connectionWidget.abstractDb.getDatabaseVersion())
+ return (
+ self.connectionWidget.abstractDb,
+ self.customNameLineEdit.text(),
+ self.connectionWidget.abstractDb.getDatabaseVersion(),
+ )
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py
index 38c38201f..21ca1ed66 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/permissionWidget.py
@@ -25,23 +25,37 @@
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, Qt
-from qgis.PyQt.QtWidgets import QTreeWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QTreeWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.core import QgsMessageLog
from DsgTools.core.Factories.DbFactory.abstractDb import AbstractDb
-from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties
+from DsgTools.gui.DatabaseTools.UserTools.permission_properties import (
+ PermissionProperties,
+)
from DsgTools.gui.DatabaseTools.UserTools.manageServerUsers import ManageServerUsers
-from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizard import PermissionWizard
+from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizard import (
+ PermissionWizard,
+)
from DsgTools.gui.DatabaseTools.UserTools.profileUserManager import ProfileUserManager
from DsgTools.gui.DatabaseTools.UserTools.dbProfileManager import DbProfileManager
from DsgTools.core.ServerManagementTools.permissionManager import PermissionManager
-from DsgTools.gui.DatabaseTools.UserTools.serverProfilesManager import ServerProfilesManager
+from DsgTools.gui.DatabaseTools.UserTools.serverProfilesManager import (
+ ServerProfilesManager,
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'permissionWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "permissionWidget.ui")
+)
+
class PermissionWidget(QtWidgets.QWidget, FORM_CLASS):
def __init__(self, parent=None):
@@ -57,11 +71,13 @@ def __init__(self, parent=None):
self.dbDict = dict()
self.permissionManager = None
self.permissionTreeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
- self.permissionTreeWidget.customContextMenuRequested.connect(self.createMenuAssigned)
+ self.permissionTreeWidget.customContextMenuRequested.connect(
+ self.createMenuAssigned
+ )
# @pyqtSlot(bool, name='on_manageProfilesPushButton_clicked')
- @pyqtSlot(bool, name='on_databasePerspectivePushButton_clicked')
- @pyqtSlot(bool, name='on_userPerspectivePushButton_clicked')
+ @pyqtSlot(bool, name="on_databasePerspectivePushButton_clicked")
+ @pyqtSlot(bool, name="on_userPerspectivePushButton_clicked")
def refresh(self):
"""
Refreshes permission table according to selected view type.
@@ -69,14 +85,16 @@ def refresh(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
viewType = self.getViewType()
self.permissionTreeWidget.clear()
- if viewType == 'database':
+ if viewType == "database":
self.populateWithDatabasePerspective()
- if viewType == 'user':
+ if viewType == "user":
self.populateWithUserPerspective()
QApplication.restoreOverrideCursor()
-
+
def populateWithDatabasePerspective(self):
- self.permissionTreeWidget.setHeaderLabels([self.tr('Database'), self.tr('Permission'), self.tr('User')])
+ self.permissionTreeWidget.setHeaderLabels(
+ [self.tr("Database"), self.tr("Permission"), self.tr("User")]
+ )
dbPerspectiveDict = self.permissionManager.getDatabasePerspectiveDict()
rootNode = self.permissionTreeWidget.invisibleRootItem()
for dbName in list(dbPerspectiveDict.keys()):
@@ -89,7 +107,9 @@ def populateWithDatabasePerspective(self):
self.permissionTreeWidget.expandAll()
def populateWithUserPerspective(self):
- self.permissionTreeWidget.setHeaderLabels([self.tr('User'), self.tr('Database'), self.tr('Permission')])
+ self.permissionTreeWidget.setHeaderLabels(
+ [self.tr("User"), self.tr("Database"), self.tr("Permission")]
+ )
userPerspectiveDict = self.permissionManager.getUserPerspectiveDict()
rootNode = self.permissionTreeWidget.invisibleRootItem()
for userName in list(userPerspectiveDict.keys()):
@@ -100,22 +120,24 @@ def populateWithUserPerspective(self):
permissionItem = self.createItem(dbItem, permission, 2)
self.permissionTreeWidget.sortItems(0, Qt.AscendingOrder)
self.permissionTreeWidget.expandAll()
-
+
def createItem(self, parent, text, column):
item = QtWidgets.QTreeWidgetItem(parent)
item.setText(column, text)
return item
-
+
def getViewType(self):
if self.databasePerspectivePushButton.isChecked():
- return 'database'
+ return "database"
else:
- return 'user'
-
+ return "user"
+
def setParameters(self, serverAbstractDb, dbDict, edgvVersion):
self.serverAbstractDb = serverAbstractDb
self.dbDict = dbDict
- self.permissionManager = PermissionManager(self.serverAbstractDb, self.dbDict, edgvVersion)
+ self.permissionManager = PermissionManager(
+ self.serverAbstractDb, self.dbDict, edgvVersion
+ )
self.refresh()
@pyqtSlot(bool)
@@ -124,9 +146,9 @@ def on_manageUsersPushButton_clicked(self):
dlg = ManageServerUsers(self.serverAbstractDb)
dlg.exec_()
except:
- QMessageBox.warning(self, self.tr('Error!'), self.tr('Select a server!'))
+ QMessageBox.warning(self, self.tr("Error!"), self.tr("Select a server!"))
self.refresh()
-
+
@pyqtSlot(bool)
def on_manageProfilesPushButton_clicked(self):
try:
@@ -134,44 +156,53 @@ def on_manageProfilesPushButton_clicked(self):
# dlg.profilesChanged.connect(self.refresh)
dlg.exec_()
except Exception as e:
- QMessageBox.warning(self, self.tr('Error!'), ':'.join(e.args))
+ QMessageBox.warning(self, self.tr("Error!"), ":".join(e.args))
self.refresh()
-
+
def createMenuAssigned(self, position):
"""
Creates a pop up menu
"""
viewType = self.getViewType()
- if viewType == 'database':
+ if viewType == "database":
self.createDbPerspectiveContextMenu(position)
- if viewType == 'user':
+ if viewType == "user":
self.createUserPerspectiveContextMenu(position)
-
-
+
def createDbPerspectiveContextMenu(self, position):
menu = QMenu()
item = self.permissionTreeWidget.itemAt(position)
if item:
- if item.text(0) != '':
- menu.addAction(self.tr('Revoke all permissions'), self.revokeAll)
- elif item.text(1) != '':
- menu.addAction(self.tr('Manage User Permissions'), self.manageUserPermissions)
- elif item.text(2) != '':
- menu.addAction(self.tr('Revoke User'), self.revokeSelectedUser)
+ if item.text(0) != "":
+ menu.addAction(self.tr("Revoke all permissions"), self.revokeAll)
+ elif item.text(1) != "":
+ menu.addAction(
+ self.tr("Manage User Permissions"), self.manageUserPermissions
+ )
+ elif item.text(2) != "":
+ menu.addAction(self.tr("Revoke User"), self.revokeSelectedUser)
menu.exec_(self.permissionTreeWidget.viewport().mapToGlobal(position))
-
+
def createUserPerspectiveContextMenu(self, position):
menu = QMenu()
item = self.permissionTreeWidget.itemAt(position)
if item:
- if item.text(0) != '':
- menu.addAction(self.tr('Revoke permissions on all granted databases'), self.revokeAllDbs)
- elif item.text(1) != '':
- menu.addAction(self.tr('Manage Permissions on database'), self.managePermissionsOnDb)
- elif item.text(2) != '':
- menu.addAction(self.tr('Revoke Permission'), self.revokeSelectedPermission)
+ if item.text(0) != "":
+ menu.addAction(
+ self.tr("Revoke permissions on all granted databases"),
+ self.revokeAllDbs,
+ )
+ elif item.text(1) != "":
+ menu.addAction(
+ self.tr("Manage Permissions on database"),
+ self.managePermissionsOnDb,
+ )
+ elif item.text(2) != "":
+ menu.addAction(
+ self.tr("Revoke Permission"), self.revokeSelectedPermission
+ )
menu.exec_(self.permissionTreeWidget.viewport().mapToGlobal(position))
-
+
def manageUserPermissions(self):
currItem = self.permissionTreeWidget.currentItem()
profileName = currItem.text(1)
@@ -184,12 +215,19 @@ def manageUserPermissions(self):
notGrantedUserList = [i[0] for i in userList if i[0] not in grantedUserList]
edgvVersion = self.dbDict[dbName].getDatabaseVersion()
try:
- dlg = ProfileUserManager(grantedUserList, notGrantedUserList, self.permissionManager, profileName, dbName, edgvVersion)
+ dlg = ProfileUserManager(
+ grantedUserList,
+ notGrantedUserList,
+ self.permissionManager,
+ profileName,
+ dbName,
+ edgvVersion,
+ )
dlg.exec_()
except:
pass
self.refresh()
-
+
def revokeSelectedUser(self):
userName = self.permissionTreeWidget.currentItem().text(2)
permissionName = self.permissionTreeWidget.currentItem().parent().text(1)
@@ -198,10 +236,20 @@ def revokeSelectedUser(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.revokePermission(dbName, permissionName, userName)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Revoke Complete!'), self.tr('Revoke for user ') + userName + self.tr(' on profile ') + permissionName + self.tr(' of database ') + dbName + self.tr(' complete.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Revoke Complete!"),
+ self.tr("Revoke for user ")
+ + userName
+ + self.tr(" on profile ")
+ + permissionName
+ + self.tr(" of database ")
+ + dbName
+ + self.tr(" complete."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Error!'), ':'.join(e.args))
+ QMessageBox.warning(self, self.tr("Error!"), ":".join(e.args))
self.refresh()
def revokeAll(self):
@@ -214,9 +262,11 @@ def revokeAll(self):
userCount = permissionNode.childCount()
for j in range(userCount):
userName = permissionNode.child(j).text(2)
- self.permissionManager.revokePermission(dbName, permissionName, userName)
+ self.permissionManager.revokePermission(
+ dbName, permissionName, userName
+ )
self.refresh()
-
+
def revokeAllDbs(self):
currItem = self.permissionTreeWidget.currentItem()
userName = currItem.text(0)
@@ -227,9 +277,11 @@ def revokeAllDbs(self):
permissionCount = dbNode.childCount()
for j in range(permissionCount):
permissionName = dbNode.child(j).text(2)
- self.permissionManager.revokePermission(dbName, permissionName, userName)
+ self.permissionManager.revokePermission(
+ dbName, permissionName, userName
+ )
self.refresh()
-
+
def managePermissionsOnDb(self):
currItem = self.permissionTreeWidget.currentItem()
dbName = currItem.text(1)
@@ -240,14 +292,23 @@ def managePermissionsOnDb(self):
grantedProfileList.append(currItem.child(i).text(2))
profileDict = self.permissionManager.getSettings()
edgvVersion = self.dbDict[dbName].getDatabaseVersion()
- notGrantedProfileList = [i for i in profileDict[edgvVersion] if i not in grantedProfileList]
+ notGrantedProfileList = [
+ i for i in profileDict[edgvVersion] if i not in grantedProfileList
+ ]
try:
- dlg = DbProfileManager(grantedProfileList, notGrantedProfileList, self.permissionManager, userName, dbName, edgvVersion)
+ dlg = DbProfileManager(
+ grantedProfileList,
+ notGrantedProfileList,
+ self.permissionManager,
+ userName,
+ dbName,
+ edgvVersion,
+ )
dlg.exec_()
except:
pass
self.refresh()
-
+
def revokeSelectedPermission(self):
permissionName = self.permissionTreeWidget.currentItem().text(2)
dbName = self.permissionTreeWidget.currentItem().parent().text(1)
@@ -256,39 +317,63 @@ def revokeSelectedPermission(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.revokePermission(dbName, permissionName, userName)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Revoke Complete!'), self.tr('Revoke for user ') + userName + self.tr(' on profile ') + permissionName + self.tr(' of database ') + dbName + self.tr(' complete.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Revoke Complete!"),
+ self.tr("Revoke for user ")
+ + userName
+ + self.tr(" on profile ")
+ + permissionName
+ + self.tr(" of database ")
+ + dbName
+ + self.tr(" complete."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Error!'), ':'.join(e.args))
+ QMessageBox.warning(self, self.tr("Error!"), ":".join(e.args))
self.refresh()
@pyqtSlot(bool)
def on_importPushButton_clicked(self):
fd = QFileDialog()
- filename = fd.getOpenFileName(caption=self.tr('Select a dsgtools profile'),filter=self.tr('json file (*.json)'))
+ filename = fd.getOpenFileName(
+ caption=self.tr("Select a dsgtools profile"),
+ filter=self.tr("json file (*.json)"),
+ )
filename = filename[0] if isinstance(filename, tuple) else filename
- if filename == '':
+ if filename == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a file to import!'))
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.importSetting(filename)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission successfully imported.'))
+ QMessageBox.warning(
+ self, self.tr("Success!"), self.tr("Permission successfully imported.")
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem importing permission: ') + ':'.join(e.args))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem importing permission: ") + ":".join(e.args),
+ )
# self.refreshProfileList()
-
+
@pyqtSlot(bool)
def on_exportPushButton_clicked(self):
- if not self.permissionTreeWidget.currentItem() or (self.permissionTreeWidget.currentItem().text(0) != '' or self.permissionTreeWidget.currentItem().text(2) != ''):
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a profile to export!'))
+ if not self.permissionTreeWidget.currentItem() or (
+ self.permissionTreeWidget.currentItem().text(0) != ""
+ or self.permissionTreeWidget.currentItem().text(2) != ""
+ ):
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Error! Select a profile to export!")
+ )
return
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output'))
- if folder == '':
+ folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output"))
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a output!'))
return
profileName = self.permissionTreeWidget.currentItem().text(1)
@@ -298,39 +383,59 @@ def on_exportPushButton_clicked(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.exportSetting(profileName, edgvVersion, folder)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission successfully exported.'))
+ QMessageBox.warning(
+ self, self.tr("Success!"), self.tr("Permission successfully exported.")
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem exporting permission: ') + ':'.join(e.args))
-
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem exporting permission: ") + ":".join(e.args),
+ )
+
@pyqtSlot(bool)
def on_batchExportPushButton_clicked(self):
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output'))
- if folder == '':
+ folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output"))
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a output!'))
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.batchExportSettings(folder)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Permissions successfully exported.'))
+ QMessageBox.warning(
+ self, self.tr("Success!"), self.tr("Permissions successfully exported.")
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem exporting permission: ') + ':'.join(e.args))
-
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem exporting permission: ") + ":".join(e.args),
+ )
+
@pyqtSlot(bool)
def on_batchImportPushButton_clicked(self):
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder with permissions: '))
- if folder == '':
+ folder = fd.getExistingDirectory(
+ caption=self.tr("Select a folder with permissions: ")
+ )
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Select a input folder!'))
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.batchImportSettings(folder)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Permissions successfully imported.'))
+ QMessageBox.warning(
+ self, self.tr("Success!"), self.tr("Permissions successfully imported.")
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem importing permission: ') + ':'.join(e.args))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem importing permission: ") + ":".join(e.args),
+ )
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py
index 6523070e7..a1f2218c8 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.py
@@ -29,12 +29,26 @@
from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog
from DsgTools.core.Utils.utils import Utils
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'setupEarthCoverage.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "setupEarthCoverage.ui")
+)
+
class SetupEarthCoverage(QtWidgets.QWizard, FORM_CLASS):
coverageChanged = pyqtSignal()
- def __init__(self, edgvVersion, areas, lines, oldCoverage, propertyList, enableSetupFromFile = True, onlySetup = False, propertyName = None, parent=None):
+
+ def __init__(
+ self,
+ edgvVersion,
+ areas,
+ lines,
+ oldCoverage,
+ propertyList,
+ enableSetupFromFile=True,
+ onlySetup=False,
+ propertyName=None,
+ parent=None,
+ ):
"""
Constructor
"""
@@ -45,8 +59,8 @@ def __init__(self, edgvVersion, areas, lines, oldCoverage, propertyList, enableS
self.lines = lines
self.propertyName = propertyName
self.edgvVersion = edgvVersion
- self.areasCustomSelector.setTitle(self.tr('Areas'))
- self.linesCustomSelector.setTitle(self.tr('Lines'))
+ self.areasCustomSelector.setTitle(self.tr("Areas"))
+ self.linesCustomSelector.setTitle(self.tr("Lines"))
self.propertyList = propertyList
self.button(QtWidgets.QWizard.NextButton).clicked.connect(self.buildTree)
self.button(QtWidgets.QWizard.FinishButton).clicked.connect(self.buildDict)
@@ -57,9 +71,22 @@ def setupFromFile(self):
"""
Opens a earth coverage file
"""
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you want to open an earth coverage file?'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you want to open an earth coverage file?"),
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
- filename, __ = QFileDialog.getOpenFileName(self, self.tr('Open Earth Coverage Setup configuration'), '', self.tr('Earth Coverage Files (*.json)'))
+ filename, __ = QFileDialog.getOpenFileName(
+ self,
+ self.tr("Open Earth Coverage Setup configuration"),
+ "",
+ self.tr("Earth Coverage Files (*.json)"),
+ )
return filename
def setupWizard(self, oldCoverage, enableSetupFromFile):
@@ -85,12 +112,12 @@ def setupWizard(self, oldCoverage, enableSetupFromFile):
if self.propertyName:
self.nameLineEdit.setText(self.propertyName)
self.nameLineEdit.setEnabled(False)
-
+
def setupUiFromFile(self, filename):
"""
Populates ui from parameters of json
"""
- #read json
+ # read json
jsonDict = self.utils.readJsonFile(filename)
self.setupUiFromDict(jsonDict)
@@ -98,19 +125,21 @@ def setupUiFromDict(self, jsonDict):
"""
Populates ui from parameters of json
"""
- #set nameLineEdit
- self.nameLineEdit.setText(jsonDict['configName'])
- #populate listWidget
- self.populateFrameListWidget(self.areas, frame = jsonDict['frameLayer'])
- linesFromList, linesToList, areasFromList, areasToList = self.populateLists(jsonDict['earthCoverageDict'])
+ # set nameLineEdit
+ self.nameLineEdit.setText(jsonDict["configName"])
+ # populate listWidget
+ self.populateFrameListWidget(self.areas, frame=jsonDict["frameLayer"])
+ linesFromList, linesToList, areasFromList, areasToList = self.populateLists(
+ jsonDict["earthCoverageDict"]
+ )
self.areasCustomSelector.setToList(areasToList)
self.areasCustomSelector.setFromList(areasFromList)
self.linesCustomSelector.setToList(linesToList)
self.linesCustomSelector.setFromList(linesFromList)
self.buildTree()
- self.checkDelimiters(jsonDict['earthCoverageDict'])
-
- def populateFrameListWidget(self, areas, frame = None):
+ self.checkDelimiters(jsonDict["earthCoverageDict"])
+
+ def populateFrameListWidget(self, areas, frame=None):
areas.sort()
self.listWidget.clear()
self.listWidget.addItems(areas)
@@ -120,7 +149,7 @@ def populateFrameListWidget(self, areas, frame = None):
self.listWidget.setCurrentItem(frameItem)
except:
pass
-
+
def populateLists(self, setupDict):
areasToList = list(setupDict.keys())
linesToList = []
@@ -143,13 +172,18 @@ def checkDelimiters(self, setupDict):
delimiterItem = areaItem.child(j)
if areaItem.text(0) in list(setupDict.keys()):
if delimiterItem.text(1) not in setupDict[areaItem.text(0)]:
- delimiterItem.setCheckState(1,Qt.Unchecked)
+ delimiterItem.setCheckState(1, Qt.Unchecked)
def loadJson(self, filename):
"""
Loads a json file
"""
- filename, __ = QFileDialog.getOpenFileName(self, self.tr('Open Field Setup configuration'), self.folder, self.tr('Earth Coverage Setup File (*.dsgearthcov)'))
+ filename, __ = QFileDialog.getOpenFileName(
+ self,
+ self.tr("Open Field Setup configuration"),
+ self.folder,
+ self.tr("Earth Coverage Setup File (*.dsgearthcov)"),
+ )
if not filename:
return
return self.readJsonFile(filename)
@@ -162,8 +196,8 @@ def populateClasses(self):
selectedAreaClasses = self.areasCustomSelector.toLs
for i in range(len(selectedAreaClasses)):
treeItem = QtWidgets.QTreeWidgetItem()
- treeItem.setText(0,selectedAreaClasses[i])
- self.treeWidget.insertTopLevelItem(0,treeItem)
+ treeItem.setText(0, selectedAreaClasses[i])
+ self.treeWidget.insertTopLevelItem(0, treeItem)
def populateDelimiters(self):
"""
@@ -174,10 +208,12 @@ def populateDelimiters(self):
delimiterList.append(self.linesCustomSelector.toList.item(i).text())
for i in range(self.treeWidget.invisibleRootItem().childCount()):
for delimiter in delimiterList:
- treeItem = QtWidgets.QTreeWidgetItem(self.treeWidget.invisibleRootItem().child(i))
- treeItem.setText(1,delimiter)
+ treeItem = QtWidgets.QTreeWidgetItem(
+ self.treeWidget.invisibleRootItem().child(i)
+ )
+ treeItem.setText(1, delimiter)
treeItem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
- treeItem.setCheckState(1,Qt.Checked)
+ treeItem.setCheckState(1, Qt.Checked)
self.treeWidget.invisibleRootItem().child(i).setExpanded(True)
def getEarthCoverageDictFromTree(self):
@@ -191,17 +227,19 @@ def getEarthCoverageDictFromTree(self):
earthCoverageDict[childClass.text(0)] = []
for j in range(childClass.childCount()):
if childClass.child(j).checkState(1) == Qt.Checked:
- earthCoverageDict[childClass.text(0)].append(childClass.child(j).text(1))
+ earthCoverageDict[childClass.text(0)].append(
+ childClass.child(j).text(1)
+ )
return earthCoverageDict
-
+
def buildDict(self):
- '''
+ """
Gets earth coverage dict from interface
- '''
- self.configDict['edgvVersion'] = self.edgvVersion
- self.configDict['configName'] = self.nameLineEdit.text()
- self.configDict['frameLayer'] = self.listWidget.currentItem().text()
- self.configDict['earthCoverageDict'] = self.getEarthCoverageDictFromTree()
+ """
+ self.configDict["edgvVersion"] = self.edgvVersion
+ self.configDict["configName"] = self.nameLineEdit.text()
+ self.configDict["frameLayer"] = self.listWidget.currentItem().text()
+ self.configDict["earthCoverageDict"] = self.getEarthCoverageDictFromTree()
def buildTree(self):
"""
@@ -210,9 +248,11 @@ def buildTree(self):
self.populateClasses()
self.populateDelimiters()
self.treeWidget.expandAll()
- self.treeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
+ self.treeWidget.header().setSectionResizeMode(
+ QtWidgets.QHeaderView.ResizeToContents
+ )
self.treeWidget.header().setStretchLastSection(False)
-
+
def on_filterLineEdit_textChanged(self, text):
"""
Filters the items to make it easier to spot and select them
@@ -221,7 +261,7 @@ def on_filterLineEdit_textChanged(self, text):
self.listWidget.clear()
self.listWidget.addItems(classes)
self.listWidget.sortItems()
-
+
def validateEarthCoverageTreeWidget(self):
rootNode = self.treeWidget.invisibleRootItem()
childCount = rootNode.childCount()
@@ -240,38 +280,42 @@ def validateEarthCoverageTreeWidget(self):
def validateCurrentPage(self):
if self.currentId() == 0:
- errorMsg = ''
+ errorMsg = ""
isValidated = True
- if self.nameLineEdit.text() == '':
- errorMsg += self.tr('An Earth Coverage name must be set.\n')
+ if self.nameLineEdit.text() == "":
+ errorMsg += self.tr("An Earth Coverage name must be set.\n")
isValidated = False
if self.nameLineEdit.text() in self.propertyList:
- errorMsg += self.tr('An Earth Coverage with this name already exists.\n')
+ errorMsg += self.tr(
+ "An Earth Coverage with this name already exists.\n"
+ )
isValidated = False
if self.listWidget.currentRow() == -1:
- errorMsg += self.tr('A frame layer must be chosen.\n')
+ errorMsg += self.tr("A frame layer must be chosen.\n")
isValidated = False
if not isValidated:
- QMessageBox.warning(self, self.tr('Error!'), errorMsg)
+ QMessageBox.warning(self, self.tr("Error!"), errorMsg)
return isValidated
elif self.currentId() == 1:
if self.areasCustomSelector.toLs == []:
- errorMsg = self.tr('Areas must be chosen for Earth Coverage.\n')
- QMessageBox.warning(self, self.tr('Error!'), errorMsg)
+ errorMsg = self.tr("Areas must be chosen for Earth Coverage.\n")
+ QMessageBox.warning(self, self.tr("Error!"), errorMsg)
return False
return True
elif self.currentId() == 2:
if self.linesCustomSelector.toLs == []:
- errorMsg = self.tr('Lines must be chosen for Earth Coverage.\n')
- QMessageBox.warning(self, self.tr('Error!'), errorMsg)
+ errorMsg = self.tr("Lines must be chosen for Earth Coverage.\n")
+ QMessageBox.warning(self, self.tr("Error!"), errorMsg)
return False
return True
elif self.currentId() == 3:
- #at least one line selected for each area
+ # at least one line selected for each area
if not self.validateEarthCoverageTreeWidget():
- errorMsg = self.tr('At least one line must be chosen for each Earth Coverage area.\n')
- QMessageBox.warning(self, self.tr('Error!'), errorMsg)
+ errorMsg = self.tr(
+ "At least one line must be chosen for each Earth Coverage area.\n"
+ )
+ QMessageBox.warning(self, self.tr("Error!"), errorMsg)
return False
return True
else:
- return True
\ No newline at end of file
+ return True
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui
index b0d50ff32..ad2e60c3d 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/setupEarthCoverage.ui
@@ -91,7 +91,7 @@
- 4- Choose the line classes that, along with the frame, build the areas of earth coverage
+ 4- Choose the line classes that, along with the frame, build the areas of earth coverage
(only parent classes are listed here).
@@ -106,7 +106,7 @@
- 5- For each area class of earth coverage, define which lines are used to build it
+ 5- For each area class of earth coverage, define which lines are used to build it
(note that frame is always used to close areas)
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py
index 6c7b23a72..9eb76b26b 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/BasicPropertyWidgets/styleManagerWidget.py
@@ -28,24 +28,29 @@
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
+# DsgTools imports
from DsgTools.core.ServerManagementTools.styleManager import StyleManager
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import GenericManagerWidget
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import (
+ GenericParameterSetter,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericManagerWidget import (
+ GenericManagerWidget,
+)
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
from qgis.core import QgsMessageLog
import json
+
class StyleManagerWidget(GenericManagerWidget):
- def __init__(self, manager = None, parent = None):
+ def __init__(self, manager=None, parent=None):
"""
Constructor
"""
- super(self.__class__, self).__init__(genericDbManager = manager, parent = parent)
+ super(self.__class__, self).__init__(genericDbManager=manager, parent=parent)
- def setParameters(self, serverAbstractDb, edgvVersion, dbsDict = {}):
+ def setParameters(self, serverAbstractDb, edgvVersion, dbsDict={}):
if serverAbstractDb:
self.setComponentsEnabled(True)
self.serverAbstractDb = serverAbstractDb
@@ -59,37 +64,37 @@ def on_createPushButton_clicked(self):
"""
Slot that opens the create profile dialog
"""
- #TODO
- pass
-
- def populateConfigInterface(self, templateDb, jsonDict = None):
- '''
+ # TODO
+ pass
+
+ def populateConfigInterface(self, templateDb, jsonDict=None):
+ """
Must be reimplemented in each child
- '''
- #TODO
+ """
+ # TODO
pass
-
+
def getUpdateSelectedSettingHeader(self):
- header = self.tr('Update Style configuration complete. \n')
- operation = self.tr('style configuration')
+ header = self.tr("Update Style configuration complete. \n")
+ operation = self.tr("style configuration")
return header, operation
def getUninstallSelectedSettingHeader(self):
- header = self.tr('Uninstall Style configuration complete. \n')
- operation = self.tr('style configuration')
+ header = self.tr("Uninstall Style configuration complete. \n")
+ operation = self.tr("style configuration")
return header, operation
def getApplyHeader(self):
- header = self.tr('Install Style configuration complete. \n')
- operation = self.tr('style configurations')
+ header = self.tr("Install Style configuration complete. \n")
+ operation = self.tr("style configurations")
return header, operation
-
+
def getDeleteHeader(self):
- header = self.tr('Delete Style configuration complete. \n')
- operation = self.tr('style configurations')
+ header = self.tr("Delete Style configuration complete. \n")
+ operation = self.tr("style configurations")
return header, operation
-
+
def getUninstallFromSelected(self):
- header = self.tr('Uninstall Style configuration complete. \n')
- operation = self.tr('style configurations')
- return header, operation
\ No newline at end of file
+ header = self.tr("Uninstall Style configuration complete. \n")
+ operation = self.tr("style configurations")
+ return header, operation
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py
index 2160156ef..689fff02d 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/attributeRulesCompactPropertyManagerWidget.py
@@ -28,32 +28,39 @@
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
-from DsgTools.core.ServerManagementTools.attributeRulesManager import AttributeRulesManager
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import GenericCompactPropertyManagerWidget
-from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.attributeRulesEditor import AttributeRulesEditor
+# DsgTools imports
+from DsgTools.core.ServerManagementTools.attributeRulesManager import (
+ AttributeRulesManager,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import (
+ GenericCompactPropertyManagerWidget,
+)
+from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.attributeRulesEditor import (
+ AttributeRulesEditor,
+)
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
from qgis.core import QgsMessageLog
import json
+
class AttributeRulesCompactPropertyManagerWidget(GenericCompactPropertyManagerWidget):
- def __init__(self, manager = None, parent = None):
+ def __init__(self, manager=None, parent=None):
"""
Constructor
"""
- super(AttributeRulesCompactPropertyManagerWidget, self).__init__(parent = parent)
-
- def populateConfigInterface(self, templateDb, jsonDict = None):
- '''
+ super(AttributeRulesCompactPropertyManagerWidget, self).__init__(parent=parent)
+
+ def populateConfigInterface(self, templateDb, jsonDict=None):
+ """
Must be reimplemented in each child
- '''
- dlg = AttributeRulesEditor(templateDb, parameterDict = jsonDict)
+ """
+ dlg = AttributeRulesEditor(templateDb, parameterDict=jsonDict)
if dlg.exec_():
return dlg.getParameterDict()
else:
return None
-
+
def instantiateManagerObject(self, abstractDb, dbDict, edgvVersion):
- return AttributeRulesManager(abstractDb, dbDict, edgvVersion)
\ No newline at end of file
+ return AttributeRulesManager(abstractDb, dbDict, edgvVersion)
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py
index 69703f385..efdd58637 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/genericCompactPropertyManagerWidget.py
@@ -27,39 +27,52 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic, QtCore
from qgis.PyQt.QtCore import pyqtSlot, Qt, pyqtSignal
-from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog, QMenu, QHeaderView
+from qgis.PyQt.QtWidgets import (
+ QMessageBox,
+ QApplication,
+ QFileDialog,
+ QMenu,
+ QHeaderView,
+)
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
+# DsgTools imports
from DsgTools.gui.CustomWidgets.SelectionWidgets.listSelector import ListSelector
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import (
+ GenericParameterSetter,
+)
from qgis.core import QgsMessageLog
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'genericCompactPropertyManagerWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "genericCompactPropertyManagerWidget.ui")
+)
+
class GenericCompactPropertyManagerWidget(QtWidgets.QWidget, FORM_CLASS):
Add, Remove, Import, Export, Update = list(range(5))
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""
Constructor
"""
super(GenericCompactPropertyManagerWidget, self).__init__(parent)
self.setupUi(self)
self.genericDbManager = None
- self.textDict = {'EarthCoverage':self.tr('Earth Coverage'),
- 'Customization':self.tr('Customization'),
- 'Style':self.tr('Style'),
- 'ValidationConfig':self.tr('Validation'),
- 'Permission':self.tr('Permissions'),
- 'AttributeRules':self.tr('Attribute Rules Configuration'),
- 'SpatialRules':self.tr('Spatial Rules Configuration'),
- 'Generic':self.tr('Generic Property'),
- 'ValidationWorkflow':self.tr('Validation Workflow')}
+ self.textDict = {
+ "EarthCoverage": self.tr("Earth Coverage"),
+ "Customization": self.tr("Customization"),
+ "Style": self.tr("Style"),
+ "ValidationConfig": self.tr("Validation"),
+ "Permission": self.tr("Permissions"),
+ "AttributeRules": self.tr("Attribute Rules Configuration"),
+ "SpatialRules": self.tr("Spatial Rules Configuration"),
+ "Generic": self.tr("Generic Property"),
+ "ValidationWorkflow": self.tr("Validation Workflow"),
+ }
self.widgetName = self.textDict[self.getWhoAmI()]
self.changeTooltips(self.widgetName)
self.parent = parent
@@ -70,38 +83,61 @@ def refresh(self):
"""
self.propertyComboBox.clear()
if self.genericDbManager:
- propertyList = list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys())
+ propertyList = list(
+ self.genericDbManager.getPropertyPerspectiveDict(
+ viewType=DsgEnums.Property
+ ).keys()
+ )
propertyList.sort()
self.propertyComboBox.addItems(propertyList)
-
+
def getWhoAmI(self):
- return str(self.__class__).split('.')[-1].replace('\'>', '').replace('CompactPropertyManagerWidget','')
-
+ return (
+ str(self.__class__)
+ .split(".")[-1]
+ .replace("'>", "")
+ .replace("CompactPropertyManagerWidget", "")
+ )
+
def instantiateManagerObject(self, abstractDb, dbDict, edgvVersion):
"""
Reimplemented in each child.
"""
pass
-
+
def setParameters(self, abstractDb):
"""
1. Get abstract db
2. Instantiate manager object
"""
self.abstractDb = abstractDb
- self.genericDbManager = self.instantiateManagerObject(abstractDb, {self.abstractDb.db.databaseName():self.abstractDb}, self.abstractDb.getDatabaseVersion())
+ self.genericDbManager = self.instantiateManagerObject(
+ abstractDb,
+ {self.abstractDb.db.databaseName(): self.abstractDb},
+ self.abstractDb.getDatabaseVersion(),
+ )
self.refresh()
def changeTooltips(self, propertyName):
"""
Changes all buttons' tooltips according to propertyName
"""
- self.createPropertyPushButton.setToolTip(self.tr('Add {0}').format(propertyName))
- self.removePropertyPushButton.setToolTip(self.tr('Remove {0}').format(propertyName))
- self.importPropertyPushButton.setToolTip(self.tr('Import {0}').format(propertyName))
- self.exportPropertyPushButton.setToolTip(self.tr('Export {0}').format(propertyName))
- self.updatePropertyPushButton.setToolTip(self.tr('Update {0}').format(propertyName))
-
+ self.createPropertyPushButton.setToolTip(
+ self.tr("Add {0}").format(propertyName)
+ )
+ self.removePropertyPushButton.setToolTip(
+ self.tr("Remove {0}").format(propertyName)
+ )
+ self.importPropertyPushButton.setToolTip(
+ self.tr("Import {0}").format(propertyName)
+ )
+ self.exportPropertyPushButton.setToolTip(
+ self.tr("Export {0}").format(propertyName)
+ )
+ self.updatePropertyPushButton.setToolTip(
+ self.tr("Update {0}").format(propertyName)
+ )
+
def enableButtons(self, enabled):
"""
Enables or disables all buttons according to boolean enabled
@@ -113,55 +149,85 @@ def enableButtons(self, enabled):
self.updatePropertyPushButton.setEnabled(enabled)
def getWhoAmI(self):
- return str(self.__class__).split('.')[-1].replace('\'>', '').replace('CompactPropertyManagerWidget','')
+ return (
+ str(self.__class__)
+ .split(".")[-1]
+ .replace("'>", "")
+ .replace("CompactPropertyManagerWidget", "")
+ )
def getParameterDict(self):
"""
This is used to get ui state
Returns a dict in the format:
{
- 'selectedConfig':--name of the selected config--,
+ 'selectedConfig':--name of the selected config--,
}
"""
parameterDict = dict()
- parameterDict['selectedConfig'] = self.propertyComboBox.currentText()
+ parameterDict["selectedConfig"] = self.propertyComboBox.currentText()
return parameterDict
-
+
def setInterface(self, parameterDict):
"""
Uses parameterDict to populate interface
Sets the interface with a dict in the format:
{
- 'selectedConfig':--name of the selected config--,
+ 'selectedConfig':--name of the selected config--,
}
"""
- if 'selectedConfig' in parameterDict:
- idx = self.propertyComboBox.findText(parameterDict['selectedConfig'], flags = Qt.MatchFlags)
+ if "selectedConfig" in parameterDict:
+ idx = self.propertyComboBox.findText(
+ parameterDict["selectedConfig"], flags=Qt.MatchFlags
+ )
if idx != -1:
self.propertyComboBox.setCurrentIndex(idx)
-
+
@pyqtSlot(bool)
def on_createPropertyPushButton_clicked(self):
"""
1. Open custom manager according to property type;
2. Use manager to apply to database
"""
- dlg = GenericParameterSetter(hideDbUi = True)
+ dlg = GenericParameterSetter(hideDbUi=True)
if not dlg.exec_():
return
propertyName = dlg.getParameters()
- if propertyName == '':
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Enter a {0} name!').format(self.widgetName))
+ if propertyName == "":
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Enter a {0} name!").format(self.widgetName),
+ )
return
- if propertyName in list(self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property).keys()):
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! {0} name already exists!').format(self.widgetName))
+ if propertyName in list(
+ self.genericDbManager.getPropertyPerspectiveDict(
+ viewType=DsgEnums.Property
+ ).keys()
+ ):
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! {0} name already exists!").format(self.widgetName),
+ )
return
setupDict = self.populateConfigInterface(self.abstractDb)
if setupDict:
- self.genericDbManager.createAndInstall(propertyName, setupDict, self.genericDbManager.edgvVersion, dbList = [self.abstractDb.db.databaseName()])
+ self.genericDbManager.createAndInstall(
+ propertyName,
+ setupDict,
+ self.genericDbManager.edgvVersion,
+ dbList=[self.abstractDb.db.databaseName()],
+ )
self.refresh()
- QMessageBox.information(self, self.tr('Success!'), self.tr('{0} configuration {1} created successfuly!').format(self.widgetName, propertyName))
-
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.tr("{0} configuration {1} created successfuly!").format(
+ self.widgetName, propertyName
+ ),
+ )
+
@pyqtSlot(bool)
def on_removePropertyPushButton_clicked(self):
"""
@@ -176,22 +242,40 @@ def on_importPropertyPushButton_clicked(self):
"""
fd = QFileDialog()
widgetType = self.getWhoAmI()
- filename = fd.getOpenFileName(caption=self.captionDict[widgetType],filter=self.filterDict[widgetType])
- if filename == '':
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a file to import!'))
+ filename = fd.getOpenFileName(
+ caption=self.captionDict[widgetType], filter=self.filterDict[widgetType]
+ )
+ if filename == "":
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Warning! Select a file to import!")
+ )
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.genericDbManager.importSetting(filename)
- settingName = os.path.basename(fullFilePath).split('.')[0]
- self.genericDbManager.installSetting(settingName, dbList = [self.abstractDb.db.databaseName()])
+ settingName = os.path.basename(fullFilePath).split(".")[0]
+ self.genericDbManager.installSetting(
+ settingName, dbList=[self.abstractDb.db.databaseName()]
+ )
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Sucess!'), self.tr('Success! {0} successfully imported and installed in {1}.').format(widgetType, settingName))
+ QMessageBox.information(
+ self,
+ self.tr("Sucess!"),
+ self.tr(
+ "Success! {0} successfully imported and installed in {1}."
+ ).format(widgetType, settingName),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem importing {0}: {1}').format(widgetType, ':'.join(e.args)) )
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem importing {0}: {1}").format(
+ widgetType, ":".join(e.args)
+ ),
+ )
self.refresh()
-
+
@pyqtSlot(bool)
def on_exportPropertyPushButton_clicked(self):
"""
@@ -199,12 +283,16 @@ def on_exportPropertyPushButton_clicked(self):
"""
exportPropertyList = [self.propertyComboBox.currentText()]
if exportPropertyList == []:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a profile to export!'))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Warning! Select a profile to export!"),
+ )
return
fd = QFileDialog()
- folder = fd.getExistingDirectory(caption = self.tr('Select a folder to output'))
+ folder = fd.getExistingDirectory(caption=self.tr("Select a folder to output"))
folder = folder[0] if isinstance(folder, tuple) else folder
- if folder == '':
+ if folder == "":
# QMessageBox.warning(self, self.tr('Warning!'), self.tr('Warning! Select a output!'))
return
edgvVersion = self.genericDbManager.edgvVersion
@@ -213,10 +301,20 @@ def on_exportPropertyPushButton_clicked(self):
for exportProperty in exportPropertyList:
self.genericDbManager.exportSetting(exportProperty, edgvVersion, folder)
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Success!'), self.tr('Success! {0} successfully exported.').format(self.widgetName))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.tr("Success! {0} successfully exported.").format(self.widgetName),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem exporting {0}: {1}').format(self.widgetName, ':'.join(e.args)) )
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem exporting {0}: {1}").format(
+ self.widgetName, ":".join(e.args)
+ ),
+ )
@pyqtSlot(bool)
def on_updatePropertyPushButton_clicked(self):
@@ -228,21 +326,43 @@ def on_updatePropertyPushButton_clicked(self):
4. Update property
"""
propertyName = self.propertyComboBox.currentText()
- propertyDict = self.genericDbManager.getPropertyPerspectiveDict(viewType = DsgEnums.Property)
+ propertyDict = self.genericDbManager.getPropertyPerspectiveDict(
+ viewType=DsgEnums.Property
+ )
if propertyName not in list(propertyDict.keys()):
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem getting {0}: Invalid property {1}').format(self.widgetName, propertyName) )
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem getting {0}: Invalid property {1}").format(
+ self.widgetName, propertyName
+ ),
+ )
return
- parameterDict = self.genericDbManager.getSetting(propertyName, self.genericDbManager.edgvVersion)
- setupDict = self.populateConfigInterface(self.abstractDb, jsonDict = parameterDict)
+ parameterDict = self.genericDbManager.getSetting(
+ propertyName, self.genericDbManager.edgvVersion
+ )
+ setupDict = self.populateConfigInterface(
+ self.abstractDb, jsonDict=parameterDict
+ )
if setupDict:
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.genericDbManager.updateSetting(propertyName, setupDict)
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Success!'), self.tr('Success! Property {0} successfully updated.').format(propertyName))
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.tr("Success! Property {0} successfully updated.").format(
+ propertyName
+ ),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Error!'), self.tr('Error! Problem updating {0}').format(propertyName) )
-
- def populateConfigInterface(self, abstractDb, jsonDict = None):
- return None
\ No newline at end of file
+ QMessageBox.critical(
+ self,
+ self.tr("Error!"),
+ self.tr("Error! Problem updating {0}").format(propertyName),
+ )
+
+ def populateConfigInterface(self, abstractDb, jsonDict=None):
+ return None
diff --git a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py
index 8a6e45409..2f67e0781 100644
--- a/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/DatabasePropertiesWidgets/CompactPropertyWidgets/validationWorkflowCompactPropertyManagerWidget.py
@@ -28,36 +28,47 @@
from qgis.PyQt.QtWidgets import QMessageBox, QApplication, QFileDialog
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import GenericCompactPropertyManagerWidget
-from DsgTools.core.ServerManagementTools.validationWorkflowManager import ValidationWorkflowManager
-from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.validationWorkflowCreator import ValidationWorkflowCreator
+# DsgTools imports
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.CompactPropertyWidgets.genericCompactPropertyManagerWidget import (
+ GenericCompactPropertyManagerWidget,
+)
+from DsgTools.core.ServerManagementTools.validationWorkflowManager import (
+ ValidationWorkflowManager,
+)
+from DsgTools.gui.ProductionTools.Toolboxes.ValidationToolbox.validationWorkflowCreator import (
+ ValidationWorkflowCreator,
+)
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.dsgEnums import DsgEnums
from qgis.core import QgsMessageLog
import json
-class ValidationWorkflowCompactPropertyManagerWidget(GenericCompactPropertyManagerWidget):
- def __init__(self, manager = None, parent = None):
+
+class ValidationWorkflowCompactPropertyManagerWidget(
+ GenericCompactPropertyManagerWidget
+):
+ def __init__(self, manager=None, parent=None):
"""
Constructor
"""
- super(ValidationWorkflowCompactPropertyManagerWidget, self).__init__(parent = parent)
-
- def populateConfigInterface(self, validationManager, jsonDict = None):
- '''
+ super(ValidationWorkflowCompactPropertyManagerWidget, self).__init__(
+ parent=parent
+ )
+
+ def populateConfigInterface(self, validationManager, jsonDict=None):
+ """
Must be reimplemented in each child
- '''
- dlg = ValidationWorkflowCreator(validationManager, parameterDict = jsonDict)
+ """
+ dlg = ValidationWorkflowCreator(validationManager, parameterDict=jsonDict)
if dlg.exec_():
return dlg.getParameterDict()
else:
return None
-
+
def instantiateManagerObject(self, abstractDb, dbDict, edgvVersion):
return ValidationWorkflowManager(abstractDb, dbDict, edgvVersion)
-
+
@pyqtSlot(bool)
def on_createPropertyPushButton_clicked(self):
"""
@@ -66,7 +77,17 @@ def on_createPropertyPushButton_clicked(self):
"""
setupDict = self.populateConfigInterface(self.parent.validationManager)
if setupDict:
- self.genericDbManager.createAndInstall(propertyName, setupDict, self.genericDbManager.edgvVersion, dbList = [self.abstractDb.db.databaseName()])
+ self.genericDbManager.createAndInstall(
+ propertyName,
+ setupDict,
+ self.genericDbManager.edgvVersion,
+ dbList=[self.abstractDb.db.databaseName()],
+ )
self.refresh()
- QMessageBox.information(self, self.tr('Success!'), self.tr('{0} configuration {1} created successfuly!').format(self.widgetName, propertyName))
-
\ No newline at end of file
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.tr("{0} configuration {1} created successfuly!").format(
+ self.widgetName, propertyName
+ ),
+ )
diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py
index 91e57bf1a..14ee99b3d 100644
--- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py
+++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRuleTypesWidget.py
@@ -22,26 +22,29 @@
"""
import os
from collections import OrderedDict
+
# Qt imports
from qgis.PyQt import QtGui, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QTableWidgetItem
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget
-from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleTypeWidget import AttributeRuleTypeWidget
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import (
+ OrderedStructureWidget,
+)
+from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleTypeWidget import (
+ AttributeRuleTypeWidget,
+)
-class OrderedAttributeRuleTypesWidget(OrderedStructureWidget):
+class OrderedAttributeRuleTypesWidget(OrderedStructureWidget):
def __init__(self, parent=None):
"""
Initializates OrderedAttributeRulesWidget
"""
super(OrderedAttributeRuleTypesWidget, self).__init__(parent)
self.args = None
- self.tableWidget.setHorizontalHeaderLabels([self.tr('Attribute Rule Types')])
- self.widgetKey = 'attributeRuleTypeWidgetList'
-
+ self.tableWidget.setHorizontalHeaderLabels([self.tr("Attribute Rule Types")])
+ self.widgetKey = "attributeRuleTypeWidgetList"
+
def instantiateWidgetItem(self):
return AttributeRuleTypeWidget()
-
-
diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py
index 9223bd45f..ae230eb6f 100644
--- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py
+++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedAttributeRulesWidget.py
@@ -22,26 +22,29 @@
"""
import os
from collections import OrderedDict
+
# Qt imports
from qgis.PyQt import QtGui, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QTableWidgetItem
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget
-from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleWidget import AttributeRuleWidget
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import (
+ OrderedStructureWidget,
+)
+from DsgTools.gui.CustomWidgets.AttributeValidityWidgets.attributeRuleWidget import (
+ AttributeRuleWidget,
+)
-class OrderedAttributeRulesWidget(OrderedStructureWidget):
+class OrderedAttributeRulesWidget(OrderedStructureWidget):
def __init__(self, parent=None):
"""
Initializates OrderedAttributeRulesWidget
"""
super(OrderedAttributeRulesWidget, self).__init__(parent)
self.args = None
- self.tableWidget.setHorizontalHeaderLabels([self.tr('Attribute Rules')])
- self.widgetKey = 'attributeRuleWidgetList'
-
+ self.tableWidget.setHorizontalHeaderLabels([self.tr("Attribute Rules")])
+ self.widgetKey = "attributeRuleWidgetList"
+
def instantiateWidgetItem(self):
return AttributeRuleWidget(*self.args)
-
-
diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py
index 7c0fd8fc4..6ab083b30 100644
--- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py
+++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedRecursiveSnapWidget.py
@@ -23,55 +23,64 @@
from builtins import range
import os
from collections import OrderedDict
+
# Qt imports
from qgis.PyQt import QtGui, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QTableWidgetItem
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.snapChooserWidget import SnapChooserWidget
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import (
+ OrderedStructureWidget,
+)
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.snapChooserWidget import (
+ SnapChooserWidget,
+)
-class OrderedRecursiveSnapWidget(OrderedStructureWidget):
+class OrderedRecursiveSnapWidget(OrderedStructureWidget):
def __init__(self, parent=None):
"""
Initializates OrderedRecursiveSnapWidget
"""
super(OrderedRecursiveSnapWidget, self).__init__(parent)
self.args = None
- self.tableWidget.setHorizontalHeaderLabels([self.tr('Snap Order')])
- self.widgetKey = 'snapChooserWidgetList'
-
+ self.tableWidget.setHorizontalHeaderLabels([self.tr("Snap Order")])
+ self.widgetKey = "snapChooserWidgetList"
+
def instantiateWidgetItem(self):
return SnapChooserWidget(*self.args)
-
+
def setInitialState(self, layerList):
self.args = layerList
-
+
def getHierarchicalSnapDict(self):
snapList = self.getParameterDict()[self.widgetKey]
snapDictList = []
- for i in range(len(snapList)-1):
+ for i in range(len(snapList) - 1):
snapItemDict = dict()
- snapItemDict['referenceLayer'] = snapList[i]['layerName']
- snapItemDict['snap'] = snapList[i]['snap']
- snapItemDict['snapLayerList'] = [i['layerName'] for i in snapList[(i+1)::]]
+ snapItemDict["referenceLayer"] = snapList[i]["layerName"]
+ snapItemDict["snap"] = snapList[i]["snap"]
+ snapItemDict["snapLayerList"] = [
+ i["layerName"] for i in snapList[(i + 1) : :]
+ ]
snapDictList.append(snapItemDict)
return snapDictList
-
- @pyqtSlot(bool, name = 'on_addRulePushButton_clicked')
- def addItem(self, parameterDict = None):
+
+ @pyqtSlot(bool, name="on_addRulePushButton_clicked")
+ def addItem(self, parameterDict=None):
"""
1. Use super to instantiate parent's add item
2. Connect new item's layerComboBox.currentIndexChanged signal to self.componentsRefresher
"""
- super(OrderedRecursiveSnapWidget, self).addItem(parameterDict = parameterDict)
+ super(OrderedRecursiveSnapWidget, self).addItem(parameterDict=parameterDict)
row = self.tableWidget.rowCount() - 1
- newItemWidget = self.tableWidget.cellWidget(row,0)
- newItemWidget.layerComboBox.currentIndexChanged.connect(self.componentsRefresher)
+ newItemWidget = self.tableWidget.cellWidget(row, 0)
+ newItemWidget.layerComboBox.currentIndexChanged.connect(
+ self.componentsRefresher
+ )
newItemWidget.layerComboBox.currentIndexChanged.emit(-1)
-
- @pyqtSlot(bool, name = 'on_removeRulePushButton_clicked')
+
+ @pyqtSlot(bool, name="on_removeRulePushButton_clicked")
def removeItem(self):
"""
1. Get selected row
@@ -79,9 +88,9 @@ def removeItem(self):
3. Update control list
"""
super(OrderedRecursiveSnapWidget, self).removeItem()
- self.componentsRefresher(onDelete = True)
-
- def componentsRefresher(self, onDelete = False):
+ self.componentsRefresher(onDelete=True)
+
+ def componentsRefresher(self, onDelete=False):
"""
1. Get all widgets
2. Iterate over widgets and build black list from selected texts
@@ -89,23 +98,31 @@ def componentsRefresher(self, onDelete = False):
4. Refresh all combos with remaining values plus selected one
5. Reconnect signals
"""
- #1. get widgetList and blackList:
- widgetList = [self.tableWidget.cellWidget(i,0) for i in range(self.tableWidget.rowCount())]
- blackList = [i.layerComboBox.currentText() for i in widgetList if i.layerComboBox.currentIndex() > 0]
+ # 1. get widgetList and blackList:
+ widgetList = [
+ self.tableWidget.cellWidget(i, 0)
+ for i in range(self.tableWidget.rowCount())
+ ]
+ blackList = [
+ i.layerComboBox.currentText()
+ for i in widgetList
+ if i.layerComboBox.currentIndex() > 0
+ ]
if not onDelete:
currentText = self.sender().currentText()
if currentText not in blackList:
blackList.append(currentText)
- #3. disconect signals
+ # 3. disconect signals
for widget in widgetList:
try:
- widget.layerComboBox.currentIndexChanged.disconnect(self.componentsRefresher)
+ widget.layerComboBox.currentIndexChanged.disconnect(
+ self.componentsRefresher
+ )
except:
pass
- #4. refresh combos
+ # 4. refresh combos
for widget in widgetList:
widget.refresh(blackList)
- #5. reconnect signals
+ # 5. reconnect signals
for widget in widgetList:
widget.layerComboBox.currentIndexChanged.connect(self.componentsRefresher)
-
diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py
index 2f83eabfb..dd6e69f64 100644
--- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py
+++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedStructureWidget.py
@@ -23,16 +23,18 @@
from builtins import range
import os, importlib
from collections import OrderedDict
+
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QTableWidgetItem, QTableWidgetSelectionRange
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'orderedStructureWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "orderedStructureWidget.ui")
+)
-class OrderedStructureWidget(QtWidgets.QWidget, FORM_CLASS):
+class OrderedStructureWidget(QtWidgets.QWidget, FORM_CLASS):
def __init__(self, parent=None):
"""
Initializates OrderedStructureWidget
@@ -40,7 +42,7 @@ def __init__(self, parent=None):
super(OrderedStructureWidget, self).__init__(parent)
self.setupUi(self)
self.args = None
-
+
def setArgs(self, args):
self.args = args
@@ -49,9 +51,9 @@ def instantiateWidgetItem(self):
Must be reimplemented in each child.
"""
pass
-
- @pyqtSlot(bool, name = 'on_addRulePushButton_clicked')
- def addItem(self, parameterDict = None):
+
+ @pyqtSlot(bool, name="on_addRulePushButton_clicked")
+ def addItem(self, parameterDict=None):
"""
1. Instantiate new line
2. Add new line in the end
@@ -63,8 +65,8 @@ def addItem(self, parameterDict = None):
widget.populateInterface(parameterDict)
self.tableWidget.setCellWidget(rowCount, 0, widget)
self.tableWidget.resizeRowToContents(rowCount)
-
- @pyqtSlot(bool, name = 'on_removeRulePushButton_clicked')
+
+ @pyqtSlot(bool, name="on_removeRulePushButton_clicked")
def removeItem(self):
"""
1. Get selected row
@@ -87,63 +89,76 @@ def on_moveRuleUpPushButton_clicked(self):
if selected == []:
return
firstItemIdx = selected[0].row() - 1
- if firstItemIdx < 0: #first item in selection, do nothing
+ if firstItemIdx < 0: # first item in selection, do nothing
return
for idx in selected:
self.moveUp(self.tableWidget, idx.row(), 0)
- self.tableWidget.setRangeSelected(QTableWidgetSelectionRange(firstItemIdx, 0, selected[-1].row()-1, 0), True)
+ self.tableWidget.setRangeSelected(
+ QTableWidgetSelectionRange(firstItemIdx, 0, selected[-1].row() - 1, 0), True
+ )
-
@pyqtSlot(bool)
def on_moveRuleDownPushButton_clicked(self):
selected = self.tableWidget.selectedIndexes()
if selected == []:
return
firstItemIdx = selected[-1].row() + 1
- if firstItemIdx > self.tableWidget.rowCount(): #last item in selection, do nothing
+ if (
+ firstItemIdx > self.tableWidget.rowCount()
+ ): # last item in selection, do nothing
return
for idx in selected[::-1]:
self.moveDown(self.tableWidget, idx.row(), 0)
- self.tableWidget.setRangeSelected(QTableWidgetSelectionRange(firstItemIdx-1, 0, selected[-1].row()+1, 0), True)
-
+ self.tableWidget.setRangeSelected(
+ QTableWidgetSelectionRange(firstItemIdx - 1, 0, selected[-1].row() + 1, 0),
+ True,
+ )
+
def moveDown(self, tableWidget, rowIdx, columnIdx):
"""
Moves item down
"""
- tableWidget.insertRow(rowIdx+2)
+ tableWidget.insertRow(rowIdx + 2)
tableWidget.takeItem(rowIdx, columnIdx)
- tableWidget.setCellWidget(rowIdx+2, columnIdx, tableWidget.cellWidget(rowIdx, columnIdx))
+ tableWidget.setCellWidget(
+ rowIdx + 2, columnIdx, tableWidget.cellWidget(rowIdx, columnIdx)
+ )
tableWidget.removeRow(rowIdx)
def moveUp(self, tableWidget, rowIdx, columnIdx):
"""
Moves item up
"""
- tableWidget.insertRow(rowIdx-1)
- tableWidget.takeItem(rowIdx+1, columnIdx)
- tableWidget.setCellWidget(rowIdx-1, columnIdx, tableWidget.cellWidget(rowIdx+1, columnIdx))
- tableWidget.removeRow(rowIdx+1)
+ tableWidget.insertRow(rowIdx - 1)
+ tableWidget.takeItem(rowIdx + 1, columnIdx)
+ tableWidget.setCellWidget(
+ rowIdx - 1, columnIdx, tableWidget.cellWidget(rowIdx + 1, columnIdx)
+ )
+ tableWidget.removeRow(rowIdx + 1)
def validate(self):
for i in range(self.tableWidget.rowCount()):
if not self.tableWidget.cellWidget(i, 0).validate():
return False
return True
-
+
def invalidatedReason(self):
- msg = ''
+ msg = ""
for i in range(self.tableWidget.rowCount()):
if not self.tableWidget.cellWidget(i, 0).validate():
- msg += self.tr('Error for rule #{0}:\n'.format(i+1))+self.tableWidget.cellWidget(i, 0).invalidatedReason()
+ msg += (
+ self.tr("Error for rule #{0}:\n".format(i + 1))
+ + self.tableWidget.cellWidget(i, 0).invalidatedReason()
+ )
return msg
-
+
def populateInterface(self, parameterDict):
"""
Populates interface with parameters from parameterDict.
"""
for ruleDict in parameterDict[self.widgetKey]:
- self.addItem(parameterDict = ruleDict)
-
+ self.addItem(parameterDict=ruleDict)
+
def getParameterDict(self):
"""
Returns an OrderedDict with the number of the rule and the rule json
@@ -151,7 +166,7 @@ def getParameterDict(self):
parameterList = []
for i in range(self.tableWidget.rowCount()):
parameterList.append(self.tableWidget.cellWidget(i, 0).getParameterDict())
- return {self.widgetKey:parameterList} #outputs list of widgets parameters
+ return {self.widgetKey: parameterList} # outputs list of widgets parameters
def validateJson(self, inputJson):
"""
@@ -165,6 +180,8 @@ def validateJson(self, inputJson):
if [self.widgetKey] != list(inputJson.keys()):
return False
for i in range(self.tableWidget.rowCount()):
- if not self.tableWidget.cellWidget(i, 0).validateJson(inputJson[self.widgetKey][i]):
+ if not self.tableWidget.cellWidget(i, 0).validateJson(
+ inputJson[self.widgetKey][i]
+ ):
return False
return True
diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py
index 92cee538b..c2af5cd98 100644
--- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py
+++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedTableWidget.py
@@ -27,18 +27,21 @@
from qgis.PyQt import uic
from qgis.utils import iface
from qgis.PyQt.QtCore import Qt, pyqtSlot, pyqtSignal
-from qgis.PyQt.QtWidgets import (QWidget,
- QFileDialog,
- QHeaderView,
- QMessageBox,
- QTableWidgetItem,
- QAbstractItemView,
- QDoubleSpinBox)
+from qgis.PyQt.QtWidgets import (
+ QWidget,
+ QFileDialog,
+ QHeaderView,
+ QMessageBox,
+ QTableWidgetItem,
+ QAbstractItemView,
+ QDoubleSpinBox,
+)
FORM_CLASS, _ = uic.loadUiType(
- os.path.join(os.path.dirname(__file__), 'orderedTableWidget.ui')
+ os.path.join(os.path.dirname(__file__), "orderedTableWidget.ui")
)
+
class OrderedTableWidget(QWidget, FORM_CLASS):
rowAdded = pyqtSignal(int)
rowRemoved = pyqtSignal(int)
@@ -48,15 +51,21 @@ class OrderedTableWidget(QWidget, FORM_CLASS):
ORDER_MODE_COUNT = 2
ASC_ORDER, DESC_ORDER = range(ORDER_MODE_COUNT)
- def __init__(self, parent=None, headerMap=None, showButtons=False,
- fileType=None, extension=None):
+ def __init__(
+ self,
+ parent=None,
+ headerMap=None,
+ showButtons=False,
+ fileType=None,
+ extension=None,
+ ):
"""
Class constructor.
:param headerMap: (dict) a map from each header to be shown and type of
cell content (e.g. widget or item).
:param parent: (QtWidgets.*) any widget parent to current instance.
:param showButtons: (bool) whether buttons are visible.
- :param fileType: (str) ex/import file type extension name (e.g. JSON
+ :param fileType: (str) ex/import file type extension name (e.g. JSON
file).
:param fileType: (str) ex/import file type extension (e.g. .json).
"""
@@ -99,13 +108,13 @@ def setHeaders(self, headerMap):
self.clear()
self.headers = headerMap
self.tableWidget.setColumnCount(len(self.headers))
- self.tableWidget.setHorizontalHeaderLabels([
- p["header"] for p in self.headers.values()
- ])
+ self.tableWidget.setHorizontalHeaderLabels(
+ [p["header"] for p in self.headers.values()]
+ )
def replicateColumnValue(self, col):
"""
- Replicates the value from the first cell of a colums based on column
+ Replicates the value from the first cell of a colums based on column
filled values.
:param col: (int) column to have its first value replicated to the
other rows.
@@ -131,14 +140,15 @@ def orderColumn(self, col):
self.currentRowOrder[col] = self.ASC_ORDER
else:
# get next mode
- self.currentRowOrder[col] = (self.currentRowOrder[col] + 1) % \
- self.ORDER_MODE_COUNT
+ self.currentRowOrder[col] = (
+ self.currentRowOrder[col] + 1
+ ) % self.ORDER_MODE_COUNT
contents = []
for row in range(self.rowCount()):
contents.append(self.row(row))
self.clear()
rev = self.currentRowOrder[col] == self.DESC_ORDER
- for content in sorted(contents, key = lambda i: i[col], reverse=rev):
+ for content in sorted(contents, key=lambda i: i[col], reverse=rev):
self.addRow(content)
def setHeaderDoubleClickBehaviour(self, mode=None, cols=None):
@@ -151,13 +161,11 @@ def setHeaderDoubleClickBehaviour(self, mode=None, cols=None):
"""
self.unsetHeaderDoubleClickBehaviour()
self.headerDoubleClicked = {
- "replicate" : self.replicateColumnValue,
- "order" : self.orderColumn,
- "none" : lambda col : None
+ "replicate": self.replicateColumnValue,
+ "order": self.orderColumn,
+ "none": lambda col: None,
}[mode or "none"]
- self.horizontalHeader().sectionDoubleClicked.connect(
- self.headerDoubleClicked
- )
+ self.horizontalHeader().sectionDoubleClicked.connect(self.headerDoubleClicked)
def unsetHeaderDoubleClickBehaviour(self):
"""
@@ -179,7 +187,7 @@ def clear(self):
for row in range(self.rowCount()):
self.tableWidget.removeRow(row)
self.tableWidget.setRowCount(0)
-
+
def getValue(self, row, column):
"""
Gets the value from a table cell. It uses column definitions from
@@ -211,14 +219,14 @@ def setValue(self, row, column, value):
writeable data (int, float, str, dict, etc). Depends on
input widget.
"""
- if self.headers[column]['type'] == 'item':
+ if self.headers[column]["type"] == "item":
self.tableWidget.item(row, column).setText(value)
else:
- setter = self.headers[column]['setter']
+ setter = self.headers[column]["setter"]
widget = self.tableWidget.cellWidget(row, column)
if not setter:
raise Exception(
- self.tr('Setter method must be defined for widget type.')
+ self.tr("Setter method must be defined for widget type.")
)
getattr(widget, setter)(value)
@@ -250,10 +258,10 @@ def setSectionResizeMode(self, col, mode):
:param mode: (str) resize policy identifier.
"""
policies = {
- "interactive" : QHeaderView.Interactive,
- "stretch" : QHeaderView.Stretch,
- "fixed" : QHeaderView.Fixed,
- "resizetocontents" : QHeaderView.ResizeToContents,
+ "interactive": QHeaderView.Interactive,
+ "stretch": QHeaderView.Stretch,
+ "fixed": QHeaderView.Fixed,
+ "resizetocontents": QHeaderView.ResizeToContents,
}
if col < 0 or col >= self.rowCount() or mode not in policies:
return
@@ -283,9 +291,15 @@ def addNewRow(self, row=None):
Adds a new row of items and fill it into table.
:param row: (int) position to add the new row.
"""
- row = self.rowCount() if row is None else \
- 0 if row < 0 else \
- row if row <= self.rowCount() else self.rowCount()
+ row = (
+ self.rowCount()
+ if row is None
+ else 0
+ if row < 0
+ else row
+ if row <= self.rowCount()
+ else self.rowCount()
+ )
# row = row if row is not None else self.rowCount()
self.tableWidget.insertRow(row)
for col, properties in self.headers.items():
@@ -296,9 +310,7 @@ def addNewRow(self, row=None):
item.setFlags(Qt.ItemIsEditable)
self.tableWidget.setItem(row, col, item)
else:
- self.tableWidget.setCellWidget(
- row, col, properties["widget"]()
- )
+ self.tableWidget.setCellWidget(row, col, properties["widget"]())
self.rowAdded.emit(row)
def addRow(self, contents, row=None):
@@ -307,9 +319,15 @@ def addRow(self, contents, row=None):
:param row: (int) position to add the new row.
:param contents: (dict) a map to items to be filled.
"""
- row = self.rowCount() if row is None else \
- 0 if row < 0 else \
- row if row <= self.rowCount() else self.rowCount()
+ row = (
+ self.rowCount()
+ if row is None
+ else 0
+ if row < 0
+ else row
+ if row <= self.rowCount()
+ else self.rowCount()
+ )
self.tableWidget.insertRow(row)
for col, properties in self.headers.items():
value = contents[col] if col in contents else None
@@ -359,8 +377,7 @@ def itemAt(self, row, col):
:param col: (int) item's column to be read.
:return: (QTableWIdgetItem/QWidget) cell contents.
"""
- if row >= self.rowCount() or col >= self.columnCount() \
- or row < 0 or col < 0:
+ if row >= self.rowCount() or col >= self.columnCount() or row < 0 or col < 0:
return None
if self.headers[col]["type"] == "item":
return self.tableWidget.item(row, col)
@@ -391,7 +408,7 @@ def selectedRows(self, reverseOrder=False):
"""
return sorted(
set(i.row() for i in self.tableWidget.selectionModel().selectedRows()),
- reverse=reverseOrder
+ reverse=reverseOrder,
)
def selectedColumns(self, reverseOrder=False):
@@ -401,8 +418,7 @@ def selectedColumns(self, reverseOrder=False):
:return: (list-of-int) ordered list of selected columns' indexes.
"""
return sorted(
- set(i.column() for i in self.selectedIndexes()),
- reverse=reverseOrder
+ set(i.column() for i in self.selectedIndexes()), reverse=reverseOrder
)
def selectRow(self, row):
@@ -564,7 +580,7 @@ def load(self, filepath):
QMessageBox.warning(
iface.mainWindow(),
self.tr("Unable to import {0}").format(filepath),
- "Check file {0}:\n{1}".format(filepath, "\n".join(e.args))
+ "Check file {0}:\n{1}".format(filepath, "\n".join(e.args)),
)
self.setHeaders(self.headers)
@@ -581,7 +597,7 @@ def save(self, filepath):
QMessageBox.warning(
iface.mainWindow(),
self.tr("Unable to export {0}").format(filepath),
- "Check file {0}:\n{1}".format(filepath, "\n".join(e.args))
+ "Check file {0}:\n{1}".format(filepath, "\n".join(e.args)),
)
@pyqtSlot()
@@ -592,10 +608,8 @@ def on_loadPushButton_clicked(self):
fd = QFileDialog()
# fd.setDirectory(QDir.homePath())
filepath = fd.getOpenFileName(
- caption=self.tr("Select a {0} to export data from")\
- .format(self.fileType),
- filter=self.tr("{0} (*{1})")\
- .format(self.fileType, self.extension),
+ caption=self.tr("Select a {0} to export data from").format(self.fileType),
+ filter=self.tr("{0} (*{1})").format(self.fileType, self.extension),
)
filepath = filepath[0] if isinstance(filepath, tuple) else filepath
if filepath:
@@ -606,7 +620,7 @@ def now(self):
Gets time and date from the system. Format: "dd/mm/yyyy HH:MM:SS".
:return: (str) current's date and time
"""
- paddle = lambda n : str(n) if n > 9 else "0{0}".format(n)
+ paddle = lambda n: str(n) if n > 9 else "0{0}".format(n)
now = datetime.now()
return "{day}/{month}/{year} {hour}:{minute}:{second}".format(
year=now.year,
@@ -614,7 +628,7 @@ def now(self):
day=paddle(now.day),
hour=paddle(now.hour),
minute=paddle(now.minute),
- second=paddle(now.second)
+ second=paddle(now.second),
)
def metadata(self, updated=False):
@@ -624,9 +638,7 @@ def metadata(self, updated=False):
modification history.
"""
if not hasattr(self, "_metadata"):
- self._metadata = {
- "lastModified": self.now()
- }
+ self._metadata = {"lastModified": self.now()}
elif updated:
self._metadata["lastModified"] = self.now()
return dict(self._metadata)
@@ -643,15 +655,13 @@ def setMetadata(self, metadata, updated=True):
@pyqtSlot()
def on_savePushButton_clicked(self):
"""
- Collects filepath and
+ Collects filepath and
"""
fd = QFileDialog()
# fd.setDirectory(QDir.homePath())
filepath = fd.getSaveFileName(
- caption=self.tr("Select a {0} to export data to")\
- .format(self.fileType),
- filter=self.tr("{0} (*{1})")\
- .format(self.fileType, self.extension),
+ caption=self.tr("Select a {0} to export data to").format(self.fileType),
+ filter=self.tr("{0} (*{1})").format(self.fileType, self.extension),
)
filepath = filepath[0] if isinstance(filepath, tuple) else filepath
if filepath:
diff --git a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py
index 01b8bbffa..0100c7bf3 100644
--- a/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py
+++ b/DsgTools/gui/CustomWidgets/OrderedPropertyWidgets/orderedValidationProcessesWidget.py
@@ -22,27 +22,32 @@
"""
import os
from collections import OrderedDict
+
# Qt imports
from qgis.PyQt import QtGui, uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, QSettings, Qt
from qgis.PyQt.QtWidgets import QTableWidgetItem
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import OrderedStructureWidget
-from DsgTools.gui.CustomWidgets.ValidationWidgets.validationProcessWidget import ValidationProcessWidget
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedStructureWidget import (
+ OrderedStructureWidget,
+)
+from DsgTools.gui.CustomWidgets.ValidationWidgets.validationProcessWidget import (
+ ValidationProcessWidget,
+)
-class OrderedValidationProcessesWidget(OrderedStructureWidget):
+class OrderedValidationProcessesWidget(OrderedStructureWidget):
def __init__(self, parent=None):
"""
Initializates OrderedAttributeRulesWidget
"""
super(OrderedValidationProcessesWidget, self).__init__(parent)
self.args = None
- self.tableWidget.setHorizontalHeaderLabels([self.tr('QGIS Processing Models')])
- self.widgetKey = 'validationProcessWidgetList'
+ self.tableWidget.setHorizontalHeaderLabels([self.tr("QGIS Processing Models")])
+ self.widgetKey = "validationProcessWidgetList"
self.parent = parent
if self.parent:
self.validationManager = self.parent.parent().parent().validationManager
-
+
def instantiateWidgetItem(self):
- return ValidationProcessWidget(parent = self)
\ No newline at end of file
+ return ValidationProcessWidget(parent=self)
diff --git a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py
index 808fe6a89..9847d9e51 100644
--- a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py
+++ b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.py
@@ -33,8 +33,9 @@
from DsgTools.core.Utils.utils import Utils
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), "fmeManagerWidget.ui"))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "fmeManagerWidget.ui")
+)
class FMEManagerWidget(QWidget, FORM_CLASS):
@@ -51,7 +52,7 @@ def clearLayout(self):
"""
Removes all inserted widgets from workspace's parameters from GUI.
"""
- for i in range(self.verticalLayout_2.count()-1, -1, -1):
+ for i in range(self.verticalLayout_2.count() - 1, -1, -1):
self.verticalLayout_2.itemAt(i).widget().setParent(None)
@pyqtSlot(int)
@@ -63,7 +64,7 @@ def on_workspaceComboBox_currentIndexChanged(self):
self.clearLayout()
workspace = self.getCurrentWorkspace()
key = "parameters" if self.version() == "v1" else "parametros"
- _parameters = workspace.get(key, list())
+ _parameters = workspace.get(key, list())
parameters = filter(lambda x: x != "LOG_FILE", _parameters)
for parameter in parameters:
newLabel = QLabel(parameter)
@@ -76,12 +77,7 @@ def resizeEvent(self, e):
"""
Resize QgsMessageBar to widget's width
"""
- self.messageBar.resize(
- QSize(
- self.geometry().size().width(),
- 30
- )
- )
+ self.messageBar.resize(QSize(self.geometry().size().width(), 30))
def getProxyInfo(self):
"""
@@ -139,41 +135,37 @@ def getWorkspacesFromServer(self):
jsonKey = "dados"
try:
if not self.useProxy():
- workspaceList = requests.get(
- url,
- verify=useSsl,
- timeout=15
- ).json()[jsonKey]
+ workspaceList = requests.get(url, verify=useSsl, timeout=15).json()[
+ jsonKey
+ ]
else:
proxyInfo, proxyAuth = self.getProxyInfo()
workspaceList = requests.get(
- url,
- proxies=proxyInfo,
- auth=proxyAuth,
- verify=useSsl,
- timeout=15
+ url, proxies=proxyInfo, auth=proxyAuth, verify=useSsl, timeout=15
).json()[jsonKey]
except ReadTimeout:
self.messageBar.pushMessage(
- self.tr("Connection timed out."), level=Qgis.Warning)
+ self.tr("Connection timed out."), level=Qgis.Warning
+ )
workspaceList = list()
except ConnectTimeout:
self.messageBar.pushMessage(
- self.tr("Connection timed out (max attempts)."),
- level=Qgis.Warning
+ self.tr("Connection timed out (max attempts)."), level=Qgis.Warning
)
workspaceList = list()
except InvalidSchema:
self.messageBar.pushMessage(
self.tr("Missing connection schema (e.g.'http', etc)."),
- level=Qgis.Warning
+ level=Qgis.Warning,
)
workspaceList = list()
except BaseException as e:
self.messageBar.pushMessage(
- self.tr("Unexpected error while trying to reach server. "
- "Check your parameters. Error message: {}".format(e)),
- level=Qgis.Warning
+ self.tr(
+ "Unexpected error while trying to reach server. "
+ "Check your parameters. Error message: {}".format(e)
+ ),
+ level=Qgis.Warning,
)
workspaceList = list()
return workspaceList
@@ -181,7 +173,7 @@ def getWorkspacesFromServer(self):
def setWorkspaces(self, workspaces):
"""
Sets a list of workspaces to the GUI.
- :param workspaces: (list-of-str)
+ :param workspaces: (list-of-str)
"""
self.workspaceComboBox.clear()
if workspaces:
@@ -216,7 +208,7 @@ def on_loadPushButton_clicked(self):
self.workspaceComboBox.addItem(
"{name} ({description})".format(
name=workspace[workspaceNameKey],
- description=workspace[workspaceDescKey]
+ description=workspace[workspaceDescKey],
)
)
@@ -231,16 +223,17 @@ def validate(self, pushAlert=False):
if self.useProxy() and not proxyInfo:
if pushAlert:
self.messageBar.pushMessage(
- self.tr("Proxy usage is set but no QGIS proxy settings "
- "was found."),
- level=Qgis.Warning
+ self.tr(
+ "Proxy usage is set but no QGIS proxy settings " "was found."
+ ),
+ level=Qgis.Warning,
)
return False
if self.server() == "":
if pushAlert:
self.messageBar.pushMessage(
self.tr("URL to FME Manager server was not provided."),
- level=Qgis.Warning
+ level=Qgis.Warning,
)
return False
return True
@@ -253,7 +246,9 @@ def getParameters(self):
workspaceId = workspace.get("id", None)
version = self.version()
parameters = {
- "parameters" if version == "v1" else "parametros": {
+ "parameters"
+ if version == "v1"
+ else "parametros": {
key: value.text() for key, value in self.paramWidgetMap.items()
}
}
@@ -266,5 +261,5 @@ def getParameters(self):
"auth": proxyAuth,
"proxy_dict": proxyInfo,
"use_ssl": self.useSsl(),
- "use_proxy": self.useProxy()
+ "use_proxy": self.useProxy(),
}
diff --git a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui
index 92ef97131..014265008 100644
--- a/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui
+++ b/DsgTools/gui/CustomWidgets/ProcessingParameterWidgets/fmeManagerWidget.ui
@@ -97,4 +97,4 @@
-
\ No newline at end of file
+
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py
index f2943cc36..a53d32ba2 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customReferenceAndLayersParameterSelector.py
@@ -28,83 +28,106 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'customReferenceAndLayersParameterSelector.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(
+ os.path.dirname(__file__), "customReferenceAndLayersParameterSelector.ui"
+ )
+)
-class CustomReferenceAndLayersParameterSelector(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, parent = None):
+class CustomReferenceAndLayersParameterSelector(QtWidgets.QWidget, FORM_CLASS):
+ def __init__(self, parent=None):
"""Constructor."""
super(CustomReferenceAndLayersParameterSelector, self).__init__(parent)
self.referenceLayerKey = None
self.selectedLayersItems = []
self.setupUi(self)
-
+
def setTitle(self, title):
self.customTableSelectorWidget.setTitle(title)
-
+
@pyqtSlot(int)
def on_referenceComboBox_currentIndexChanged(self, idx):
if idx == 0:
if self.referenceLayerKey and self.unifiedList:
- self.customTableSelectorWidget.addItemsToWidget([self.layersTextDict[self.referenceLayerKey]], unique = True)
+ self.customTableSelectorWidget.addItemsToWidget(
+ [self.layersTextDict[self.referenceLayerKey]], unique=True
+ )
self.referenceLayerKey = None
self.customTableSelectorWidget.setEnabled(False)
else:
if self.referenceLayerKey:
if self.unifiedList:
- self.customTableSelectorWidget.addItemsToWidget([self.layersTextDict[self.referenceLayerKey]], unique = True)
+ self.customTableSelectorWidget.addItemsToWidget(
+ [self.layersTextDict[self.referenceLayerKey]], unique=True
+ )
else:
- self.customTableSelectorWidget.addItemsToWidget([self.referenceTextDict[self.referenceLayerKey]], unique = True)
+ self.customTableSelectorWidget.addItemsToWidget(
+ [self.referenceTextDict[self.referenceLayerKey]], unique=True
+ )
self.customTableSelectorWidget.setEnabled(True)
self.referenceLayerKey = self.referenceComboBox.currentText()
if self.unifiedList:
- self.customTableSelectorWidget.removeItemsFromWidget([self.layersTextDict[self.referenceLayerKey]])
+ self.customTableSelectorWidget.removeItemsFromWidget(
+ [self.layersTextDict[self.referenceLayerKey]]
+ )
else:
- self.customTableSelectorWidget.removeItemsFromWidget([self.referenceTextDict[self.referenceLayerKey]])
-
+ self.customTableSelectorWidget.removeItemsFromWidget(
+ [self.referenceTextDict[self.referenceLayerKey]]
+ )
+
def setInitialState(self, inputOrderedDict, unique=True):
"""
Sets the initial state
referenceDict: {'cat,lyrName,geom,geomType,tableType':{'tableSchema':tableSchema, 'tableName':tableName, 'geom':geom, 'geomType':geomType, 'tableType':tableType, 'lyrName':lyrName, 'cat':cat}}
- referenceDictList: interface ready dict like
+ referenceDictList: interface ready dict like
{
- self.tr('Category'):cat,
- self.tr('Layer Name'):lyrName,
- self.tr('Geometry\nColumn'):geom,
- self.tr('Geometry\nType'):geomType,
+ self.tr('Category'):cat,
+ self.tr('Layer Name'):lyrName,
+ self.tr('Geometry\nColumn'):geom,
+ self.tr('Geometry\nType'):geomType,
self.tr('Layer\nType'):tableType
}
"""
- self.referenceDictList = inputOrderedDict['referenceDictList']
- self.layersDictList = inputOrderedDict['layersDictList']
-
- #makes referenceTextDict
+ self.referenceDictList = inputOrderedDict["referenceDictList"]
+ self.layersDictList = inputOrderedDict["layersDictList"]
+
+ # makes referenceTextDict
self.referenceTextDict = OrderedDict()
- self.referenceTextDict[self.tr('Select a layer')] = None
+ self.referenceTextDict[self.tr("Select a layer")] = None
sortedRefKeys = list(self.referenceDictList.keys())
sortedRefKeys.sort()
for key in sortedRefKeys:
- cat, lyrName, geom, geomType, tableType = key.split(',')
- textItem = """{0}.{1} ({2}, {3}, {4})""".format(cat, lyrName, geom, geomType, tableType)
+ cat, lyrName, geom, geomType, tableType = key.split(",")
+ textItem = """{0}.{1} ({2}, {3}, {4})""".format(
+ cat, lyrName, geom, geomType, tableType
+ )
self.referenceTextDict[textItem] = self.referenceDictList[key]
- #makes referenceTextDict
+ # makes referenceTextDict
self.layersTextDict = OrderedDict()
- self.layersTextDict[self.tr('Select a layer')] = None
+ self.layersTextDict[self.tr("Select a layer")] = None
sortedLyrsKeys = list(self.layersDictList.keys())
sortedLyrsKeys.sort()
for key in sortedLyrsKeys:
- cat, lyrName, geom, geomType, tableType = key.split(',')
- textItem = """{0}.{1} ({2}, {3}, {4})""".format(cat, lyrName, geom, geomType, tableType)
+ cat, lyrName, geom, geomType, tableType = key.split(",")
+ textItem = """{0}.{1} ({2}, {3}, {4})""".format(
+ cat, lyrName, geom, geomType, tableType
+ )
self.layersTextDict[textItem] = self.layersDictList[key]
if len(list(self.referenceTextDict.keys())) == 1:
self.unifiedList = True
- self.referenceComboBox.addItems(list(self.layersTextDict.keys())) #uses all layers to populate ref combo
+ self.referenceComboBox.addItems(
+ list(self.layersTextDict.keys())
+ ) # uses all layers to populate ref combo
else:
self.unifiedList = False
- self.referenceComboBox.addItems(list(self.referenceTextDict.keys())) #uses only some layers to populate ref combo
- self.customTableSelectorWidget.setInitialState(list(self.layersDictList.values()))
-
+ self.referenceComboBox.addItems(
+ list(self.referenceTextDict.keys())
+ ) # uses only some layers to populate ref combo
+ self.customTableSelectorWidget.setInitialState(
+ list(self.layersDictList.values())
+ )
+
def getParameters(self):
"""
Gets parameters
@@ -116,7 +139,7 @@ def getParameters(self):
refItem = self.referenceTextDict[self.referenceLayerKey]
originalRefDict = self.referenceDictList
try:
- referenceKey = [k for (k,v) in originalRefDict.items() if v == refItem][0]
+ referenceKey = [k for (k, v) in originalRefDict.items() if v == refItem][0]
except:
referenceKey = None
- return referenceKey, self.customTableSelectorWidget.getSelectedNodes()
\ No newline at end of file
+ return referenceKey, self.customTableSelectorWidget.getSelectedNodes()
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py
index cf56c7ba9..3482f98ff 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSelector.py
@@ -28,13 +28,15 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'customSelector.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "customSelector.ui")
+)
+
class CustomSelector(QtWidgets.QWidget, FORM_CLASS):
- selectionChanged = pyqtSignal(list,str)
+ selectionChanged = pyqtSignal(list, str)
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
# Set up the user interface from Designer.
@@ -45,7 +47,7 @@ def __init__(self, parent = None):
self.fromLs = []
self.toLs = []
self.setupUi(self)
-
+
def clearAll(self):
"""
Clears everything to return to the initial state
@@ -55,7 +57,7 @@ def clearAll(self):
self.fromList.clear()
self.toList.clear()
self.filterLineEdit.clear()
-
+
def setInitialState(self, fromList, unique=False):
"""
Sets the initial state
@@ -63,7 +65,7 @@ def setInitialState(self, fromList, unique=False):
self.clearAll()
if not isinstance(fromList, int):
self.setFromList(fromList, unique)
-
+
def setFromList(self, fromList, unique=False):
"""
Setting the "from" items (QListWidget and python list)
@@ -78,7 +80,7 @@ def setFromList(self, fromList, unique=False):
self.fromLs.sort()
self.fromList.addItems(fromList)
self.fromList.sortItems()
-
+
def addItems(self, addList, unique=False):
"""
Adding "from" items (QListWidget and python list)
@@ -95,7 +97,7 @@ def addItems(self, addList, unique=False):
self.fromList.addItems(toAddList)
self.fromList.sortItems()
self.fromLs.sort()
-
+
def removeItem(self, removeItem):
"""
Removing items (QListWidget and python list)
@@ -113,7 +115,6 @@ def removeItem(self, removeItem):
self.toLs.remove(toItem.text())
item = self.toList.takeItem(i)
-
def setToList(self, toList):
"""
Setting the "to" items (QListWidget and python list)
@@ -121,14 +122,14 @@ def setToList(self, toList):
self.toLs = list(toList)
self.toList.addItems(self.toLs)
self.toList.sortItems()
-
- def setTitle(self,title):
+
+ def setTitle(self, title):
"""
Setting the title
"""
self.groupBox.setTitle(title)
- @pyqtSlot(bool, name='on_pushButtonSelectOne_clicked')
+ @pyqtSlot(bool, name="on_pushButtonSelectOne_clicked")
def selectItems(self, isSelected, selectedItems=None):
"""
Adds the selected items to the "to" list
@@ -154,10 +155,10 @@ def selectItems(self, isSelected, selectedItems=None):
self.fromLs.remove(item.text())
added.append(item.text())
self.toList.sortItems()
- #emits added items
+ # emits added items
if len(added) > 0:
- self.selectionChanged.emit(added,'added')
-
+ self.selectionChanged.emit(added, "added")
+
@pyqtSlot(bool)
def on_pushButtonSelectAll_clicked(self):
"""
@@ -165,16 +166,16 @@ def on_pushButtonSelectAll_clicked(self):
"""
tam = self.fromList.__len__()
added = []
- for i in range(tam+1,1,-1):
- item = self.fromList.takeItem(i-2)
+ for i in range(tam + 1, 1, -1):
+ item = self.fromList.takeItem(i - 2)
self.toList.addItem(item)
self.toLs.append(item.text())
added.append(item.text())
self.fromLs.remove(item.text())
self.toList.sortItems()
- #emits added items
+ # emits added items
if len(added) > 0:
- self.selectionChanged.emit(added,'added')
+ self.selectionChanged.emit(added, "added")
@pyqtSlot(bool)
def on_pushButtonDeselectOne_clicked(self):
@@ -190,9 +191,9 @@ def on_pushButtonDeselectOne_clicked(self):
removed.append(item.text())
self.fromList.addItem(item)
self.fromList.sortItems()
- #emits removed items
+ # emits removed items
if len(removed) > 0:
- self.selectionChanged.emit(removed,'removed')
+ self.selectionChanged.emit(removed, "removed")
@pyqtSlot(bool)
def on_pushButtonDeselectAll_clicked(self):
@@ -201,23 +202,27 @@ def on_pushButtonDeselectAll_clicked(self):
"""
tam = self.toList.__len__()
removed = []
- for i in range(tam+1,1,-1):
- item = self.toList.takeItem(i-2)
+ for i in range(tam + 1, 1, -1):
+ item = self.toList.takeItem(i - 2)
self.fromLs.append(item.text())
self.toLs.remove(item.text())
self.fromList.addItem(item)
removed.append(item.text())
self.fromList.sortItems()
- #emits removed items
+ # emits removed items
if len(removed) > 0:
- self.selectionChanged.emit(removed,'removed')
-
+ self.selectionChanged.emit(removed, "removed")
+
def on_filterLineEdit_textChanged(self, text):
"""
Filters the items to make it easier to spot and select them
"""
- classes = [edgvClass for edgvClass in self.fromLs if text.lower() in edgvClass.lower()]
- filteredClasses = [i for i in classes if i.lower() not in [j.lower() for j in self.toLs]]
+ classes = [
+ edgvClass for edgvClass in self.fromLs if text.lower() in edgvClass.lower()
+ ]
+ filteredClasses = [
+ i for i in classes if i.lower() not in [j.lower() for j in self.toLs]
+ ]
self.fromList.clear()
self.fromList.addItems(classes)
self.fromList.sortItems()
@@ -234,8 +239,8 @@ def resetSelections(self):
and avoid losing items.
"""
tam = self.toList.__len__()
- for i in range(tam+1,1,-1):
- item = self.toList.takeItem(i-2)
+ for i in range(tam + 1, 1, -1):
+ item = self.toList.takeItem(i - 2)
self.fromLs.append(item.text())
self.toLs.remove(item.text())
self.fromLs.sort()
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py
index a4d9e00f3..ebe83571e 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customSnaperParameterSelector.py
@@ -27,22 +27,24 @@
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'customSnaperParameterSelector.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "customSnaperParameterSelector.ui")
+)
+
class CustomSnaperParameterSelector(QtWidgets.QWidget, FORM_CLASS):
- selectionChanged = pyqtSignal(list,str)
+ selectionChanged = pyqtSignal(list, str)
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.referenceLayer = None
self.selectedLayers = []
self.setupUi(self)
-
+
def setTitle(self, title):
self.customSelectorWidget.setTitle(title)
-
+
@pyqtSlot(int)
def on_referenceComboBox_currentIndexChanged(self, idx):
if idx == 0:
@@ -58,14 +60,16 @@ def on_referenceComboBox_currentIndexChanged(self, idx):
self.referenceLayer = self.referenceComboBox.currentText()
if self.unifiedList:
self.customSelectorWidget.removeItem(self.referenceLayer)
-
- def setInitialState(self, referenceList, originalList, unique=False, parameterDict = {}):
+
+ def setInitialState(
+ self, referenceList, originalList, unique=False, parameterDict={}
+ ):
"""
Sets the initial state
"""
self.originalList = originalList
self.customSelectorWidget.addItems(originalList)
- self.referenceComboBox.addItem(self.tr('Select a layer'))
+ self.referenceComboBox.addItem(self.tr("Select a layer"))
originalList.sort()
if len(referenceList) == 0:
self.unifiedList = True
@@ -75,7 +79,7 @@ def setInitialState(self, referenceList, originalList, unique=False, parameterDi
self.referenceComboBox.addItems(referenceList)
if parameterDict:
self.populateInterface(parameterDict)
-
+
def getParameters(self):
"""
Gets parameters
@@ -83,10 +87,12 @@ def getParameters(self):
return self.referenceLayer, self.customSelectorWidget.toLs
def getParameterDict(self):
- return OrderedDict({'referenceDictList':interfaceLineDict, 'layersDictList':interfaceDict})
-
+ return OrderedDict(
+ {"referenceDictList": interfaceLineDict, "layersDictList": interfaceDict}
+ )
+
def populateInterface(self, parameterDict):
"""
Sets saved state
"""
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py
index d56fb9c11..a74e82e4b 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableSelector.py
@@ -31,31 +31,37 @@
from ....core.Utils.utils import Utils
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'customTableSelector.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "customTableSelector.ui")
+)
+
class CustomTableSelector(QtWidgets.QWidget, FORM_CLASS):
- selectionChanged = pyqtSignal(list,str)
+ selectionChanged = pyqtSignal(list, str)
- def __init__(self, customNumber = None, parent = None):
+ def __init__(self, customNumber=None, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.fromLs = []
self.toLs = []
self.utils = Utils()
self.setupUi(self)
-
+
def resizeTrees(self):
"""
Expands headers
"""
self.fromTreeWidget.expandAll()
- self.fromTreeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
+ self.fromTreeWidget.header().setSectionResizeMode(
+ QtWidgets.QHeaderView.ResizeToContents
+ )
self.fromTreeWidget.header().setStretchLastSection(False)
self.toTreeWidget.expandAll()
- self.toTreeWidget.header().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
+ self.toTreeWidget.header().setSectionResizeMode(
+ QtWidgets.QHeaderView.ResizeToContents
+ )
self.toTreeWidget.header().setStretchLastSection(False)
-
+
def sortItems(self, treeWidget):
"""
Sorts items from input treeWidget
@@ -64,14 +70,14 @@ def sortItems(self, treeWidget):
rootNode.sortChildren(0, Qt.AscendingOrder)
for i in range(rootNode.childCount()):
rootNode.child(i).sortChildren(1, Qt.AscendingOrder)
-
- def setTitle(self,title):
+
+ def setTitle(self, title):
"""
Setting the title
"""
self.groupBox.setTitle(title)
-
- def setFilterColumn(self, customNumber = None):
+
+ def setFilterColumn(self, customNumber=None):
"""
Chooses which column is going to be used in the filter
"""
@@ -81,23 +87,23 @@ def setFilterColumn(self, customNumber = None):
self.filterColumnKey = self.headerList[1]
else:
self.filterColumnKey = self.headerList[0]
-
+
def clearAll(self):
"""
Clears everything to return to the initial state
"""
self.filterLineEdit.clear()
-
- def setHeaders(self, headerList, customNumber = None):
+
+ def setHeaders(self, headerList, customNumber=None):
"""
Sets fromTreeWidget and toTreeWidget headers
"""
self.headerList = headerList
self.fromTreeWidget.setHeaderLabels(headerList)
self.toTreeWidget.setHeaderLabels(headerList)
- self.setFilterColumn(customNumber = customNumber)
-
- def setInitialState(self, fromDictList, unique=False, selectedDictList = []):
+ self.setFilterColumn(customNumber=customNumber)
+
+ def setInitialState(self, fromDictList, unique=False, selectedDictList=[]):
"""
Sets the initial state
"""
@@ -106,10 +112,16 @@ def setInitialState(self, fromDictList, unique=False, selectedDictList = []):
self.fromTreeWidget.clear()
self.fromTreeWidget.clear()
if not isinstance(fromDictList, int):
- self.addItemsToTree(self.fromTreeWidget, fromDictList, self.fromLs, unique = unique, selectedDictList = selectedDictList)
+ self.addItemsToTree(
+ self.fromTreeWidget,
+ fromDictList,
+ self.fromLs,
+ unique=unique,
+ selectedDictList=selectedDictList,
+ )
if selectedDictList:
self.pushButtonSelectOne.clicked.emit()
-
+
def getChildNode(self, parentNode, textList):
"""
Returns child node with columns equals to textList items. If no node is found, return None
@@ -125,35 +137,49 @@ def getChildNode(self, parentNode, textList):
return childNode
return None
- def addItemsToTree(self, treeWidget, addItemDictList, controlList, unique = False, selectedDictList = []):
+ def addItemsToTree(
+ self,
+ treeWidget,
+ addItemDictList,
+ controlList,
+ unique=False,
+ selectedDictList=[],
+ ):
"""
Adds items from addItemDictList in treeWidget.
addItemDictList = [-list of dicts with keys corresponding to header list texts-]
unique: only adds item if it is not in already in tree
"""
- rootNode = treeWidget.invisibleRootItem() #invisible root item
+ rootNode = treeWidget.invisibleRootItem() # invisible root item
for dictItem in addItemDictList:
- firstColumnChild = self.getChildNode(rootNode, [dictItem[self.headerList[0]]]+['']*(len(self.headerList)-1)) #looks for a item in the format ['first column text', '','',...,'']
+ firstColumnChild = self.getChildNode(
+ rootNode,
+ [dictItem[self.headerList[0]]] + [""] * (len(self.headerList) - 1),
+ ) # looks for a item in the format ['first column text', '','',...,'']
if not firstColumnChild:
- firstColumnChild = self.utils.createWidgetItem(rootNode,dictItem[self.headerList[0]],0)
- textList = [dictItem[self.headerList[i]] for i in range(len(self.headerList))]
+ firstColumnChild = self.utils.createWidgetItem(
+ rootNode, dictItem[self.headerList[0]], 0
+ )
+ textList = [
+ dictItem[self.headerList[i]] for i in range(len(self.headerList))
+ ]
if unique:
childNode = self.getChildNode(firstColumnChild, textList)
if not childNode:
- item = self.utils.createWidgetItem(firstColumnChild,textList)
+ item = self.utils.createWidgetItem(firstColumnChild, textList)
if selectedDictList:
item.setSelected(True)
itemList = self.getItemList(item)
if itemList not in controlList:
controlList.append(itemList)
else:
- item = self.utils.createWidgetItem(firstColumnChild,textList)
+ item = self.utils.createWidgetItem(firstColumnChild, textList)
itemList = self.getItemList(item)
controlList.append(itemList)
self.resizeTrees()
self.sortItems(treeWidget)
-
- def getItemList(self, item, returnAsDict = False):
+
+ def getItemList(self, item, returnAsDict=False):
"""
Gets item as a list
"""
@@ -173,35 +199,41 @@ def getLists(self, sender):
Returns a list composed by (originTreeWidget, --list that controls previous originTreeWidget--, destinationTreeWidget, --list that controls previous destinationTreeWidget--)
"""
text = sender.text()
- if text == '>':
+ if text == ">":
return self.fromTreeWidget, self.fromLs, self.toTreeWidget, self.toLs, False
- if text == '>>':
+ if text == ">>":
return self.fromTreeWidget, self.fromLs, self.toTreeWidget, self.toLs, True
- if text == '<':
+ if text == "<":
return self.toTreeWidget, self.toLs, self.fromTreeWidget, self.fromLs, False
- if text == '<<':
+ if text == "<<":
return self.toTreeWidget, self.toLs, self.fromTreeWidget, self.fromLs, True
- @pyqtSlot(bool, name='on_pushButtonSelectOne_clicked')
- @pyqtSlot(bool, name='on_pushButtonDeselectOne_clicked')
- @pyqtSlot(bool, name='on_pushButtonSelectAll_clicked')
- @pyqtSlot(bool, name='on_pushButtonDeselectAll_clicked')
+ @pyqtSlot(bool, name="on_pushButtonSelectOne_clicked")
+ @pyqtSlot(bool, name="on_pushButtonDeselectOne_clicked")
+ @pyqtSlot(bool, name="on_pushButtonSelectAll_clicked")
+ @pyqtSlot(bool, name="on_pushButtonDeselectAll_clicked")
def selectItems(self, isSelected, selectedItems=[]):
"""
Adds the selected items to the "to" list
"""
- #gets lists
- originTreeWidget, originControlLs, destinationTreeWidget, destinationControlLs, allItems = self.getLists(self.sender())
- #root nodes
+ # gets lists
+ (
+ originTreeWidget,
+ originControlLs,
+ destinationTreeWidget,
+ destinationControlLs,
+ allItems,
+ ) = self.getLists(self.sender())
+ # root nodes
originRoot = originTreeWidget.invisibleRootItem()
destinationRoot = destinationTreeWidget.invisibleRootItem()
selectedItemList = []
self.getSelectedItems(originRoot, selectedItemList)
for i in range(originRoot.childCount())[::-1]:
catChild = originRoot.child(i)
- #if son of originRootNode is selected, adds it to destinationRootNode
+ # if son of originRootNode is selected, adds it to destinationRootNode
moveNode = allItems or (catChild in selectedItemList)
- #get destination parent, creates one in destination if not exists
+ # get destination parent, creates one in destination if not exists
destinationCatChild = self.getDestinationNode(destinationRoot, catChild)
for j in range(catChild.childCount())[::-1]:
nodeChild = catChild.child(j)
@@ -230,7 +262,7 @@ def getSelectedItems(self, treeWidgetNode, itemList):
itemList.append(childItem)
for j in range(childItem.childCount()):
self.getSelectedItems(childItem, itemList)
-
+
def moveChild(self, parentNode, idx, destinationNode, isSelected):
"""
If node is selected, removes node from parentNode and adds it to destinationNode
@@ -242,13 +274,13 @@ def moveChild(self, parentNode, idx, destinationNode, isSelected):
else:
return False
- def getDestinationNode(self, destinationRoot, catChild, returnNew = True):
+ def getDestinationNode(self, destinationRoot, catChild, returnNew=True):
"""
Looks for node in destination and returns it. If none is found, creates one and returns it
"""
- #get destination parent, creates one in destination if not exists
+ # get destination parent, creates one in destination if not exists
destinationCatChild = None
- if isinstance(catChild,list):
+ if isinstance(catChild, list):
comparisonText = catChild[0]
if returnNew:
itemTextList = [catChild[i] for i in range(len(catChild))]
@@ -260,42 +292,48 @@ def getDestinationNode(self, destinationRoot, catChild, returnNew = True):
for i in range(destinationRoot.childCount()):
candidate = destinationRoot.child(i)
if candidate.text(0) == comparisonText:
- #if candidate is found, returns candidate
+ # if candidate is found, returns candidate
return candidate
- #if candidate is not found, creates one and returns it
+ # if candidate is not found, creates one and returns it
if returnNew:
if not destinationCatChild:
- return QTreeWidgetItem(destinationRoot,itemTextList)
+ return QTreeWidgetItem(destinationRoot, itemTextList)
else:
return None
-
+
def on_filterLineEdit_textChanged(self, text):
"""
Filters the items to make it easier to spot and select them
"""
- classes = [node[1].lower() for node in self.fromLs if text.lower() in node[1].lower()] #text list
- filteredClasses = [i for i in classes if i.lower() not in [j[1].lower() for j in self.toLs]] #text list
+ classes = [
+ node[1].lower() for node in self.fromLs if text.lower() in node[1].lower()
+ ] # text list
+ filteredClasses = [
+ i for i in classes if i.lower() not in [j[1].lower() for j in self.toLs]
+ ] # text list
self.filterTree(self.fromTreeWidget, self.fromLs, filteredClasses, 1)
self.resizeTrees()
-
+
def filterTree(self, treeWidget, controlList, filterList, columnIdx):
- '''
+ """
Actual filter
- '''
+ """
treeWidget.clear()
rootNode = treeWidget.invisibleRootItem()
- #remove items that are not in filterList
+ # remove items that are not in filterList
for item in controlList:
if item[columnIdx].lower() in filterList:
- firstColumnChild = self.getChildNode(rootNode, [item[0]]+['']*(len(item)-1)) #looks for a item in the format ['first column text', '','',...,'']
+ firstColumnChild = self.getChildNode(
+ rootNode, [item[0]] + [""] * (len(item) - 1)
+ ) # looks for a item in the format ['first column text', '','',...,'']
if not firstColumnChild:
firstColumnChild = self.utils.createWidgetItem(rootNode, item[0], 0)
QTreeWidgetItem(firstColumnChild, item)
rootNode.sortChildren(0, Qt.AscendingOrder)
for i in range(rootNode.childCount()):
rootNode.child(i).sortChildren(1, Qt.AscendingOrder)
-
- def getSelectedNodes(self, concatenated = True):
+
+ def getSelectedNodes(self, concatenated=True):
"""
Returns a list of selected nodes converted into a string separated by ','
"""
@@ -307,28 +345,28 @@ def getSelectedNodes(self, concatenated = True):
item = catNode.child(j)
if concatenated:
catList = [item.text(i) for i in range(item.columnCount())]
- selected.append(','.join(catList))
+ selected.append(",".join(catList))
else:
selected.append(item)
return selected
- def addItemsToWidget(self, itemList, unique = False):
+ def addItemsToWidget(self, itemList, unique=False):
"""
Adds items to tree that is already built.
"""
- self.addItemsToTree(self.fromTreeWidget, itemList, self.fromLs, unique = unique)
-
+ self.addItemsToTree(self.fromTreeWidget, itemList, self.fromLs, unique=unique)
+
def removeItemsFromWidget(self, removeList):
"""
Searches both lists and removes items that are in removeList
"""
self.removeItemsFromTree(removeList, self.fromTreeWidget, self.fromLs)
self.removeItemsFromTree(removeList, self.toTreeWidget, self.toLs)
-
+
def removeItemsFromTree(self, dictItemList, treeWidget, controlList):
"""
Searches treeWidget and removes items that are in removeList and updates controlList
- """
+ """
treeRoot = treeWidget.invisibleRootItem()
catList = [i[self.headerList[0]] for i in dictItemList]
returnList = []
@@ -337,7 +375,7 @@ def removeItemsFromTree(self, dictItemList, treeWidget, controlList):
if catChild.text(0) in catList:
for j in range(catChild.childCount())[::-1]:
nodeChild = catChild.child(j)
- nodeChildDict = self.getItemList(nodeChild, returnAsDict = True)
+ nodeChildDict = self.getItemList(nodeChild, returnAsDict=True)
nodeChildDict[self.headerList[0]] = catChild.text(0)
if nodeChildDict in dictItemList:
catChild.takeChild(j)
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py
index 38493c601..ae0b4ef0c 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/customTableWidget.py
@@ -32,14 +32,16 @@
from qgis.PyQt.QtWidgets import QFileDialog
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'customTableWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "customTableWidget.ui")
+)
+
class ValidatedItemDelegate(QtWidgets.QStyledItemDelegate):
- def defineValidatorList(self, validatorList, maskList = None):
+ def defineValidatorList(self, validatorList, maskList=None):
self.validatorList = validatorList
if not maskList:
- self.maskList = [None]*len(self.validatorList)
+ self.maskList = [None] * len(self.validatorList)
else:
self.maskList = maskList
@@ -54,40 +56,42 @@ def createEditor(self, widget, option, index):
return editor
return super(ValidatedItemDelegate, self).createEditor(widget, option, index)
+
class CustomTableWidget(QtWidgets.QWidget, FORM_CLASS):
filesSelected = pyqtSignal()
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
-
+
def setHeaders(self, headerList):
for header in headerList:
currColumn = self.tableWidget.columnCount()
self.tableWidget.insertColumn(currColumn)
self.tableWidget.setHorizontalHeaderLabels(headerList)
-
+
def setValidator(self, validatorList):
itemDelegate = ValidatedItemDelegate()
itemDelegate.defineValidatorList(validatorList)
self.tableWidget.setItemDelegate(itemDelegate)
-
- @pyqtSlot(bool, name = 'on_addPushButton_clicked')
- def addItems(self, itemList = []):
+
+ @pyqtSlot(bool, name="on_addPushButton_clicked")
+ def addItems(self, itemList=[]):
if isinstance(itemList, bool):
- oneItemList = ['' for i in range(self.tableWidget.columnCount())]
+ oneItemList = ["" for i in range(self.tableWidget.columnCount())]
self.addOneItem(oneItemList)
else:
for item in itemList:
self.addOneItem(item)
-
+
def addOneItem(self, oneItemList):
rowCount = self.tableWidget.rowCount()
self.tableWidget.insertRow(rowCount)
for i in range(len(oneItemList)):
newItem = QtGui.QTableWidgetItem(oneItemList[i])
self.tableWidget.setItem(rowCount, i, newItem)
-
+
@pyqtSlot(bool)
def on_removePushButton_clicked(self):
selected = self.tableWidget.selectedIndexes()
@@ -97,7 +101,7 @@ def on_removePushButton_clicked(self):
self.tableWidget.removeRow(row)
self.validatorList.pop(row)
self.maskList.pop(row)
-
+
def clearItems(self):
rowList = list(range(self.tableWidget.rowCount()))
rowList.sort(reverse=True)
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py
index cf4deb2c9..987e3e965 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/listSelector.py
@@ -27,28 +27,37 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'listSelector.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "listSelector.ui")
+)
+
class ListSelector(QtWidgets.QDialog, FORM_CLASS):
-
- def __init__(self, originList, destinationList, parent = None):
+ def __init__(self, originList, destinationList, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
self.originList = originList
self.destinationList = destinationList
- self.listCustomSelector.setTitle(self.tr('Select'))
- self.listCustomSelector.setFromList(list(originList), unique = True) #passes a copy using list()
+ self.listCustomSelector.setTitle(self.tr("Select"))
+ self.listCustomSelector.setFromList(
+ list(originList), unique=True
+ ) # passes a copy using list()
self.listCustomSelector.setToList(list(destinationList))
-
+
def getSelected(self):
return self.listCustomSelector.toLs
-
+
def getInputAndOutputLists(self):
return (self.listCustomSelector.fromLs, self.listCustomSelector.toLs)
@@ -58,4 +67,4 @@ def on_buttonBox_accepted(self):
@pyqtSlot()
def on_buttonBox_rejected(self):
- self.done(0)
\ No newline at end of file
+ self.done(0)
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py
index 7e22e2041..84f1cec92 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectFileWidget.py
@@ -31,20 +31,23 @@
from qgis.PyQt.QtWidgets import QFileDialog
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'selectFileWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "selectFileWidget.ui")
+)
+
class SelectFileWidget(QtWidgets.QWidget, FORM_CLASS):
filesSelected = pyqtSignal()
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
self.fileNameList = []
self.lineEdit.setReadOnly(True)
- self.caption = ''
- self.filter = ''
- self.type = 'single'
+ self.caption = ""
+ self.filter = ""
+ self.type = "single"
@pyqtSlot(bool)
def on_selectFilePushButton_clicked(self):
@@ -53,48 +56,56 @@ def on_selectFilePushButton_clicked(self):
"""
fd = QFileDialog()
fd.setDirectory(QDir.homePath())
- if self.type == 'multi':
- self.fileNameList = fd.getOpenFileNames(caption=self.caption, filter=self.filter)
- selectedFiles = ', '.join(self.fileNameList[0])
- elif self.type == 'single':
+ if self.type == "multi":
+ self.fileNameList = fd.getOpenFileNames(
+ caption=self.caption, filter=self.filter
+ )
+ selectedFiles = ", ".join(self.fileNameList[0])
+ elif self.type == "single":
selectedFiles = fd.getOpenFileName(caption=self.caption, filter=self.filter)
if isinstance(selectedFiles, tuple):
self.fileNameList = selectedFiles[0]
- elif self.type == 'dir':
- selectedFiles = fd.getExistingDirectory(directory=os.path.expanduser('~'), caption=self.caption, options=QFileDialog.ShowDirsOnly)
- if selectedFiles != '':
- self.fileNameList = [selectedFiles]
- selectedFiles = selectedFiles[0] if isinstance(selectedFiles, tuple) else selectedFiles
+ elif self.type == "dir":
+ selectedFiles = fd.getExistingDirectory(
+ directory=os.path.expanduser("~"),
+ caption=self.caption,
+ options=QFileDialog.ShowDirsOnly,
+ )
+ if selectedFiles != "":
+ self.fileNameList = [selectedFiles]
+ selectedFiles = (
+ selectedFiles[0] if isinstance(selectedFiles, tuple) else selectedFiles
+ )
self.lineEdit.setText(selectedFiles)
self.filesSelected.emit()
-
+
def resetAll(self):
"""
Resets all
"""
self.lineEdit.clear()
self.fileNameList = []
-
+
def setTitle(self, text):
"""
Sets the label title
"""
self.label.setText(text)
-
+
def setCaption(self, caption):
"""
Sets the caption
"""
self.caption = caption
-
+
def setFilter(self, filter):
"""
Sets the file filter
"""
self.filter = filter
-
+
def setType(self, type):
"""
Sets selection type (e.g multi, single, dir)
"""
- self.type = type
\ No newline at end of file
+ self.type = type
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py
index 468a34398..b5824e16d 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/selectTaskWizard.py
@@ -7,7 +7,7 @@
git sha : $Format:%H$
copyright : (C) 2017 by Philipe Borba - Cartographic Engineer @ Brazilian Army
email : borba.philipe@eb.mil.br
- mod history :
+ mod history :
***************************************************************************/
/***************************************************************************
@@ -21,15 +21,17 @@
"""
import os, json
-#PyQt imports
+# PyQt imports
from qgis.PyQt import QtWidgets, QtCore, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt
from qgis.PyQt.QtWidgets import QApplication, QMessageBox
from qgis.PyQt.QtGui import QCursor
-#DsgTools imports
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'selectTaskWizard.ui'))
+# DsgTools imports
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "selectTaskWizard.ui")
+)
+
class SelectTaskWizard(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, iface, settingList, parent=None):
@@ -40,20 +42,20 @@ def __init__(self, iface, settingList, parent=None):
self.setupUi(self)
self.hideSettings(True)
self.settingList = settingList
-
+
def hideSettings(self, hide):
self.settingComboBox.hide(hide)
self.label.hide(hide)
-
+
def populateSettingCombo(self, settingList):
self.settingComboBox.clear()
- self.settingComboBox.addItem(self.tr('Select one setting'))
+ self.settingComboBox.addItem(self.tr("Select one setting"))
for setting in settingList:
self.settingComboBox.addItem(setting)
-
- @pyqtSlot(name='on_importRadioButton_toggled')
- @pyqtSlot(name='on_createNewRadioButton_toggled')
- @pyqtSlot(name='on_installRadioButton_toggled')
+
+ @pyqtSlot(name="on_importRadioButton_toggled")
+ @pyqtSlot(name="on_createNewRadioButton_toggled")
+ @pyqtSlot(name="on_installRadioButton_toggled")
def manageCombos(self):
if self.installRadioButton.checkState() == Qt.Checked:
self.hideSettings(False)
@@ -64,17 +66,21 @@ def manageCombos(self):
def validateCurrentPage(self):
if self.currentId() == 0:
- if self.importRadioButton.checkState() == Qt.Unchecked() and self.createNewRadioButton.checkState() == Qt.Unchecked() and self.installRadioButton.checkState() == Qt.Unchecked():
- errorMsg = self.tr('An option must be chosen!\n')
- QMessageBox.warning(self, self.tr('Error!'), errorMsg)
+ if (
+ self.importRadioButton.checkState() == Qt.Unchecked()
+ and self.createNewRadioButton.checkState() == Qt.Unchecked()
+ and self.installRadioButton.checkState() == Qt.Unchecked()
+ ):
+ errorMsg = self.tr("An option must be chosen!\n")
+ QMessageBox.warning(self, self.tr("Error!"), errorMsg)
return False
if self.installRadioButton.checkState() == Qt.Checked():
if self.settingComboBox.currentIndex() == 0:
- errorMsg = self.tr('A setting must be chosen!\n')
- QMessageBox.warning(self, self.tr('Error!'), errorMsg)
+ errorMsg = self.tr("A setting must be chosen!\n")
+ QMessageBox.warning(self, self.tr("Error!"), errorMsg)
return False
else:
return True
return True
else:
- return True
\ No newline at end of file
+ return True
diff --git a/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py b/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py
index e5d0aac27..b1ca9de39 100644
--- a/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py
+++ b/DsgTools/gui/CustomWidgets/SelectionWidgets/tabDbSelectorWidget.py
@@ -28,14 +28,15 @@
from qgis.PyQt.QtWidgets import QMessageBox
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "tabDbSelectorWidget.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'tabDbSelectorWidget.ui'))
class TabDbSelectorWidget(QtWidgets.QWidget, FORM_CLASS):
- selectionChanged = pyqtSignal(list,str)
+ selectionChanged = pyqtSignal(list, str)
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
# Set up the user interface from Designer.
@@ -50,16 +51,20 @@ def __init__(self, parent = None):
def setSpatiaLitePage(self):
"""
- By default, select files comes "clean", this method adapts it for SpatiaLite databases.
+ By default, select files comes "clean", this method adapts it for SpatiaLite databases.
"""
- self.outputDirSelector.setCaption(self.tr("Select a path to save the SpatiaLite database"))
+ self.outputDirSelector.setCaption(
+ self.tr("Select a path to save the SpatiaLite database")
+ )
self.outputDirSelector.setType("dir")
def setGeopackagePage(self):
"""
- By default, select files comes "clean", this method adapts it for Geopackage databases.
+ By default, select files comes "clean", this method adapts it for Geopackage databases.
"""
- self.outputDirSelectorGeopackage.setCaption(self.tr("Select a path to save the Geopackage database"))
+ self.outputDirSelectorGeopackage.setCaption(
+ self.tr("Select a path to save the Geopackage database")
+ )
self.outputDirSelectorGeopackage.setType("dir")
@pyqtSlot(int)
@@ -77,13 +82,17 @@ def validate(self):
"""
if self.tabWidget.currentIndex() == 0:
if self.serverWidget.serversCombo.currentIndex() == 0:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('Select a server!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("Select a server!")
+ )
return False
else:
return True
elif self.tabWidget.currentIndex() == 1:
if self.outputDirSelector.fileNameList == []:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('Select a folder!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("Select a folder!")
+ )
return False
else:
return True
@@ -93,27 +102,33 @@ def validate(self):
# return False
# else:
# return True
-
+
def getFactoryCreationParam(self):
"""
Adjusts the database selection according to the database type
"""
- if self.tabWidget.currentIndex() == 0 and self.serverWidget.serversCombo.currentIndex() > 0:
- return self.serverWidget.abstractDb
- elif self.tabWidget.currentIndex() == 1 and self.outputDirSelector.fileNameList != []:
+ if (
+ self.tabWidget.currentIndex() == 0
+ and self.serverWidget.serversCombo.currentIndex() > 0
+ ):
+ return self.serverWidget.abstractDb
+ elif (
+ self.tabWidget.currentIndex() == 1
+ and self.outputDirSelector.fileNameList != []
+ ):
return self.outputDirSelector.fileNameList[0]
# elif self.tabWidget.currentIndex() == 2 and self.outputDirSelectorGeopackage.fileNameList != []:
# return self.outputDirSelectorGeopackage.fileNameList[0]
else:
return None
-
+
def getType(self):
"""
gets database type (QPSQL, QSQLITE, GPKG)
"""
if self.tabWidget.currentIndex() == 0:
- return 'QPSQL'
+ return "QPSQL"
elif self.tabWidget.currentIndex() == 1:
- return 'QSQLITE'
+ return "QSQLITE"
# elif self.tabWidget.currentIndex() == 2:
- # return 'GPKG'
\ No newline at end of file
+ # return 'GPKG'
diff --git a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py
index b2ffa41a8..2c992b9e1 100644
--- a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py
+++ b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationProcessWidget.py
@@ -28,39 +28,47 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'validationProcessWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "validationProcessWidget.ui")
+)
+
class ValidationProcessWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, parameterDict = {}, parent = None):
+ def __init__(self, parameterDict={}, parent=None):
"""Constructor."""
- super(ValidationProcessWidget, self).__init__(parent = parent)
+ super(ValidationProcessWidget, self).__init__(parent=parent)
self.setupUi(self)
self.parent = parent
if self.parent:
self.validationManager = parent.validationManager
- self.validKeys = ['halt', 'validationProcess']
+ self.validKeys = ["halt", "validationProcess"]
self.parameters = None
self.setInitialState()
if parameterDict != {}:
self.populateInterface(parameterDict)
-
+
def setInitialState(self):
self.validationProcessComboBox.clear()
- self.validationProcessComboBox.addItem(self.tr('Select a model'))
+ self.validationProcessComboBox.addItem(self.tr("Select a model"))
for model in self.validationManager.modelList:
self.validationProcessComboBox.addItem(model.displayName())
-
+
def clearAll(self):
"""
Clears all widget information
"""
pass
-
+
def getParameterDict(self):
"""
Components:
@@ -70,7 +78,9 @@ def getParameterDict(self):
if not self.validate():
raise Exception(self.invalidatedReason())
parameterDict = dict()
- parameterDict['validationProcess'] = self.validationProcessComboBox.currentText()
+ parameterDict[
+ "validationProcess"
+ ] = self.validationProcessComboBox.currentText()
return parameterDict
def populateInterface(self, parameterDict):
@@ -79,10 +89,12 @@ def populateInterface(self, parameterDict):
"""
if parameterDict:
if not self.validateJson(parameterDict):
- raise Exception(self.tr('Invalid Validation Process Widget json config!'))
- #set layer combo
- self.validationProcessComboBox.setText(parameterDict['validationProcess'])
-
+ raise Exception(
+ self.tr("Invalid Validation Process Widget json config!")
+ )
+ # set layer combo
+ self.validationProcessComboBox.setText(parameterDict["validationProcess"])
+
def validateJson(self, inputJson):
"""
Validates input json
@@ -98,15 +110,15 @@ def validate(self):
"""
Validates fields. Returns True if all information are filled correctly.
"""
- if self.attributeRuleTypeLineEdit.text() == '':
+ if self.attributeRuleTypeLineEdit.text() == "":
return False
return True
-
+
def invalidatedReason(self):
"""
Error reason
"""
- msg = ''
- if self.attributeRuleTypeLineEdit.text() == '':
- msg += self.tr('Invalid rule name!\n')
- return msg
\ No newline at end of file
+ msg = ""
+ if self.attributeRuleTypeLineEdit.text() == "":
+ msg += self.tr("Invalid rule name!\n")
+ return msg
diff --git a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py
index 7739ff2b4..da4692c4e 100644
--- a/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py
+++ b/DsgTools/gui/CustomWidgets/ValidationWidgets/validationWorkflowItemWidget.py
@@ -30,31 +30,39 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'validationWorkflowItemWidget.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "validationWorkflowItemWidget.ui")
+)
+
class ValidationWorkflowItemWidget(QtWidgets.QWidget, FORM_CLASS):
- def __init__(self, parameterDict = {}, parent = None):
+ def __init__(self, parameterDict={}, parent=None):
"""Constructor."""
- super(ValidationWorkflowItemWidget, self).__init__(parent = parent)
+ super(ValidationWorkflowItemWidget, self).__init__(parent=parent)
self.setupUi(self)
- self.validKeys = ['name', 'validationProcessList']
+ self.validKeys = ["name", "validationProcessList"]
self.parent = parent
if self.parent:
self.validationManager = parent.validationManager
if parameterDict != {}:
self.populateInterface(parameterDict)
-
+
def clearAll(self):
"""
Clears all widget information
"""
pass
-
+
def getParameterDict(self):
"""
Components:
@@ -66,8 +74,10 @@ def getParameterDict(self):
if not self.validate():
raise Exception(self.invalidatedReason())
parameterDict = dict()
- parameterDict['attributeRuleType'] = self.attributeRuleTypeLineEdit.text()
- parameterDict['ruleColor'] = ','.join(map(str,self.mColorButton.color().getRgb()))
+ parameterDict["attributeRuleType"] = self.attributeRuleTypeLineEdit.text()
+ parameterDict["ruleColor"] = ",".join(
+ map(str, self.mColorButton.color().getRgb())
+ )
return parameterDict
def populateInterface(self, parameterDict):
@@ -76,12 +86,16 @@ def populateInterface(self, parameterDict):
"""
if parameterDict:
if not self.validateJson(parameterDict):
- raise Exception(self.tr('Invalid Attribute Rule Type Widget json config!'))
- #set layer combo
- self.attributeRuleTypeLineEdit.setText(parameterDict['attributeRuleType'])
- R,G,B,A = list(map(int,parameterDict['ruleColor'].split(','))) #QColor only accepts int values
- self.mColorButton.setColor(QColor(R,G,B,A))
-
+ raise Exception(
+ self.tr("Invalid Attribute Rule Type Widget json config!")
+ )
+ # set layer combo
+ self.attributeRuleTypeLineEdit.setText(parameterDict["attributeRuleType"])
+ R, G, B, A = list(
+ map(int, parameterDict["ruleColor"].split(","))
+ ) # QColor only accepts int values
+ self.mColorButton.setColor(QColor(R, G, B, A))
+
def validateJson(self, inputJson):
"""
Validates input json
@@ -97,24 +111,24 @@ def validate(self):
"""
Validates fields. Returns True if all information are filled correctly.
"""
- if self.attributeRuleTypeLineEdit.text() == '':
+ if self.attributeRuleTypeLineEdit.text() == "":
return False
return True
-
+
def invalidatedReason(self):
"""
Error reason
"""
- msg = ''
- if self.attributeRuleTypeLineEdit.text() == '':
- msg += self.tr('Invalid rule name!\n')
+ msg = ""
+ if self.attributeRuleTypeLineEdit.text() == "":
+ msg += self.tr("Invalid rule name!\n")
return msg
-
+
@pyqtSlot(bool)
def on_mGroupBox_collapsedStateChanged(self):
for i in range(self.parent.tableWidget.rowCount()):
self.parent.tableWidget.resizeRowToContents(i)
-
+
@pyqtSlot(str)
def on_workspaceItemLineEdit_textEdited(self, text):
- self.mGroupBox.setTitle(text)
\ No newline at end of file
+ self.mGroupBox.setTitle(text)
diff --git a/DsgTools/gui/CustomWidgets/customRasterToolTip.py b/DsgTools/gui/CustomWidgets/customRasterToolTip.py
index d930ca57e..63fb8a778 100644
--- a/DsgTools/gui/CustomWidgets/customRasterToolTip.py
+++ b/DsgTools/gui/CustomWidgets/customRasterToolTip.py
@@ -25,8 +25,10 @@
from qgis.PyQt import QtWidgets, uic
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'createDatabaseCustomization.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "createDatabaseCustomization.ui")
+)
+
class CreateDatabaseCustomization(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, iface):
@@ -35,4 +37,4 @@ def __init__(self, iface):
self.setupUi(self)
def setToolUse(self, enabled):
- self.toolCheckBox.setEnabled(enabled)
\ No newline at end of file
+ self.toolCheckBox.setEnabled(enabled)
diff --git a/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py b/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py
index b4cfe0a61..b06d84784 100644
--- a/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py
+++ b/DsgTools/gui/DatabaseTools/ConversionTools/datasourceConversion.py
@@ -31,18 +31,26 @@
from qgis.core import Qgis, QgsApplication, QgsMessageLog, Qgis
from qgis.gui import QgsCollapsibleGroupBox, QgsMessageBar
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import GenericDialogLayout
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.textBrowserDialog import TextBrowserDialog
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.genericDialogLayout import (
+ GenericDialogLayout,
+)
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.textBrowserDialog import (
+ TextBrowserDialog,
+)
from DsgTools.core.DbTools.dbConverter import DbConverter
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'datasourceConversion.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "datasourceConversion.ui")
+)
+
class DatasourceConversion(QtWidgets.QWizard, FORM_CLASS):
# enum for column ordering
COLUMN_COUNT = 7
# InDs, Filter, SpatialFilterFanOut, InEdgv, OutDs, OutEdgv, outCrs, ConversionMode = list(range(COLUMN_COUNT))
- InDs, Filter, InEdgv, OutDs, OutEdgv, outCrs, ConversionMode = list(range(COLUMN_COUNT))
+ InDs, Filter, InEdgv, OutDs, OutEdgv, outCrs, ConversionMode = list(
+ range(COLUMN_COUNT)
+ )
def __init__(self, manager, parentMenu, parentButton, parent=None):
"""
@@ -61,48 +69,82 @@ def __init__(self, manager, parentMenu, parentButton, parent=None):
self.datasourceManagementWidgetOut.fillSupportedDatasources(inputPage=False)
self.connectToolSignals()
# initiate widget dicts
- self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers)
- self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers)
+ self.outDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetOut.activeDrivers
+ )
+ self.inDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetIn.activeDrivers
+ )
# set table to its initial state
self.resetTable(enabled=True)
# set pages titles
- self.page(0).setTitle(self.tr('Input Datasources'))
- self.page(1).setTitle(self.tr('Output Datasources'))
- self.page(2).setTitle(self.tr('Conversion Map and Summary'))
+ self.page(0).setTitle(self.tr("Input Datasources"))
+ self.page(1).setTitle(self.tr("Output Datasources"))
+ self.page(2).setTitle(self.tr("Conversion Map and Summary"))
# set policy to make cell size adjust to content
- self.tableWidget.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
-
+ self.tableWidget.setSizeAdjustPolicy(
+ QtWidgets.QAbstractScrollArea.AdjustToContents
+ )
+
def connectToolSignals(self):
"""
Connects all tool generic signals.
"""
# if any widget was turned active/inactive
- self.datasourceManagementWidgetIn.activeWidgetAdded.connect(self.addInputDatasource)
- self.datasourceManagementWidgetOut.activeWidgetAdded.connect(self.addOutputDatasource)
- self.datasourceManagementWidgetIn.activeWidgetRemoved.connect(self.removeInputDatasource)
- self.datasourceManagementWidgetOut.activeWidgetRemoved.connect(self.removeOutputDatasource)
+ self.datasourceManagementWidgetIn.activeWidgetAdded.connect(
+ self.addInputDatasource
+ )
+ self.datasourceManagementWidgetOut.activeWidgetAdded.connect(
+ self.addOutputDatasource
+ )
+ self.datasourceManagementWidgetIn.activeWidgetRemoved.connect(
+ self.removeInputDatasource
+ )
+ self.datasourceManagementWidgetOut.activeWidgetRemoved.connect(
+ self.removeOutputDatasource
+ )
# if datasource is changed (e.g. user changed his postgis database selection, for instance)
- self.datasourceManagementWidgetIn.widgetUpdated.connect(self.updateInputInformation)
- self.datasourceManagementWidgetOut.widgetUpdated.connect(self.updateOutputInformation)
+ self.datasourceManagementWidgetIn.widgetUpdated.connect(
+ self.updateInputInformation
+ )
+ self.datasourceManagementWidgetOut.widgetUpdated.connect(
+ self.updateOutputInformation
+ )
# erase all options settled
self.refreshPushButton.clicked.connect(self.setTableInitialState)
# conversion mapping start
- self.button(QtWidgets.QWizard.FinishButton).clicked.connect(self.startConversion)
+ self.button(QtWidgets.QWizard.FinishButton).clicked.connect(
+ self.startConversion
+ )
def disconnectToolSignals(self):
"""
Connects all tool generic signals.
"""
# if any widget was turned active/inactive
- self.datasourceManagementWidgetIn.activeWidgetAdded.disconnect(self.addInputDatasource)
- self.datasourceManagementWidgetOut.activeWidgetAdded.disconnect(self.addOutputDatasource)
- self.datasourceManagementWidgetIn.activeWidgetRemoved.disconnect(self.removeInputDatasource)
- self.datasourceManagementWidgetOut.activeWidgetRemoved.disconnect(self.removeOutputDatasource)
+ self.datasourceManagementWidgetIn.activeWidgetAdded.disconnect(
+ self.addInputDatasource
+ )
+ self.datasourceManagementWidgetOut.activeWidgetAdded.disconnect(
+ self.addOutputDatasource
+ )
+ self.datasourceManagementWidgetIn.activeWidgetRemoved.disconnect(
+ self.removeInputDatasource
+ )
+ self.datasourceManagementWidgetOut.activeWidgetRemoved.disconnect(
+ self.removeOutputDatasource
+ )
# if datasource is changed (e.g. user changed his postgis database selection, for instance)
- self.datasourceManagementWidgetIn.widgetUpdated.disconnect(self.updateInputInformation)
- self.datasourceManagementWidgetOut.widgetUpdated.disconnect(self.updateOutputInformation)
+ self.datasourceManagementWidgetIn.widgetUpdated.disconnect(
+ self.updateInputInformation
+ )
+ self.datasourceManagementWidgetOut.widgetUpdated.disconnect(
+ self.updateOutputInformation
+ )
self.refreshPushButton.clicked.disconnect(self.setTableInitialState)
- self.button(QtWidgets.QWizard.FinishButton).clicked.disconnect(self.startConversion)
+ self.button(QtWidgets.QWizard.FinishButton).clicked.disconnect(
+ self.startConversion
+ )
def getWidgetNameDict(self, d):
"""
@@ -121,7 +163,10 @@ def replicateFirstRowContent(self, col):
Replicates first row value to all the other rows from a selected column.
:param col: (int) column to have its first row replicated.
"""
- if col in [DatasourceConversion.OutDs, DatasourceConversion.ConversionMode]: #, DatasourceConversion.SpatialFilterFanOut]:
+ if col in [
+ DatasourceConversion.OutDs,
+ DatasourceConversion.ConversionMode,
+ ]: # , DatasourceConversion.SpatialFilterFanOut]:
value = None
for row in range(self.tableWidget.rowCount()):
widget = self.getRowContents(row=row)[col]
@@ -155,19 +200,23 @@ def resetTable(self, enabled=False):
self.tableWidget.setRowCount(0)
# map header to its enum
headerDict = {
- DatasourceConversion.InDs : self.tr("Input"),
- DatasourceConversion.Filter : self.tr("Filters"),
+ DatasourceConversion.InDs: self.tr("Input"),
+ DatasourceConversion.Filter: self.tr("Filters"),
# DatasourceConversion.SpatialFilterFanOut : self.tr("Spatial Fan-out"),
- DatasourceConversion.InEdgv : self.tr("In: EDGV Version"),
- DatasourceConversion.OutDs : self.tr("Output"),
- DatasourceConversion.outCrs : self.tr("Out: CRS"),
- DatasourceConversion.OutEdgv : self.tr("Out: EDGV Version"),
- DatasourceConversion.ConversionMode : self.tr("Conversion Mode")
+ DatasourceConversion.InEdgv: self.tr("In: EDGV Version"),
+ DatasourceConversion.OutDs: self.tr("Output"),
+ DatasourceConversion.outCrs: self.tr("Out: CRS"),
+ DatasourceConversion.OutEdgv: self.tr("Out: EDGV Version"),
+ DatasourceConversion.ConversionMode: self.tr("Conversion Mode"),
}
# make the order always follow as presented at enum
- self.tableWidget.setHorizontalHeaderLabels(list([headerDict[i] for i in range(DatasourceConversion.COLUMN_COUNT)]))
+ self.tableWidget.setHorizontalHeaderLabels(
+ list([headerDict[i] for i in range(DatasourceConversion.COLUMN_COUNT)])
+ )
# connect header double click signal to first row contents replicate to the other rows
- self.tableWidget.horizontalHeader().sectionDoubleClicked.connect(self.replicateFirstRowContent)
+ self.tableWidget.horizontalHeader().sectionDoubleClicked.connect(
+ self.replicateFirstRowContent
+ )
def addInputDatasource(self, containerWidget, resizeColumns=True):
"""
@@ -175,26 +224,43 @@ def addInputDatasource(self, containerWidget, resizeColumns=True):
:param containerWidget:
:param resizeColumns: (bool)
"""
- self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers)
+ self.inDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetIn.activeDrivers
+ )
# create a 'function' to get datasource exposing name and create the output list
- getNameAlias = lambda widget : '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName())
+ getNameAlias = lambda widget: "{0}: {1}".format(
+ widget.groupBox.title(), widget.getDatasourceConnectionName()
+ )
# use it in a map loop to get output list
- outDsList = [self.tr('Select a datasource')] + sorted(list(map(getNameAlias, self.outDs.values())))
+ outDsList = [self.tr("Select a datasource")] + sorted(
+ list(map(getNameAlias, self.outDs.values()))
+ )
# update table rows #
lastRow = self.tableWidget.rowCount()
self.tableWidget.insertRow(lastRow)
# crsIcon = QIcon(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'icons', 'CRS_qgis.svg'))
# create the item containing current loop's input ds
- t = '{0}: {1}'.format(containerWidget.groupBox.title(), containerWidget.getDatasourceConnectionName())
- self.addItemToTable(col=DatasourceConversion.InDs, row=lastRow, text=t, isEditable=False)
+ t = "{0}: {1}".format(
+ containerWidget.groupBox.title(),
+ containerWidget.getDatasourceConnectionName(),
+ )
+ self.addItemToTable(
+ col=DatasourceConversion.InDs, row=lastRow, text=t, isEditable=False
+ )
# populate edgv versions column
# input is always text
t = containerWidget.connectionWidget.getDatasourceEdgvVersion()
- self.addItemToTable(col=DatasourceConversion.InEdgv, row=lastRow, text=t, isEditable=False)
+ self.addItemToTable(
+ col=DatasourceConversion.InEdgv, row=lastRow, text=t, isEditable=False
+ )
# create filter push button
filterPushButton = QtWidgets.QPushButton()
filterPushButton.setIcon(
- QIcon(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'icons', 'filter.png'))
+ QIcon(
+ os.path.join(
+ os.path.dirname(__file__), "..", "..", "..", "icons", "filter.png"
+ )
+ )
)
# # create push button
# fanOutCheckBox = QtWidgets.QCheckBox()
@@ -207,18 +273,32 @@ def addInputDatasource(self, containerWidget, resizeColumns=True):
outDsComboBox.addItems(outDsList)
# create combobox containing conversion mode options
convModeComboBox = QtWidgets.QComboBox()
- convModeComboBox.addItems([
- self.tr('Choose Conversion Mode'), self.tr('Flexible Conversion'), self.tr('Strict Conversion')
- ])
+ convModeComboBox.addItems(
+ [
+ self.tr("Choose Conversion Mode"),
+ self.tr("Flexible Conversion"),
+ self.tr("Strict Conversion"),
+ ]
+ )
# set each widget to their column
- self.tableWidget.setCellWidget(lastRow, DatasourceConversion.OutDs, outDsComboBox)
- self.tableWidget.setCellWidget(lastRow, DatasourceConversion.Filter, filterPushButton)
+ self.tableWidget.setCellWidget(
+ lastRow, DatasourceConversion.OutDs, outDsComboBox
+ )
+ self.tableWidget.setCellWidget(
+ lastRow, DatasourceConversion.Filter, filterPushButton
+ )
# self.tableWidget.setCellWidget(lastRow, DatasourceConversion.SpatialFilterFanOut, fanOutCheckBox)
- self.tableWidget.setCellWidget(lastRow, DatasourceConversion.ConversionMode, convModeComboBox)
+ self.tableWidget.setCellWidget(
+ lastRow, DatasourceConversion.ConversionMode, convModeComboBox
+ )
# start filter widget
- filterPushButton.clicked.connect(partial(self.prepareRowFilterDialog, container=containerWidget))
+ filterPushButton.clicked.connect(
+ partial(self.prepareRowFilterDialog, container=containerWidget)
+ )
# set table output information population to its widget
- outDsComboBox.currentIndexChanged.connect(partial(self.fillOutDsInfoRow, row=lastRow))
+ outDsComboBox.currentIndexChanged.connect(
+ partial(self.fillOutDsInfoRow, row=lastRow)
+ )
if resizeColumns:
# resize to contents
self.tableWidget.resizeColumnsToContents()
@@ -226,42 +306,59 @@ def addInputDatasource(self, containerWidget, resizeColumns=True):
def removeInputDatasource(self, containerWidget):
"""
Removes the map table row containing a given input information.
- :param containerWidget: (DatasourceContainerWidget) input container widget.
+ :param containerWidget: (DatasourceContainerWidget) input container widget.
"""
row, _ = self.getInputDatasourceRow(inputDatasourceWidget=containerWidget)
self.tableWidget.removeRow(row)
# after the row is removed, it is also necessary to update datasources names, given that group boxes were renamed
for row in range(self.tableWidget.rowCount()):
inDs = self.getRowContents(row=row)[DatasourceConversion.InDs]
- widget = self.inDs[inDs.split(':')[0]]
- t = '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName())
- self.addItemToTable(col=DatasourceConversion.InDs, row=row, text=t, isEditable=False)
+ widget = self.inDs[inDs.split(":")[0]]
+ t = "{0}: {1}".format(
+ widget.groupBox.title(), widget.getDatasourceConnectionName()
+ )
+ self.addItemToTable(
+ col=DatasourceConversion.InDs, row=row, text=t, isEditable=False
+ )
# update input map - if map was updated before it would not be possible to retrieve widget (name changed)
- self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers)
+ self.inDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetIn.activeDrivers
+ )
def addOutputDatasource(self, containerWidget):
"""
Updates datasource options for every row in table widget.
- :param containerWidget: (DatasourceContainerWidget) output container widget.
+ :param containerWidget: (DatasourceContainerWidget) output container widget.
"""
# update output map
- self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers)
+ self.outDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetOut.activeDrivers
+ )
# get new datasource info
- dsName = '{0}: {1}'.format(containerWidget.groupBox.title(), containerWidget.getDatasourceConnectionName())
+ dsName = "{0}: {1}".format(
+ containerWidget.groupBox.title(),
+ containerWidget.getDatasourceConnectionName(),
+ )
for row in range(self.tableWidget.rowCount()):
outCombobox = self.getRowContents(row=row)[DatasourceConversion.OutDs]
outCombobox.addItem(dsName)
def removeOutputDatasource(self, containerWidget):
"""
- Removes output option from evey row in table widget.
- :param containerWidget: (DatasourceContainerWidget) output container widget.
+ Removes output option from evey row in table widget.
+ :param containerWidget: (DatasourceContainerWidget) output container widget.
"""
# update output map
- self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers)
+ self.outDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetOut.activeDrivers
+ )
# get new datasource info
- getNewDsNames = lambda widget : '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName())
- newDsNames = [self.tr('Select a datasource')] + sorted(list(map(getNewDsNames, self.outDs.values())))
+ getNewDsNames = lambda widget: "{0}: {1}".format(
+ widget.groupBox.title(), widget.getDatasourceConnectionName()
+ )
+ newDsNames = [self.tr("Select a datasource")] + sorted(
+ list(map(getNewDsNames, self.outDs.values()))
+ )
groupTitle = containerWidget.groupBox.title()
# initiate its index
dsIdx = None
@@ -271,7 +368,7 @@ def removeOutputDatasource(self, containerWidget):
# retrieve replaced datasource old index
if dsIdx is None:
# retrive old name
- oldName = ''
+ oldName = ""
for i in range(outDsCombobox.count()):
if groupTitle in outDsCombobox.itemText(i):
oldName = outDsCombobox.itemText(i)
@@ -299,29 +396,42 @@ def removeOutputDatasource(self, containerWidget):
def updateInputInformation(self, containerWidget):
"""
Updates input information.
- :param containerWidget: (DatasourceContainerWidget) input container widget.
+ :param containerWidget: (DatasourceContainerWidget) input container widget.
"""
# update input map
- self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers)
+ self.inDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetIn.activeDrivers
+ )
# get input row
row, _ = self.getInputDatasourceRow(inputDatasourceWidget=containerWidget)
# get new datasource info
- dsName = '{0}: {1}'.format(containerWidget.groupBox.title(), containerWidget.getDatasourceConnectionName())
+ dsName = "{0}: {1}".format(
+ containerWidget.groupBox.title(),
+ containerWidget.getDatasourceConnectionName(),
+ )
inEdgv = containerWidget.connectionWidget.getDatasourceEdgvVersion()
# update edgv and input name
- self.addItemToTable(col=DatasourceConversion.InDs, row=row, text=dsName, isEditable=False)
- self.addItemToTable(col=DatasourceConversion.InEdgv, row=row, text=inEdgv, isEditable=False)
+ self.addItemToTable(
+ col=DatasourceConversion.InDs, row=row, text=dsName, isEditable=False
+ )
+ self.addItemToTable(
+ col=DatasourceConversion.InEdgv, row=row, text=inEdgv, isEditable=False
+ )
def updateOutputInformation(self, containerWidget):
"""
Updates input information.
- :param containerWidget: (DatasourceContainerWidget) output container widget.
+ :param containerWidget: (DatasourceContainerWidget) output container widget.
"""
# update output map
- self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers)
+ self.outDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetOut.activeDrivers
+ )
# get new datasource info
groupTitle = containerWidget.groupBox.title()
- dsName = '{0}: {1}'.format(groupTitle, containerWidget.getDatasourceConnectionName())
+ dsName = "{0}: {1}".format(
+ groupTitle, containerWidget.getDatasourceConnectionName()
+ )
outEdgv = containerWidget.connectionWidget.getDatasourceEdgvVersion()
# initiate its index
dsIdx = None
@@ -331,7 +441,7 @@ def updateOutputInformation(self, containerWidget):
# retrieve replaced datasource old index
if dsIdx is None:
# retrive old name
- oldName = ''
+ oldName = ""
for i in range(outDsCombobox.count()):
if groupTitle in outDsCombobox.itemText(i):
oldName = outDsCombobox.itemText(i)
@@ -356,8 +466,10 @@ def getRowContents(self, row):
inDs = self.tableWidget.item(row, DatasourceConversion.InDs).text()
inEdgv = self.tableWidget.item(row, DatasourceConversion.InEdgv).text()
outEdgvItem = self.tableWidget.item(row, DatasourceConversion.OutEdgv)
- outEdgv = outEdgvItem.text() if outEdgvItem else ''
- conversionMode = self.tableWidget.cellWidget(row, DatasourceConversion.ConversionMode)
+ outEdgv = outEdgvItem.text() if outEdgvItem else ""
+ conversionMode = self.tableWidget.cellWidget(
+ row, DatasourceConversion.ConversionMode
+ )
# output datasource, input and output SRC and filter status are always a QWidget
outDs = self.tableWidget.cellWidget(row, DatasourceConversion.OutDs)
# however, output info might not yet have been filled
@@ -386,13 +498,28 @@ def getInputDatasourceRow(self, inputDatasourceWidget):
inputText = inputDatasourceWidget.groupBox.title()
for row in range(self.tableWidget.rowCount()):
# inDs, _filter, spatialFanOut, inEdgv, outDs, outEdgv, outCrs, conversionMode = self.getRowContents(row=row)
- inDs, _filter, inEdgv, outDs, outEdgv, outCrs, conversionMode = self.getRowContents(row=row)
+ (
+ inDs,
+ _filter,
+ inEdgv,
+ outDs,
+ outEdgv,
+ outCrs,
+ conversionMode,
+ ) = self.getRowContents(row=row)
if inputText in inDs:
# return row, [inDs, _filter, spatialFanOut, inEdgv, outDs, outEdgv, outCrs, conversionMode]
- return row, [inDs, _filter, inEdgv, outDs, outEdgv, outCrs, conversionMode]
+ return row, [
+ inDs,
+ _filter,
+ inEdgv,
+ outDs,
+ outEdgv,
+ outCrs,
+ conversionMode,
+ ]
return -1, []
-
def clearOutDsInforRow(self, row):
"""
Clears output information for a given row.
@@ -406,7 +533,7 @@ def clearOutDsInforRow(self, row):
def fillOutDsInfoRow(self, row):
"""
- Fills out row with output info for each output column. In here, ouput SRC and EDGV are filled.
+ Fills out row with output info for each output column. In here, ouput SRC and EDGV are filled.
:param row: (int) row index to have its output columns populated.
:return: (list-of-object) return a list containing (str) output EDGV version and (QPushButton) output SRC.
"""
@@ -419,8 +546,12 @@ def fillOutDsInfoRow(self, row):
outDs = self.getRowContents(row=row)[DatasourceConversion.OutDs]
# widget dict keys are defined as group title, which is part of outDs current text
if outDs:
- groupTitle = outDs.currentText().split(':')[0]
- crsIcon = QIcon(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'icons', 'CRS_qgis.svg'))
+ groupTitle = outDs.currentText().split(":")[0]
+ crsIcon = QIcon(
+ os.path.join(
+ os.path.dirname(__file__), "..", "..", "..", "icons", "CRS_qgis.svg"
+ )
+ )
else:
return []
if groupTitle in self.outDs:
@@ -431,10 +562,10 @@ def fillOutDsInfoRow(self, row):
outCrs.setIcon(crsIcon)
# get new text item to add output datasource
edgvOut = containerWidget.connectionWidget.getDatasourceEdgvVersion()
- edgvOut = edgvOut[5:] if 'EDGV' in edgvOut else edgvOut
+ edgvOut = edgvOut[5:] if "EDGV" in edgvOut else edgvOut
itemEdgvOut = QtWidgets.QTableWidgetItem()
itemEdgvOut.setText(edgvOut)
- itemEdgvOut.setFlags(Qt.ItemIsEditable) # not editable
+ itemEdgvOut.setFlags(Qt.ItemIsEditable) # not editable
# add both to table
self.tableWidget.setCellWidget(row, DatasourceConversion.outCrs, outCrs)
self.tableWidget.setItem(row, DatasourceConversion.OutEdgv, itemEdgvOut)
@@ -443,7 +574,7 @@ def fillOutDsInfoRow(self, row):
# if is not controlled, clear line
return []
- def getNewTableItem(self, text='', isEditable=True):
+ def getNewTableItem(self, text="", isEditable=True):
"""
Gets an item to be added to the table that may be set to not be editable.
:param text: (str) name to be exposed on table cell.
@@ -453,10 +584,10 @@ def getNewTableItem(self, text='', isEditable=True):
item = QtWidgets.QTableWidgetItem()
item.setText(text)
if not isEditable:
- item.setFlags(Qt.ItemIsEditable) # not editable
+ item.setFlags(Qt.ItemIsEditable) # not editable
return item
- def addItemToTable(self, col, row, text='', isEditable=True):
+ def addItemToTable(self, col, row, text="", isEditable=True):
"""
Adds an item to the mapping table into a given column and row.
:param col: (int) column containing new item.
@@ -491,14 +622,24 @@ def setTableInitialState(self):
"""
self.resetTable(enabled=True)
# output ds dict/list
- self.outDs = self.getWidgetNameDict(self.datasourceManagementWidgetOut.activeDrivers)
+ self.outDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetOut.activeDrivers
+ )
# create a 'function' to get datasource exposing name and create the output list
- getNameAlias = lambda widget : '{0}: {1}'.format(widget.groupBox.title(), widget.getDatasourceConnectionName())
- outDsList = [self.tr('Select a datasource')] + sorted(list(map(getNameAlias, self.outDs.values())))
+ getNameAlias = lambda widget: "{0}: {1}".format(
+ widget.groupBox.title(), widget.getDatasourceConnectionName()
+ )
+ outDsList = [self.tr("Select a datasource")] + sorted(
+ list(map(getNameAlias, self.outDs.values()))
+ )
# input ds dict/list
- self.inDs = self.getWidgetNameDict(self.datasourceManagementWidgetIn.activeDrivers)
+ self.inDs = self.getWidgetNameDict(
+ self.datasourceManagementWidgetIn.activeDrivers
+ )
for groupTitle in sorted(self.inDs.keys()):
- self.addInputDatasource(containerWidget=self.inDs[groupTitle], resizeColumns=False)
+ self.addInputDatasource(
+ containerWidget=self.inDs[groupTitle], resizeColumns=False
+ )
self.tableWidget.resizeColumnsToContents()
def getConversionMap(self):
@@ -516,23 +657,35 @@ def getConversionMap(self):
# initiate this row's mapping dict and fill it
rowMapping = dict()
# get input information to be mapped - input datasource identification and filtering options
- containerWidget = self.inDs[inDs.split(':')[0]] # input group box title (widget's dict key)
- inputDatasourceId = containerWidget.connectionWidget.getDatasourcePath()
+ containerWidget = self.inDs[
+ inDs.split(":")[0]
+ ] # input group box title (widget's dict key)
+ inputDatasourceId = containerWidget.connectionWidget.getDatasourcePath()
inputFilteredLayers = containerWidget.filters()
# get output information to be mapped - output datasource identification and if it's
- containerWidget = self.outDs[outDs.currentText().split(':')[0]] # output group box title (widget's dict key)
+ containerWidget = self.outDs[
+ outDs.currentText().split(":")[0]
+ ] # output group box title (widget's dict key)
# populate row's conversion map
- rowMapping['outDs'] = containerWidget.connectionWidget.getDatasourcePath(), # still to decide what to fill up in here
- rowMapping['outDs'] = rowMapping['outDs'][-1] # I DON'T KNOW WHY, BUT THAT'S THE ONLY WAY THIS COMES OUT AS A TUPLE.
- rowMapping['filter'] = inputFilteredLayers
+ rowMapping["outDs"] = (
+ containerWidget.connectionWidget.getDatasourcePath(),
+ ) # still to decide what to fill up in here
+ rowMapping["outDs"] = rowMapping["outDs"][
+ -1
+ ] # I DON'T KNOW WHY, BUT THAT'S THE ONLY WAY THIS COMES OUT AS A TUPLE.
+ rowMapping["filter"] = inputFilteredLayers
# rowMapping['spatialFanOut'] = spatialFanOut.isChecked()
# parameter indicating whether it is a new datasource
- rowMapping['createDs'] = self.tr('new') in outDs.currentText().split(':')[0]
- if self.tr('new') in outDs.currentText().split(':')[0]:
+ rowMapping["createDs"] = self.tr("new") in outDs.currentText().split(":")[0]
+ if self.tr("new") in outDs.currentText().split(":")[0]:
# if a new datasource will be created, EDGV version and CRS will be needed
- rowMapping['edgv'] = containerWidget.connectionWidget.selectionWidget.edgvVersion()
- rowMapping['crs'] = containerWidget.connectionWidget.selectionWidget.authId()
- rowMapping['conversionMode'] = conversionMode.currentIndex()
+ rowMapping[
+ "edgv"
+ ] = containerWidget.connectionWidget.selectionWidget.edgvVersion()
+ rowMapping[
+ "crs"
+ ] = containerWidget.connectionWidget.selectionWidget.authId()
+ rowMapping["conversionMode"] = conversionMode.currentIndex()
# it is possible for the same dataset to be chosen for different outputs, in order to prevent instantiating it
# more than once, map it all to the same dict entry and control layer/feature flux through filter entry
if inputDatasourceId not in conversionMap:
@@ -557,8 +710,8 @@ def exportConversionJson(self, filepath=None):
"""
conversionMap = self.getConversionMap()
if not filepath:
- filepath = os.path.join(os.path.dirname(__file__), 'conversion_map.json')
- with open(filepath, 'w') as fp:
+ filepath = os.path.join(os.path.dirname(__file__), "conversion_map.json")
+ with open(filepath, "w") as fp:
json.dump(conversionMap, fp, indent=4, sort_keys=True)
def validateJson(self, inputJson):
@@ -579,7 +732,7 @@ def checkEdgvConversion(edgvIn, edgvOut):
:param edgvOut: (str) output EDGV version.
"""
# TO DO
- return edgvIn == edgvOut and edgvOut != ''
+ return edgvIn == edgvOut and edgvOut != ""
def validate(self):
"""
@@ -594,10 +747,12 @@ def validate(self):
msgBar = QgsMessageBar(self)
# if window is resized, msgBar stays, not ideal, but works for now
# maybe we should connect to some parent resizing signal or something...
- msgBar.resize(QSize(self.geometry().size().width(), msgBar.geometry().height()))
- msgBar.pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5)
- QgsMessageLog.logMessage(msg, 'DSGTools Plugin', Qgis.Critical)
- return msg == ''
+ msgBar.resize(
+ QSize(self.geometry().size().width(), msgBar.geometry().height())
+ )
+ msgBar.pushMessage(self.tr("Warning!"), msg, level=Qgis.Warning, duration=5)
+ QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Critical)
+ return msg == ""
def validateCurrentPage(self):
"""
@@ -616,7 +771,10 @@ def invalidatedReason(self):
"""
if self.tableWidget.rowCount() == 0:
return self.tr("No datasets were selected (input or output)")
- for obj in [self.datasourceManagementWidgetIn, self.datasourceManagementWidgetOut]:
+ for obj in [
+ self.datasourceManagementWidgetIn,
+ self.datasourceManagementWidgetOut,
+ ]:
# validate in/ouput
msg = obj.validate()
if msg:
@@ -627,31 +785,54 @@ def invalidatedReason(self):
for row in range(self.tableWidget.rowCount()):
# get row contents
# inDsName, _, _, inEdgv, outDs, _, outEdgv, conversionMode = self.getRowContents(row=row)
- inDsName, _, inEdgv, outDs, outEdgv, _, conversionMode = self.getRowContents(row=row)
+ (
+ inDsName,
+ _,
+ inEdgv,
+ outDs,
+ outEdgv,
+ _,
+ conversionMode,
+ ) = self.getRowContents(row=row)
outDsName = outDs.currentText()
# FTer was discontinued. conv should not allow dataset creation for this EDGV version
- if outEdgv == 'EDGV 2.1.3 F Ter' and self.tr('new') in outDsName.split(' #')[0]:
- return self.tr('EDGV 2.1.3 F Ter model was terminated. DSGTools no longer support its creation (row {1})').format(inDsName, row + 1)
+ if (
+ outEdgv == "EDGV 2.1.3 F Ter"
+ and self.tr("new") in outDsName.split(" #")[0]
+ ):
+ return self.tr(
+ "EDGV 2.1.3 F Ter model was terminated. DSGTools no longer support its creation (row {1})"
+ ).format(inDsName, row + 1)
# check if a conversion mode was selected
- if conversionMode.currentText() == self.tr('Choose Conversion Mode'):
- return self.tr('Conversion mode not selected for input {0} (row {1})').format(inDsName, row + 1)
+ if conversionMode.currentText() == self.tr("Choose Conversion Mode"):
+ return self.tr(
+ "Conversion mode not selected for input {0} (row {1})"
+ ).format(inDsName, row + 1)
# check if EDGV versions are compatible
if not self.checkEdgvConversion(edgvIn=inEdgv, edgvOut=outEdgv):
- return self.tr('Conversion map unavailable for {0} to {1} (row {2})').format(inEdgv, outEdgv, row + 1)
+ return self.tr(
+ "Conversion map unavailable for {0} to {1} (row {2})"
+ ).format(inEdgv, outEdgv, row + 1)
# # add input to the checked ones list
# inChecked.append(inDsName)
# add output to checked ones list, if it's not 'select a datasource'
- if outDsName == self.tr('Select a datasource'):
- return self.tr('Output datasource not selected for {0} (row {1})').format(inDsName, row + 1)
+ if outDsName == self.tr("Select a datasource"):
+ return self.tr(
+ "Output datasource not selected for {0} (row {1})"
+ ).format(inDsName, row + 1)
outChecked.add(outDsName)
# last check: if all chosen outputs are listed
- splitAlias = lambda x : x.split(':')[0]
+ splitAlias = lambda x: x.split(":")[0]
if len(outChecked) != len(self.outDs):
# if not all outputs were used, user should remove it (or may have wrongfully chosen a different dataset)
notUsed = set(self.outDs.keys()) - set(map(splitAlias, outChecked))
- msg = self.tr('Output datasource {0} was not used.') if len(notUsed) == 1 else self.tr('Output datasources {0} were not used.')
+ msg = (
+ self.tr("Output datasource {0} was not used.")
+ if len(notUsed) == 1
+ else self.tr("Output datasources {0} were not used.")
+ )
return msg.format(", ".join(notUsed))
- return ''
+ return ""
def cancelConversion(self, conversionTask, summaryDlg):
"""
@@ -664,7 +845,11 @@ def cancelConversion(self, conversionTask, summaryDlg):
summaryDlg.cancelPushButton.setEnabled(False)
conversionTask.blockSignals(True)
summaryDlg.progressBar.setValue(0)
- summaryDlg.addToHtml(self.tr('
CONVERSION TASK WAS CANCELLED.
'))
+ summaryDlg.addToHtml(
+ self.tr(
+ '
CONVERSION TASK WAS CANCELLED.
'
+ )
+ )
summaryDlg.savePushButton.setEnabled(True)
def run(self, conversionMap):
@@ -686,7 +871,9 @@ def run(self, conversionMap):
# QgsApplication.taskManager().addTask(task)
# summaryDlg.show()
# conversion off the thread
- conv = DbConverter(iface, conversionMap, description=self.tr('DSGTools Dataset Conversion'))
+ conv = DbConverter(
+ iface, conversionMap, description=self.tr("DSGTools Dataset Conversion")
+ )
summaryDlg = TextBrowserDialog(parent=iface.mainWindow())
summaryDlg.cancelPushButton.hide()
summaryDlg.progressBar.hide()
@@ -694,17 +881,25 @@ def run(self, conversionMap):
QtWidgets.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
if not conv.run():
# advise conversion has failed
- msg = self.tr("Dataset conversion has finished with some errors. Check conversion log for details.")
- iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5)
+ msg = self.tr(
+ "Dataset conversion has finished with some errors. Check conversion log for details."
+ )
+ iface.messageBar().pushMessage(
+ self.tr("Warning!"), msg, level=Qgis.Warning, duration=5
+ )
else:
self.resetInterface()
QtWidgets.QApplication.restoreOverrideCursor()
- summaryDlg.setHtml(conv.output['log'])
+ summaryDlg.setHtml(conv.output["log"])
except Exception as e:
QtWidgets.QApplication.restoreOverrideCursor()
- msg = self.tr("Dataset conversion has failed: '{0}'").format(', '.join(map(str, e.args)))
- iface.messageBar().pushMessage(self.tr('Warning!'), msg, level=Qgis.Warning, duration=5)
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
+ msg = self.tr("Dataset conversion has failed: '{0}'").format(
+ ", ".join(map(str, e.args))
+ )
+ iface.messageBar().pushMessage(
+ self.tr("Warning!"), msg, level=Qgis.Warning, duration=5
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
summaryDlg.exec_()
def startConversion(self, exportMap=False):
@@ -734,15 +929,15 @@ def execute(self):
def initGui(self):
"""
- Instantiate GUI for user, including button shortcut (if necessary) and tool insertion on DSGTools tab on QGIS.
+ Instantiate GUI for user, including button shortcut (if necessary) and tool insertion on DSGTools tab on QGIS.
"""
self.manager.addTool(
- text=self.tr('Convert Databases'),
+ text=self.tr("Convert Databases"),
callback=self.execute,
parentMenu=self.parentMenu,
- icon='install.png',
+ icon="install.png",
parentButton=self.parentButton,
- defaultButton=False
+ defaultButton=False,
)
def resetInterface(self):
@@ -767,7 +962,10 @@ def unload(self):
except:
pass
# remove every widget added to interface (in and output) and, consequently, disconnect all signals
- for obj in [self.datasourceManagementWidgetIn, self.datasourceManagementWidgetOut]:
+ for obj in [
+ self.datasourceManagementWidgetIn,
+ self.datasourceManagementWidgetOut,
+ ]:
for driverName, wList in obj.activeDrivers.items():
for w in wList:
# removeWidget method disconnects all widget signals
diff --git a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py
index 7e05d2792..a3a3e15f9 100644
--- a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py
+++ b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/batchDbCreator.py
@@ -28,14 +28,21 @@
from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog, QWizard
from fileinput import filename
from DsgTools.core.Utils.utils import Utils
-from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchFromCsv import CreateBatchFromCsv
-from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchIncrementing import CreateBatchIncrementing
+from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchFromCsv import (
+ CreateBatchFromCsv,
+)
+from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.createBatchIncrementing import (
+ CreateBatchIncrementing,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "batchDbCreator.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'batchDbCreator.ui'))
class BatchDbCreator(QtWidgets.QWizard, FORM_CLASS):
coverageChanged = pyqtSignal()
+
def __init__(self, manager, parentButton, parentMenu, parent=None):
"""Constructor."""
super(self.__class__, self).__init__()
@@ -49,39 +56,47 @@ def __init__(self, manager, parentButton, parentMenu, parent=None):
self.parentMenu = parentMenu
self.parent = parent
self.setupUi(self)
- self.sequenceDict = {'CreateBatchFromCsv':1, 'CreateBatchIncrementing':2, 'CreateBatchBasedOnList':3}
-
- self.setPage(self.sequenceDict['CreateBatchFromCsv'],CreateBatchFromCsv())
- self.setPage(self.sequenceDict['CreateBatchIncrementing'],CreateBatchIncrementing())
-
+ self.sequenceDict = {
+ "CreateBatchFromCsv": 1,
+ "CreateBatchIncrementing": 2,
+ "CreateBatchBasedOnList": 3,
+ }
+
+ self.setPage(self.sequenceDict["CreateBatchFromCsv"], CreateBatchFromCsv())
+ self.setPage(
+ self.sequenceDict["CreateBatchIncrementing"], CreateBatchIncrementing()
+ )
+
def nextId(self):
if self.currentId() == 0:
if self.csvRadioButton.isChecked():
- return self.sequenceDict['CreateBatchFromCsv']
+ return self.sequenceDict["CreateBatchFromCsv"]
elif self.patternRadioButton.isChecked():
- return self.sequenceDict['CreateBatchIncrementing']
+ return self.sequenceDict["CreateBatchIncrementing"]
else:
return self.currentId()
- elif self.currentId() == self.sequenceDict['CreateBatchFromCsv']:
+ elif self.currentId() == self.sequenceDict["CreateBatchFromCsv"]:
return -1
- elif self.currentId() == self.sequenceDict['CreateBatchIncrementing']:
+ elif self.currentId() == self.sequenceDict["CreateBatchIncrementing"]:
return -1
else:
return -1
def initGui(self):
"""
- Instantiates user interface and prepare it to be called whenever tool button is activated.
+ Instantiates user interface and prepare it to be called whenever tool button is activated.
"""
- callback = lambda : self.manager.createDatabase(isBatchCreation=True)
+ callback = lambda: self.manager.createDatabase(isBatchCreation=True)
self.manager.addTool(
- text=self.tr('Create batches of PostGIS, SpatiaLite or Geopackage Databases'),
+ text=self.tr(
+ "Create batches of PostGIS, SpatiaLite or Geopackage Databases"
+ ),
callback=callback,
parentMenu=self.parentMenu,
- icon='batchDatabase.png',
+ icon="batchDatabase.png",
parentButton=self.parentButton,
- defaultButton=False
+ defaultButton=False,
)
def unload(self):
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py
index bb1504673..c5c43c516 100644
--- a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py
+++ b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchFromCsv.py
@@ -33,42 +33,63 @@
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'createBatchFromCsv.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "createBatchFromCsv.ui")
+)
+
class CreateBatchFromCsv(QtWidgets.QWizardPage, FORM_CLASS):
coverageChanged = pyqtSignal()
+
def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__()
self.setupUi(self)
self.databaseParameterWidget.setDbNameVisible(False)
- self.customFileSelector.setCaption(self.tr('Select a Comma Separated Values File'))
- self.customFileSelector.setFilter(self.tr('Comma Separated Values File (*.csv)'))
- self.customFileSelector.setType('single')
- self.customFileSelector.setTitle(self.tr('CSV File'))
- self.tabDbSelectorWidget.tabWidget.currentChanged.connect(self.changeTemplateInterface)
- self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(self.databaseParameterWidget.setServerDb)
+ self.customFileSelector.setCaption(
+ self.tr("Select a Comma Separated Values File")
+ )
+ self.customFileSelector.setFilter(
+ self.tr("Comma Separated Values File (*.csv)")
+ )
+ self.customFileSelector.setType("single")
+ self.customFileSelector.setTitle(self.tr("CSV File"))
+ self.tabDbSelectorWidget.tabWidget.currentChanged.connect(
+ self.changeTemplateInterface
+ )
+ self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(
+ self.databaseParameterWidget.setServerDb
+ )
self.databaseParameterWidget.comboBoxPostgis.parent = self
-
+
def getParameters(self):
- #Get outputDir, outputList, refSys
+ # Get outputDir, outputList, refSys
parameterDict = dict()
- parameterDict['prefix'] = None
- parameterDict['sufix'] = None
- parameterDict['srid'] = self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs().authid().split(':')[-1]
- parameterDict['version'] = self.databaseParameterWidget.getVersion()
- parameterDict['nonDefaultTemplate'] = self.databaseParameterWidget.getTemplateName()
- if self.databaseParameterWidget.prefixLineEdit.text() != '':
- parameterDict['prefix'] = self.databaseParameterWidget.prefixLineEdit.text()
- if self.databaseParameterWidget.sufixLineEdit.text() != '':
- parameterDict['sufix'] = self.databaseParameterWidget.sufixLineEdit.text()
- parameterDict['miList'] = self.getMiListFromCSV()
- parameterDict['driverName'] = self.tabDbSelectorWidget.getType()
- parameterDict['factoryParam'] = self.tabDbSelectorWidget.getFactoryCreationParam()
- parameterDict['templateInfo'] = self.databaseParameterWidget.getTemplateParameters()
+ parameterDict["prefix"] = None
+ parameterDict["sufix"] = None
+ parameterDict["srid"] = (
+ self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs()
+ .authid()
+ .split(":")[-1]
+ )
+ parameterDict["version"] = self.databaseParameterWidget.getVersion()
+ parameterDict[
+ "nonDefaultTemplate"
+ ] = self.databaseParameterWidget.getTemplateName()
+ if self.databaseParameterWidget.prefixLineEdit.text() != "":
+ parameterDict["prefix"] = self.databaseParameterWidget.prefixLineEdit.text()
+ if self.databaseParameterWidget.sufixLineEdit.text() != "":
+ parameterDict["sufix"] = self.databaseParameterWidget.sufixLineEdit.text()
+ parameterDict["miList"] = self.getMiListFromCSV()
+ parameterDict["driverName"] = self.tabDbSelectorWidget.getType()
+ parameterDict[
+ "factoryParam"
+ ] = self.tabDbSelectorWidget.getFactoryCreationParam()
+ parameterDict[
+ "templateInfo"
+ ] = self.databaseParameterWidget.getTemplateParameters()
return parameterDict
-
+
def getMiListFromCSV(self):
"""
Old method for CSV reading. It identifies the databases names from the
@@ -83,7 +104,7 @@ def getMiListFromCSV(self):
return miList
def validatePage(self):
- #insert validation messages
+ # insert validation messages
validatedDbParams = self.databaseParameterWidget.validate()
if not validatedDbParams:
return False
@@ -92,50 +113,66 @@ def validatePage(self):
return False
parameterDict = self.getParameters()
dbDict, errorDict = self.createDatabases(parameterDict)
- creationMsg = ''
+ creationMsg = ""
if len(list(dbDict.keys())) > 0:
- creationMsg += self.tr('Database(s) {0} created successfully.').format(', '.join(list(dbDict.keys())))
- errorFrameMsg = ''
- errorMsg = ''
+ creationMsg += self.tr("Database(s) {0} created successfully.").format(
+ ", ".join(list(dbDict.keys()))
+ )
+ errorFrameMsg = ""
+ errorMsg = ""
if len(list(errorDict.keys())) > 0:
frameList = []
errorList = []
for key in list(errorDict.keys()):
- if self.tr('Invalid inomen parameter!') in errorDict[key]:
+ if self.tr("Invalid inomen parameter!") in errorDict[key]:
frameList.append(key)
else:
errorList.append(key)
- QgsMessageLog.logMessage(self.tr('Error on {0}: ').format(key)+errorDict[key], "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.tr("Error on {0}: ").format(key) + errorDict[key],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
if len(frameList) > 0:
- errorFrameMsg += self.tr('Frame was not created on the following databases: {0}').format(', '.join(frameList))
+ errorFrameMsg += self.tr(
+ "Frame was not created on the following databases: {0}"
+ ).format(", ".join(frameList))
if len(errorList) > 0:
- errorMsg += self.tr('Some errors occurred while trying to create database(s) {0}').format(', '.join(errorList))
- logMsg = ''
- if errorFrameMsg != '' or errorMsg != '':
- logMsg += self.tr('Check log for more details.')
- msg = [i for i in (creationMsg, errorFrameMsg, errorMsg, logMsg) if i != '']
- QMessageBox.warning(self, self.tr('Info!'), self.tr('Process finished.')+'\n'+'\n'.join(msg))
+ errorMsg += self.tr(
+ "Some errors occurred while trying to create database(s) {0}"
+ ).format(", ".join(errorList))
+ logMsg = ""
+ if errorFrameMsg != "" or errorMsg != "":
+ logMsg += self.tr("Check log for more details.")
+ msg = [i for i in (creationMsg, errorFrameMsg, errorMsg, logMsg) if i != ""]
+ QMessageBox.warning(
+ self, self.tr("Info!"), self.tr("Process finished.") + "\n" + "\n".join(msg)
+ )
return True
-
+
def createDatabases(self, parameterDict):
- dbCreator = DbCreatorFactory().createDbCreatorFactory(parameterDict['driverName'], parameterDict['factoryParam'], parentWidget = self)
+ dbCreator = DbCreatorFactory().createDbCreatorFactory(
+ parameterDict["driverName"],
+ parameterDict["factoryParam"],
+ parentWidget=self,
+ )
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
dbDict, errorDict = dbCreator.createDbFromMIList(
- parameterDict['miList'],
- parameterDict['srid'],
- prefix=parameterDict['prefix'],
- sufix=parameterDict['sufix'],
+ parameterDict["miList"],
+ parameterDict["srid"],
+ prefix=parameterDict["prefix"],
+ sufix=parameterDict["sufix"],
# DEEPER FIX SUGGESTION: validate whether name matches INOM or MI
- # formatting and, if it does, set this to True
+ # formatting and, if it does, set this to True
# createFrame=True, # i don't know why this is ALWAYS true
createFrame=False,
- paramDict=parameterDict['templateInfo']
+ paramDict=parameterDict["templateInfo"],
)
QApplication.restoreOverrideCursor()
return dbDict, errorDict
-
+
def changeTemplateInterface(self):
if self.tabDbSelectorWidget.tabWidget.currentIndex() == 1:
- self.databaseParameterWidget.changeInterfaceState(True, hideInterface = True)
+ self.databaseParameterWidget.changeInterfaceState(True, hideInterface=True)
else:
- self.databaseParameterWidget.changeInterfaceState(True, hideInterface = False)
+ self.databaseParameterWidget.changeInterfaceState(True, hideInterface=False)
diff --git a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py
index 2e60ab853..cd0c9e7aa 100644
--- a/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py
+++ b/DsgTools/gui/DatabaseTools/DbTools/BatchDbCreator/createBatchIncrementing.py
@@ -29,46 +29,65 @@
from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog, QApplication
from qgis.PyQt.QtGui import QCursor
from DsgTools.core.Utils.utils import Utils
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
-from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import TabDbSelectorWidget
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import (
+ ProgressWidget,
+)
+from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import (
+ TabDbSelectorWidget,
+)
from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'createBatchIncrementing.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "createBatchIncrementing.ui")
+)
+
class CreateBatchIncrementing(QtWidgets.QWizardPage, FORM_CLASS):
parametersSet = pyqtSignal(dict)
+
def __init__(self, parent=None):
"""Constructor."""
super(self.__class__, self).__init__()
self.setupUi(self)
self.databaseParameterWidget.setDbNameVisible(False)
- self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(self.databaseParameterWidget.setServerDb)
+ self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(
+ self.databaseParameterWidget.setServerDb
+ )
self.databaseParameterWidget.comboBoxPostgis.parent = self
self.databaseParameterWidget.useFrame = False
self.databaseParameterWidget.setDbNameVisible(True)
-
+
def getParameters(self):
- #Get outputDir, outputList, refSys
+ # Get outputDir, outputList, refSys
parameterDict = dict()
- parameterDict['prefix'] = None
- parameterDict['sufix'] = None
- parameterDict['srid'] = self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs().authid().split(':')[-1]
- parameterDict['version'] = self.databaseParameterWidget.getVersion()
- parameterDict['nonDefaultTemplate'] = self.databaseParameterWidget.getTemplateName()
- if self.databaseParameterWidget.prefixLineEdit.text() != '':
- parameterDict['prefix'] = self.databaseParameterWidget.prefixLineEdit.text()
- if self.databaseParameterWidget.sufixLineEdit.text() != '':
- parameterDict['sufix'] = self.databaseParameterWidget.sufixLineEdit.text()
- parameterDict['dbBaseName'] = self.databaseParameterWidget.dbNameLineEdit.text()
- parameterDict['driverName'] = self.tabDbSelectorWidget.getType()
- parameterDict['factoryParam'] = self.tabDbSelectorWidget.getFactoryCreationParam()
- parameterDict['numberOfDatabases'] = self.spinBox.value()
- parameterDict['templateInfo'] = self.databaseParameterWidget.getTemplateParameters()
+ parameterDict["prefix"] = None
+ parameterDict["sufix"] = None
+ parameterDict["srid"] = (
+ self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs()
+ .authid()
+ .split(":")[-1]
+ )
+ parameterDict["version"] = self.databaseParameterWidget.getVersion()
+ parameterDict[
+ "nonDefaultTemplate"
+ ] = self.databaseParameterWidget.getTemplateName()
+ if self.databaseParameterWidget.prefixLineEdit.text() != "":
+ parameterDict["prefix"] = self.databaseParameterWidget.prefixLineEdit.text()
+ if self.databaseParameterWidget.sufixLineEdit.text() != "":
+ parameterDict["sufix"] = self.databaseParameterWidget.sufixLineEdit.text()
+ parameterDict["dbBaseName"] = self.databaseParameterWidget.dbNameLineEdit.text()
+ parameterDict["driverName"] = self.tabDbSelectorWidget.getType()
+ parameterDict[
+ "factoryParam"
+ ] = self.tabDbSelectorWidget.getFactoryCreationParam()
+ parameterDict["numberOfDatabases"] = self.spinBox.value()
+ parameterDict[
+ "templateInfo"
+ ] = self.databaseParameterWidget.getTemplateParameters()
return parameterDict
def validatePage(self):
- #insert validation messages
+ # insert validation messages
validatedDbParams = self.databaseParameterWidget.validate()
if not validatedDbParams:
return False
@@ -77,28 +96,49 @@ def validatePage(self):
return False
parameterDict = self.getParameters()
dbDict, errorDict = self.createDatabases(parameterDict)
- creationMsg = ''
+ creationMsg = ""
if len(list(dbDict.keys())) > 0:
- creationMsg += self.tr('Database(s) {0} created successfully.').format(', '.join(list(dbDict.keys())))
- errorMsg = ''
+ creationMsg += self.tr("Database(s) {0} created successfully.").format(
+ ", ".join(list(dbDict.keys()))
+ )
+ errorMsg = ""
if len(list(errorDict.keys())) > 0:
frameList = []
errorList = []
for key in list(errorDict.keys()):
errorList.append(key)
- QgsMessageLog.logMessage(self.tr('Error on {0}: ').format(key)+errorDict[key], "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.tr("Error on {0}: ").format(key) + errorDict[key],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
if len(errorList) > 0:
- errorMsg += self.tr('Some errors occurred while trying to create database(s) {0}').format(', '.join(errorList))
- logMsg = ''
- if errorMsg != '':
- logMsg += self.tr('Check log for more details.')
- msg = [i for i in (creationMsg, errorMsg, logMsg) if i != '']
- QMessageBox.warning(self, self.tr('Info!'), self.tr('Process finished.')+'\n'+'\n'.join(msg))
+ errorMsg += self.tr(
+ "Some errors occurred while trying to create database(s) {0}"
+ ).format(", ".join(errorList))
+ logMsg = ""
+ if errorMsg != "":
+ logMsg += self.tr("Check log for more details.")
+ msg = [i for i in (creationMsg, errorMsg, logMsg) if i != ""]
+ QMessageBox.warning(
+ self, self.tr("Info!"), self.tr("Process finished.") + "\n" + "\n".join(msg)
+ )
return True
-
+
def createDatabases(self, parameterDict):
- dbCreator = DbCreatorFactory().createDbCreatorFactory(parameterDict['driverName'], parameterDict['factoryParam'], parentWidget = self)
+ dbCreator = DbCreatorFactory().createDbCreatorFactory(
+ parameterDict["driverName"],
+ parameterDict["factoryParam"],
+ parentWidget=self,
+ )
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
- dbDict, errorDict = dbCreator.createDbWithAutoIncrementingName(parameterDict['dbBaseName'], parameterDict['srid'], parameterDict['numberOfDatabases'], prefix = parameterDict['prefix'], sufix = parameterDict['sufix'], paramDict = parameterDict['templateInfo'])
+ dbDict, errorDict = dbCreator.createDbWithAutoIncrementingName(
+ parameterDict["dbBaseName"],
+ parameterDict["srid"],
+ parameterDict["numberOfDatabases"],
+ prefix=parameterDict["prefix"],
+ sufix=parameterDict["sufix"],
+ paramDict=parameterDict["templateInfo"],
+ )
QApplication.restoreOverrideCursor()
return dbDict, errorDict
diff --git a/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py b/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py
index 882da6eaa..636750c6f 100644
--- a/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py
+++ b/DsgTools/gui/DatabaseTools/DbTools/SingleDbCreator/singleDbCreator.py
@@ -31,15 +31,22 @@
from qgis.PyQt.QtWidgets import QMessageBox, QFileDialog, QApplication
from qgis.PyQt.QtGui import QCursor
from DsgTools.core.Utils.utils import Utils
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
-from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import TabDbSelectorWidget
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import (
+ ProgressWidget,
+)
+from DsgTools.gui.CustomWidgets.SelectionWidgets.tabDbSelectorWidget import (
+ TabDbSelectorWidget,
+)
from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'singleDbCreator.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "singleDbCreator.ui")
+)
+
class CreateSingleDatabase(QtWidgets.QDialog, FORM_CLASS):
parametersSet = pyqtSignal(dict)
+
def __init__(self, manager, parentButton, parentMenu, parent=None):
"""Constructor."""
super(CreateSingleDatabase, self).__init__()
@@ -53,13 +60,17 @@ def __init__(self, manager, parentButton, parentMenu, parent=None):
self.databaseParameterWidget.sufixLineEdit.hide()
self.databaseParameterWidget.prefixLabel.hide()
self.databaseParameterWidget.sufixLabel.hide()
- self.databaseParameterWidget.groupBox.setTitle('')
+ self.databaseParameterWidget.groupBox.setTitle("")
self.databaseParameterWidget.setDbNameVisible(False)
- self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(self.databaseParameterWidget.setServerDb)
+ self.tabDbSelectorWidget.serverWidget.serverAbstractDbLoaded.connect(
+ self.databaseParameterWidget.setServerDb
+ )
self.databaseParameterWidget.comboBoxPostgis.parent = self
self.databaseParameterWidget.useFrame = False
self.databaseParameterWidget.setDbNameVisible(True)
- self.tabDbSelectorWidget.outputDirSelector.label.setText(self.tr('Select Database Path'))
+ self.tabDbSelectorWidget.outputDirSelector.label.setText(
+ self.tr("Select Database Path")
+ )
self.okPushButton.clicked.connect(self.validateParameters)
self.cancelPushButton.clicked.connect(self.close_)
@@ -85,19 +96,29 @@ def getParameters(self):
}
}
"""
- #Get outputDir, outputList, refSys
+ # Get outputDir, outputList, refSys
parameterDict = dict()
- parameterDict['srid'] = self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs().authid().split(':')[-1]
- parameterDict['version'] = self.databaseParameterWidget.getVersion()
- parameterDict['nonDefaultTemplate'] = self.databaseParameterWidget.getTemplateName()
- parameterDict['dbBaseName'] = self.databaseParameterWidget.dbNameLineEdit.text()
- parameterDict['driverName'] = self.tabDbSelectorWidget.getType()
- parameterDict['factoryParam'] = self.tabDbSelectorWidget.getFactoryCreationParam()
- parameterDict['templateInfo'] = self.databaseParameterWidget.getTemplateParameters()
+ parameterDict["srid"] = (
+ self.databaseParameterWidget.mQgsProjectionSelectionWidget.crs()
+ .authid()
+ .split(":")[-1]
+ )
+ parameterDict["version"] = self.databaseParameterWidget.getVersion()
+ parameterDict[
+ "nonDefaultTemplate"
+ ] = self.databaseParameterWidget.getTemplateName()
+ parameterDict["dbBaseName"] = self.databaseParameterWidget.dbNameLineEdit.text()
+ parameterDict["driverName"] = self.tabDbSelectorWidget.getType()
+ parameterDict[
+ "factoryParam"
+ ] = self.tabDbSelectorWidget.getFactoryCreationParam()
+ parameterDict[
+ "templateInfo"
+ ] = self.databaseParameterWidget.getTemplateParameters()
return parameterDict
def validateParameters(self):
- #insert validation messages
+ # insert validation messages
validatedDbParams = self.databaseParameterWidget.validate()
if not validatedDbParams:
return False
@@ -106,51 +127,69 @@ def validateParameters(self):
return False
parameterDict = self.getParameters()
dbDict, errorDict = self.createDatabases(parameterDict)
- creationMsg = ''
+ creationMsg = ""
if len(dbDict):
- creationMsg = self.tr('Database {0} successfully created.').format(', '.join(list(dbDict.keys())))
- errorMsg = ''
+ creationMsg = self.tr("Database {0} successfully created.").format(
+ ", ".join(list(dbDict.keys()))
+ )
+ errorMsg = ""
if len(errorDict):
frameList = []
errorList = []
for key in list(errorDict.keys()):
errorList.append(key)
- QgsMessageLog.logMessage(self.tr('Error on {0}: ').format(key)+errorDict[key], "DSGTools Plugin", Qgis.Critical)
+ QgsMessageLog.logMessage(
+ self.tr("Error on {0}: ").format(key) + errorDict[key],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
if len(errorList) > 0:
- errorMsg += self.tr('Some errors occurred while trying to create database(s) {0}').format(', '.join(errorList))
- logMsg = ''
- if errorMsg != '':
- logMsg += self.tr('Check log for more details.')
- msg = [i for i in (creationMsg, errorMsg, logMsg) if i != '']
- QMessageBox.warning(self, self.tr('Info!'), self.tr('Process finished.')+'\n'+'\n'.join(msg))
+ errorMsg += self.tr(
+ "Some errors occurred while trying to create database(s) {0}"
+ ).format(", ".join(errorList))
+ logMsg = ""
+ if errorMsg != "":
+ logMsg += self.tr("Check log for more details.")
+ msg = [i for i in (creationMsg, errorMsg, logMsg) if i != ""]
+ QMessageBox.warning(
+ self, self.tr("Info!"), self.tr("Process finished.") + "\n" + "\n".join(msg)
+ )
self.close()
return True
-
+
def createDatabases(self, parameterDict):
- dbCreator = DbCreatorFactory().createDbCreatorFactory(parameterDict['driverName'], parameterDict['factoryParam'], parentWidget=self)
+ dbCreator = DbCreatorFactory().createDbCreatorFactory(
+ parameterDict["driverName"],
+ parameterDict["factoryParam"],
+ parentWidget=self,
+ )
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
dbDict, errorDict = dict(), dict()
try:
- newDb = dbCreator.createDb(dbName=parameterDict['dbBaseName'], srid=parameterDict['srid'],\
- paramDict=parameterDict['templateInfo'], parentWidget=self)
- dbDict[parameterDict['dbBaseName']] = newDb
+ newDb = dbCreator.createDb(
+ dbName=parameterDict["dbBaseName"],
+ srid=parameterDict["srid"],
+ paramDict=parameterDict["templateInfo"],
+ parentWidget=self,
+ )
+ dbDict[parameterDict["dbBaseName"]] = newDb
except Exception as e:
- errorDict[parameterDict['dbBaseName']] = ':'.join(map(str, e.args))
- QApplication.restoreOverrideCursor()
+ errorDict[parameterDict["dbBaseName"]] = ":".join(map(str, e.args))
+ QApplication.restoreOverrideCursor()
return dbDict, errorDict
def initGui(self):
"""
- Instantiates user interface and prepare it to be called whenever tool button is activated.
+ Instantiates user interface and prepare it to be called whenever tool button is activated.
"""
- callback = lambda : self.manager.createDatabase(isBatchCreation=False)
+ callback = lambda: self.manager.createDatabase(isBatchCreation=False)
self.manager.addTool(
- text=self.tr('Create a PostGIS, SpatiaLite or Geopackage Database'),
+ text=self.tr("Create a PostGIS, SpatiaLite or Geopackage Database"),
callback=callback,
parentMenu=self.parentMenu,
- icon='database.png',
+ icon="database.png",
parentButton=self.parentButton,
- defaultButton=True
+ defaultButton=True,
)
def close_(self):
@@ -160,4 +199,4 @@ def close_(self):
self.close()
def unload(self):
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py
index c682ee124..1a8756b89 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizard.py
@@ -28,14 +28,18 @@
from fileinput import filename
from DsgTools.core.Utils.utils import Utils
-from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizardProfile import PermissionWizardProfile
+from DsgTools.gui.DatabaseTools.UserTools.PermissionManagerWizard.permissionWizardProfile import (
+ PermissionWizardProfile,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "permissionWizard.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'permissionWizard.ui'))
class PermissionWizard(QtWidgets.QWizard, FORM_CLASS):
def __init__(self, serverAbstractDb, dbsDict, parent=None):
- '''Constructor.'''
+ """Constructor."""
super(self.__class__, self).__init__()
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
@@ -45,21 +49,21 @@ def __init__(self, serverAbstractDb, dbsDict, parent=None):
self.parent = parent
self.setupUi(self)
self.serverAbstractDb = serverAbstractDb
- self.userCustomSelector.setTitle(self.tr('Select users to be managed'))
+ self.userCustomSelector.setTitle(self.tr("Select users to be managed"))
userList = [i[0] for i in self.serverAbstractDb.getUsersFromServer()]
self.userCustomSelector.setInitialState(userList)
- self.sequenceDict = {'PermissionWizardProfile':1}
-
- self.setPage(self.sequenceDict['PermissionWizardProfile'],PermissionWizardProfile())
- #self.setPage(self.sequenceDict['CreateBatchIncrementing'],CreateBatchIncrementing())
+ self.sequenceDict = {"PermissionWizardProfile": 1}
+
+ self.setPage(
+ self.sequenceDict["PermissionWizardProfile"], PermissionWizardProfile()
+ )
+ # self.setPage(self.sequenceDict['CreateBatchIncrementing'],CreateBatchIncrementing())
def nextId(self):
if self.currentId() == 0:
if len(self.userCustomSelector.toLs) != 0:
- return self.sequenceDict['PermissionWizardProfile']
+ return self.sequenceDict["PermissionWizardProfile"]
else:
return -1
else:
return self.currentId()
-
-
\ No newline at end of file
diff --git a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py
index 8cbc46c9c..f2149bc6a 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/PermissionManagerWizard/permissionWizardProfile.py
@@ -30,12 +30,14 @@
from DsgTools.core.Utils.utils import Utils
from DsgTools.core.Factories.DbCreatorFactory.dbCreatorFactory import DbCreatorFactory
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'permissionWizardProfile.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "permissionWizardProfile.ui")
+)
+
class PermissionWizardProfile(QtWidgets.QWizardPage, FORM_CLASS):
def __init__(self, parent=None):
- '''Constructor.'''
+ """Constructor."""
super(self.__class__, self).__init__()
# Set up the user interface from Designer.
# After setupUI you can access any designer object by doing
@@ -43,18 +45,18 @@ def __init__(self, parent=None):
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
- self.profileCustomSelector.setTitle(self.tr('Select profiles to be installed'))
+ self.profileCustomSelector.setTitle(self.tr("Select profiles to be installed"))
profiles = self.getModelProfiles()
self.profileCustomSelector.setInitialState(profiles)
-
+
def getModelProfiles(self):
ret = []
- folder = os.path.join(os.path.dirname(__file__),'..', 'profiles')
+ folder = os.path.join(os.path.dirname(__file__), "..", "profiles")
for root, dirs, files in os.walk(folder):
for file in files:
- ext = file.split('.')[-1]
- if ext == 'json':
- ret.append(file.split('.')[0])
+ ext = file.split(".")[-1]
+ if ext == "json":
+ ret.append(file.split(".")[0])
ret.sort()
return ret
diff --git a/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py b/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py
index db6e386f2..770e9642a 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/alter_user_password.py
@@ -29,11 +29,13 @@
from qgis.core import Qgis, QgsMessageLog
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'alter_user_password.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "alter_user_password.ui")
+)
+
class AlterUserPassword(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, user = None, abstractDb = None, userList = None, parent = None):
+ def __init__(self, user=None, abstractDb=None, userList=None, parent=None):
"""
Constructor
"""
@@ -48,7 +50,7 @@ def __init__(self, user = None, abstractDb = None, userList = None, parent = Non
self.user = user
self.newPasswordLineEdit.setFocus()
self.userList = userList
-
+
@pyqtSlot(bool)
def on_alterPasswordButton_clicked(self):
"""
@@ -57,14 +59,18 @@ def on_alterPasswordButton_clicked(self):
newpassword = self.newPasswordLineEdit.text()
newpassword_2 = self.newPasswordLineEdit_2.text()
if newpassword != newpassword_2:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('Password mismatch! Password not altered!'))
+ QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("Password mismatch! Password not altered!"),
+ )
return
if self.user:
self.alterDatabasePassword(self.user, newpassword)
if self.userList:
self.alterServerPassword(self.userList, newpassword)
self.close()
-
+
def alterDatabasePassword(self, user, newpassword):
"""
Alters the password of a specific user
@@ -72,10 +78,18 @@ def alterDatabasePassword(self, user, newpassword):
try:
self.abstractDb.alterUserPass(self.user, newpassword)
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), e.args[0])
+ QMessageBox.critical(self, self.tr("Critical!"), e.args[0])
return
- QMessageBox.warning(self, self.tr('Success!'), self.tr('User ') +self.user+self.tr(' password successfully updated on database ')+self.abstractDb.getDatabaseName()+'!')
-
+ QMessageBox.warning(
+ self,
+ self.tr("Success!"),
+ self.tr("User ")
+ + self.user
+ + self.tr(" password successfully updated on database ")
+ + self.abstractDb.getDatabaseName()
+ + "!",
+ )
+
def alterServerPassword(self, userList, newpassword):
"""
Alters the password of a list of database users
@@ -87,38 +101,49 @@ def alterServerPassword(self, userList, newpassword):
self.abstractDb.alterUserPass(user, newpassword)
successList.append(user)
except Exception as e:
- exceptionDict[user] = ':'.join(e.args)
- header = self.tr('Alter operation on server ')+self.abstractDb.getHostName()+self.tr(' complete!\n')
+ exceptionDict[user] = ":".join(e.args)
+ header = (
+ self.tr("Alter operation on server ")
+ + self.abstractDb.getHostName()
+ + self.tr(" complete!\n")
+ )
self.outputMessage(header, successList, exceptionDict)
-
+
def outputMessage(self, header, successList, exceptionDict):
"""
Makes the output message
"""
msg = header
if len(successList) > 0:
- msg += self.tr('\nSuccessful users: ')
- msg +=', '.join(successList)
+ msg += self.tr("\nSuccessful users: ")
+ msg += ", ".join(successList)
msg += self.logInternalError(exceptionDict)
- QMessageBox.warning(self, self.tr('Operation Complete!'), msg)
+ QMessageBox.warning(self, self.tr("Operation Complete!"), msg)
def logInternalError(self, exceptionDict):
"""
Logs all internal errors into QGIS' log
"""
- msg = ''
+ msg = ""
errorDbList = list(exceptionDict.keys())
- if len(errorDbList)> 0:
- msg += self.tr('\nUsers with error:')
- msg+= ', '.join(errorDbList)
- msg+= self.tr('\nError messages for each user were output in qgis log.')
+ if len(errorDbList) > 0:
+ msg += self.tr("\nUsers with error:")
+ msg += ", ".join(errorDbList)
+ msg += self.tr("\nError messages for each user were output in qgis log.")
for errorDb in errorDbList:
- QgsMessageLog.logMessage(self.tr('Error for user ')+ errorDb + ': ' +exceptionDict[errorDb], "DSGTools Plugin", Qgis.Critical)
- return msg
+ QgsMessageLog.logMessage(
+ self.tr("Error for user ")
+ + errorDb
+ + ": "
+ + exceptionDict[errorDb],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ return msg
@pyqtSlot(bool)
def on_cancelButton_clicked(self):
"""
Cancels everything
"""
- self.close()
\ No newline at end of file
+ self.close()
diff --git a/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py b/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py
index 2c7049722..165362882 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/assign_profiles.py
@@ -22,7 +22,7 @@
"""
import os
-#PyQt imports
+# PyQt imports
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtGui import QCursor
@@ -35,11 +35,13 @@
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'assign_profiles.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "assign_profiles.ui")
+)
+
class AssignProfiles(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, serverIndex = None, index = None, parent = None):
+ def __init__(self, serverIndex=None, index=None, parent=None):
"""
Constructor
"""
@@ -55,56 +57,60 @@ def __init__(self, serverIndex = None, index = None, parent = None):
self.widget.serverWidget.serversCombo.setCurrentIndex(serverIndex)
self.widget.comboBoxPostgis.setCurrentIndex(index)
self.widget.serverWidget.superNeeded = True
- self.folder = os.path.join(os.path.dirname(__file__), 'profiles')
+ self.folder = os.path.join(os.path.dirname(__file__), "profiles")
self.getModelProfiles()
self.getInstalledProfiles()
-
- #Objects Connections
- QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("connectionChanged()")), self.getInstalledProfiles)
+
+ # Objects Connections
+ QtCore.QObject.connect(
+ self.widget,
+ QtCore.SIGNAL(("connectionChanged()")),
+ self.getInstalledProfiles,
+ )
def parseJson(self, filename):
"""
Parses the profile file and creates a dictionary
"""
try:
- file = open(filename, 'r')
+ file = open(filename, "r")
data = file.read()
profileDict = json.loads(data)
file.close()
return profileDict
except:
return None
-
+
def getModelProfiles(self):
"""
Scans the profile folder for files and make a list with them
"""
self.possibleProfiles.clear()
-
+
ret = []
for root, dirs, files in os.walk(self.folder):
for file in files:
- ext = file.split('.')[-1]
- if ext == 'json':
- ret.append(file.split('.')[0])
+ ext = file.split(".")[-1]
+ if ext == "json":
+ ret.append(file.split(".")[0])
ret.sort()
self.possibleProfiles.addItems(ret)
-
+
def getInstalledProfiles(self):
"""
Gets the installed profiles from a database
"""
self.assignedProfiles.clear()
-
+
if not self.widget.abstractDb:
return
-
+
ret = []
try:
ret = self.widget.abstractDb.getRoles()
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.assignedProfiles.addItems(ret)
@@ -114,35 +120,41 @@ def on_installButton_clicked(self):
Installs the selected profiles into the database selected
"""
if len(self.possibleProfiles.selectedItems()) == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one profile and try again!'))
- return
-
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Select at least one profile and try again!"),
+ )
+ return
+
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
for item in self.possibleProfiles.selectedItems():
role = item.text()
- profile = os.path.join(self.folder, role +'.json')
+ profile = os.path.join(self.folder, role + ".json")
dict = self.parseJson(profile)
-
+
try:
self.widget.abstractDb.createRole(role, dict)
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
return
-
+
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profiles assigned successfully!'))
-
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Profiles assigned successfully!")
+ )
+
self.getInstalledProfiles()
-
+
@pyqtSlot(bool)
def on_closeButton_clicked(self):
"""
Closes the dialog
"""
self.close()
-
+
@pyqtSlot(bool)
def on_openProfileEditor_clicked(self):
"""
@@ -151,16 +163,20 @@ def on_openProfileEditor_clicked(self):
dlg = ProfileEditor()
dlg.exec_()
self.getModelProfiles()
-
+
@pyqtSlot(bool)
def on_removeButton_clicked(self):
"""
Removes a installed profile from the database (i.e we execute a drop role sql query)
"""
if len(self.assignedProfiles.selectedItems()) == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one profile and try again!'))
- return
-
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Select at least one profile and try again!"),
+ )
+ return
+
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
problem = False
@@ -172,12 +188,14 @@ def on_removeButton_clicked(self):
except Exception as e:
problem = True
QApplication.restoreOverrideCursor()
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
if not problem:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profiles removed successfully!'))
-
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Profiles removed successfully!")
+ )
+
self.getInstalledProfiles()
@pyqtSlot(bool)
@@ -186,19 +204,38 @@ def on_removeJson_clicked(self):
Deletes a profile file
"""
if len(self.possibleProfiles.selectedItems()) == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select at least one profile and try again!'))
- return
-
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to remove selected profile models?'), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Select at least one profile and try again!"),
+ )
+ return
+
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to remove selected profile models?"),
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
-
+
for item in self.possibleProfiles.selectedItems():
json = item.text()
- file = json+'.json'
+ file = json + ".json"
path = os.path.join(self.folder, file)
try:
os.remove(path)
except OSError as e:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('Problem removing profile model: ')+json+'\n'+e.strerror)
-
+ QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("Problem removing profile model: ")
+ + json
+ + "\n"
+ + e.strerror,
+ )
+
self.getModelProfiles()
diff --git a/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py b/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py
index 51b571b23..cfcb967b8 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/createProfileWithProfileManager.py
@@ -33,13 +33,15 @@
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'createProfileWithProfileManager.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "createProfileWithProfileManager.ui")
+)
+
class CreateProfileWithProfileManager(QtWidgets.QDialog, FORM_CLASS):
profileCreated = pyqtSignal(str, str)
-
- def __init__(self, permissionManager, abstractDb, parent = None):
+
+ def __init__(self, permissionManager, abstractDb, parent=None):
"""
Constructor
"""
@@ -55,7 +57,7 @@ def __init__(self, permissionManager, abstractDb, parent = None):
self.abstractDbFactory = DbFactory()
self.populateTreeDict()
-
+
def __del__(self):
"""
Destructor
@@ -70,26 +72,30 @@ def populateTreeDict(self):
"""
try:
geomTypeDict = self.abstractDb.getGeomTypeDict()
- geomDict = self.abstractDb.getGeomDict(geomTypeDict, insertCategory = True)
+ geomDict = self.abstractDb.getGeomDict(geomTypeDict, insertCategory=True)
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("A problem occurred! Check log for details."),
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return
version = self.abstractDb.getDatabaseVersion()
self.profile = dict()
categories = dict()
for layerName in list(geomDict.keys()):
- schema = geomDict[layerName]['schema']
- category = geomDict[layerName]['category']
+ schema = geomDict[layerName]["schema"]
+ category = geomDict[layerName]["category"]
if schema not in list(categories.keys()):
categories[schema] = dict()
if category not in list(categories[schema].keys()):
categories[schema][category] = dict()
if layerName not in categories[schema][category]:
categories[schema][category][layerName] = dict()
- categories[schema][category][layerName]['read'] = '0'
- categories[schema][category][layerName]['write'] = '0'
- self.profile['database'+'_'+version] = categories
+ categories[schema][category][layerName]["read"] = "0"
+ categories[schema][category][layerName]["write"] = "0"
+ self.profile["database" + "_" + version] = categories
@pyqtSlot()
def on_buttonBox_accepted(self):
@@ -97,7 +103,9 @@ def on_buttonBox_accepted(self):
Creates the profile file
"""
if not self.lineEdit.text():
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Fill the profile name!'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Fill the profile name!")
+ )
return
else:
profileName = self.lineEdit.text()
@@ -105,7 +113,15 @@ def on_buttonBox_accepted(self):
edgvVersion = self.versionCombo.currentText()
if edgvVersion in list(permissionDict.keys()):
if profileName in permissionDict[edgvVersion]:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profile ') + profileName + self.tr(' for EDGV ') + edgvVersion + self.tr(' already exists!'))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Profile ")
+ + profileName
+ + self.tr(" for EDGV ")
+ + edgvVersion
+ + self.tr(" already exists!"),
+ )
return
jsonDict = json.dumps(self.profile, sort_keys=True, indent=4)
self.permissionManager.createSetting(profileName, edgvVersion, jsonDict)
diff --git a/DsgTools/gui/DatabaseTools/UserTools/create_profile.py b/DsgTools/gui/DatabaseTools/UserTools/create_profile.py
index ce4303906..fe5b75df2 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/create_profile.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/create_profile.py
@@ -34,13 +34,15 @@
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'create_profile.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "create_profile.ui")
+)
+
class CreateProfile(QtWidgets.QDialog, FORM_CLASS):
profileCreated = pyqtSignal(str)
-
- def __init__(self, parent = None):
+
+ def __init__(self, parent=None):
"""
Constructor
"""
@@ -51,13 +53,13 @@ def __init__(self, parent = None):
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
- self.folder = os.path.join(os.path.dirname(__file__), 'profiles')
+ self.folder = os.path.join(os.path.dirname(__file__), "profiles")
self.abstractDb = None
self.abstractDbFactory = DbFactory()
self.populateTreeDict()
-
+
def __del__(self):
"""
Destructor
@@ -65,28 +67,54 @@ def __del__(self):
if self.abstractDb:
del self.abstractDb
self.abstractDb = None
-
+
def getDbInfo(self):
"""
Gets database info. This info is used to create a profile model that will be adjusted by the user
"""
currentPath = os.path.dirname(__file__)
- if self.versionCombo.currentText() == '2.1.3':
- edgvPath = os.path.join(currentPath, '..', 'DbTools', 'SpatialiteTool', 'template', '213', 'seed_edgv213.sqlite')
- elif self.versionCombo.currentText() == 'FTer_2a_Ed':
- edgvPath = os.path.join(currentPath, '..', 'DbTools', 'SpatialiteTool', 'template', 'FTer_2a_Ed', 'seed_edgvfter_2a_ed.sqlite')
-
- self.abstractDb = self.abstractDbFactory.createDbFactory(DsgEnums.DriverSpatiaLite)
+ if self.versionCombo.currentText() == "2.1.3":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "DbTools",
+ "SpatialiteTool",
+ "template",
+ "213",
+ "seed_edgv213.sqlite",
+ )
+ elif self.versionCombo.currentText() == "FTer_2a_Ed":
+ edgvPath = os.path.join(
+ currentPath,
+ "..",
+ "DbTools",
+ "SpatialiteTool",
+ "template",
+ "FTer_2a_Ed",
+ "seed_edgvfter_2a_ed.sqlite",
+ )
+
+ self.abstractDb = self.abstractDbFactory.createDbFactory(
+ DsgEnums.DriverSpatiaLite
+ )
if not self.abstractDb:
- QtWidgets.QMessageBox.warning(self, self.tr('Warning!'), self.tr('A problem occurred! Check log for details.'))
+ QtWidgets.QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("A problem occurred! Check log for details."),
+ )
return
self.abstractDb.connectDatabase(edgvPath)
try:
self.abstractDb.checkAndOpenDb()
except Exception as e:
- QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ QtWidgets.QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("A problem occurred! Check log for details."),
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
def populateTreeDict(self):
"""
@@ -98,34 +126,46 @@ def populateTreeDict(self):
try:
tables = self.abstractDb.getTablesFromDatabase()
except Exception as e:
- QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
-
+ QtWidgets.QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("A problem occurred! Check log for details."),
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
+
self.profile = dict()
categories = dict()
for tableName in tables:
- #proceed only for edgv tables
- if tableName.split("_")[-1] == "p" or tableName.split("_")[-1] == "l" or tableName.split("_")[-1] == "a" or tableName.split("_")[0] == 'complexos' or tableName.split("_")[0] == 'dominios':
- layerName = tableName.split('_')[0]+'.'+'_'.join(tableName.split('_')[1::])
- split = tableName.split('_')
-
+ # proceed only for edgv tables
+ if (
+ tableName.split("_")[-1] == "p"
+ or tableName.split("_")[-1] == "l"
+ or tableName.split("_")[-1] == "a"
+ or tableName.split("_")[0] == "complexos"
+ or tableName.split("_")[0] == "dominios"
+ ):
+ layerName = (
+ tableName.split("_")[0] + "." + "_".join(tableName.split("_")[1::])
+ )
+ split = tableName.split("_")
+
if len(split) < 2:
continue
-
+
schema = split[0]
category = split[1]
if schema not in list(categories.keys()):
categories[schema] = dict()
-
+
if category not in list(categories[schema].keys()):
categories[schema][category] = dict()
if layerName not in categories[schema][category]:
categories[schema][category][layerName] = dict()
- categories[schema][category][layerName]['read'] = '0'
- categories[schema][category][layerName]['write'] = '0'
-
- self.profile['database'+'_'+self.versionCombo.currentText()] = categories
+ categories[schema][category][layerName]["read"] = "0"
+ categories[schema][category][layerName]["write"] = "0"
+
+ self.profile["database" + "_" + self.versionCombo.currentText()] = categories
@pyqtSlot()
def on_buttonBox_accepted(self):
@@ -133,14 +173,16 @@ def on_buttonBox_accepted(self):
Creates the profile file
"""
if not self.lineEdit.text():
- QtWidgets.QMessageBox.warning(self, self.tr('Warning!'), self.tr('Fill the profile name!'))
+ QtWidgets.QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Fill the profile name!")
+ )
return
else:
profileName = self.lineEdit.text()
-
- path = os.path.join(self.folder, profileName+'.json')
-
- with open(path, 'w') as outfile:
+
+ path = os.path.join(self.folder, profileName + ".json")
+
+ with open(path, "w") as outfile:
json.dump(self.profile, outfile, sort_keys=True, indent=4)
self.profileCreated.emit(profileName)
diff --git a/DsgTools/gui/DatabaseTools/UserTools/create_user.py b/DsgTools/gui/DatabaseTools/UserTools/create_user.py
index be5374f69..5bd542071 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/create_user.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/create_user.py
@@ -27,11 +27,13 @@
from qgis.PyQt.QtCore import pyqtSlot
from qgis.PyQt.QtSql import QSqlQuery
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'create_user.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "create_user.ui")
+)
+
class CreateUser(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, user = None, abstractDb = None, parent = None):
+ def __init__(self, user=None, abstractDb=None, parent=None):
"""
Constructor
"""
@@ -44,16 +46,16 @@ def __init__(self, user = None, abstractDb = None, parent = None):
self.setupUi(self)
self.abstractDb = abstractDb
self.refreshScreen()
-
+
def refreshScreen(self):
"""
Restores the initial state
"""
- self.userLineEdit.setText('')
- self.passwordLineEdit.setText('')
- self.passwordLineEdit_2.setText('')
+ self.userLineEdit.setText("")
+ self.passwordLineEdit.setText("")
+ self.passwordLineEdit_2.setText("")
self.superUserCheckBox.setCheckState(0)
-
+
@pyqtSlot(bool)
def on_createUserButton_clicked(self):
"""
@@ -63,11 +65,14 @@ def on_createUserButton_clicked(self):
password = self.passwordLineEdit.text()
password_2 = self.passwordLineEdit_2.text()
if password != password_2:
- QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), self.tr('Password mismatch! User not created!'))
+ QtWidgets.QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("Password mismatch! User not created!"),
+ )
self.refreshScreen()
return
-
-
+
if self.superUserCheckBox.checkState() == 2:
isSuperUser = True
else:
@@ -76,11 +81,19 @@ def on_createUserButton_clicked(self):
try:
self.abstractDb.createUser(user, password, isSuperUser)
except Exception as e:
- QtWidgets.QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QtWidgets.QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.refreshScreen()
return
- QtWidgets.QMessageBox.warning(self, self.tr('Success!'), self.tr('User ') +user+self.tr(' created successfully on server ')+self.abstractDb.getHostName()+'!')
+ QtWidgets.QMessageBox.warning(
+ self,
+ self.tr("Success!"),
+ self.tr("User ")
+ + user
+ + self.tr(" created successfully on server ")
+ + self.abstractDb.getHostName()
+ + "!",
+ )
self.refreshScreen()
return
diff --git a/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py b/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py
index ac3594d94..d4367592d 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/dbProfileManager.py
@@ -28,16 +28,32 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'dbProfileManager.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "dbProfileManager.ui")
+)
+
class DbProfileManager(QtWidgets.QDialog, FORM_CLASS):
-
- def __init__(self, grantedProfileList, notGrantedProfileList, permissionManager, userName, dbName, edgvVersion, parent = None):
+ def __init__(
+ self,
+ grantedProfileList,
+ notGrantedProfileList,
+ permissionManager,
+ userName,
+ dbName,
+ edgvVersion,
+ parent=None,
+ ):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
@@ -47,54 +63,80 @@ def __init__(self, grantedProfileList, notGrantedProfileList, permissionManager,
self.userName = userName
self.dbName = dbName
self.edgvVersion = edgvVersion
- self.profileCustomSelector.setTitle(self.tr('Manage permissions to user ') + userName + self.tr(' on database ') + dbName)
- self.profileCustomSelector.setFromList(list(notGrantedProfileList), unique = True) #passes a copy using list()
+ self.profileCustomSelector.setTitle(
+ self.tr("Manage permissions to user ")
+ + userName
+ + self.tr(" on database ")
+ + dbName
+ )
+ self.profileCustomSelector.setFromList(
+ list(notGrantedProfileList), unique=True
+ ) # passes a copy using list()
self.profileCustomSelector.setToList(list(grantedProfileList))
-
+
@pyqtSlot(bool)
def on_applyPushButton_clicked(self):
- permissionsToGrant = [i for i in self.profileCustomSelector.toLs if i not in self.grantedProfileList]
- profilesToRevoke = [i for i in self.profileCustomSelector.fromLs if i not in self.notGrantedProfileList]
- #grant operation
- header = self.tr('Grant / Revoke operation complete: ')
+ permissionsToGrant = [
+ i
+ for i in self.profileCustomSelector.toLs
+ if i not in self.grantedProfileList
+ ]
+ profilesToRevoke = [
+ i
+ for i in self.profileCustomSelector.fromLs
+ if i not in self.notGrantedProfileList
+ ]
+ # grant operation
+ header = self.tr("Grant / Revoke operation complete: ")
successList = []
errorDict = dict()
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
for profileName in permissionsToGrant:
try:
- self.permissionManager.grantPermission(self.dbName, profileName, self.edgvVersion, self.userName) #TODO: add error treatment
+ self.permissionManager.grantPermission(
+ self.dbName, profileName, self.edgvVersion, self.userName
+ ) # TODO: add error treatment
successList.append(profileName)
except Exception as e:
errorDict[profileName] = str(e.args[0])
for profileName in profilesToRevoke:
try:
- self.permissionManager.revokePermission(self.dbName, profileName, self.userName) #TODO: add error treatment
+ self.permissionManager.revokePermission(
+ self.dbName, profileName, self.userName
+ ) # TODO: add error treatment
successList.append(profileName)
except Exception as e:
- errorDict[profileName] = ':'.join(e.args)
+ errorDict[profileName] = ":".join(e.args)
QApplication.restoreOverrideCursor()
self.outputMessage(header, successList, errorDict)
self.close()
-
+
@pyqtSlot(bool)
def on_cancelPushButton_clicked(self):
- self.close()
-
+ self.close()
+
def outputMessage(self, header, successList, exceptionDict):
msg = header
if len(successList) > 0:
- msg += self.tr('\nSuccessful profiles: ')
- msg +=', '.join(successList)
+ msg += self.tr("\nSuccessful profiles: ")
+ msg += ", ".join(successList)
msg += self.logInternalError(exceptionDict)
- QMessageBox.warning(self, self.tr('Operation Complete!'), msg)
-
+ QMessageBox.warning(self, self.tr("Operation Complete!"), msg)
+
def logInternalError(self, exceptionDict):
- msg = ''
+ msg = ""
errorDbList = list(exceptionDict.keys())
- if len(errorDbList)> 0:
- msg += self.tr('\Profiles with error:')
- msg+= ', '.join(errorDbList)
- msg+= self.tr('\nError messages for each profile were output in qgis log.')
+ if len(errorDbList) > 0:
+ msg += self.tr("\Profiles with error:")
+ msg += ", ".join(errorDbList)
+ msg += self.tr("\nError messages for each profile were output in qgis log.")
for errorDb in errorDbList:
- QgsMessageLog.logMessage(self.tr('Error for profile ')+ errorDb + ': ' +exceptionDict[errorDb], "DSGTools Plugin", Qgis.Critical)
- return msg
\ No newline at end of file
+ QgsMessageLog.logMessage(
+ self.tr("Error for profile ")
+ + errorDb
+ + ": "
+ + exceptionDict[errorDb],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ return msg
diff --git a/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py b/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py
index 5bffb7a2c..16d165751 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/manageServerUsers.py
@@ -28,29 +28,38 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt, QSettings
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
from qgis.PyQt.QtSql import QSqlDatabase, QSqlQuery
# DSGTools imports
from DsgTools.gui.DatabaseTools.UserTools.create_user import CreateUser
from DsgTools.gui.DatabaseTools.UserTools.alter_user_password import AlterUserPassword
-from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties
+from DsgTools.gui.DatabaseTools.UserTools.permission_properties import (
+ PermissionProperties,
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'manageServerUsers.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "manageServerUsers.ui")
+)
+
class ManageServerUsers(QtWidgets.QDialog, FORM_CLASS):
-
- def __init__(self, abstractDb, parent = None):
+ def __init__(self, abstractDb, parent=None):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
self.abstractDb = abstractDb
- self.userTypeDict = {True:self.tr('Super User'), False:self.tr('User')}
+ self.userTypeDict = {True: self.tr("Super User"), False: self.tr("User")}
self.populateUsers()
-
+
def populateUsers(self):
self.serverUserTable.clear()
rootNode = self.serverUserTable.invisibleRootItem()
@@ -60,36 +69,51 @@ def populateUsers(self):
try:
ret = self.abstractDb.getUsersFromServer()
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
for user, type in ret:
userNameItem = self.createItem(rootNode, user, 0)
- userNameItem.setText(1,self.userTypeDict[type])
-
+ userNameItem.setText(1, self.userTypeDict[type])
+
def createItem(self, parent, text, column):
item = QtWidgets.QTreeWidgetItem(parent)
item.setText(column, text)
return item
-
+
@pyqtSlot(bool)
def on_createUserButton_clicked(self):
if not self.abstractDb:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a database!")
+ )
return
dlg = CreateUser(abstractDb=self.abstractDb)
dlg.exec_()
self.populateUsers()
-
- @pyqtSlot(bool)
+
+ @pyqtSlot(bool)
def on_removeUserButton_clicked(self):
selectedUsers = self.serverUserTable.selectedItems()
if not self.abstractDb:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a database!")
+ )
return
if len(selectedUsers) == 0:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user to remove!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a user to remove!")
+ )
return
selectedUserNames = [i.text(0) for i in selectedUsers]
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to remove users: ')+', '.join(selectedUserNames), QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to remove users: ")
+ + ", ".join(selectedUserNames),
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
exceptionDict = dict()
successList = []
@@ -98,44 +122,53 @@ def on_removeUserButton_clicked(self):
self.abstractDb.reassignAndDropUser(user)
successList.append(user)
except Exception as e:
- exceptionDict[user] = ':'.join(e.args)
- header = self.tr('Drop user(s) operation complete!\n')
+ exceptionDict[user] = ":".join(e.args)
+ header = self.tr("Drop user(s) operation complete!\n")
self.outputMessage(header, successList, exceptionDict)
- self.populateUsers()
+ self.populateUsers()
@pyqtSlot(bool)
def on_alterPasswordButton_clicked(self):
selectedUsers = self.serverUserTable.selectedItems()
selectedUserNames = [i.text(0) for i in selectedUsers]
if not self.abstractDb:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a database!")
+ )
return
if len(selectedUsers) == 0:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user to remove!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a user to remove!")
+ )
return
- dlg = AlterUserPassword(userList = selectedUserNames, abstractDb = self.abstractDb)
+ dlg = AlterUserPassword(userList=selectedUserNames, abstractDb=self.abstractDb)
dlg.exec_()
-
+
@pyqtSlot(bool)
def on_closeButton_clicked(self):
self.done(0)
-
+
def outputMessage(self, header, successList, exceptionDict):
msg = header
if len(successList) > 0:
- msg += self.tr('\nSuccessful users: ')
- msg +=', '.join(successList)
+ msg += self.tr("\nSuccessful users: ")
+ msg += ", ".join(successList)
msg += self.logInternalError(exceptionDict)
- QMessageBox.warning(self, self.tr('Operation Complete!'), msg)
+ QMessageBox.warning(self, self.tr("Operation Complete!"), msg)
def logInternalError(self, exceptionDict):
- msg = ''
+ msg = ""
errorDbList = list(exceptionDict.keys())
- if len(errorDbList)> 0:
- msg += self.tr('\nUsers with error:')
- msg+= ', '.join(errorDbList)
- msg+= self.tr('\nError messages for each user were output in qgis log.')
+ if len(errorDbList) > 0:
+ msg += self.tr("\nUsers with error:")
+ msg += ", ".join(errorDbList)
+ msg += self.tr("\nError messages for each user were output in qgis log.")
for errorDb in errorDbList:
- QgsMessageLog.logMessage(self.tr('Error for user {user}: {exception}').format(user=errorDb, exception=exceptionDict[errorDb]), "DSGTools Plugin", Qgis.Critical)
- return msg
-
\ No newline at end of file
+ QgsMessageLog.logMessage(
+ self.tr("Error for user {user}: {exception}").format(
+ user=errorDb, exception=exceptionDict[errorDb]
+ ),
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ return msg
diff --git a/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py b/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py
index 1872345b1..29a2c48a7 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/permission_properties.py
@@ -29,11 +29,13 @@
# DSGTools imports
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'permission_properties.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "permission_properties.ui")
+)
+
class PermissionProperties(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, permissionsDict, parent = None):
+ def __init__(self, permissionsDict, parent=None):
"""
Constructor
"""
@@ -45,17 +47,17 @@ def __init__(self, permissionsDict, parent = None):
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
self.treeWidget.setColumnWidth(0, 400)
-
- #invisible root item
+
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
- dbItem = self.createItem(rootItem, 'database')
+ # database item
+ dbItem = self.createItem(rootItem, "database")
self.createChildrenItems(dbItem, permissionsDict)
-
+
self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.treeWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
-
+
def createItem(self, parent, text):
"""
Creates a tree widget item
@@ -68,15 +70,15 @@ def createItem(self, parent, text):
item.setCheckState(2, QtCore.Qt.Unchecked)
item.setText(0, text)
return item
-
+
def createChildrenItems(self, parent, mydict):
"""
Creates children items
parent: parent item
mydict: data dictionary used to populate tree items
"""
- #permissions
- lista = ['read', 'write']
+ # permissions
+ lista = ["read", "write"]
for key in list(mydict.keys()):
if key in lista:
self.setItemCheckState(parent, mydict, key)
@@ -84,13 +86,12 @@ def createChildrenItems(self, parent, mydict):
itemText = key
item = self.createItem(parent, itemText)
self.createChildrenItems(item, mydict[key])
-
+
def setItemCheckState(self, item, mydict, key):
"""
Sets item check state
"""
- if key == 'read':
+ if key == "read":
item.setCheckState(1, int(mydict[key]))
- elif key == 'write':
+ elif key == "write":
item.setCheckState(2, int(mydict[key]))
-
\ No newline at end of file
diff --git a/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py b/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py
index 425211b51..e1cdee9ed 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/profileUserManager.py
@@ -27,16 +27,32 @@
# Qt imports
from qgis.PyQt import QtWidgets, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt
-from qgis.PyQt.QtWidgets import QListWidgetItem, QMessageBox, QMenu, QApplication, QFileDialog
+from qgis.PyQt.QtWidgets import (
+ QListWidgetItem,
+ QMessageBox,
+ QMenu,
+ QApplication,
+ QFileDialog,
+)
from qgis.PyQt.QtGui import QCursor
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'profileUserManager.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "profileUserManager.ui")
+)
+
class ProfileUserManager(QtWidgets.QDialog, FORM_CLASS):
-
- def __init__(self, grantedUserList, notGrantedUserList, permissionManager, profileName, dbName, edgvVersion, parent = None):
+ def __init__(
+ self,
+ grantedUserList,
+ notGrantedUserList,
+ permissionManager,
+ profileName,
+ dbName,
+ edgvVersion,
+ parent=None,
+ ):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
@@ -46,54 +62,78 @@ def __init__(self, grantedUserList, notGrantedUserList, permissionManager, profi
self.profileName = profileName
self.dbName = dbName
self.edgvVersion = edgvVersion
- self.userCustomSelector.setTitle(self.tr('Manage user permissions to profile ') + profileName + self.tr(' on database ') + dbName)
- self.userCustomSelector.setFromList(list(notGrantedUserList), unique = True) #passes a copy using list()
+ self.userCustomSelector.setTitle(
+ self.tr("Manage user permissions to profile ")
+ + profileName
+ + self.tr(" on database ")
+ + dbName
+ )
+ self.userCustomSelector.setFromList(
+ list(notGrantedUserList), unique=True
+ ) # passes a copy using list()
self.userCustomSelector.setToList(list(grantedUserList))
-
+
@pyqtSlot(bool)
def on_applyPushButton_clicked(self):
- usersToGrant = [i for i in self.userCustomSelector.toLs if i not in self.grantedUserList]
- usersToRevoke = [i for i in self.userCustomSelector.fromLs if i not in self.notGrantedUserList]
- #grant operation
- header = self.tr('Grant / Revoke operation complete: ')
+ usersToGrant = [
+ i for i in self.userCustomSelector.toLs if i not in self.grantedUserList
+ ]
+ usersToRevoke = [
+ i
+ for i in self.userCustomSelector.fromLs
+ if i not in self.notGrantedUserList
+ ]
+ # grant operation
+ header = self.tr("Grant / Revoke operation complete: ")
successList = []
errorDict = dict()
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
for userName in usersToGrant:
try:
- self.permissionManager.grantPermission(self.dbName, self.profileName, self.edgvVersion, userName)
+ self.permissionManager.grantPermission(
+ self.dbName, self.profileName, self.edgvVersion, userName
+ )
successList.append(userName)
except Exception as e:
- errorDict[userName] = ':'.join(e.args)
+ errorDict[userName] = ":".join(e.args)
for userName in usersToRevoke:
try:
- self.permissionManager.revokePermission(self.dbName, self.profileName, userName)
+ self.permissionManager.revokePermission(
+ self.dbName, self.profileName, userName
+ )
successList.append(userName)
except Exception as e:
- errorDict[userName] = ':'.join(e.args)
+ errorDict[userName] = ":".join(e.args)
QApplication.restoreOverrideCursor()
self.outputMessage(header, successList, errorDict)
self.close()
-
+
@pyqtSlot(bool)
def on_cancelPushButton_clicked(self):
- self.close()
-
+ self.close()
+
def outputMessage(self, header, successList, exceptionDict):
msg = header
if len(successList) > 0:
- msg += self.tr('\nSuccessful users: ')
- msg +=', '.join(successList)
+ msg += self.tr("\nSuccessful users: ")
+ msg += ", ".join(successList)
msg += self.logInternalError(exceptionDict)
- QMessageBox.warning(self, self.tr('Operation Complete!'), msg)
-
+ QMessageBox.warning(self, self.tr("Operation Complete!"), msg)
+
def logInternalError(self, exceptionDict):
- msg = ''
+ msg = ""
errorDbList = list(exceptionDict.keys())
- if len(errorDbList)> 0:
- msg += self.tr('\nUsers with error:')
- msg+= ', '.join(errorDbList)
- msg+= self.tr('\nError messages for each user were output in qgis log.')
+ if len(errorDbList) > 0:
+ msg += self.tr("\nUsers with error:")
+ msg += ", ".join(errorDbList)
+ msg += self.tr("\nError messages for each user were output in qgis log.")
for errorDb in errorDbList:
- QgsMessageLog.logMessage(self.tr('Error for user ')+ errorDb + ': ' +exceptionDict[errorDb], "DSGTools Plugin", Qgis.Critical)
- return msg
\ No newline at end of file
+ QgsMessageLog.logMessage(
+ self.tr("Error for user ")
+ + errorDb
+ + ": "
+ + exceptionDict[errorDb],
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ return msg
diff --git a/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py b/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py
index 389e7b9e6..c6c1996a1 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/profile_editor.py
@@ -33,11 +33,13 @@
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'profile_editor.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "profile_editor.ui")
+)
+
class ProfileEditor(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""
Constructor
"""
@@ -49,27 +51,27 @@ def __init__(self, parent = None):
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
self.treeWidget.setColumnWidth(0, 400)
-
- self.folder = os.path.join(os.path.dirname(__file__), 'profiles')
+
+ self.folder = os.path.join(os.path.dirname(__file__), "profiles")
self.getProfiles()
self.setInitialState()
-
- def getProfiles(self, profileName = None):
+
+ def getProfiles(self, profileName=None):
"""
Get profile files and insert them in the combo box
"""
ret = []
for root, dirs, files in os.walk(self.folder):
for file in files:
- ext = file.split('.')[-1]
- if ext == 'json':
- ret.append(file.split('.')[0])
+ ext = file.split(".")[-1]
+ if ext == "json":
+ ret.append(file.split(".")[0])
ret.sort()
self.jsonCombo.clear()
- self.jsonCombo.addItem(self.tr('Select a profile'))
+ self.jsonCombo.addItem(self.tr("Select a profile"))
self.jsonCombo.addItems(ret)
-
+
index = self.jsonCombo.findText(profileName)
if index != -1:
self.jsonCombo.setCurrentIndex(index)
@@ -85,33 +87,37 @@ def setInitialState(self):
self.treeWidget.clear()
return
else:
- profile = os.path.join(self.folder, self.jsonCombo.currentText()+'.json')
+ profile = os.path.join(self.folder, self.jsonCombo.currentText() + ".json")
self.readJsonFile(profile)
self.treeWidget.sortByColumn(0, QtCore.Qt.AscendingOrder)
-
+
def createItem(self, parent, text):
"""
Creates tree widget items
"""
item = QtWidgets.QTreeWidgetItem(parent)
- item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable)
+ item.setFlags(
+ QtCore.Qt.ItemIsEnabled
+ | QtCore.Qt.ItemIsTristate
+ | QtCore.Qt.ItemIsUserCheckable
+ )
item.setCheckState(1, QtCore.Qt.Unchecked)
item.setCheckState(2, QtCore.Qt.Unchecked)
item.setText(0, text)
return item
-
+
def makeProfileDict(self):
"""
Makes a dictionary out of the tree widget items
"""
profileDict = dict()
-
- #invisible root item
+
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
+ # database item
dbItem = rootItem.child(0)
permissions = dict()
-
+
schema_count = dbItem.childCount()
for i in range(schema_count):
schemaItem = dbItem.child(i)
@@ -123,38 +129,40 @@ def makeProfileDict(self):
layer_count = categoryItem.childCount()
for k in range(layer_count):
layerItem = categoryItem.child(k)
- permissions[schemaItem.text(0)][categoryItem.text(0)][layerItem.text(0)] = self.getItemCheckState(layerItem)
-
- profileDict[self.parent] = permissions
+ permissions[schemaItem.text(0)][categoryItem.text(0)][
+ layerItem.text(0)
+ ] = self.getItemCheckState(layerItem)
+
+ profileDict[self.parent] = permissions
return profileDict
-
+
def readJsonFile(self, filename):
"""
Reads the profile file, gets a dictionary of it and builds the tree widget
"""
try:
- file = open(filename, 'r')
+ file = open(filename, "r")
data = file.read()
profileDict = json.loads(data)
self.parent = list(profileDict.keys())[0]
file.close()
except:
return
-
- #invisible root item
+
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
+ # database item
dbItem = self.createItem(rootItem, self.parent)
permissions = profileDict[self.parent]
self.createChildrenItems(dbItem, permissions)
-
+
def createChildrenItems(self, parent, mydict):
"""
Creates children item in the tree widget
"""
- #permissions
- lista = ['read', 'write']
+ # permissions
+ lista = ["read", "write"]
for key in list(mydict.keys()):
if key in lista:
self.setItemCheckState(parent, mydict, key)
@@ -162,32 +170,32 @@ def createChildrenItems(self, parent, mydict):
itemText = key
item = self.createItem(parent, itemText)
self.createChildrenItems(item, mydict[key])
-
+
def setItemCheckState(self, item, mydict, key):
"""
Sets the item check state
"""
- if key == 'read':
+ if key == "read":
item.setCheckState(1, int(mydict[key]))
- elif key == 'write':
+ elif key == "write":
item.setCheckState(2, int(mydict[key]))
-
+
def getItemCheckState(self, item):
"""
Gets the item check state for READ and WRITE columns
"""
ret = dict()
- ret['read'] = str(item.checkState(1))
- ret['write'] = str(item.checkState(2))
+ ret["read"] = str(item.checkState(1))
+ ret["write"] = str(item.checkState(2))
return ret
-
+
@pyqtSlot(int)
def on_jsonCombo_currentIndexChanged(self):
"""
Slot to update the initial state
"""
self.setInitialState()
-
+
@pyqtSlot(bool)
def on_createButton_clicked(self):
"""
@@ -196,49 +204,57 @@ def on_createButton_clicked(self):
dlg = CreateProfile()
dlg.profileCreated.connect(self.getProfiles)
dlg.exec_()
-
+
@pyqtSlot(bool)
def on_clearButton_clicked(self):
"""
Clears the tree widget
"""
- #invisible root item
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
+ # database item
dbItem = rootItem.child(0)
if dbItem:
dbItem.setCheckState(1, 0)
dbItem.setCheckState(2, 0)
-
+
@pyqtSlot(bool)
def on_saveButton_clicked(self):
"""
Saves the profile file
"""
if self.jsonCombo.currentIndex() == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select a profile model!'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Select a profile model!")
+ )
return
else:
profile = self.jsonCombo.currentText()
-
- path = os.path.join(self.folder, profile+'.json')
-
+
+ path = os.path.join(self.folder, profile + ".json")
+
try:
- with open(path, 'w') as outfile:
+ with open(path, "w") as outfile:
json.dump(self.makeProfileDict(), outfile, sort_keys=True, indent=4)
except Exception as e:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Problem saving file! \n')+':'.join(e.args))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Problem saving file! \n") + ":".join(e.args),
+ )
return
-
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profile saved successfully!'))
-
+
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Profile saved successfully!")
+ )
+
@pyqtSlot(bool)
def on_closeButton_clicked(self):
"""
Closes the dialog
"""
self.close()
-
+
@pyqtSlot(bool)
def on_deletePushButton_clicked(self):
"""
@@ -247,12 +263,26 @@ def on_deletePushButton_clicked(self):
"""
if self.jsonCombo.currentIndex() != 0:
profileName = self.jsonCombo.currentText()
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to remove profile ')+profileName+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to remove profile ")
+ + profileName
+ + "?",
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
try:
- os.remove(os.path.join(self.folder,profileName+'.json'))
+ os.remove(os.path.join(self.folder, profileName + ".json"))
except Exception as e:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Problem deleting profile! \n')+':'.join(e.args))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Problem deleting profile! \n") + ":".join(e.args),
+ )
return
self.getProfiles()
- self.setInitialState()
\ No newline at end of file
+ self.setInitialState()
diff --git a/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py b/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py
index ebb832d22..e3b80a749 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/serverProfilesManager.py
@@ -33,17 +33,24 @@
from qgis.core import QgsMessageLog
# DSGTools imports
-from DsgTools.gui.DatabaseTools.UserTools.createProfileWithProfileManager import CreateProfileWithProfileManager
-from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import GenericParameterSetter
+from DsgTools.gui.DatabaseTools.UserTools.createProfileWithProfileManager import (
+ CreateProfileWithProfileManager,
+)
+from DsgTools.gui.CustomWidgets.DatabasePropertiesWidgets.BasicPropertyWidgets.genericParameterSetter import (
+ GenericParameterSetter,
+)
import json
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'serverProfilesManager.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "serverProfilesManager.ui")
+)
+
class ServerProfilesManager(QtWidgets.QDialog, FORM_CLASS):
profilesChanged = pyqtSignal()
- def __init__(self, permissionManager, parent = None):
+
+ def __init__(self, permissionManager, parent=None):
"""
Constructor
"""
@@ -56,30 +63,34 @@ def __init__(self, permissionManager, parent = None):
self.setupUi(self)
self.permissionManager = permissionManager
self.refreshProfileList()
-
+
def createItem(self, parent, text):
"""
Creates tree widget items
"""
item = QtWidgets.QTreeWidgetItem(parent)
- item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsTristate | QtCore.Qt.ItemIsUserCheckable)
+ item.setFlags(
+ QtCore.Qt.ItemIsEnabled
+ | QtCore.Qt.ItemIsTristate
+ | QtCore.Qt.ItemIsUserCheckable
+ )
item.setCheckState(1, QtCore.Qt.Unchecked)
item.setCheckState(2, QtCore.Qt.Unchecked)
item.setText(0, text)
return item
-
+
def makeProfileDict(self):
"""
Makes a dictionary out of the tree widget items
"""
profileDict = dict()
-
- #invisible root item
+
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
+ # database item
dbItem = rootItem.child(0)
permissions = dict()
-
+
schema_count = dbItem.childCount()
for i in range(schema_count):
schemaItem = dbItem.child(i)
@@ -91,11 +102,13 @@ def makeProfileDict(self):
layer_count = categoryItem.childCount()
for k in range(layer_count):
layerItem = categoryItem.child(k)
- permissions[schemaItem.text(0)][categoryItem.text(0)][layerItem.text(0)] = self.getItemCheckState(layerItem)
-
- profileDict[self.parent] = permissions
+ permissions[schemaItem.text(0)][categoryItem.text(0)][
+ layerItem.text(0)
+ ] = self.getItemCheckState(layerItem)
+
+ profileDict[self.parent] = permissions
return profileDict
-
+
def readJsonFromDatabase(self, profileName, edgvVersion):
"""
Reads the profile file, gets a dictionary of it and builds the tree widget
@@ -103,21 +116,21 @@ def readJsonFromDatabase(self, profileName, edgvVersion):
profileDict = self.permissionManager.getSetting(profileName, edgvVersion)
self.parent = list(profileDict.keys())[0]
- #invisible root item
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
+ # database item
dbItem = self.createItem(rootItem, self.parent)
permissions = profileDict[self.parent]
self.createChildrenItems(dbItem, permissions)
self.treeWidget.sortItems(0, Qt.AscendingOrder)
-
+
def createChildrenItems(self, parent, mydict):
"""
Creates children item in the tree widget
"""
- #permissions
- lista = ['read', 'write']
+ # permissions
+ lista = ["read", "write"]
for key in list(mydict.keys()):
if key in lista:
self.setItemCheckState(parent, mydict, key)
@@ -125,145 +138,203 @@ def createChildrenItems(self, parent, mydict):
itemText = key
item = self.createItem(parent, itemText)
self.createChildrenItems(item, mydict[key])
-
+
def setItemCheckState(self, item, mydict, key):
"""
Sets the item check state
"""
- if key == 'read':
+ if key == "read":
item.setCheckState(1, int(mydict[key]))
- elif key == 'write':
+ elif key == "write":
item.setCheckState(2, int(mydict[key]))
-
+
def getItemCheckState(self, item):
"""
Gets the item check state for READ and WRITE columns
"""
ret = dict()
- ret['read'] = str(item.checkState(1))
- ret['write'] = str(item.checkState(2))
+ ret["read"] = str(item.checkState(1))
+ ret["write"] = str(item.checkState(2))
return ret
-
+
@pyqtSlot(bool)
def on_clearButton_clicked(self):
"""
Clears the tree widget
"""
- #invisible root item
+ # invisible root item
rootItem = self.treeWidget.invisibleRootItem()
- #database item
+ # database item
dbItem = rootItem.child(0)
if dbItem:
dbItem.setCheckState(1, 0)
dbItem.setCheckState(2, 0)
-
+
@pyqtSlot(bool)
def on_closeButton_clicked(self):
"""
Closes the dialog
"""
self.close()
-
+
def refreshProfileList(self):
self.profilesListWidget.clear()
self.treeWidget.clear()
self.setEnabled(False)
profilesDict = self.permissionManager.getSettings()
for edgvVersion in list(profilesDict.keys()):
- self.profilesListWidget.addItems([i + ' ({0})'.format(edgvVersion) for i in profilesDict[edgvVersion]] )
- self.profilesListWidget.sortItems(order = Qt.AscendingOrder)
-
+ self.profilesListWidget.addItems(
+ [i + " ({0})".format(edgvVersion) for i in profilesDict[edgvVersion]]
+ )
+ self.profilesListWidget.sortItems(order=Qt.AscendingOrder)
+
@pyqtSlot(bool)
def on_createPermissionPushButton_clicked(self):
"""
Slot that opens the create profile dialog
"""
- #use selector
+ # use selector
permissionDict = self.permissionManager.getSettings()
- parameterDlg = GenericParameterSetter(nameList = list(permissionDict.keys()))
+ parameterDlg = GenericParameterSetter(nameList=list(permissionDict.keys()))
if not parameterDlg.exec_():
return
templateDb, profileName, edgvVersion = parameterDlg.getParameters()
if edgvVersion in list(permissionDict.keys()):
if profileName in permissionDict[edgvVersion]:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Profile ') + profileName + self.tr(' for EDGV ') + edgvVersion + self.tr(' already exists!'))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Profile ")
+ + profileName
+ + self.tr(" for EDGV ")
+ + edgvVersion
+ + self.tr(" already exists!"),
+ )
return
newItem = self.populateTreeDict(templateDb, edgvVersion)
jsonDict = json.dumps(newItem, sort_keys=True, indent=4)
self.permissionManager.createSetting(profileName, edgvVersion, jsonDict)
self.updateInterface(profileName, edgvVersion)
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Profile ') + profileName + self.tr(' created successfully!'))
-
+ QMessageBox.warning(
+ self,
+ self.tr("Success!"),
+ self.tr("Profile ") + profileName + self.tr(" created successfully!"),
+ )
+
def setEnabled(self, enabled):
self.treeWidget.setEnabled(enabled)
self.saveButton.setEnabled(enabled)
self.clearButton.setEnabled(enabled)
-
+
@pyqtSlot()
def on_profilesListWidget_itemSelectionChanged(self):
- profileName, edgvVersion = self.profilesListWidget.currentItem().text().split(' (')
- edgvVersion = edgvVersion.replace(')','')
+ profileName, edgvVersion = (
+ self.profilesListWidget.currentItem().text().split(" (")
+ )
+ edgvVersion = edgvVersion.replace(")", "")
try:
self.setEnabled(True)
self.treeWidget.clear()
self.readJsonFromDatabase(profileName, edgvVersion)
except:
pass
-
+
def updateInterface(self, profileName, edgvVersion):
self.refreshProfileList()
- profileItem = self.profilesListWidget.findItems(profileName + ' ({0})'.format(edgvVersion), Qt.MatchExactly)[0]
+ profileItem = self.profilesListWidget.findItems(
+ profileName + " ({0})".format(edgvVersion), Qt.MatchExactly
+ )[0]
self.profilesListWidget.setCurrentItem(profileItem)
-
+
@pyqtSlot(bool)
def on_deletePermissionPushButton_clicked(self):
if self.profilesListWidget.currentItem() is not None:
- profileName, edgvVersion = self.profilesListWidget.currentItem().text().split(' (')
- edgvVersion = edgvVersion.replace(')','')
- if QMessageBox.question(self, self.tr('Question'), self.tr('Do you really want to delete profile ')+profileName+'?', QMessageBox.Ok|QMessageBox.Cancel) == QMessageBox.Cancel:
+ profileName, edgvVersion = (
+ self.profilesListWidget.currentItem().text().split(" (")
+ )
+ edgvVersion = edgvVersion.replace(")", "")
+ if (
+ QMessageBox.question(
+ self,
+ self.tr("Question"),
+ self.tr("Do you really want to delete profile ")
+ + profileName
+ + "?",
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Cancel
+ ):
return
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.permissionManager.deleteSetting(profileName, edgvVersion)
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission ') + profileName + self.tr(' successfully deleted.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Success!"),
+ self.tr("Permission ")
+ + profileName
+ + self.tr(" successfully deleted."),
+ )
self.refreshProfileList()
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem deleting permission: ') + ':'.join(e.args))
-
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem deleting permission: ") + ":".join(e.args),
+ )
+
@pyqtSlot(bool)
def on_saveButton_clicked(self):
- profileName, edgvVersion = self.profilesListWidget.currentItem().text().split(' (')
- edgvVersion = edgvVersion.replace(')','')
+ profileName, edgvVersion = (
+ self.profilesListWidget.currentItem().text().split(" (")
+ )
+ edgvVersion = edgvVersion.replace(")", "")
newProfileDict = self.makeProfileDict()
try:
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
- self.permissionManager.updateSetting(profileName, edgvVersion, newProfileDict)
+ self.permissionManager.updateSetting(
+ profileName, edgvVersion, newProfileDict
+ )
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Success!'), self.tr('Permission ') + profileName + self.tr(' successfully updated.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Success!"),
+ self.tr("Permission ")
+ + profileName
+ + self.tr(" successfully updated."),
+ )
except Exception as e:
QApplication.restoreOverrideCursor()
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Error! Problem updating permission: ') + ':'.join(e.args))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("Error! Problem updating permission: ") + ":".join(e.args),
+ )
def populateTreeDict(self, abstractDb, version):
"""
Makes a tree widget were the user can define profile properties
"""
try:
- #get a dict with all tables from database
+ # get a dict with all tables from database
geomList = abstractDb.getTablesJsonList()
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('A problem occurred! Check log for details.'))
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ QMessageBox.critical(
+ self,
+ self.tr("Critical!"),
+ self.tr("A problem occurred! Check log for details."),
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
return
profile = dict()
categories = dict()
for jsonItem in geomList:
- layerName = jsonItem['table_name']
- schema = jsonItem['table_schema']
- if version != 'Non_EDGV':
- category = layerName.split('_')[0]
+ layerName = jsonItem["table_name"]
+ schema = jsonItem["table_schema"]
+ if version != "Non_EDGV":
+ category = layerName.split("_")[0]
else:
category = schema
if schema not in list(categories.keys()):
@@ -272,7 +343,7 @@ def populateTreeDict(self, abstractDb, version):
categories[schema][category] = dict()
if layerName not in categories[schema][category]:
categories[schema][category][layerName] = dict()
- categories[schema][category][layerName]['read'] = '0'
- categories[schema][category][layerName]['write'] = '0'
- profile['database'+'_'+version] = categories
- return profile
\ No newline at end of file
+ categories[schema][category][layerName]["read"] = "0"
+ categories[schema][category][layerName]["write"] = "0"
+ profile["database" + "_" + version] = categories
+ return profile
diff --git a/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py b/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py
index a23bbe33e..f4004ca68 100644
--- a/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py
+++ b/DsgTools/gui/DatabaseTools/UserTools/user_profiles.py
@@ -36,13 +36,17 @@
from DsgTools.gui.DatabaseTools.UserTools.assign_profiles import AssignProfiles
from DsgTools.gui.DatabaseTools.UserTools.create_user import CreateUser
from DsgTools.gui.DatabaseTools.UserTools.alter_user_password import AlterUserPassword
-from DsgTools.gui.DatabaseTools.UserTools.permission_properties import PermissionProperties
+from DsgTools.gui.DatabaseTools.UserTools.permission_properties import (
+ PermissionProperties,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "user_profiles.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'user_profiles.ui'))
class ManageUserProfiles(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, parent = None):
+ def __init__(self, parent=None):
"""
Constructor
"""
@@ -55,27 +59,33 @@ def __init__(self, parent = None):
self.setupUi(self)
self.widget.tabWidget.setTabEnabled(1, False)
self.widget.serverWidget.superNeeded = True
- #Objects Connections
- QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("connectionChanged()")), self.populateUsers)
-
+ # Objects Connections
+ QtCore.QObject.connect(
+ self.widget, QtCore.SIGNAL(("connectionChanged()")), self.populateUsers
+ )
+
self.installedProfiles.setContextMenuPolicy(Qt.CustomContextMenu)
- self.installedProfiles.customContextMenuRequested.connect(self.createMenuInstalled)
+ self.installedProfiles.customContextMenuRequested.connect(
+ self.createMenuInstalled
+ )
self.assignedProfiles.setContextMenuPolicy(Qt.CustomContextMenu)
- self.assignedProfiles.customContextMenuRequested.connect(self.createMenuAssigned)
+ self.assignedProfiles.customContextMenuRequested.connect(
+ self.createMenuAssigned
+ )
def createMenuInstalled(self, position):
"""
Creates a pop up menu to show permission properties
"""
menu = QMenu()
-
+
item = self.installedProfiles.itemAt(position)
- if item:
- menu.addAction(self.tr('Show properties'), self.showInstalledProperties)
-
+ if item:
+ menu.addAction(self.tr("Show properties"), self.showInstalledProperties)
+
menu.exec_(self.installedProfiles.viewport().mapToGlobal(position))
-
+
def showInstalledProperties(self):
"""
Shows the installed permission's properties dialog
@@ -86,13 +96,15 @@ def showInstalledProperties(self):
permissionsDict = dict()
try:
- permissionsDict = self.widget.abstractDb.getRolePrivileges(permission, dbname)
+ permissionsDict = self.widget.abstractDb.getRolePrivileges(
+ permission, dbname
+ )
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
-
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
+
dlg = PermissionProperties(permissionsDict)
dlg.exec_()
-
+
def createMenuAssigned(self, position):
"""
Creates a pop up menu to show properties of a permission assigned to a user
@@ -102,7 +114,7 @@ def createMenuAssigned(self, position):
item = self.assignedProfiles.itemAt(position)
if item:
- menu.addAction(self.tr('Show properties'), self.showAssignedProperties)
+ menu.addAction(self.tr("Show properties"), self.showAssignedProperties)
menu.exec_(self.assignedProfiles.viewport().mapToGlobal(position))
@@ -116,9 +128,11 @@ def showAssignedProperties(self):
permissionsDict = dict()
try:
- permissionsDict = self.widget.abstractDb.getRolePrivileges(permission, dbname)
+ permissionsDict = self.widget.abstractDb.getRolePrivileges(
+ permission, dbname
+ )
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
dlg = PermissionProperties(permissionsDict)
dlg.exec_()
@@ -128,19 +142,19 @@ def populateUsers(self):
Populates postgresql users list
"""
self.comboBox.clear()
-
+
if not self.widget.abstractDb:
return
-
+
ret = []
try:
ret = self.widget.abstractDb.getUsers()
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
-
- self.comboBox.addItem(self.tr('Select a User'))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
+
+ self.comboBox.addItem(self.tr("Select a User"))
self.comboBox.addItems(ret)
-
+
def getProfiles(self, username):
"""
Gets the installed and assigned profiles related to a user
@@ -151,27 +165,32 @@ def getProfiles(self, username):
if self.comboBox.currentIndex() == 0:
return
-
+
if not self.widget.abstractDb:
return
-
+
self.installed, self.assigned = [], []
try:
- self.installed, self.assigned = self.widget.abstractDb.getUserRelatedRoles(username)
+ self.installed, self.assigned = self.widget.abstractDb.getUserRelatedRoles(
+ username
+ )
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.installedProfiles.addItems(self.installed)
self.assignedProfiles.addItems(self.assigned)
-
+
@pyqtSlot(bool)
def on_installProfile_clicked(self):
"""
Slot to install profile
"""
- dlg = AssignProfiles(self.widget.serverWidget.serversCombo.currentIndex(),self.widget.comboBoxPostgis.currentIndex())
+ dlg = AssignProfiles(
+ self.widget.serverWidget.serversCombo.currentIndex(),
+ self.widget.comboBoxPostgis.currentIndex(),
+ )
dlg.exec_()
- self.getProfiles(self.comboBox.currentText())
+ self.getProfiles(self.comboBox.currentText())
@pyqtSlot(bool)
def on_createUserButton_clicked(self):
@@ -179,35 +198,43 @@ def on_createUserButton_clicked(self):
Slot to open create user dialog
"""
if not self.widget.abstractDb:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a database!")
+ )
return
- dlg = CreateUser(self.comboBox.currentText(),self.widget.abstractDb)
+ dlg = CreateUser(self.comboBox.currentText(), self.widget.abstractDb)
dlg.exec_()
self.populateUsers()
-
- @pyqtSlot(bool)
+
+ @pyqtSlot(bool)
def on_removeUserButton_clicked(self):
"""
Slot to remove user
"""
user = self.comboBox.currentText()
if not self.widget.abstractDb:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a database!")
+ )
return
if self.comboBox.currentIndex() == 0:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user to remove!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a user to remove!")
+ )
return
try:
self.widget.abstractDb.removeUser(user)
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.getProfiles(user)
return
self.getProfiles(user)
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('User removed successfully!'))
- self.populateUsers()
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("User removed successfully!")
+ )
+ self.populateUsers()
@pyqtSlot(bool)
def on_alterPasswordButton_clicked(self):
@@ -216,10 +243,14 @@ def on_alterPasswordButton_clicked(self):
"""
user = self.comboBox.currentText()
if not self.widget.abstractDb:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a database!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a database!")
+ )
return
if self.comboBox.currentIndex() == 0:
- QMessageBox.critical(self, self.tr('Critical!'), self.tr('First select a user!'))
+ QMessageBox.critical(
+ self, self.tr("Critical!"), self.tr("First select a user!")
+ )
return
dlg = AlterUserPassword(user, self.widget.abstractDb)
dlg.exec_()
@@ -230,7 +261,7 @@ def on_comboBox_currentIndexChanged(self):
Slot to update assigned and installed profiles
"""
self.getProfiles(self.comboBox.currentText())
-
+
def saveUserState(self):
"""
Saves the user state.
@@ -246,7 +277,7 @@ def saveUserState(self):
for i in range(self.assignedProfiles.__len__()):
role = self.assignedProfiles.item(i).text()
profiles1.append(role)
-
+
for role in profiles1:
if role not in self.assigned:
grant.append(role)
@@ -255,16 +286,16 @@ def saveUserState(self):
for i in range(self.installedProfiles.__len__()):
role = self.installedProfiles.item(i).text()
profiles2.append(role)
-
+
for role in profiles2:
if role not in self.installed:
revoke.append(role)
-
+
for role in grant:
try:
self.widget.abstractDb.grantRole(user, role)
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), e.args[0])
+ QMessageBox.critical(self, self.tr("Critical!"), e.args[0])
self.getProfiles(user)
return
@@ -272,20 +303,22 @@ def saveUserState(self):
try:
self.widget.abstractDb.revokeRole(user, role)
except Exception as e:
- QMessageBox.critical(self, self.tr('Critical!'), ':'.join(e.args))
+ QMessageBox.critical(self, self.tr("Critical!"), ":".join(e.args))
self.getProfiles(user)
return
self.getProfiles(user)
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('User updated successfully!'))
-
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("User updated successfully!")
+ )
+
@pyqtSlot(bool)
def on_closeButton_clicked(self):
"""
Closes the dialog
"""
self.close()
-
+
@pyqtSlot(bool)
def on_insertAllButton_clicked(self):
"""
@@ -293,14 +326,18 @@ def on_insertAllButton_clicked(self):
"""
tam = self.installedProfiles.__len__()
if tam == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('No profiles installed! Install at least one and try again.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("No profiles installed! Install at least one and try again."),
+ )
return
-
- for i in range(tam+1,1,-1):
- item = self.installedProfiles.takeItem(i-2)
+
+ for i in range(tam + 1, 1, -1):
+ item = self.installedProfiles.takeItem(i - 2)
self.assignedProfiles.addItem(item)
self.assignedProfiles.sortItems()
-
+
self.saveUserState()
@pyqtSlot(bool)
@@ -310,11 +347,15 @@ def on_removeAllButton_clicked(self):
"""
tam = self.assignedProfiles.__len__()
if tam == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('No profiles assigned! Assign at least one and try again.'))
+ QMessageBox.warning(
+ self,
+ self.tr("Warning!"),
+ self.tr("No profiles assigned! Assign at least one and try again."),
+ )
return
-
- for i in range(tam+1,1,-1):
- item = self.assignedProfiles.takeItem(i-2)
+
+ for i in range(tam + 1, 1, -1):
+ item = self.assignedProfiles.takeItem(i - 2)
self.installedProfiles.addItem(item)
self.installedProfiles.sortItems()
@@ -327,9 +368,11 @@ def on_insertButton_clicked(self):
"""
listedItems = self.installedProfiles.selectedItems()
if len(listedItems) == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select a profile first!'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Select a profile first!")
+ )
return
-
+
for i in listedItems:
item = self.installedProfiles.takeItem(self.installedProfiles.row(i))
self.assignedProfiles.addItem(item)
@@ -344,12 +387,14 @@ def on_removeButton_clicked(self):
"""
listedItems = self.assignedProfiles.selectedItems()
if len(listedItems) == 0:
- QMessageBox.warning(self, self.tr('Warning!'), self.tr('Select a profile first!'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Select a profile first!")
+ )
return
-
+
for i in listedItems:
item = self.assignedProfiles.takeItem(self.assignedProfiles.row(i))
self.installedProfiles.addItem(item)
self.installedProfiles.sortItems()
- self.saveUserState()
\ No newline at end of file
+ self.saveUserState()
diff --git a/DsgTools/gui/DatabaseTools/databaseManager.py b/DsgTools/gui/DatabaseTools/databaseManager.py
index 5a76e501e..34b5c50df 100644
--- a/DsgTools/gui/DatabaseTools/databaseManager.py
+++ b/DsgTools/gui/DatabaseTools/databaseManager.py
@@ -24,12 +24,18 @@
from qgis.PyQt.QtCore import QObject
-from DsgTools.gui.DatabaseTools.DbTools.SingleDbCreator.singleDbCreator import CreateSingleDatabase
-from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.batchDbCreator import BatchDbCreator
-from DsgTools.gui.DatabaseTools.ConversionTools.datasourceConversion import DatasourceConversion
+from DsgTools.gui.DatabaseTools.DbTools.SingleDbCreator.singleDbCreator import (
+ CreateSingleDatabase,
+)
+from DsgTools.gui.DatabaseTools.DbTools.BatchDbCreator.batchDbCreator import (
+ BatchDbCreator,
+)
+from DsgTools.gui.DatabaseTools.ConversionTools.datasourceConversion import (
+ DatasourceConversion,
+)
-class DatabaseGuiManager(QObject):
+class DatabaseGuiManager(QObject):
def __init__(self, manager, iface, parentMenu=None, toolbar=None):
"""Constructor.
:param iface: An interface instance that will be passed to this class
@@ -44,13 +50,17 @@ def __init__(self, manager, iface, parentMenu=None, toolbar=None):
self.parentMenu = parentMenu
# self.dbAbstract = dbAbstract
self.toolbar = toolbar
- self.menu = self.manager.addMenu(u'databasetools', self.tr('Database Tools'),'database.png')
- self.stackButton = self.manager.createToolButton(self.toolbar, u'DatabaseTools')
- self.iconBasePath = ':/plugins/DsgTools/icons/'
+ self.menu = self.manager.addMenu(
+ "databasetools", self.tr("Database Tools"), "database.png"
+ )
+ self.stackButton = self.manager.createToolButton(self.toolbar, "DatabaseTools")
+ self.iconBasePath = ":/plugins/DsgTools/icons/"
self.singleDbCreator = None
self.batchCreator = None
-
- def addTool(self, text, callback, parentMenu, icon, parentButton=None, defaultButton=False):
+
+ def addTool(
+ self, text, callback, parentMenu, icon, parentButton=None, defaultButton=False
+ ):
"""
Prepares the funcionalities to be added to both the DSGTools menu and it's shortcut button into QGIS main interface.
:param text: (str) text to be shown when the action is hovered over.
@@ -58,7 +68,7 @@ def addTool(self, text, callback, parentMenu, icon, parentButton=None, defaultBu
:param parentMenu: (QMenu) menu to which action will be added.
:param parentButton: (QButton) button to which action will be associated.
:param defaultButton: (bool) considering it is a stack button (button overloaded with >1 actions associated), it indicates
- whether the included action will be the default one (e.g. if it will the action representative and
+ whether the included action will be the default one (e.g. if it will the action representative and
1st to be displayed).
"""
icon_path = self.iconBasePath + icon
@@ -71,34 +81,36 @@ def addTool(self, text, callback, parentMenu, icon, parentButton=None, defaultBu
withShortcut=False,
parentToolbar=parentMenu,
isCheckable=False,
- parentButton=self.stackButton
+ parentButton=self.stackButton,
)
if defaultButton:
self.stackButton.setDefaultAction(action)
def initGui(self):
"""
- Instantiates all available database creation GUI.
+ Instantiates all available database creation GUI.
"""
- callback = lambda : self.createDatabase(isBatchCreation=False)
+ callback = lambda: self.createDatabase(isBatchCreation=False)
self.addTool(
- text=self.tr('Create a PostGIS or SpatiaLite Database'),
+ text=self.tr("Create a PostGIS or SpatiaLite Database"),
callback=callback,
parentMenu=self.menu,
- icon='database.png',
+ icon="database.png",
parentButton=self.stackButton,
- defaultButton=True
+ defaultButton=True,
)
- callback = lambda : self.createDatabase(isBatchCreation=True)
+ callback = lambda: self.createDatabase(isBatchCreation=True)
self.addTool(
- text=self.tr('Create batches of PostGIS or SpatiaLite Databases'),
+ text=self.tr("Create batches of PostGIS or SpatiaLite Databases"),
callback=callback,
parentMenu=self.menu,
- icon='batchDatabase.png',
+ icon="batchDatabase.png",
parentButton=self.stackButton,
- defaultButton=False
+ defaultButton=False,
+ )
+ self.datasourceConversion = DatasourceConversion(
+ manager=self, parentMenu=self.menu, parentButton=self.stackButton
)
- self.datasourceConversion = DatasourceConversion(manager=self, parentMenu=self.menu, parentButton=self.stackButton)
self.datasourceConversion.initGui()
def unload(self):
@@ -122,11 +134,15 @@ def createDatabase(self, isBatchCreation):
pass
if not isBatchCreation:
if self.singleDbCreator is None:
- self.singleDbCreator = CreateSingleDatabase(manager=self, parentButton=self.stackButton, parentMenu=self.menu)
+ self.singleDbCreator = CreateSingleDatabase(
+ manager=self, parentButton=self.stackButton, parentMenu=self.menu
+ )
dlg = self.singleDbCreator
else:
if self.batchCreator is None:
- self.batchCreator = BatchDbCreator(manager=self, parentButton=self.stackButton, parentMenu=self.menu)
+ self.batchCreator = BatchDbCreator(
+ manager=self, parentButton=self.stackButton, parentMenu=self.menu
+ )
dlg = self.batchCreator
if dlg:
result = dlg.exec_()
diff --git a/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py b/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py
index bc08b9246..7086b06df 100644
--- a/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py
+++ b/DsgTools/gui/LayerTools/CreateFrameTool/ui_create_inom_dialog.py
@@ -24,25 +24,34 @@
from __future__ import print_function
from builtins import str
from builtins import range
-from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform, \
- QgsProcessingContext, QgsFeature
+from qgis.core import (
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsProcessingContext,
+ QgsFeature,
+)
from qgis.PyQt import QtWidgets, QtCore, uic, QtGui
from qgis.PyQt.QtWidgets import QMessageBox
from qgis.PyQt.QtCore import pyqtSlot, Qt
from qgis.PyQt.QtGui import QCursor
import os
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'ui_create_inom_dialog_base.ui'))
-#DsgTools imports
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "ui_create_inom_dialog_base.ui")
+)
+
+# DsgTools imports
from DsgTools.core.Utils.FrameTools.map_index import UtmGrid
-from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory
+from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import (
+ LayerLoaderFactory,
+)
-#qgis imports
+# qgis imports
import qgis as qgis
import processing
+
class CreateInomDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, iface, parent=None):
"""Constructor."""
@@ -65,11 +74,15 @@ def on_okButton_clicked(self):
Creates the actual frame.
"""
if not self.widget.dbLoaded:
- QMessageBox.warning(self, self.tr("Warning!"), self.tr('Please, select a database first.'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Please, select a database first.")
+ )
return
if not self.validateMI():
- QMessageBox.warning(self, self.tr("Warning!"), self.tr('Map name index not valid!'))
+ QMessageBox.warning(
+ self, self.tr("Warning!"), self.tr("Map name index not valid!")
+ )
return
try:
QtWidgets.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
@@ -80,29 +93,30 @@ def on_okButton_clicked(self):
QtWidgets.QApplication.restoreOverrideCursor()
raise e
self.done(1)
-
+
def runCreateFrameAndAddFeaturesToFrame(self, layer):
crs = self.widget.crs.authid()
inom = self.inomLineEdit.text()
scaleIdx = self.scaleCombo.currentIndex()
context = QgsProcessingContext()
processingOutput = processing.run(
- 'dsgtools:gridzonegenerator',
+ "dsgtools:gridzonegenerator",
{
- 'START_SCALE' : scaleIdx,
- 'STOP_SCALE' : scaleIdx,
- 'INDEX_TYPE' : 1,
- 'INDEX' : inom,
- 'CRS' : crs,
- 'OUTPUT' : 'memory:'
+ "START_SCALE": scaleIdx,
+ "STOP_SCALE": scaleIdx,
+ "INDEX_TYPE": 1,
+ "INDEX": inom,
+ "CRS": crs,
+ "OUTPUT": "memory:",
},
- context = context)
+ context=context,
+ )
featList = []
- for feat in processingOutput['OUTPUT'].getFeatures():
+ for feat in processingOutput["OUTPUT"].getFeatures():
newFeat = QgsFeature(layer.fields())
- newFeat['mi'] = feat['mi']
- newFeat['inom'] = feat['inom']
- newFeat['escala'] = self.scaleCombo.currentText()
+ newFeat["mi"] = feat["mi"]
+ newFeat["inom"] = feat["inom"]
+ newFeat["escala"] = self.scaleCombo.currentText()
newFeat.setGeometry(feat.geometry())
newFeat.geometry().convertToMultiType()
featList.append(newFeat)
@@ -110,7 +124,7 @@ def runCreateFrameAndAddFeaturesToFrame(self, layer):
layer.addFeatures(featList)
layer.commitChanges()
self.zoomToLayer(layer, featList[0].geometry())
-
+
def zoomToLayer(self, layer, frame):
"""
Zooms in to the updated frame layer.
@@ -122,47 +136,63 @@ def zoomToLayer(self, layer, frame):
bbox = self.iface.mapCanvas().mapSettings().layerToMapCoordinates(layer, bbox)
self.iface.mapCanvas().setExtent(bbox)
self.iface.mapCanvas().refresh()
-
+
def loadFrameLayer(self):
"""
Loads the frame layer case it is not loaded yet.
"""
- loader = LayerLoaderFactory().makeLoader(self.iface,self.widget.abstractDb)
- if loader.provider == 'postgres':
- layerMeta = {'cat': 'aux', 'geom': 'geom', 'geomType':'MULTIPOLYGON', 'lyrName': 'moldura_a', 'tableName':'aux_moldura_a', 'tableSchema':'public', 'tableType': 'BASE TABLE'}
- elif loader.provider == 'spatialite':
- layerMeta = {'cat': 'aux', 'geom': 'GEOMETRY', 'geomType':'MULTIPOLYGON', 'lyrName': 'moldura_a', 'tableName':'aux_moldura_a', 'tableSchema':'public', 'tableType': 'BASE TABLE'}
+ loader = LayerLoaderFactory().makeLoader(self.iface, self.widget.abstractDb)
+ if loader.provider == "postgres":
+ layerMeta = {
+ "cat": "aux",
+ "geom": "geom",
+ "geomType": "MULTIPOLYGON",
+ "lyrName": "moldura_a",
+ "tableName": "aux_moldura_a",
+ "tableSchema": "public",
+ "tableType": "BASE TABLE",
+ }
+ elif loader.provider == "spatialite":
+ layerMeta = {
+ "cat": "aux",
+ "geom": "GEOMETRY",
+ "geomType": "MULTIPOLYGON",
+ "lyrName": "moldura_a",
+ "tableName": "aux_moldura_a",
+ "tableSchema": "public",
+ "tableType": "BASE TABLE",
+ }
else:
layerMeta = None
- layerDict = loader.load([layerMeta], uniqueLoad = True)
- if layerMeta['lyrName'] in list(layerDict.keys()):
- layer = layerDict[layerMeta['lyrName']]
+ layerDict = loader.load([layerMeta], uniqueLoad=True)
+ if layerMeta["lyrName"] in list(layerDict.keys()):
+ layer = layerDict[layerMeta["lyrName"]]
else:
layer = None
return layer
- def getFrameLayer(self,ifaceLayers):
+ def getFrameLayer(self, ifaceLayers):
"""
Gets the frame layer according to the database.
"""
for lyr in ifaceLayers:
- if 'moldura_a' in lyr.name():
+ if "moldura_a" in lyr.name():
dbname = self.getDBNameFromLayer(lyr)
if dbname == self.widget.abstractDb.getDatabaseName():
return lyr
return None
-
+
def getDBNameFromLayer(self, lyr):
"""
Gets the database name according to the database.
"""
dbname = None
- splitUri = lyr.dataProvider().dataSourceUri().split(' ')
+ splitUri = lyr.dataProvider().dataSourceUri().split(" ")
if len(splitUri) > 0:
- dbsplit = splitUri[0].split('=')
- if len(dbsplit) > 1 and dbsplit[0] == 'dbname':
+ dbsplit = splitUri[0].split("=")
+ if len(dbsplit) > 1 and dbsplit[0] == "dbname":
dbnameInString = dbsplit[1]
- dbnameSplit = dbnameInString.split('\'')
+ dbnameSplit = dbnameInString.split("'")
if len(dbnameSplit) > 1:
dbname = dbnameSplit[1]
return dbname
@@ -173,41 +203,41 @@ def on_cancelButton_clicked(self):
Closes the dialog returning 0.
"""
self.done(0)
-
+
@pyqtSlot(str)
- def on_inomLineEdit_textEdited(self,s):
+ def on_inomLineEdit_textEdited(self, s):
"""
Method to automatically update MI based on the INOM.
It also changes all characters to upper case
"""
- if (s!=''):
+ if s != "":
s = s.upper()
self.inomLineEdit.setText(s)
mi = self.map_index.getMIfromInom(str(s))
self.miLineEdit.setText(mi)
@pyqtSlot(str)
- def on_miLineEdit_textEdited(self,s):
+ def on_miLineEdit_textEdited(self, s):
"""
Method to automatically update INOM based on the MI.
It also changes all characters to upper case
"""
- if (s!=''):
+ if s != "":
s = s.upper()
self.miLineEdit.setText(s)
- self.inomen=self.map_index.getINomenFromMI(str(s))
+ self.inomen = self.map_index.getINomenFromMI(str(s))
self.inomLineEdit.setText(self.inomen)
@pyqtSlot(str)
- def on_mirLineEdit_textEdited(self,s):
+ def on_mirLineEdit_textEdited(self, s):
"""
Method to automatically update INOM based on the MIR.
It also changes all characters to upper case
"""
- if (s!=''):
+ if s != "":
s = s.upper()
self.mirLineEdit.setText(s)
- self.inomen=self.map_index.getINomenFromMIR(str(s))
+ self.inomen = self.map_index.getINomenFromMIR(str(s))
self.inomLineEdit.setText(self.inomen)
def reprojectFrame(self, poly):
@@ -229,79 +259,151 @@ def setValidCharacters(self):
"""
self.chars = []
- chars = 'NS'
+ chars = "NS"
self.chars.append(chars)
- chars = 'ABCDEFGHIJKLMNOPQRSTUVZ'
+ chars = "ABCDEFGHIJKLMNOPQRSTUVZ"
self.chars.append(chars)
- chars = ['01','02','03','04','05','06','07','08','09','10',
- '11','12','13','14','15','16','17','18','19','20',
- '21','22','23','24','25','26','27','28','29','30',
- '31','32','33','34','35','36','37','38','39','40',
- '41','42','43','44','45','46','47','48','49','50',
- '51','52','53','54','55','56','57','58','59','60']
+ chars = [
+ "01",
+ "02",
+ "03",
+ "04",
+ "05",
+ "06",
+ "07",
+ "08",
+ "09",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "15",
+ "16",
+ "17",
+ "18",
+ "19",
+ "20",
+ "21",
+ "22",
+ "23",
+ "24",
+ "25",
+ "26",
+ "27",
+ "28",
+ "29",
+ "30",
+ "31",
+ "32",
+ "33",
+ "34",
+ "35",
+ "36",
+ "37",
+ "38",
+ "39",
+ "40",
+ "41",
+ "42",
+ "43",
+ "44",
+ "45",
+ "46",
+ "47",
+ "48",
+ "49",
+ "50",
+ "51",
+ "52",
+ "53",
+ "54",
+ "55",
+ "56",
+ "57",
+ "58",
+ "59",
+ "60",
+ ]
self.chars.append(chars)
- chars = 'VXYZ'
+ chars = "VXYZ"
self.chars.append(chars)
- chars = 'ABCD'
+ chars = "ABCD"
self.chars.append(chars)
- chars = ['I','II','III','IV','V','VI']
+ chars = ["I", "II", "III", "IV", "V", "VI"]
self.chars.append(chars)
- chars = '1234'
+ chars = "1234"
self.chars.append(chars)
- chars = ['NO','NE','SO','SE']
+ chars = ["NO", "NE", "SO", "SE"]
self.chars.append(chars)
- chars = 'ABCDEF'
+ chars = "ABCDEF"
self.chars.append(chars)
- chars = ['I','II','III','IV']
+ chars = ["I", "II", "III", "IV"]
self.chars.append(chars)
- chars = '123456'
+ chars = "123456"
self.chars.append(chars)
- chars = 'ABCD'
+ chars = "ABCD"
self.chars.append(chars)
def setMask(self):
"""
REGEx closely related to the valid chars method 'setValidCharacters'
"""
- if self.scaleCombo.currentText() == '1000k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}')
+ if self.scaleCombo.currentText() == "1000k":
+ regex = QtCore.QRegExp("[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}")
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '500k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}')
+ elif self.scaleCombo.currentText() == "500k":
+ regex = QtCore.QRegExp("[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}")
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '250k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}')
+ elif self.scaleCombo.currentText() == "250k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '100k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}')
+ elif self.scaleCombo.currentText() == "100k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '50k':
- self.inomLineEdit.setInputMask('NN-NN-N-N-Nnn-0')
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}')
+ elif self.scaleCombo.currentText() == "50k":
+ self.inomLineEdit.setInputMask("NN-NN-N-N-Nnn-0")
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '25k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}')
+ elif self.scaleCombo.currentText() == "25k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '10k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}')
+ elif self.scaleCombo.currentText() == "10k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '5k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}')
+ elif self.scaleCombo.currentText() == "5k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '2k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}')
+ elif self.scaleCombo.currentText() == "2k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
- elif self.scaleCombo.currentText() == '1k':
- regex = QtCore.QRegExp('[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}\-[A-Da-d]{1}')
+ elif self.scaleCombo.currentText() == "1k":
+ regex = QtCore.QRegExp(
+ "[NSns]{1}[A-Za-z]{1}\-[0-9]{1,2}\-[V-Zv-z]{1}\-[A-Da-d]{1}\-[IViv]{1,3}\-[1-4]{1}\-[NSns]{1}[OEoe]{1}\-[A-Fa-f]{1}\-[IViv]{1,3}\-[1-6]{1}\-[A-Da-d]{1}"
+ )
validator = QtGui.QRegExpValidator(regex, self.inomLineEdit)
self.inomLineEdit.setValidator(validator)
@@ -310,7 +412,7 @@ def validateMI(self):
Method to validate INOM based on the valid characters.
"""
mi = self.inomLineEdit.text()
- split = mi.split('-')
+ split = mi.split("-")
for i in range(len(split)):
word = str(split[i])
if len(word) == 0:
@@ -390,7 +492,7 @@ def on_scaleCombo_currentIndexChanged(self):
Adjusts the mask according to the scale.
"""
self.setMask()
- if self.scaleCombo.currentText() == '1000k':
+ if self.scaleCombo.currentText() == "1000k":
self.miRadioButton.setEnabled(False)
self.miLineEdit.setEnabled(False)
self.mirRadioButton.setEnabled(True)
@@ -429,4 +531,4 @@ def on_inomRadioButton_toggled(self, toggled):
if toggled:
self.inomLineEdit.setEnabled(True)
else:
- self.inomLineEdit.setEnabled(False)
\ No newline at end of file
+ self.inomLineEdit.setEnabled(False)
diff --git a/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py b/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py
index 565c6a64a..71ec63d49 100644
--- a/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py
+++ b/DsgTools/gui/LayerTools/LoadLayersFromServer/loadLayersFromServer.py
@@ -239,6 +239,7 @@ def on_buttonBox_accepted(self):
QApplication.restoreOverrideCursor()
self.logInternalError(exceptionDict)
self.close()
+
def logInternalError(self, exceptionDict):
"""
Logs internal errors during the load process in QGIS' log
diff --git a/DsgTools/gui/LayerTools/layerToolsGuiManager.py b/DsgTools/gui/LayerTools/layerToolsGuiManager.py
index f311a8ac0..10d1412a8 100644
--- a/DsgTools/gui/LayerTools/layerToolsGuiManager.py
+++ b/DsgTools/gui/LayerTools/layerToolsGuiManager.py
@@ -29,44 +29,55 @@
from .LoadLayersFromServer.loadLayersFromServer import LoadLayersFromServer
from .CreateFrameTool.ui_create_inom_dialog import CreateInomDialog
-class LayerToolsGuiManager(QObject):
- def __init__(self, manager, iface, parentMenu = None, toolbar = None):
- """Constructor.
- """
+class LayerToolsGuiManager(QObject):
+ def __init__(self, manager, iface, parentMenu=None, toolbar=None):
+ """Constructor."""
super(LayerToolsGuiManager, self).__init__()
self.manager = manager
self.iface = iface
self.parentMenu = parentMenu
self.toolbar = toolbar
- self.menu = self.manager.addMenu(u'layers', self.tr('Layer Tools'),'layers.png')
- self.stackButton = self.manager.createToolButton(self.toolbar, u'LayerTools')
- self.iconBasePath = ':/plugins/DsgTools/icons/'
-
- def addTool(self, text, callback, parentMenu, icon, defaultButton = False):
+ self.menu = self.manager.addMenu("layers", self.tr("Layer Tools"), "layers.png")
+ self.stackButton = self.manager.createToolButton(self.toolbar, "LayerTools")
+ self.iconBasePath = ":/plugins/DsgTools/icons/"
+
+ def addTool(self, text, callback, parentMenu, icon, defaultButton=False):
icon_path = self.iconBasePath + icon
action = self.manager.add_action(
icon_path,
text=text,
callback=callback,
- add_to_menu = False,
- add_to_toolbar = False,
- withShortcut = False,
- parentToolbar = parentMenu,
- isCheckable = False
+ add_to_menu=False,
+ add_to_toolbar=False,
+ withShortcut=False,
+ parentToolbar=parentMenu,
+ isCheckable=False,
)
self.stackButton.addAction(action)
if defaultButton:
self.stackButton.setDefaultAction(action)
-
+
def initGui(self):
- #adding minimum area tool
- self.addTool(self.tr('Load Layers'), self.loadLayersFromServer, self.menu, 'category.png', defaultButton=True)
- self.addTool(self.tr('Create Frame'), self.createFrame, self.menu, 'frame.png', defaultButton=False)
-
+ # adding minimum area tool
+ self.addTool(
+ self.tr("Load Layers"),
+ self.loadLayersFromServer,
+ self.menu,
+ "category.png",
+ defaultButton=True,
+ )
+ self.addTool(
+ self.tr("Create Frame"),
+ self.createFrame,
+ self.menu,
+ "frame.png",
+ defaultButton=False,
+ )
+
def unload(self):
pass
-
+
def loadLayersFromServer(self):
"""
Shows the dialog that loads layers from server
@@ -86,4 +97,4 @@ def createFrame(self):
dlg.show()
result = dlg.exec_()
if result:
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/LayerTools/loadAuxStruct.py b/DsgTools/gui/LayerTools/loadAuxStruct.py
index 44b21ca0a..9c6ba93a0 100644
--- a/DsgTools/gui/LayerTools/loadAuxStruct.py
+++ b/DsgTools/gui/LayerTools/loadAuxStruct.py
@@ -9,7 +9,7 @@
git sha : $Format:%H$
copyright : (C) 2014 by Philipe Borba - Cartographic Engineer @ Brazilian Army
email : borba.philipe@eb.mil.br
- mod history :
+ mod history :
***************************************************************************/
/***************************************************************************
@@ -23,22 +23,26 @@
"""
import os, json
-#Qgis imports
+# Qgis imports
from qgis.gui import QgsMessageBar
from qgis.core import QgsMessageLog
-#PyQt imports
+# PyQt imports
from qgis.PyQt import QtWidgets, QtCore, uic
from qgis.PyQt.QtCore import pyqtSlot, Qt
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtGui import QCursor
import qgis as qgis
-#DsgTools imports
-from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import LayerLoaderFactory
+# DsgTools imports
+from DsgTools.core.Factories.LayerLoaderFactory.layerLoaderFactory import (
+ LayerLoaderFactory,
+)
+
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "loadAuxStruct.ui")
+)
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'loadAuxStruct.ui'))
class LoadAuxStruct(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, iface, parent=None):
@@ -50,18 +54,22 @@ def __init__(self, iface, parent=None):
self.iface = iface
self.layerFactory = LayerLoaderFactory()
self.selectedClasses = []
- self.widget.tabWidget.setTabEnabled(0,True)
- self.widget.tabWidget.setTabEnabled(1,False)
+ self.widget.tabWidget.setTabEnabled(0, True)
+ self.widget.tabWidget.setTabEnabled(1, False)
self.widget.tabWidget.setCurrentIndex(0)
self.bar = QgsMessageBar()
self.setLayout(QtGui.QGridLayout(self))
- self.layout().setContentsMargins(0,0,0,0)
+ self.layout().setContentsMargins(0, 0, 0, 0)
self.layout().setAlignment(QtCore.Qt.AlignTop)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+ sizePolicy = QtGui.QSizePolicy(
+ QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed
+ )
self.bar.setSizePolicy(sizePolicy)
- self.layout().addWidget(self.bar, 0,0,1,1)
+ self.layout().addWidget(self.bar, 0, 0, 1, 1)
- QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage)
+ QtCore.QObject.connect(
+ self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage
+ )
self.widget.dbChanged.connect(self.widgetConv.setDatabase)
@pyqtSlot(bool)
@@ -70,7 +78,7 @@ def on_pushButtonCancel_clicked(self):
Closes the dialog
"""
self.close()
-
+
def pushMessage(self, msg):
"""
Pushes a message into message bar
@@ -80,12 +88,16 @@ def pushMessage(self, msg):
@pyqtSlot(bool)
def on_pushButtonOk_clicked(self):
"""
- Checks the linee-centroid structure and loads the correspondent layers
+ Checks the linee-centroid structure and loads the correspondent layers
"""
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
if self.widgetConv.settingDict == dict():
QApplication.restoreOverrideCursor()
- self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load auxiliary classes! Check log for details!"), level=QgsMessageBar.CRITICAL)
+ self.bar.pushMessage(
+ self.tr("Error!"),
+ self.tr("Could not load auxiliary classes! Check log for details!"),
+ level=QgsMessageBar.CRITICAL,
+ )
else:
self.loadLayers()
QApplication.restoreOverrideCursor()
@@ -96,27 +108,34 @@ def loadLayers(self):
Loads the layers defined in the line-centroid structure
"""
try:
- if self.widget.abstractDb.getDatabaseVersion() == 'Non_EDGV':
+ if self.widget.abstractDb.getDatabaseVersion() == "Non_EDGV":
isEdgv = False
else:
isEdgv = True
- auxClassesDict = self.widgetConv.settingDict['earthCoverageDict']
+ auxClassesDict = self.widgetConv.settingDict["earthCoverageDict"]
auxClasses = []
for key in list(auxClassesDict.keys()):
for cl in auxClassesDict[key]:
if cl not in auxClasses:
- if '.' in cl:
- classToLoad = cl.split('.')[-1]
+ if "." in cl:
+ classToLoad = cl.split(".")[-1]
else:
classToLoad = cl
auxClasses.append(classToLoad)
auxCentroids = self.widgetConv.abstractDb.getEarthCoverageCentroids()
auxClasses = auxClasses + auxCentroids
auxClasses.sort(reverse=True)
- auxClasses = [self.widgetConv.settingDict['frameLayer'].split('.')[-1]]+auxClasses
- factory = self.layerFactory.makeLoader(self.iface, self.widget.abstractDb, loadCentroids=True)
- factory.load(auxClasses, uniqueLoad = True, isEdgv = isEdgv)
+ auxClasses = [
+ self.widgetConv.settingDict["frameLayer"].split(".")[-1]
+ ] + auxClasses
+ factory = self.layerFactory.makeLoader(
+ self.iface, self.widget.abstractDb, loadCentroids=True
+ )
+ factory.load(auxClasses, uniqueLoad=True, isEdgv=isEdgv)
except Exception as e:
- QgsMessageLog.logMessage(':'.join(e.args), "DSGTools Plugin", Qgis.Critical)
- self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load auxiliary classes! Check log for details!"), level=QgsMessageBar.CRITICAL)
-
\ No newline at end of file
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
+ self.bar.pushMessage(
+ self.tr("Error!"),
+ self.tr("Could not load auxiliary classes! Check log for details!"),
+ level=QgsMessageBar.CRITICAL,
+ )
diff --git a/DsgTools/gui/LayerTools/load_by_class.py b/DsgTools/gui/LayerTools/load_by_class.py
index 3ad6dea92..e1baf78e4 100644
--- a/DsgTools/gui/LayerTools/load_by_class.py
+++ b/DsgTools/gui/LayerTools/load_by_class.py
@@ -24,22 +24,24 @@
from builtins import range
import os
-#Qgis imports
+# Qgis imports
from qgis.gui import QgsMessageBar
from qgis.core import QgsMessageLog
-#PyQt imports
+# PyQt imports
from qgis.PyQt import QtWidgets, QtCore, uic
from qgis.PyQt.QtCore import Qt, pyqtSlot
from qgis.PyQt.QtWidgets import QApplication
from qgis.PyQt.QtGui import QCursor
import qgis as qgis
-#DsgTools imports
+# DsgTools imports
from DsgTools.core.Factories.LayerFactory.layerFactory import LayerFactory
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'load_by_class_base.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "load_by_class_base.ui")
+)
+
class LoadByClass(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, codeList, parent=None):
@@ -58,53 +60,73 @@ def __init__(self, codeList, parent=None):
self.bar = QgsMessageBar()
self.setLayout(QtGui.QGridLayout(self))
- self.layout().setContentsMargins(0,0,0,0)
+ self.layout().setContentsMargins(0, 0, 0, 0)
self.layout().setAlignment(QtCore.Qt.AlignTop)
- sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+ sizePolicy = QtGui.QSizePolicy(
+ QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed
+ )
self.bar.setSizePolicy(sizePolicy)
- self.layout().addWidget(self.bar, 0,0,1,1)
-
- #Objects Connections
- QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("connectionChanged()")), self.listClassesFromDatabase)
- QtCore.QObject.connect(self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage)
-
- QtCore.QObject.connect(self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel)
- QtCore.QObject.connect(self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll)
- QtCore.QObject.connect(self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected)
-
+ self.layout().addWidget(self.bar, 0, 0, 1, 1)
+
+ # Objects Connections
+ QtCore.QObject.connect(
+ self.widget,
+ QtCore.SIGNAL(("connectionChanged()")),
+ self.listClassesFromDatabase,
+ )
+ QtCore.QObject.connect(
+ self.widget, QtCore.SIGNAL(("problemOccurred()")), self.pushMessage
+ )
+
+ QtCore.QObject.connect(
+ self.pushButtonCancel, QtCore.SIGNAL(("clicked()")), self.cancel
+ )
+ QtCore.QObject.connect(
+ self.selectAllCheck, QtCore.SIGNAL(("stateChanged(int)")), self.selectAll
+ )
+ QtCore.QObject.connect(
+ self.pushButtonOk, QtCore.SIGNAL(("clicked()")), self.okSelected
+ )
+
self.widget.tabWidget.currentChanged.connect(self.restoreInitialState)
self.widget.styleChanged.connect(self.populateStyleCombo)
self.codeList = codeList
self.layerFactory = LayerFactory()
def restoreInitialState(self):
- '''
+ """
Restores the dialog initial state
- '''
+ """
self.selectedClasses = []
tam = self.classesListWidget.__len__()
- for i in range(tam+1,1,-1):
- item = self.classesListWidget.takeItem(i-2)
+ for i in range(tam + 1, 1, -1):
+ item = self.classesListWidget.takeItem(i - 2)
self.selectAllCheck.setCheckState(0)
def listClassesFromDatabase(self):
- '''
+ """
List all classes from database
- '''
+ """
self.classes = []
self.classesListWidget.clear()
self.dbVersion = self.widget.getDBVersion()
self.qmlPath = self.widget.getQmlPath()
- self.parentClassList = self.widget.abstractDb.getOrphanGeomTablesWithElements(loading = True)
+ self.parentClassList = self.widget.abstractDb.getOrphanGeomTablesWithElements(
+ loading=True
+ )
self.classes = []
try:
self.classes = self.widget.abstractDb.listGeomClassesFromDatabase()
except Exception as e:
- self.bar.pushMessage(self.tr("CRITICAL!"), self.tr('A problem occurred! Check log for details.'), level=QgsMessageBar.CRITICAL)
- QgsMessageLog.logMessage(':'.join(e.args), 'DSGTools Plugin', Qgis.Critical)
+ self.bar.pushMessage(
+ self.tr("CRITICAL!"),
+ self.tr("A problem occurred! Check log for details."),
+ level=QgsMessageBar.CRITICAL,
+ )
+ QgsMessageLog.logMessage(":".join(e.args), "DSGTools Plugin", Qgis.Critical)
if self.onlyParentsCheckBox.isChecked() and not self.widget.isSpatialite:
self.classesListWidget.addItems(self.parentClassList)
@@ -113,48 +135,48 @@ def listClassesFromDatabase(self):
self.classesListWidget.sortItems()
def on_filterEdit_textChanged(self, text):
- '''
+ """
Filters shown classes
text: text used to filter classes
- '''
+ """
classes = [edgvClass for edgvClass in self.classes if text in edgvClass]
self.classesListWidget.clear()
self.classesListWidget.addItems(classes)
self.classesListWidget.sortItems()
def cancel(self):
- '''
+ """
Cancels the process
- '''
+ """
self.restoreInitialState()
self.close()
-
+
def pushMessage(self, msg):
- '''
+ """
Pushes a message into message bar
- '''
+ """
self.bar.pushMessage("", msg, level=QgsMessageBar.CRITICAL)
def selectAll(self):
- '''
+ """
Select all classes to be loaded
- '''
+ """
if self.selectAllCheck.isChecked():
tam = self.classesListWidget.__len__()
- for i in range(tam+1):
- item = self.classesListWidget.item(i-1)
- self.classesListWidget.setItemSelected(item,2)
+ for i in range(tam + 1):
+ item = self.classesListWidget.item(i - 1)
+ self.classesListWidget.setItemSelected(item, 2)
else:
tam = self.classesListWidget.__len__()
- for i in range(tam+1):
- item = self.classesListWidget.item(i-1)
- self.classesListWidget.setItemSelected(item,0)
+ for i in range(tam + 1):
+ item = self.classesListWidget.item(i - 1)
+ self.classesListWidget.setItemSelected(item, 0)
def getSelectedItems(self):
- '''
+ """
Gets the selected classes
- '''
+ """
lista = self.classesListWidget.selectedItems()
self.selectedClasses = []
tam = len(lista)
@@ -163,39 +185,61 @@ def getSelectedItems(self):
self.selectedClasses.sort()
def okSelected(self):
- '''
+ """
Loads the selected layers
- '''
+ """
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.loadLayers()
QApplication.restoreOverrideCursor()
def loadLayers(self):
- '''
+ """
Actual method that load layers
- '''
+ """
self.getSelectedItems()
- if len(self.selectedClasses)>0:
+ if len(self.selectedClasses) > 0:
try:
selectedStyle = None
if self.styleDict:
if self.styleComboBox.currentText() in list(self.styleDict.keys()):
- selectedStyle = self.styleDict[self.styleComboBox.currentText()]
+ selectedStyle = self.styleDict[self.styleComboBox.currentText()]
for layer in self.selectedClasses:
dbName = self.widget.abstractDb.getDatabaseName()
- groupList = qgis.utils.iface.legendInterface().groups()
- edgvLayer = self.layerFactory.makeLayer(self.widget.abstractDb, self.codeList, layer)
+ groupList = qgis.utils.iface.legendInterface().groups()
+ edgvLayer = self.layerFactory.makeLayer(
+ self.widget.abstractDb, self.codeList, layer
+ )
if dbName in groupList:
- edgvLayer.load(self.widget.crs, groupList.index(dbName), stylePath = selectedStyle)
+ edgvLayer.load(
+ self.widget.crs,
+ groupList.index(dbName),
+ stylePath=selectedStyle,
+ )
else:
- self.parentTreeNode = qgis.utils.iface.legendInterface().addGroup(self.widget.abstractDb.getDatabaseName(), -1)
- edgvLayer.load(self.widget.crs, self.parentTreeNode, stylePath = selectedStyle)
+ self.parentTreeNode = (
+ qgis.utils.iface.legendInterface().addGroup(
+ self.widget.abstractDb.getDatabaseName(), -1
+ )
+ )
+ edgvLayer.load(
+ self.widget.crs,
+ self.parentTreeNode,
+ stylePath=selectedStyle,
+ )
self.restoreInitialState()
self.close()
except:
- self.bar.pushMessage(self.tr("Error!"), self.tr("Could not load the selected classes!"), level=QgsMessageBar.CRITICAL)
+ self.bar.pushMessage(
+ self.tr("Error!"),
+ self.tr("Could not load the selected classes!"),
+ level=QgsMessageBar.CRITICAL,
+ )
else:
- self.bar.pushMessage(self.tr("Warning!"), self.tr("Please, select at least one class!"), level=QgsMessageBar.WARNING)
+ self.bar.pushMessage(
+ self.tr("Warning!"),
+ self.tr("Please, select at least one class!"),
+ level=QgsMessageBar.WARNING,
+ )
def populateStyleCombo(self, styleDict):
self.styleComboBox.clear()
@@ -203,12 +247,12 @@ def populateStyleCombo(self, styleDict):
styleList = list(styleDict.keys())
numberOfStyles = len(styleList)
if numberOfStyles > 0:
- self.styleComboBox.addItem(self.tr('Select Style'))
+ self.styleComboBox.addItem(self.tr("Select Style"))
for i in range(numberOfStyles):
self.styleComboBox.addItem(styleList[i])
else:
- self.syleComboBox.addItem(self.tr('No available styles'))
-
+ self.syleComboBox.addItem(self.tr("No available styles"))
+
@pyqtSlot(int)
def on_onlyParentsCheckBox_stateChanged(self):
- self.listClassesFromDatabase()
\ No newline at end of file
+ self.listClassesFromDatabase()
diff --git a/DsgTools/gui/Misc/ImageTools/processingTools.py b/DsgTools/gui/Misc/ImageTools/processingTools.py
index 53649c256..d029725d8 100644
--- a/DsgTools/gui/Misc/ImageTools/processingTools.py
+++ b/DsgTools/gui/Misc/ImageTools/processingTools.py
@@ -36,8 +36,10 @@
from qgis.core import QgsCoordinateReferenceSystem, QgsMessageLog
from qgis.gui import QgsProjectionSelectionTreeWidget
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'ui_processingTools.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "ui_processingTools.ui")
+)
+
class ProcessingTools(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, iface):
@@ -54,65 +56,93 @@ def __init__(self, iface):
self.tabWidget.removeTab(1)
self.epsg = 4326
- srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
+ srs = QgsCoordinateReferenceSystem(
+ self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId
+ )
self.srLineEdit.setText(srs.description())
@pyqtSlot()
def on_buttonBox_accepted(self):
- '''
+ """
Starts to process the selected images
- '''
+ """
if self.fileListWidget.count() == 0:
- QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please select at least one image."))
+ QMessageBox.warning(
+ self.iface.mainWindow(),
+ self.tr("Warning!"),
+ self.tr("Please select at least one image."),
+ )
return
- if self.outputFolderEdit.text() == '':
- QMessageBox.warning(self.iface.mainWindow(), self.tr("Warning!"), self.tr("Please select at the output folder."))
+ if self.outputFolderEdit.text() == "":
+ QMessageBox.warning(
+ self.iface.mainWindow(),
+ self.tr("Warning!"),
+ self.tr("Please select at the output folder."),
+ )
return
- QMessageBox.information(self.iface.mainWindow(), self.tr("Information!"), self.tr("The processing may take several minutes. Please wait the final message."))
+ QMessageBox.information(
+ self.iface.mainWindow(),
+ self.tr("Information!"),
+ self.tr(
+ "The processing may take several minutes. Please wait the final message."
+ ),
+ )
self.filesList = []
- for itemNumber in range(0,self.fileListWidget.count()):
+ for itemNumber in range(0, self.fileListWidget.count()):
inFile = self.fileListWidget.item(itemNumber).text()
self.filesList.append(str(inFile))
def getParameters(self):
- '''
+ """
Gets the process parameters
- '''
+ """
(rasterType, minOutValue, maxOutValue) = self.getGDALRasterType()
- return (self.filesList, rasterType, minOutValue, maxOutValue, str(self.outputFolderEdit.text()), self.getStretchingPercentage(), self.epsg)
+ return (
+ self.filesList,
+ rasterType,
+ minOutValue,
+ maxOutValue,
+ str(self.outputFolderEdit.text()),
+ self.getStretchingPercentage(),
+ self.epsg,
+ )
@pyqtSlot(bool)
def on_srsButton_clicked(self):
- '''
+ """
Opens the dialog to select CRS
- '''
+ """
projSelector = QgsProjectionSelectionTreeWidget()
- message = self.tr('Select the Spatial Reference System!')
+ message = self.tr("Select the Spatial Reference System!")
projSelector.setMessage(theMessage=message)
if not projSelector.exec_():
QMessageBox.warning(self, self.tr("Warning!"), message)
return
else:
- self.epsg = int(projSelector.selectedAuthId().split(':')[-1])
- srs = QgsCoordinateReferenceSystem(self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId)
+ self.epsg = int(projSelector.selectedAuthId().split(":")[-1])
+ srs = QgsCoordinateReferenceSystem(
+ self.epsg, QgsCoordinateReferenceSystem.EpsgCrsId
+ )
self.srLineEdit.setText(srs.description())
@pyqtSlot(bool)
def on_addButton_clicked(self):
- '''
+ """
Adds image files to be processed
- '''
- fileNames, __ = QFileDialog.getOpenFileNames(self, self.tr("Select Images"), "", self.tr("Image files (*.tif)"))
+ """
+ fileNames, __ = QFileDialog.getOpenFileNames(
+ self, self.tr("Select Images"), "", self.tr("Image files (*.tif)")
+ )
self.fileListWidget.addItems(fileNames)
@pyqtSlot(bool)
def on_removeButton_clicked(self):
- '''
+ """
Remove files from processing list
- '''
+ """
selectedItems = self.fileListWidget.selectedItems()
for item in selectedItems:
row = self.fileListWidget.row(item)
@@ -120,27 +150,27 @@ def on_removeButton_clicked(self):
@pyqtSlot(bool)
def on_addFolderButton_clicked(self):
- '''
+ """
Adds a folder to be processed
- '''
+ """
folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory"))
for dirName, subdirList, fileList in os.walk(folder):
for fileName in fileList:
- if fileName.split(".")[-1] == 'tif':
- self.fileListWidget.addItem(os.path.join(dirName,fileName))
+ if fileName.split(".")[-1] == "tif":
+ self.fileListWidget.addItem(os.path.join(dirName, fileName))
@pyqtSlot(bool)
def on_outputFolderButton_clicked(self):
- '''
+ """
Defines the output folder
- '''
+ """
folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory"))
self.outputFolderEdit.setText(folder)
def getStretchingPercentage(self):
- '''
+ """
Gets the histogram stretching percentage
- '''
+ """
index = self.stretchComboBox.currentIndex()
if index == 0:
return 0
@@ -148,9 +178,9 @@ def getStretchingPercentage(self):
return 2
def getGDALRasterType(self):
- '''
+ """
Gets the output raster type
- '''
+ """
index = self.numberComboBox.currentIndex()
if index == 0:
min = numpy.iinfo(numpy.uint8).min
@@ -180,4 +210,3 @@ def getGDALRasterType(self):
min = numpy.finfo(numpy.float64).min
max = numpy.finfo(numpy.float64).max
return (osgeo.gdal.GDT_Float64, min, max)
-
diff --git a/DsgTools/gui/Misc/ImageTools/raster_processing.py b/DsgTools/gui/Misc/ImageTools/raster_processing.py
index 2a626f8bb..f09944c12 100644
--- a/DsgTools/gui/Misc/ImageTools/raster_processing.py
+++ b/DsgTools/gui/Misc/ImageTools/raster_processing.py
@@ -42,14 +42,14 @@ def __init__(self):
gdal.UseExceptions()
def openRaster(self, file):
- '''
+ """
Opens a gdal raster file
- '''
+ """
try:
raster = gdal.Open(file)
except RuntimeError as e:
# fix_print_with_import
- print('Unable to open image')
+ print("Unable to open image")
# fix_print_with_import
print(e)
@@ -58,17 +58,17 @@ def openRaster(self, file):
return raster
def getBandAsArray(self, raster, bandnumber):
- '''
+ """
Gets a raster band as array
raster: gdal raster file
bandnumber: band number
- '''
+ """
try:
band = raster.GetRasterBand(bandnumber)
except RuntimeError as e:
# for example, try GetRasterBand(10)
# fix_print_with_import
- print('Band ( %i ) not found' % bandnumber)
+ print("Band ( %i ) not found" % bandnumber)
# fix_print_with_import
print(e)
sys.exit(1)
@@ -76,10 +76,10 @@ def getBandAsArray(self, raster, bandnumber):
return band.ReadAsArray()
def getGeoreferenceInfo(self, raster):
- '''
+ """
Gets georeference information
- raster: raster file
- '''
+ raster: raster file
+ """
# Get raster georeference info
transform = raster.GetGeoTransform()
xOrigin = transform[0]
@@ -90,58 +90,60 @@ def getGeoreferenceInfo(self, raster):
return (xOrigin, yOrigin, pixelWidth, pixelHeight)
def getCRS(self, raster):
- '''
+ """
Gets raster file CRS
- '''
+ """
targetSR = osr.SpatialReference()
targetSR.ImportFromWkt(raster.GetProjectionRef())
return targetSR
def createRasterFromRGBbands(self, srcraster, red, green, blue, destfile):
- '''
+ """
Creates a raster file from RGB bands
srcraster: source raster file
red: red band
green: green band
blue: blue band
destfile: destination file
- '''
+ """
outRaster = self.createRaster(srcraster, destfile)
-
+
outRaster.GetRasterBand(1).WriteArray(red)
outRaster.GetRasterBand(2).WriteArray(green)
outRaster.GetRasterBand(3).WriteArray(blue)
def createRaster(self, srcraster, destfile, pixelType):
- '''
+ """
Creates a raster file
srcraster: source raster
destfile: destination file
pixelType: raster pixel type (e.g byte)
- '''
+ """
cols = srcraster.RasterXSize
rows = srcraster.RasterYSize
- (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo(srcraster)
+ (xOrigin, yOrigin, pixelWidth, pixelHeight) = self.getGeoreferenceInfo(
+ srcraster
+ )
targetSR = self.getCRS(srcraster)
- driver = gdal.GetDriverByName('GTiff')
+ driver = gdal.GetDriverByName("GTiff")
outRaster = driver.Create(destfile, cols, rows, 3, pixelType)
outRaster.SetGeoTransform((xOrigin, pixelWidth, 0, yOrigin, 0, pixelHeight))
outRaster.SetProjection(targetSR.ExportToWkt())
-
+
return outRaster
def pansharpenImage(self, rgbfile, panfile, destfile):
- '''
+ """
Performs a HSV fusion
rgbfile: original RGB raster file
panfile: original PAN raster file
destfile: destination file
- '''
+ """
rgb = self.openRaster(rgbfile)
red = rgb.GetRasterBand(1)
green = rgb.GetRasterBand(2)
@@ -149,10 +151,10 @@ def pansharpenImage(self, rgbfile, panfile, destfile):
panraster = self.openRaster(panfile)
pan = panraster.GetRasterBand(1)
-
+
rgb_to_hsv = numpy.vectorize(colorsys.rgb_to_hsv)
hsv_to_rgb = numpy.vectorize(colorsys.hsv_to_rgb)
-
+
if red.DataType > pan.DataType:
pixelType = red.DataType
else:
@@ -164,17 +166,17 @@ def pansharpenImage(self, rgbfile, panfile, destfile):
outB = outRaster.GetRasterBand(3)
sizeX = pan.XSize
- sizeY = pan.YSize
+ sizeY = pan.YSize
for row in range(sizeY):
redblock = self.readBlock(red, sizeX, 1, row, red.DataType)
greenblock = self.readBlock(green, sizeX, 1, row, green.DataType)
blueblock = self.readBlock(blue, sizeX, 1, row, blue.DataType)
-
+
panblock = self.readBlock(pan, sizeX, 1, row, pan.DataType)
-
+
h, s, v = rgb_to_hsv(redblock, greenblock, blueblock)
r, g, b = hsv_to_rgb(h, s, panblock)
-
+
self.writeBlock(outR, r, sizeX, 1, row, pixelType)
self.writeBlock(outG, g, sizeX, 1, row, pixelType)
self.writeBlock(outB, b, sizeX, 1, row, pixelType)
@@ -182,36 +184,38 @@ def pansharpenImage(self, rgbfile, panfile, destfile):
rgb = None
panraster = None
outRaster = None
-
+
def normalize(self, arr):
- '''
+ """
Function to normalize an input array to 0-1
- '''
+ """
arr_min = arr.min()
arr_max = arr.max()
- return [(arr - arr_min) / (arr_max - arr_min)]*255
-
- def readBlock(self, band, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte):
- '''
+ return [(arr - arr_min) / (arr_max - arr_min)] * 255
+
+ def readBlock(self, band, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte):
+ """
Reads image block
band: band used
sizeX: x block size
sizeY: y block size
offsetY: Y offset
pixelType: pixel type
- '''
+ """
numpytype = self.getNumpyType(pixelType)
- bandscanline =band.ReadRaster( 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType )
- pixelArray=numpy.fromstring(bandscanline, dtype=numpytype)
-
+ bandscanline = band.ReadRaster(
+ 0, offsetY, sizeX, sizeY, sizeX, sizeY, pixelType
+ )
+ pixelArray = numpy.fromstring(bandscanline, dtype=numpytype)
+
return pixelArray
-
- def getNumpyType(self, pixelType = gdal.GDT_Byte):
- '''
+
+ def getNumpyType(self, pixelType=gdal.GDT_Byte):
+ """
Translates the gdal raster type to numpy type
pixelType: gdal raster type
- '''
+ """
if pixelType == gdal.GDT_Byte:
return numpy.uint8
elif pixelType == gdal.GDT_UInt16:
@@ -226,21 +230,26 @@ def getNumpyType(self, pixelType = gdal.GDT_Byte):
return numpy.float32
elif pixelType == gdal.GDT_Float64:
return numpy.float64
-
- def writeBlock(self, band, block, sizeX, sizeY = 1, offsetY = 0, pixelType = gdal.GDT_Byte):
- '''
+
+ def writeBlock(
+ self, band, block, sizeX, sizeY=1, offsetY=0, pixelType=gdal.GDT_Byte
+ ):
+ """
Writes image block
band: band used
sizeX: x block size
sizeY: y block size
offsetY: Y offset
pixelType: pixel type
- '''
+ """
numpytype = self.getNumpyType(pixelType)
band.WriteRaster(0, offsetY, sizeX, sizeY, block.astype(numpytype).tostring())
+
obj = RasterProcess()
-obj.pansharpenImage('/home/lclaudio/Documents/classificacao_rgb.tif',
- '/home/lclaudio/Documents/corte_amp.tif',
- '/home/lclaudio/Documents/teste.tif')
+obj.pansharpenImage(
+ "/home/lclaudio/Documents/classificacao_rgb.tif",
+ "/home/lclaudio/Documents/corte_amp.tif",
+ "/home/lclaudio/Documents/teste.tif",
+)
diff --git a/DsgTools/gui/Misc/InventoryTools/inventoryTools.py b/DsgTools/gui/Misc/InventoryTools/inventoryTools.py
index e66fed8f3..b855b045a 100644
--- a/DsgTools/gui/Misc/InventoryTools/inventoryTools.py
+++ b/DsgTools/gui/Misc/InventoryTools/inventoryTools.py
@@ -30,13 +30,23 @@
from qgis.PyQt import uic
from qgis.PyQt.Qt import QObject
from qgis.PyQt.QtCore import Qt, pyqtSlot
-from qgis.PyQt.QtWidgets import QMenu, QApplication, QFileDialog, QMessageBox, QTreeWidgetItem, QInputDialog, QDialog
+from qgis.PyQt.QtWidgets import (
+ QMenu,
+ QApplication,
+ QFileDialog,
+ QMessageBox,
+ QTreeWidgetItem,
+ QInputDialog,
+ QDialog,
+)
from qgis.PyQt.QtGui import QCursor
from _csv import writer
from qgis._core import QgsAction
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'ui_inventoryTools.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "ui_inventoryTools.ui")
+)
+
class InventoryTools(QDialog, FORM_CLASS):
def __init__(self, iface):
@@ -51,147 +61,175 @@ def __init__(self, iface):
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
self.iface = iface
-
+
self.files = list()
-
+
self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeWidget.customContextMenuRequested.connect(self.createMenu)
-
+
self.whitelistRadio.setChecked(True)
- # set most used file extensions
+ # set most used file extensions
item = QTreeWidgetItem(self.treeWidget.invisibleRootItem())
- item.setText(0,'shp')
+ item.setText(0, "shp")
item = QTreeWidgetItem(self.treeWidget.invisibleRootItem())
- item.setText(0,'tif')
-
+ item.setText(0, "tif")
+
def depth(self, item):
- '''
+ """
Calculates the depth of the item
- '''
+ """
depth = 0
while item is not None:
item = item.parent()
depth += 1
return depth
-
+
def createMenu(self, position):
- '''
+ """
Creates the popup menu that allows extension insertion and removal
position: mouse click position
- '''
+ """
menu = QMenu()
-
+
item = self.treeWidget.itemAt(position)
if not item:
- menu.addAction(self.tr('Insert Extension'), self.insertExtension)
- else:
+ menu.addAction(self.tr("Insert Extension"), self.insertExtension)
+ else:
if self.depth(item) == 1:
- menu.addAction(self.tr('Remove Extension'), self.removeExtension)
-
+ menu.addAction(self.tr("Remove Extension"), self.removeExtension)
+
menu.exec_(self.treeWidget.viewport().mapToGlobal(position))
-
+
def insertExtension(self):
- '''
+ """
Inserts a new extension to be analyzed
- '''
- text = QInputDialog.getText(self, self.tr('Type the extension'), self.tr('File extension'), mode=QLineEdit.Normal)
+ """
+ text = QInputDialog.getText(
+ self,
+ self.tr("Type the extension"),
+ self.tr("File extension"),
+ mode=QLineEdit.Normal,
+ )
item = QTreeWidgetItem(self.treeWidget.invisibleRootItem())
- item.setText(0,text[0])
-
+ item.setText(0, text[0])
+
def removeExtension(self):
- '''
+ """
Removes a extension from the list
- '''
+ """
item = self.treeWidget.selectedItems()[0]
index = self.treeWidget.indexOfTopLevelItem(item)
self.treeWidget.takeTopLevelItem(index)
def getParameters(self):
- '''
+ """
Gets process parameters
- '''
+ """
formatsList = []
root = self.treeWidget.invisibleRootItem()
for i in range(root.childCount()):
item = root.child(i)
extension = item.text(0)
formatsList.append(extension)
-
- return (self.parentFolderEdit.text(), self.outputFileEdit.text(), self.copyFilesCheckBox.isChecked(), \
- self.destinationFolderEdit.text(), formatsList, self.whitelistRadio.isChecked(), self.onlyGeoCheckBox.isChecked())
-
+
+ return (
+ self.parentFolderEdit.text(),
+ self.outputFileEdit.text(),
+ self.copyFilesCheckBox.isChecked(),
+ self.destinationFolderEdit.text(),
+ formatsList,
+ self.whitelistRadio.isChecked(),
+ self.onlyGeoCheckBox.isChecked(),
+ )
+
@pyqtSlot(bool)
def on_parentFolderButton_clicked(self):
- '''
+ """
Opens the dialog to select the folder
- '''
- folder = QFileDialog.getExistingDirectory(self, self.tr('Select Directory'))
+ """
+ folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory"))
self.parentFolderEdit.setText(folder)
@pyqtSlot(bool)
def on_copyFilesButton_clicked(self):
- '''
+ """
Opens the dialog to define the copy destination folder
- '''
- folder = QFileDialog.getExistingDirectory(self, self.tr('Select Directory'))
+ """
+ folder = QFileDialog.getExistingDirectory(self, self.tr("Select Directory"))
self.destinationFolderEdit.setText(folder)
@pyqtSlot(bool)
def on_outputFileButton_clicked(self):
- '''
+ """
Inventory output file selection
- '''
+ """
if self.onlyGeoCheckBox.isChecked():
- fileName, __ = QFileDialog.getSaveFileName(parent=self, caption=self.tr('Save Output File'), filter='Shapefile (*.shp)')
+ fileName, __ = QFileDialog.getSaveFileName(
+ parent=self,
+ caption=self.tr("Save Output File"),
+ filter="Shapefile (*.shp)",
+ )
else:
- fileName, __ = QFileDialog.getSaveFileName(parent=self, caption=self.tr('Save Output File'), filter='CSV (*.csv)')
+ fileName, __ = QFileDialog.getSaveFileName(
+ parent=self, caption=self.tr("Save Output File"), filter="CSV (*.csv)"
+ )
self.outputFileEdit.setText(fileName)
-
+
@pyqtSlot(int)
def on_copyFilesCheckBox_stateChanged(self, state):
- '''
+ """
Slot to update the dialog when copy files definition changes
- '''
+ """
if self.copyFilesCheckBox.isChecked():
self.frame_3.setEnabled(True)
else:
self.frame_3.setEnabled(False)
-
+
@pyqtSlot(bool)
def on_cancelButton_clicked(self):
- '''
+ """
Closes the dialog
- '''
+ """
self.done(0)
@pyqtSlot(bool)
def on_okButton_clicked(self):
- '''
+ """
Runs the process
- '''
+ """
parentFolder = self.parentFolderEdit.text()
outputFile = self.outputFileEdit.text()
if not parentFolder or not outputFile:
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Information!'), self.tr('Please, fill all fields.'))
+ QMessageBox.information(
+ self, self.tr("Information!"), self.tr("Please, fill all fields.")
+ )
return
if self.whitelistRadio.isChecked():
root = self.treeWidget.invisibleRootItem()
if root.childCount() == 0:
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Information!'), self.tr('Please, insert file extensions to be considered.'))
+ QMessageBox.information(
+ self,
+ self.tr("Information!"),
+ self.tr("Please, insert file extensions to be considered."),
+ )
return
-
+
if self.copyFilesCheckBox.isChecked():
destinationFolder = self.destinationFolderEdit.text()
-
+
if not destinationFolder:
QApplication.restoreOverrideCursor()
- QMessageBox.information(self, self.tr('Information!'), self.tr('Please, choose a location to save the files.'))
+ QMessageBox.information(
+ self,
+ self.tr("Information!"),
+ self.tr("Please, choose a location to save the files."),
+ )
return
self.done(1)
diff --git a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py
index 9f86df769..1c3426555 100644
--- a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py
+++ b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONBuilder.py
@@ -21,41 +21,101 @@
***************************************************************************/
"""
import json
-#Qt Imports
+
+# Qt Imports
from qgis.PyQt.Qt import QObject
-#DsgTools Imports
+
+# DsgTools Imports
+
class CustomJSONBuilder(QObject):
def __init__(self):
- super(CustomJSONBuilder,self).__init__()
+ super(CustomJSONBuilder, self).__init__()
def buildClassElement(self, schema, name, attrList):
- return {'schema':schema, 'name':name, 'attrs':attrList}
+ return {"schema": schema, "name": name, "attrs": attrList}
def buildNewAttributeElement(self, schema, name, attrList, childrenToAlter=[]):
- return {'schema':schema, 'name':name, 'attrs':attrList, 'childrenToAlter':childrenToAlter}
+ return {
+ "schema": schema,
+ "name": name,
+ "attrs": attrList,
+ "childrenToAlter": childrenToAlter,
+ }
- def buildAttributeElement(self, attrName, attrType, isPk, isNullable, defaultValue = None, references = None, filter=[]):
- return {'attrName':attrName, 'attrType':attrType, 'isPk':isPk, 'isNullable':isNullable, 'defaultValue':defaultValue, 'references':references, 'filter':filter}
+ def buildAttributeElement(
+ self,
+ attrName,
+ attrType,
+ isPk,
+ isNullable,
+ defaultValue=None,
+ references=None,
+ filter=[],
+ ):
+ return {
+ "attrName": attrName,
+ "attrType": attrType,
+ "isPk": isPk,
+ "isNullable": isNullable,
+ "defaultValue": defaultValue,
+ "references": references,
+ "filter": filter,
+ }
def addDomainTableElement(self, domainName, valueDict):
- return {'domainName':domainName, 'valueDict': valueDict}
+ return {"domainName": domainName, "valueDict": valueDict}
def addValueToValueDict(self, valueDict, code, codeName):
if code not in list(valueDict.keys()):
valueDict[code] = codeName
- def buildCodeNameToChangeElement(self, domainTable, codeValue, oldCodeName, newCodeName):
- return {'domainTable':domainTable, 'codeValue':codeValue, 'oldCodeName':oldCodeName, 'newCodeName':newCodeName}
+ def buildCodeNameToChangeElement(
+ self, domainTable, codeValue, oldCodeName, newCodeName
+ ):
+ return {
+ "domainTable": domainTable,
+ "codeValue": codeValue,
+ "oldCodeName": oldCodeName,
+ "newCodeName": newCodeName,
+ }
def buildChangeDefaultElement(self, schema, table, attrName, oldValue, newValue):
- return {'schema': schema, 'table': table, 'attrName':attrName, 'oldValue':oldValue, 'newValue':newValue}
+ return {
+ "schema": schema,
+ "table": table,
+ "attrName": attrName,
+ "oldValue": oldValue,
+ "newValue": newValue,
+ }
def buildChangeNullityElement(self, schema, table, attrName, notNull):
- return {'schema':schema, 'table':table, 'attrName':attrName, 'notNull':notNull}
+ return {
+ "schema": schema,
+ "table": table,
+ "attrName": attrName,
+ "notNull": notNull,
+ }
def addDomainValueElement(self, domainName, code, codeName):
- return {'domainName':domainName, 'code':code, 'codeName':codeName}
+ return {"domainName": domainName, "code": code, "codeName": codeName}
- def alterFilterElement(self, schema, tableName, attrName, filterName, originalFilterList, valueList, isMulti = False):
- return {'schema':schema, 'tableName':tableName, 'attrName':attrName, 'filterName':filterName,'originalFilterList':originalFilterList, 'valueList':valueList, 'isMulti':isMulti}
\ No newline at end of file
+ def alterFilterElement(
+ self,
+ schema,
+ tableName,
+ attrName,
+ filterName,
+ originalFilterList,
+ valueList,
+ isMulti=False,
+ ):
+ return {
+ "schema": schema,
+ "tableName": tableName,
+ "attrName": attrName,
+ "filterName": filterName,
+ "originalFilterList": originalFilterList,
+ "valueList": valueList,
+ "isMulti": isMulti,
+ }
diff --git a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py
index 2f76dfab3..355ba5219 100644
--- a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py
+++ b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONTools/customJSONValidator.py
@@ -21,26 +21,29 @@
***************************************************************************/
"""
import json
-#Qt Imports
+
+# Qt Imports
from qgis.PyQt.Qt import QObject
-#DsgTools Imports
+
+# DsgTools Imports
+
class CustomJSONValidator(QObject):
def __init__(self, jsonFile):
- super(CustomJSONValidator,self).__init__()
+ super(CustomJSONValidator, self).__init__()
self.jsonFile = jsonFile
-
+
def parseJson(self):
pass
-
+
def validateTags(self):
pass
-
+
def validateDsgToolsClassNames(self):
pass
-
+
def validateGeometricPrimitives(self):
pass
-
+
def validate(self):
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py
index 2f76dfab3..355ba5219 100644
--- a/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py
+++ b/DsgTools/gui/Misc/PostgisCustomization/CustomJSONValidator/customJSONValidator.py
@@ -21,26 +21,29 @@
***************************************************************************/
"""
import json
-#Qt Imports
+
+# Qt Imports
from qgis.PyQt.Qt import QObject
-#DsgTools Imports
+
+# DsgTools Imports
+
class CustomJSONValidator(QObject):
def __init__(self, jsonFile):
- super(CustomJSONValidator,self).__init__()
+ super(CustomJSONValidator, self).__init__()
self.jsonFile = jsonFile
-
+
def parseJson(self):
pass
-
+
def validateTags(self):
pass
-
+
def validateDsgToolsClassNames(self):
pass
-
+
def validateGeometricPrimitives(self):
pass
-
+
def validate(self):
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py b/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py
index e0be406ca..7e861eaee 100644
--- a/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py
+++ b/DsgTools/gui/Misc/PostgisCustomization/createDatabaseCustomization.py
@@ -34,25 +34,55 @@
from qgis.PyQt.QtGui import QCursor
# DSGTools imports
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newClassWidget import NewClassWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newAttributeWidget import NewAttributeWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainWidget import NewDomainWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainValueWidget import NewDomainValueWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.codeNameCustomizationWidget import CodeNameCustomizationWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeNullityWidget import ChangeNullityWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeFilterWidget import ChangeFilterWidget
-from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.alterDefaultWidget import AlterDefaultWidget
-from DsgTools.gui.CustomWidgets.SelectionWidgets.selectFileWidget import SelectFileWidget
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newClassWidget import (
+ NewClassWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newAttributeWidget import (
+ NewAttributeWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainWidget import (
+ NewDomainWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.newDomainValueWidget import (
+ NewDomainValueWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.codeNameCustomizationWidget import (
+ CodeNameCustomizationWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeNullityWidget import (
+ ChangeNullityWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.changeFilterWidget import (
+ ChangeFilterWidget,
+)
+from DsgTools.gui.CustomWidgets.CustomDbManagementWidgets.alterDefaultWidget import (
+ AlterDefaultWidget,
+)
+from DsgTools.gui.CustomWidgets.SelectionWidgets.selectFileWidget import (
+ SelectFileWidget,
+)
from DsgTools.gui.Misc.PostgisCustomization.dbCustomizer import DbCustomizer
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import ProgressWidget
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.progressWidget import (
+ ProgressWidget,
+)
from DsgTools.core.Factories.DbFactory.dbFactory import DbFactory
from DsgTools.core.Utils.utils import Utils
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'createDatabaseCustomization.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "createDatabaseCustomization.ui")
+)
+
class CreateDatabaseCustomization(QtWidgets.QDialog, FORM_CLASS):
- def __init__(self, customizationName, abstractDb, edgvVersion, customizationManager, customJsonDict = None, parent = None):
+ def __init__(
+ self,
+ customizationName,
+ abstractDb,
+ edgvVersion,
+ customizationManager,
+ customJsonDict=None,
+ parent=None,
+ ):
"""Constructor."""
super(self.__class__, self).__init__(parent)
self.setupUi(self)
@@ -70,7 +100,7 @@ def __init__(self, customizationName, abstractDb, edgvVersion, customizationMana
def clearWidgets(self):
rootItem = self.customizationTreeWidget.invisibleRootItem()
childNodeCount = rootItem.childCount()
- #remove widgets
+ # remove widgets
for i in range(childNodeCount):
typeChild = rootItem.child(i)
childCount = typeChild.childCount()
@@ -78,100 +108,160 @@ def clearWidgets(self):
for j in range(childCount):
childTextList.append(typeChild.child(i).text(0))
for childText in childTextList:
- self.removeWidget(widgetText = childText)
-
+ self.removeWidget(widgetText=childText)
+
def setWidgetsEnabled(self, enabled):
self.customizationSelectionComboBox.setEnabled(enabled)
self.addAttributePushButton.setEnabled(enabled)
self.customizationTreeWidget.setEnabled(enabled)
self.removeSelectedPushButton.setEnabled(enabled)
-
+
def populateCustomizationCombo(self):
- '''
+ """
Populates the customization combo and also defines customDict.
- '''
+ """
self.customDict = dict()
- self.customDict['attribute'] = self.tr('Attribute Customization')
- self.customDict['class'] = self.tr('Class Customization')
- self.customDict['codeName'] = self.tr('Code Name Customization')
- self.customDict['default'] = self.tr('Default Customization')
- self.customDict['domain'] = self.tr('Domain Customization')
- self.customDict['domainValue'] = self.tr('Domain Value Customization')
- self.customDict['nullity'] = self.tr('Attribute Nullity Customization')
- self.customDict['filter'] = self.tr('Attribute Filter Customization')
+ self.customDict["attribute"] = self.tr("Attribute Customization")
+ self.customDict["class"] = self.tr("Class Customization")
+ self.customDict["codeName"] = self.tr("Code Name Customization")
+ self.customDict["default"] = self.tr("Default Customization")
+ self.customDict["domain"] = self.tr("Domain Customization")
+ self.customDict["domainValue"] = self.tr("Domain Value Customization")
+ self.customDict["nullity"] = self.tr("Attribute Nullity Customization")
+ self.customDict["filter"] = self.tr("Attribute Filter Customization")
rootNode = self.customizationTreeWidget.invisibleRootItem()
for type in list(self.customDict.keys()):
if self.customDict[type] not in list(self.contentsDict.keys()):
self.contentsDict[self.customDict[type]] = dict()
self.customizationSelectionComboBox.addItem(self.customDict[type])
- self.contentsDict[self.customDict[type]]['widgetList'] = []
- self.contentsDict[self.customDict[type]]['treeItem'] = self.createItem(rootNode, self.customDict[type], 0)
+ self.contentsDict[self.customDict[type]]["widgetList"] = []
+ self.contentsDict[self.customDict[type]]["treeItem"] = self.createItem(
+ rootNode, self.customDict[type], 0
+ )
self.customizationTreeWidget.expandAll()
-
+
@pyqtSlot(bool)
def on_addAttributePushButton_clicked(self):
- if self.customizationSelectionComboBox.currentText() == self.tr('Attribute Customization'):
+ if self.customizationSelectionComboBox.currentText() == self.tr(
+ "Attribute Customization"
+ ):
self.addAttributeWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Class Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Class Customization"
+ ):
self.addClassWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Code Name Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Code Name Customization"
+ ):
self.addCodeNameWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Default Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Default Customization"
+ ):
self.addDefaultWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Domain Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Domain Customization"
+ ):
self.addDomainWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Domain Value Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Domain Value Customization"
+ ):
self.addDomainValueWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Attribute Nullity Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Attribute Nullity Customization"
+ ):
self.addNullityWidget()
- elif self.customizationSelectionComboBox.currentText() == self.tr('Attribute Filter Customization'):
+ elif self.customizationSelectionComboBox.currentText() == self.tr(
+ "Attribute Filter Customization"
+ ):
self.addFilterWidget()
else:
- QMessageBox.warning(self, self.tr('Warning'), self.tr('Select a custom operation!'))
-
+ QMessageBox.warning(
+ self, self.tr("Warning"), self.tr("Select a custom operation!")
+ )
+
def addWidgetItem(self, contentsKey, widgetTitle, widget):
- widgetList = self.contentsDict[contentsKey]['widgetList']
+ widgetList = self.contentsDict[contentsKey]["widgetList"]
if len(widgetList) > 0:
- i = int(widgetList[-1].layout().itemAt(0).widget().getTitle().split('#')[-1])
+ i = int(
+ widgetList[-1].layout().itemAt(0).widget().getTitle().split("#")[-1]
+ )
else:
i = 0
- title = widgetTitle+' #{0}'.format(i+1) #add number
+ title = widgetTitle + " #{0}".format(i + 1) # add number
widget.setTitle(title)
- self.contentsDict[contentsKey]['widgetList'].append(self.addWidget(widget, title))
- self.createItem(self.contentsDict[contentsKey]['treeItem'], title, 0)
-
- def addAttributeWidget(self,uiParameterJsonDict=None):
- widget = NewAttributeWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Attribute Customization'), self.tr('New Custom Attribute'), widget)
-
- def addClassWidget(self,uiParameterJsonDict=None):
- widget = NewClassWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Class Customization'), self.tr('New Custom Class'), widget)
-
- def addCodeNameWidget(self,uiParameterJsonDict=None):
- widget = CodeNameCustomizationWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Code Name Customization'), self.tr('New Custom Code Name'), widget)
+ self.contentsDict[contentsKey]["widgetList"].append(
+ self.addWidget(widget, title)
+ )
+ self.createItem(self.contentsDict[contentsKey]["treeItem"], title, 0)
+
+ def addAttributeWidget(self, uiParameterJsonDict=None):
+ widget = NewAttributeWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Attribute Customization"), self.tr("New Custom Attribute"), widget
+ )
+
+ def addClassWidget(self, uiParameterJsonDict=None):
+ widget = NewClassWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Class Customization"), self.tr("New Custom Class"), widget
+ )
- def addDefaultWidget(self,uiParameterJsonDict=None):
- widget = AlterDefaultWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Default Customization'), self.tr('New Custom Default'), widget)
+ def addCodeNameWidget(self, uiParameterJsonDict=None):
+ widget = CodeNameCustomizationWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Code Name Customization"), self.tr("New Custom Code Name"), widget
+ )
- def addDomainWidget(self,uiParameterJsonDict=None):
- widget = NewDomainWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Domain Customization'), self.tr('New Custom Domain'), widget)
+ def addDefaultWidget(self, uiParameterJsonDict=None):
+ widget = AlterDefaultWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Default Customization"), self.tr("New Custom Default"), widget
+ )
- def addDomainValueWidget(self,uiParameterJsonDict=None):
- widget = NewDomainValueWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Domain Value Customization'), self.tr('New Domain Value'), widget)
+ def addDomainWidget(self, uiParameterJsonDict=None):
+ widget = NewDomainWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Domain Customization"), self.tr("New Custom Domain"), widget
+ )
- def addNullityWidget(self,uiParameterJsonDict=None):
- widget = ChangeNullityWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Attribute Nullity Customization'), self.tr('New Custom Attribute Nullity'), widget)
+ def addDomainValueWidget(self, uiParameterJsonDict=None):
+ widget = NewDomainValueWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Domain Value Customization"), self.tr("New Domain Value"), widget
+ )
+
+ def addNullityWidget(self, uiParameterJsonDict=None):
+ widget = ChangeNullityWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Attribute Nullity Customization"),
+ self.tr("New Custom Attribute Nullity"),
+ widget,
+ )
+
+ def addFilterWidget(self, uiParameterJsonDict=None):
+ widget = ChangeFilterWidget(
+ self.abstractDb, uiParameterJsonDict=uiParameterJsonDict
+ )
+ self.addWidgetItem(
+ self.tr("Attribute Filter Customization"),
+ self.tr("New Custom Attribute Filter"),
+ widget,
+ )
- def addFilterWidget(self,uiParameterJsonDict=None):
- widget = ChangeFilterWidget(self.abstractDb,uiParameterJsonDict = uiParameterJsonDict)
- self.addWidgetItem(self.tr('Attribute Filter Customization'), self.tr('New Custom Attribute Filter'), widget)
-
def addWidget(self, widget, title):
layout = QtGui.QFormLayout()
layout.addRow(widget)
@@ -181,15 +271,15 @@ def addWidget(self, widget, title):
groupBox.setLayout(layout)
self.scrollAreaLayout.addWidget(groupBox)
return groupBox
-
+
def createItem(self, parent, text, column):
item = QtWidgets.QTreeWidgetItem(parent)
item.setText(column, text)
return item
-
+
def getWidgetIndexFromTreeItem(self, treeItem):
parent = treeItem.parent()
- widgetName = treeItem.text(0)
+ widgetName = treeItem.text(0)
if not parent:
return
if parent == self.customizationTreeWidget.invisibleRootItem():
@@ -199,23 +289,25 @@ def getWidgetIndexFromTreeItem(self, treeItem):
child = parent.child(i)
if child.text(0) == widgetName:
return i
-
- @pyqtSlot(bool, name='on_removeSelectedPushButton_clicked')
- def removeWidget(self, widgetText = None):
+
+ @pyqtSlot(bool, name="on_removeSelectedPushButton_clicked")
+ def removeWidget(self, widgetText=None):
if not widgetText:
treeItemList = [self.customizationTreeWidget.currentItem()]
else:
- treeItemList = self.customizationTreeWidget.findItems(widgetText, flags = Qt.MatchExactly)
- if len(treeItemList)>0:
+ treeItemList = self.customizationTreeWidget.findItems(
+ widgetText, flags=Qt.MatchExactly
+ )
+ if len(treeItemList) > 0:
for treeItem in treeItemList:
parent = treeItem.parent()
if parent == self.customizationTreeWidget.invisibleRootItem():
return
idx = self.getWidgetIndexFromTreeItem(treeItem)
- itemToRemove = self.contentsDict[parent.text(0)]['widgetList'].pop(idx)
+ itemToRemove = self.contentsDict[parent.text(0)]["widgetList"].pop(idx)
itemToRemove.setParent(None)
- self.contentsDict[parent.text(0)]['treeItem'].removeChild(treeItem)
-
+ self.contentsDict[parent.text(0)]["treeItem"].removeChild(treeItem)
+
@pyqtSlot()
def on_buttonBox_accepted(self):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
@@ -223,80 +315,98 @@ def on_buttonBox_accepted(self):
customJsonDict = dict()
for i in list(self.customDict.keys()):
customJsonDict[i] = []
- correspondenceDict = {self.customDict[i]:i for i in list(self.customDict.keys())}
+ correspondenceDict = {
+ self.customDict[i]: i for i in list(self.customDict.keys())
+ }
nCustom = 0
for key in list(self.contentsDict.keys()):
- for widgetItem in self.contentsDict[key]['widgetList']:
+ for widgetItem in self.contentsDict[key]["widgetList"]:
nCustom += 1
- progress = ProgressWidget(1,nCustom,self.tr('Preparing to export customizations... '), parent = self)
+ progress = ProgressWidget(
+ 1, nCustom, self.tr("Preparing to export customizations... "), parent=self
+ )
progress.initBar()
for key in list(self.contentsDict.keys()):
jsonTagList = []
- for widget in self.contentsDict[key]['widgetList']:
- currJsonItem = {'jsonUi':None, 'dbJsonTagList':[]}
+ for widget in self.contentsDict[key]["widgetList"]:
+ currJsonItem = {"jsonUi": None, "dbJsonTagList": []}
currentWidget = widget.layout().itemAt(0).widget()
try:
jsonTagList = currentWidget.getJSONTag()
jsonUi = currentWidget.getUiParameterJsonDict()
except Exception as e:
- exceptionList.append(':'.join(e.args))
+ exceptionList.append(":".join(e.args))
if len(exceptionList) == 0:
- currJsonItem['jsonUi'] = jsonUi
+ currJsonItem["jsonUi"] = jsonUi
for jsonItem in jsonTagList:
- if jsonItem not in currJsonItem['dbJsonTagList']:
- currJsonItem['dbJsonTagList'].append(jsonItem)
+ if jsonItem not in currJsonItem["dbJsonTagList"]:
+ currJsonItem["dbJsonTagList"].append(jsonItem)
if currJsonItem not in customJsonDict[correspondenceDict[key]]:
customJsonDict[correspondenceDict[key]].append(currJsonItem)
progress.step()
QApplication.restoreOverrideCursor()
if self.validateJsonDict(customJsonDict) and len(exceptionList) == 0:
- versionText = 'database_'+self.edgvVersion
- finalJsonDict = {versionText:customJsonDict}
- self.customizationManager.createSetting(self.customizationName, self.edgvVersion, finalJsonDict)
- QMessageBox.information(self, self.tr('Success!'), self.tr('Database Customization ') + self.customizationName + self.tr(' created successfuly!'))
- #EMIT to reload?
+ versionText = "database_" + self.edgvVersion
+ finalJsonDict = {versionText: customJsonDict}
+ self.customizationManager.createSetting(
+ self.customizationName, self.edgvVersion, finalJsonDict
+ )
+ QMessageBox.information(
+ self,
+ self.tr("Success!"),
+ self.tr("Database Customization ")
+ + self.customizationName
+ + self.tr(" created successfuly!"),
+ )
+ # EMIT to reload?
self.close()
else:
- msg = ''
- if len(exceptionList)> 0:
- msg += self.tr('\Errors occured while trying to export customs built. Check qgis log for further details.')
+ msg = ""
+ if len(exceptionList) > 0:
+ msg += self.tr(
+ "\Errors occured while trying to export customs built. Check qgis log for further details."
+ )
for error in exceptionList:
- QgsMessageLog.logMessage(self.tr('Customization error: ') + error, "DSGTools Plugin", Qgis.Critical)
- QMessageBox.warning(self, self.tr('Error!'), msg)
-
+ QgsMessageLog.logMessage(
+ self.tr("Customization error: ") + error,
+ "DSGTools Plugin",
+ Qgis.Critical,
+ )
+ QMessageBox.warning(self, self.tr("Error!"), msg)
+
def validateJsonDict(self, customJsonDict):
"""
Method to apply validation to customJsonDict
"""
- #TODO
+ # TODO
return True
def populateWidgetsFromSelectedFile(self):
jsonFileName = self.selectFileWidget.fileNameList
customJsonDict = self.utils.readJsonFile(jsonFileName)
self.createWidgetsFromCustomJsonDict(customJsonDict)
-
+
def createWidgetsFromCustomJsonDict(self, customJsonDict):
for key in list(customJsonDict.keys()):
for jsonTag in customJsonDict[key]:
- self.createWidgetFromKey(key, jsonTag['jsonUi'])
-
+ self.createWidgetFromKey(key, jsonTag["jsonUi"])
+
def createWidgetFromKey(self, key, uiParameterJsonDict):
- if key == 'attribute':
+ if key == "attribute":
self.addAttributeWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'class':
+ elif key == "class":
self.addClassWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'codeName':
+ elif key == "codeName":
self.addCodeNameWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'default':
+ elif key == "default":
self.addDefaultWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'domain':
+ elif key == "domain":
self.addDomainWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'domainValue':
+ elif key == "domainValue":
self.addDomainValueWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'nullity':
+ elif key == "nullity":
self.addNullityWidget(uiParameterJsonDict=uiParameterJsonDict)
- elif key == 'filter':
+ elif key == "filter":
self.addFilterWidget(uiParameterJsonDict=uiParameterJsonDict)
else:
pass
diff --git a/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py b/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py
index 2e5d95e93..77465d78e 100644
--- a/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py
+++ b/DsgTools/gui/Misc/PostgisCustomization/dbCustomizer.py
@@ -20,30 +20,40 @@
* *
***************************************************************************/
"""
-#Qt Imports
+# Qt Imports
from qgis.PyQt.Qt import QObject
-#DsgTools Imports
-from DsgTools.core.Utils.utils import Utils
+
+# DsgTools Imports
+from DsgTools.core.Utils.utils import Utils
from DsgTools.core.Factories.DbFactory.postgisDb import PostgisDb
-from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONValidator import CustomJSONValidator
-from DsgTools.core.Factories.DbCustomizationFactory.dbCustomizationFactory import DbCustomizationFactory
+from DsgTools.gui.Misc.PostgisCustomization.CustomJSONTools.customJSONValidator import (
+ CustomJSONValidator,
+)
+from DsgTools.core.Factories.DbCustomizationFactory.dbCustomizationFactory import (
+ DbCustomizationFactory,
+)
+
class DbCustomizer(QObject):
def __init__(self):
super(DbCustomizer, self).__init__()
self.customJSONValidator = None
self.dbCustomizationFactory = DbCustomizationFactory()
-
+
def buildCustomizationSQL(self, customJSON):
- sql = ''
+ sql = ""
for customizationTag in list(customJSON.keys()):
- customCreator = self.dbCustomizationFactory.createCustomization(customizationTag, customJSON[customizationTag])
+ customCreator = self.dbCustomizationFactory.createCustomization(
+ customizationTag, customJSON[customizationTag]
+ )
sql += customCreator.buildSql()
return sql
-
+
def buildUndoCustomizationSQL(self, customJSON):
- sql = ''
+ sql = ""
for customizationTag in list(customJSON.keys()):
- customCreator = self.dbCustomizationFactory.createCustomization(customizationTag, customJSON[customizationTag])
+ customCreator = self.dbCustomizationFactory.createCustomization(
+ customizationTag, customJSON[customizationTag]
+ )
sql += customCreator.buildUndoSql()
- return sql
\ No newline at end of file
+ return sql
diff --git a/DsgTools/gui/Misc/ProcessingTools/processManager.py b/DsgTools/gui/Misc/ProcessingTools/processManager.py
index 9238cf85a..1d10e264d 100644
--- a/DsgTools/gui/Misc/ProcessingTools/processManager.py
+++ b/DsgTools/gui/Misc/ProcessingTools/processManager.py
@@ -30,6 +30,7 @@
from DsgTools.core.Factories.ThreadFactory.threadFactory import ThreadFactory
+
class ProcessManager(QObject):
def __init__(self, iface):
"""
@@ -83,8 +84,8 @@ def stepProcessed(self, uuid):
if not sip.isdeleted(progressBar):
progressBar.setValue(progressBar.value() + 1)
- @pyqtSlot(int,str,str)
- def processFinished( self, feedback, message, uuid):
+ @pyqtSlot(int, str, str)
+ def processFinished(self, feedback, message, uuid):
"""
Finalizes the process
feedback: feedback code
@@ -101,7 +102,7 @@ def processFinished( self, feedback, message, uuid):
if feedback == 1:
progressBar.setValue(progressBar.maximum())
- QMessageBox.information(self.iface.mainWindow(), 'DSG Tools', message)
+ QMessageBox.information(self.iface.mainWindow(), "DSG Tools", message)
def prepareProcess(self, process, message):
"""
@@ -112,67 +113,98 @@ def prepareProcess(self, process, message):
# Setting the progress bar
progressMessageBar = self.iface.messageBar().createMessage(message)
progressBar = QProgressBar()
- progressBar.setAlignment(Qt.AlignLeft|Qt.AlignVCenter)
+ progressBar.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
progressMessageBar.layout().addWidget(progressBar)
- self.iface.messageBar().pushWidget(progressMessageBar, self.iface.messageBar().INFO)
+ self.iface.messageBar().pushWidget(
+ progressMessageBar, self.iface.messageBar().INFO
+ )
- #connecting the destroyed signal
+ # connecting the destroyed signal
progressMessageBar.destroyed.connect(process.messenger.progressCanceled)
- #storing the process and its related progressBar
+ # storing the process and its related progressBar
self.processDict[process] = progressBar
- #initiating processing
+ # initiating processing
QThreadPool.globalInstance().start(process)
def createPostgisDatabaseProcess(self, dbName, abstractDb, version, epsg):
"""
Create the postgis databsae process
"""
- #creating process
- process = self.threadFactory.makeProcess('pgdb')
+ # creating process
+ process = self.threadFactory.makeProcess("pgdb")
stopped = [False]
- process.setParameters(abstractDb,dbName,version,epsg,stopped)
- #connecting signal/slots
+ process.setParameters(abstractDb, dbName, version, epsg, stopped)
+ # connecting signal/slots
process.signals.rangeCalculated.connect(self.setProgressRange)
process.signals.stepProcessed.connect(self.stepProcessed)
process.signals.processingFinished.connect(self.processFinished)
- #preparing the progressBar that will be created
+ # preparing the progressBar that will be created
self.prepareProcess(process, self.tr("Creating database structure..."))
- def createDpiProcess(self, filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg):
+ def createDpiProcess(
+ self, filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg
+ ):
"""
Creates the digital image process
"""
- #creating process
- process = self.threadFactory.makeProcess('dpi')
+ # creating process
+ process = self.threadFactory.makeProcess("dpi")
stopped = [False]
- process.setParameters(filesList, rasterType, minOutValue, maxOutValue, outDir, percent, epsg, stopped)
-
- #connecting signal/slots
+ process.setParameters(
+ filesList,
+ rasterType,
+ minOutValue,
+ maxOutValue,
+ outDir,
+ percent,
+ epsg,
+ stopped,
+ )
+
+ # connecting signal/slots
process.signals.rangeCalculated.connect(self.setProgressRange)
process.signals.stepProcessed.connect(self.stepProcessed)
process.signals.processingFinished.connect(self.processFinished)
- #preparing the progressBar that will be created
+ # preparing the progressBar that will be created
self.prepareProcess(process, self.tr("Processing images..."))
- def createInventoryProcess(self, parentFolder, outputFile, makeCopy, destinationFolder, formatsList, isWhitelist, isOnlyGeo):
+ def createInventoryProcess(
+ self,
+ parentFolder,
+ outputFile,
+ makeCopy,
+ destinationFolder,
+ formatsList,
+ isWhitelist,
+ isOnlyGeo,
+ ):
"""
Creates the inventory process
"""
- #creating process
- process = self.threadFactory.makeProcess('inventory')
+ # creating process
+ process = self.threadFactory.makeProcess("inventory")
stopped = [False]
- process.setParameters(parentFolder, outputFile, makeCopy, destinationFolder, formatsList, isWhitelist, isOnlyGeo, stopped)
-
- #connecting signal/slots
+ process.setParameters(
+ parentFolder,
+ outputFile,
+ makeCopy,
+ destinationFolder,
+ formatsList,
+ isWhitelist,
+ isOnlyGeo,
+ stopped,
+ )
+
+ # connecting signal/slots
process.signals.rangeCalculated.connect(self.setProgressRange)
process.signals.stepProcessed.connect(self.stepProcessed)
process.signals.processingFinished.connect(self.processFinished)
process.signals.loadFile.connect(self.loadInventoryFile)
- #preparing the progressBar that will be created
+ # preparing the progressBar that will be created
self.prepareProcess(process, self.tr("Making inventory, please wait..."))
@pyqtSlot(str, bool)
@@ -183,16 +215,24 @@ def loadInventoryFile(self, outputFile, isOnlyGeo):
if not isOnlyGeo:
# Adding the layer and making it active
url = QUrl.fromLocalFile(outputFile)
- url.addQueryItem('delimiter', ',')
+ url.addQueryItem("delimiter", ",")
layer_uri = str(url.toEncoded())
- layer = self.iface.addVectorLayer(layer_uri, 'Inventory', 'delimitedtext')
+ layer = self.iface.addVectorLayer(layer_uri, "Inventory", "delimitedtext")
else:
- layer = self.iface.addVectorLayer(outputFile, 'Inventory', 'ogr')
+ layer = self.iface.addVectorLayer(outputFile, "Inventory", "ogr")
if layer:
- self.iface.setActiveLayer(layer)
+ self.iface.setActiveLayer(layer)
# Creating and Attribute Action to load the inventoried file
actions = layer.actions()
field = '[% "fileName" %]'
- actions.addAction(QgsAction.GenericPython, 'Load Vector Layer', 'qgis.utils.iface.addVectorLayer(r\'%s\', \'File\', \'ogr\')' % field)
- actions.addAction(QgsAction.GenericPython, 'Load Raster Layer', 'qgis.utils.iface.addRasterLayer(r\'%s\', \'File\')' % field)
+ actions.addAction(
+ QgsAction.GenericPython,
+ "Load Vector Layer",
+ "qgis.utils.iface.addVectorLayer(r'%s', 'File', 'ogr')" % field,
+ )
+ actions.addAction(
+ QgsAction.GenericPython,
+ "Load Raster Layer",
+ "qgis.utils.iface.addRasterLayer(r'%s', 'File')" % field,
+ )
diff --git a/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py b/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py
index c357111d3..24ffab2aa 100644
--- a/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py
+++ b/DsgTools/gui/Misc/ToolboxTools/models_and_scripts_installer.py
@@ -31,11 +31,13 @@
from processing.core.Processing import Processing
from qgis.core import QgsMessageLog
-FORM_CLASS, _ = uic.loadUiType(os.path.join(
- os.path.dirname(__file__), 'models_and_scripts_installer.ui'))
+FORM_CLASS, _ = uic.loadUiType(
+ os.path.join(os.path.dirname(__file__), "models_and_scripts_installer.ui")
+)
currentPath = os.path.dirname(__file__)
+
class ModelsAndScriptsInstaller(QDialog, FORM_CLASS):
def __init__(self):
"""
@@ -60,7 +62,7 @@ def __del__(self):
def createItems(self, widget, names):
"""
- Create items
+ Create items
"""
for name in names:
item = QListWidgetItem(widget)
@@ -74,9 +76,9 @@ def scanFolder(self, folder, extension):
ret = []
for root, dirs, files in os.walk(folder):
for file in files:
- ext = file.split('.')[-1]
+ ext = file.split(".")[-1]
if ext == extension:
- path = os.path.join(root, file.decode(encoding='UTF-8'))
+ path = os.path.join(root, file.decode(encoding="UTF-8"))
ret.append(path)
return ret
@@ -85,16 +87,16 @@ def getModels(self):
"""
Get models in the folder
"""
- modelspath = os.path.join(currentPath, '..', 'QGIS_Models')
- extension = 'model'
+ modelspath = os.path.join(currentPath, "..", "QGIS_Models")
+ extension = "model"
return self.scanFolder(modelspath, extension)
def getScripts(self):
"""
Get scripts in the folder
"""
- scriptspath = os.path.join(currentPath, '..', 'QGIS_Scripts')
- extension = 'py'
+ scriptspath = os.path.join(currentPath, "..", "QGIS_Scripts")
+ extension = "py"
return self.scanFolder(scriptspath, extension)
def copyFiles(self, widget, files, folder):
@@ -109,7 +111,11 @@ def copyFiles(self, widget, files, folder):
try:
shutil.copy2(file, destination)
except IOError as e:
- QgsMessageLog.logMessage(self.tr('Error copying file: ')+text+'\n'+e.strerror, "DSGTools Plugin", QgsMessageLog.INFO)
+ QgsMessageLog.logMessage(
+ self.tr("Error copying file: ") + text + "\n" + e.strerror,
+ "DSGTools Plugin",
+ QgsMessageLog.INFO,
+ )
continue
@pyqtSlot(QAbstractButton)
@@ -126,7 +132,15 @@ def on_buttonBox_accepted(self):
"""
Copy the files to the correct location
"""
- self.copyFiles(self.scriptsList, self.scripts, os.path.join(currentPath, '..', '..', '..', '..', 'processing', 'scripts'))
+ self.copyFiles(
+ self.scriptsList,
+ self.scripts,
+ os.path.join(currentPath, "..", "..", "..", "..", "processing", "scripts"),
+ )
Processing.initialize()
- self.copyFiles(self.modelsList, self.models, os.path.join(currentPath, '..', '..', '..', '..', 'processing', 'models'))
+ self.copyFiles(
+ self.modelsList,
+ self.models,
+ os.path.join(currentPath, "..", "..", "..", "..", "processing", "models"),
+ )
Processing.initialize()
diff --git a/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py b/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py
index d90a40b35..36c6e1b4a 100644
--- a/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py
+++ b/DsgTools/gui/ProcessingUI/attributeRulesWrapper.py
@@ -20,34 +20,36 @@
* *
***************************************************************************/
"""
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedAttributeRulesWidget import \
- OrderedAttributeRulesWidget
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedAttributeRulesWidget import (
+ OrderedAttributeRulesWidget,
+)
from processing.gui.wrappers import WidgetWrapper
+
class AttributeRulesWrapper(WidgetWrapper):
def __init__(self, *args, **kwargs):
super(AttributeRulesWrapper, self).__init__(*args, **kwargs)
-
+
def createPanel(self):
return OrderedAttributeRulesWidget()
-
+
def createWidget(self):
self.panel = self.createPanel()
self.panel.dialogType = self.dialogType
return self.panel
-
+
def parentLayerChanged(self, layer=None):
pass
-
+
def setLayer(self, layer):
pass
-
+
def setValue(self, value):
pass
-
+
def value(self):
return self.panel.getHierarchicalSnapDict()
-
+
def postInitialize(self, wrappers):
pass
# for wrapper in wrappers:
diff --git a/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py b/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py
index ffab7781a..5513f0137 100644
--- a/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py
+++ b/DsgTools/gui/ProcessingUI/colorWidgetWrapper.py
@@ -24,29 +24,30 @@
from qgis.PyQt.QtGui import QColor
from processing.gui.wrappers import WidgetWrapper
+
class ColorWidgetWrapper(WidgetWrapper):
def __init__(self, *args, **kwargs):
super(ColorWidgetWrapper, self).__init__(*args, **kwargs)
-
+
def createPanel(self):
return QgsColorButton()
-
+
def createWidget(self):
self.panel = self.createPanel()
self.panel.dialogType = self.dialogType
return self.panel
-
+
def parentLayerChanged(self, layer=None):
pass
-
+
def setLayer(self, layer):
pass
-
+
def setValue(self, value):
self.panel.setColor(value)
-
+
def value(self):
return self.panel.color()
-
+
def postInitialize(self, wrappers):
pass
diff --git a/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py b/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py
index 6e4a4dd19..e2868055d 100644
--- a/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py
+++ b/DsgTools/gui/ProcessingUI/enforceAttributeRulesWrapper.py
@@ -23,21 +23,26 @@
import json
from functools import partial
-from qgis.core import (QgsProject, QgsVectorLayer)
+from qgis.core import QgsProject, QgsVectorLayer
from qgis.gui import QgsFieldExpressionWidget
from qgis.PyQt.QtCore import Qt
-from qgis.PyQt.QtWidgets import (QMessageBox,
- QHeaderView,
- QComboBox,
- QLineEdit)
-from processing.gui.wrappers import (WidgetWrapper,
- DIALOG_STANDARD,
- DIALOG_MODELER,
- DIALOG_BATCH)
-
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import OrderedTableWidget
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.colorSelectorWidget import ColorSelectorWidget
-from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.layerAndFieldSelectorWidget import LayerAndFieldSelectorWidget
+from qgis.PyQt.QtWidgets import QMessageBox, QHeaderView, QComboBox, QLineEdit
+from processing.gui.wrappers import (
+ WidgetWrapper,
+ DIALOG_STANDARD,
+ DIALOG_MODELER,
+ DIALOG_BATCH,
+)
+
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import (
+ OrderedTableWidget,
+)
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.colorSelectorWidget import (
+ ColorSelectorWidget,
+)
+from DsgTools.gui.CustomWidgets.BasicInterfaceWidgets.layerAndFieldSelectorWidget import (
+ LayerAndFieldSelectorWidget,
+)
from ...core.Utils.utils import ValidateImportedDataMethods
@@ -47,13 +52,13 @@ class EnforceAttributeRulesWrapper(WidgetWrapper):
been customized, for a specific type of parameter used in QGIS processing
algorithms.
"""
+
__ATTRIBUTE_MAP_VERSION = 0.1
# enum for column ordering
STD_COLUMN_COUNT = 5
MODELER_COLUMN_COUNT = 6
descStd, lyrStd, expStd, errStd, colorStd = list(range(STD_COLUMN_COUNT))
- descMd, lyrMd, fldMd, expMd, errMd, colorMd = list(
- range(MODELER_COLUMN_COUNT))
+ descMd, lyrMd, fldMd, expMd, errMd, colorMd = list(range(MODELER_COLUMN_COUNT))
def __init__(self, *args, **kwargs):
"""
@@ -95,10 +100,11 @@ def errorTypeComboBox(self):
Retrieves the configured error type selection combo box.
:return: (QComboBox) configured error selection widget.
"""
- errorTypeList = ["Atributo de valor incomum",
- "Atributo com valor incorreto",
- "Preencher atributo",
- ]
+ errorTypeList = [
+ "Atributo de valor incomum",
+ "Atributo com valor incorreto",
+ "Preencher atributo",
+ ]
cb = QComboBox()
cb.addItem(self.tr("Select an error type"))
@@ -135,8 +141,7 @@ def getLoadedLayers(self):
layers = QgsProject.instance().mapLayers().values()
for layer in layers:
if layer.type() == 0:
- loaded[layer.name()] = [field.name()
- for field in layer.fields()]
+ loaded[layer.name()] = [field.name() for field in layer.fields()]
else:
pass
return loaded
@@ -153,8 +158,9 @@ def getUnloadedLayers(self, attrRulesMap):
for k, v in attrRulesMap.items():
if k == "metadata":
continue
- if self.validateMethods.validatePythonTypes(v["1"], "list") and \
- self.validateMethods.validateLengthOfDataTypes(v["1"], 2):
+ if self.validateMethods.validatePythonTypes(
+ v["1"], "list"
+ ) and self.validateMethods.validateLengthOfDataTypes(v["1"], 2):
if v["1"][0] not in loadedLyr:
unsortedNotLoadedLyr.append(v["1"][0])
@@ -175,12 +181,12 @@ def modifyImportedAttributeRulesMap(self, attrRulesMap):
notLoadedLyrWarning = self.showLoadingMsg(notLoadedLyr, "warning")
if notLoadedLyrWarning == QMessageBox.Ignore:
invalidRulesWarning = self.validateMethods.showLoadingMsg(
- invalidRules, "invalid")
+ invalidRules, "invalid"
+ )
if invalidRulesWarning == QMessageBox.Ignore:
- self.modifyAttributeRulesMap(invalidRulesWarning,
- attrRulesMap,
- newDict,
- notLoadedLyr)
+ self.modifyAttributeRulesMap(
+ invalidRulesWarning, attrRulesMap, newDict, notLoadedLyr
+ )
else:
attrRulesMap.clear()
else:
@@ -188,18 +194,23 @@ def modifyImportedAttributeRulesMap(self, attrRulesMap):
elif not notLoadedLyr and invalidRules:
invalidRulesWarning = self.validateMethods.showLoadingMsg(
- invalidRules, "invalid")
+ invalidRules, "invalid"
+ )
self.modifyAttributeRulesMap(
- invalidRulesWarning, attrRulesMap, newDict, notLoadedLyr)
+ invalidRulesWarning, attrRulesMap, newDict, notLoadedLyr
+ )
elif notLoadedLyr and not invalidRules:
notLoadedLyrWarning = self.showLoadingMsg(notLoadedLyr, "warning")
self.modifyAttributeRulesMap(
- notLoadedLyrWarning, attrRulesMap, newDict, notLoadedLyr)
+ notLoadedLyrWarning, attrRulesMap, newDict, notLoadedLyr
+ )
else:
self.showLoadingMsg()
- def modifyAttributeRulesMap(self, clickedAction, attrRulesMap, newDict, notLoadedLyr):
+ def modifyAttributeRulesMap(
+ self, clickedAction, attrRulesMap, newDict, notLoadedLyr
+ ):
"""
Modifies the attrRulesMap dict with newDict data.
:param clickedAction: (QtAction) clicked button signal.
@@ -229,33 +240,64 @@ def mapAttributeRulesToNewDict(self, attrRulesMap):
for attrRulesMapKey, attrRulesMapValue in attrRulesMap.items():
if attrRulesMapKey == "metadata":
continue
- if self.validateMethods.validatePythonTypes(attrRulesMapValue["0"], "string"):
- if self.validateMethods.validatePythonTypes(attrRulesMapValue["1"], "list") \
- and self.validateMethods.validateLengthOfDataTypes(attrRulesMapValue["1"], 2):
- if self.validateMethods.validateQgsExpressions(attrRulesMapValue["2"]):
- if self.validateMethods.validatePythonTypes(attrRulesMapValue["3"], "string"):
- if self.validateMethods.validateQColor(attrRulesMapValue["4"]):
+ if self.validateMethods.validatePythonTypes(
+ attrRulesMapValue["0"], "string"
+ ):
+ if self.validateMethods.validatePythonTypes(
+ attrRulesMapValue["1"], "list"
+ ) and self.validateMethods.validateLengthOfDataTypes(
+ attrRulesMapValue["1"], 2
+ ):
+ if self.validateMethods.validateQgsExpressions(
+ attrRulesMapValue["2"]
+ ):
+ if self.validateMethods.validatePythonTypes(
+ attrRulesMapValue["3"], "string"
+ ):
+ if self.validateMethods.validateQColor(
+ attrRulesMapValue["4"]
+ ):
newDict[attrRulesMapKey] = attrRulesMapValue
else:
- invalidRules.append(self.tr(
- "Rule number {} : {} - is not a valid color.".format(
- attrRulesMapKey, attrRulesMapValue["4"])))
+ invalidRules.append(
+ self.tr(
+ "Rule number {} : {} - is not a valid color.".format(
+ attrRulesMapKey, attrRulesMapValue["4"]
+ )
+ )
+ )
else:
- invalidRules.append(self.tr(
- "Rule number {} : {} - is not a valid string.".format(
- attrRulesMapKey, attrRulesMapValue["3"])))
+ invalidRules.append(
+ self.tr(
+ "Rule number {} : {} - is not a valid string.".format(
+ attrRulesMapKey, attrRulesMapValue["3"]
+ )
+ )
+ )
else:
- invalidRules.append(self.tr(
- "Rule number {} : {} - is not a valid expression.".format(
- attrRulesMapKey, attrRulesMapValue["2"])))
+ invalidRules.append(
+ self.tr(
+ "Rule number {} : {} - is not a valid expression.".format(
+ attrRulesMapKey, attrRulesMapValue["2"]
+ )
+ )
+ )
else:
- invalidRules.append(self.tr(
- "Rule number {} : {} - is not a valid length = 2 list.".format(
- attrRulesMapKey, attrRulesMapValue["1"])))
+ invalidRules.append(
+ self.tr(
+ "Rule number {} : {} - is not a valid length = 2 list.".format(
+ attrRulesMapKey, attrRulesMapValue["1"]
+ )
+ )
+ )
else:
- invalidRules.append(self.tr(
- "Rule number {} : {} - is not a valid string description.".format(
- attrRulesMapKey, attrRulesMapValue["0"])))
+ invalidRules.append(
+ self.tr(
+ "Rule number {} : {} - is not a valid string description.".format(
+ attrRulesMapKey, attrRulesMapValue["0"]
+ )
+ )
+ )
return newDict, invalidRules
@@ -273,8 +315,7 @@ def modifyImportedAttributeRulesMapToModeler(self, attrRulesMap):
for k, v in attrRulesMap.items():
if k == "metadata":
continue
- if v["1"][0] not in loadedLyr or \
- v["1"][1] not in loadedLyr[v["1"][0]]:
+ if v["1"][0] not in loadedLyr or v["1"][1] not in loadedLyr[v["1"][0]]:
notLoadedLyr.append(v["1"][0])
else:
if isinstance(v["1"], (list, tuple)):
@@ -313,14 +354,15 @@ def showLoadingMsg(self, lyrList=None, msgType=None):
msg.setIcon(QMessageBox.Warning)
msg.setText(self.tr("Some rules have not been loaded"))
msg.setInformativeText(
- self.tr("Do you want to ignore and continue or cancel?"))
+ self.tr("Do you want to ignore and continue or cancel?")
+ )
textLyrList = sorted(set(lyrList))
formatedLyrList = ["{}" for item in textLyrList]
msgString = ",".join(formatedLyrList).replace(",", "\n")
formatedMsgString = self.tr(
- "The following layers have not been loaded:\n") + \
- msgString.format(*textLyrList)
+ "The following layers have not been loaded:\n"
+ ) + msgString.format(*textLyrList)
msg.setDetailedText(formatedMsgString)
msg.setStandardButtons(QMessageBox.Ignore | QMessageBox.Cancel)
@@ -380,48 +422,51 @@ def standardPanel(self):
Returns the table prepared for the standard Processing GUI.
:return: (OrderedTableWidget) DSGTools customized table widget.
"""
- otw = OrderedTableWidget(headerMap={
- 0: {
- "header": self.tr("Description"),
- "type": "widget",
- "widget": lambda: self.stringDataWidget(self.tr(
- "Set a name for this attribute rule...")),
- "setter": "setText",
- "getter": "text"
- },
- 1: {
- "header": self.tr("Layer and field"),
- "type": "widget",
- "widget": self.mapLyrAndFieldComboBox,
- "setter": "setCurrentInfo",
- "getter": "getCurrentInfo"
- },
- 2: {
- "header": self.tr("Expression"),
- "type": "widget",
- "widget": self.filterExpressionWidget,
- "setter": "setExpression",
- "getter": "currentText"
- },
- 3: {
- "header": self.tr("Error type"),
- "type": "widget",
- "widget": self.errorTypeComboBox,
- "setter": "setCurrentText",
- "getter": "currentText"
- },
- 4: {
- "header": self.tr("Color"),
- "type": "widget",
- "widget": self.colorSelectionWidget,
- "setter": "setCurrentColor",
- "getter": "getCurrentColor"
- },
-
- })
+ otw = OrderedTableWidget(
+ headerMap={
+ 0: {
+ "header": self.tr("Description"),
+ "type": "widget",
+ "widget": lambda: self.stringDataWidget(
+ self.tr("Set a name for this attribute rule...")
+ ),
+ "setter": "setText",
+ "getter": "text",
+ },
+ 1: {
+ "header": self.tr("Layer and field"),
+ "type": "widget",
+ "widget": self.mapLyrAndFieldComboBox,
+ "setter": "setCurrentInfo",
+ "getter": "getCurrentInfo",
+ },
+ 2: {
+ "header": self.tr("Expression"),
+ "type": "widget",
+ "widget": self.filterExpressionWidget,
+ "setter": "setExpression",
+ "getter": "currentText",
+ },
+ 3: {
+ "header": self.tr("Error type"),
+ "type": "widget",
+ "widget": self.errorTypeComboBox,
+ "setter": "setCurrentText",
+ "getter": "currentText",
+ },
+ 4: {
+ "header": self.tr("Color"),
+ "type": "widget",
+ "widget": self.colorSelectionWidget,
+ "setter": "setCurrentColor",
+ "getter": "getCurrentColor",
+ },
+ }
+ )
for row in [1, 3, 4]:
otw.horizontalHeader().setSectionResizeMode(
- row, QHeaderView.ResizeToContents)
+ row, QHeaderView.ResizeToContents
+ )
otw.setHeaderDoubleClickBehaviour("order")
otw.dataLoaded.connect(self.modifyImportedAttributeRulesMap)
otw.rowAdded.connect(self.postAddRowStandard)
@@ -439,85 +484,89 @@ def modelerPanel(self):
Returns the table prepared for the modeler Processing GUI.
:return: (OrderedTableWidget) DSGTools customized table widget.
"""
- otw = OrderedTableWidget(headerMap={
- 0: {
- "header": self.tr("Rule description"),
- "type": "widget",
- "widget": lambda: self.stringDataWidget(self.tr(
- "Set a name for this attribute rule...")),
- "setter": "setText",
- "getter": "text"
- },
- 1: {
- "header": self.tr("Layer"),
- "type": "widget",
- "widget": lambda: self.stringDataWidget(self.tr(
- "Type a vector layer name...")),
- "setter": "setText",
- "getter": "text"
- },
- 2: {
- "header": self.tr("Field"),
- "type": "widget",
- "widget": lambda: self.stringDataWidget(self.tr(
- "Type a field layer name...")),
- "setter": "setText",
- "getter": "text"
- },
- 3: {
- "header": self.tr("Expression"),
- "type": "widget",
- "widget": self.filterExpressionWidget,
- "setter": "setExpression",
- "getter": "currentText"
- },
- 4: {
- "header": self.tr("Error type"),
- "type": "widget",
- "widget": lambda: self.stringDataWidget(self.tr(
- "Type an error type...")),
- "setter": "setText",
- "getter": "text"
- },
- 5: {
- "header": self.tr("Color"),
- "type": "widget",
- "widget": self.colorSelectionWidget,
- "setter": "setCurrentColor",
- "getter": "getCurrentColor"
+ otw = OrderedTableWidget(
+ headerMap={
+ 0: {
+ "header": self.tr("Rule description"),
+ "type": "widget",
+ "widget": lambda: self.stringDataWidget(
+ self.tr("Set a name for this attribute rule...")
+ ),
+ "setter": "setText",
+ "getter": "text",
+ },
+ 1: {
+ "header": self.tr("Layer"),
+ "type": "widget",
+ "widget": lambda: self.stringDataWidget(
+ self.tr("Type a vector layer name...")
+ ),
+ "setter": "setText",
+ "getter": "text",
+ },
+ 2: {
+ "header": self.tr("Field"),
+ "type": "widget",
+ "widget": lambda: self.stringDataWidget(
+ self.tr("Type a field layer name...")
+ ),
+ "setter": "setText",
+ "getter": "text",
+ },
+ 3: {
+ "header": self.tr("Expression"),
+ "type": "widget",
+ "widget": self.filterExpressionWidget,
+ "setter": "setExpression",
+ "getter": "currentText",
+ },
+ 4: {
+ "header": self.tr("Error type"),
+ "type": "widget",
+ "widget": lambda: self.stringDataWidget(
+ self.tr("Type an error type...")
+ ),
+ "setter": "setText",
+ "getter": "text",
+ },
+ 5: {
+ "header": self.tr("Color"),
+ "type": "widget",
+ "widget": self.colorSelectionWidget,
+ "setter": "setCurrentColor",
+ "getter": "getCurrentColor",
+ },
}
- })
+ )
otw.setHeaderDoubleClickBehaviour("order")
- otw.dataLoaded.connect(self. modifyImportedAttributeRulesMapToModeler)
+ otw.dataLoaded.connect(self.modifyImportedAttributeRulesMapToModeler)
otw.rowAdded.connect(self.postAddRowModeler)
return otw
def createPanel(self):
- """ Docstring """
+ """Docstring"""
return {
DIALOG_MODELER: self.modelerPanel,
# DIALOG_MODELER: self.standardPanel,
DIALOG_STANDARD: self.standardPanel,
- DIALOG_BATCH: self.batchPanel
+ DIALOG_BATCH: self.batchPanel,
}[self.dialogType]()
def createWidget(self):
- """ Docstring """
+ """Docstring"""
self.panel = self.createPanel()
self.panel.showSaveLoadButtons(True)
self.panel.extension = ".json"
self.panel.fileType = self.tr("Set of DSGTools Attribute Rules")
- self.panel.setMetadata({
- "version": self.__ATTRIBUTE_MAP_VERSION
- })
+ self.panel.setMetadata({"version": self.__ATTRIBUTE_MAP_VERSION})
return self.panel
def parentLayerChanged(self, layer=None):
- """ Docstring """
+ """Docstring"""
pass
def setLayer(self, layer):
- """ Docstring """
+ """Docstring"""
pass
def setValue(self, value):
@@ -528,13 +577,15 @@ def setValue(self, value):
if value is None:
return
for valueMap in value:
- self.panel.addRow({
- 0: valueMap["description"],
- 1: valueMap["layerField"],
- 2: valueMap["expression"],
- 3: valueMap["errorType"],
- 4: valueMap["color"],
- })
+ self.panel.addRow(
+ {
+ 0: valueMap["description"],
+ 1: valueMap["layerField"],
+ 2: valueMap["expression"],
+ 3: valueMap["errorType"],
+ 4: valueMap["color"],
+ }
+ )
def readStandardPanel(self):
"""
@@ -564,8 +615,10 @@ def readModelerPanel(self):
for row in range(self.panel.rowCount()):
values = dict()
values["description"] = self.panel.getValue(row, 0).strip()
- values["layerField"] = [self.panel.getValue(row, 1),
- self.panel.getValue(row, 2)]
+ values["layerField"] = [
+ self.panel.getValue(row, 1),
+ self.panel.getValue(row, 2),
+ ]
values["expression"] = self.panel.getValue(row, 3)
values["errorType"] = self.panel.getValue(row, 4)
values["color"] = self.panel.getValue(row, 5)
@@ -588,9 +641,9 @@ def value(self):
return {
DIALOG_STANDARD: self.readStandardPanel,
DIALOG_MODELER: self.readModelerPanel,
- DIALOG_BATCH: self.readBatchPanel
+ DIALOG_BATCH: self.readBatchPanel,
}[self.dialogType]()
def postInitialize(self, wrappers):
- """ Docstring """
+ """Docstring"""
pass
diff --git a/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py b/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py
index 580c2d399..f20c269e1 100644
--- a/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py
+++ b/DsgTools/gui/ProcessingUI/enforceSpatialRuleWrapper.py
@@ -27,25 +27,32 @@
from qgis.gui import QgsMessageBar, QgsMapLayerComboBox, QgsFieldExpressionWidget
from qgis.PyQt.QtCore import QSize, QRegExp
from qgis.PyQt.QtGui import QRegExpValidator
-from qgis.PyQt.QtWidgets import (QWidget,
- QCheckBox,
- QComboBox,
- QLineEdit,
- QVBoxLayout,
- QMessageBox)
-from processing.gui.wrappers import (WidgetWrapper,
- DIALOG_STANDARD,
- DIALOG_MODELER,
- DIALOG_BATCH)
-
-from DsgTools.core.GeometricTools\
- .spatialRelationsHandler import (SpatialRule,
- SpatialRelationsHandler)
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets\
- .orderedTableWidget import OrderedTableWidget
+from qgis.PyQt.QtWidgets import (
+ QWidget,
+ QComboBox,
+ QLineEdit,
+ QVBoxLayout,
+ QMessageBox,
+)
+from processing.gui.wrappers import (
+ WidgetWrapper,
+ DIALOG_STANDARD,
+ DIALOG_MODELER,
+ DIALOG_BATCH,
+)
+
+from DsgTools.core.GeometricTools.spatialRelationsHandler import (
+ SpatialRule,
+ SpatialRelationsHandler,
+)
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import (
+ OrderedTableWidget,
+)
+
class EnforceSpatialRuleWrapper(WidgetWrapper):
__ATTRIBUTE_MAP_VERSION = 0.2
+
def __init__(self, *args, **kwargs):
super(EnforceSpatialRuleWrapper, self).__init__(*args, **kwargs)
self.messageBar = QgsMessageBar(self.panel)
@@ -56,12 +63,7 @@ def resizeEvent(self, e):
"""
Resize QgsMessageBar to widget's width
"""
- self.messageBar.resize(
- QSize(
- self.panel.parent().geometry().size().width(),
- 30
- )
- )
+ self.messageBar.resize(QSize(self.panel.parent().geometry().size().width(), 30))
def ruleNameWidget(self):
"""
@@ -75,7 +77,7 @@ def ruleNameWidget(self):
def mapLayerComboBox(self):
"""
Retrieves the configured map layer selection combo box.
- :return: (QgsMapLayerComboBox) configured layer selection widget.
+ :return: (QgsMapLayerComboBox) configured layer selection widget.
"""
cb = QgsMapLayerComboBox()
cb.setFilters(QgsMapLayerProxyModel.VectorLayer)
@@ -97,6 +99,7 @@ def filterExpressionWidget(self):
:return: (QgsFieldExpressionWidget) snap mode selection widget.
"""
fe = QgsFieldExpressionWidget()
+
def setValueProxy(exp):
layer = fe.layer()
if layer and exp.strip() in layer.fields().names():
@@ -105,12 +108,14 @@ def setValueProxy(exp):
# crash when running the algorithm. this seems to solve it.
exp = ""
fe.setExpression(exp)
+
def getValueProxy():
layer = fe.layer()
exp = fe.currentText()
if layer and exp.strip() in layer.fields().names():
exp = ""
return exp
+
fe.setExpression_ = setValueProxy
fe.currentText_ = getValueProxy
return fe
@@ -121,9 +126,7 @@ def predicateComboBox(self):
:return: (QComboBox) a combo box with all available predicates.
"""
cb = QComboBox()
- cb.addItems(
- list(SpatialRelationsHandler().availablePredicates().values())
- )
+ cb.addItems(list(SpatialRelationsHandler().availablePredicates().values()))
return cb
def de9imWidget(self):
@@ -149,13 +152,15 @@ def cardinalityWidget(self):
le.setPlaceholderText("1..*")
return le
- def useDE9IM(self):
- """
- Identifies whether user chose to input predicate as a DE-9IM mask.
- :return: (bool) whether GUI should handle the DE-9IM mask widget over
- the combo box selection.
- """
- return self.panel.cb.isChecked()
+ def _check_de9im_is_available(self, row):
+ otw = self.panel.otw
+ predicate = otw.getValue(row, 3)
+ handler = SpatialRelationsHandler()
+ enableDE9IM = predicate == handler.DE9IM
+ otw.itemAt(row, 4).setEnabled(enableDE9IM)
+ if not enableDE9IM:
+ otw.setValue(row, 4, "")
+ return enableDE9IM
def _checkCardinalityAvailability(self, row):
"""
@@ -166,19 +171,19 @@ def _checkCardinalityAvailability(self, row):
:return: (bool) whether cardinality is available
"""
otw = self.panel.otw
- if self.useDE9IM():
- # if user is using the DE-9IM input, cardinality won't be
- # managed
- otw.itemAt(row, 7).setEnabled(True)
- return True
predicate = otw.getValue(row, 3)
handler = SpatialRelationsHandler()
noCardinality = predicate in (
- handler.DISJOINT, handler.NOTEQUALS, handler.NOTINTERSECTS,
- handler.NOTTOUCHES, handler.NOTCROSSES, handler.NOTWITHIN,
- handler.NOTOVERLAPS, handler.NOTCONTAINS
+ handler.DISJOINT,
+ handler.NOTEQUALS,
+ handler.NOTINTERSECTS,
+ handler.NOTTOUCHES,
+ handler.NOTCROSSES,
+ handler.NOTWITHIN,
+ handler.NOTOVERLAPS,
+ handler.NOTCONTAINS,
)
- otw.itemAt(row, 7).setEnabled(not noCardinality)
+ otw.itemAt(row, 7).setEnabled(noCardinality)
if noCardinality:
otw.setValue(row, 7, "")
return not noCardinality
@@ -209,6 +214,10 @@ def postAddRowStandard(self, row):
)
# also triggers the action for the first time it is open
self._checkCardinalityAvailability(row)
+ predicateWidget.currentIndexChanged.connect(
+ partial(self._check_de9im_is_available, row)
+ )
+ self._check_de9im_is_available(row)
def postAddRowModeler(self, row):
"""
@@ -216,6 +225,7 @@ def postAddRowModeler(self, row):
:param row: (int) row to have its widgets setup.
"""
otw = self.panel.otw
+
def checkLayerBeforeConnect(le, filterExp):
lName = le.text().strip()
for layer in QgsProject.instance().mapLayersByName(lName):
@@ -223,6 +233,7 @@ def checkLayerBeforeConnect(le, filterExp):
filterExp.setLayer(layer)
return
filterExp.setLayer(None)
+
for col in [1, 5]:
le = otw.itemAt(row, col)
filterWidget = otw.itemAt(row, col + 1)
@@ -234,6 +245,10 @@ def checkLayerBeforeConnect(le, filterExp):
partial(self._checkCardinalityAvailability, row)
)
self._checkCardinalityAvailability(row)
+ predicateWidget.currentIndexChanged.connect(
+ partial(self._check_de9im_is_available, row)
+ )
+ self._check_de9im_is_available(row)
def standardPanel(self):
"""
@@ -243,78 +258,67 @@ def standardPanel(self):
widget = QWidget()
layout = QVBoxLayout()
# added as an attribute in order to make it easier to be read
- widget.cb = QCheckBox()
- widget.cb.setText(self.tr("Use DE-9IM inputs"))
- layout.addWidget(widget.cb)
- widget.otw = OrderedTableWidget(headerMap={
- 0 : {
- "header" : self.tr("Rule name"),
- "type" : "widget",
- "widget" : self.ruleNameWidget,
- "setter" : "setText",
- "getter" : "text"
- },
- 1 : {
- "header" : self.tr("Layer A"),
- "type" : "widget",
- "widget" : self.mapLayerComboBox,
- "setter" : "setCurrentText",
- "getter" : "currentText"
- },
- 2 : {
- "header" : self.tr("Filter A"),
- "type" : "widget",
- "widget" : self.filterExpressionWidget,
- "setter" : "setExpression_",
- "getter" : "currentText_"
- },
- 3 : {
- "header" : self.tr("Predicate"),
- "type" : "widget",
- "widget" : self.predicateComboBox,
- "setter" : "setCurrentIndex",
- "getter" : "currentIndex"
- },
- 4 : {
- "header" : self.tr("DE-9IM mask predicate"),
- "type" : "widget",
- "widget" : self.de9imWidget,
- "setter" : "setText",
- "getter" : "text"
- },
- 5 : {
- "header" : self.tr("Layer B"),
- "type" : "widget",
- "widget" : self.mapLayerComboBox,
- "setter" : "setCurrentText",
- "getter" : "currentText"
- },
- 6 : {
- "header" : self.tr("Filter B"),
- "type" : "widget",
- "widget" : self.filterExpressionWidget,
- "setter" : "setExpression_",
- "getter" : "currentText_"
- },
- 7 : {
- "header" : self.tr("Cardinality"),
- "type" : "widget",
- "widget" : self.cardinalityWidget,
- "setter" : "setText",
- "getter" : "text"
+ widget.otw = OrderedTableWidget(
+ headerMap={
+ 0: {
+ "header": self.tr("Rule name"),
+ "type": "widget",
+ "widget": self.ruleNameWidget,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 1: {
+ "header": self.tr("Layer A"),
+ "type": "widget",
+ "widget": self.mapLayerComboBox,
+ "setter": "setCurrentText",
+ "getter": "currentText",
+ },
+ 2: {
+ "header": self.tr("Filter A"),
+ "type": "widget",
+ "widget": self.filterExpressionWidget,
+ "setter": "setExpression_",
+ "getter": "currentText_",
+ },
+ 3: {
+ "header": self.tr("Predicate"),
+ "type": "widget",
+ "widget": self.predicateComboBox,
+ "setter": "setCurrentIndex",
+ "getter": "currentIndex",
+ },
+ 4: {
+ "header": self.tr("DE-9IM mask predicate"),
+ "type": "widget",
+ "widget": self.de9imWidget,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 5: {
+ "header": self.tr("Layer B"),
+ "type": "widget",
+ "widget": self.mapLayerComboBox,
+ "setter": "setCurrentText",
+ "getter": "currentText",
+ },
+ 6: {
+ "header": self.tr("Filter B"),
+ "type": "widget",
+ "widget": self.filterExpressionWidget,
+ "setter": "setExpression_",
+ "getter": "currentText_",
+ },
+ 7: {
+ "header": self.tr("Cardinality"),
+ "type": "widget",
+ "widget": self.cardinalityWidget,
+ "setter": "setText",
+ "getter": "text",
+ },
}
- })
- def handlePredicateColumns(checked):
- """
- Predicate input widgets are mutually exclusively: the user may only
- input data through either of them. This method manages hiding and
- showing correct columns in accord to the user selection.
- :param checked: (bool) whether the DE-9IM usage checkbox is ticked.
- """
- widget.otw.tableWidget.hideColumn(3 if checked else 4)
- widget.otw.tableWidget.showColumn(4 if checked else 3)
- widget.cb.toggled.connect(handlePredicateColumns)
- widget.cb.toggled.emit(widget.cb.isChecked())
+ )
+
widget.otw.setHeaderDoubleClickBehaviour("replicate")
widget.otw.rowAdded.connect(self.postAddRowStandard)
layout.addWidget(widget.otw)
@@ -336,78 +340,67 @@ def modelerPanel(self):
widget = QWidget()
layout = QVBoxLayout()
# added as an attribute in order to make it easier to be read
- widget.cb = QCheckBox()
- widget.cb.setText(self.tr("Use DE-9IM inputs"))
- layout.addWidget(widget.cb)
- widget.otw = OrderedTableWidget(headerMap={
- 0 : {
- "header" : self.tr("Rule name"),
- "type" : "widget",
- "widget" : self.ruleNameWidget,
- "setter" : "setText",
- "getter" : "text"
- },
- 1 : {
- "header" : self.tr("Layer A"),
- "type" : "widget",
- "widget" : self.mapLayerModelDialog,
- "setter" : "setText",
- "getter" : "text"
- },
- 2 : {
- "header" : self.tr("Filter A"),
- "type" : "widget",
- "widget" : self.filterExpressionWidget,
- "setter" : "setExpression_",
- "getter" : "currentText_"
- },
- 3 : {
- "header" : self.tr("Predicate"),
- "type" : "widget",
- "widget" : self.predicateComboBox,
- "setter" : "setCurrentIndex",
- "getter" : "currentIndex"
- },
- 4 : {
- "header" : self.tr("DE-9IM mask predicate"),
- "type" : "widget",
- "widget" : self.de9imWidget,
- "setter" : "setText",
- "getter" : "text"
- },
- 5 : {
- "header" : self.tr("Layer B"),
- "type" : "widget",
- "widget" : self.mapLayerModelDialog,
- "setter" : "setText",
- "getter" : "text"
- },
- 6 : {
- "header" : self.tr("Filter B"),
- "type" : "widget",
- "widget" : self.filterExpressionWidget,
- "setter" : "setExpression_",
- "getter" : "currentText_"
- },
- 7 : {
- "header" : self.tr("Cardinality"),
- "type" : "widget",
- "widget" : self.cardinalityWidget,
- "setter" : "setText",
- "getter" : "text"
+ widget.otw = OrderedTableWidget(
+ headerMap={
+ 0: {
+ "header": self.tr("Rule name"),
+ "type": "widget",
+ "widget": self.ruleNameWidget,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 1: {
+ "header": self.tr("Layer A"),
+ "type": "widget",
+ "widget": self.mapLayerModelDialog,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 2: {
+ "header": self.tr("Filter A"),
+ "type": "widget",
+ "widget": self.filterExpressionWidget,
+ "setter": "setExpression_",
+ "getter": "currentText_",
+ },
+ 3: {
+ "header": self.tr("Predicate"),
+ "type": "widget",
+ "widget": self.predicateComboBox,
+ "setter": "setCurrentIndex",
+ "getter": "currentIndex",
+ },
+ 4: {
+ "header": self.tr("DE-9IM mask predicate"),
+ "type": "widget",
+ "widget": self.de9imWidget,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 5: {
+ "header": self.tr("Layer B"),
+ "type": "widget",
+ "widget": self.mapLayerModelDialog,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 6: {
+ "header": self.tr("Filter B"),
+ "type": "widget",
+ "widget": self.filterExpressionWidget,
+ "setter": "setExpression_",
+ "getter": "currentText_",
+ },
+ 7: {
+ "header": self.tr("Cardinality"),
+ "type": "widget",
+ "widget": self.cardinalityWidget,
+ "setter": "setText",
+ "getter": "text",
+ },
}
- })
- def handlePredicateColumns(checked):
- """
- Predicate input widgets are mutually exclusively: the user may only
- input data through either of them. This method manages hiding and
- showing correct columns in accord to the user selection.
- :param checked: (bool) whether the DE-9IM usage checkbox is ticked.
- """
- widget.otw.tableWidget.hideColumn(3 if checked else 4)
- widget.otw.tableWidget.showColumn(4 if checked else 3)
- widget.cb.toggled.connect(handlePredicateColumns)
- widget.cb.toggled.emit(widget.cb.isChecked())
+ )
+
widget.otw.setHeaderDoubleClickBehaviour("replicate")
widget.otw.rowAdded.connect(self.postAddRowModeler)
layout.addWidget(widget.otw)
@@ -416,24 +409,22 @@ def handlePredicateColumns(checked):
def createPanel(self):
return {
- DIALOG_MODELER : self.modelerPanel,
- DIALOG_STANDARD : self.standardPanel,
- DIALOG_BATCH : self.batchPanel
+ DIALOG_MODELER: self.modelerPanel,
+ DIALOG_STANDARD: self.standardPanel,
+ DIALOG_BATCH: self.batchPanel,
}[self.dialogType]()
-
+
def createWidget(self):
self.panel = self.createPanel()
self.panel.otw.showSaveLoadButtons(True)
self.panel.otw.extension = ".rules"
self.panel.otw.fileType = self.tr("Set of DSGTools Spatial Rules")
- self.panel.otw.setMetadata({
- "version": self.__ATTRIBUTE_MAP_VERSION
- })
+ self.panel.otw.setMetadata({"version": self.__ATTRIBUTE_MAP_VERSION})
return self.panel
-
+
def parentLayerChanged(self, layer=None):
pass
-
+
def setLayer(self, layer):
pass
@@ -452,7 +443,8 @@ def showLoadingMsg(self, invalidRules=None, msgType=None):
msg.setIcon(QMessageBox.Warning)
msg.setText(self.tr("Some rules have not been loaded"))
msg.setInformativeText(
- self.tr("Do you want to ignore and continue or cancel?"))
+ self.tr("Do you want to ignore and continue or cancel?")
+ )
msgString = "\n".join((r.ruleName() for r in invalidRules))
formatedMsgString = self.tr(
"The following layers have not been loaded:\n{0}"
@@ -474,10 +466,6 @@ def setValue(self, value):
if not value:
return
otw = self.panel.otw
- useDE9IM = value[0].get("useDE9IM", False)
- self.panel.cb.setChecked(useDE9IM)
- # signal must be triggered to adjust the correct column display
- self.panel.cb.toggled.emit(useDE9IM)
isNotModeler = self.dialogType != DIALOG_MODELER
invalids = list()
for rule in value:
@@ -489,33 +477,36 @@ def setValue(self, value):
if not rule.isValid(checkLoaded=isNotModeler):
invalids.append(rule)
continue
- otw.addRow({
- 0: rule.ruleName(),
- 1: rule.layerA(),
- 2: rule.filterA(),
- 3: rule.predicateEnum(),
- 4: rule.predicateDE9IM(),
- 5: rule.layerB(),
- 6: rule.filterB(),
- 7: rule.cardinality()
- })
+ otw.addRow(
+ {
+ 0: rule.ruleName(),
+ 1: rule.layerA(),
+ 2: rule.filterA(),
+ 3: rule.predicateEnum(),
+ 4: rule.predicateDE9IM(),
+ 5: rule.layerB(),
+ 6: rule.filterB(),
+ 7: rule.cardinality(),
+ }
+ )
choice = self.showLoadingMsg(invalids, "warning" if invalids else "")
if choice == QMessageBox.Cancel:
otw.clear()
def readStandardPanel(self):
"""
- Reads widget's contents when process' parameters are set from an
+ Reads widget's contents when process' parameters are set from an
algorithm call (e.g. Processing toolbox).
"""
ruleList = list()
otw = self.panel.otw
- useDe9im = self.useDE9IM()
+ handler = SpatialRelationsHandler()
for row in range(otw.rowCount()):
+ useDE9IM = otw.getValue(row, 3) == handler.DE9IM
ruleList.append(
SpatialRule(
- name=otw.getValue(row, 0).strip(), # or \
- # self.tr("Spatial Rule #{n}".format(n=row + 1)),
+ name=otw.getValue(row, 0).strip(), # or \
+ # self.tr("Spatial Rule #{n}".format(n=row + 1)),
layer_a=otw.getValue(row, 1),
filter_a=otw.getValue(row, 2),
predicate=otw.getValue(row, 3),
@@ -523,8 +514,8 @@ def readStandardPanel(self):
layer_b=otw.getValue(row, 5),
filter_b=otw.getValue(row, 6),
cardinality=otw.getValue(row, 7) or "1..*",
- useDE9IM=useDe9im,
- checkLoadedLayer=False
+ useDE9IM=useDE9IM,
+ checkLoadedLayer=False,
).asDict()
)
return ruleList
@@ -551,16 +542,16 @@ def validate(self, pushAlert=False):
:return: (bool) whether set of filled parameters if valid.
"""
inputMap = {
- DIALOG_STANDARD : self.readStandardPanel,
- DIALOG_MODELER : self.readModelerPanel,
- DIALOG_BATCH : self.readBatchPanel
+ DIALOG_STANDARD: self.readStandardPanel,
+ DIALOG_MODELER: self.readModelerPanel,
+ DIALOG_BATCH: self.readBatchPanel,
}[self.dialogType]()
if len(inputMap) == 0:
if pushAlert:
self.messageBar.pushMessage(
self.tr("Please provide at least 1 spatial rule."),
level=Qgis.Warning,
- duration=5
+ duration=5,
)
return False
for row, rule in enumerate(inputMap):
@@ -569,10 +560,9 @@ def validate(self, pushAlert=False):
if not rule.isValid():
if pushAlert:
self.messageBar.pushMessage(
- self.tr("{0} (row {1}).")\
- .format(rule.validate(), row + 1),
+ self.tr("{0} (row {1}).").format(rule.validate(), row + 1),
level=Qgis.Warning,
- duration=5
+ duration=5,
)
return False
return True
@@ -584,10 +574,10 @@ def value(self):
"""
if self.validate(pushAlert=True):
return {
- DIALOG_STANDARD : self.readStandardPanel,
- DIALOG_MODELER : self.readModelerPanel,
- DIALOG_BATCH : self.readBatchPanel
+ DIALOG_STANDARD: self.readStandardPanel,
+ DIALOG_MODELER: self.readModelerPanel,
+ DIALOG_BATCH: self.readBatchPanel,
}[self.dialogType]()
-
+
def postInitialize(self, wrappers):
pass
diff --git a/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py b/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py
index 721aa943c..080acff47 100644
--- a/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py
+++ b/DsgTools/gui/ProcessingUI/fmeManagerWrapper.py
@@ -20,34 +20,36 @@
* *
***************************************************************************/
"""
-from DsgTools.gui.CustomWidgets.ProcessingParameterWidgets.fmeManagerWidget import \
- FMEManagerWidget
+from DsgTools.gui.CustomWidgets.ProcessingParameterWidgets.fmeManagerWidget import (
+ FMEManagerWidget,
+)
from processing.gui.wrappers import WidgetWrapper
+
class FMEManagerWrapper(WidgetWrapper):
def __init__(self, *args, **kwargs):
super(FMEManagerWrapper, self).__init__(*args, **kwargs)
-
+
def createPanel(self):
return FMEManagerWidget()
-
+
def createWidget(self):
self.panel = self.createPanel()
self.panel.dialogType = self.dialogType
return self.panel
-
+
def parentLayerChanged(self, layer=None):
pass
-
+
def setLayer(self, layer):
pass
-
+
def setValue(self, value):
pass
-
+
def value(self):
return self.panel.getParameters()
-
+
def postInitialize(self, wrappers):
pass
# for wrapper in wrappers:
diff --git a/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py b/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py
index 3b001bc52..4434900f7 100644
--- a/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py
+++ b/DsgTools/gui/ProcessingUI/fontWidgetWrapper.py
@@ -24,29 +24,30 @@
from processing.gui.wrappers import WidgetWrapper
from qgis.PyQt.QtGui import QFont
+
class FontWidgetWrapper(WidgetWrapper):
def __init__(self, *args, **kwargs):
super(FontWidgetWrapper, self).__init__(*args, **kwargs)
-
+
def createPanel(self):
return QFontComboBox()
-
+
def createWidget(self):
self.panel = self.createPanel()
self.panel.dialogType = self.dialogType
return self.panel
-
+
def parentLayerChanged(self, layer=None):
pass
-
+
def setLayer(self, layer):
pass
-
+
def setValue(self, value):
self.panel.setCurrentFont(value)
-
+
def value(self):
return self.panel.currentFont()
-
+
def postInitialize(self, wrappers):
pass
diff --git a/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py b/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py
index 2b8e64eb5..bb8cb83b1 100644
--- a/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py
+++ b/DsgTools/gui/ProcessingUI/snapHierarchyWrapper.py
@@ -22,15 +22,18 @@
"""
from qgis.gui import QgsMapLayerComboBox
-from qgis.PyQt.QtWidgets import (QComboBox,
- QLineEdit,
- QDoubleSpinBox)
-from processing.gui.wrappers import (WidgetWrapper,
- DIALOG_STANDARD,
- DIALOG_MODELER,
- DIALOG_BATCH)
+from qgis.PyQt.QtWidgets import QComboBox, QLineEdit, QDoubleSpinBox
+from processing.gui.wrappers import (
+ WidgetWrapper,
+ DIALOG_STANDARD,
+ DIALOG_MODELER,
+ DIALOG_BATCH,
+)
+
+from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import (
+ OrderedTableWidget,
+)
-from DsgTools.gui.CustomWidgets.OrderedPropertyWidgets.orderedTableWidget import OrderedTableWidget
class SnapHierarchyWrapper(WidgetWrapper):
def __init__(self, *args, **kwargs):
@@ -39,15 +42,15 @@ def __init__(self, *args, **kwargs):
def mapLayerComboBox(self):
"""
Retrieves the configured map layer selection combo box.
- :return: (QgsMapLayerComboBox) configured layer selection widget.
+ :return: (QgsMapLayerComboBox) configured layer selection widget.
"""
cb = QgsMapLayerComboBox()
return cb
-
+
def doubleSpinBox(self):
"""
Retrieves the configured map layer selection combo box.
- :return: (QgsMapLayerComboBox) configured layer selection widget.
+ :return: (QgsMapLayerComboBox) configured layer selection widget.
"""
sb = QDoubleSpinBox()
sb.setDecimals(10)
@@ -69,15 +72,17 @@ def modeComboBox(self):
:return: (QComboBox) snap mode selection widget.
"""
cb = QComboBox()
- cb.addItems([
- self.tr("Prefer aligning nodes, insert extra vertices where required"),
- self.tr("Prefer closest point, insert extra vertices where required"),
- self.tr("Prefer aligning nodes, don't insert new vertices"),
- self.tr("Prefer closest point, don't insert new vertices"),
- self.tr("Move end points only, prefer aligning nodes"),
- self.tr("Move end points only, prefer closest point"),
- self.tr("Snap end points to end points only")
- ])
+ cb.addItems(
+ [
+ self.tr("Prefer aligning nodes, insert extra vertices where required"),
+ self.tr("Prefer closest point, insert extra vertices where required"),
+ self.tr("Prefer aligning nodes, don't insert new vertices"),
+ self.tr("Prefer closest point, don't insert new vertices"),
+ self.tr("Move end points only, prefer aligning nodes"),
+ self.tr("Move end points only, prefer closest point"),
+ self.tr("Snap end points to end points only"),
+ ]
+ )
return cb
def standardPanel(self):
@@ -85,29 +90,31 @@ def standardPanel(self):
Returns the table prepared for the standard Processing GUI.
:return: (OrderedTableWidget) DSGTools customized table widget.
"""
- otw = OrderedTableWidget(headerMap={
- 0 : {
- "header" : self.tr("Layer"),
- "type" : "widget",
- "widget" : self.mapLayerComboBox,
- "setter" : "setCurrentText",
- "getter" : "currentText"
- },
- 1 : {
- "header" : self.tr("Snap"),
- "type" : "widget",
- "widget" : self.doubleSpinBox,
- "setter" : "setValue",
- "getter" : "value"
- },
- 2 : {
- "header" : self.tr("Snap mode"),
- "type" : "widget",
- "widget" : self.modeComboBox,
- "setter" : "setCurrentIndex",
- "getter" : "currentIndex"
+ otw = OrderedTableWidget(
+ headerMap={
+ 0: {
+ "header": self.tr("Layer"),
+ "type": "widget",
+ "widget": self.mapLayerComboBox,
+ "setter": "setCurrentText",
+ "getter": "currentText",
+ },
+ 1: {
+ "header": self.tr("Snap"),
+ "type": "widget",
+ "widget": self.doubleSpinBox,
+ "setter": "setValue",
+ "getter": "value",
+ },
+ 2: {
+ "header": self.tr("Snap mode"),
+ "type": "widget",
+ "widget": self.modeComboBox,
+ "setter": "setCurrentIndex",
+ "getter": "currentIndex",
+ },
}
- })
+ )
otw.setHeaderDoubleClickBehaviour("replicate")
return otw
@@ -123,50 +130,52 @@ def modelerPanel(self):
Returns the table prepared for the modeler Processing GUI.
:return: (OrderedTableWidget) DSGTools customized table widget.
"""
- otw = OrderedTableWidget(headerMap={
- 0 : {
- "header" : self.tr("Layer"),
- "type" : "widget",
- "widget" : self.mapLayerModelDialog,
- "setter" : "setText",
- "getter" : "text"
- },
- 1 : {
- "header" : self.tr("Snap"),
- "type" : "widget",
- "widget" : self.doubleSpinBox,
- "setter" : "setValue",
- "getter" : "value"
- },
- 2 : {
- "header" : self.tr("Snap mode"),
- "type" : "widget",
- "widget" : self.modeComboBox,
- "setter" : "setCurrentIndex",
- "getter" : "currentIndex"
+ otw = OrderedTableWidget(
+ headerMap={
+ 0: {
+ "header": self.tr("Layer"),
+ "type": "widget",
+ "widget": self.mapLayerModelDialog,
+ "setter": "setText",
+ "getter": "text",
+ },
+ 1: {
+ "header": self.tr("Snap"),
+ "type": "widget",
+ "widget": self.doubleSpinBox,
+ "setter": "setValue",
+ "getter": "value",
+ },
+ 2: {
+ "header": self.tr("Snap mode"),
+ "type": "widget",
+ "widget": self.modeComboBox,
+ "setter": "setCurrentIndex",
+ "getter": "currentIndex",
+ },
}
- })
+ )
otw.setHeaderDoubleClickBehaviour("replicate")
return otw
def createPanel(self):
return {
- DIALOG_MODELER : self.modelerPanel,
- DIALOG_STANDARD : self.standardPanel,
- DIALOG_BATCH : self.batchPanel
+ DIALOG_MODELER: self.modelerPanel,
+ DIALOG_STANDARD: self.standardPanel,
+ DIALOG_BATCH: self.batchPanel,
}[self.dialogType]()
-
+
def createWidget(self):
self.panel = self.createPanel()
# self.panel.dialogType = self.dialogType
return self.panel
-
+
def parentLayerChanged(self, layer=None):
pass
-
+
def setLayer(self, layer):
pass
-
+
def setValue(self, value):
"""
Sets back parameters to the GUI. Method reimplementation.
@@ -175,27 +184,27 @@ def setValue(self, value):
if value is None:
return
for valueMap in value:
- self.panel.addRow({
- 0 : valueMap["referenceLayer"],
- 1 : valueMap["snap"],
- 2 : valueMap["mode"]
- })
+ self.panel.addRow(
+ {
+ 0: valueMap["referenceLayer"],
+ 1: valueMap["snap"],
+ 2: valueMap["mode"],
+ }
+ )
def readStandardPanel(self):
"""
- Reads widget's contents when process' parameters are set from an
+ Reads widget's contents when process' parameters are set from an
algorithm call (e.g. Processing toolbox).
"""
valueMaplist = list()
- layers = [
- self.panel.getValue(r, 0) for r in range(self.panel.rowCount())
- ]
+ layers = [self.panel.getValue(r, 0) for r in range(self.panel.rowCount())]
for row in range(self.panel.rowCount()):
values = dict()
values["referenceLayer"] = self.panel.getValue(row, 0)
values["snap"] = self.panel.getValue(row, 1)
values["mode"] = self.panel.getValue(row, 2)
- values["snapLayerList"] = [l for l in layers[(row + 1)::]]
+ values["snapLayerList"] = [l for l in layers[(row + 1) : :]]
valueMaplist.append(values)
return valueMaplist
@@ -219,11 +228,11 @@ def value(self):
:return: (dict) value currently set to the GUI.
"""
return {
- DIALOG_STANDARD : self.readStandardPanel,
- DIALOG_MODELER : self.readModelerPanel,
- DIALOG_BATCH : self.readBatchPanel
+ DIALOG_STANDARD: self.readStandardPanel,
+ DIALOG_MODELER: self.readModelerPanel,
+ DIALOG_BATCH: self.readBatchPanel,
}[self.dialogType]()
-
+
def postInitialize(self, wrappers):
pass
# for wrapper in wrappers:
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py
index 365a7d1cd..0560fd834 100755
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/acquisition.py
@@ -8,6 +8,7 @@
from .circle import Circle
from .polygon import Polygon
+
class Acquisition(QObject):
def __init__(self, iface):
super(Acquisition, self).__init__()
@@ -17,26 +18,28 @@ def __init__(self, iface):
self.polygonAction = None
self.circleAction = None
self.toolAction = None
-
+
def addTool(self, manager, callback, parentMenu, iconBasePath):
- icon_path = iconBasePath + 'home.png'
- toolTip = self.tr("DSGTools: Right Degree Angle Digitizing\nControl modifier: disables tool while control is pressed.")
+ icon_path = iconBasePath + "home.png"
+ toolTip = self.tr(
+ "DSGTools: Right Degree Angle Digitizing\nControl modifier: disables tool while control is pressed."
+ )
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Right Degree Angle Digitizing'),
+ text=self.tr("DSGTools: Right Degree Angle Digitizing"),
callback=self.acquisitionNinetyDegrees,
add_to_menu=False,
add_to_toolbar=True,
- withShortcut = True,
- tooltip = toolTip,
- parentToolbar =parentMenu
- )
+ withShortcut=True,
+ tooltip=toolTip,
+ parentToolbar=parentMenu,
+ )
self.setPolygonAction(action)
self.toolAction = action
def setPolygonAction(self, action):
self.polygonAction = action
-
+
def setCircleAction(self, action):
self.circleAction = action
@@ -45,10 +48,14 @@ def acquisitionNinetyDegrees(self):
def acquisitionCircle(self):
self.run(Circle, self.circleAction)
-
+
def setToolEnabled(self):
- layer = self.iface.activeLayer()
- if not isinstance(layer, QgsVectorLayer) or layer.geometryType() == QgsWkbTypes.PointGeometry or not layer.isEditable():
+ layer = self.iface.activeLayer()
+ if (
+ not isinstance(layer, QgsVectorLayer)
+ or layer.geometryType() == QgsWkbTypes.PointGeometry
+ or not layer.isEditable()
+ ):
enabled = False
else:
enabled = True
@@ -59,22 +66,34 @@ def setToolEnabled(self):
if self.circleAction:
self.circleAction.setEnabled(enabled)
return enabled
-
+
def run(self, func, action):
layer = self.canvas.currentLayer()
if layer in self.iface.editableLayers():
- if layer.geometryType() in [QgsWkbTypes.LineGeometry , QgsWkbTypes.PolygonGeometry]:
+ if layer.geometryType() in [
+ QgsWkbTypes.LineGeometry,
+ QgsWkbTypes.PolygonGeometry,
+ ]:
if self.tool:
self.tool.deactivate()
self.tool = func(self.canvas, self.iface, action)
self.tool.setAction(action)
self.canvas.setMapTool(self.tool)
else:
- self.iface.messageBar().pushMessage(self.tr('Warning'), self.tr('Tool not defined for points'),
- level=Qgis.Info, duration=3)
+ self.iface.messageBar().pushMessage(
+ self.tr("Warning"),
+ self.tr("Tool not defined for points"),
+ level=Qgis.Info,
+ duration=3,
+ )
self.tool.deactivate() if self.tool else ""
else:
- self.iface.messageBar().pushMessage(self.tr('Warning'), self.tr('Start editing in current layer!'), level=Qgis.Info, duration=3)
+ self.iface.messageBar().pushMessage(
+ self.tr("Warning"),
+ self.tr("Start editing in current layer!"),
+ level=Qgis.Info,
+ duration=3,
+ )
self.tool.deactivate() if self.tool else ""
def unload(self):
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py
index 0b8fb9ee9..06ab05b5a 100755
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/circle.py
@@ -15,6 +15,7 @@
from qgis.core import QgsPointXY, Qgis, QgsWkbTypes
from qgis.gui import QgsMapMouseEvent, QgsMapTool
+
class Circle(GeometricaAcquisition):
def __init__(self, canvas, iface, action):
super(Circle, self).__init__(canvas, iface, action)
@@ -22,7 +23,7 @@ def __init__(self, canvas, iface, action):
self.iface = iface
self.rubberBand = None
self.initVariable()
-
+
def initVariable(self):
if self.rubberBand:
self.rubberBand.reset(True)
@@ -31,23 +32,27 @@ def initVariable(self):
self.endPoint = None
self.qntPoint = 0
self.geometry = []
-
+
def showCircle(self, startPoint, endPoint):
nPoints = 50
x = startPoint.x()
y = startPoint.y()
- r = math.sqrt((endPoint.x() - startPoint.x())**2 + (endPoint.y() - startPoint.y())**2)
+ r = math.sqrt(
+ (endPoint.x() - startPoint.x()) ** 2 + (endPoint.y() - startPoint.y()) ** 2
+ )
self.rubberBand.reset(self.iface.activeLayer().geometryType())
- for itheta in range(nPoints+1):
- theta = itheta*(2.0*math.pi/nPoints)
- self.rubberBand.addPoint(QgsPointXY(x+r*math.cos(theta), y+r*math.sin(theta)))
+ for itheta in range(nPoints + 1):
+ theta = itheta * (2.0 * math.pi / nPoints)
+ self.rubberBand.addPoint(
+ QgsPointXY(x + r * math.cos(theta), y + r * math.sin(theta))
+ )
self.rubberBand.closePoints()
def endGeometry(self):
self.geometry = self.rubberBand.asGeometry()
self.createGeometry(self.geometry)
-
+
def canvasReleaseEvent(self, event):
if event.button() == Qt.LeftButton:
if not self.startPoint:
@@ -55,7 +60,7 @@ def canvasReleaseEvent(self, event):
self.rubberBand = self.getRubberBand()
if event.button() == Qt.RightButton:
self.endGeometry()
-
+
def canvasMoveEvent(self, event):
if self.snapCursorRubberBand:
self.snapCursorRubberBand.hide()
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py
index 49fa3e1d5..850108dbf 100644
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/distanceToolTip.py
@@ -22,58 +22,61 @@
"""
from qgis.core import (
- QgsDistanceArea,
- QgsCoordinateTransformContext,
- QgsCoordinateReferenceSystem,
- QgsCoordinateTransform,
- QgsProject,
- QgsGeometry
- )
+ QgsDistanceArea,
+ QgsCoordinateTransformContext,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsProject,
+ QgsGeometry,
+)
from DsgTools.gui.ProductionTools.MapTools.Acquisition.toolTip import ToolTip
+
class DistanceToolTip(ToolTip):
- def __init__(self, iface, minSegmentDistance, decimals):
- super(DistanceToolTip, self).__init__(iface)
- self.iface = iface
- self.canvas = iface.mapCanvas()
- self.last_distance = 0
- self.showing = False
- self.minSegmentDistance = minSegmentDistance
- self.decimals = decimals
+ def __init__(self, iface, minSegmentDistance, decimals):
+ super(DistanceToolTip, self).__init__(iface)
+ self.iface = iface
+ self.canvas = iface.mapCanvas()
+ self.last_distance = 0
+ self.showing = False
+ self.minSegmentDistance = minSegmentDistance
+ self.decimals = decimals
- def calculateDistance(self, p1, p2):
- source_crs = self.iface.mapCanvas().mapSettings().destinationCrs()
- dest_crs = QgsCoordinateReferenceSystem(3857)
- tr = QgsCoordinateTransform(source_crs, dest_crs, QgsCoordinateTransformContext())
- p1t = QgsGeometry().fromPointXY(p1)
- p1t.transform(tr)
- p2t = QgsGeometry().fromPointXY(p2)
- p2t.transform(tr)
- distance = QgsDistanceArea()
- m = distance.measureLine(p1t.asPoint(), p2t.asPoint())
- return m
+ def calculateDistance(self, p1, p2):
+ source_crs = self.iface.mapCanvas().mapSettings().destinationCrs()
+ dest_crs = QgsCoordinateReferenceSystem(3857)
+ tr = QgsCoordinateTransform(
+ source_crs, dest_crs, QgsCoordinateTransformContext()
+ )
+ p1t = QgsGeometry().fromPointXY(p1)
+ p1t.transform(tr)
+ p2t = QgsGeometry().fromPointXY(p2)
+ p2t.transform(tr)
+ distance = QgsDistanceArea()
+ m = distance.measureLine(p1t.asPoint(), p2t.asPoint())
+ return m
- def canvasMoveEvent(self, last_p, current_p):
- m = float(self.calculateDistance(last_p, current_p))
- if self.showing:
- if m != self.last_distance:
- color = 'red'
- if m >= self.minSegmentDistance:
- color = 'green'
- txt = f"
{m:.{self.decimals}f}
"
- self.show(txt, current_p)
- self.last_distance = m
- else:
- if m > 1:
- color = 'red'
- if m >= self.minSegmentDistance:
- color = 'green'
- txt = f"
{m:.{self.decimals}f}
"
- super(DistanceToolTip, self).show(txt, current_p)
- self.last_distance = m
- self.showing = True
+ def canvasMoveEvent(self, last_p, current_p):
+ m = float(self.calculateDistance(last_p, current_p))
+ if self.showing:
+ if m != self.last_distance:
+ color = "red"
+ if m >= self.minSegmentDistance:
+ color = "green"
+ txt = f"
{m:.{self.decimals}f}
"
+ self.show(txt, current_p)
+ self.last_distance = m
+ else:
+ if m > 1:
+ color = "red"
+ if m >= self.minSegmentDistance:
+ color = "green"
+ txt = f"
{m:.{self.decimals}f}
"
+ super(DistanceToolTip, self).show(txt, current_p)
+ self.last_distance = m
+ self.showing = True
- def deactivate(self):
- self.deactivate()
- self.showing = False
+ def deactivate(self):
+ self.deactivate()
+ self.showing = False
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py
index 97023c886..232e48257 100755
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/geometricaAquisition.py
@@ -23,20 +23,37 @@
from qgis import core, gui
from qgis.PyQt.QtCore import Qt, QSettings
from qgis.PyQt.QtGui import QCursor, QPixmap, QColor
-from qgis.gui import QgsMapTool, QgsRubberBand, QgsAttributeDialog, \
- QgsAttributeForm, QgsSnapIndicator
+from qgis.gui import (
+ QgsMapTool,
+ QgsRubberBand,
+ QgsAttributeDialog,
+ QgsAttributeForm,
+ QgsSnapIndicator,
+)
from qgis.utils import iface
-from qgis.core import QgsPointXY, QgsFeature, QgsGeometry, Qgis, QgsCoordinateReferenceSystem,\
- QgsCoordinateTransform, QgsEditFormConfig, QgsWkbTypes, QgsProject, \
- QgsPointLocator
+from qgis.core import (
+ QgsPointXY,
+ QgsFeature,
+ QgsGeometry,
+ Qgis,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsEditFormConfig,
+ QgsWkbTypes,
+ QgsProject,
+ QgsPointLocator,
+)
+
+from DsgTools.gui.ProductionTools.MapTools.Acquisition.distanceToolTip import (
+ DistanceToolTip,
+)
-from DsgTools.gui.ProductionTools.MapTools.Acquisition.distanceToolTip import DistanceToolTip
class GeometricaAcquisition(QgsMapTool):
def __init__(self, canvas, iface, action):
super(GeometricaAcquisition, self).__init__(canvas)
super(GeometricaAcquisition, self).__init__(canvas)
- self.iface=iface
+ self.iface = iface
self.canvas = canvas
self.rubberBand = None
self.snapCursorRubberBand = None
@@ -44,44 +61,52 @@ def __init__(self, canvas, iface, action):
self.setAction(action)
self.minSegmentDistance = self.getMinSegmentDistance()
self.decimals = self.getDecimals()
- self.distanceToolTip = DistanceToolTip(self.iface, self.minSegmentDistance, self.decimals)
+ self.distanceToolTip = DistanceToolTip(
+ self.iface, self.minSegmentDistance, self.decimals
+ )
def getSuppressOption(self):
qgisSettigns = QSettings()
- qgisSettigns.beginGroup('qgis/digitizing')
- setting = qgisSettigns.value('disable_enter_attribute_values_dialog')
+ qgisSettigns.beginGroup("qgis/digitizing")
+ setting = qgisSettigns.value("disable_enter_attribute_values_dialog")
qgisSettigns.endGroup()
- return setting == 'true'
+ return setting == "true"
def setAction(self, action):
self.toolAction = action
self.toolAction.setCheckable(True)
-
+
def canvasPressEvent(self, e):
pass
-
+
def activate(self):
if self.toolAction:
self.toolAction.setChecked(True)
self.free = False
- self.cur = QCursor(QPixmap(["18 13 4 1",
- " c None",
- "# c #FF0000",
- ". c #FF0000",
- "+ c #1210f3",
- " ",
- " +++++++++++ ",
- " + # + ",
- " + # + ",
- "+ # +",
- "+ # +",
- "++#############++",
- "+ # +",
- "+ # +",
- " + # +",
- " + # + ",
- " +++++++++++ ",
- " ",]))
+ self.cur = QCursor(
+ QPixmap(
+ [
+ "18 13 4 1",
+ " c None",
+ "# c #FF0000",
+ ". c #FF0000",
+ "+ c #1210f3",
+ " ",
+ " +++++++++++ ",
+ " + # + ",
+ " + # + ",
+ "+ # +",
+ "+ # +",
+ "++#############++",
+ "+ # +",
+ "+ # +",
+ " + # +",
+ " + # + ",
+ " +++++++++++ ",
+ " ",
+ ]
+ )
+ )
self.canvas.setCursor(self.cur)
def deactivate(self):
@@ -96,7 +121,7 @@ def keyReleaseEvent(self, event):
self.initVariable()
if event.key() == Qt.Key_Control:
self.free = False
-
+
def keyPressEvent(self, event):
if event.key() == Qt.Key_Control:
self.free = True
@@ -107,20 +132,20 @@ def keyPressEvent(self, event):
self.rubberBand.setToGeometry(geom, self.iface.activeLayer())
def getParametersFromConfig(self):
- #Método para obter as configurações da tool do QSettings
- #Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta)
+ # Método para obter as configurações da tool do QSettings
+ # Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta)
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
parameters = {
- u'minSegmentDistance' : settings.value('minSegmentDistance'),
- u'rightAngleDecimals': settings.value('rightAngleDecimals'),
+ "minSegmentDistance": settings.value("minSegmentDistance"),
+ "rightAngleDecimals": settings.value("rightAngleDecimals"),
}
settings.endGroup()
return parameters
def initVariable(self):
if self.rubberBand:
- self.rubberBand.reset(geometryType = self.iface.activeLayer().geometryType())
+ self.rubberBand.reset(geometryType=self.iface.activeLayer().geometryType())
self.rubberBand = None
self.qntPoint = 0
self.geometry = []
@@ -131,32 +156,41 @@ def initVariable(self):
def getMinSegmentDistance(self):
parameters = self.getParametersFromConfig()
- return float(parameters[u'minSegmentDistance'])
-
+ return float(parameters["minSegmentDistance"])
+
def getDecimals(self):
parameters = self.getParametersFromConfig()
- return int(parameters[u'rightAngleDecimals']) if parameters[u'rightAngleDecimals'] is not None else 2
+ return (
+ int(parameters["rightAngleDecimals"])
+ if parameters["rightAngleDecimals"] is not None
+ else 2
+ )
- def completePolygon(self,geom, p4):
- if (len(geom)>=2) and (len(geom) % 2 == 0):
- p1 = geom[1]
- p2 = geom[0]
- p3 = geom[-1]
+ def completePolygon(self, geom, p4):
+ if (len(geom) >= 2) and (len(geom) % 2 == 0):
+ p1 = geom[1]
+ p2 = geom[0]
+ p3 = geom[-1]
pf = self.lineIntersection(p1, p2, p3, p4)
- new_geom = QgsGeometry.fromPolygonXY([self.geometry+[p4, pf]])
+ new_geom = QgsGeometry.fromPolygonXY([self.geometry + [p4, pf]])
else:
- new_geom = QgsGeometry.fromPolygonXY([self.geometry+[QgsPointXY(p4.x(), p4.y())]])
- pf = p4
+ new_geom = QgsGeometry.fromPolygonXY(
+ [self.geometry + [QgsPointXY(p4.x(), p4.y())]]
+ )
+ pf = p4
return new_geom, pf
def bufferDistanceTest(self, geom, penult, last):
def isWithinLimits(pnt):
"""checks whether point is distant enough from proposed geom's
ending points (penult and last)"""
- return self.distanceToolTip.calculateDistance(
- last, pnt) >= self.minSegmentDistance and \
- self.distanceToolTip.calculateDistance(
- penult, pnt) >= self.minSegmentDistance
+ return (
+ self.distanceToolTip.calculateDistance(last, pnt)
+ >= self.minSegmentDistance
+ and self.distanceToolTip.calculateDistance(penult, pnt)
+ >= self.minSegmentDistance
+ )
+
for i in range(len(geom)):
if not isWithinLimits(geom[i]):
return False
@@ -164,11 +198,11 @@ def isWithinLimits(pnt):
def distanceBetweenLinesTest(self, geom, p):
teste_answer = True
- for i in range(len(geom)-1):
+ for i in range(len(geom) - 1):
p1 = geom[i]
p2 = geom[i + 1]
- projected_point = self.projectPoint(p1,p2,p)
- distance = self.distanceToolTip.calculateDistance(projected_point,p2)
+ projected_point = self.projectPoint(p1, p2, p)
+ distance = self.distanceToolTip.calculateDistance(projected_point, p2)
if distance > self.minSegmentDistance:
continue
else:
@@ -176,54 +210,54 @@ def distanceBetweenLinesTest(self, geom, p):
break
return teste_answer
- def lineIntersection(self, p1, p2, p3, p4):
+ def lineIntersection(self, p1, p2, p3, p4):
p3Projected = p4
- if((p1.y() == p2.y()) or (p3.x()==p4.x())):
+ if (p1.y() == p2.y()) or (p3.x() == p4.x()):
y = p3Projected.y()
x = p2.x()
- return QgsPointXY(x,y)
- if((p1.x() == p2.x()) or (p3.y() == p4.y())):
+ return QgsPointXY(x, y)
+ if (p1.x() == p2.x()) or (p3.y() == p4.y()):
y = p2.y()
- x = p3Projected.x()
- return QgsPointXY(x,y)
- else:
- m1 = (p1.y() - p2.y())/(p1.x() - p2.x())
- a1 = p2.y() + p2.x()/m1
- m2 = (p3.y() - p4.y())/(p3.x() - p4.x())
- #Reta perpendicular P3 P4 que passa por P4
- a2 = p4.y() + p4.x()/m2
+ x = p3Projected.x()
+ return QgsPointXY(x, y)
+ else:
+ m1 = (p1.y() - p2.y()) / (p1.x() - p2.x())
+ a1 = p2.y() + p2.x() / m1
+ m2 = (p3.y() - p4.y()) / (p3.x() - p4.x())
+ # Reta perpendicular P3 P4 que passa por P4
+ a2 = p4.y() + p4.x() / m2
if abs(m1 - m2) > 0.01:
- #intersecao
- x = (a2 - a1)/(1/m2 - 1/m1)
- y = -x/m1 + a1
- return QgsPointXY(x,y)
+ # intersecao
+ x = (a2 - a1) / (1 / m2 - 1 / m1)
+ y = -x / m1 + a1
+ return QgsPointXY(x, y)
return False
-
+
def projectPoint(self, p1, p2, p3):
- #reta P1 P2
+ # reta P1 P2
try:
# p1 e p2 na vertical
- if (p1.x() == p2.x()):
+ if p1.x() == p2.x():
x = p3.x()
y = p2.y()
# p1 e p2 na horizontal
- elif (p1.y()== p2.y()):
+ elif p1.y() == p2.y():
x = p2.x()
y = p3.y()
else:
- a = (p2.y()-p1.y())/(p2.x()-p1.x())
- #reta perpendicular a P1P2 que passa por P2
- a2 = -1/a
- b2 = p2.y() - a2*p2.x()
- #reta paralela a P1P2 que passa por P3
- b3 = p3.y() - a*p3.x()
- #intersecao entre retas
- x = (b3 - b2)/(a2 - a)
- y = a*x + b3
+ a = (p2.y() - p1.y()) / (p2.x() - p1.x())
+ # reta perpendicular a P1P2 que passa por P2
+ a2 = -1 / a
+ b2 = p2.y() - a2 * p2.x()
+ # reta paralela a P1P2 que passa por P3
+ b3 = p3.y() - a * p3.x()
+ # intersecao entre retas
+ x = (b3 - b2) / (a2 - a)
+ y = a * x + b3
return QgsPointXY(x, y)
except:
return None
-
+
def getRubberBand(self):
geomType = self.iface.activeLayer().geometryType()
if geomType == QgsWkbTypes.PolygonGeometry:
@@ -234,9 +268,9 @@ def getRubberBand(self):
rubberBand.setSecondaryStrokeColor(QColor(255, 0, 0, 200))
rubberBand.setWidth(2)
return rubberBand
-
+
def getSnapRubberBand(self):
- rubberBand = QgsRubberBand(self.canvas, geometryType = QgsWkbTypes.PointGeometry)
+ rubberBand = QgsRubberBand(self.canvas, geometryType=QgsWkbTypes.PointGeometry)
rubberBand.setFillColor(QColor(255, 0, 0, 40))
rubberBand.setSecondaryStrokeColor(QColor(255, 0, 0, 200))
rubberBand.setWidth(2)
@@ -257,47 +291,53 @@ def loadDefaultFields(self, layer, feature):
attributesValues = {}
primaryKeyIndexes = layer.dataProvider().pkAttributeIndexes()
for fieldIndex in layer.attributeList():
- fieldName = layer.fields().field( fieldIndex ).name()
+ fieldName = layer.fields().field(fieldIndex).name()
if fieldIndex in primaryKeyIndexes:
continue
- attributeExpression = layer.defaultValueDefinition( fieldIndex ).expression()
- if attributeExpression == '':
+ attributeExpression = layer.defaultValueDefinition(fieldIndex).expression()
+ if attributeExpression == "":
continue
- evaluatedExpression = self.evaluateExpression(layer, layer.defaultValueDefinition( fieldIndex ).expression() )
+ evaluatedExpression = self.evaluateExpression(
+ layer, layer.defaultValueDefinition(fieldIndex).expression()
+ )
if evaluatedExpression is None:
- feature[ fieldName ] = attributeExpression
+ feature[fieldName] = attributeExpression
continue
- feature[ fieldName ] = evaluatedExpression
+ feature[fieldName] = evaluatedExpression
def evaluateExpression(self, layer, expression):
context = core.QgsExpressionContext()
- context.appendScopes( core.QgsExpressionContextUtils.globalProjectLayerScopes(layer) )
- return core.QgsExpression( expression ).evaluate( context )
+ context.appendScopes(
+ core.QgsExpressionContextUtils.globalProjectLayerScopes(layer)
+ )
+ return core.QgsExpression(expression).evaluate(context)
def createGeometry(self, geom):
geom = self.reprojectRubberBand(geom)
- if geom :
+ if geom:
layer = self.canvas.currentLayer()
fields = layer.fields()
feature = core.QgsFeature()
feature.setFields(fields)
feature.setGeometry(geom)
-
- feature.initAttributes(fields.count())
- provider = layer.dataProvider()
+
+ feature.initAttributes(fields.count())
+ provider = layer.dataProvider()
for i in range(fields.count()):
defaultClauseCandidate = provider.defaultValueClause(i)
if defaultClauseCandidate:
- feature.setAttribute(i, defaultClauseCandidate)
+ feature.setAttribute(i, defaultClauseCandidate)
+
+ self.loadDefaultFields(layer, feature)
- self.loadDefaultFields( layer, feature )
-
form = QgsAttributeDialog(layer, feature, False)
- form.setAttribute( QtCore.Qt.WA_DeleteOnClose )
+ form.setAttribute(QtCore.Qt.WA_DeleteOnClose)
form.setMode(int(QgsAttributeForm.AddFeatureMode))
formSuppress = layer.editFormConfig().suppress()
if formSuppress == QgsEditFormConfig.SuppressDefault:
- if self.getSuppressOption(): #this is calculated every time because user can switch options while using tool
+ if (
+ self.getSuppressOption()
+ ): # this is calculated every time because user can switch options while using tool
layer.addFeature(feature)
else:
form.exec_()
@@ -307,12 +347,12 @@ def createGeometry(self, geom):
layer.addFeature(feature)
layer.endEditCommand()
self.canvas.refresh()
- self.initVariable()
+ self.initVariable()
def createSnapCursor(self, point):
self.snapCursorRubberBand = self.getSnapRubberBand()
- self.snapCursorRubberBand.addPoint(point)
-
+ self.snapCursorRubberBand.addPoint(point)
+
def reprojectRubberBand(self, geom):
"""
Reprojects the geometry
@@ -321,12 +361,16 @@ def reprojectRubberBand(self, geom):
# Defining the crs from src and destiny
epsg = self.canvas.mapSettings().destinationCrs().authid()
crsSrc = QgsCoordinateReferenceSystem(epsg)
- #getting srid from something like 'EPSG:31983'
+ # getting srid from something like 'EPSG:31983'
layer = self.canvas.currentLayer()
srid = layer.crs().authid()
- crsDest = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid
+ crsDest = QgsCoordinateReferenceSystem(
+ srid
+ ) # here we have to put authid, not srid
# Creating a transformer
- coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance())
+ coordinateTransformer = QgsCoordinateTransform(
+ crsSrc, crsDest, QgsProject.instance()
+ )
lyrType = self.iface.activeLayer().geometryType()
# Transforming the points
if lyrType == QgsWkbTypes.LineGeometry:
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt b/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt
index f8385d904..6fe41f2e0 100755
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/metadata.txt
@@ -5,7 +5,7 @@ name=Ferramenta de Aquisição personalizada
qgisMinimumVersion=2.0
description=Ferramenta para auxiliar na aquisição de contornos
version=version Version 0.1
-author=Jossan
+author=Jossan
email=me@hotmail.com
; end of mandatory metadata
@@ -25,4 +25,3 @@ tags=digitizing
; in a future version of the web application it will
; be probably possible to create a project on redmine
; if they are not filled
-
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py
index edc851b21..4119ccad4 100755
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/polygon.py
@@ -25,6 +25,7 @@
from .geometricaAquisition import GeometricaAcquisition
+
class Polygon(GeometricaAcquisition):
def __init__(self, canvas, iface, action):
super(Polygon, self).__init__(canvas, iface, action)
@@ -53,10 +54,14 @@ def distance_acceptable(self, p1, p_n, p_n_1, p_n_2):
d_n = self.distanceToolTip.calculateDistance(p_n, p1)
d_n_1 = self.distanceToolTip.calculateDistance(p_n, p_n_1)
d_n_2 = self.distanceToolTip.calculateDistance(p_n_1, p_n_2)
- return (d_n > self.minSegmentDistance) and (d_n_1 > self.minSegmentDistance) and (d_n_2 > self.minSegmentDistance)
+ return (
+ (d_n > self.minSegmentDistance)
+ and (d_n_1 > self.minSegmentDistance)
+ and (d_n_2 > self.minSegmentDistance)
+ )
def canvasReleaseEvent(self, event):
- event.snapPoint() #snap!!!
+ event.snapPoint() # snap!!!
if self.snapCursorRubberBand:
self.snapCursorRubberBand.reset(geometryType=QgsWkbTypes.PointGeometry)
self.snapCursorRubberBand.hide()
@@ -72,28 +77,42 @@ def canvasReleaseEvent(self, event):
self.endGeometryFree()
self.qntPoint = 0
else:
- if (self.qntPoint >=2):
- if (self.qntPoint % 2 == 0):
+ if self.qntPoint >= 2:
+ if self.qntPoint % 2 == 0:
point = QgsPointXY(pointMap)
- projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point)
- if projectedMousePoint:
- new_geom, last_point = self.completePolygon(self.geometry, projectedMousePoint)
- if self.bufferDistanceTest(self.geometry, projectedMousePoint, last_point):
- self.geometry.append(QgsPointXY(projectedMousePoint.x(), projectedMousePoint.y()))
- self.geometry.append(last_point)
- self.endGeometry()
+ projectedMousePoint = self.projectPoint(
+ self.geometry[-2], self.geometry[-1], point
+ )
+ if projectedMousePoint:
+ new_geom, last_point = self.completePolygon(
+ self.geometry, projectedMousePoint
+ )
+ if self.bufferDistanceTest(
+ self.geometry, projectedMousePoint, last_point
+ ):
+ self.geometry.append(
+ QgsPointXY(
+ projectedMousePoint.x(), projectedMousePoint.y()
+ )
+ )
+ self.geometry.append(last_point)
+ self.endGeometry()
else:
self.iface.messageBar().pushMessage(
- self.tr("Info:"),
- self.tr("Not possible to digitize, segment smaller than minimun distance."),
- level=Qgis.Info
- )
+ self.tr("Info:"),
+ self.tr(
+ "Not possible to digitize, segment smaller than minimun distance."
+ ),
+ level=Qgis.Info,
+ )
else:
self.iface.messageBar().pushMessage(
- self.tr("Info:"),
- self.tr("The right angle tool should be used only for rectangular shapes."),
- level=Qgis.Info
- )
+ self.tr("Info:"),
+ self.tr(
+ "The right angle tool should be used only for rectangular shapes."
+ ),
+ level=Qgis.Info,
+ )
elif self.free:
self.geometry.append(pointMap)
self.qntPoint += 1
@@ -106,29 +125,46 @@ def canvasReleaseEvent(self, event):
self.qntPoint += 1
elif self.qntPoint == 1:
point = QgsPointXY(pointMap)
- if self.distanceToolTip.calculateDistance(self.geometry[-1], point) > self.minSegmentDistance:
+ if (
+ self.distanceToolTip.calculateDistance(self.geometry[-1], point)
+ > self.minSegmentDistance
+ ):
self.geometry.append(point)
self.qntPoint += 1
else:
self.iface.messageBar().pushMessage(
- self.tr("Info:"),
- self.tr("Not possible to digitise, segment smaller than minimun distance."),
- level=Qgis.Info
- )
+ self.tr("Info:"),
+ self.tr(
+ "Not possible to digitise, segment smaller than minimun distance."
+ ),
+ level=Qgis.Info,
+ )
else:
point = QgsPointXY(pointMap)
- projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point)
+ projectedMousePoint = self.projectPoint(
+ self.geometry[-2], self.geometry[-1], point
+ )
if projectedMousePoint:
- new_geom, last_point = self.completePolygon(self.geometry, projectedMousePoint)
- if self.bufferDistanceTest(self.geometry, projectedMousePoint, last_point):
- self.geometry.append(QgsPointXY(projectedMousePoint.x(), projectedMousePoint.y()))
+ new_geom, last_point = self.completePolygon(
+ self.geometry, projectedMousePoint
+ )
+ if self.bufferDistanceTest(
+ self.geometry, projectedMousePoint, last_point
+ ):
+ self.geometry.append(
+ QgsPointXY(
+ projectedMousePoint.x(), projectedMousePoint.y()
+ )
+ )
self.qntPoint += 1
else:
self.iface.messageBar().pushMessage(
- self.tr("Info:"),
- self.tr("Not possible to digitise, segment smaller than minimun distance."),
- level=Qgis.Info
- )
+ self.tr("Info:"),
+ self.tr(
+ "Not possible to digitise, segment smaller than minimun distance."
+ ),
+ level=Qgis.Info,
+ )
def canvasMoveEvent(self, event):
if self.snapCursorRubberBand:
@@ -145,20 +181,28 @@ def canvasMoveEvent(self, event):
self.distanceToolTip.canvasMoveEvent(self.geometry[0], point)
geom = QgsGeometry.fromPolylineXY([self.geometry[0], point])
self.rubberBand.setToGeometry(geom, None)
- elif self.qntPoint >= 2:
+ elif self.qntPoint >= 2:
if self.free:
self.distanceToolTip.canvasMoveEvent(self.geometry[-1], point)
- geom = QgsGeometry.fromPolygonXY([self.geometry+[QgsPointXY(point.x(), point.y())]])
+ geom = QgsGeometry.fromPolygonXY(
+ [self.geometry + [QgsPointXY(point.x(), point.y())]]
+ )
self.rubberBand.setToGeometry(geom, None)
- else:
- if (self.qntPoint % 2 == 1):
+ else:
+ if self.qntPoint % 2 == 1:
self.setAvoidStyleSnapRubberBand()
else:
- self.setAllowedStyleSnapRubberBand()
- projectedMousePoint = self.projectPoint(self.geometry[-2], self.geometry[-1], point)
- self.distanceToolTip.canvasMoveEvent(self.geometry[-1], projectedMousePoint)
+ self.setAllowedStyleSnapRubberBand()
+ projectedMousePoint = self.projectPoint(
+ self.geometry[-2], self.geometry[-1], point
+ )
+ self.distanceToolTip.canvasMoveEvent(
+ self.geometry[-1], projectedMousePoint
+ )
if projectedMousePoint:
- geom, pf = self.completePolygon(self.geometry, projectedMousePoint)
+ geom, pf = self.completePolygon(
+ self.geometry, projectedMousePoint
+ )
self.rubberBand.setToGeometry(geom, None)
else:
self.initVariable()
diff --git a/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py b/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py
index ce0c5b3c6..7801a1245 100644
--- a/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py
+++ b/DsgTools/gui/ProductionTools/MapTools/Acquisition/toolTip.py
@@ -23,14 +23,16 @@
from PyQt5.QtWidgets import QToolTip
+
class ToolTip(object):
- def __init__(self, iface):
- self.iface = iface
- self.canvas = iface.mapCanvas()
-
- def show(self, text, toolTipPoint):
- QToolTip.showText(self.canvas.mapToGlobal(self.canvas.mouseLastXY()),str(text), self.canvas)
-
- def deactivate(self):
- QToolTip.hideText()
+ def __init__(self, iface):
+ self.iface = iface
+ self.canvas = iface.mapCanvas()
+
+ def show(self, text, toolTipPoint):
+ QToolTip.showText(
+ self.canvas.mapToGlobal(self.canvas.mouseLastXY()), str(text), self.canvas
+ )
+ def deactivate(self):
+ QToolTip.hideText()
diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py
index 33115754c..2dd81a04a 100644
--- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py
+++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/copiarwkt.py
@@ -21,7 +21,12 @@
***************************************************************************/
"""
-from qgis.core import Qgis, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsCoordinateTransformContext
+from qgis.core import (
+ Qgis,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsCoordinateTransformContext,
+)
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
@@ -30,23 +35,19 @@
from qgis.utils import iface
import os
-class GetCrsDialog(QDialog):
+class GetCrsDialog(QDialog):
def __init__(self):
super(GetCrsDialog, self).__init__()
uic.loadUi(self.getUiPath(), self)
self.buttonBox.addButton("Sim", QDialogButtonBox.AcceptRole)
self.buttonBox.addButton("Não mudar", QDialogButtonBox.RejectRole)
-
def setCrsValue(self, value):
- self.selectCRS.setCrs( value)
+ self.selectCRS.setCrs(value)
def getUiPath(self):
- return os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- 'changeCRS.ui'
- )
+ return os.path.join(os.path.abspath(os.path.dirname(__file__)), "changeCRS.ui")
def getCrs(self):
return self.selectCRS.crs()
@@ -54,7 +55,14 @@ def getCrs(self):
def copywkt():
layer = iface.activeLayer()
-
+ if layer is None:
+ iface.messageBar().pushMessage(
+ "Warning",
+ "Selecione uma camada antes de rodar o processo",
+ level=Qgis.Warning,
+ duration=5
+ )
+
result, destCrs = callDialog(layer.crs())
wktcoord = []
for feature in layer.getSelectedFeatures():
@@ -63,11 +71,16 @@ def copywkt():
transformcrs = getGeometryTransforms(layer.crs(), destCrs)
geom.transform(transformcrs)
wktcoord.append(geom.asWkt())
- QApplication.clipboard().setText(
- '\n'.join(wktcoord)
+ QApplication.clipboard().setText("\n".join(wktcoord))
+ iface.messageBar().pushMessage(
+ "Executado",
+ " As coordenadas das feições selecionadas foram copiadas em WKT para o sistema {}".format(
+ destCrs.authid()
+ ),
+ level=Qgis.Success,
+ duration=5,
)
- iface.messageBar().pushMessage("Executado",
- u" As coordenadas das feições selecionadas foram copiadas em WKT para o sistema {}".format(destCrs.authid()), level=Qgis.Success, duration=5)
+
def callDialog(crsvalue):
getCrsDialog = GetCrsDialog()
@@ -78,11 +91,20 @@ def callDialog(crsvalue):
errorAction()
return callDialog()
return result, crs
+
+
def errorAction():
- reply = QMessageBox.question(iface.mainWindow(), 'CRS Invalido',
- 'Se deseja mudar o CRS, selecione um CRS valido', QMessageBox.Ok)
+ reply = QMessageBox.question(
+ iface.mainWindow(),
+ "CRS Invalido",
+ "Se deseja mudar o CRS, selecione um CRS valido",
+ QMessageBox.Ok,
+ )
return False
+
def getGeometryTransforms(sourceCrs, destCrs):
- destTransform = QgsCoordinateTransform(sourceCrs, destCrs, QgsCoordinateTransformContext())
+ destTransform = QgsCoordinateTransform(
+ sourceCrs, destCrs, QgsCoordinateTransformContext()
+ )
return destTransform
diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py
index 617669425..de311b28a 100644
--- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py
+++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/filterTools.py
@@ -22,29 +22,38 @@
***************************************************************************/
"""
from qgis import core
+from qgis.gui import QgsMapTool
from qgis.utils import iface
from qgis.PyQt.QtCore import QObject
-class FilterTools(QObject):
+class FilterTools(QgsMapTool):
+
+ def __init__(self, iface):
+ """
+ Hides or show active layers labels.
+ """
+ self.iface = iface
+ self.canvas = self.iface.mapCanvas()
+ super(FilterTools, self).__init__(self.canvas)
def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
self.stackButton = stackButton
- icon_path = iconBasePath + '/filter.svg'
+ icon_path = iconBasePath + "/filter.svg"
toolTip = self.tr("DSGTools: Filter Selected")
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Filter Selected'),
+ text=self.tr("DSGTools: Filter Selected"),
callback=self.filterSelections,
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
- icon_path = iconBasePath + '/filterByGeomtries.png'
+ icon_path = iconBasePath + "/filterByGeomtries.png"
toolTip = self.tr("DSGTools: Filter All Using the Selected Feature's Geometry")
action = manager.add_action(
icon_path,
@@ -55,10 +64,10 @@ def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
- icon_path = iconBasePath + '/removeSpatialFilter.png'
+ icon_path = iconBasePath + "/removeSpatialFilter.png"
toolTip = self.tr("DSGTools: Remove Filters")
action = manager.add_action(
icon_path,
@@ -69,52 +78,67 @@ def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
-
+
def unload(self):
pass
+
+ def setCurrentActionOnStackButton(self):
+ try:
+ self.stackButton.setDefaultAction(self.sender())
+ except:
+ pass
def cleanAllFilters(self):
- loadedLayers = core.QgsProject.instance().mapLayers().values()
+ self.setCurrentActionOnStackButton()
+ loadedLayers = core.QgsProject.instance().mapLayers().values()
showMessage = False
for layer in loadedLayers:
if layer.isEditable():
showMessage = True
- layer.setSubsetString('')
+ layer.setSubsetString("")
iface.mapCanvas().refresh()
if showMessage:
- iface.messageBar().pushMessage("Attention", "Enabled layers for edition have not been unfiltered.", level=core.Qgis.Info, duration=3)
+ iface.messageBar().pushMessage(
+ "Attention",
+ "Enabled layers for edition have not been unfiltered.",
+ level=core.Qgis.Info,
+ duration=3,
+ )
def filterBySelectedGeometries(self):
+ self.setCurrentActionOnStackButton()
layer = iface.activeLayer()
if not layer:
return
selectedFeatures = layer.selectedFeatures()
if not selectedFeatures:
return
- if not( layer.geometryType() == core.QgsWkbTypes.PolygonGeometry ):
+ if not (layer.geometryType() == core.QgsWkbTypes.PolygonGeometry):
return
multiPolygon = core.QgsMultiPolygon()
for feature in selectedFeatures:
for geometry in feature.geometry().asGeometryCollection():
- multiPolygon.addGeometry( geometry.constGet().clone() )
+ multiPolygon.addGeometry(geometry.constGet().clone())
multiPolygon = core.QgsGeometry(multiPolygon).makeValid()
- textFilter = "(geom && st_geomfromewkt('SRID={0};{1}') ) AND st_relate(geom, st_geomfromewkt('SRID={0};{1}'), 'T********')".format(
- layer.crs().authid().split(':')[-1],
- multiPolygon.asWkt()
+ textFilter = "(geom && st_geomfromewkt('SRID={0};{1}') ) AND st_relate(geom, st_geomfromewkt('SRID={0};{1}'), 'T********')".format(
+ layer.crs().authid().split(":")[-1], multiPolygon.asWkt()
)
- layersBacklist = [ 'aux_moldura_a' ]
- loadedLayers = core.QgsProject.instance().mapLayers().values()
+ layersBacklist = ["aux_moldura_a"]
+ loadedLayers = core.QgsProject.instance().mapLayers().values()
for loadedLayer in loadedLayers:
- if not isinstance(loadedLayer, core.QgsVectorLayer) or \
- loadedLayer.dataProvider().name() != 'postgres' or \
- loadedLayer.dataProvider().uri().table() in layersBacklist:
+ if (
+ not isinstance(loadedLayer, core.QgsVectorLayer)
+ or loadedLayer.dataProvider().name() != "postgres"
+ or loadedLayer.dataProvider().uri().table() in layersBacklist
+ ):
continue
- loadedLayer.setSubsetString( textFilter )
+ loadedLayer.setSubsetString(textFilter)
iface.mapCanvas().refresh()
def filterSelections(self):
+ self.setCurrentActionOnStackButton()
layer = iface.activeLayer()
if not layer:
return
@@ -122,13 +146,17 @@ def filterSelections(self):
if not selectedFeatures:
return
primaryKeyIndex = layer.primaryKeyAttributes()[0]
- primaryKeyName = layer.fields().names()[ primaryKeyIndex ]
- layer.setSubsetString(
- '"{0}" in ({1})'.format(
- primaryKeyName,
- ','.join([
- "'{}'".format(str(i[primaryKeyName])) if not isinstance(i[primaryKeyName], int) else str(i[primaryKeyName])
- for i in selectedFeatures
- ])
- )
+ primaryKeyName = layer.fields().names()[primaryKeyIndex]
+ layer.setSubsetString(
+ '"{0}" in ({1})'.format(
+ primaryKeyName,
+ ",".join(
+ [
+ "'{}'".format(str(i[primaryKeyName]))
+ if not isinstance(i[primaryKeyName], int)
+ else str(i[primaryKeyName])
+ for i in selectedFeatures
+ ]
+ ),
+ )
)
diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py
index cbbc64dc9..f1ca63d92 100644
--- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py
+++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/otherTools.py
@@ -21,62 +21,80 @@
* *
***************************************************************************/
"""
-from qgis.core import (QgsProject,
- Qgis,
- QgsVectorLayer
- )
+from qgis.core import QgsProject, Qgis, QgsVectorLayer
+from qgis.gui import QgsMapTool
from qgis.utils import iface
from qgis.PyQt.QtCore import QObject
from qgis.PyQt.QtWidgets import QMessageBox
from .copiarwkt import copywkt
-class OtherTools(QObject):
+
+class OtherTools(QgsMapTool):
+ def __init__(self, iface):
+ self.iface = iface
+ self.canvas = self.iface.mapCanvas()
+ super(OtherTools, self).__init__(self.canvas)
def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
self.stackButton = stackButton
- icon_path = iconBasePath + '/tempLayer.png'
+ icon_path = iconBasePath + "/tempLayer.png"
toolTip = self.tr("DSGTools: Copy Features to Temporary Layer")
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Copy Features to Temporary Layer'),
+ text=self.tr("DSGTools: Copy Features to Temporary Layer"),
callback=self.copyToTempLayer,
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
self.stackButton.setDefaultAction(action)
- icon_path = iconBasePath + '/copywkt.png'
+ icon_path = iconBasePath + "/copywkt.png"
toolTip = self.tr("DSGTools: Copy Feature's Coordinates as WKT")
action = manager.add_action(
icon_path,
text=self.tr("DSGTools: Copy Feature's Coordinates as WKT"),
- callback=copywkt,
+ callback=self.runCopyWkt,
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
-
+ def setCurrentActionOnStackButton(self):
+ try:
+ self.stackButton.setDefaultAction(self.sender())
+ except:
+ pass
+
def unload(self):
pass
+
+ def runCopyWkt(self):
+ self.setCurrentActionOnStackButton()
+ copywkt()
def copyToTempLayer(self):
+ self.setCurrentActionOnStackButton()
confirmation = self.confirmAction()
if not confirmation:
- iface.messageBar().pushMessage("Cancelado", u"ação cancelada pelo usuário",
- level=Qgis.Warning, duration=5)
+ iface.messageBar().pushMessage(
+ "Cancelado",
+ "ação cancelada pelo usuário",
+ level=Qgis.Warning,
+ duration=5,
+ )
return
layer = iface.activeLayer()
if not layer:
- iface.messageBar().pushMessage("Erro", u"Selecione uma camada válida",
- level=Qgis.Critical, duration=5)
+ iface.messageBar().pushMessage(
+ "Erro", "Selecione uma camada válida", level=Qgis.Critical, duration=5
+ )
return
features = layer.selectedFeatures()
newFields = layer.fields()
@@ -84,9 +102,9 @@ def copyToTempLayer(self):
geomtype = layer.geometryType()
print(geomtype)
print(type(geomtype))
- newName = name + '_temp'
- geomdict = {0:'multipoint', 1:'multilinestring', 2:'multipolygon'}
- selection = QgsVectorLayer(geomdict[int(geomtype)], newName , 'memory')
+ newName = name + "_temp"
+ geomdict = {0: "multipoint", 1: "multilinestring", 2: "multipolygon"}
+ selection = QgsVectorLayer(geomdict[int(geomtype)], newName, "memory")
selection.startEditing()
selection.setCrs(layer.crs())
dp = selection.dataProvider()
@@ -95,11 +113,19 @@ def copyToTempLayer(self):
selection.commitChanges()
selection.updateExtents()
QgsProject.instance().addMapLayer(selection)
- iface.messageBar().pushMessage("Executado", "Camada temporária criada: "+newName,
- level=Qgis.Success, duration=5)
+ iface.messageBar().pushMessage(
+ "Executado",
+ "Camada temporária criada: " + newName,
+ level=Qgis.Success,
+ duration=5,
+ )
def confirmAction(self):
- reply = QMessageBox.question(iface.mainWindow(), 'Continuar?',
- 'Será criado uma nova camada com as feições selecionadas. Deseja continuar?', QMessageBox.Yes, QMessageBox.No)
+ reply = QMessageBox.question(
+ iface.mainWindow(),
+ "Continuar?",
+ "Será criado uma nova camada com as feições selecionadas. Deseja continuar?",
+ QMessageBox.Yes,
+ QMessageBox.No,
+ )
return reply == QMessageBox.Yes
-
diff --git a/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py b/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py
index aca7e8e18..6ec344819 100644
--- a/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py
+++ b/DsgTools/gui/ProductionTools/MapTools/AuxTools/spatialFilter.py
@@ -22,32 +22,50 @@
"""
from qgis import gui, core
+from qgis.gui import QgsMapTool
from qgis.utils import iface
from PyQt5 import QtGui, QtCore
-class SpatialFilter:
- def __init__(self):
+class SpatialFilter(QgsMapTool):
+ def __init__(self, stackButton):
+ self.stackButton = stackButton
self.previousMapTool = iface.mapCanvas().mapTool()
- self.myMapTool = gui.QgsMapToolEmitPoint( iface.mapCanvas() )
+ self.myMapTool = gui.QgsMapToolEmitPoint(iface.mapCanvas())
self.coordinates = []
self.isEditing = 0
self.isActive = False
- self.myMapTool.canvasClicked.connect( self.mouseClick )
- self.myMapTool.keyReleaseEvent = lambda event: self.disconnect() if event.key() == QtCore.Qt.Key_Escape else ''
+ self.myMapTool.canvasClicked.connect(self.mouseClick)
+ self.myMapTool.keyReleaseEvent = (
+ lambda event: self.disconnect()
+ if event.key() == QtCore.Qt.Key_Escape
+ else ""
+ )
+ self.iface = iface
+ self.canvas = self.iface.mapCanvas()
+ super(SpatialFilter, self).__init__(self.canvas)
+
+ def setCurrentActionOnStackButton(self):
+ try:
+ self.stackButton.setDefaultAction(self.sender())
+ except:
+ pass
def start(self):
+ self.setCurrentActionOnStackButton()
self.isActive = not self.isActive
if self.isActive:
- self.myRubberBand = gui.QgsRubberBand( iface.mapCanvas(), core.QgsWkbTypes.PolygonGeometry )
+ self.myRubberBand = gui.QgsRubberBand(
+ iface.mapCanvas(), core.QgsWkbTypes.PolygonGeometry
+ )
color = QtGui.QColor(78, 97, 114)
color.setAlpha(190)
self.myRubberBand.setColor(color)
self.myRubberBand.setFillColor(QtGui.QColor(255, 0, 0, 40))
-
+
# Set MapTool
- iface.mapCanvas().setMapTool( self.myMapTool )
- iface.mapCanvas().xyCoordinates.connect( self.mouseMove )
+ iface.mapCanvas().setMapTool(self.myMapTool)
+ iface.mapCanvas().xyCoordinates.connect(self.mouseMove)
else:
self.disconnect()
@@ -56,7 +74,7 @@ def disconnect(self):
self.coordinates = []
iface.mapCanvas().unsetMapTool(self.myMapTool)
try:
- iface.mapCanvas().xyCoordinates.disconnect (self.mouseMove)
+ iface.mapCanvas().xyCoordinates.disconnect(self.mouseMove)
except:
pass
@@ -65,54 +83,64 @@ def disconnect(self):
except:
pass
- def mouseClick( self, currentPos, clickedButton ):
- if clickedButton == QtCore.Qt.LeftButton:# and myRubberBand.numberOfVertices() == 0:
- self.myRubberBand.addPoint( core.QgsPointXY(currentPos))
- self.coordinates.append( core.QgsPointXY(currentPos))
+ def mouseClick(self, currentPos, clickedButton):
+ if (
+ clickedButton == QtCore.Qt.LeftButton
+ ): # and myRubberBand.numberOfVertices() == 0:
+ self.myRubberBand.addPoint(core.QgsPointXY(currentPos))
+ self.coordinates.append(core.QgsPointXY(currentPos))
self.isEditing = 1
-
- elif clickedButton == QtCore.Qt.RightButton and self.myRubberBand.numberOfVertices() > 2:
+
+ elif (
+ clickedButton == QtCore.Qt.RightButton
+ and self.myRubberBand.numberOfVertices() > 2
+ ):
self.isEditing = 0
# create feature and set geometry.
-
- poly = core.QgsFeature()
+
+ poly = core.QgsFeature()
geomP = self.myRubberBand.asGeometry()
poly.setGeometry(geomP)
- g = geomP.asWkt() # Get WKT coordenates.
+ g = geomP.asWkt() # Get WKT coordenates.
- canvas=iface.mapCanvas()
+ canvas = iface.mapCanvas()
+
+ c = canvas.mapSettings().destinationCrs().authid() # Get EPSG.
+ rep = c.replace("EPSG:", "")
+
+ vlyr = core.QgsVectorLayer(
+ "?query=SELECT geom_from_wkt('%s') as geometry&geometry=geometry:3:%s"
+ % (g, rep),
+ "Polygon_Reference",
+ "virtual",
+ )
- c = canvas.mapSettings().destinationCrs().authid() # Get EPSG.
- rep = c.replace("EPSG:","")
-
- vlyr = core.QgsVectorLayer("?query=SELECT geom_from_wkt('%s') as geometry&geometry=geometry:3:%s"%(g,rep), "Polygon_Reference", "virtual")
-
core.QgsProject.instance().addMapLayer(vlyr)
self.myRubberBand.reset(core.QgsWkbTypes.PolygonGeometry)
string = f"(geom && ST_GEOMFROMEWKT('SRID={rep};{g}')) AND ST_INTERSECTS(geom, ST_GEOMFROMEWKT('SRID={rep};{g}'))"
layers = core.QgsProject.instance().mapLayers().values()
-
+
layersBacklist = self.getLayersBacklist()
-
+
for layer in layers:
- if not isinstance(layer, core.QgsVectorLayer) or \
- layer.dataProvider().name() != 'postgres' or \
- layer.dataProvider().uri().table() in layersBacklist:
+ if (
+ not isinstance(layer, core.QgsVectorLayer)
+ or layer.dataProvider().name() != "postgres"
+ or layer.dataProvider().uri().table() in layersBacklist
+ ):
continue
try:
layer.setSubsetString(string)
except Exception:
pass
-
+
self.myRubberBand.reset(core.QgsWkbTypes.PolygonGeometry)
self.disconnect()
def getLayersBacklist(self):
- return [
- 'aux_moldura_a'
- ]
+ return ["aux_moldura_a"]
- def mouseMove( self, currentPos ):
+ def mouseMove(self, currentPos):
if self.isEditing == 1:
- self.myRubberBand.movePoint(core.QgsPointXY(currentPos))
\ No newline at end of file
+ self.myRubberBand.movePoint(core.QgsPointXY(currentPos))
diff --git a/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py b/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py
index 06a7cd2ed..f24b62065 100644
--- a/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py
+++ b/DsgTools/gui/ProductionTools/MapTools/FlipLineTool/flipLineTool.py
@@ -22,36 +22,47 @@
"""
from __future__ import absolute_import
from qgis.gui import QgsMapTool, QgsMessageBar
-from qgis.core import QgsMapLayer, QgsVectorLayer, QgsMessageLog, QgsFeatureRequest, QgsWkbTypes, Qgis
+from qgis.core import (
+ QgsMapLayer,
+ QgsVectorLayer,
+ QgsMessageLog,
+ QgsFeatureRequest,
+ QgsWkbTypes,
+ Qgis,
+)
from qgis.PyQt import QtCore, QtGui
from .....core.GeometricTools.geometryHandler import GeometryHandler
+
class FlipLine(QgsMapTool):
"""
Tool expected behaviour:
When (valid) line features are selected, it flips them upon tool activation.
"""
+
def __init__(self, iface):
- self.iface = iface
+ self.iface = iface
self.canvas = self.iface.mapCanvas()
self.toolAction = None
QgsMapTool.__init__(self, self.canvas)
self.DsgGeometryHandler = GeometryHandler(iface)
self.currentLayer = None
-
+
def addTool(self, manager, callback, parentMenu, iconBasePath):
- icon_path = iconBasePath + '/flipLineTool.png'
- toolTip = self.tr("DSGTools: Flip Line Tool\nInsert tool tip for Flip Line Tool.")
+ icon_path = iconBasePath + "/flipLineTool.png"
+ toolTip = self.tr(
+ "DSGTools: Flip Line Tool\nInsert tool tip for Flip Line Tool."
+ )
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Flip Line Tool'),
+ text=self.tr("DSGTools: Flip Line Tool"),
callback=callback,
add_to_menu=False,
add_to_toolbar=True,
- withShortcut = True,
- tooltip = toolTip,
- parentToolbar =parentMenu
+ withShortcut=True,
+ tooltip=toolTip,
+ parentToolbar=parentMenu,
)
self.setAction(action)
@@ -63,7 +74,12 @@ def setToolEnabled(self, layer=None):
"""
if not isinstance(layer, QgsVectorLayer):
layer = self.iface.mapCanvas().currentLayer()
- if not layer or not isinstance(layer, QgsVectorLayer) or layer.geometryType() != QgsWkbTypes.LineGeometry or not layer.isEditable():
+ if (
+ not layer
+ or not isinstance(layer, QgsVectorLayer)
+ or layer.geometryType() != QgsWkbTypes.LineGeometry
+ or not layer.isEditable()
+ ):
enabled = False
else:
enabled = True
@@ -76,7 +92,7 @@ def activate(self):
"""
if self.toolAction:
self.toolAction.setChecked(False)
-
+
def setAction(self, action):
"""
Defines an action for tool.
@@ -101,37 +117,43 @@ def getAllSelectedLines(self):
def flipSelectedLines(self):
"""
Method for flipping all selected lines. Used for button callback.
- """
+ """
# get all selected features and remove all features that are not lines
selectedFeatures = self.getAllSelectedLines()
pop = 0
for idx, item in enumerate(selectedFeatures):
if item[2] != 1:
- selectedFeatures.pop(idx-pop)
+ selectedFeatures.pop(idx - pop)
pop += 1
if not selectedFeatures:
logMsg = self.getLogMessage(None, None)
- self.iface.messageBar().pushMessage(self.tr('Error'), logMsg, level=Qgis.Critical, duration=3)
+ self.iface.messageBar().pushMessage(
+ self.tr("Error"), logMsg, level=Qgis.Critical, duration=3
+ )
# QMessageBox.critical(self, self.tr('Critical!'), logMsg)
QgsMessageLog.logMessage(logMsg, "DSGTools Plugin", Qgis.Critical)
return
# call the method for flipping features from geometry module
- flippedLines, failedLines = self.DsgGeometryHandler.flipFeatureList(featureList=selectedFeatures, debugging=True)
+ flippedLines, failedLines = self.DsgGeometryHandler.flipFeatureList(
+ featureList=selectedFeatures, debugging=True
+ )
logMsg = self.getLogMessage(flippedLines, failedLines)
- self.iface.messageBar().pushMessage(self.tr('Success'), logMsg, level=Qgis.Info, duration=3)
+ self.iface.messageBar().pushMessage(
+ self.tr("Success"), logMsg, level=Qgis.Info, duration=3
+ )
QgsMessageLog.logMessage(logMsg, "DSGTools Plugin", Qgis.Info)
-
+
def getLogMessage(self, flippedLines, failedLines):
"""
Method for mounting log message to be exposed to user.
:param flippedLines: list of lines that were selected and were successfully flipped.
:param failedLines: list of lines that were selected and failed to be flipped.
- :param success: indicates whether the log is for a failed execution or
+ :param success: indicates whether the log is for a failed execution or
"""
- nrFlipped = nrFailed = 0
- logMsg = ''
+ nrFlipped = nrFailed = 0
+ logMsg = ""
if not flippedLines and not failedLines:
- return self.tr('There are no (valid) lines selected!')
+ return self.tr("There are no (valid) lines selected!")
if flippedLines:
nrFlipped = len(flippedLines)
logMsg = self.tr("Feature(s) flipped: ")
@@ -144,14 +166,21 @@ def getLogMessage(self, flippedLines, failedLines):
for item in failedLines:
logMsg += "{} (id={}), ".format(item[0].name(), item[1].id())
logMsg = (logMsg + ")").replace(", )", ".")
- return logMsg + self.tr("\n{} lines flipped. {} failed to be flipped.").format(nrFlipped, nrFailed)
+ return logMsg + self.tr("\n{} lines flipped. {} failed to be flipped.").format(
+ nrFlipped, nrFailed
+ )
def startFlipLineTool(self):
if self.canvas.currentLayer() in self.iface.editableLayers():
self.flipSelectedLines()
else:
- self.iface.messageBar().pushMessage(self.tr('Warning'), self.tr('Start editing in current layer!'), level=Qgis.Info, duration=3)
+ self.iface.messageBar().pushMessage(
+ self.tr("Warning"),
+ self.tr("Start editing in current layer!"),
+ level=Qgis.Info,
+ duration=3,
+ )
def deactivate(self):
QgsMapTool.deactivate(self)
- self.canvas.unsetMapTool(self)
\ No newline at end of file
+ self.canvas.unsetMapTool(self)
diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py
index 611885d07..ccd1cc64a 100644
--- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py
+++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/controllers/acquisitionFreeController.py
@@ -25,13 +25,22 @@
from qgis.PyQt.QtWidgets import QMessageBox
from qgis import core, gui
from qgis.utils import iface
-from qgis.core import QgsPoint, QgsLineString, QgsVectorLayer, QgsWkbTypes, \
- QgsProject, QgsMessageLog, Qgis
+from qgis.core import (
+ QgsPoint,
+ QgsLineString,
+ QgsVectorLayer,
+ QgsWkbTypes,
+ QgsProject,
+ QgsMessageLog,
+ Qgis,
+)
-from DsgTools.gui.ProductionTools.MapTools.FreeHandTool.models.acquisitionFree import AcquisitionFree
+from DsgTools.gui.ProductionTools.MapTools.FreeHandTool.models.acquisitionFree import (
+ AcquisitionFree,
+)
-class AcquisitionFreeController(object):
+class AcquisitionFreeController(object):
def __init__(self, acquisitionFree, iface):
"""
Class constructor.
@@ -42,7 +51,7 @@ def __init__(self, acquisitionFree, iface):
self.acquisitionFree = acquisitionFree
self.iface = iface
self.active = False
-
+
def setIface(self, iface):
"""
Sets a QGIS interface object to iface attribute from AcquisitionFreeController object.
@@ -57,43 +66,52 @@ def getIface(self):
return self.iface
def setActionAcquisitionFree(self, actionAcquisitionFree):
- #Método para definir a classe ActionAcquisitionFree
- #Parâmetro de entrada: actionAcquisitionFree (classe ActionAcquisitionFree)
+ # Método para definir a classe ActionAcquisitionFree
+ # Parâmetro de entrada: actionAcquisitionFree (classe ActionAcquisitionFree)
self.actionAcquisitionFree = actionAcquisitionFree
-
+
def getActionAcquisitionFree(self):
- #Método para obter a classe ActionAcquisitionFree
- #Parâmetro de retorno: self.actionAcquisitionFree (classe ActionAcquisitionFree)
- return self.actionAcquisitionFree
+ # Método para obter a classe ActionAcquisitionFree
+ # Parâmetro de retorno: self.actionAcquisitionFree (classe ActionAcquisitionFree)
+ return self.actionAcquisitionFree
@property
def toolAction(self):
return self.actionAcquisitionFree
def setAcquisitionFree(self, acquisitionFree):
- #Método para definir a classe AcquisitionFree
- #Parâmetro de entrada: acquisitionFree (classe AcquisitionFree)
+ # Método para definir a classe AcquisitionFree
+ # Parâmetro de entrada: acquisitionFree (classe AcquisitionFree)
self.acquisitionFree = acquisitionFree
def getAcquisitionFree(self):
- #Método para obter a classe AcquisitionFree
- #Parâmetro de retorno: self.acquisitionFree (classe AcquisitionFree)
+ # Método para obter a classe AcquisitionFree
+ # Parâmetro de retorno: self.acquisitionFree (classe AcquisitionFree)
return self.acquisitionFree
def setActiveState(self, state):
- #Método para definir estado da ferramento (ativada ou desativada)
- #Parâmetro de entrada: state (boleano)
+ # Método para definir estado da ferramento (ativada ou desativada)
+ # Parâmetro de entrada: state (boleano)
self.active = state
-
+
def getActiveState(self):
- #Método para obter estado da tool (ativada ou desativada)
- #Parâmetro de retorno: state (boleano)
+ # Método para obter estado da tool (ativada ou desativada)
+ # Parâmetro de retorno: state (boleano)
return self.active
def checkToActiveAction(self):
- #Método para testar se a camada ativa é valida para ativar a ferramenta
- layer = self.getIface().activeLayer()
- if core is not None and layer and layer.isEditable() and (layer.type() == core.QgsMapLayer.VectorLayer) and (layer.geometryType() in [core.QgsWkbTypes.LineGeometry, core.QgsWkbTypes.PolygonGeometry]):
+ # Método para testar se a camada ativa é valida para ativar a ferramenta
+ layer = self.getIface().activeLayer()
+ if (
+ core is not None
+ and layer
+ and layer.isEditable()
+ and (layer.type() == core.QgsMapLayer.VectorLayer)
+ and (
+ layer.geometryType()
+ in [core.QgsWkbTypes.LineGeometry, core.QgsWkbTypes.PolygonGeometry]
+ )
+ ):
if not self.actionAcquisitionFree.isEnabled():
self.actionAcquisitionFree.setEnabled(True)
return True
@@ -103,8 +121,12 @@ def checkToActiveAction(self):
return False
def setToolEnabled(self):
- layer = self.iface.activeLayer()
- if not isinstance(layer, QgsVectorLayer) or layer.geometryType() == QgsWkbTypes.PointGeometry or not layer.isEditable():
+ layer = self.iface.activeLayer()
+ if (
+ not isinstance(layer, QgsVectorLayer)
+ or layer.geometryType() == QgsWkbTypes.PointGeometry
+ or not layer.isEditable()
+ ):
enabled = False
else:
enabled = True
@@ -115,68 +137,76 @@ def setToolEnabled(self):
return enabled
def getParametersFromConfig(self):
- #Método para obter as configurações da tool do QSettings
- #Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta)
+ # Método para obter as configurações da tool do QSettings
+ # Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta)
settings = QtCore.QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
parameters = {
- u'freeHandTolerance' : settings.value('freeHandTolerance'),
- u'freeHandFinalSimplifyTolerance' : settings.value('freeHandFinalSimplifyTolerance'),
- u'freeHandSmoothIterations' : settings.value('freeHandSmoothIterations'),
- u'freeHandSmoothOffset' : settings.value('freeHandSmoothOffset'),
- u'algIterations' : settings.value('algIterations'),
- u'undoPoints' : settings.value('undoPoints')
+ "freeHandTolerance": settings.value("freeHandTolerance"),
+ "freeHandFinalSimplifyTolerance": settings.value(
+ "freeHandFinalSimplifyTolerance"
+ ),
+ "freeHandSmoothIterations": settings.value("freeHandSmoothIterations"),
+ "freeHandSmoothOffset": settings.value("freeHandSmoothOffset"),
+ "algIterations": settings.value("algIterations"),
+ "undoPoints": settings.value("undoPoints"),
}
settings.endGroup()
return parameters
def getTolerance(self, layer):
- #Método para obter tolerância para simplificação de geometria
- #Parâmetro de entrada: layer (camada em uso)
- #Parâmetro de retorno: sGeom (Geometria simplificada)
+ # Método para obter tolerância para simplificação de geometria
+ # Parâmetro de entrada: layer (camada em uso)
+ # Parâmetro de retorno: sGeom (Geometria simplificada)
parameters = self.getParametersFromConfig()
- return parameters[u'freeHandTolerance']
-
+ return parameters["freeHandTolerance"]
+
def getFinalTolerance(self):
parameters = self.getParametersFromConfig()
- finalTolerance = parameters[u'freeHandFinalSimplifyTolerance']
+ finalTolerance = parameters["freeHandFinalSimplifyTolerance"]
return 0 if finalTolerance is None else float(finalTolerance)
def simplifyGeometry(self, geom, tolerance):
- #Método para simplificar geometria
- #Parâmetro de entrada: geom (Geometria adquirida), tolerance (Tolerância para simplificação)
- #Parâmetro de retorno: sGeom (Geometria simplificada)
+ # Método para simplificar geometria
+ # Parâmetro de entrada: geom (Geometria adquirida), tolerance (Tolerância para simplificação)
+ # Parâmetro de retorno: sGeom (Geometria simplificada)
parameters = self.getParametersFromConfig()
- firstVertex = geom.vertexAt(0)
- lastVertex = geom.vertexAt(geom.constGet().nCoordinates() - 1 )
+ firstVertex = geom.vertexAt(0)
+ lastVertex = geom.vertexAt(geom.constGet().nCoordinates() - 1)
sGeom = geom
source_crs = self.iface.activeLayer().crs()
dest_crs = core.QgsCoordinateReferenceSystem(3857)
- tr = core.QgsCoordinateTransform(source_crs, dest_crs, core.QgsCoordinateTransformContext())
+ tr = core.QgsCoordinateTransform(
+ source_crs, dest_crs, core.QgsCoordinateTransformContext()
+ )
sGeom.transform(tr)
- for x in range(int(parameters[u'algIterations'])):
+ for x in range(int(parameters["algIterations"])):
sGeom = sGeom.simplify(float(tolerance))
try:
sGeom = sGeom.smooth(
- int(parameters[u'freeHandSmoothIterations']),
- float(parameters[u'freeHandSmoothOffset'])
+ int(parameters["freeHandSmoothIterations"]),
+ float(parameters["freeHandSmoothOffset"]),
)
except:
- msg = QMessageBox().tr('Probably too many smoothing iteration, try reducing it (3 usually is enough). Geometry was not smoothened.')
+ msg = QMessageBox().tr(
+ "Probably too many smoothing iteration, try reducing it (3 usually is enough). Geometry was not smoothened."
+ )
QMessageBox.warning(
- self.iface.mainWindow(),
- QMessageBox().tr('Error!'),
- msg
+ self.iface.mainWindow(), QMessageBox().tr("Error!"), msg
)
- QgsMessageLog.logMessage(msg, 'DSGTools Plugin', Qgis.Critical)
+ QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Critical)
return geom
finalGeom = sGeom.simplify(self.getFinalTolerance())
- tr = core.QgsCoordinateTransform(dest_crs, source_crs, core.QgsCoordinateTransformContext())
+ tr = core.QgsCoordinateTransform(
+ dest_crs, source_crs, core.QgsCoordinateTransformContext()
+ )
finalGeom.transform(tr)
if self.iface.activeLayer().geometryType() == core.QgsWkbTypes.PolygonGeometry:
return finalGeom
finalGeom.moveVertex(firstVertex.x(), firstVertex.y(), 0)
- finalGeom.moveVertex(lastVertex.x(), lastVertex.y(), finalGeom.constGet().nCoordinates() - 1)
+ finalGeom.moveVertex(
+ lastVertex.x(), lastVertex.y(), finalGeom.constGet().nCoordinates() - 1
+ )
return finalGeom
def reprojectGeometry(self, geom):
@@ -186,18 +216,18 @@ def reprojectGeometry(self, geom):
epsgSrc = canvas.mapSettings().destinationCrs().authid()
epsgDest = layer.crs().authid()
if epsgSrc != epsgDest:
- ct = canvas.mapSettings().layerTransform( layer )
+ ct = canvas.mapSettings().layerTransform(layer)
geom.transform(ct, core.QgsCoordinateTransform.ReverseTransform)
- return geom
+ return geom
def createFeature(self, geom):
- #Método para criar feição
- #Parâmetro de entrada: geom (geometria adquirida)
- if not geom :
+ # Método para criar feição
+ # Parâmetro de entrada: geom (geometria adquirida)
+ if not geom:
return
settings = QtCore.QSettings()
canvas = self.getIface().mapCanvas()
- layer = canvas.currentLayer()
+ layer = canvas.currentLayer()
tolerance = self.getTolerance(layer)
geom = self.reprojectGeometry(geom)
simplifyGeometry = self.simplifyGeometry(geom, tolerance)
@@ -205,7 +235,7 @@ def createFeature(self, geom):
feature = core.QgsFeature()
feature.setFields(fields)
feature.setGeometry(simplifyGeometry)
- provider = layer.dataProvider()
+ provider = layer.dataProvider()
for i in range(fields.count()):
defaultClauseCandidate = provider.defaultValueClause(i)
if defaultClauseCandidate:
@@ -213,13 +243,10 @@ def createFeature(self, geom):
formSuppressOnLayer = layer.editFormConfig().suppress()
formSuppressOnSettings = self.getFormSuppressStateSettings()
featureAdded = True
- if (
- formSuppressOnLayer == core.QgsEditFormConfig.SuppressOn
- or (
- formSuppressOnLayer == core.QgsEditFormConfig.SuppressDefault
- and formSuppressOnSettings == 'true'
- )
- ):
+ if formSuppressOnLayer == core.QgsEditFormConfig.SuppressOn or (
+ formSuppressOnLayer == core.QgsEditFormConfig.SuppressDefault
+ and formSuppressOnSettings == "true"
+ ):
self.addFeatureWithoutForm(layer, feature)
else:
featureAdded = self.addFeatureWithForm(layer, feature)
@@ -227,15 +254,14 @@ def createFeature(self, geom):
self.createTopology(feature)
def createTopology(self, feature):
- currentLayer = iface.activeLayer()
- otherLayers = [
- layer for layer in iface.mapCanvas().layers()
+ currentLayer = iface.activeLayer()
+ otherLayers = [
+ layer
+ for layer in iface.mapCanvas().layers()
if (
layer.id() != currentLayer.id()
- and
- layer.isEditable()
- and
- layer.type() == core.QgsMapLayer.VectorLayer
+ and layer.isEditable()
+ and layer.type() == core.QgsMapLayer.VectorLayer
)
]
createdGeometry = feature.geometry()
@@ -244,57 +270,69 @@ def createTopology(self, feature):
currentLayer.addTopologicalPoints(createdGeometry)
iface.mapCanvas().refresh()
- def reshapeSimplify(self, reshapeLine):
+ def reshapeSimplify(self, reshapeLine):
canvas = self.getIface().mapCanvas()
layer = canvas.currentLayer()
tolerance = self.getTolerance(layer)
reshapeLine_ = self.reprojectGeometry(reshapeLine)
rsLine = self.simplifyGeometry(reshapeLine_, tolerance)
request = core.QgsFeatureRequest().setFilterRect(rsLine.boundingBox())
- for feat in layer.getSelectedFeatures(request) if layer.selectedFeatureCount() > 0 else layer.getFeatures(request):
- geom = feat.geometry() # geometria que receberá o reshape.
- if geom.intersects(rsLine): # Se intersecta e transforma frompolyline em geometria.
- geom.reshapeGeometry(QgsLineString([QgsPoint(p) for p in rsLine.asPolyline()])) # realiza o reshape entre a linha e a geometria.
+ for feat in (
+ layer.getSelectedFeatures(request)
+ if layer.selectedFeatureCount() > 0
+ else layer.getFeatures(request)
+ ):
+ geom = feat.geometry() # geometria que receberá o reshape.
+ if geom.intersects(
+ rsLine
+ ): # Se intersecta e transforma frompolyline em geometria.
+ geom.reshapeGeometry(
+ QgsLineString([QgsPoint(p) for p in rsLine.asPolyline()])
+ ) # realiza o reshape entre a linha e a geometria.
layer.changeGeometry(feat.id(), geom)
-
- canvas.refresh() # Refresh para atualizar, mas não salvar as alterações.
+
+ canvas.refresh() # Refresh para atualizar, mas não salvar as alterações.
def getFormSuppressStateSettings(self):
- #Método para verificar se o formulário de aquisição está suprimido nas configurações do projeto
- #Parâmetro de retorno: suppressForm ( boleano )
+ # Método para verificar se o formulário de aquisição está suprimido nas configurações do projeto
+ # Parâmetro de retorno: suppressForm ( boleano )
s = QtCore.QSettings()
- suppressForm = s.value(u"qgis/digitizing/disable_enter_attribute_values_dialog")
+ suppressForm = s.value("qgis/digitizing/disable_enter_attribute_values_dialog")
return suppressForm == "true"
def loadDefaultFields(self, layer, feature):
attributesValues = {}
primaryKeyIndexes = layer.dataProvider().pkAttributeIndexes()
for fieldIndex in layer.attributeList():
- fieldName = layer.fields().field( fieldIndex ).name()
+ fieldName = layer.fields().field(fieldIndex).name()
if fieldIndex in primaryKeyIndexes:
continue
- attributeExpression = layer.defaultValueDefinition( fieldIndex ).expression()
- if attributeExpression == '':
+ attributeExpression = layer.defaultValueDefinition(fieldIndex).expression()
+ if attributeExpression == "":
continue
- evaluatedExpression = self.evaluateExpression(layer, layer.defaultValueDefinition( fieldIndex ).expression() )
+ evaluatedExpression = self.evaluateExpression(
+ layer, layer.defaultValueDefinition(fieldIndex).expression()
+ )
if evaluatedExpression is None:
- feature[ fieldName ] = attributeExpression
+ feature[fieldName] = attributeExpression
continue
- feature[ fieldName ] = evaluatedExpression
+ feature[fieldName] = evaluatedExpression
def evaluateExpression(self, layer, expression):
context = core.QgsExpressionContext()
- context.appendScopes( core.QgsExpressionContextUtils.globalProjectLayerScopes(layer) )
- return core.QgsExpression( expression ).evaluate( context )
+ context.appendScopes(
+ core.QgsExpressionContextUtils.globalProjectLayerScopes(layer)
+ )
+ return core.QgsExpression(expression).evaluate(context)
def addFeatureWithForm(self, layer, feature):
- #Método para adicionar a feição com formulário
- #Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida)
+ # Método para adicionar a feição com formulário
+ # Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida)
layer.beginEditCommand("dsgtools freehand feature added")
- self.loadDefaultFields( layer, feature )
+ self.loadDefaultFields(layer, feature)
attrDialog = gui.QgsAttributeDialog(layer, feature, False)
- attrDialog.setAttribute( QtCore.Qt.WA_DeleteOnClose )
- attrDialog.setMode( int( gui.QgsAttributeForm.AddFeatureMode ) )
+ attrDialog.setAttribute(QtCore.Qt.WA_DeleteOnClose)
+ attrDialog.setMode(int(gui.QgsAttributeForm.AddFeatureMode))
res = attrDialog.exec_()
if res == 0:
layer.destroyEditCommand()
@@ -303,15 +341,15 @@ def addFeatureWithForm(self, layer, feature):
return res
def addFeatureWithoutForm(self, layer, feature):
- #Método para adicionar a feição sem formulário
- #Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida)
+ # Método para adicionar a feição sem formulário
+ # Parâmetro de entrada: layer (Camada ativa), feature (Feição adquirida)
layer.beginEditCommand("dsgtools freehand feature added")
layer.addFeatures([feature])
layer.removeSelection()
layer.endEditCommand()
def activateTool(self):
- #Método para iniciar a ferramenta
+ # Método para iniciar a ferramenta
state = self.actionAcquisitionFree.isChecked()
self.actionAcquisitionFree.setChecked(not state)
self.setActiveState(state)
diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py
index 156bbe831..797760506 100644
--- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py
+++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandMain.py
@@ -24,31 +24,40 @@
from .models.acquisitionFree import AcquisitionFree
from .controllers.acquisitionFreeController import AcquisitionFreeController
-class FreeHandMain(QObject):
+class FreeHandMain(QObject):
def __init__(self, iface):
- #construtor
+ # construtor
super(FreeHandMain, self).__init__()
self.iface = iface
self.acquisitionFree = AcquisitionFree(iface)
self.acquisitionFreeController = AcquisitionFreeController(
- self.acquisitionFree,
- iface
+ self.acquisitionFree, iface
)
- def addTool(self, manager, callback, parentMenu, iconBasePath, parentButton=None, defaultButton=False):
+ def addTool(
+ self,
+ manager,
+ callback,
+ parentMenu,
+ iconBasePath,
+ parentButton=None,
+ defaultButton=False,
+ ):
self.parentButton = parentButton
- icon_path = iconBasePath + 'free_hand.png'
+ icon_path = iconBasePath + "free_hand.png"
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Free Hand Acquisition'),
+ text=self.tr("DSGTools: Free Hand Acquisition"),
callback=self.run,
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
- tooltip = self.tr('DSGTools: Free Hand Acquisition\nAcquires polygon or line features from mouse movement.'),
+ tooltip=self.tr(
+ "DSGTools: Free Hand Acquisition\nAcquires polygon or line features from mouse movement."
+ ),
parentToolbar=parentMenu,
- parentButton=parentButton
+ parentButton=parentButton,
)
self.setAction(action)
if defaultButton:
@@ -56,7 +65,7 @@ def addTool(self, manager, callback, parentMenu, iconBasePath, parentButton=None
def setAcquisitionFreeController(self, acquisitionFreeController):
self.acquisitionFreeController = acquisitionFreeController
-
+
def getAcquisitionFreeController(self):
return self.acquisitionFreeController
@@ -65,7 +74,7 @@ def toolAction(self):
return self.getAction()
def setIface(self, iface):
- self.iface = iface
+ self.iface = iface
def getIface(self):
return self.iface
@@ -85,4 +94,4 @@ def run(self):
try:
self.parentButton.setDefaultAction(self.action)
except:
- pass
\ No newline at end of file
+ pass
diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py
index 5d1664cd4..4a888b1d8 100644
--- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py
+++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/freeHandReshape.py
@@ -20,27 +20,37 @@
from .freeHandMain import FreeHandMain
-class FreeHandReshape(FreeHandMain):
+class FreeHandReshape(FreeHandMain):
def __init__(self, iface):
- #construtor
+ # construtor
super(FreeHandReshape, self).__init__(iface)
self.acquisitionFree.controlPressed = True
- def addTool(self, manager, callback, parentMenu, iconBasePath, parentButton=None, defaultButton=False):
+ def addTool(
+ self,
+ manager,
+ callback,
+ parentMenu,
+ iconBasePath,
+ parentButton=None,
+ defaultButton=False,
+ ):
self.parentButton = parentButton
- icon_path = iconBasePath + 'free_hand_reshape.png'
+ icon_path = iconBasePath + "free_hand_reshape.png"
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Free Hand Reshape'),
+ text=self.tr("DSGTools: Free Hand Reshape"),
callback=self.run,
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
- tooltip = self.tr('DSGTools: Free Hand Reshape\nReshapes polygon or line features from mouse movement.'),
+ tooltip=self.tr(
+ "DSGTools: Free Hand Reshape\nReshapes polygon or line features from mouse movement."
+ ),
parentToolbar=parentMenu,
- parentButton=parentButton
+ parentButton=parentButton,
)
self.setAction(action)
if defaultButton:
- self.parentButton.setDefaultAction(action)
\ No newline at end of file
+ self.parentButton.setDefaultAction(action)
diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt
index 09c61bd5e..718f16091 100644
--- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt
+++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/metadata.txt
@@ -25,5 +25,3 @@ tags=digitizing
; in a future version of the web application it will
; be probably possible to create a project on redmine
; if they are not filled
-
-
diff --git a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py
index 1b7e0aef0..3dcd0d705 100644
--- a/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py
+++ b/DsgTools/gui/ProductionTools/MapTools/FreeHandTool/models/acquisitionFree.py
@@ -23,14 +23,15 @@
from qgis.utils import iface
from qgis.core import QgsGeometry
+
class AcquisitionFree(gui.QgsMapTool):
-
- #Sinal usado para enviar a geometria adquirida ao finalizar aquisição
+
+ # Sinal usado para enviar a geometria adquirida ao finalizar aquisição
acquisitionFinished = QtCore.pyqtSignal(QgsGeometry)
reshapeLineCreated = QtCore.pyqtSignal(QgsGeometry)
def __init__(self, iface):
- #construtor
+ # construtor
self.iface = iface
self.canvas = iface.mapCanvas()
super(AcquisitionFree, self).__init__(self.canvas)
@@ -41,125 +42,131 @@ def __init__(self, iface):
self.active = False
self.contadorVert = 0
self.stopState = False
- self.cur = QtGui.QCursor(QtGui.QPixmap(["18 13 4 1",
- " c None",
- "# c #FF0000",
- ". c #FF0000",
- "+ c #1210f3",
- " ",
- " +++++++++++ ",
- " + # + ",
- " + # + ",
- "+ # +",
- "+ # +",
- "++#############++",
- "+ # +",
- "+ # +",
- " + # +",
- " + # + ",
- " +++++++++++ ",
- " ",]))
+ self.cur = QtGui.QCursor(
+ QtGui.QPixmap(
+ [
+ "18 13 4 1",
+ " c None",
+ "# c #FF0000",
+ ". c #FF0000",
+ "+ c #1210f3",
+ " ",
+ " +++++++++++ ",
+ " + # + ",
+ " + # + ",
+ "+ # +",
+ "+ # +",
+ "++#############++",
+ "+ # +",
+ "+ # +",
+ " + # +",
+ " + # + ",
+ " +++++++++++ ",
+ " ",
+ ]
+ )
+ )
self.controlPressed = False
def setCursor(self, cursor):
- #Método para definir cursor da ferramenta
- #Parâmetro de entrada: cursor (cursor usado na ferramenta)
- self.cur = cursor
+ # Método para definir cursor da ferramenta
+ # Parâmetro de entrada: cursor (cursor usado na ferramenta)
+ self.cur = cursor
def getCursor(self):
- #Método para obter cursor da ferramenta
- #Parâmetro de retorno: cursor (cursor usado na ferramenta)
+ # Método para obter cursor da ferramenta
+ # Parâmetro de retorno: cursor (cursor usado na ferramenta)
return self.cur
def setCanvas(self, canvas):
- #Método para definir o canvas do Qgis
- #Parâmetro de entrada: canvas (Canvas do Qgis)
+ # Método para definir o canvas do Qgis
+ # Parâmetro de entrada: canvas (Canvas do Qgis)
self.canvas = canvas
def getCanvas(self):
- #Método para obter o canvas do Qgis
- #Parâmetro de retorno: canvas (Canvas do Qgis)
+ # Método para obter o canvas do Qgis
+ # Parâmetro de retorno: canvas (Canvas do Qgis)
return self.canvas
def setActiveState(self, state):
- #Método para definir se a ferramenta está ativa ou não
- #Parâmetro de entrada: state (Boleano)
- self.active = state
-
+ # Método para definir se a ferramenta está ativa ou não
+ # Parâmetro de entrada: state (Boleano)
+ self.active = state
+
def getActiveState(self):
- #Método para obter se a ferramenta está ativa ou não
- #Parâmetro de retorno: state (Boleano)
+ # Método para obter se a ferramenta está ativa ou não
+ # Parâmetro de retorno: state (Boleano)
return self.active
-
+
def setStopedState(self, state):
- #Método para definir se a ferramenta está pausada
- #Parâmetro de entrada: state (Boleano)
+ # Método para definir se a ferramenta está pausada
+ # Parâmetro de entrada: state (Boleano)
self.stopState = state
-
+
def getStopedState(self):
- #Método para obter se a ferramenta está pausada
- #Parâmetro de retorno: state (Boleano)
+ # Método para obter se a ferramenta está pausada
+ # Parâmetro de retorno: state (Boleano)
return self.stopState
def setDrawingState(self, state):
- #Método para definir se a ferramenta está desenhando
- #Parâmetro de entrada: state (Boleano)
+ # Método para definir se a ferramenta está desenhando
+ # Parâmetro de entrada: state (Boleano)
self.drawing = state
def getDrawingState(self):
- #Método para obter se a ferramenta está desenhando
- #Parâmetro de retorno: state (Boleano)
+ # Método para obter se a ferramenta está desenhando
+ # Parâmetro de retorno: state (Boleano)
return self.drawing
def setRubberBand(self, rb):
- #Método para definir o rubberBand de aquisição
- #Parâmetro de entrada: rb (rubberBand)
+ # Método para definir o rubberBand de aquisição
+ # Parâmetro de entrada: rb (rubberBand)
self.rubberBand = rb
def getRubberBand(self):
- #Método para obter o rubberBand de aquisição
- #Parâmetro de retorno: rb (rubberBand)
+ # Método para obter o rubberBand de aquisição
+ # Parâmetro de retorno: rb (rubberBand)
return self.rubberBand
def setRubberBandToStopState(self, rb):
- #Método para definir o rubberBand de pausa da ferramenta
- #Parâmetro de entrada: rb (rubberBand)
+ # Método para definir o rubberBand de pausa da ferramenta
+ # Parâmetro de entrada: rb (rubberBand)
self.rubberBandToStopState = rb
def getRubberBandToStopState(self):
- #Método para obter o rubberBand de pausa da ferramenta
- #Parâmetro de retorno: rb (rubberBand)
+ # Método para obter o rubberBand de pausa da ferramenta
+ # Parâmetro de retorno: rb (rubberBand)
return self.rubberBandToStopState
def setGeometryType(self, geomType):
- #Método para definir o tipo da geometria
- #Parâmetro de entrada: geomType (Tipo da geometria)
+ # Método para definir o tipo da geometria
+ # Parâmetro de entrada: geomType (Tipo da geometria)
self.geometryType = geomType
def getGeometryType(self):
- #Método para obter o tipo da geometria
- #Parâmetro de retorno: geomType (Tipo da geometria)
+ # Método para obter o tipo da geometria
+ # Parâmetro de retorno: geomType (Tipo da geometria)
return self.geometryType
def setSnapRubberBand(self, snapRb):
- #Método para definir o rubberBand do snap
- #Parâmetro de entrada: rb (rubberBand)
- self.snapCursorRubberBand = snapRb
+ # Método para definir o rubberBand do snap
+ # Parâmetro de entrada: rb (rubberBand)
+ self.snapCursorRubberBand = snapRb
def getSnapRubberBand(self):
- #Método para obter o rubberBand do snap
- #Parâmetro de entrada: rb (rubberBand)
+ # Método para obter o rubberBand do snap
+ # Parâmetro de entrada: rb (rubberBand)
return self.snapCursorRubberBand
def isPolygon(self):
- #Método para testar se a camada atual é polígono
- #Parâmetro de retorno: isPolygon (Boleano)
- isPolygon = (self.getGeometryType() != core.QgsWkbTypes.LineGeometry)
+ # Método para testar se a camada atual é polígono
+ # Parâmetro de retorno: isPolygon (Boleano)
+ isPolygon = self.getGeometryType() != core.QgsWkbTypes.LineGeometry
return isPolygon
-
+
def keyPressEvent(self, event):
- #Método para receber os eventos do teclado
- #Parâmetro de entrada: event (Evento que chamou o método)
+ # Método para receber os eventos do teclado
+ # Parâmetro de entrada: event (Evento que chamou o método)
if event.key() in [QtCore.Qt.Key_Delete, QtCore.Qt.Key_Backspace]:
self.setStopedState(True)
self.removeVertice()
@@ -168,8 +175,8 @@ def keyPressEvent(self, event):
self.cancelEdition()
event.ignore()
- def cancelEdition(self):
- #Método para cancelar aquisição
+ def cancelEdition(self):
+ # Método para cancelar aquisição
self.getRubberBand().reset() if self.getRubberBand() else None
self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else None
self.setRubberBand(None)
@@ -177,18 +184,18 @@ def cancelEdition(self):
self.setActiveState(False)
self.contadorVert = 0
self.getCanvas().refresh()
-
+
def getParametersFromConfig(self):
- #Método para obter as configurações da tool do QSettings
- #Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta)
+ # Método para obter as configurações da tool do QSettings
+ # Parâmetro de retorno: parameters (Todas os parâmetros do QSettings usado na ferramenta)
settings = QtCore.QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- undoPoints = settings.value('undoPoints')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ undoPoints = settings.value("undoPoints")
settings.endGroup()
return int(undoPoints)
-
+
def removeVertice(self):
- #Método para remover vertices
+ # Método para remover vertices
firstPoint = None
lastPoint = None
rubberBand = self.getRubberBand()
@@ -198,13 +205,17 @@ def removeVertice(self):
rubberBand.removeLastPoint()
if not self.isPolygon():
lastPoint = rubberBand.asGeometry().asPolyline()[-1]
- new_rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.LineGeometry)
+ new_rubberBand = gui.QgsRubberBand(
+ self.getCanvas(), core.QgsWkbTypes.LineGeometry
+ )
new_rubberBand.setColor(QtGui.QColor(255, 0, 0, 150))
- else:
+ else:
if len(rubberBand.asGeometry().asPolygon()[0]) > 1:
firstPoint = rubberBand.asGeometry().asPolygon()[0][0]
lastPoint = rubberBand.asGeometry().asPolygon()[0][-2]
- new_rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.PolygonGeometry)
+ new_rubberBand = gui.QgsRubberBand(
+ self.getCanvas(), core.QgsWkbTypes.PolygonGeometry
+ )
new_rubberBand.setColor(QtGui.QColor(255, 0, 0, 63))
new_rubberBand.setWidth(1)
rubberBandToStopState = self.getRubberBandToStopState()
@@ -217,30 +228,29 @@ def removeVertice(self):
self.setRubberBandToStopState(new_rubberBand)
elif rubberBand:
self.setStopedState(False)
- self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else ''
+ self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else ""
self.cancelEdition()
def createSnapCursor(self, point):
- #Método para criar rubberBand do snap
+ # Método para criar rubberBand do snap
rubberBand = self.getSnapRubberBand()
if rubberBand:
rubberBand.reset()
else:
rubberBand = gui.QgsRubberBand(
- self.getCanvas(),
- geometryType = core.QgsWkbTypes.PointGeometry
+ self.getCanvas(), geometryType=core.QgsWkbTypes.PointGeometry
)
rubberBand.setColor(QtGui.QColor(255, 0, 0, 200))
rubberBand.setFillColor(QtGui.QColor(255, 0, 0, 40))
rubberBand.setWidth(5)
rubberBand.setIcon(gui.QgsRubberBand.ICON_X)
rubberBand.addPoint(point)
- self.setSnapRubberBand(rubberBand)
-
+ self.setSnapRubberBand(rubberBand)
+
def canvasReleaseEvent(self, event):
- #Método para receber os eventos release do canvas do Qgis
- #Parâmetro de entrada: event (Evento que chamou o método)
- self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else ''
+ # Método para receber os eventos release do canvas do Qgis
+ # Parâmetro de entrada: event (Evento que chamou o método)
+ self.getRubberBandToStopState().reset() if self.getRubberBandToStopState() else ""
if self.getStopedState():
self.setStopedState(False)
elif self.getActiveState():
@@ -251,8 +261,8 @@ def canvasReleaseEvent(self, event):
self.startEdition(event)
def startEdition(self, event):
- #Método para iniciar a aquisição
- #Parâmetro de entrada: event (Evento)
+ # Método para iniciar a aquisição
+ # Parâmetro de entrada: event (Evento)
snapRubberBand = self.getSnapRubberBand()
if snapRubberBand:
snapRubberBand.reset(geometryType=core.QgsWkbTypes.PointGeometry)
@@ -260,29 +270,33 @@ def startEdition(self, event):
self.setSnapRubberBand(None)
layer = self.getCanvas().currentLayer()
if layer:
- mapPoint = event.snapPoint()
+ mapPoint = event.snapPoint()
self.startRubberBand(mapPoint, layer)
def startRubberBand(self, pointMap, layer):
- #Método para iniciar o rubberBand da aquisição
- #Parâmetro de entrada: pointMap (Primeiro ponto da feição em aquisição), layer (Camada ativa)
+ # Método para iniciar o rubberBand da aquisição
+ # Parâmetro de entrada: pointMap (Primeiro ponto da feição em aquisição), layer (Camada ativa)
self.setDrawingState(True)
self.setGeometryType(layer.geometryType())
if self.isPolygon():
- rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.PolygonGeometry)
+ rubberBand = gui.QgsRubberBand(
+ self.getCanvas(), core.QgsWkbTypes.PolygonGeometry
+ )
rubberBand.setColor(QtGui.QColor(255, 0, 0, 63))
rubberBand.setWidth(2)
else:
- rubberBand = gui.QgsRubberBand(self.getCanvas(), core.QgsWkbTypes.LineGeometry)
+ rubberBand = gui.QgsRubberBand(
+ self.getCanvas(), core.QgsWkbTypes.LineGeometry
+ )
rubberBand.setColor(QtGui.QColor(255, 0, 0, 150))
rubberBand.setWidth(1)
rubberBand.addPoint(pointMap)
self.setRubberBand(rubberBand)
-
+
def canvasMoveEvent(self, event):
- #Método para receber os eventos canvas move do Qgis
- #Parâmetro de entrada: event (Evento que chamou o método)
- if not(self.getStopedState()):
+ # Método para receber os eventos canvas move do Qgis
+ # Parâmetro de entrada: event (Evento que chamou o método)
+ if not (self.getStopedState()):
snapRubberBand = self.getSnapRubberBand()
if snapRubberBand:
snapRubberBand.hide()
@@ -291,21 +305,23 @@ def canvasMoveEvent(self, event):
oldPoint = event.mapPoint()
event.snapPoint()
point = event.mapPoint()
- self.createSnapCursor(point) if oldPoint != point else ''
+ self.createSnapCursor(point) if oldPoint != point else ""
if self.getRubberBand() and self.getRubberBand().numberOfVertices() == 0:
self.getRubberBand().addPoint(point)
elif self.getRubberBand():
self.getRubberBand().addPoint(oldPoint)
if self.getRubberBandToStopState():
- self.updateRubberBandToStopState(
- self.toMapCoordinates( event.pos() )
- )
+ self.updateRubberBandToStopState(self.toMapCoordinates(event.pos()))
def updateRubberBandToStopState(self, point):
- #Método para atualizar o rubberband do pause da ferramenta
+ # Método para atualizar o rubberband do pause da ferramenta
rubberBand = self.getRubberBandToStopState()
if rubberBand.asGeometry():
- listPoints = rubberBand.asGeometry().asPolygon() if self.isPolygon() else rubberBand.asGeometry().asPolyline()
+ listPoints = (
+ rubberBand.asGeometry().asPolygon()
+ if self.isPolygon()
+ else rubberBand.asGeometry().asPolyline()
+ )
if self.isPolygon() and self.getRubberBand():
rubberBand.reset(geometryType=core.QgsWkbTypes.PolygonGeometry)
firstPoint = self.getRubberBand().asGeometry().asPolygon()[0][0]
@@ -313,12 +329,12 @@ def updateRubberBandToStopState(self, point):
rubberBand.addPoint(secondPoint)
rubberBand.addPoint(point)
rubberBand.addPoint(firstPoint)
- elif not(self.isPolygon()) and len(listPoints) >= 1:
+ elif not (self.isPolygon()) and len(listPoints) >= 1:
rubberBand.removeLastPoint()
rubberBand.addPoint(point)
def finishEdition(self, event):
- #Método para finalizar a aquisição
+ # Método para finalizar a aquisição
if self.getRubberBand():
event.snapPoint()
self.getRubberBand().addPoint(event.mapPoint())
@@ -333,7 +349,7 @@ def finishEdition(self, event):
self.cancelEdition()
def doReshape(self, geom):
- line = ''
+ line = ""
if geom.type() == core.QgsWkbTypes.LineGeometry:
line = geom.asPolyline()
elif geom.type() == core.QgsWkbTypes.PolygonGeometry:
@@ -342,11 +358,11 @@ def doReshape(self, geom):
else:
line = geom.asPolygon()[0]
del line[-1]
-
+
self.reshapeLineCreated.emit(QgsGeometry.fromPolylineXY(line))
def activate(self):
- #Método chamado ao ativar a ferramenta
+ # Método chamado ao ativar a ferramenta
mapCanvas = self.getCanvas()
mapCanvas.setCursor(self.getCursor())
diff --git a/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py b/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py
index cffdfacb4..92ba5132d 100644
--- a/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py
+++ b/DsgTools/gui/ProductionTools/MapTools/GenericSelectionTool/genericSelectionTool.py
@@ -27,20 +27,28 @@
from functools import partial
from qgis.gui import QgsMapTool, QgsRubberBand
-from qgis.core import QgsPointXY, QgsRectangle, QgsFeatureRequest, QgsVectorLayer, \
- QgsProject, QgsWkbTypes, QgsRasterLayer
+from qgis.core import (
+ QgsPointXY,
+ QgsRectangle,
+ QgsFeatureRequest,
+ QgsVectorLayer,
+ QgsProject,
+ QgsWkbTypes,
+ QgsRasterLayer,
+)
from qgis.PyQt.QtCore import Qt, QSettings
from qgis.PyQt.QtGui import QColor, QCursor
from qgis.PyQt.QtWidgets import QMenu, QApplication
from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler
+
class GenericSelectionTool(QgsMapTool):
def __init__(self, iface):
"""
Tool Behaviours: (all behaviours start edition, except for rectangle one)
- 1- Left Click: Clears previous selection, selects feature, sets feature layer as active layer.
- The selection is done with the following priority: Point, Line then Polygon.
+ 1- Left Click: Clears previous selection, selects feature, sets feature layer as active layer.
+ The selection is done with the following priority: Point, Line then Polygon.
Selection is only done in visible layer.
2- Control + Left Click: Adds to selection selected feature. This selection follows the priority in item 1.
3- Right Click: Opens feature form
@@ -48,60 +56,50 @@ def __init__(self, iface):
follows priority of item 1;
5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangl'e are added to selection
"""
- self.iface = iface
+ self.iface = iface
self.canvas = self.iface.mapCanvas()
self.toolAction = None
QgsMapTool.__init__(self, self.canvas)
self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
self.hoverRubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
- mFillColor = QColor( 254, 178, 76, 63 )
+ mFillColor = QColor(254, 178, 76, 63)
self.rubberBand.setColor(mFillColor)
- self.hoverRubberBand.setColor(QColor( 255, 0, 0, 90 ))
+ self.hoverRubberBand.setColor(QColor(255, 0, 0, 90))
self.rubberBand.setWidth(1)
self.reset()
self.blackList = self.getBlackList()
self.cursorChanged = False
- self.cursorChangingHotkey = Qt.Key_Alt
- self.menuHovered = False # indicates hovering actions over context menu
+ self.menuHovered = False # indicates hovering actions over context menu
self.geometryHandler = GeometryHandler(iface=self.iface)
-
+
def addTool(self, manager, callback, parentMenu, iconBasePath):
- icon_path = iconBasePath + '/genericSelect.png'
- toolTip = self.tr("DSGTools: Generic Selector\nLeft Click: select feature's layer and put it on edit mode\nRight Click: Open feature's form\nControl+Left Click: add/remove feature from selection\nShift+Left Click+drag and drop: select all features that intersects rubberband.")
+ icon_path = iconBasePath + "/genericSelect.png"
+ toolTip = self.tr(
+ "DSGTools: Generic Selector\nLeft Click: select feature's layer and put it on edit mode\nRight Click: Open feature's form\nControl+Left Click: add/remove feature from selection\nShift+Left Click+drag and drop: select all features that intersects rubberband."
+ )
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Generic Selector'),
+ text=self.tr("DSGTools: Generic Selector"),
callback=callback,
add_to_menu=False,
add_to_toolbar=True,
- withShortcut = True,
- tooltip = toolTip,
- parentToolbar =parentMenu,
- isCheckable = True
+ withShortcut=True,
+ tooltip=toolTip,
+ parentToolbar=parentMenu,
+ isCheckable=True,
)
self.setAction(action)
-
- def keyPressEvent(self, e):
- """
- Reimplemetation of keyPressEvent() in order to handle cursor changing hotkey (Alt).
- """
- if e.key() == self.cursorChangingHotkey and not self.cursorChanged:
- self.cursorChanged = True
- QApplication.setOverrideCursor(QCursor(Qt.PointingHandCursor))
- else:
- self.cursorChanged = False
- QApplication.restoreOverrideCursor()
-
+
def getBlackList(self):
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- valueList = settings.value('valueList')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ valueList = settings.value("valueList")
if valueList:
- valueList = valueList.split(';')
+ valueList = valueList.split(";")
return valueList
else:
- return ['moldura']
-
+ return ["moldura"]
+
def reset(self):
"""
Resets rubber band.
@@ -109,29 +107,18 @@ def reset(self):
self.startPoint = self.endPoint = None
self.isEmittingPoint = False
self.rubberBand.reset(QgsWkbTypes.PolygonGeometry)
-
- def keyPressEvent(self, e):
- """
- Reimplemetation of keyPressEvent() in order to handle cursor changing hotkey (F2).
- """
- if e.key() == self.cursorChangingHotkey and not self.cursorChanged:
- self.cursorChanged = True
- QApplication.setOverrideCursor(QCursor(Qt.PointingHandCursor))
- else:
- self.cursorChanged = False
- QApplication.restoreOverrideCursor()
def canvasMoveEvent(self, e):
"""
Used only on rectangle select.
"""
if self.menuHovered:
- # deactivates rubberband when the context menu is "destroyed"
+ # deactivates rubberband when the context menu is "destroyed"
self.hoverRubberBand.reset(QgsWkbTypes.PolygonGeometry)
if not self.isEmittingPoint:
return
- self.endPoint = self.toMapCoordinates( e.pos() )
- self.showRect(self.startPoint, self.endPoint)
+ self.endPoint = self.toMapCoordinates(e.pos())
+ self.showRect(self.startPoint, self.endPoint)
def showRect(self, startPoint, endPoint):
"""
@@ -144,11 +131,11 @@ def showRect(self, startPoint, endPoint):
point2 = QgsPointXY(startPoint.x(), endPoint.y())
point3 = QgsPointXY(endPoint.x(), endPoint.y())
point4 = QgsPointXY(endPoint.x(), startPoint.y())
-
+
self.rubberBand.addPoint(point1, False)
self.rubberBand.addPoint(point2, False)
self.rubberBand.addPoint(point3, False)
- self.rubberBand.addPoint(point4, True) # true to update canvas
+ self.rubberBand.addPoint(point4, True) # true to update canvas
self.rubberBand.show()
def rectangle(self):
@@ -157,14 +144,17 @@ def rectangle(self):
"""
if self.startPoint is None or self.endPoint is None:
return None
- elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():
+ elif (
+ self.startPoint.x() == self.endPoint.x()
+ or self.startPoint.y() == self.endPoint.y()
+ ):
return None
return QgsRectangle(self.startPoint, self.endPoint)
def setAction(self, action):
self.toolAction = action
self.toolAction.setCheckable(True)
-
+
def canvasReleaseEvent(self, e):
"""
After the rectangle is built, here features are selected.
@@ -177,16 +167,18 @@ def canvasReleaseEvent(self, e):
return
layers = self.canvas.layers()
for layer in layers:
- #ignore layers on black list and features that are not vector layers
- if not isinstance(layer, QgsVectorLayer) or (self.layerHasPartInBlackList(layer.name())):
+ # ignore layers on black list and features that are not vector layers
+ if not isinstance(layer, QgsVectorLayer) or (
+ self.layerHasPartInBlackList(layer.name())
+ ):
continue
if firstGeom is not None and layer.geometryType() != firstGeom:
# if there are features already selected, shift will only get the same type geometry
# if more than one ty of geometry is present, only the strongest will be selected
continue
- #builds bbRect and select from layer, adding selection
+ # builds bbRect and select from layer, adding selection
bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, r)
- layer.selectByRect(bbRect, behavior = QgsVectorLayer.AddToSelection)
+ layer.selectByRect(bbRect, behavior=QgsVectorLayer.AddToSelection)
self.rubberBand.hide()
def canvasPressEvent(self, e):
@@ -202,15 +194,15 @@ def canvasPressEvent(self, e):
else:
self.isEmittingPoint = False
self.createContextMenu(e)
-
+
def getCursorRect(self, e):
"""
Calculates small cursor rectangle around mouse position. Used to facilitate operations
"""
p = self.toMapCoordinates(e.pos())
w = self.canvas.mapUnitsPerPixel() * 10
- return QgsRectangle(p.x()-w, p.y()-w, p.x()+w, p.y()+w)
-
+ return QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w)
+
def layerHasPartInBlackList(self, lyrName):
"""
Verifies if terms in black list appear on lyrName
@@ -219,35 +211,50 @@ def layerHasPartInBlackList(self, lyrName):
if item.lower() in lyrName.lower():
return True
return False
-
- def getPrimitiveDict(self, e, hasControlModifier=False):
+
+ def getPrimitiveDict(self, e, hasControlModifier=False, hasAltModifier=False):
"""
Builds a dict with keys as geometryTypes of layer, which are Qgis.Point (value 0), Qgis.Line (value 1) or Qgis.Polygon (value 2),
and values as layers from self.iface.mapCanvas().layers(). When self.iface.mapCanvas().layers() is called, a list of
layers ordered according to lyr order in TOC is returned.
"""
- #these layers are ordered by view order
+ # these layers are ordered by view order
primitiveDict = dict()
firstGeom = self.checkSelectedLayers()
visibleLayers = QgsProject.instance().layerTreeRoot().checkedLayers()
- for lyr in self.iface.mapCanvas().layers(): #ordered layers
- #layer types other than VectorLayer are ignored, as well as layers in black list and layers that are not visible
- if not isinstance(lyr, QgsVectorLayer) or (self.layerHasPartInBlackList(lyr.name())) or lyr not in visibleLayers:
+ iterator = (
+ self.iface.mapCanvas().layers()
+ if not hasAltModifier
+ else [self.iface.activeLayer()]
+ )
+ for lyr in iterator: # ordered layers
+ # layer types other than VectorLayer are ignored, as well as layers in black list and layers that are not visible
+ if (
+ not isinstance(lyr, QgsVectorLayer)
+ or (self.layerHasPartInBlackList(lyr.name()))
+ or lyr not in visibleLayers
+ ):
continue
- if hasControlModifier and (not firstGeom) and (not primitiveDict or lyr.geometryType() < firstGeom):
+ if (
+ hasControlModifier
+ and (not firstGeom)
+ and (not primitiveDict or lyr.geometryType() < firstGeom)
+ ):
firstGeom = lyr.geometryType()
geomType = lyr.geometryType()
if geomType not in primitiveDict:
primitiveDict[geomType] = []
- #removes selection
- if (not hasControlModifier and e.button() == Qt.LeftButton) or (hasControlModifier and e.button() == Qt.RightButton):
+ # removes selection
+ if (not hasControlModifier and e.button() == Qt.LeftButton) or (
+ hasControlModifier and e.button() == Qt.RightButton
+ ):
lyr.removeSelection()
primitiveDict[geomType].append(lyr)
if hasControlModifier and firstGeom in [0, 1, 2]:
- return { firstGeom : primitiveDict[firstGeom] }
+ return {firstGeom: primitiveDict[firstGeom]}
else:
return primitiveDict
-
+
def deactivate(self):
"""
Deactivate tool.
@@ -271,15 +278,17 @@ def activate(self):
self.toolAction.setChecked(True)
QgsMapTool.activate(self)
- def setSelectionFeature(self, layer, feature, selectAll=False, setActiveLayer=False):
+ def setSelectionFeature(
+ self, layer, feature, selectAll=False, setActiveLayer=False
+ ):
"""
- Selects a given feature on canvas.
+ Selects a given feature on canvas.
:param layer: (QgsVectorLayer) layer containing the target feature.
:param feature: (QgsFeature) taget feature to be selected.
:param selectAll: (bool) indicates whether or not this fuction was called from a select all command.
so it doesn't remove selection from those that are selected already from the list.
:param setActiveLayer: (bool) indicates whether method should set layer as active.
- """
+ """
idList = layer.selectedFeatureIds()
self.iface.setActiveLayer(layer)
layer.startEditing()
@@ -296,7 +305,7 @@ def setSelectionFeature(self, layer, feature, selectAll=False, setActiveLayer=Fa
def setSelectionListFeature(self, dictLayerFeature, selectAll=True):
"""
- Selects all features on canvas of a given dict.
+ Selects all features on canvas of a given dict.
:param dictLayerFeature: (dict) dict of layers/features to be selected.
:param selectAll: (bool) indicates if "All"-command comes from a "Select All". In that case, selected features
won't be deselected.
@@ -315,7 +324,7 @@ def setSelectionListFeature(self, dictLayerFeature, selectAll=True):
idList.pop(idList.index(featId))
layer.selectByIds(idList)
layer.startEditing()
- # last layer is set active and
+ # last layer is set active and
self.iface.setActiveLayer(layer)
def openMultipleFeatureForm(self, dictLayerFeature):
@@ -346,11 +355,11 @@ def filterStrongestGeometry(self, dictLayerFeature):
if lyr.geometryType() == strongest_geometry:
outDict[lyr] = dictLayerFeature[lyr]
return outDict
-
+
def createRubberBand(self, feature, layer, geom):
"""
Creates a rubber band around from a given a standard feature string.
- :param feature: taget feature to be highlighted
+ :param feature: taget feature to be highlighted
:param layer: layer containing the target feature
:param geom: int indicating geometry type of target feature
"""
@@ -423,20 +432,32 @@ def getCallback(self, e, layer, feature, geomType=None, selectAll=True):
"""
if not geomType:
geomType = layer.geometryType()
- if e.button() == Qt.LeftButton:
+ if e.button() == Qt.LeftButton:
# line added to make sure the action is associated with current loop value,
# lambda function is used with standard parameter set to current loops value.
# triggeredAction = lambda t=[layer, feature] : self.setSelectionFeature(t[0], feature=t[1], selectAll=selectAll, setActiveLayer=True)
- triggeredAction = partial(self.setSelectionFeature, layer=layer, feature=feature, selectAll=selectAll, setActiveLayer=True)
- hoveredAction = partial(self.createRubberBand, feature=feature, layer=layer, geom=geomType)
+ triggeredAction = partial(
+ self.setSelectionFeature,
+ layer=layer,
+ feature=feature,
+ selectAll=selectAll,
+ setActiveLayer=True,
+ )
+ hoveredAction = partial(
+ self.createRubberBand, feature=feature, layer=layer, geom=geomType
+ )
elif e.button() == Qt.RightButton:
- selected = (QApplication.keyboardModifiers() == Qt.ControlModifier)
+ selected = QApplication.keyboardModifiers() == Qt.ControlModifier
if selected:
triggeredAction = partial(self.iface.setActiveLayer, layer)
hoveredAction = None
else:
- triggeredAction = partial(self.iface.openFeatureForm, layer, feature, showModal=False)
- hoveredAction = partial(self.createRubberBand, feature=feature, layer=layer, geom=geomType)
+ triggeredAction = partial(
+ self.iface.openFeatureForm, layer, feature, showModal=False
+ )
+ hoveredAction = partial(
+ self.createRubberBand, feature=feature, layer=layer, geom=geomType
+ )
return triggeredAction, hoveredAction
def getCallbackMultipleFeatures(self, e, dictLayerFeature, selectAll=True):
@@ -448,16 +469,24 @@ def getCallbackMultipleFeatures(self, e, dictLayerFeature, selectAll=True):
"""
# setting the action for the "All" options
if e.button() == Qt.LeftButton:
- triggeredAction = partial(self.setSelectionListFeature, dictLayerFeature=dictLayerFeature, selectAll=selectAll)
+ triggeredAction = partial(
+ self.setSelectionListFeature,
+ dictLayerFeature=dictLayerFeature,
+ selectAll=selectAll,
+ )
else:
- triggeredAction = partial(self.openMultipleFeatureForm, dictLayerFeature=dictLayerFeature)
+ triggeredAction = partial(
+ self.openMultipleFeatureForm, dictLayerFeature=dictLayerFeature
+ )
# to trigger "Hover" signal on QMenu for the multiple options
- hoveredAction = partial(self.createMultipleRubberBand, dictLayerFeature=dictLayerFeature)
+ hoveredAction = partial(
+ self.createMultipleRubberBand, dictLayerFeature=dictLayerFeature
+ )
return triggeredAction, hoveredAction
def createSubmenu(self, e, parentMenu, menuDict, genericAction, selectAll):
"""
- Creates a submenu in a given parent context menu and populates it, with classes/feature sublevels from the menuDict.
+ Creates a submenu in a given parent context menu and populates it, with classes/feature sublevels from the menuDict.
:param e: (QMouseEvent) mouse event on canvas. If menuDict has only 1 class in it, method will populate parent QMenu.
:param parentMenu: (QMenu) menu containing the populated submenu
:param menuDict: (dict) dictionary containing all classes and their features to be filled into submenu.
@@ -467,7 +496,7 @@ def createSubmenu(self, e, parentMenu, menuDict, genericAction, selectAll):
# creating a dict to handle all "menu" for each class
submenuDict = dict()
# sort the layers from diciotnary
- classNameDict = { cl.name() : cl for cl in menuDict }
+ classNameDict = {cl.name(): cl for cl in menuDict}
layers = sorted(list(classNameDict.keys()))
for className in layers:
# menu for features of each class
@@ -476,54 +505,92 @@ def createSubmenu(self, e, parentMenu, menuDict, genericAction, selectAll):
# get layer database name
dsUri = cl.dataProvider().dataSourceUri()
temp = []
- if '/' in dsUri or '\\' in dsUri:
+ if "/" in dsUri or "\\" in dsUri:
db_name = dsUri.split("|")[0] if "|" in dsUri else dsUri
- db_name = os.path.basename(db_name.split("'")[1] if "'" in db_name else db_name)
- elif 'memory' in dsUri:
- db_name = self.tr('{0} (Memory Layer)').format(className)
+ db_name = os.path.basename(
+ db_name.split("'")[1] if "'" in db_name else db_name
+ )
+ elif "memory" in dsUri:
+ db_name = self.tr("{0} (Memory Layer)").format(className)
else:
db_name = dsUri.split("'")[1]
if len(menuDict) == 1:
# if dictionaty has only 1 class, no need for an extra QMenu - features will be enlisted directly
# order features by ID to be displayer ordered
- featDict = { feat.id() : feat for feat in menuDict[cl] }
+ featDict = {feat.id(): feat for feat in menuDict[cl]}
orderedFeatIdList = sorted(list(featDict.keys()))
for featId in orderedFeatIdList:
feat = featDict[featId]
- s = "{db_name} | {className} (feat_id = {featId})".format(db_name=db_name, className=className, featId=featId)
+ s = "{db_name} | {className} (feat_id = {featId})".format(
+ db_name=db_name, className=className, featId=featId
+ )
# inserting action for each feature
action = parentMenu.addAction(s)
- triggeredAction, hoveredAction = self.getCallback(e=e, layer=cl, feature=feat, geomType=geomType, selectAll=selectAll)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
+ triggeredAction, hoveredAction = self.getCallback(
+ e=e,
+ layer=cl,
+ feature=feat,
+ geomType=geomType,
+ selectAll=selectAll,
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
# inserting generic action, if necessary
if len(menuDict[cl]) > 1:
# if there are more than 1 feature to be filled, "All"-command should be added
- action = parentMenu.addAction(self.tr("{0} From Class {1}").format(genericAction, className))
- triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=menuDict, selectAll=selectAll)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
+ action = parentMenu.addAction(
+ self.tr("{0} From Class {1}").format(genericAction, className)
+ )
+ triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(
+ e=e, dictLayerFeature=menuDict, selectAll=selectAll
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
# there is no mapping of class to be exposed, only information added to parent QMenu itself
return dict()
- title = "{db_name} | {className}".format(db_name=db_name, className=className)
+ title = "{db_name} | {className}".format(
+ db_name=db_name, className=className
+ )
submenuDict[cl] = QMenu(title=title, parent=parentMenu)
parentMenu.addMenu(submenuDict[cl])
# inserting an entry for every feature of each class in its own context menu
# order features by ID to be displayer ordered
- featDict = { feat.id() : feat for feat in menuDict[cl] }
+ featDict = {feat.id(): feat for feat in menuDict[cl]}
orderedFeatIdList = sorted(list(featDict.keys()))
for featId in orderedFeatIdList:
feat = featDict[featId]
- s = 'feat_id = {0}'.format(featId)
+ s = "feat_id = {0}".format(featId)
action = submenuDict[cl].addAction(s)
- triggeredAction, hoveredAction = self.getCallback(e=e, layer=cl, feature=feat, geomType=geomType, selectAll=selectAll)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
+ triggeredAction, hoveredAction = self.getCallback(
+ e=e, layer=cl, feature=feat, geomType=geomType, selectAll=selectAll
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
# set up list for the "All"-commands
temp.append([cl, feat, geomType])
# adding generic action for each class
if len(menuDict[cl]) > 1:
# if there are more than 1 feature to be filled, "All"-command should be added
- action = submenuDict[cl].addAction(self.tr("{0} From Class {1}").format(genericAction, className))
- triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature={ cl : menuDict[cl] }, selectAll=selectAll)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
+ action = submenuDict[cl].addAction(
+ self.tr("{0} From Class {1}").format(genericAction, className)
+ )
+ triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(
+ e=e, dictLayerFeature={cl: menuDict[cl]}, selectAll=selectAll
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
return submenuDict
def setContextMenuStyle(self, e, dictMenuSelected, dictMenuNotSelected):
@@ -538,54 +605,97 @@ def setContextMenuStyle(self, e, dictMenuSelected, dictMenuNotSelected):
selectedDict = bool(dictMenuSelected)
notSelectedDict = bool(dictMenuNotSelected)
# finding out if one of either dictionaty are filled ("Exclusive or")
- selectedXORnotSelected = (selectedDict != notSelectedDict)
+ selectedXORnotSelected = selectedDict != notSelectedDict
# setting "All"-command name
if e.button() == Qt.RightButton:
- genericAction = self.tr('Open All Feature Forms')
+ genericAction = self.tr("Open All Feature Forms")
else:
- genericAction = self.tr('Select All Features')
+ genericAction = self.tr("Select All Features")
# in case one of given dict is empty
if selectedXORnotSelected:
if selectedDict:
- menuDict, menu = dictMenuSelected, QMenu(title=self.tr('Selected Features'))
- genericAction = self.tr('Deselect All Features')
+ menuDict, menu = dictMenuSelected, QMenu(
+ title=self.tr("Selected Features")
+ )
+ genericAction = self.tr("Deselect All Features")
# if the dictionary is from selected features, we want commands to be able to deselect them
selectAll = False
else:
- menuDict, menu = dictMenuNotSelected, QMenu(title=self.tr('Not Selected Features'))
- genericAction = self.tr('Select All Features')
+ menuDict, menu = dictMenuNotSelected, QMenu(
+ title=self.tr("Not Selected Features")
+ )
+ genericAction = self.tr("Select All Features")
# if the dictionary is from non-selected features, we want commands to be able to select them
selectAll = True
if e.button() == Qt.RightButton:
- genericAction = self.tr('Open All Feature Forms')
- self.createSubmenu(e=e, parentMenu=menu, menuDict=menuDict, genericAction=genericAction, selectAll=selectAll)
+ genericAction = self.tr("Open All Feature Forms")
+ self.createSubmenu(
+ e=e,
+ parentMenu=menu,
+ menuDict=menuDict,
+ genericAction=genericAction,
+ selectAll=selectAll,
+ )
if len(menuDict) != 1 and len(list(menuDict.values())) > 1:
# if there's only one class, "All"-command is given by createSubmenu method
action = menu.addAction(genericAction)
- triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=menuDict, selectAll=selectAll)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
+ triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(
+ e=e, dictLayerFeature=menuDict, selectAll=selectAll
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
elif selectedDict:
# if both of them is empty one more QMenu level is added
menu = QMenu()
- selectedMenu = QMenu(title=self.tr('Selected Features'))
- notSelectedMenu = QMenu(title=self.tr('Not Selected Features'))
+ selectedMenu = QMenu(title=self.tr("Selected Features"))
+ notSelectedMenu = QMenu(title=self.tr("Not Selected Features"))
menu.addMenu(selectedMenu)
menu.addMenu(notSelectedMenu)
- selectedGenericAction = self.tr('Deselect All Features')
- notSelectedGenericAction = self.tr('Select All Features')
+ selectedGenericAction = self.tr("Deselect All Features")
+ notSelectedGenericAction = self.tr("Select All Features")
# selectAll is set to True as now we want command to Deselect Features in case they are selected
- self.createSubmenu(e=e, parentMenu=selectedMenu, menuDict=dictMenuSelected, genericAction=selectedGenericAction, selectAll=False)
+ self.createSubmenu(
+ e=e,
+ parentMenu=selectedMenu,
+ menuDict=dictMenuSelected,
+ genericAction=selectedGenericAction,
+ selectAll=False,
+ )
if len(dictMenuSelected) != 1 and len(list(dictMenuSelected.values())) > 1:
# if there's only one class, "All"-command is given by createSubmenu method
action = selectedMenu.addAction(selectedGenericAction)
- triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=dictMenuSelected, selectAll=False)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
- self.createSubmenu(e=e, parentMenu=notSelectedMenu, menuDict=dictMenuNotSelected, genericAction=notSelectedGenericAction, selectAll=True)
- if len(dictMenuNotSelected) != 1 and len(list(dictMenuNotSelected.values())) > 1:
+ triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(
+ e=e, dictLayerFeature=dictMenuSelected, selectAll=False
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
+ self.createSubmenu(
+ e=e,
+ parentMenu=notSelectedMenu,
+ menuDict=dictMenuNotSelected,
+ genericAction=notSelectedGenericAction,
+ selectAll=True,
+ )
+ if (
+ len(dictMenuNotSelected) != 1
+ and len(list(dictMenuNotSelected.values())) > 1
+ ):
# if there's only one class, "All"-command is given by createSubmenu method
action = notSelectedMenu.addAction(notSelectedGenericAction)
- triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(e=e, dictLayerFeature=dictMenuNotSelected, selectAll=True)
- self.addCallBackToAction(action=action, onTriggeredAction=triggeredAction, onHoveredAction=hoveredAction)
+ triggeredAction, hoveredAction = self.getCallbackMultipleFeatures(
+ e=e, dictLayerFeature=dictMenuNotSelected, selectAll=True
+ )
+ self.addCallBackToAction(
+ action=action,
+ onTriggeredAction=triggeredAction,
+ onHoveredAction=hoveredAction,
+ )
menu.exec_(self.canvas.viewport().mapToGlobal(e.pos()))
def checkSelectedFeaturesOnDict(self, menuDict):
@@ -610,24 +720,11 @@ def checkSelectedFeaturesOnDict(self, menuDict):
notSelectedFeaturesDict[cl].append(feat)
return selectedFeaturesDict, notSelectedFeaturesDict
- def getSelectedRasters(self, e):
- rasters = []
- rect = self.getCursorRect(e)
- layers = self.iface.mapCanvas().layers()
- for layer in self.iface.mapCanvas().layers():
- if not isinstance(layer, QgsRasterLayer):
- continue
- bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, rect)
- if not layer.extent().intersects(bbRect):
- continue
- rasters.append(layer)
- return rasters
-
def addRasterMenu(self, menu, rasters):
rasterMenu = QMenu(title="Rasters", parent=menu)
for raster in rasters:
action = rasterMenu.addAction(raster.name())
- action.triggered.connect(lambda : self.iface.setActiveLayer(raster))
+ action.triggered.connect(lambda: self.iface.setActiveLayer(raster))
menu.addMenu(rasterMenu)
def createContextMenu(self, e):
@@ -635,75 +732,86 @@ def createContextMenu(self, e):
Creates the context menu for overlapping layers.
:param e: mouse event caught from canvas.
"""
- selected = (QApplication.keyboardModifiers() == Qt.ControlModifier)
+ selected = QApplication.keyboardModifiers() == Qt.ControlModifier
if selected:
firstGeom = self.checkSelectedLayers()
# setting a list of features to iterate over
- layerList = self.getPrimitiveDict(e, hasControlModifier=selected)
+ layerList = self.getPrimitiveDict(
+ e,
+ hasControlModifier=selected,
+ hasAltModifier=QApplication.keyboardModifiers() == Qt.AltModifier,
+ )
layers = []
for key in layerList:
layers += layerList[key]
- if layers:
- rect = self.getCursorRect(e)
- lyrFeatDict = dict()
- for layer in layers:
- if not isinstance(layer, QgsVectorLayer):
+ if not layers:
+ return
+ rect = self.getCursorRect(e)
+ lyrFeatDict = dict()
+ for layer in layers:
+ if not isinstance(layer, QgsVectorLayer):
+ continue
+ geomType = layer.geometryType()
+ # iterate over features inside the mouse bounding box
+ bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, rect)
+ for feature in layer.getFeatures(QgsFeatureRequest(bbRect)):
+ geom = feature.geometry()
+ if not geom:
continue
- geomType = layer.geometryType()
- # iterate over features inside the mouse bounding box
- bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, rect)
- for feature in layer.getFeatures(QgsFeatureRequest(bbRect)):
- geom = feature.geometry()
- if geom:
- searchRect = self.geometryHandler.reprojectSearchArea(layer, rect)
- if selected:
- # if Control was held, appending behaviour is different
- if not firstGeom:
- firstGeom = geomType
- elif firstGeom > geomType:
- firstGeom = geomType
- if geomType == firstGeom and geom.intersects(searchRect):
- # only appends features if it has the same geometry as first selected feature
- if layer in lyrFeatDict:
- lyrFeatDict[layer].append(feature)
- else:
- lyrFeatDict[layer] = [feature]
+ searchRect = self.geometryHandler.reprojectSearchArea(layer, rect)
+ if selected:
+ # if Control was held, appending behaviour is different
+ if not firstGeom:
+ firstGeom = geomType
+ elif firstGeom > geomType:
+ firstGeom = geomType
+ if geomType == firstGeom and geom.intersects(searchRect):
+ # only appends features if it has the same geometry as first selected feature
+ if layer in lyrFeatDict:
+ lyrFeatDict[layer].append(feature)
else:
- if geom.intersects(searchRect):
- if layer in lyrFeatDict:
- lyrFeatDict[layer].append(feature)
- else:
- lyrFeatDict[layer] = [feature]
- lyrFeatDict = self.filterStrongestGeometry(lyrFeatDict)
- #rasters = self.getSelectedRasters(e)
- if lyrFeatDict:
- moreThanOneFeat = len(list(lyrFeatDict.values())) > 1 or len(list(lyrFeatDict.values())[0]) > 1
- if moreThanOneFeat:
- # if there are overlapping features (valid candidates only)
- selectedFeaturesDict, notSelectedFeaturesDict = self.checkSelectedFeaturesOnDict(menuDict=lyrFeatDict)
- self.setContextMenuStyle(
- e=e,
- dictMenuSelected=selectedFeaturesDict,
- dictMenuNotSelected=notSelectedFeaturesDict
- )
+ lyrFeatDict[layer] = [feature]
else:
- layer = list(lyrFeatDict.keys())[0]
- feature = lyrFeatDict[layer][0]
- selected = (QApplication.keyboardModifiers() == Qt.ControlModifier)
- if e.button() == Qt.LeftButton:
- # if feature is selected, we want it to be de-selected
- self.setSelectionFeature(layer=layer, feature=feature, selectAll=False, setActiveLayer=True)
- elif selected:
- self.iface.setActiveLayer(layer)
+ if not geom.intersects(searchRect):
+ continue
+ if layer in lyrFeatDict:
+ lyrFeatDict[layer].append(feature)
else:
- self.iface.openFeatureForm(layer, feature, showModal=False)
- #elif rasters and e.button() == Qt.LeftButton:
- # self.openRastersMenu(e, rasters)
-
- def openRastersMenu(self, e, rasters):
- menu = QMenu()
- self.addRasterMenu(menu, rasters)
- menu.exec_(self.canvas.viewport().mapToGlobal(e.pos()))
+ lyrFeatDict[layer] = [feature]
+ lyrFeatDict = self.filterStrongestGeometry(lyrFeatDict)
+ if not lyrFeatDict:
+ return
+ moreThanOneFeat = (
+ len(list(lyrFeatDict.values())) > 1
+ or len(list(lyrFeatDict.values())[0]) > 1
+ )
+ if moreThanOneFeat:
+ # if there are overlapping features (valid candidates only)
+ (
+ selectedFeaturesDict,
+ notSelectedFeaturesDict,
+ ) = self.checkSelectedFeaturesOnDict(menuDict=lyrFeatDict)
+ self.setContextMenuStyle(
+ e=e,
+ dictMenuSelected=selectedFeaturesDict,
+ dictMenuNotSelected=notSelectedFeaturesDict,
+ )
+ else:
+ layer = list(lyrFeatDict.keys())[0]
+ feature = lyrFeatDict[layer][0]
+ selected = QApplication.keyboardModifiers() == Qt.ControlModifier
+ if e.button() == Qt.LeftButton:
+ # if feature is selected, we want it to be de-selected
+ self.setSelectionFeature(
+ layer=layer,
+ feature=feature,
+ selectAll=False,
+ setActiveLayer=True,
+ )
+ elif selected:
+ self.iface.setActiveLayer(layer)
+ else:
+ self.iface.openFeatureForm(layer, feature, showModal=False)
def unload(self):
self.deactivate()
diff --git a/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py b/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py
index 776492f8a..06927249d 100644
--- a/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py
+++ b/DsgTools/gui/ProductionTools/MapTools/LabelTogglingTool/labelTogglingTool.py
@@ -26,68 +26,76 @@
from qgis.gui import QgsMapTool
from qgis.core import QgsProject, QgsVectorLayer
+
class LabelTogglingTool(QgsMapTool):
AllLayers, SelectedLayers, ActiveLayer = range(3)
+
def __init__(self, iface):
"""
Hides or show active layers labels.
"""
- self.iface = iface
+ self.iface = iface
self.canvas = self.iface.mapCanvas()
super(LabelTogglingTool, self).__init__(self.canvas)
-
+
def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
self.stackButton = stackButton
- icon_path = iconBasePath + '/toggleAllLabels.png'
+ icon_path = iconBasePath + "/toggleAllLabels.png"
toolTip = self.tr("DSGTools: Toggle all labels visibility")
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Toggle all labels visibility'),
- callback=partial(self.run, mode=LabelTogglingTool.AllLayers, iface=self.iface),
+ text=self.tr("DSGTools: Toggle all labels visibility"),
+ callback=partial(
+ self.run, mode=LabelTogglingTool.AllLayers, iface=self.iface
+ ),
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=self.stackButton,
- isCheckable=False
+ isCheckable=False,
)
self.setAction(action)
self.stackButton.setDefaultAction(action)
- icon_path = iconBasePath + '/toggleSelectedLayersLabel.png'
+ icon_path = iconBasePath + "/toggleSelectedLayersLabel.png"
toolTip = self.tr("DSGTools: Toggle selected layers' labels visibility")
action = manager.add_action(
icon_path,
text=self.tr("DSGTools: Toggle selected layers' label visibility"),
- callback=partial(self.run, mode=LabelTogglingTool.SelectedLayers, iface=self.iface),
+ callback=partial(
+ self.run, mode=LabelTogglingTool.SelectedLayers, iface=self.iface
+ ),
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=self.stackButton,
- isCheckable=False
+ isCheckable=False,
)
- self.setAction(action)
+ self.setAction(action)
- icon_path = iconBasePath + '/toggleActiveLayerLabel.png'
+ icon_path = iconBasePath + "/toggleActiveLayerLabel.png"
toolTip = self.tr("DSGTools: Toggle active layer' label visibility")
action = manager.add_action(
icon_path,
text=self.tr("DSGTools: Toggle active layer' label visibility"),
- callback=partial(self.run, mode=LabelTogglingTool.ActiveLayer, iface=self.iface),
+ callback=partial(
+ self.run, mode=LabelTogglingTool.ActiveLayer, iface=self.iface
+ ),
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=self.stackButton,
- isCheckable=False
+ isCheckable=False,
)
self.setAction(action)
def setAction(self, action):
self.toolAction = action
-
+
def deactivate(self):
"""
Deactivate tool.
@@ -107,7 +115,7 @@ def run(self, iface, mode=None):
self.stackButton.setDefaultAction(self.sender())
except:
pass
- for lyr in self.getLayers(iface, mode): #ordered layers
+ for lyr in self.getLayers(iface, mode): # ordered layers
if not isinstance(lyr, QgsVectorLayer):
continue
lyr.setLabelsEnabled(not lyr.labelsEnabled())
diff --git a/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py b/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py
index 0cdadc00b..877773b33 100644
--- a/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py
+++ b/DsgTools/gui/ProductionTools/MapTools/SelectRasterTool/selectRaster.py
@@ -29,50 +29,30 @@
class SelectRasterTool(QgsMapTool):
def __init__(self, iface):
self.rasters = []
- self.iface = iface
+ self.iface = iface
self.canvas = self.iface.mapCanvas()
super(SelectRasterTool, self).__init__(self.canvas)
-
+
def addTool(self, manager, callback, parentToolbar, iconBasePath):
- icon_path = iconBasePath + '/selectRaster.png'
+ icon_path = iconBasePath + "/selectRaster.png"
toolTip = self.tr("DSGTools: Select Raster")
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Select Raster'),
+ text=self.tr("DSGTools: Select Raster"),
callback=callback,
add_to_menu=False,
add_to_toolbar=False,
- withShortcut = True,
- tooltip = toolTip,
+ withShortcut=True,
+ tooltip=toolTip,
parentToolbar=parentToolbar,
- isCheckable = True
+ isCheckable=True,
)
self.setAction(action)
-
+
def setAction(self, action):
self.toolAction = action
self.toolAction.setCheckable(True)
-
- # def activate(self):
- # """
- # Activate tool.
- # """
- # if self.toolAction:
- # self.toolAction.setChecked(True)
- # QgsMapTool.activate(self)
-
- # def deactivate(self):
- # """
- # Deactivate tool.
- # """
- # try:
- # if self.toolAction:
- # self.toolAction.setChecked(False)
- # if self is not None:
- # QgsMapTool.deactivate(self)
- # except:
- # pass
-
+
def canvasPressEvent(self, e):
self.run()
@@ -113,7 +93,10 @@ def addRasterMenu(self, menu, rasters):
for raster in rasters:
action = rasterMenu.addAction(raster.name())
action.triggered.connect(lambda b, raster=raster: self.selectOnly(raster))
- # menu.addMenu(rasterMenu)
+ dummyAction = rasterMenu.addAction("")
+ dummyAction.setSeparator(True)
+ action = rasterMenu.addAction(self.tr("Deselect all rasters"))
+ action.triggered.connect(lambda x: self.selectAll(visible=False))
def selectOnly(self, raster):
for otherRaster in self.rasters:
@@ -121,6 +104,13 @@ def selectOnly(self, raster):
otherRaster, otherRaster.id() == raster.id()
)
self.toolAction.setChecked(False)
+
+ def selectAll(self, visible=True):
+ for otherRaster in self.rasters:
+ self.iface.layerTreeView().setLayerVisible(
+ otherRaster, visible
+ )
+ self.toolAction.setChecked(False)
def unload(self):
self.deactivate()
diff --git a/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py b/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py
index d1a1c84f1..e747bf274 100644
--- a/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py
+++ b/DsgTools/gui/ProductionTools/MapTools/ShortcutTool/shortcutTool.py
@@ -27,31 +27,32 @@
from qgis.core import QgsProject, QgsVectorLayer
+
class ShortcutTool(QObject):
def __init__(self, iface):
"""
Hides or show active layers labels.
"""
- self.iface = iface
+ self.iface = iface
super(ShortcutTool, self).__init__()
-
+
def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
self.stackButton = stackButton
- icon_path = iconBasePath + '/on_off.png'
+ icon_path = iconBasePath + "/on_off.png"
toolTip = self.tr("DSGTools: Active Layer visibility")
action = manager.add_action(
icon_path,
- text=self.tr('DSGTools: Active Layer visibility'),
+ text=self.tr("DSGTools: Active Layer visibility"),
callback=self.hideOrShowActiveLayer,
add_to_menu=False,
add_to_toolbar=False,
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
- icon_path = iconBasePath + '/vertex.png'
+ icon_path = iconBasePath + "/vertex.png"
toolTip = self.tr("DSGTools: Toggle vertex's marker visibility")
action = manager.add_action(
icon_path,
@@ -62,7 +63,7 @@ def addTool(self, manager, callback, parentToolbar, stackButton, iconBasePath):
withShortcut=True,
tooltip=toolTip,
parentButton=stackButton,
- isCheckable=False
+ isCheckable=False,
)
def hideOrShowMarkers(self):
@@ -71,8 +72,8 @@ def hideOrShowMarkers(self):
except:
pass
qSettings = QSettings()
- currentState = qSettings.value(u'qgis/digitizing/marker_only_for_selected')
- qSettings.setValue(u'qgis/digitizing/marker_only_for_selected', not currentState)
+ currentState = qSettings.value("qgis/digitizing/marker_only_for_selected")
+ qSettings.setValue("qgis/digitizing/marker_only_for_selected", not currentState)
self.iface.mapCanvas().refresh()
def hideOrShowActiveLayer(self):
@@ -83,8 +84,9 @@ def hideOrShowActiveLayer(self):
activeLayer = self.iface.activeLayer()
layerTreeRoot = QgsProject.instance().layerTreeRoot()
layerVisibilityState = activeLayer in layerTreeRoot.checkedLayers()
- layerTreeRoot.findLayer(activeLayer.id()).setItemVisibilityChecked(not layerVisibilityState)
-
+ layerTreeRoot.findLayer(activeLayer.id()).setItemVisibilityChecked(
+ not layerVisibilityState
+ )
+
def unload(self):
pass
-
diff --git a/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py b/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py
index dbed4d8a4..44d89a87d 100644
--- a/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py
+++ b/DsgTools/gui/ProductionTools/MapTools/mapToolsGuiManager.py
@@ -25,7 +25,9 @@
import os.path
import sys
from DsgTools.gui.ProductionTools.MapTools.AuxTools.spatialFilter import SpatialFilter
-from DsgTools.gui.ProductionTools.MapTools.SelectRasterTool.selectRaster import SelectRasterTool
+from DsgTools.gui.ProductionTools.MapTools.SelectRasterTool.selectRaster import (
+ SelectRasterTool,
+)
from qgis.PyQt.QtCore import pyqtSignal
from qgis.core import QgsVectorLayer
@@ -41,83 +43,140 @@
from .AuxTools.otherTools import OtherTools
from qgis.PyQt.QtCore import QObject
+
class MapToolsGuiManager(QObject):
# signals to replicate current layer's editing started/stopped signal
editingStarted = pyqtSignal()
editingStopped = pyqtSignal()
- def __init__(self, manager, iface, parentMenu = None, toolbar = None):
- """Constructor.
- """
+ def __init__(self, manager, iface, parentMenu=None, toolbar=None):
+ """Constructor."""
super(MapToolsGuiManager, self).__init__()
self.manager = manager
self.iface = iface
self.parentMenu = parentMenu
self.toolbar = toolbar
- self.toolbar_extra = self.iface.addToolBar(u'DsgTools_ExtraTools')
- self.toolbar_extra.setObjectName(u'DsgTools_ExtraTools')
- self.iconBasePath = ':/plugins/DsgTools/icons/'
+ self.toolbar_extra = self.iface.addToolBar("DsgTools_ExtraTools")
+ self.toolbar_extra.setObjectName("DsgTools_ExtraTools")
+ self.iconBasePath = ":/plugins/DsgTools/icons/"
# initiate current layer and make sure signals are connected
self.currentLayer = None
self.resetCurrentLayerSignals()
self.iface.currentLayerChanged.connect(self.resetCurrentLayerSignals)
def initGui(self):
- #adding generic selection tool
+ # adding generic selection tool
self.genericTool = GenericSelectionTool(self.iface)
- self.genericTool.addTool(self.manager, self.activateGenericTool, self.parentMenu, self.iconBasePath)
- #adding flip line tool
+ self.genericTool.addTool(
+ self.manager, self.activateGenericTool, self.parentMenu, self.iconBasePath
+ )
+ # adding flip line tool
self.flipLineTool = FlipLine(self.iface)
- self.flipLineTool.addTool(self.manager, self.flipLineTool.startFlipLineTool, self.parentMenu, self.iconBasePath)
+ self.flipLineTool.addTool(
+ self.manager,
+ self.flipLineTool.startFlipLineTool,
+ self.parentMenu,
+ self.iconBasePath,
+ )
self.flipLineTool.setToolEnabled(self.iface.mapCanvas().currentLayer())
- #adding acquisition
+ # adding acquisition
self.acquisition = Acquisition(self.iface)
self.acquisition.addTool(self.manager, None, self.parentMenu, self.iconBasePath)
self.acquisition.setToolEnabled()
- #adding stack
- self.freeHandStackButton = self.manager.createToolButton(self.toolbar, u'FreeHandTools')
- #adding free hand tool (acquisition)
+ # adding stack
+ self.freeHandStackButton = self.manager.createToolButton(
+ self.toolbar, "FreeHandTools"
+ )
+ # adding free hand tool (acquisition)
self.freeHandAcquisiton = FreeHandMain(self.iface)
- self.freeHandAcquisiton.addTool(self.manager, None, self.parentMenu, self.iconBasePath, parentButton=self.freeHandStackButton, defaultButton=True)
+ self.freeHandAcquisiton.addTool(
+ self.manager,
+ None,
+ self.parentMenu,
+ self.iconBasePath,
+ parentButton=self.freeHandStackButton,
+ defaultButton=True,
+ )
self.freeHandAcquisiton.acquisitionFreeController.setToolEnabled()
- #adding free hand tool (acquisition)
+ # adding free hand tool (acquisition)
self.freeHandReshape = FreeHandReshape(self.iface)
- self.freeHandReshape.addTool(self.manager, None, self.parentMenu, self.iconBasePath, parentButton=self.freeHandStackButton)
+ self.freeHandReshape.addTool(
+ self.manager,
+ None,
+ self.parentMenu,
+ self.iconBasePath,
+ parentButton=self.freeHandStackButton,
+ )
self.freeHandReshape.acquisitionFreeController.setToolEnabled()
- #adding select raster
- self.labelStackButton = self.manager.createToolButton(self.toolbar_extra, u'LabelTools')
+ # adding select raster
+ self.labelStackButton = self.manager.createToolButton(
+ self.toolbar_extra, "LabelTools"
+ )
self.rasterSelectTool = SelectRasterTool(self.iface)
- self.rasterSelectTool.addTool(self.manager, self.rasterSelectTool.run, self.labelStackButton, self.iconBasePath)
- #adding label toggling tool
+ self.rasterSelectTool.addTool(
+ self.manager,
+ self.rasterSelectTool.run,
+ self.labelStackButton,
+ self.iconBasePath,
+ )
+ # adding label toggling tool
self.labelTool = LabelTogglingTool(self.iface)
- self.labelTool.addTool(self.manager, None, self.toolbar_extra, self.labelStackButton, self.iconBasePath)
- #adding shortcuts tools
+ self.labelTool.addTool(
+ self.manager,
+ None,
+ self.toolbar_extra,
+ self.labelStackButton,
+ self.iconBasePath,
+ )
+ # adding shortcuts tools
self.shortcutsTool = ShortcutTool(self.iface)
- self.shortcutsTool.addTool(self.manager, None, self.toolbar_extra, self.labelStackButton, self.iconBasePath)
+ self.shortcutsTool.addTool(
+ self.manager,
+ None,
+ self.toolbar_extra,
+ self.labelStackButton,
+ self.iconBasePath,
+ )
- self.filterStackButton = self.manager.createToolButton(self.toolbar_extra, u'FilterTools')
- self.spatialFilterTool = SpatialFilter()
+ self.filterStackButton = self.manager.createToolButton(
+ self.toolbar_extra, "FilterTools"
+ )
+ self.spatialFilterTool = SpatialFilter(
+ stackButton=self.filterStackButton
+ )
action = self.manager.add_action(
- icon_path=self.iconBasePath + 'spatialFilter.png',
+ icon_path=self.iconBasePath + "spatialFilter.png",
text=self.tr("DSGTools: Spatial Filter"),
callback=self.spatialFilterTool.start,
add_to_toolbar=False,
parentButton=self.filterStackButton,
- withShortcut=True
+ withShortcut=True,
)
self.filterStackButton.setDefaultAction(action)
self.filterTool = FilterTools(self.iface)
- self.filterTool.addTool(self.manager, None, self.toolbar_extra, self.filterStackButton, self.iconBasePath)
+ self.filterTool.addTool(
+ self.manager,
+ None,
+ self.toolbar_extra,
+ self.filterStackButton,
+ self.iconBasePath,
+ )
- self.otherToolsStackButton = self.manager.createToolButton(self.toolbar_extra, u'OtherTools')
+ self.otherToolsStackButton = self.manager.createToolButton(
+ self.toolbar_extra, "OtherTools"
+ )
self.otherTools = OtherTools(self.iface)
- self.otherTools.addTool(self.manager, None, self.toolbar_extra, self.otherToolsStackButton, self.iconBasePath)
-
+ self.otherTools.addTool(
+ self.manager,
+ None,
+ self.toolbar_extra,
+ self.otherToolsStackButton,
+ self.iconBasePath,
+ )
- #initiate tools signals
+ # initiate tools signals
self.initiateToolsSignals()
-
def resetCurrentLayerSignals(self):
"""
@@ -140,8 +199,12 @@ def initiateToolsSignals(self):
"""
Connects all tools' signals.
"""
- for tool in [self.flipLineTool, self.acquisition, self.freeHandAcquisiton.acquisitionFreeController, \
- self.freeHandReshape.acquisitionFreeController]:
+ for tool in [
+ self.flipLineTool,
+ self.acquisition,
+ self.freeHandAcquisiton.acquisitionFreeController,
+ self.freeHandReshape.acquisitionFreeController,
+ ]:
# connect current layer changed signal to all tools that use it
self.iface.currentLayerChanged.connect(tool.setToolEnabled)
# connect editing started/stopped signals to all tools that use it
@@ -151,16 +214,19 @@ def initiateToolsSignals(self):
self.iface.actionToggleEditing().triggered.connect(tool.setToolEnabled)
# free hand has its own signal connected when started
for free_hand_tool in [self.freeHandAcquisiton, self.freeHandReshape]:
- free_hand_tool.acquisitionFreeController.actionAcquisitionFree.triggered.connect(\
- free_hand_tool.acquisitionFreeController.activateTool)
- free_hand_tool.acquisitionFreeController.acquisitionFree.acquisitionFinished.connect(\
- free_hand_tool.acquisitionFreeController.createFeature)
- free_hand_tool.acquisitionFreeController.acquisitionFree.reshapeLineCreated.connect(\
- free_hand_tool.acquisitionFreeController.reshapeSimplify)
+ free_hand_tool.acquisitionFreeController.actionAcquisitionFree.triggered.connect(
+ free_hand_tool.acquisitionFreeController.activateTool
+ )
+ free_hand_tool.acquisitionFreeController.acquisitionFree.acquisitionFinished.connect(
+ free_hand_tool.acquisitionFreeController.createFeature
+ )
+ free_hand_tool.acquisitionFreeController.acquisitionFree.reshapeLineCreated.connect(
+ free_hand_tool.acquisitionFreeController.reshapeSimplify
+ )
def activateGenericTool(self):
self.iface.mapCanvas().setMapTool(self.genericTool)
-
+
def activateRasterSelectTool(self):
self.iface.mapCanvas().setMapTool(self.rasterSelectTool)
@@ -169,4 +235,3 @@ def unload(self):
self.rasterSelectTool.unload()
self.iface.mainWindow().removeToolBar(self.toolbar_extra)
del self.toolbar_extra
-
diff --git a/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py b/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py
index b318bd9f8..220ca3a63 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/DataValidationTool/dataValidationTool.py
@@ -22,19 +22,17 @@
import processing
from processing.modeler.ModelerUtils import ModelerUtils
-from qgis.core import (QgsProject,
- QgsMapLayer,
- QgsProcessingModelAlgorithm,
- QgsProcessingContext,
- QgsProcessingFeedback,
- QgsLayerTreeLayer,
- QgsMessageLog,
- Qgis)
-from qgis.PyQt.QtWidgets import (QApplication,
- QWidget,
- QMessageBox,
- QFileDialog,
- QAction)
+from qgis.core import (
+ QgsProject,
+ QgsMapLayer,
+ QgsProcessingModelAlgorithm,
+ QgsProcessingContext,
+ QgsProcessingFeedback,
+ QgsLayerTreeLayer,
+ QgsMessageLog,
+ Qgis,
+)
+from qgis.PyQt.QtWidgets import QApplication, QWidget, QMessageBox, QFileDialog, QAction
from qgis.PyQt.QtGui import QCursor, QIcon
from qgis.PyQt import uic
from qgis.PyQt.QtCore import pyqtSlot, pyqtSignal, Qt
@@ -42,16 +40,18 @@
from DsgTools.gui.AboutAndFurtherInfo.Options.options import Options
FORM_CLASS, _ = uic.loadUiType(
- os.path.join(os.path.dirname(__file__), 'dataValidationTool.ui')
+ os.path.join(os.path.dirname(__file__), "dataValidationTool.ui")
)
+
class DataValidationTool(QWidget, FORM_CLASS):
"""
Toolbar for fast usage of processing methods. It is assumed that the models
- have all of its child algorithm's variable's well defined and the only
- variables expected on input are the output layers, whenever needed and as
- many as it may be.
+ have all of its child algorithm's variable's well defined and the only
+ variables expected on input are the output layers, whenever needed and as
+ many as it may be.
"""
+
__dsgToolsModelPath__ = os.path.join(
os.path.dirname(__file__), "..", "..", "..", "..", "core", "Misc", "QGIS_Models"
)
@@ -89,7 +89,7 @@ def _widgets(self):
self.addModelPushButton,
self.removeModelPushButton,
self.runModelPushButton,
- self.splitter
+ self.splitter,
]
def options(self):
@@ -133,12 +133,12 @@ def resetModelList(self):
self.modelComboBox.addItem(self.tr("Select a model..."))
models = []
for file_ in os.listdir(self.defaultModelPath()):
- if file_.endswith('.model') or file_.endswith('.model3'):
+ if file_.endswith(".model") or file_.endswith(".model3"):
models.append(file_)
if models:
self.modelComboBox.addItems(models)
- @pyqtSlot(bool, name='on_validationPushButton_toggled')
+ @pyqtSlot(bool, name="on_validationPushButton_toggled")
def activateTool(self, toggled=None):
"""
Shows/hides the toolbar.
@@ -159,15 +159,22 @@ def confirmAction(self, msg, showCancel=True):
:return: (bool) whether action was confirmed.
"""
if showCancel:
- return QMessageBox.question(
- self, self.tr('Confirm Action'), msg,
- QMessageBox.Ok|QMessageBox.Cancel
- ) == QMessageBox.Ok
+ return (
+ QMessageBox.question(
+ self,
+ self.tr("Confirm Action"),
+ msg,
+ QMessageBox.Ok | QMessageBox.Cancel,
+ )
+ == QMessageBox.Ok
+ )
else:
- return QMessageBox.question(
- self, self.tr('Confirm Action'), msg,
- QMessageBox.Ok
- ) == QMessageBox.Ok
+ return (
+ QMessageBox.question(
+ self, self.tr("Confirm Action"), msg, QMessageBox.Ok
+ )
+ == QMessageBox.Ok
+ )
def modelExists(self, modelName):
"""
@@ -191,7 +198,7 @@ def setActiveModel(self, modelName):
return True
return False
- @pyqtSlot(int, name='on_modelComboBox_currentIndexChanged')
+ @pyqtSlot(int, name="on_modelComboBox_currentIndexChanged")
def modelIsValid(self, idx):
"""
Checks if a model is valid and sets GUI buttons enabled if so.
@@ -226,7 +233,7 @@ def addLayerToGroup(self, layer, groupname, subgroupname=None):
QgsProject.instance().addMapLayer(layer, False)
subgroup.insertChildNode(1, QgsLayerTreeLayer(layer))
- @pyqtSlot(bool, name='on_updatePushButton_clicked')
+ @pyqtSlot(bool, name="on_updatePushButton_clicked")
def updateModelList(self):
"""
Checks current default path for models and refreshes current displayed
@@ -238,7 +245,7 @@ def updateModelList(self):
self.setActiveModel(currentModel)
QApplication.restoreOverrideCursor()
- @pyqtSlot(bool, name='on_addModelPushButton_clicked')
+ @pyqtSlot(bool, name="on_addModelPushButton_clicked")
def registerModel(self, modelPath=None):
"""
Registers a model to the model runner. This application register all
@@ -248,23 +255,22 @@ def registerModel(self, modelPath=None):
if modelPath is None or not isinstance(modelPath, str):
fd = QFileDialog()
modelPathList = fd.getOpenFileNames(
- caption=self.tr('Select a QGIS processing model to be added'),
- filter=self.tr('QGIS Processing Model (*.model *.model3)')
+ caption=self.tr("Select a QGIS processing model to be added"),
+ filter=self.tr("QGIS Processing Model (*.model *.model3)"),
)
modelPathList = modelPathList[0] if modelPathList else modelPathList
if modelPathList == []:
return
msg = self.tr(
- "Model seems to be already registered, would you like to overwrite"
- " it?"
+ "Model seems to be already registered, would you like to overwrite" " it?"
)
for modelPath in modelPathList:
modelName = os.path.basename(modelPath)
if self.modelExists(modelName) and not self.confirmAction(msg):
QgsMessageLog.logMessage(
self.tr("Model {model} was not imported.").format(model=modelName),
- 'DSGTools Plugin',
- Qgis.Info
+ "DSGTools Plugin",
+ Qgis.Info,
)
return
dest = os.path.join(self.defaultModelPath(), modelName)
@@ -275,16 +281,17 @@ def registerModel(self, modelPath=None):
self.setActiveModel(modelName)
self.modelAdded.emit(modelName)
QgsMessageLog.logMessage(
- self.tr("Model {model} imported to {dest}.").format(model=modelName, dest=dest),
- 'DSGTools Plugin',
- Qgis.Info
+ self.tr("Model {model} imported to {dest}.").format(
+ model=modelName, dest=dest
+ ),
+ "DSGTools Plugin",
+ Qgis.Info,
)
-
- @pyqtSlot(bool, name='on_removeModelPushButton_clicked')
+ @pyqtSlot(bool, name="on_removeModelPushButton_clicked")
def unregisterModel(self, modelName=None):
"""
- Unregisters a model to the model runner. Removes the model from the
+ Unregisters a model to the model runner. Removes the model from the
default directory.
:param modelName: (str) basename for the model to be removed.
"""
@@ -300,7 +307,9 @@ def unregisterModel(self, modelName=None):
try:
os.remove(modelPath)
if not os.path.exists(modelPath):
- self.modelComboBox.removeItem(self.modelComboBox.findText(modelName))
+ self.modelComboBox.removeItem(
+ self.modelComboBox.findText(modelName)
+ )
self.modelRemoved.emit(modelName)
except Exception as e:
msg = self.tr("Unable to remove '{model}':\n{error}.").format(
@@ -308,7 +317,7 @@ def unregisterModel(self, modelName=None):
)
self.confirmAction(msg, showCancel=False)
- @pyqtSlot(bool, name='on_runModelPushButton_clicked')
+ @pyqtSlot(bool, name="on_runModelPushButton_clicked")
def runModel(self, modelName=None):
"""
Executes chosen model, if possible.
@@ -325,36 +334,38 @@ def runModel(self, modelName=None):
if not self.modelExists(modelName):
# if model was manually removed and combo box was not refreshed
self.iface.messageBar().pushMessage(
- self.tr('Failed'),
- self.tr("model {model} seems to have been deleted.").format(model=modelName),
+ self.tr("Failed"),
+ self.tr("model {model} seems to have been deleted.").format(
+ model=modelName
+ ),
level=Qgis.Critical,
- duration=5
+ duration=5,
)
return
alg.fromFile(modelPath)
alg.initAlgorithm()
# as this tool assumes that every parameter is pre-set, only output shall
# be passed on - ALL outputs from this tool is set to memory layers.
- param = {vl.name() : "memory:" for vl in alg.parameterDefinitions()}
+ param = {vl.name(): "memory:" for vl in alg.parameterDefinitions()}
msg = self.tr("Would you like to run {model}").format(model=modelName)
if self.options()["checkBeforeRunModel"] and not self.confirmAction(msg):
return
try:
out = processing.run(alg, param)
self.iface.messageBar().pushMessage(
- self.tr('Sucess'),
+ self.tr("Sucess"),
self.tr("model {model} finished.").format(model=modelName),
level=Qgis.Info,
- duration=5
+ duration=5,
)
QgsMessageLog.logMessage(
- self.tr(
- "Model {model} finished running with no errors. You may"
- " check model output on Processing log tab."
- ).format(model=modelName),
- 'DSGTools Plugin',
- Qgis.Info
- )
+ self.tr(
+ "Model {model} finished running with no errors. You may"
+ " check model output on Processing log tab."
+ ).format(model=modelName),
+ "DSGTools Plugin",
+ Qgis.Info,
+ )
if not self.options()["loadModelOutput"]:
return
for var, value in out.items():
@@ -371,12 +382,12 @@ def runModel(self, modelName=None):
"execution log) {model}:\n{error}"
).format(model=modelName, error=str(e))
self.iface.messageBar().pushMessage(
- self.tr("Model {model} failed").format(model=modelName),
+ self.tr("Model {model} failed").format(model=modelName),
self.tr("check log for more information."),
level=Qgis.Critical,
- duration=5
+ duration=5,
)
- QgsMessageLog.logMessage(msg, 'DSGTools Plugin',Qgis.Info)
+ QgsMessageLog.logMessage(msg, "DSGTools Plugin", Qgis.Info)
def unload(self):
"""
@@ -390,18 +401,18 @@ def unload(self):
for w in self._widgets():
w.blockSignals(True)
del w
- self.iface.unregisterMainWindowAction(self.runAction)
+ self.iface.unregisterMainWindowAction(self.runAction)
def addShortcut(self):
"""
Adds the action to main menu allowing QGIS to assign a shortcut for run.
"""
self.runAction = QAction(
- QIcon(':/plugins/DsgTools/icons/runModel.png'),
- self.tr('DSGTools: Validation Toolbar - Run Processing Model'),
- self.parent
+ QIcon(":/plugins/DsgTools/icons/runModel.png"),
+ self.tr("DSGTools: Validation Toolbar - Run Processing Model"),
+ self.parent,
)
self.runAction.triggered.connect(self.runModel)
if self.parent:
self.parent.addAction(self.runAction)
- self.iface.registerMainWindowAction(self.runAction, '')
+ self.iface.registerMainWindowAction(self.runAction, "")
diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py
index 13f60813d..5116bf031 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/assignBandValueTool.py
@@ -23,12 +23,28 @@
from functools import partial
-from qgis.gui import QgsMapTool, QgsRubberBand, QgsMapToolEmitPoint, \
- QgsAttributeDialog, QgsAttributeForm, QgsMessageBar
+from qgis.gui import (
+ QgsMapTool,
+ QgsRubberBand,
+ QgsMapToolEmitPoint,
+ QgsAttributeDialog,
+ QgsAttributeForm,
+ QgsMessageBar,
+)
from qgis import core
-from qgis.core import QgsPointXY, QgsRectangle, QgsVectorLayer, QgsGeometry, \
- QgsEditFormConfig, QgsRaster, QgsFeature, QgsWkbTypes, \
- QgsProject, QgsVectorLayerUtils, Qgis
+from qgis.core import (
+ QgsPointXY,
+ QgsRectangle,
+ QgsVectorLayer,
+ QgsGeometry,
+ QgsEditFormConfig,
+ QgsRaster,
+ QgsFeature,
+ QgsWkbTypes,
+ QgsProject,
+ QgsVectorLayerUtils,
+ Qgis,
+)
from qgis.PyQt.QtCore import QSettings
from qgis.PyQt import QtCore, QtGui
from qgis.PyQt.QtGui import QColor, QCursor
@@ -37,15 +53,16 @@
from qgis.PyQt.QtCore import Qt
from DsgTools.core.GeometricTools.geometryHandler import GeometryHandler
+
class AssignBandValueTool(QgsMapTool):
def __init__(self, iface, rasterLayer):
"""
Tool Behaviours: (all behaviours start edition, except for rectangle one)
- 1- Left Click: Creates a new point feature with the value from raster, according to selected attribute.
- 5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangle are selected
+ 1- Left Click: Creates a new point feature with the value from raster, according to selected attribute.
+ 5- Shift + drag and drop: draws a rectangle, then features that intersect this rectangle are selected
and their value is set according to raster value and selected attribute.
"""
- self.iface = iface
+ self.iface = iface
self.canvas = self.iface.mapCanvas()
QgsMapTool.__init__(self, self.canvas)
self.toolAction = None
@@ -59,28 +76,28 @@ def __init__(self, iface, rasterLayer):
def getDecimals(self):
settings = QSettings()
- settings.beginGroup('PythonPlugins/DsgTools/Options')
- decimals = settings.value('decimals')
+ settings.beginGroup("PythonPlugins/DsgTools/Options")
+ decimals = settings.value("decimals")
if decimals:
return int(decimals)
else:
return 0
-
+
def getSuppressOptions(self):
qgisSettings = QSettings()
- qgisSettings.beginGroup('qgis/digitizing')
- setting = qgisSettings.value('disable_enter_attribute_values_dialog')
+ qgisSettings.beginGroup("qgis/digitizing")
+ setting = qgisSettings.value("disable_enter_attribute_values_dialog")
qgisSettings.endGroup()
return setting
def setRubberbandParameters(self):
self.rubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
self.hoverRubberBand = QgsRubberBand(self.canvas, QgsWkbTypes.PolygonGeometry)
- mFillColor = QColor( 254, 178, 76, 63 )
+ mFillColor = QColor(254, 178, 76, 63)
self.rubberBand.setColor(mFillColor)
- self.hoverRubberBand.setColor(QColor( 255, 0, 0, 90 ))
+ self.hoverRubberBand.setColor(QColor(255, 0, 0, 90))
self.rubberBand.setWidth(1)
-
+
def reset(self):
"""
Resets rubber band.
@@ -109,8 +126,8 @@ def canvasMoveEvent(self, e):
"""
if not self.isEmittingPoint:
return
- self.endPoint = self.toMapCoordinates( e.pos() )
- self.showRect(self.startPoint, self.endPoint)
+ self.endPoint = self.toMapCoordinates(e.pos())
+ self.showRect(self.startPoint, self.endPoint)
def showRect(self, startPoint, endPoint):
"""
@@ -123,11 +140,11 @@ def showRect(self, startPoint, endPoint):
point2 = QgsPointXY(startPoint.x(), endPoint.y())
point3 = QgsPointXY(endPoint.x(), endPoint.y())
point4 = QgsPointXY(endPoint.x(), startPoint.y())
-
+
self.rubberBand.addPoint(point1, False)
self.rubberBand.addPoint(point2, False)
self.rubberBand.addPoint(point3, False)
- self.rubberBand.addPoint(point4, True) # true to update canvas
+ self.rubberBand.addPoint(point4, True) # true to update canvas
self.rubberBand.show()
def rectangle(self):
@@ -136,19 +153,22 @@ def rectangle(self):
"""
if self.startPoint is None or self.endPoint is None:
return None
- elif self.startPoint.x() == self.endPoint.x() or self.startPoint.y() == self.endPoint.y():
+ elif (
+ self.startPoint.x() == self.endPoint.x()
+ or self.startPoint.y() == self.endPoint.y()
+ ):
return None
return QgsRectangle(self.startPoint, self.endPoint)
def setAction(self, action):
self.toolAction = action
self.toolAction.setCheckable(True)
-
+
def canvasReleaseEvent(self, e):
"""
After the rectangle is built, here features are selected.
"""
- # tool was planned to work on left click
+ # tool was planned to work on left click
if e.button() == QtCore.Qt.LeftButton:
layer = self.iface.mapCanvas().currentLayer()
if QApplication.keyboardModifiers() == QtCore.Qt.ShiftModifier:
@@ -158,25 +178,29 @@ def canvasReleaseEvent(self, e):
return
bbRect = self.canvas.mapSettings().mapToLayerCoordinates(layer, r)
self.rubberBand.hide()
- #select all stuff
- layer.selectByIds([]) #portar para o feature handler
+ # select all stuff
+ layer.selectByIds([]) # portar para o feature handler
layer.selectByRect(bbRect)
- #mudar depois para o dsgmothafucka
+ # mudar depois para o dsgmothafucka
featDict = dict()
pointDict = dict()
for feat in layer.selectedFeatures():
featDict[feat.id()] = feat
pointDict[feat.id()] = feat.geometry()
- pixelValueDict = self.getPixelValueFromPointDict(pointDict, self.rasterLayer)
+ pixelValueDict = self.getPixelValueFromPointDict(
+ pointDict, self.rasterLayer
+ )
for idx in pointDict:
value = pixelValueDict[idx]
if value:
- self.auxList.append({'featId':idx, 'feat':featDict[idx], 'value':value})
+ self.auxList.append(
+ {"featId": idx, "feat": featDict[idx], "value": value}
+ )
else:
value, pointGeom = self.getPixelValue(self.rasterLayer)
if value:
- self.auxList.append({'geom':pointGeom, 'value':value})
- #create context menu to select attribute
+ self.auxList.append({"geom": pointGeom, "value": value})
+ # create context menu to select attribute
if self.auxList:
self.createContextMenuOnPosition(e, layer)
self.iface.mapCanvas().currentLayer().triggerRepaint()
@@ -190,34 +214,38 @@ def createContextMenuOnPosition(self, e, layer):
callback = partial(self.handleFeatures, field, layer)
action.triggered.connect(callback)
menu.exec_(self.canvas.viewport().mapToGlobal(e.pos()))
-
+
def handleFeatures(self, selectedField, layer):
layer.startEditing()
for item in self.auxList:
- if 'featId' in item:
- feat = item['feat']
+ if "featId" in item:
+ feat = item["feat"]
idx = feat.fieldNameIndex(selectedField)
- feat.setAttribute(idx, item['value'])
+ feat.setAttribute(idx, item["value"])
layer.updateFeature(feat)
else:
- self.geometryHandler.reprojectFeature(item['geom'], layer.crs())
- feature = QgsVectorLayerUtils.createFeature(layer, item['geom'])
- self.addFeature(feature, layer, selectedField, item['value'])
+ self.geometryHandler.reprojectFeature(item["geom"], layer.crs())
+ feature = QgsVectorLayerUtils.createFeature(layer, item["geom"])
+ self.addFeature(feature, layer, selectedField, item["value"])
self.auxList = []
self.canvas.refresh()
-
+
def addFeature(self, feature, layer, field, pointValue):
- fields = layer.fields()
- provider = layer.dataProvider()
+ fields = layer.fields()
+ provider = layer.dataProvider()
for i in range(fields.count()):
- value = provider.defaultValue(i) if fields[i].name() != field else pointValue
+ value = (
+ provider.defaultValue(i) if fields[i].name() != field else pointValue
+ )
if value is not None:
- feature.setAttribute(i, value)
+ feature.setAttribute(i, value)
form = QgsAttributeDialog(layer, feature, False)
form.setMode(int(QgsAttributeForm.AddFeatureMode))
formSuppress = layer.editFormConfig().suppress()
if formSuppress == QgsEditFormConfig.SuppressDefault:
- if self.getSuppressOptions(): #this is calculated every time because user can switch options while using tool
+ if (
+ self.getSuppressOptions()
+ ): # this is calculated every time because user can switch options while using tool
layer.addFeature(feature)
else:
if not form.exec_():
@@ -234,8 +262,8 @@ def getCursorRect(self, e):
"""
p = self.toMapCoordinates(e.pos())
w = self.canvas.mapUnitsPerPixel() * 10
- return QgsRectangle(p.x()-w, p.y()-w, p.x()+w, p.y()+w)
-
+ return QgsRectangle(p.x() - w, p.y() - w, p.x() + w, p.y() + w)
+
def deactivate(self):
"""
Deactivate tool.
@@ -261,7 +289,12 @@ def activate(self):
# self.iface.mapCanvas().setMapTool(self)
layer = self.iface.mapCanvas().currentLayer()
if not layer or not isinstance(layer, QgsVectorLayer):
- self.iface.messageBar().pushMessage(self.tr("Warning"), self.tr("Select a point vector layer as the active layer"), level=Qgis.Warning, duration=5)
+ self.iface.messageBar().pushMessage(
+ self.tr("Warning"),
+ self.tr("Select a point vector layer as the active layer"),
+ level=Qgis.Warning,
+ duration=5,
+ )
self.deactivate()
def getPixelValue(self, rasterLayer):
@@ -270,30 +303,41 @@ def getPixelValue(self, rasterLayer):
return self.getPixelValueFromPoint(mousePosGeom, rasterLayer), mousePosGeom
def getPixelValueFromPoint(self, mousePosGeom, rasterLayer, fromCanvas=True):
- """
-
- """
+ """ """
rasterCrs = rasterLayer.crs()
# if fromCanvas:
# self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, QgsProject.instance().crs())
# else:
mousePosGeom = QgsGeometry(mousePosGeom)
- self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, self.canvas.currentLayer().crs())
- mousePos = mousePosGeom.asMultiPoint()[0] if mousePosGeom.isMultipart() else mousePosGeom.asPoint()
+ self.geometryHandler.reprojectFeature(
+ geom=mousePosGeom,
+ destinationCrs=self.canvas.currentLayer().crs(),
+ referenceCrs=rasterCrs,
+ )
+ mousePos = (
+ mousePosGeom.asMultiPoint()[0]
+ if mousePosGeom.isMultipart()
+ else mousePosGeom.asPoint()
+ )
# identify pixel(s) information
- i = rasterLayer.dataProvider().identify( mousePos, QgsRaster.IdentifyFormatValue )
+ i = rasterLayer.dataProvider().identify(mousePos, QgsRaster.IdentifyFormatValue)
if i.isValid():
value = list(i.results().values())[0]
if value:
- value = int(value) if self.decimals == 0 else round(value, self.decimals)
+ value = (
+ int(value) if self.decimals == 0 else round(value, self.decimals)
+ )
return value
else:
return None
-
+
def getPixelValueFromPointDict(self, pointDict, rasterLayer):
"""
pointDict = {'pointId':QgsGeometry}
returns {'pointId': value}
"""
- return {key : self.getPixelValueFromPoint(value, rasterLayer, fromCanvas=False) for key, value in pointDict.items()} #no python3 eh items()
+ return {
+ key: self.getPixelValueFromPoint(value, rasterLayer, fromCanvas=False)
+ for key, value in pointDict.items()
+ } # no python3 eh items()
diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py
index d483870a2..f3652c667 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/bandValueTool.py
@@ -30,6 +30,7 @@
from .....core.GeometricTools.geometryHandler import GeometryHandler
+
class BandValueTool(QgsMapTool):
"""
This class is supposed to help revision operators. It shows, on mouse hovering
@@ -39,6 +40,7 @@ class BandValueTool(QgsMapTool):
2- On mouse click: create a new instance of desired layer (filled on config).
* behaviour 2 is an extrapolation of first conception
"""
+
def __init__(self, iface, parent):
"""
Class constructor.
@@ -51,15 +53,13 @@ def __init__(self, iface, parent):
self.toolAction = None
self.QgsMapToolEmitPoint = QgsMapToolEmitPoint(self.canvas)
self.geometryHandler = GeometryHandler(iface)
- self.timerMapTips = QTimer( self.canvas )
- self.timerMapTips.timeout.connect( self.showToolTip )
+ self.timerMapTips = QTimer(self.canvas)
+ self.timerMapTips.timeout.connect(self.showToolTip)
self.activated = False
self.canvasCrs = self.canvas.mapRenderer().destinationCrs()
-
+
def setAction(self, action):
- """
-
- """
+ """ """
self.toolAction = action
def activate(self):
@@ -70,7 +70,7 @@ def activate(self):
self.activated = True
QgsMapTool.activate(self)
self.canvas.setMapTool(self)
-
+
def deactivate(self):
"""
Deactivates tool.
@@ -83,38 +83,36 @@ def deactivate(self):
if self is not None:
QgsMapTool.deactivate(self)
except:
- pass
+ pass
def canvasMoveEvent(self, e):
QToolTip.hideText()
- self.timerMapTips.start( 500 ) # time in milliseconds
- self.showToolTip()
-
+ self.timerMapTips.start(500) # time in milliseconds
+ self.showToolTip()
+
def getPixelValue(self, rasterLayer):
- """
-
- """
+ """ """
rasterCrs = rasterLayer.crs()
mousePos = self.QgsMapToolEmitPoint.toMapCoordinates(self.canvas.mouseLastXY())
mousePosGeom = QgsGeometry.fromPoint(mousePos)
self.geometryHandler.reprojectFeature(mousePosGeom, rasterCrs, self.canvasCrs)
mousePos = mousePosGeom.asPoint()
# identify pixel(s) information
- i = rasterLayer.dataProvider().identify( mousePos, QgsRaster.IdentifyFormatValue )
+ i = rasterLayer.dataProvider().identify(mousePos, QgsRaster.IdentifyFormatValue)
if i.isValid():
- text = ", ".join(['{0:g}'.format(r) for r in list(i.results().values()) if r is not None] )
+ text = ", ".join(
+ ["{0:g}".format(r) for r in list(i.results().values()) if r is not None]
+ )
else:
text = ""
return text
def showToolTip(self):
- """
-
- """
+ """ """
self.timerMapTips.stop()
if self.canvas.underMouse():
raster = self.parent.rasterComboBox.currentLayer()
if raster:
text = self.getPixelValue(raster)
- p = self.canvas.mapToGlobal( self.canvas.mouseLastXY() )
- QToolTip.showText( p, text, self.canvas )
\ No newline at end of file
+ p = self.canvas.mapToGlobal(self.canvas.mouseLastXY())
+ QToolTip.showText(p, text, self.canvas)
diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py
index ccc9d4f81..e355e1349 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool.py
@@ -30,7 +30,7 @@
QgsVectorLayer,
QgsRasterLayer,
QgsWkbTypes,
- Qgis
+ Qgis,
)
from qgis.PyQt import QtGui, uic
@@ -49,6 +49,7 @@
# FORM_CLASS, _ = uic.loadUiType(os.path.join(os.path.dirname(__file__), 'dsgRasterInfoTool.ui'))
from .dsgRasterInfoTool_ui import Ui_DsgRasterInfoTool
+
class DsgRasterInfoTool(QWidget, Ui_DsgRasterInfoTool):
"""
This class is supposed to help revision operators. It shows, on mouse hovering
diff --git a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py
index a4b2b5aed..67af411dd 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/DsgRasterInfoTool/dsgRasterInfoTool_ui.py
@@ -12,26 +12,35 @@
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
+
def _fromUtf8(s):
return s
+
try:
_encoding = QtWidgets.QApplication.UnicodeUTF8
+
def _translate(context, text, disambig):
return QtWidgets.QApplication.translate(context, text, disambig, _encoding)
+
except AttributeError:
+
def _translate(context, text, disambig):
return QtWidgets.QApplication.translate(context, text, disambig)
+
from qgis.gui import QgsMapLayerComboBox
from qgis.core import QgsMapLayerProxyModel
import resources_rc
+
class Ui_DsgRasterInfoTool(object):
def setupUi(self, DsgRasterInfoTool):
DsgRasterInfoTool.setObjectName(_fromUtf8("DsgRasterInfoTool"))
DsgRasterInfoTool.resize(309, 49)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(DsgRasterInfoTool.sizePolicy().hasHeightForWidth())
@@ -42,16 +51,24 @@ def setupUi(self, DsgRasterInfoTool):
self.gridLayout = QtWidgets.QGridLayout(DsgRasterInfoTool)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.rasterInfoPushButton = QtWidgets.QPushButton(DsgRasterInfoTool)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.rasterInfoPushButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.rasterInfoPushButton.sizePolicy().hasHeightForWidth()
+ )
self.rasterInfoPushButton.setSizePolicy(sizePolicy)
self.rasterInfoPushButton.setMinimumSize(QtCore.QSize(16, 16))
self.rasterInfoPushButton.setMaximumSize(QtCore.QSize(24, 24))
self.rasterInfoPushButton.setText(_fromUtf8(""))
icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/rasterToolTip.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon.addPixmap(
+ QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/rasterToolTip.png")),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.rasterInfoPushButton.setIcon(icon)
self.rasterInfoPushButton.setIconSize(QtCore.QSize(16, 16))
self.rasterInfoPushButton.setCheckable(True)
@@ -62,73 +79,111 @@ def setupUi(self, DsgRasterInfoTool):
self.splitter.setObjectName(_fromUtf8("splitter"))
self.rasterComboBox = QgsMapLayerComboBox(self.splitter)
self.rasterComboBox.setFilters(QgsMapLayerProxyModel.RasterLayer)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.rasterComboBox.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.rasterComboBox.sizePolicy().hasHeightForWidth()
+ )
self.rasterComboBox.setSizePolicy(sizePolicy)
self.rasterComboBox.setMinimumSize(QtCore.QSize(0, 20))
self.rasterComboBox.setMaximumSize(QtCore.QSize(16777215, 24))
self.rasterComboBox.setObjectName(_fromUtf8("rasterComboBox"))
self.refreshPushButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.refreshPushButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.refreshPushButton.sizePolicy().hasHeightForWidth()
+ )
self.refreshPushButton.setSizePolicy(sizePolicy)
self.refreshPushButton.setMinimumSize(QtCore.QSize(24, 24))
self.refreshPushButton.setMaximumSize(QtCore.QSize(24, 24))
self.refreshPushButton.setText("")
icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.refreshPushButton.setIcon(icon)
self.refreshPushButton.setIconSize(QtCore.QSize(16, 16))
self.refreshPushButton.setObjectName("refreshPushButton")
self.bandTooltipButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.bandTooltipButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.bandTooltipButton.sizePolicy().hasHeightForWidth()
+ )
self.bandTooltipButton.setSizePolicy(sizePolicy)
self.bandTooltipButton.setMinimumSize(QtCore.QSize(16, 16))
self.bandTooltipButton.setMaximumSize(QtCore.QSize(24, 24))
self.bandTooltipButton.setToolTip(_fromUtf8("Show raster tooltip"))
self.bandTooltipButton.setText(_fromUtf8(""))
icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/band_tooltip.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon1.addPixmap(
+ QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/band_tooltip.png")),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.bandTooltipButton.setIcon(icon1)
self.bandTooltipButton.setIconSize(QtCore.QSize(16, 16))
self.bandTooltipButton.setCheckable(True)
self.bandTooltipButton.setObjectName(_fromUtf8("bandTooltipButton"))
self.dynamicHistogramButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.dynamicHistogramButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.dynamicHistogramButton.sizePolicy().hasHeightForWidth()
+ )
self.dynamicHistogramButton.setSizePolicy(sizePolicy)
self.dynamicHistogramButton.setMinimumSize(QtCore.QSize(16, 16))
self.dynamicHistogramButton.setMaximumSize(QtCore.QSize(24, 24))
self.dynamicHistogramButton.setToolTip(_fromUtf8("Dynamic histogram view"))
self.dynamicHistogramButton.setText(_fromUtf8(""))
icon2 = QtGui.QIcon()
- icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/dynamic_histogram_viewer.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon2.addPixmap(
+ QtGui.QPixmap(
+ _fromUtf8(":/plugins/DsgTools/icons/dynamic_histogram_viewer.png")
+ ),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.dynamicHistogramButton.setIcon(icon2)
- self.dynamicHistogramButton.setIconSize(QtCore.QSize(16,16))
+ self.dynamicHistogramButton.setIconSize(QtCore.QSize(16, 16))
self.dynamicHistogramButton.setCheckable(True)
self.dynamicHistogramButton.setObjectName(_fromUtf8("dynamicHistogramButton"))
self.gridLayout.addWidget(self.splitter, 0, 1, 1, 1)
self.valueSetterButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.valueSetterButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.valueSetterButton.sizePolicy().hasHeightForWidth()
+ )
self.valueSetterButton.setSizePolicy(sizePolicy)
self.valueSetterButton.setMinimumSize(QtCore.QSize(16, 16))
self.valueSetterButton.setMaximumSize(QtCore.QSize(24, 24))
self.valueSetterButton.setToolTip(_fromUtf8("Set Value From Raster"))
self.valueSetterButton.setText(_fromUtf8(""))
icon2 = QtGui.QIcon()
- icon2.addPixmap(QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/valueSetter.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon2.addPixmap(
+ QtGui.QPixmap(_fromUtf8(":/plugins/DsgTools/icons/valueSetter.png")),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.valueSetterButton.setIcon(icon2)
self.valueSetterButton.setIconSize(QtCore.QSize(40, 40))
self.valueSetterButton.setCheckable(True)
@@ -140,4 +195,6 @@ def setupUi(self, DsgRasterInfoTool):
def retranslateUi(self, DsgRasterInfoTool):
DsgRasterInfoTool.setWindowTitle(_translate("DsgRasterInfoTool", "Form", None))
- self.rasterInfoPushButton.setToolTip(_translate("DsgRasterInfoTool", "Raster Info Tool", None))
+ self.rasterInfoPushButton.setToolTip(
+ _translate("DsgRasterInfoTool", "Raster Info Tool", None)
+ )
diff --git a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py
index 7056f594d..4f3021a03 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures.py
@@ -27,16 +27,27 @@
from qgis.PyQt import QtGui, uic, QtCore
from qgis.PyQt.Qt import QObject
-from qgis.core import QgsMapLayer, Qgis, QgsVectorLayer, QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsFeatureRequest, QgsWkbTypes, QgsProject
+from qgis.core import (
+ QgsMapLayer,
+ Qgis,
+ QgsVectorLayer,
+ QgsCoordinateReferenceSystem,
+ QgsCoordinateTransform,
+ QgsFeatureRequest,
+ QgsWkbTypes,
+ QgsProject,
+)
from qgis.gui import QgsMessageBar
from .inspectFeatures_ui import Ui_Form
+
# FORM_CLASS, _ = uic.loadUiType(os.path.join(
# os.path.dirname(__file__), 'inspectFeatures.ui'))
-class InspectFeatures(QWidget,Ui_Form):
+
+class InspectFeatures(QWidget, Ui_Form):
# idxChanged = pyqtSignal(int)
- def __init__(self, iface, parent = None):
+ def __init__(self, iface, parent=None):
"""
Constructor
"""
@@ -48,7 +59,9 @@ def __init__(self, iface, parent = None):
self.iface = iface
# self.iface.currentLayerChanged.connect(self.enableScale)
self.mMapLayerComboBox.layerChanged.connect(self.enableScale)
- self.mMapLayerComboBox.layerChanged.connect(self.mFieldExpressionWidget.setLayer)
+ self.mMapLayerComboBox.layerChanged.connect(
+ self.mFieldExpressionWidget.setLayer
+ )
self.mMapLayerComboBox.layerChanged.connect(self.mFieldComboBox.setLayer)
if not self.iface.activeLayer():
self.enableTool(False)
@@ -58,38 +71,48 @@ def __init__(self, iface, parent = None):
self.zoomPercentageSpinBox.setMaximum(100)
self.zoomPercentageSpinBox.setDecimals(3)
self.zoomPercentageSpinBox.setSingleStep(1)
- self.zoomPercentageSpinBox.setSuffix('%')
+ self.zoomPercentageSpinBox.setSuffix("%")
self.zoomPercentageSpinBox.setValue(100)
self.zoomPercentageSpinBox.setEnabled(False)
self.zoomPercentageSpinBox.hide()
- self.mScaleWidget.setScaleString('1:40000')
+ self.mScaleWidget.setScaleString("1:40000")
self.mScaleWidget.setEnabled(False)
self.mScaleWidget.hide()
self.enableScale()
self.canvas = self.iface.mapCanvas()
- self.allLayers={}
+ self.allLayers = {}
# self.idxChanged.connect(self.setNewId)
- self.setToolTip('')
- icon_path = ':/plugins/DsgTools/icons/inspectFeatures.png'
- text = self.tr('DSGTools: Inspect Features')
- self.activateToolAction = self.add_action(icon_path, text, self.inspectPushButton.toggle, parent = self.parent)
- self.iface.registerMainWindowAction(self.activateToolAction, '')
- icon_path = ':/plugins/DsgTools/icons/backInspect.png'
- text = self.tr('DSGTools: Back Inspect')
- self.backButtonAction = self.add_action(icon_path, text, self.backInspectButton.click, parent = self.parent)
- self.iface.registerMainWindowAction(self.backButtonAction, '')
- icon_path = ':/plugins/DsgTools/icons/nextInspect.png'
- text = self.tr('DSGTools: Next Inspect')
- self.nextButtonAction = self.add_action(icon_path, text, self.nextInspectButton.click, parent = self.parent)
- self.iface.registerMainWindowAction(self.nextButtonAction, '')
- icon_path = ':/plugins/DsgTools/icons/reload.png'
- text = self.tr('DSGTools: Set Active Layer on Feature Inspector')
- self.refreshPushButtonAction = self.add_action(icon_path, text, self.refreshPushButton.click, parent = self.parent)
- self.iface.registerMainWindowAction(self.refreshPushButtonAction, '')
- self.refreshPushButton.setToolTip(self.tr('Set current layer as selected layer on inspect tool'))
- self.sortPushButton.setToolTip(self.tr('Sort by attribute'))
+ self.setToolTip("")
+ icon_path = ":/plugins/DsgTools/icons/inspectFeatures.png"
+ text = self.tr("DSGTools: Inspect Features")
+ self.activateToolAction = self.add_action(
+ icon_path, text, self.inspectPushButton.toggle, parent=self.parent
+ )
+ self.iface.registerMainWindowAction(self.activateToolAction, "")
+ icon_path = ":/plugins/DsgTools/icons/backInspect.png"
+ text = self.tr("DSGTools: Back Inspect")
+ self.backButtonAction = self.add_action(
+ icon_path, text, self.backInspectButton.click, parent=self.parent
+ )
+ self.iface.registerMainWindowAction(self.backButtonAction, "")
+ icon_path = ":/plugins/DsgTools/icons/nextInspect.png"
+ text = self.tr("DSGTools: Next Inspect")
+ self.nextButtonAction = self.add_action(
+ icon_path, text, self.nextInspectButton.click, parent=self.parent
+ )
+ self.iface.registerMainWindowAction(self.nextButtonAction, "")
+ icon_path = ":/plugins/DsgTools/icons/reload.png"
+ text = self.tr("DSGTools: Set Active Layer on Feature Inspector")
+ self.refreshPushButtonAction = self.add_action(
+ icon_path, text, self.refreshPushButton.click, parent=self.parent
+ )
+ self.iface.registerMainWindowAction(self.refreshPushButtonAction, "")
+ self.refreshPushButton.setToolTip(
+ self.tr("Set current layer as selected layer on inspect tool")
+ )
+ self.sortPushButton.setToolTip(self.tr("Sort by attribute"))
self.mFieldExpressionWidget.fieldChanged.connect(self.resetCurrentIndex)
-
+
def add_action(self, icon_path, text, callback, parent=None):
icon = QIcon(icon_path)
action = QAction(icon, text, parent)
@@ -97,19 +120,23 @@ def add_action(self, icon_path, text, callback, parent=None):
if parent:
parent.addAction(action)
return action
-
+
def getIterateLayer(self):
- return self.mMapLayerComboBox.currentLayer()
+ return self.mMapLayerComboBox.currentLayer()
- def enableTool(self, enabled = True):
- allowed = False if enabled == None or not isinstance(enabled, QgsVectorLayer) else True
+ def enableTool(self, enabled=True):
+ allowed = (
+ False
+ if enabled == None or not isinstance(enabled, QgsVectorLayer)
+ else True
+ )
toggled = self.inspectPushButton.isChecked()
enabled = allowed and toggled
self.backInspectButton.setEnabled(enabled)
self.nextInspectButton.setEnabled(enabled)
self.idSpinBox.setEnabled(enabled)
self.sortPushButton.setEnabled(enabled)
-
+
def enableScale(self):
"""
The scale combo should only be enabled for point layers
@@ -129,16 +156,16 @@ def enableScale(self):
self.mScaleWidget.hide()
self.zoomPercentageSpinBox.setEnabled(True)
self.zoomPercentageSpinBox.show()
-
+
@pyqtSlot(bool)
def on_nextInspectButton_clicked(self):
"""
Inspects the next feature
"""
if self.nextInspectButton.isEnabled():
- method = getattr(self, 'testIndexFoward')
+ method = getattr(self, "testIndexFoward")
self.iterateFeature(method)
-
+
def testIndexFoward(self, index, maxIndex, minIndex):
"""
Gets the next index
@@ -147,7 +174,7 @@ def testIndexFoward(self, index, maxIndex, minIndex):
if index > maxIndex:
index = minIndex
return index
-
+
def testIndexBackwards(self, index, maxIndex, minIndex):
"""
gets the previous index
@@ -156,17 +183,17 @@ def testIndexBackwards(self, index, maxIndex, minIndex):
if index < minIndex:
index = maxIndex
return index
-
+
@pyqtSlot(bool)
def on_backInspectButton_clicked(self):
"""
Inspects the previous feature
"""
if self.backInspectButton.isEnabled():
- method = getattr(self, 'testIndexBackwards')
+ method = getattr(self, "testIndexBackwards")
self.iterateFeature(method)
-
- @pyqtSlot(int, name = 'on_idSpinBox_valueChanged')
+
+ @pyqtSlot(int, name="on_idSpinBox_valueChanged")
def setNewId(self, newId):
if not isinstance(self.sender(), QSpinBox):
self.idSpinBox.setValue(newId)
@@ -182,7 +209,11 @@ def setNewId(self, newId):
featIdList = self.getFeatIdList(currentLayer)
if oldIndex not in featIdList:
oldIndex = 0
- zoom = self.mScaleWidget.scale() if currentLayer.geometryType() == QgsWkbTypes.PointGeometry else self.zoomPercentageSpinBox.value()
+ zoom = (
+ self.mScaleWidget.scale()
+ if currentLayer.geometryType() == QgsWkbTypes.PointGeometry
+ else self.zoomPercentageSpinBox.value()
+ )
if oldIndex == newId:
# self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Selected id does not exist in layer {0}. Returned to previous id.').format(lyrName), level=Qgis.Warning, duration=2)
return
@@ -190,24 +221,34 @@ def setNewId(self, newId):
index = featIdList.index(newId)
self.allLayers[lyrName] = index
self.makeZoom(zoom, currentLayer, newId)
- self.idSpinBox.setSuffix(' ({0}/{1})'.format(index+1,len(featIdList)))
+ self.idSpinBox.setSuffix(
+ " ({0}/{1})".format(index + 1, len(featIdList))
+ )
except:
# self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Selected id does not exist in layer {0}. Returned to previous id.').format(lyrName), level=Qgis.Warning, duration=2)
self.idSpinBox.setValue(oldIndex)
self.makeZoom(zoom, currentLayer, oldIndex)
def getFeatIdList(self, currentLayer):
- #getting all features ids
- if self.mFieldExpressionWidget.currentText() != '' and not self.mFieldExpressionWidget.isValidExpression():
- self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Invalid attribute filter!'), level=Qgis.Warning, duration=2)
+ # getting all features ids
+ if (
+ self.mFieldExpressionWidget.currentText() != ""
+ and not self.mFieldExpressionWidget.isValidExpression()
+ ):
+ self.iface.messageBar().pushMessage(
+ self.tr("Warning!"),
+ self.tr("Invalid attribute filter!"),
+ level=Qgis.Warning,
+ duration=2,
+ )
return []
request = QgsFeatureRequest()
request.setFlags(QgsFeatureRequest.NoGeometry)
- if self.mFieldExpressionWidget.currentText() != '':
+ if self.mFieldExpressionWidget.currentText() != "":
request.setFilterExpression(self.mFieldExpressionWidget.asExpression())
clauseList = []
if self.sortPushButton.isChecked():
- #order by some attribute
+ # order by some attribute
clause = QgsFeatureRequest.OrderByClause(
self.mFieldComboBox.currentField(),
self.ascRadioButton.isChecked(),
@@ -221,9 +262,9 @@ def getFeatIdList(self, currentLayer):
orderby = QgsFeatureRequest.OrderBy(clauseList)
request.setOrderBy(orderby)
featIdList = [i.id() for i in currentLayer.getFeatures(request)]
- #sort is faster than sorted (but sort is just available for lists)
+ # sort is faster than sorted (but sort is just available for lists)
return featIdList
-
+
def iterateFeature(self, method):
"""
Iterates over the features selecting and zooming to the desired one
@@ -231,52 +272,63 @@ def iterateFeature(self, method):
"""
currentLayer = self.getIterateLayer()
lyrName = currentLayer.name()
-
- zoom = self.mScaleWidget.scale() if currentLayer.geometryType() == QgsWkbTypes.PointGeometry else self.zoomPercentageSpinBox.value()
-
+
+ zoom = (
+ self.mScaleWidget.scale()
+ if currentLayer.geometryType() == QgsWkbTypes.PointGeometry
+ else self.zoomPercentageSpinBox.value()
+ )
+
featIdList = self.getFeatIdList(currentLayer)
if not currentLayer or len(featIdList) == 0:
self.errorMessage()
return
-
- #checking if this is the first time for this layer (currentLayer)
+
+ # checking if this is the first time for this layer (currentLayer)
first = False
if lyrName not in list(self.allLayers.keys()):
self.allLayers[lyrName] = 0
first = True
- #getting the current index
+ # getting the current index
index = self.allLayers[lyrName]
- #getting max and min ids
- #this was made because the list is already sorted, there's no need to calculate max and min
+ # getting max and min ids
+ # this was made because the list is already sorted, there's no need to calculate max and min
maxIndex = len(featIdList) - 1
minIndex = 0
-
+
self.idSpinBox.setMaximum(maxIndex)
self.idSpinBox.setMinimum(minIndex)
- #getting the new index
+ # getting the new index
if not first:
index = method(index, maxIndex, minIndex)
- self.idSpinBox.setSuffix(' ({0}/{1})'.format(index+1,len(featIdList)))
+ self.idSpinBox.setSuffix(" ({0}/{1})".format(index + 1, len(featIdList)))
self.allLayers[lyrName] = index
- #getting the new feature id
+ # getting the new feature id
id = featIdList[index]
- #adjustin the spin box value
+ # adjustin the spin box value
# self.idxChanged.emit(id)
self.makeZoom(zoom, currentLayer, id)
self.selectLayer(id, currentLayer)
-
+
def errorMessage(self):
"""
Shows am error message
"""
- QMessageBox.warning(self.iface.mainWindow(), self.tr(u"ERROR:"), self.tr(u"There are no features in the current layer: Add features and try again!"), QMessageBox.Close)
+ QMessageBox.warning(
+ self.iface.mainWindow(),
+ self.tr("ERROR:"),
+ self.tr(
+ "There are no features in the current layer: Add features and try again!"
+ ),
+ QMessageBox.Close,
+ )
def selectLayer(self, index, currentLayer):
"""
@@ -286,27 +338,31 @@ def selectLayer(self, index, currentLayer):
if currentLayer:
currentLayer.removeSelection()
currentLayer.select(index)
-
- def zoomToLayer(self, layer, zoom = None):
+
+ def zoomToLayer(self, layer, zoom=None):
box = layer.boundingBoxOfSelected()
if zoom is not None:
- box.grow(min(box.width(),box.height())*(100-zoom)/100)
+ box.grow(min(box.width(), box.height()) * (100 - zoom) / 100)
# Defining the crs from src and destiny
epsg = self.iface.mapCanvas().mapSettings().destinationCrs().authid()
crsDest = QgsCoordinateReferenceSystem(epsg)
- #getting srid from something like 'EPSG:31983'
+ # getting srid from something like 'EPSG:31983'
if not layer:
layer = self.iface.mapCanvas().currentLayer()
srid = layer.crs().authid()
- crsSrc = QgsCoordinateReferenceSystem(srid) #here we have to put authid, not srid
+ crsSrc = QgsCoordinateReferenceSystem(
+ srid
+ ) # here we have to put authid, not srid
# Creating a transformer
- coordinateTransformer = QgsCoordinateTransform(crsSrc, crsDest, QgsProject.instance())
+ coordinateTransformer = QgsCoordinateTransform(
+ crsSrc, crsDest, QgsProject.instance()
+ )
newBox = coordinateTransformer.transform(box)
self.iface.mapCanvas().setExtent(newBox)
self.iface.mapCanvas().refresh()
- def zoomFeature(self, zoom, idDict = None):
+ def zoomFeature(self, zoom, idDict=None):
"""
Zooms to current layer selected features according to a specific zoom
zoom: zoom to be applied
@@ -316,18 +372,18 @@ def zoomFeature(self, zoom, idDict = None):
if idDict == {}:
self.zoomToLayer(currentLayer, zoom=float(zoom))
else:
- id = idDict['id']
- lyr = idDict['lyr']
+ id = idDict["id"]
+ lyr = idDict["lyr"]
selectIdList = lyr.selectedFeatureIds()
lyr.removeSelection()
lyr.selectByIds([id])
- self.zoomToLayer(layer = lyr, zoom=float(zoom))
+ self.zoomToLayer(layer=lyr, zoom=float(zoom))
lyr.selectByIds(selectIdList)
if self.getIterateLayer().geometryType() == QgsWkbTypes.PointGeometry:
self.iface.mapCanvas().zoomScale(float(zoom))
-
- @pyqtSlot(bool, name = 'on_inspectPushButton_toggled')
+
+ @pyqtSlot(bool, name="on_inspectPushButton_toggled")
def toggleBar(self, toggled=None):
"""
Shows/Hides the tool bar
@@ -337,13 +393,13 @@ def toggleBar(self, toggled=None):
if toggled:
self.splitter.show()
self.enableTool(self.mMapLayerComboBox.currentLayer())
- self.setToolTip(self.tr('Select a vector layer to enable tool'))
+ self.setToolTip(self.tr("Select a vector layer to enable tool"))
else:
- self.splitter.hide()
+ self.splitter.hide()
self.enableTool(False)
- self.setToolTip('')
-
- @pyqtSlot(bool, name='on_sortPushButton_toggled')
+ self.setToolTip("")
+
+ @pyqtSlot(bool, name="on_sortPushButton_toggled")
def toggleSort(self, toggled=None):
"""
Shows/hides the sort options
@@ -369,31 +425,31 @@ def setValues(self, featIdList, currentLayer):
maxIndex = len(featIdList) - 1
minIndex = 0
-
+
self.idSpinBox.setMaximum(featIdList[maxIndex])
self.idSpinBox.setMinimum(featIdList[minIndex])
- #getting the new feature id
+ # getting the new feature id
id = featIdList[0]
- #adjustin the spin box value
+ # adjustin the spin box value
# self.idxChanged.emit(id)
- #self.idSpinBox.setValue(id)
+ # self.idSpinBox.setValue(id)
zoom = self.mScaleWidget.scale()
self.makeZoom(zoom, currentLayer, id)
def makeZoom(self, zoom, currentLayer, id):
- #selecting and zooming to the feature
+ # selecting and zooming to the feature
# if not self.onlySelectedRadioButton.isChecked():
# self.selectLayer(id, currentLayer)
# self.zoomFeature(zoom)
# else:
if self.usePanCkb.isChecked():
currentLayer.select(id)
- self.iface.mapCanvas().panToFeatureIds( currentLayer, [id] )
+ self.iface.mapCanvas().panToFeatureIds(currentLayer, [id])
return
- self.zoomFeature(zoom, idDict = {'id':id, 'lyr':currentLayer})
+ self.zoomFeature(zoom, idDict={"id": id, "lyr": currentLayer})
@pyqtSlot(bool)
def on_onlySelectedRadioButton_toggled(self, toggled):
@@ -406,18 +462,22 @@ def on_onlySelectedRadioButton_toggled(self, toggled):
featIdList = currentLayer.allFeatureIds()
self.setValues(featIdList, currentLayer)
self.idSpinBox.setEnabled(True)
-
+
@pyqtSlot(bool)
def on_refreshPushButton_clicked(self):
activeLayer = self.iface.activeLayer()
if isinstance(activeLayer, QgsVectorLayer):
self.mMapLayerComboBox.setLayer(activeLayer)
else:
- self.iface.messageBar().pushMessage(self.tr('Warning!'), self.tr('Active layer is not valid to be used in this tool.'), level=Qgis.Warning, duration=2)
- self.mFieldExpressionWidget.setExpression('')
-
+ self.iface.messageBar().pushMessage(
+ self.tr("Warning!"),
+ self.tr("Active layer is not valid to be used in this tool."),
+ level=Qgis.Warning,
+ duration=2,
+ )
+ self.mFieldExpressionWidget.setExpression("")
+
def unload(self):
self.iface.unregisterMainWindowAction(self.activateToolAction)
self.iface.unregisterMainWindowAction(self.backButtonAction)
self.iface.unregisterMainWindowAction(self.nextButtonAction)
-
diff --git a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py
index 06d8adc44..c51c70a71 100644
--- a/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py
+++ b/DsgTools/gui/ProductionTools/Toolbars/InspectFeatures/inspectFeatures_ui.py
@@ -8,11 +8,14 @@
from PyQt5 import QtCore, QtGui, QtWidgets
+
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(858, 36)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(Form.sizePolicy().hasHeightForWidth())
@@ -28,40 +31,66 @@ def setupUi(self, Form):
self.splitter.setOrientation(QtCore.Qt.Horizontal)
self.splitter.setObjectName("splitter")
self.mMapLayerComboBox = QgsMapLayerComboBox(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.mMapLayerComboBox.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.mMapLayerComboBox.sizePolicy().hasHeightForWidth()
+ )
self.mMapLayerComboBox.setSizePolicy(sizePolicy)
self.mMapLayerComboBox.setMinimumSize(QtCore.QSize(0, 20))
self.mMapLayerComboBox.setMaximumSize(QtCore.QSize(16777215, 32))
- self.mMapLayerComboBox.setFilters(core.QgsMapLayerProxyModel.HasGeometry|core.QgsMapLayerProxyModel.LineLayer|core.QgsMapLayerProxyModel.NoGeometry|core.QgsMapLayerProxyModel.PluginLayer|core.QgsMapLayerProxyModel.PointLayer|core.QgsMapLayerProxyModel.PolygonLayer|core.QgsMapLayerProxyModel.VectorLayer)
+ self.mMapLayerComboBox.setFilters(
+ core.QgsMapLayerProxyModel.HasGeometry
+ | core.QgsMapLayerProxyModel.LineLayer
+ | core.QgsMapLayerProxyModel.NoGeometry
+ | core.QgsMapLayerProxyModel.PluginLayer
+ | core.QgsMapLayerProxyModel.PointLayer
+ | core.QgsMapLayerProxyModel.PolygonLayer
+ | core.QgsMapLayerProxyModel.VectorLayer
+ )
self.mMapLayerComboBox.setObjectName("mMapLayerComboBox")
self.refreshPushButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.refreshPushButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.refreshPushButton.sizePolicy().hasHeightForWidth()
+ )
self.refreshPushButton.setSizePolicy(sizePolicy)
self.refreshPushButton.setMinimumSize(QtCore.QSize(24, 24))
self.refreshPushButton.setMaximumSize(QtCore.QSize(24, 24))
self.refreshPushButton.setText("")
icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/reload.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.refreshPushButton.setIcon(icon)
self.refreshPushButton.setIconSize(QtCore.QSize(16, 16))
self.refreshPushButton.setObjectName("refreshPushButton")
self.zoomPercentageSpinBox = QgsDoubleSpinBox(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.zoomPercentageSpinBox.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.zoomPercentageSpinBox.sizePolicy().hasHeightForWidth()
+ )
self.zoomPercentageSpinBox.setSizePolicy(sizePolicy)
self.zoomPercentageSpinBox.setMinimumSize(QtCore.QSize(0, 20))
self.zoomPercentageSpinBox.setMaximumSize(QtCore.QSize(16777215, 16777215))
self.zoomPercentageSpinBox.setObjectName("zoomPercentageSpinBox")
self.mScaleWidget = QgsScaleWidget(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.mScaleWidget.sizePolicy().hasHeightForWidth())
@@ -71,7 +100,9 @@ def setupUi(self, Form):
self.mScaleWidget.setShowCurrentScaleButton(True)
self.mScaleWidget.setObjectName("mScaleWidget")
self.idSpinBox = QtWidgets.QSpinBox(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.idSpinBox.sizePolicy().hasHeightForWidth())
@@ -81,8 +112,10 @@ def setupUi(self, Form):
self.idSpinBox.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
self.idSpinBox.setSuffix("")
self.idSpinBox.setObjectName("idSpinBox")
- self.usePanCkb = QtWidgets.QCheckBox(self.tr('Use pan'), self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ self.usePanCkb = QtWidgets.QCheckBox(self.tr("Use pan"), self.splitter)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.usePanCkb.sizePolicy().hasHeightForWidth())
@@ -91,52 +124,80 @@ def setupUi(self, Form):
self.usePanCkb.setMaximumSize(QtCore.QSize(70, 20))
self.usePanCkb.setObjectName("usePanCkb")
self.backInspectButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.backInspectButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.backInspectButton.sizePolicy().hasHeightForWidth()
+ )
self.backInspectButton.setSizePolicy(sizePolicy)
self.backInspectButton.setMinimumSize(QtCore.QSize(24, 24))
self.backInspectButton.setMaximumSize(QtCore.QSize(24, 24))
self.backInspectButton.setText("")
icon = QtGui.QIcon()
- icon.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/backInspect.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/backInspect.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.backInspectButton.setIcon(icon)
self.backInspectButton.setIconSize(QtCore.QSize(16, 16))
self.backInspectButton.setObjectName("backInspectButton")
self.nextInspectButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.nextInspectButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.nextInspectButton.sizePolicy().hasHeightForWidth()
+ )
self.nextInspectButton.setSizePolicy(sizePolicy)
self.nextInspectButton.setMinimumSize(QtCore.QSize(24, 24))
self.nextInspectButton.setMaximumSize(QtCore.QSize(24, 24))
self.nextInspectButton.setText("")
icon1 = QtGui.QIcon()
- icon1.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/nextInspect.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon1.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/nextInspect.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.nextInspectButton.setIcon(icon1)
self.nextInspectButton.setIconSize(QtCore.QSize(16, 16))
self.nextInspectButton.setObjectName("nextInspectButton")
self.mFieldExpressionWidget = QgsFieldExpressionWidget(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Preferred
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.mFieldExpressionWidget.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.mFieldExpressionWidget.sizePolicy().hasHeightForWidth()
+ )
self.mFieldExpressionWidget.setSizePolicy(sizePolicy)
self.mFieldExpressionWidget.setMinimumSize(QtCore.QSize(0, 20))
self.mFieldExpressionWidget.setObjectName("mFieldExpressionWidget")
self.sortPushButton = QtWidgets.QPushButton(self.splitter)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.sortPushButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.sortPushButton.sizePolicy().hasHeightForWidth()
+ )
self.sortPushButton.setSizePolicy(sizePolicy)
self.sortPushButton.setMinimumSize(QtCore.QSize(24, 24))
self.sortPushButton.setMaximumSize(QtCore.QSize(24, 24))
self.sortPushButton.setText("")
icon3 = QtGui.QIcon()
- icon3.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/sort.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon3.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/sort.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.sortPushButton.setIcon(icon3)
self.sortPushButton.setCheckable(True)
self.sortPushButton.setObjectName("sortPushButton")
@@ -144,10 +205,14 @@ def setupUi(self, Form):
self.splitter2.setOrientation(QtCore.Qt.Horizontal)
self.splitter2.setObjectName("splitter2")
self.mFieldComboBox = QgsFieldComboBox(self.splitter2)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.mFieldComboBox.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.mFieldComboBox.sizePolicy().hasHeightForWidth()
+ )
self.mFieldComboBox.setSizePolicy(sizePolicy)
self.mFieldComboBox.setMinimumSize(QtCore.QSize(100, 0))
self.mFieldComboBox.setObjectName("mFieldComboBox")
@@ -157,49 +222,75 @@ def setupUi(self, Form):
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.ascRadioButton = QtWidgets.QRadioButton(self.widget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.ascRadioButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.ascRadioButton.sizePolicy().hasHeightForWidth()
+ )
self.ascRadioButton.setSizePolicy(sizePolicy)
self.ascRadioButton.setText("")
icon4 = QtGui.QIcon()
- icon4.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/up.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon4.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/up.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.ascRadioButton.setIcon(icon4)
self.ascRadioButton.setChecked(True)
self.ascRadioButton.setObjectName("ascRadioButton")
self.horizontalLayout.addWidget(self.ascRadioButton)
self.descRadioButton = QtWidgets.QRadioButton(self.widget)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.descRadioButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.descRadioButton.sizePolicy().hasHeightForWidth()
+ )
self.descRadioButton.setSizePolicy(sizePolicy)
self.descRadioButton.setText("")
icon5 = QtGui.QIcon()
- icon5.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/down.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon5.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/down.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.descRadioButton.setIcon(icon5)
self.descRadioButton.setObjectName("descRadioButton")
self.horizontalLayout.addWidget(self.descRadioButton)
self.gridLayout.addWidget(self.splitter, 0, 2, 1, 1)
self.inspectPushButton = QtWidgets.QPushButton(Form)
- sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
+ sizePolicy = QtWidgets.QSizePolicy(
+ QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
+ )
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
- sizePolicy.setHeightForWidth(self.inspectPushButton.sizePolicy().hasHeightForWidth())
+ sizePolicy.setHeightForWidth(
+ self.inspectPushButton.sizePolicy().hasHeightForWidth()
+ )
self.inspectPushButton.setSizePolicy(sizePolicy)
self.inspectPushButton.setMinimumSize(QtCore.QSize(24, 24))
self.inspectPushButton.setMaximumSize(QtCore.QSize(24, 24))
self.inspectPushButton.setText("")
icon2 = QtGui.QIcon()
- icon2.addPixmap(QtGui.QPixmap(":/plugins/DsgTools/icons/inspectFeatures.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ icon2.addPixmap(
+ QtGui.QPixmap(":/plugins/DsgTools/icons/inspectFeatures.png"),
+ QtGui.QIcon.Normal,
+ QtGui.QIcon.Off,
+ )
self.inspectPushButton.setIcon(icon2)
self.inspectPushButton.setIconSize(QtCore.QSize(16, 16))
self.inspectPushButton.setCheckable(True)
self.inspectPushButton.setObjectName("inspectPushButton")
self.gridLayout.addWidget(self.inspectPushButton, 0, 0, 1, 1)
- spacerItem = QtWidgets.QSpacerItem(10, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
+ spacerItem = QtWidgets.QSpacerItem(
+ 10, 20, QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum
+ )
self.gridLayout.addItem(spacerItem, 0, 1, 1, 1)
self.retranslateUi(Form)
@@ -209,10 +300,24 @@ def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
# self.idSpinBox.setPrefix(_translate("Form", "ID: "))
- self.backInspectButton.setToolTip(_translate("Form", "