Tôi đã được hỏi trong một khóa đào tạo gần đây nếu QGIS có thể tự động tính toán số trang tiếp theo / trước và trên / dưới cho một cuốn sách bản đồ được tạo bằng trình tạo bản đồ. Tôi đã quản lý để tìm ra một biểu thức nhãn khá hợp lý cho lưới thông thường nếu bạn biết chiều rộng và chiều cao của lưới.
Nhưng sau đó chúng tôi bắt đầu nghĩ về các ví dụ thực tế nơi chúng tôi không muốn vẽ các trang không chứa quận quan tâm của chúng tôi, chẳng hạn như đây là một trong những quận nhà của tôi:
Vì vậy, chiều nay tôi đã chơi một kịch bản python để tìm ra 4 người hàng xóm mà tôi quan tâm cho từng ô lưới và thêm các giá trị đó vào lưới của tôi (điều này chủ yếu dựa trên hướng dẫn của 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()
Điều này chỉ hoạt động tốt.
Nhưng thành thật mà nói, toàn bộ việc tạo ra một điểm kiểm tra về phía Bắc và sau đó kiểm tra tất cả các nước láng giềng có thể có vẻ sai. Tuy nhiên, sau một buổi chiều vắt óc, tôi không thể nghĩ ra cách nào tốt hơn để xác định đâu là hàng xóm phía bắc của một tế bào lưới cụ thể?
Lý tưởng nhất là tôi muốn một cái gì đó đủ đơn giản để đặt vào hộp văn bản của nhà soạn nhạc in, nhưng tôi nghi ngờ đó là quá nhiều để yêu cầu.