本文整理汇总了Python中qgis.core.QgsSpatialIndex.addFeature方法的典型用法代码示例。如果您正苦于以下问题:Python QgsSpatialIndex.addFeature方法的具体用法?Python QgsSpatialIndex.addFeature怎么用?Python QgsSpatialIndex.addFeature使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类qgis.core.QgsSpatialIndex
的用法示例。
在下文中一共展示了QgsSpatialIndex.addFeature方法的7个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Python代码示例。
示例1: processAlgorithm
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def processAlgorithm(self, parameters, context, feedback):
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context)
bbox = self.parameterAsExtent(parameters, self.EXTENT, context, crs)
extent = QgsGeometry().fromRect(bbox)
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.Point, crs)
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
nPoints = 0
nIterations = 0
maxIterations = pointCount * 200
total = 100.0 / pointCount if pointCount else 1
index = QgsSpatialIndex()
points = dict()
random.seed()
while nIterations < maxIterations and nPoints < pointCount:
if feedback.isCanceled():
break
rx = bbox.xMinimum() + bbox.width() * random.random()
ry = bbox.yMinimum() + bbox.height() * random.random()
p = QgsPointXY(rx, ry)
geom = QgsGeometry.fromPointXY(p)
if geom.within(extent) and \
vector.checkMinDistance(p, index, minDistance, points):
f = QgsFeature(nPoints)
f.initAttributes(1)
f.setFields(fields)
f.setAttribute('id', nPoints)
f.setGeometry(geom)
sink.addFeature(f, QgsFeatureSink.FastInsert)
index.addFeature(f)
points[nPoints] = p
nPoints += 1
feedback.setProgress(int(nPoints * total))
nIterations += 1
if nPoints < pointCount:
feedback.pushInfo(self.tr('Could not generate requested number of random points. '
'Maximum number of attempts exceeded.'))
return {self.OUTPUT: dest_id}
示例2: compute_graph
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def compute_graph(features, feedback, create_id_graph=False, min_distance=0):
""" compute topology from a layer/field """
s = Graph(sort_graph=False)
id_graph = None
if create_id_graph:
id_graph = Graph(sort_graph=True)
# skip features without geometry
features_with_geometry = {f_id: f for (f_id, f) in features.items() if f.hasGeometry()}
total = 70.0 / len(features_with_geometry) if features_with_geometry else 1
index = QgsSpatialIndex()
i = 0
for feature_id, f in features_with_geometry.items():
if feedback.isCanceled():
break
g = f.geometry()
if min_distance > 0:
g = g.buffer(min_distance, 5)
engine = QgsGeometry.createGeometryEngine(g.constGet())
engine.prepareGeometry()
feature_bounds = g.boundingBox()
# grow bounds a little so we get touching features
feature_bounds.grow(feature_bounds.width() * 0.01)
intersections = index.intersects(feature_bounds)
for l2 in intersections:
f2 = features_with_geometry[l2]
if engine.intersects(f2.geometry().constGet()):
s.add_edge(f.id(), f2.id())
s.add_edge(f2.id(), f.id())
if id_graph:
id_graph.add_edge(f.id(), f2.id())
index.addFeature(f)
i += 1
feedback.setProgress(int(i * total))
for feature_id, f in features_with_geometry.items():
if feedback.isCanceled():
break
if feature_id not in s.node_edge:
s.add_edge(feature_id, None)
return s, id_graph
示例3: processAlgorithm
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
bbox = source.sourceExtent()
sourceIndex = QgsSpatialIndex(source, feedback)
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.Point, source.sourceCrs())
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
nPoints = 0
nIterations = 0
maxIterations = pointCount * 200
total = 100.0 / pointCount if pointCount else 1
index = QgsSpatialIndex()
points = dict()
random.seed()
while nIterations < maxIterations and nPoints < pointCount:
if feedback.isCanceled():
break
rx = bbox.xMinimum() + bbox.width() * random.random()
ry = bbox.yMinimum() + bbox.height() * random.random()
p = QgsPointXY(rx, ry)
geom = QgsGeometry.fromPointXY(p)
ids = sourceIndex.intersects(geom.buffer(5, 5).boundingBox())
if len(ids) > 0 and \
vector.checkMinDistance(p, index, minDistance, points):
request = QgsFeatureRequest().setFilterFids(ids).setSubsetOfAttributes([])
for f in source.getFeatures(request):
if feedback.isCanceled():
break
tmpGeom = f.geometry()
if geom.within(tmpGeom):
f = QgsFeature(nPoints)
f.initAttributes(1)
f.setFields(fields)
f.setAttribute('id', nPoints)
f.setGeometry(geom)
sink.addFeature(f, QgsFeatureSink.FastInsert)
index.addFeature(f)
points[nPoints] = p
nPoints += 1
feedback.setProgress(int(nPoints * total))
nIterations += 1
if nPoints < pointCount:
feedback.pushInfo(self.tr('Could not generate requested number of random points. '
'Maximum number of attempts exceeded.'))
return {self.OUTPUT: dest_id}
示例4: processAlgorithm
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.Point, source.sourceCrs())
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
nPoints = 0
nIterations = 0
maxIterations = pointCount * 200
featureCount = source.featureCount()
total = 100.0 / pointCount if pointCount else 1
index = QgsSpatialIndex()
points = dict()
da = QgsDistanceArea()
da.setSourceCrs(source.sourceCrs(), context.transformContext())
da.setEllipsoid(context.project().ellipsoid())
request = QgsFeatureRequest()
random.seed()
while nIterations < maxIterations and nPoints < pointCount:
if feedback.isCanceled():
break
# pick random feature
fid = random.randint(0, featureCount - 1)
f = next(source.getFeatures(request.setFilterFid(fid).setSubsetOfAttributes([])))
fGeom = f.geometry()
if fGeom.isMultipart():
lines = fGeom.asMultiPolyline()
# pick random line
lineId = random.randint(0, len(lines) - 1)
vertices = lines[lineId]
else:
vertices = fGeom.asPolyline()
# pick random segment
if len(vertices) == 2:
vid = 0
else:
vid = random.randint(0, len(vertices) - 2)
startPoint = vertices[vid]
endPoint = vertices[vid + 1]
length = da.measureLine(startPoint, endPoint)
dist = length * random.random()
if dist > minDistance:
d = dist / (length - dist)
rx = (startPoint.x() + d * endPoint.x()) / (1 + d)
ry = (startPoint.y() + d * endPoint.y()) / (1 + d)
# generate random point
p = QgsPointXY(rx, ry)
geom = QgsGeometry.fromPointXY(p)
if vector.checkMinDistance(p, index, minDistance, points):
f = QgsFeature(nPoints)
f.initAttributes(1)
f.setFields(fields)
f.setAttribute('id', nPoints)
f.setGeometry(geom)
sink.addFeature(f, QgsFeatureSink.FastInsert)
index.addFeature(f)
points[nPoints] = p
nPoints += 1
feedback.setProgress(int(nPoints * total))
nIterations += 1
if nPoints < pointCount:
feedback.pushInfo(self.tr('Could not generate requested number of random points. '
'Maximum number of attempts exceeded.'))
return {self.OUTPUT: dest_id}
示例5: processAlgorithm
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
proximity = self.parameterAsDouble(parameters, self.PROXIMITY, context)
radius = self.parameterAsDouble(parameters, self.DISTANCE, context)
horizontal = self.parameterAsBool(parameters, self.HORIZONTAL, context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
features = source.getFeatures()
total = 100.0 / source.featureCount() if source.featureCount() else 0
def searchRect(p):
return QgsRectangle(p.x() - proximity, p.y() - proximity, p.x() + proximity, p.y() + proximity)
index = QgsSpatialIndex()
# NOTE: this is a Python port of QgsPointDistanceRenderer::renderFeature. If refining this algorithm,
# please port the changes to QgsPointDistanceRenderer::renderFeature also!
clustered_groups = []
group_index = {}
group_locations = {}
for current, f in enumerate(features):
if feedback.isCanceled():
break
if not f.hasGeometry():
continue
point = f.geometry().asPoint()
other_features_within_radius = index.intersects(searchRect(point))
if not other_features_within_radius:
index.addFeature(f)
group = [f]
clustered_groups.append(group)
group_index[f.id()] = len(clustered_groups) - 1
group_locations[f.id()] = point
else:
# find group with closest location to this point (may be more than one within search tolerance)
min_dist_feature_id = other_features_within_radius[0]
min_dist = group_locations[min_dist_feature_id].distance(point)
for i in range(1, len(other_features_within_radius)):
candidate_id = other_features_within_radius[i]
new_dist = group_locations[candidate_id].distance(point)
if new_dist < min_dist:
min_dist = new_dist
min_dist_feature_id = candidate_id
group_index_pos = group_index[min_dist_feature_id]
group = clustered_groups[group_index_pos]
# calculate new centroid of group
old_center = group_locations[min_dist_feature_id]
group_locations[min_dist_feature_id] = QgsPointXY((old_center.x() * len(group) + point.x()) / (len(group) + 1.0),
(old_center.y() * len(group) + point.y()) / (len(group) + 1.0))
# add to a group
clustered_groups[group_index_pos].append(f)
group_index[f.id()] = group_index_pos
feedback.setProgress(int(current * total))
current = 0
total = 100.0 / len(clustered_groups) if clustered_groups else 1
feedback.setProgress(0)
fullPerimeter = 2 * math.pi
for group in clustered_groups:
if feedback.isCanceled():
break
count = len(group)
if count == 1:
sink.addFeature(group[0], QgsFeatureSink.FastInsert)
else:
angleStep = fullPerimeter / count
if count == 2 and horizontal:
currentAngle = math.pi / 2
else:
currentAngle = 0
old_point = group_locations[group[0].id()]
for f in group:
if feedback.isCanceled():
break
sinusCurrentAngle = math.sin(currentAngle)
cosinusCurrentAngle = math.cos(currentAngle)
dx = radius * sinusCurrentAngle
dy = radius * cosinusCurrentAngle
#.........这里部分代码省略.........
示例6: processAlgorithm
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)
expression = QgsExpression(self.parameterAsString(parameters, self.EXPRESSION, context))
if expression.hasParserError():
raise QgsProcessingException(expression.parserErrorString())
expressionContext = self.createExpressionContext(parameters, context, source)
expression.prepare(expressionContext)
fields = QgsFields()
fields.append(QgsField('id', QVariant.Int, '', 10, 0))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.Point, source.sourceCrs(), QgsFeatureSink.RegeneratePrimaryKey)
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
da = QgsDistanceArea()
da.setSourceCrs(source.sourceCrs(), context.transformContext())
da.setEllipsoid(context.project().ellipsoid())
total = 100.0 / source.featureCount() if source.featureCount() else 0
current_progress = 0
for current, f in enumerate(source.getFeatures()):
if feedback.isCanceled():
break
if not f.hasGeometry():
continue
current_progress = total * current
feedback.setProgress(current_progress)
expressionContext.setFeature(f)
value = expression.evaluate(expressionContext)
if expression.hasEvalError():
feedback.pushInfo(
self.tr('Evaluation error for feature ID {}: {}').format(f.id(), expression.evalErrorString()))
continue
fGeom = f.geometry()
engine = QgsGeometry.createGeometryEngine(fGeom.constGet())
engine.prepareGeometry()
bbox = fGeom.boundingBox()
if strategy == 0:
pointCount = int(value)
else:
pointCount = int(round(value * da.measureArea(fGeom)))
if pointCount == 0:
feedback.pushInfo("Skip feature {} as number of points for it is 0.".format(f.id()))
continue
index = QgsSpatialIndex()
points = dict()
nPoints = 0
nIterations = 0
maxIterations = pointCount * 200
feature_total = total / pointCount if pointCount else 1
random.seed()
while nIterations < maxIterations and nPoints < pointCount:
if feedback.isCanceled():
break
rx = bbox.xMinimum() + bbox.width() * random.random()
ry = bbox.yMinimum() + bbox.height() * random.random()
p = QgsPointXY(rx, ry)
geom = QgsGeometry.fromPointXY(p)
if engine.contains(geom.constGet()) and \
vector.checkMinDistance(p, index, minDistance, points):
f = QgsFeature(nPoints)
f.initAttributes(1)
f.setFields(fields)
f.setAttribute('id', nPoints)
f.setGeometry(geom)
sink.addFeature(f, QgsFeatureSink.FastInsert)
index.addFeature(f)
points[nPoints] = p
nPoints += 1
feedback.setProgress(current_progress + int(nPoints * feature_total))
nIterations += 1
if nPoints < pointCount:
feedback.pushInfo(self.tr('Could not generate requested number of random '
'points. Maximum number of attempts exceeded.'))
feedback.setProgress(100)
return {self.OUTPUT: dest_id}
示例7: processAlgorithm
# 需要导入模块: from qgis.core import QgsSpatialIndex [as 别名]
# 或者: from qgis.core.QgsSpatialIndex import addFeature [as 别名]
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())
if sink is None:
raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT))
features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([]))
total = 100.0 / source.featureCount() if source.featureCount() else 0
geoms = dict()
index = QgsSpatialIndex()
for current, f in enumerate(features):
if feedback.isCanceled():
break
geoms[f.id()] = f.geometry()
index.addFeature(f)
feedback.setProgress(int(0.10 * current * total)) # takes about 10% of time
# start by assuming everything is unique, and chop away at this list
unique_features = dict(geoms)
current = 0
for feature_id, geometry in geoms.items():
if feedback.isCanceled():
break
if feature_id not in unique_features:
# feature was already marked as a duplicate
continue
candidates = index.intersects(geometry.boundingBox())
candidates.remove(feature_id)
for candidate_id in candidates:
if candidate_id not in unique_features:
# candidate already marked as a duplicate (not sure if this is possible,
# since it would mean the current feature would also have to be a duplicate!
# but let's be safe!)
continue
if geometry.isGeosEqual(geoms[candidate_id]):
# candidate is a duplicate of feature
del unique_features[candidate_id]
current += 1
feedback.setProgress(int(0.80 * current * total) + 10) # takes about 80% of time
total = 100.0 / len(unique_features) if unique_features else 1
# now, fetch all the feature attributes for the unique features only
# be super-smart and don't re-fetch geometries
request = QgsFeatureRequest().setFilterFids(list(unique_features.keys())).setFlags(QgsFeatureRequest.NoGeometry)
for current, f in enumerate(source.getFeatures(request)):
if feedback.isCanceled():
break
# use already fetched geometry
f.setGeometry(unique_features[f.id()])
sink.addFeature(f, QgsFeatureSink.FastInsert)
feedback.setProgress(int(0.10 * current * total) + 90) # takes about 10% of time
return {self.OUTPUT: dest_id}