Podczas ostatniego szkolenia zapytano mnie, czy QGIS może automatycznie obliczyć numery następnych / poprzednich i powyżej / poniżej stron książek z mapami utworzonych za pomocą generatora atlasu. Udało mi się wypracować dość rozsądne wyrażenie etykiety dla regularnej siatki, jeśli znasz szerokość i wysokość siatki.
Ale potem zaczęliśmy myśleć o realistycznych przykładach, w których nie chcemy rysować stron, które nie zawierają naszej dzielnicy zainteresowań, takich jak ten w moim rodzinnym hrabstwie:
Więc tego popołudnia bawiłem się skryptem Pythona, aby obliczyć 4 sąsiadów, którymi byłem zainteresowany dla każdej komórki siatki i dodałem te wartości do mojej siatki (jest to w dużej mierze oparte na tutorialu Ujavala Gandhiego ):
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()
To działa dobrze.
Ale szczerze mówiąc, stworzenie punktu testowego na północ, a następnie przetestowanie wszystkich możliwych sąsiadów wydaje się błędne. Jednak po popołudniowym zniszczeniu mózgu nie mogę wymyślić lepszego sposobu na określenie, kto jest północnym sąsiadem konkretnej komórki sieci?
Idealnie chciałbym, aby coś prostego umieścić w polu tekstowym kompozytora wydruku, ale podejrzewam, że to zbyt wiele, o co mogę prosić.