[英]Finding largest inscribed rectangle of a polygon with Shapely
我試圖在六個多邊形中定位數百萬個點。 這是我的代碼:
def find_shape(longitude,latitude):
if longitude != 0 and latitude != 0:
point = shapely.geometry.Point(longitude,latitude)
else:
return "Unknown"
for current_shape in all_shapes:
if current_shape['bounding_box'].contains(point):
if current_shape['shape'].contains(point):
return current_shape['properties']['ShapeName']
break
return "Unknown"
我已經閱讀了其他有關以勻稱方式改善多邊形點查詢性能的問題。 他們建議Rtrees。 但是,對於有多個多邊形( 一個問題為36,000個,另一個問題為 100,000個 )的情況,這似乎很有用,並且不希望對它們全部進行循環。
如您所見,我已經在設置一個邊界框。 這是我的形狀設置代碼:
with fiona.open(SHAPEFILE) as f_col:
all_shapes = []
for shapefile_record in f_col:
current_shape = {}
current_shape['shape'] = shapely.geometry.asShape(shapefile_record['geometry'])
minx, miny, maxx, maxy = current_shape['shape'].bounds
current_shape['bounding_box'] = shapely.geometry.box(minx, miny, maxx, maxy)
current_shape['properties'] = shapefile_record['properties']
all_shapes.append(current_shape)
同時檢查該形狀的另一個非常簡化的版本(即由最大內切矩形(或三角形)制成的形狀)是否有用 ?
檢查整齊的文檔,似乎沒有此功能。 也許一些simplify()
設置? 當然,我總是要確保新的簡化形狀不會超出原始形狀的范圍,因此我不必在實際形狀上調用contains()
。 我還認為我想使新的簡化形狀盡可能簡單,以提高速度。
任何其他建議也表示贊賞。 謝謝!
編輯 :在等待答復時,我想到了創建符合我要求的簡化形狀的想法:
current_shape['simple_shape'] = current_shape['shape'].simplify(.5)
current_shape['simple_shape'] = current_shape['simple_shape'].intersection(current_shape['shape'])
測試每個點時,我將使用以下方法:
if current_shape['simple_shape'].contains(point):
return current_shape['properties']['ShapeName']
elif current_shape['shape'].contains(point):
return current_shape['properties']['ShapeName']
這不是完美的,因為形狀並不像進行必要的intersection()
之后那樣簡單。 盡管如此,這種方法仍使處理時間減少了60%。 在我的測試中,簡單多邊形用於85%的點查詢。
編輯2 :關於GIS StackExchange的另一個相關問題: Python效率—需要有關如何以更有效的方式使用OGR和Shapely的建議 。 這涉及約3,000個多邊形中的150萬個點。
我會使用R樹。 但是我會將所有點(而不是多邊形的邊界框)插入R-Tree。
例如,使用r樹索引: http : //toblerity.org/rtree/
from rtree import index
from rtree.index import Rtree
idx = index.Index();
//插入一個點,即在其中left == right && top == bottom的地方,實際上將在索引中插入一個點
for current_point in all_points:
idx.insert(current_point.id, (current_point.x, current_point.y, current_point.x, current_point.y))
//現在遍歷多邊形
for current_shape in all_shapes:
for n in idx.intersect( current_shape['bounding_box'] )
if current_shape['shape'].contains(n):
# now we know that n is inside the current shape
因此,您最終在大型R-Tree上進行了六次查詢,而不是在小型R-Tree上進行了數百萬次查詢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.