Ich wurde kürzlich in einem Schulungskurs gefragt, ob QGIS die nächsten / vorherigen und oberen / unteren Seitenzahlen für ein mit dem Atlasgenerator erstelltes Kartenbuch automatisch berechnen kann. Ich habe es geschafft, einen ziemlich vernünftigen Beschriftungsausdruck für ein reguläres Raster zu erarbeiten, wenn Sie die Breite und Höhe des Rasters kennen.
Aber dann haben wir uns realistische Beispiele ausgedacht, bei denen wir keine Seiten zeichnen möchten, die nicht unseren interessierenden Bezirk enthalten, wie diesen aus meinem Heimatland:
Also habe ich heute Nachmittag ein Python-Skript gespielt, um die 4 Nachbarn, an denen ich interessiert war, für jede Gitterzelle herauszufinden und diese Werte zu meinem Gitter hinzuzufügen (dies basiert stark auf Ujaval Gandhis Tutorial ):
for f in feature_dict.values():
print 'Working on %s' % f[_NAME_FIELD]
geom = f.geometry()
# Find all features that intersect the bounding box of the current feature.
# We use spatial index to find the features intersecting the bounding box
# of the current feature. This will narrow down the features that we need
# to check neighboring features.
intersecting_ids = index.intersects(geom.boundingBox())
# Initalize neighbors list and sum
neighbors = []
neighbors_sum = 0
for intersecting_id in intersecting_ids:
# Look up the feature from the dictionary
intersecting_f = feature_dict[intersecting_id]
int_geom = intersecting_f.geometry()
centroid = geom.centroid()
height = geom.boundingBox().height()
width = geom.boundingBox().width()
# For our purpose we consider a feature as 'neighbor' if it touches or
# intersects a feature. We use the 'disjoint' predicate to satisfy
# these conditions. So if a feature is not disjoint, it is a neighbor.
if (f != intersecting_f and
not int_geom.disjoint(geom)):
above_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x(),
centroid.asPoint().y()+height))
below_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x(),
centroid.asPoint().y()-height))
left_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x()-width,
centroid.asPoint().y()))
right_point = QgsGeometry.fromPoint(QgsPoint(centroid.asPoint().x()+width,
centroid.asPoint().y()))
above = int_geom.contains(above_point)
below = int_geom.contains(below_point)
left = int_geom.contains(left_point)
right = int_geom.contains(right_point)
if above:
print "setting %d as above %d"%(intersecting_f['id'],f['id'])
f['above']=intersecting_f['id']
if below:
print "setting %d as below %d"%(intersecting_f['id'],f['id'])
f['below']=intersecting_f['id']
if left:
print "setting %d as left of %d"%(intersecting_f['id'],f['id'])
f['left']=intersecting_f['id']
if right:
print "setting %d as right of %d"%(intersecting_f['id'],f['id'])
f['right']=intersecting_f['id']
# Update the layer with new attribute values.
layer.updateFeature(f)
layer.commitChanges()
Das funktioniert gut.
Aber um ehrlich zu sein, scheint es falsch, das Ganze einen Testpunkt nach Norden zu schaffen und dann alle möglichen Nachbarn zu testen. Nach einem Nachmittag, an dem ich mir das Gehirn zerbrochen habe, kann ich mir keinen besseren Weg vorstellen, um festzustellen, was der nördliche Nachbar einer bestimmten Gitterzelle ist.
Idealerweise hätte ich gerne etwas, das einfach genug ist, um es in ein Textfeld für Druckkomponisten einzufügen, aber ich vermute, das ist zu viel verlangt.