簡體   English   中英

用Shapely查找多邊形的最大內切矩形

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM