In un recente corso di formazione mi è stato chiesto se QGIS potesse calcolare automaticamente i numeri di pagina successiva / precedente e sopra / sotto per un libro di mappe creato usando il generatore di atlanti. Sono riuscito a elaborare un'espressione dell'etichetta abbastanza ragionevole per una griglia normale se conosci la larghezza e l'altezza della griglia.
Ma poi abbiamo iniziato a pensare ad esempi realistici in cui non vogliamo disegnare pagine che non contengono il nostro distretto di interesse, come questo del mio paese di origine:
Quindi oggi pomeriggio ho suonato in uno script Python per elaborare i 4 vicini a cui ero interessato per ogni cella della griglia e ho aggiunto quei valori alla mia griglia (questo è fortemente basato sul tutorial di Ujaval Gandhi ):
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()
Questo funziona bene.
Ma ad essere sincero, il tutto creando un punto di prova a nord e poi testando tutti i possibili vicini sembra sbagliato. Tuttavia, dopo un pomeriggio di distruzione del mio cervello, non riesco a pensare a un modo migliore per determinare quale sia il vicino settentrionale di una particolare cellula della griglia?
Idealmente, vorrei qualcosa di abbastanza semplice da inserire in una casella di testo per il compositore di stampe, ma sospetto che sia troppo da chiedere.