mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
[processing] Optimise feature requests within qgis algs
- don't use setFilterFid() within loops to fetch features one at time (as it's extremely slow), instead use setFilterFids() outside the loop - don't fetch unused attributes/geometry when it can be avoided
This commit is contained in:
parent
55f207108d
commit
86368f39c3
@ -85,9 +85,9 @@ class Difference(GeoAlgorithm):
|
||||
diff_geom = QgsGeometry(geom)
|
||||
attrs = inFeatA.attributes()
|
||||
intersections = index.intersects(geom.boundingBox())
|
||||
for i in intersections:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
inFeatB = next(layerB.getFeatures(request))
|
||||
|
||||
request = QgsFeatureRequest().setFilterFids(intersections).setSubsetOfAttributes([])
|
||||
for inFeatB in layerB.getFeatures(request):
|
||||
tmpGeom = inFeatB.geometry()
|
||||
if diff_geom.intersects(tmpGeom):
|
||||
diff_geom = QgsGeometry(diff_geom.difference(tmpGeom))
|
||||
|
||||
@ -246,7 +246,7 @@ class Eliminate(GeoAlgorithm):
|
||||
geom2Eliminate = feat.geometry()
|
||||
bbox = geom2Eliminate.boundingBox()
|
||||
fit = processLayer.getFeatures(
|
||||
QgsFeatureRequest().setFilterRect(bbox))
|
||||
QgsFeatureRequest().setFilterRect(bbox).setSubsetOfAttributes([]))
|
||||
mergeWithFid = None
|
||||
mergeWithGeom = None
|
||||
max = 0
|
||||
|
||||
@ -84,9 +84,8 @@ class ExtractByLocation(GeoAlgorithm):
|
||||
geom = vector.snapToPrecision(f.geometry(), precision)
|
||||
bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision)
|
||||
intersects = index.intersects(bbox)
|
||||
for i in intersects:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
feat = next(layer.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
||||
for feat in layer.getFeatures(request):
|
||||
tmpGeom = vector.snapToPrecision(feat.geometry(), precision)
|
||||
res = False
|
||||
for predicate in predicates:
|
||||
|
||||
@ -109,7 +109,7 @@ class HubDistanceLines(GeoAlgorithm):
|
||||
src = f.geometry().boundingBox().center()
|
||||
|
||||
neighbors = index.nearestNeighbor(src, 1)
|
||||
ft = next(layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0])))
|
||||
ft = next(layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], layerHubs.fields())))
|
||||
closest = ft.geometry().boundingBox().center()
|
||||
hubDist = distance.measureLine(src, closest)
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ class HubDistancePoints(GeoAlgorithm):
|
||||
src = f.geometry().boundingBox().center()
|
||||
|
||||
neighbors = index.nearestNeighbor(src, 1)
|
||||
ft = next(layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0])))
|
||||
ft = next(layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], layerHubs.fields())))
|
||||
closest = ft.geometry().boundingBox().center()
|
||||
hubDist = distance.measureLine(src, closest)
|
||||
|
||||
|
||||
@ -88,9 +88,8 @@ class Intersection(GeoAlgorithm):
|
||||
geom = inFeatA.geometry()
|
||||
atMapA = inFeatA.attributes()
|
||||
intersects = index.intersects(geom.boundingBox())
|
||||
for i in intersects:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
inFeatB = next(vlayerB.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(intersects)
|
||||
for inFeatB in vlayerB.getFeatures(request):
|
||||
tmpGeom = inFeatB.geometry()
|
||||
if geom.intersects(tmpGeom):
|
||||
atMapB = inFeatB.attributes()
|
||||
|
||||
@ -105,9 +105,8 @@ class LinesIntersection(GeoAlgorithm):
|
||||
hasIntersections = True
|
||||
|
||||
if hasIntersections:
|
||||
for i in lines:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
inFeatB = next(layerB.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(lines)
|
||||
for inFeatB in layerB.getFeatures(request):
|
||||
tmpGeom = inFeatB.geometry()
|
||||
|
||||
points = []
|
||||
|
||||
@ -95,7 +95,7 @@ class NearestNeighbourAnalysis(GeoAlgorithm):
|
||||
for current, feat in enumerate(features):
|
||||
neighbourID = spatialIndex.nearestNeighbor(
|
||||
feat.geometry().asPoint(), 2)[1]
|
||||
request = QgsFeatureRequest().setFilterFid(neighbourID)
|
||||
request = QgsFeatureRequest().setFilterFid(neighbourID).setSubsetOfAttributes([])
|
||||
neighbour = next(layer.getFeatures(request))
|
||||
sumDist += distance.measureLine(neighbour.geometry().asPoint(),
|
||||
feat.geometry().asPoint())
|
||||
|
||||
@ -136,9 +136,8 @@ class PointDistance(GeoAlgorithm):
|
||||
featList = index.nearestNeighbor(inGeom.asPoint(), nPoints)
|
||||
distList = []
|
||||
vari = 0.0
|
||||
for i in featList:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
outFeat = next(targetLayer.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(featList).setSubsetOfAttributes([outIdx])
|
||||
for outFeat in targetLayer.getFeatures(request):
|
||||
outID = outFeat.attributes()[outIdx]
|
||||
outGeom = outFeat.geometry()
|
||||
dist = distArea.measureLine(inGeom.asPoint(),
|
||||
|
||||
@ -86,11 +86,10 @@ class PointsDisplacement(GeoAlgorithm):
|
||||
|
||||
fullPerimeter = 2 * math.pi
|
||||
|
||||
request = QgsFeatureRequest()
|
||||
for (geom, fids) in list(duplicates.items()):
|
||||
count = len(fids)
|
||||
if count == 1:
|
||||
f = next(layer.getFeatures(request.setFilterFid(fids[0])))
|
||||
f = next(layer.getFeatures(QgsFeatureRequest().setFilterFid(fids[0])))
|
||||
writer.addFeature(f)
|
||||
else:
|
||||
angleStep = fullPerimeter / count
|
||||
@ -100,14 +99,14 @@ class PointsDisplacement(GeoAlgorithm):
|
||||
currentAngle = 0
|
||||
|
||||
old_point = QgsGeometry.fromWkt(geom).asPoint()
|
||||
for fid in fids:
|
||||
|
||||
request = QgsFeatureRequest().setFilterFids(fids).setFlags(QgsFeatureRequest.NoGeometry)
|
||||
for f in layer.getFeatures(request):
|
||||
sinusCurrentAngle = math.sin(currentAngle)
|
||||
cosinusCurrentAngle = math.cos(currentAngle)
|
||||
dx = radius * sinusCurrentAngle
|
||||
dy = radius * cosinusCurrentAngle
|
||||
|
||||
f = next(layer.getFeatures(request.setFilterFid(fid)))
|
||||
|
||||
new_point = QgsPoint(old_point.x() + dx, old_point.y()
|
||||
+ dy)
|
||||
out_feature = QgsFeature()
|
||||
|
||||
@ -96,7 +96,7 @@ class PointsInPolygon(GeoAlgorithm):
|
||||
count = 0
|
||||
points = spatialIndex.intersects(geom.boundingBox())
|
||||
if len(points) > 0:
|
||||
request = QgsFeatureRequest().setFilterFids(points)
|
||||
request = QgsFeatureRequest().setFilterFids(points).setSubsetOfAttributes([])
|
||||
fit = pointLayer.getFeatures(request)
|
||||
ftPoint = QgsFeature()
|
||||
while fit.nextFeature(ftPoint):
|
||||
|
||||
@ -90,7 +90,7 @@ class PointsInPolygonUnique(GeoAlgorithm):
|
||||
classes = set()
|
||||
points = spatialIndex.intersects(geom.boundingBox())
|
||||
if len(points) > 0:
|
||||
request = QgsFeatureRequest().setFilterFids(points)
|
||||
request = QgsFeatureRequest().setFilterFids(points).setSubsetOfAttributes([classFieldIndex])
|
||||
fit = pointLayer.getFeatures(request)
|
||||
ftPoint = QgsFeature()
|
||||
while fit.nextFeature(ftPoint):
|
||||
|
||||
@ -98,7 +98,7 @@ class PointsInPolygonWeighted(GeoAlgorithm):
|
||||
points = spatialIndex.intersects(geom.boundingBox())
|
||||
if len(points) > 0:
|
||||
progress.setText(str(len(points)))
|
||||
request = QgsFeatureRequest().setFilterFids(points)
|
||||
request = QgsFeatureRequest().setFilterFids(points).setSubsetOfAttributes([fieldIdx])
|
||||
fit = pointLayer.getFeatures(request)
|
||||
ftPoint = QgsFeature()
|
||||
while fit.nextFeature(ftPoint):
|
||||
|
||||
@ -88,7 +88,7 @@ class RandomPointsAlongLines(GeoAlgorithm):
|
||||
while nIterations < maxIterations and nPoints < pointCount:
|
||||
# pick random feature
|
||||
fid = random.randint(0, featureCount - 1)
|
||||
f = next(layer.getFeatures(request.setFilterFid(fid)))
|
||||
f = next(layer.getFeatures(request.setFilterFid(fid).setSubsetOfAttributes([])))
|
||||
fGeom = f.geometry()
|
||||
|
||||
if fGeom.isMultipart():
|
||||
|
||||
@ -88,8 +88,6 @@ class RandomPointsLayer(GeoAlgorithm):
|
||||
index = QgsSpatialIndex()
|
||||
points = dict()
|
||||
|
||||
request = QgsFeatureRequest()
|
||||
|
||||
random.seed()
|
||||
|
||||
while nIterations < maxIterations and nPoints < pointCount:
|
||||
@ -101,8 +99,8 @@ class RandomPointsLayer(GeoAlgorithm):
|
||||
ids = idxLayer.intersects(geom.buffer(5, 5).boundingBox())
|
||||
if len(ids) > 0 and \
|
||||
vector.checkMinDistance(pnt, index, minDistance, points):
|
||||
for i in ids:
|
||||
f = next(layer.getFeatures(request.setFilterFid(i)))
|
||||
request = QgsFeatureRequest().setFilterFids(ids).setSubsetOfAttributes([])
|
||||
for f in layer.getFeatures(request):
|
||||
tmpGeom = f.geometry()
|
||||
if geom.within(tmpGeom):
|
||||
f = QgsFeature(nPoints)
|
||||
|
||||
@ -111,7 +111,7 @@ class SelectByAttribute(GeoAlgorithm):
|
||||
|
||||
qExp = QgsExpression(expr)
|
||||
if not qExp.hasParserError():
|
||||
qReq = QgsFeatureRequest(qExp)
|
||||
qReq = QgsFeatureRequest(qExp).setSubsetOfAttributes([])
|
||||
else:
|
||||
raise GeoAlgorithmExecutionException(qExp.parserErrorString())
|
||||
selected = [f.id() for f in layer.getFeatures(qReq)]
|
||||
|
||||
@ -82,8 +82,8 @@ class SelectByAttributeSum(GeoAlgorithm):
|
||||
progress.setInfo(self.tr('No adjacent features found.'))
|
||||
break
|
||||
|
||||
for i in intersected:
|
||||
ft = next(layer.getFeatures(req.setFilterFid(i)))
|
||||
req = QgsFeatureRequest().setFilterFids(intersected).setSubsetOfAttributes([fieldName], layer.fields())
|
||||
for ft in layer.getFeatures(req):
|
||||
tmpGeom = ft.geometry()
|
||||
if tmpGeom.touches(geom):
|
||||
geom = tmpGeom.combine(geom)
|
||||
|
||||
@ -105,9 +105,8 @@ class SelectByLocation(GeoAlgorithm):
|
||||
bbox = vector.bufferedBoundingBox(geom.boundingBox(), 0.51 * precision)
|
||||
intersects = index.intersects(bbox)
|
||||
|
||||
for i in intersects:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
feat = next(inputLayer.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
||||
for feat in inputLayer.getFeatures(request):
|
||||
tmpGeom = vector.snapToPrecision(feat.geometry(), precision)
|
||||
|
||||
res = False
|
||||
|
||||
@ -79,9 +79,8 @@ class SplitLinesWithLines(GeoAlgorithm):
|
||||
if len(lines) > 0: # hasIntersections
|
||||
splittingLines = []
|
||||
|
||||
for i in lines:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
inFeatB = next(layerB.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(lines).setSubsetOfAttributes([])
|
||||
for inFeatB in layerB.getFeatures(request):
|
||||
# check if trying to self-intersect
|
||||
if sameLayer:
|
||||
if inFeatA.id() == inFeatB.id():
|
||||
|
||||
@ -104,9 +104,8 @@ class SumLines(GeoAlgorithm):
|
||||
hasIntersections = True
|
||||
|
||||
if hasIntersections:
|
||||
for i in lines:
|
||||
request = QgsFeatureRequest().setFilterFid(i)
|
||||
ftLine = next(lineLayer.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(lines).setSubsetOfAttributes([])
|
||||
for ftLine in lineLayer.getFeatures(request):
|
||||
tmpGeom = ftLine.geometry()
|
||||
if inGeom.intersects(tmpGeom):
|
||||
outGeom = inGeom.intersection(tmpGeom)
|
||||
|
||||
@ -88,8 +88,8 @@ class SymmetricalDifference(GeoAlgorithm):
|
||||
diffGeom = QgsGeometry(geom)
|
||||
attrs = featA.attributes()
|
||||
intersects = indexA.intersects(geom.boundingBox())
|
||||
for i in intersects:
|
||||
layerB.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
|
||||
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
||||
for featB in layerB.getFeatures(request):
|
||||
tmpGeom = featB.geometry()
|
||||
if diffGeom.intersects(tmpGeom):
|
||||
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
|
||||
@ -123,8 +123,8 @@ class SymmetricalDifference(GeoAlgorithm):
|
||||
attrs = featA.attributes()
|
||||
attrs = [NULL] * length + attrs
|
||||
intersects = indexB.intersects(geom.boundingBox())
|
||||
for i in intersects:
|
||||
layerA.getFeatures(QgsFeatureRequest().setFilterFid(i)).nextFeature(featB)
|
||||
request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([])
|
||||
for featB in layerA.getFeatures(request):
|
||||
tmpGeom = featB.geometry()
|
||||
if diffGeom.intersects(tmpGeom):
|
||||
diffGeom = QgsGeometry(diffGeom.difference(tmpGeom))
|
||||
|
||||
@ -105,10 +105,10 @@ class Union(GeoAlgorithm):
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
else:
|
||||
for id in intersects:
|
||||
request = QgsFeatureRequest().setFilterFids(intersects)
|
||||
for inFeatB in vlayerB.getFeatures(request):
|
||||
count += 1
|
||||
request = QgsFeatureRequest().setFilterFid(id)
|
||||
inFeatB = next(vlayerB.getFeatures(request))
|
||||
|
||||
atMapB = inFeatB.attributes()
|
||||
tmpGeom = inFeatB.geometry()
|
||||
|
||||
@ -197,9 +197,8 @@ class Union(GeoAlgorithm):
|
||||
ProcessingLog.addToLog(ProcessingLog.LOG_INFO,
|
||||
self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'))
|
||||
else:
|
||||
for id in intersects:
|
||||
request = QgsFeatureRequest().setFilterFid(id)
|
||||
inFeatB = next(vlayerA.getFeatures(request))
|
||||
request = QgsFeatureRequest().setFilterFids(intersects)
|
||||
for inFeatB in vlayerA.getFeatures(request):
|
||||
atMapB = inFeatB.attributes()
|
||||
tmpGeom = inFeatB.geometry()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user