Skip to content

Commit

Permalink
Merge pull request #4950 from nyalldawson/algs
Browse files Browse the repository at this point in the history
Port some more algs to new API
  • Loading branch information
nyalldawson committed Aug 5, 2017
2 parents ca1abdc + 470afbe commit a5ddab6
Show file tree
Hide file tree
Showing 48 changed files with 2,141 additions and 675 deletions.
4 changes: 4 additions & 0 deletions python/plugins/processing/algs/help/qgis.yaml
Expand Up @@ -242,7 +242,9 @@ qgis:generatepointspixelcentroidsinsidepolygons:


qgis:hublines:
This algorithm creates hub and spoke diagrams with lines drawn from points on the Spoke Point layer to matching points in the Hub Point layer.

Determination of which hub goes with each point is based on a match between the Hub ID field on the hub points and the Spoke ID field on the spoke points.

qgis:hypsometriccurves: >
This algorithm computes hypsometric curves for an input Digital Elevation Model. Curves are produced as table files in an output folder specified by the user.
Expand Down Expand Up @@ -368,7 +370,9 @@ qgis:pointslayerfromtable: >
The attributes table of the resulting layer will be the input table.

qgis:pointstopath:
Converts a point layer to a line layer, by joining points in a defined order.

Points can be grouped by a field to output individual line features per group.

qgis:polarplot: >
This algorithm generates a polar plot based on the value of an input vector layer.
Expand Down
68 changes: 41 additions & 27 deletions python/plugins/processing/algs/qgis/EliminateSelection.py
Expand Up @@ -34,15 +34,14 @@
QgsFeature,
QgsFeatureSink,
QgsGeometry,
QgsMessageLog,
QgsProcessingUtils)
QgsProcessingException,
QgsProcessingUtils,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterEnum,
QgsProcessing,
QgsProcessingParameterFeatureSink)

from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterSelection
from processing.core.outputs import OutputVector
from processing.tools import dataobjects

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]

Expand All @@ -67,16 +66,17 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.modes = [self.tr('Largest area'),
self.modes = [self.tr('Largest Area'),
self.tr('Smallest Area'),
self.tr('Largest common boundary')]
self.tr('Largest Common Boundary')]

self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
self.addParameter(ParameterSelection(self.MODE,
self.tr('Merge selection with the neighbouring polygon with the'),
self.modes))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Eliminated'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT,
self.tr('Input layer'), [QgsProcessing.TypeVectorPolygon]))
self.addParameter(QgsProcessingParameterEnum(self.MODE,
self.tr('Merge selection with the neighbouring polygon with the'),
options=self.modes))

self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Eliminated'), QgsProcessing.TypeVectorPolygon))

def name(self):
return 'eliminateselectedpolygons'
Expand All @@ -85,29 +85,32 @@ def displayName(self):
return self.tr('Eliminate selected polygons')

def processAlgorithm(self, parameters, context, feedback):
inLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY
smallestArea = self.getParameterValue(self.MODE) == self.MODE_SMALLEST_AREA
inLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
boundary = self.parameterAsEnum(parameters, self.MODE, context) == self.MODE_BOUNDARY
smallestArea = self.parameterAsEnum(parameters, self.MODE, context) == self.MODE_SMALLEST_AREA

if inLayer.selectedFeatureCount() == 0:
QgsMessageLog.logMessage(self.tr('{0}: (No selection in input layer "{1}")').format(self.displayName(), self.getParameterValue(self.INPUT)),
self.tr('Processing'), QgsMessageLog.WARNING)
feedback.reportError(self.tr('{0}: (No selection in input layer "{1}")').format(self.displayName(), parameters[self.INPUT]))

featToEliminate = []
selFeatIds = inLayer.selectedFeatureIds()
output = self.getOutputFromName(self.OUTPUT)
writer = output.getVectorWriter(inLayer.fields(), inLayer.wkbType(), inLayer.crs(), context)

(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
inLayer.fields(), inLayer.wkbType(), inLayer.sourceCrs())

for aFeat in inLayer.getFeatures():
if feedback.isCanceled():
break

