Điểm (của một linestring) trong Đa giác bằng cách sử dụng ogr và Python


10

Tôi hiện đang làm việc trong một dự án mà tôi cần xây dựng một mạng lưới tôpô từ các tính năng hình học mà tôi tìm thấy trong các shapefiles. Cho đến nay, bằng cách sử dụng dự án nguồn mở của Ben Reilly, tôi đã quản lý để chuyển đổi các linestrings thành các cạnh mạng, cũng như phát hiện các tính năng gần gũi (các linestrings khác nói) và thêm chúng vào điểm gần nhất để tôi có thể chạy các thuật toán đường đi ngắn nhất.

Nhưng điều đó tốt cho một shapefile. Tuy nhiên, bây giờ tôi cần kết nối các tính năng từ các shapefile khác nhau thành một biểu đồ mạng lớn. Vì vậy, ví dụ, nếu một điểm nằm trong đa giác, tôi sẽ kết nối nó (bằng cách kết nối với nó, ý tôi là thêm cạnh mạngx - add_edge (g.GetPoint (1), g.GetPoint (2)) với điểm trong shapefile tiếp theo cũng nằm trong một đa giác có chung một thuộc tính tương tự (giả sử ID). Lưu ý rằng các đa giác trong các shps khác nhau chỉ chia sẻ cùng một ID chứ không phải tọa độ. Các điểm nằm trong đa giác cũng không chia sẻ cùng tọa độ.

Giải pháp của tôi cho vấn đề này là xác định điểm nằm trong đa giác, lưu trữ nó, tìm điểm trong shapefile tiếp theo nằm trong đa giác có cùng id và sau đó thêm cạnh mạngx giữa chúng.

Làm thế nào để tìm nếu một điểm nằm trong một đa giác? Chà, có một thuật toán nổi tiếng: Thuật toán RayCasting thực hiện điều đó. Đây là nơi tôi thực sự gặp khó khăn, vì để thực hiện thuật toán, tôi cần tọa độ của đa giác và không biết làm thế nào để truy cập chúng ngay bây giờ, ngay cả sau khi lướt qua tài liệu của Hình học OGR. Vì vậy, câu hỏi mà tôi đang hỏi là làm thế nào để truy cập các điểm đa giác hoặc tọa độ HOẶC có cách nào dễ dàng hơn để phát hiện xem một điểm có nằm trong đa giác không? Sử dụng python với thư viện osgeo.ogr tôi đã mã hóa như sau:

 if g.GetGeometryType() == 3: #polygon
                c = g.GetDimension()
                x = g.GetPointCount()
                y = g.GetY()
                z = g.GetZ()

xem hình ảnh để hiểu rõ hơn về vấn đề của tôi văn bản thay thế

[EDIT] Cho đến nay tôi đã cố gắng lưu trữ tất cả các đối tượng đa giác trong một danh sách mà tôi sau đó sẽ so sánh các chuỗi đường điểm đầu tiên và cuối cùng. Nhưng ví dụ của Paolo liên quan đến việc sử dụng tham chiếu Đối tượng điểm và tham chiếu Đối tượng đa giác, sẽ không hoạt động với tham chiếu đối tượng đường vì không phải toàn bộ dòng nằm trong đa giác mà là điểm đầu tiên hoặc điểm cuối cùng của dòng.

[EDIT3] Tạo một đối tượng điểm Hình học mới từ tọa độ của điểm đầu tiên và điểm cuối của dòng và sau đó sử dụng đối tượng đó để so sánh với các đối tượng hình học đa giác được lưu trong danh sách có vẻ hoạt động tốt:

for findex in xrange(lyr.GetFeatureCount()):
    f = lyr.GetFeature(findex)
    flddata = getfieldinfo(lyr,f,fields)
    g = f.geometry()
    if g.GetGeometryType() == 2:
        for j in xrange(g.GetPointCount()):
            if j == 0 or j == g.GetPointCount():
                point = ogr.Geometry(ogr.wkbPoint)
                point.AddPoint(g.Getx(j),g.GetY(j))
                if point.Within(Network.polygons[x][0].GetGeometryRef()):
    print g.GetPoint(j)

Cảm ơn PaoloChris cho gợi ý.

Câu trả lời:


11

Shapely là mát mẻ và thanh lịch, nhưng tại sao không sử dụng vẫn ogr, với các toán tử không gian của nó (trong lớp OGRGeometry)?

mã mẫu:

from osgeo import ogr
driver = ogr.GetDriverByName('ESRI Shapefile')
polyshp = driver.Open('/home/pcorti/data/shapefile/multipoly.shp')
polylyr = polyshp.GetLayer(0)
pointshp = driver.Open('/home/pcorti/data/shapefile/point.shp')
pointlyr = pointshp.GetLayer(0)
point = pointlyr.GetNextFeature()
polygon = polylyr.GetNextFeature()
point_geom = point.GetGeometryRef()
polygon_geom = polygon.GetGeometryRef()
print point_geom.Within(polygon_geom)

Lưu ý rằng bạn cần biên dịch GDAL với sự hỗ trợ của GEOS.


grzie Paolo, nhưng điều tôi thực sự cần không phải là so sánh các tham chiếu đối tượng của một điểm với một đa giác, mà là điểm cuối cùng và điểm đầu tiên của một linestring, mà tôi hiện đang truy cập với GetPoint. Tôi không nhận thấy GetPointRef. Làm thế nào tôi sẽ đi về thực hiện điều đó?
dùng39901230

1
linestring là một tập hợp hình học lặp lại của điểm (đỉnh), bạn có thể dễ dàng truy cập đầu tiên và cuối cùng của chúng.
capooti

Tôi đã cố gắng lưu trữ các đối tượng đa giác trong một danh sách mà sau này tôi sẽ sử dụng để kiểm tra điểm đầu tiên và điểm cuối của dòng. Tuy nhiên, không có điểm nào được thêm vào danh sách các điểm trong đa giác vì một số lý do: hãy xem tại đây: codepad.org/Cm2BV5mp
user39901230

8

Tôi không quen thuộc với networkx nhưng nếu tôi hiểu đúng câu hỏi của bạn, bạn có thể sử dụng quyến rũ và OGR lib cho việc tìm kiếm điểm trong đa giác từ shapefile. Dưới đây là một ví dụ về cách nó hoạt động để tìm nếu một điểm (2000,1200) không thành công với bất kỳ đa giác nào từ một shapefile. Đối với kết quả, nó in tọa độ của đa giác đó.

from shapely.geometry import Point, Polygon
from shapely.wkb import loads
from osgeo import ogr

file1 = ogr.Open("d:\\fileWithData.shp")
layer1 = file1.GetLayerByName("fileWithData")

point1 = Point(2000,1200)

polygon1 = layer1.GetNextFeature()

while polygon1 is not None:
    geomPolygon = loads(polygon1.GetGeometryRef().ExportToWkb())
    if geomPolygon.contains(point1):
        xList,yList = geomPolygon.exterior.xy
        print xList
        print yList
    polygon1 = layer1.GetNextFeature()

Tôi hy vọng nó sẽ giúp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.