From cf71b0379d0930a4860fed5a6f266a7ac84d9846 Mon Sep 17 00:00:00 2001 From: phborba Date: Wed, 31 Jul 2024 15:20:34 -0300 Subject: [PATCH 1/3] partial commit --- .../GeometricAlgs/extractElevationPoints.py | 70 ++++++++++--------- .../identifyTerrainModelErrorsAlgorithm.py | 2 +- .../core/GeometricTools/terrainHandler.py | 9 ++- 3 files changed, 46 insertions(+), 35 deletions(-) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractElevationPoints.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractElevationPoints.py index 403edee46..e61078b14 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractElevationPoints.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/extractElevationPoints.py @@ -596,7 +596,6 @@ def computePoints( geographicBoundsLyr, areaWithoutInformationLyr, waterBodiesLyr, - contourBufferLyr, context, algRunner, feedback=multiStepFeedback, @@ -608,7 +607,7 @@ def computePoints( multiStepFeedback.pushInfo( self.tr("Getting max min feats and building exclusion polygons...") ) - minMaxFeats = self.getMinMaxFeatures( + maxFeats = self.getMaxFeatures( fields, npRaster, transform, @@ -616,6 +615,18 @@ def computePoints( maskLyr=maskLyr, feedback=multiStepFeedback, ) + minMaxFeats = self.getMinFeatures( + maxFeats, + fields, + npRaster, + transform, + distance=localBufferDistance, + maskLyr=maskLyr, + feedback=multiStepFeedback, + ) + maskLyr = AlgRunner().runMergeVectorLayers( + [maskLyr, contourBufferLyr], context + ) elevationPointsLayer = layerHandler.createMemoryLayerWithFeatures( featList=minMaxFeats, fields=fields, @@ -1070,7 +1081,6 @@ def readAndMaskRaster( geographicBoundsLyr, areaWithoutInformationLyr, waterBodiesLyr, - contourBufferLyr, context, algRunner, feedback, @@ -1095,11 +1105,11 @@ def readAndMaskRaster( layerList = list( filter( lambda x: x is not None, - [areaWithoutInformationLyr, waterBodiesLyr, contourBufferLyr], + [areaWithoutInformationLyr, waterBodiesLyr], ) ) if layerList == []: - return npRaster, npRaster, transform, contourBufferLyr + return npRaster, npRaster, transform, None maskLyr = ( AlgRunner().runMergeVectorLayers( layerList, context, feedback=multiStepFeedback @@ -1115,7 +1125,7 @@ def readAndMaskRaster( ) if maskLyr.featureCount() == 0: - return npRaster + return npRaster, npRaster, transform, None if multiStepFeedback is not None: currentStep += 1 multiStepFeedback.setCurrentStep(currentStep) @@ -1591,21 +1601,15 @@ def getElevationPointsFromLineIntersections( context=context, feedback=multiStepFeedback, ) - - def getMinMaxFeatures( + + def getMaxFeatures( self, fields, npRaster, transform, distance, maskLyr, feedback=None ): featSet = set() maxCoordinatesArray = rasterHandler.getMaxCoordinatesFromNpArray(npRaster) - multiStepFeedback = ( - QgsProcessingMultiStepFeedback(3, feedback) - if feedback is not None - else None - ) npRasterCopy = np.array(npRaster) - if multiStepFeedback is not None: - multiStepFeedback.setCurrentStep(1) - multiStepFeedback.pushInfo( + if feedback is not None: + feedback.pushInfo( self.tr("Creating max feature list from pixel coordinates array...") ) maxFeatList = ( @@ -1630,16 +1634,17 @@ def getMinMaxFeatures( filteredFeatureList = self.filterFeaturesByDistanceAndExclusionLayer( candidatesPointLyr=maxFeatLyr, exclusionLyr=maskLyr, - distance=distance, + distance=distance/10, context=QgsProcessingContext(), feedback=None, ) if filteredFeatureList != []: featSet |= self.filterFeaturesByBuffer( - filteredFeatureList, distance, cotaMaisAlta=True + filteredFeatureList, distance/10, cotaMaisAlta=True ) break - npRasterCopy[npRasterCopy == cotaMax] = np.nan + if len(npRasterCopy[npRasterCopy == cotaMax]) > 0: + npRasterCopy[npRasterCopy == cotaMax] = np.nan maxCoordinatesArray = rasterHandler.getMaxCoordinatesFromNpArray( npRasterCopy ) @@ -1656,19 +1661,20 @@ def getMinMaxFeatures( ) ) cotaMax -= 1 - if multiStepFeedback is not None and multiStepFeedback.isCanceled(): + if feedback is not None and feedback.isCanceled(): break - if multiStepFeedback is not None: - multiStepFeedback.setCurrentStep(2) - multiStepFeedback.pushInfo( - self.tr("Getting min coordinates from numpy array...") - ) + return list(featSet) + + def getMinFeatures( + self, maxFeats, fields, npRaster, transform, distance, maskLyr, feedback=None + ): + featSet = set(maxFeats) + npRasterCopy = np.array(npRaster) minCoordinatesArray = rasterHandler.getMinCoordinatesFromNpArray(npRasterCopy) - if minCoordinatesArray == []: + if len(minCoordinatesArray) == 0: return list(featSet) - if multiStepFeedback is not None: - multiStepFeedback.setCurrentStep(3) - multiStepFeedback.pushInfo( + if feedback is not None: + feedback.pushInfo( self.tr("Creating min feature list from pixel coordinates array...") ) minFeatList = ( @@ -1693,7 +1699,7 @@ def getMinMaxFeatures( filteredFeatureList = self.filterFeaturesByDistanceAndExclusionLayer( candidatesPointLyr=minFeatLyr, exclusionLyr=maskLyr, - distance=distance, + distance=distance / 10, context=QgsProcessingContext(), feedback=None, ) @@ -1704,7 +1710,7 @@ def getMinMaxFeatures( minCoordinatesArray = rasterHandler.getMinCoordinatesFromNpArray( npRasterCopy ) - if minCoordinatesArray == []: + if len(minCoordinatesArray) == 0: return list(featSet) minFeatList = ( rasterHandler.createFeatureListWithPixelValuesFromPixelCoordinatesArray( @@ -1717,7 +1723,7 @@ def getMinMaxFeatures( ) ) cota += 1 - if multiStepFeedback is not None and multiStepFeedback.isCanceled(): + if feedback is not None and feedback.isCanceled(): break return list(featSet) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyTerrainModelErrorsAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyTerrainModelErrorsAlgorithm.py index 5b30806e0..208196fb5 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyTerrainModelErrorsAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyTerrainModelErrorsAlgorithm.py @@ -335,7 +335,7 @@ def compute(localGeographicBoundsLyr): spotElevationLyr=localElevationPointsLyr, spotElevationFieldName=elevationPointHeightFieldName, ) - return terrainModel.validate() + return terrainModel.validate(context=localContext) multiStepFeedback.setCurrentStep(currentStep) nRegions = len(geographicBoundaryLayerList) diff --git a/DsgTools/core/GeometricTools/terrainHandler.py b/DsgTools/core/GeometricTools/terrainHandler.py index 994e92a19..6df1a3142 100644 --- a/DsgTools/core/GeometricTools/terrainHandler.py +++ b/DsgTools/core/GeometricTools/terrainHandler.py @@ -36,8 +36,9 @@ QgsSpatialIndex, QgsGeometry, QgsProject, + QgsProcessingUtils, ) -from typing import Dict, List, Optional, Set, Tuple +from typing import Dict, List, Optional, Set, Tuple, Union from . import graphHandler from DsgTools.core.DSGToolsProcessingAlgs.algRunner import AlgRunner @@ -50,7 +51,7 @@ class TerrainSlice: outershellFeat: QgsFeature holesFeatSet: Set[QgsFeature] contoursOnSlice: Set[QgsFeature] - contourLineLayer: QgsVectorLayer + contourLineLayer: Union[QgsVectorLayer, str] contourIdField: str def __post_init__(self): @@ -59,6 +60,9 @@ def __post_init__(self): for feat in self.contoursOnSlice: self.contourDict[feat.id()] = feat self.spatialIndex.addFeature(feat) + if isinstance(self.contourLineLayer, str): + self.context = QgsProcessingContext() + self.contourLineLayer: QgsVectorLayer = QgsProcessingUtils.mapLayerFromString(self.contourLineLayer, self.context) self.contourLineDict = { feat[self.contourIdField]: feat for feat in self.contourLineLayer.getFeatures() @@ -574,6 +578,7 @@ def buildTerrainBand( ",)", ")" ), context=context, + is_child_algorithm=True, ) futures.add( pool.submit( From 33fac3e75e06fbda2161053e576041827865c8b8 Mon Sep 17 00:00:00 2001 From: phborba Date: Wed, 11 Sep 2024 09:55:13 -0300 Subject: [PATCH 2/3] fix --- .../DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py index 1b47da61c..ca3d345c9 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/GeometricAlgs/line2Multiline.py @@ -161,7 +161,7 @@ def populateAuxStructure(self, lines, feedback): break self.id_to_feature[currentFeature["AUTO"]] = currentFeature self.ids_in_stack.add(currentFeature["AUTO"]) - feedback.setCurrentStep(current * stepSize) + feedback.setProgress(current * stepSize) def aggregate(self, featureId, feedback): stack = [featureId] From 2f315a75a0914a992f68e6344449539dc2599467 Mon Sep 17 00:00:00 2001 From: phborba Date: Wed, 11 Sep 2024 10:02:51 -0300 Subject: [PATCH 3/3] corrige dangle --- .../ValidationAlgs/identifyDanglesAlgorithm.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py index 9dddd7241..1ad303695 100644 --- a/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py +++ b/DsgTools/core/DSGToolsProcessingAlgs/Algs/ValidationAlgs/identifyDanglesAlgorithm.py @@ -258,8 +258,10 @@ def processAlgorithm(self, parameters, context, feedback): for current, point in enumerate(dangleSet): if multiStepFeedback.isCanceled(): break + geom = QgsGeometry() + geom.fromWkb(point) self.flagFeature( - QgsGeometry.fromPointXY(point), + geom, self.tr("Dangle on {0}").format(inputLyr.name()), ) multiStepFeedback.setProgress(current * currentTotal) @@ -315,7 +317,8 @@ def buildInitialAndEndPointDict( id = feat["AUTO"] pointList = geom.asMultiPoint() if geom.isMultipart() else [geom.asPoint()] for point in pointList: - pointDict[point].add(id) + pointGeom = QgsGeometry.fromPointXY(point) + pointDict[pointGeom.asWkb()].add(id) multiStepFeedback.setProgress(current * step) return pointDict @@ -386,7 +389,9 @@ def getDanglesOnInputLayerFeatures( futures = set() def evaluate(point) -> Union[QgsPointXY, None]: - qgisPoint = QgsGeometry.fromPointXY(point) + # qgisPoint = QgsGeometry.fromPointXY(point) + qgisPoint = QgsGeometry() + qgisPoint.fromWkb(point) geomEngine = QgsGeometry.createGeometryEngine(qgisPoint.constGet()) geomEngine.prepareGeometry() buffer = qgisPoint.buffer(searchRadius, -1) @@ -396,7 +401,7 @@ def evaluate(point) -> Union[QgsPointXY, None]: bufferCount, intersectCount = 0, 0 point_relationship_lambda = ( lambda x: geomEngine.intersects(x.constGet()) - or qgisPoint.distance(x) < 1e-8 + or qgisPoint.distance(x) < 1e-16 if ignoreDanglesOnUnsegmentedLines else geomEngine.touches(x.constGet()) ) @@ -476,7 +481,9 @@ def getDanglesWithFilterLayers( def evaluate(point: QgsPointXY) -> dict: candidateCount, bufferCount = 0, 0 - qgisPoint = QgsGeometry.fromPointXY(point) + qgisPoint = QgsGeometry() + qgisPoint.fromWkb(point) + # qgisPoint = QgsGeometry.fromPointXY(point) # search radius to narrow down candidates buffer = qgisPoint.buffer(searchRadius, -1) bufferBB = buffer.boundingBox()