if aFeat.id() in selFeatIds:
# Keep references to the features to eliminate
featToEliminate.append(aFeat)
else:
# write the others to output
writer.addFeature(aFeat, QgsFeatureSink.FastInsert)
sink.addFeature(aFeat, QgsFeatureSink.FastInsert)

# Delete all features to eliminate in processLayer
processLayer = output.layer
processLayer = QgsProcessingUtils.mapLayerFromString(dest_id, context)
processLayer.startEditing()

# ANALYZE
Expand All @@ -129,6 +132,9 @@ def processAlgorithm(self, parameters, context, feedback):

# Iterate over the polygons to eliminate
for i in range(len(featToEliminate)):
if feedback.isCanceled():
break

feat = featToEliminate.pop()
geom2Eliminate = feat.geometry()
bbox = geom2Eliminate.boundingBox()
Expand All @@ -145,6 +151,9 @@ def processAlgorithm(self, parameters, context, feedback):
engine.prepareGeometry()

while fit.nextFeature(selFeat):
if feedback.isCanceled():
break

selGeom = selFeat.geometry()

if engine.intersects(selGeom.geometry()):
Expand Down Expand Up @@ -193,7 +202,7 @@ def processAlgorithm(self, parameters, context, feedback):
if processLayer.changeGeometry(mergeWithFid, newGeom):
madeProgress = True
else:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('Could not replace geometry of feature with id {0}').format(mergeWithFid))

start = start + add
Expand All @@ -207,7 +216,12 @@ def processAlgorithm(self, parameters, context, feedback):

# End while
if not processLayer.commitChanges():
raise GeoAlgorithmExecutionException(self.tr('Could not commit changes'))
raise QgsProcessingException(self.tr('Could not commit changes'))

for feature in featNotEliminated:
writer.addFeature(feature, QgsFeatureSink.FastInsert)
if feedback.isCanceled():
break

sink.addFeature(feature, QgsFeatureSink.FastInsert)

return {self.OUTPUT: dest_id}
81 changes: 46 additions & 35 deletions python/plugins/processing/algs/qgis/GridLine.py
Expand Up @@ -39,14 +39,15 @@
QgsPoint,
QgsLineString,
QgsWkbTypes,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterEnum,
QgsProcessingParameterExtent,
QgsProcessingParameterNumber,
QgsProcessingParameterCrs,
QgsProcessingParameterFeatureSink,
QgsFields)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.core.parameters import ParameterExtent
from processing.core.parameters import ParameterNumber
from processing.core.parameters import ParameterCrs
from processing.core.outputs import OutputVector
from processing.tools import dataobjects

pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]

Expand All @@ -73,19 +74,24 @@ def __init__(self):
super().__init__()

def initAlgorithm(self, config=None):
self.addParameter(ParameterExtent(self.EXTENT,
self.tr('Grid extent'), optional=False))
self.addParameter(ParameterNumber(self.HSPACING,
self.tr('Horizontal spacing'), 0.0, 1000000000.0, default=0.0001))
self.addParameter(ParameterNumber(self.VSPACING,
self.tr('Vertical spacing'), 0.0, 1000000000.0, default=0.0001))
self.addParameter(ParameterNumber(self.HOVERLAY,
self.tr('Horizontal overlay'), 0.0, 1000000000.0, default=0.0))
self.addParameter(ParameterNumber(self.VOVERLAY,
self.tr('Vertical overlay'), 0.0, 1000000000.0, default=0.0))
self.addParameter(ParameterCrs(self.CRS, 'Grid CRS', 'EPSG:4326'))

self.addOutput(OutputVector(self.OUTPUT, self.tr('Grid'), datatype=[dataobjects.TYPE_VECTOR_LINE]))
self.addParameter(QgsProcessingParameterExtent(self.EXTENT, self.tr('Grid extent')))

self.addParameter(QgsProcessingParameterNumber(self.HSPACING,
self.tr('Horizontal spacing'), QgsProcessingParameterNumber.Double,
0.0001, False, 0, 1000000000.0))
self.addParameter(QgsProcessingParameterNumber(self.VSPACING,
self.tr('Vertical spacing'), QgsProcessingParameterNumber.Double,
0.0001, False, 0, 1000000000.0))
self.addParameter(QgsProcessingParameterNumber(self.HOVERLAY,
self.tr('Horizontal overlay'), QgsProcessingParameterNumber.Double,
0.0, False, 0, 1000000000.0))
self.addParameter(QgsProcessingParameterNumber(self.VOVERLAY,
self.tr('Vertical overlay'), QgsProcessingParameterNumber.Double,
0.0, False, 0, 1000000000.0))

self.addParameter(QgsProcessingParameterCrs(self.CRS, 'Grid CRS', 'ProjectCrs'))

self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Grid'), type=QgsProcessing.TypeVectorLine))

def name(self):
return 'creategridlines'
Expand All @@ -94,33 +100,31 @@ def displayName(self):
return self.tr('Create grid (lines)')

def processAlgorithm(self, parameters, context, feedback):
extent = self.getParameterValue(self.EXTENT).split(',')
hSpacing = self.getParameterValue(self.HSPACING)
vSpacing = self.getParameterValue(self.VSPACING)
hOverlay = self.getParameterValue(self.HOVERLAY)
vOverlay = self.getParameterValue(self.VOVERLAY)
crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS))
hSpacing = self.parameterAsDouble(parameters, self.HSPACING, context)
vSpacing = self.parameterAsDouble(parameters, self.VSPACING, context)
hOverlay = self.parameterAsDouble(parameters, self.HOVERLAY, context)
vOverlay = self.parameterAsDouble(parameters, self.VOVERLAY, context)

bbox = QgsRectangle(float(extent[0]), float(extent[2]),
float(extent[1]), float(extent[3]))
bbox = self.parameterAsExtent(parameters, self.EXTENT, context)
crs = self.parameterAsCrs(parameters, self.CRS, context)

width = bbox.width()
height = bbox.height()

if hSpacing <= 0 or vSpacing <= 0:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('Invalid grid spacing: {0}/{1}').format(hSpacing, vSpacing))

if hSpacing <= hOverlay or vSpacing <= vOverlay:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('Invalid overlay: {0}/{1}').format(hOverlay, vOverlay))

if width < hSpacing:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('Horizontal spacing is too small for the covered area'))

if height < vSpacing:
raise GeoAlgorithmExecutionException(
raise QgsProcessingException(
self.tr('Vertical spacing is too small for the covered area'))

fields = QgsFields()
Expand All @@ -131,7 +135,8 @@ def processAlgorithm(self, parameters, context, feedback):
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
fields.append(QgsField('coord', QVariant.Double, '', 24, 15))

writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.LineString, crs, context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.LineString, crs)

if hOverlay > 0:
hSpace = [hSpacing - hOverlay, hOverlay]
Expand All @@ -154,6 +159,9 @@ def processAlgorithm(self, parameters, context, feedback):
count_update = count_max * 0.10
y = bbox.yMaximum()
while y >= bbox.yMinimum():
if feedback.isCanceled():
break

pt1 = QgsPoint(bbox.xMinimum(), y)
pt2 = QgsPoint(bbox.xMaximum(), y)
line = QgsLineString()
Expand All @@ -165,7 +173,7 @@ def processAlgorithm(self, parameters, context, feedback):
y,
id,
y])
writer.addFeature(feat, QgsFeatureSink.FastInsert)
sink.addFeature(feat, QgsFeatureSink.FastInsert)
y = y - vSpace[count % 2]
id += 1
count += 1
Expand All @@ -181,6 +189,9 @@ def processAlgorithm(self, parameters, context, feedback):
count_update = count_max * 0.10
x = bbox.xMinimum()
while x <= bbox.xMaximum():
if feedback.isCanceled():
break

pt1 = QgsPoint(x, bbox.yMaximum())
pt2 = QgsPoint(x, bbox.yMinimum())
line = QgsLineString()
Expand All @@ -192,11 +203,11 @@ def processAlgorithm(self, parameters, context, feedback):
bbox.yMinimum(),
id,
x])
writer.addFeature(feat, QgsFeatureSink.FastInsert)
sink.addFeature(feat, QgsFeatureSink.FastInsert)
x = x + hSpace[count % 2]
id += 1
count += 1
if int(math.fmod(count, count_update)) == 0:
feedback.setProgress(50 + int(count / count_max * 50))

del writer
return {self.OUTPUT: dest_id}

0 comments on commit a5ddab6

Please sign in to comment.