Lọc theo giới hạn hộp trong geopandas?


11

Tôi có một khung dữ liệu geopandas trong EPSG: 4326 và tôi sẽ tạo một khung dữ liệu mới bao gồm tất cả các hàng nằm trong một khung giới hạn nhất định.

Đầu tiên tôi nhận được hộp giới hạn mà tôi quan tâm (thực ra là hộp giới hạn của khung dữ liệu khác):

print df_sussex.total_bounds
[ -1.57239292  50.57467674   0.14528384  51.27465152]

Sau đó, tôi tạo một khung dữ liệu chỉ bao gồm hộp giới hạn đó:

pts = gpd.GeoDataFrame(df_sussex.total_bounds)

Và cuối cùng tôi cố gắng để có được tất cả các tính năng giao nhau với hộp giới hạn đó:

sac_sussex = gpd.overlay(pts, df_sac, how='intersection')

Nhưng điều này mang lại cho tôi AttributeError: No geometry data set yet (expected in column 'geometry'.

Tôi đang làm gì sai?


Vấn đề là bởi vì bạn đang sử dụng phương pháp 'Total_bound'. Nó chỉ tạo ra một tuple với các điểm giới hạn tối đa và tối thiểu của hộp giới hạn. Phương pháp được sử dụng là 'phong bì'; trước đây để xây dựng GeoDataFrame tương ứng của nó .
xunilk

Câu trả lời:


5

Vấn đề là bởi vì bạn đang sử dụng phương pháp 'Total_bound'. Nó chỉ tạo ra một tuple với các điểm giới hạn tối đa và tối thiểu của hộp giới hạn. Phương pháp được sử dụng là 'phong bì'; trước đây để xây dựng 'GeoDataFrame' tương ứng. Chẳng hạn, đọc các shapefiles của tôi dưới dạng GeoDataFrame :

import geopandas as gpd
pol1 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon1.shp")
pol8 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon8.shp")

Xây dựng hộp giới hạn của pol1 và tạo GeoDataFrame tương ứng của nó :

bounding_box = pol1.envelope
df = gpd.GeoDataFrame(gpd.GeoSeries(bounding_box), columns=['geometry'])

Giao cắt cả GeoDataFrame :

intersections = gpd.overlay(df, pol8, how='intersection')

Vẽ kết quả:

from matplotlib import pyplot as plt
plt.ion()
intersections.plot() 

nhập mô tả hình ảnh ở đây

Nó làm việc như mong đợi.

Chỉnh sửa ghi chú:

Bằng cách sử dụng phương thức 'Total_bound' (vì phương thức 'phong bì' trả về hộp giới hạn cho mỗi tính năng của đa giác), có thể sử dụng phương pháp này:

from matplotlib import pyplot as plt
import geopandas as gpd
from shapely.geometry import Point, Polygon

pol1 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon1.shp")
pol8 = gpd.GeoDataFrame.from_file("pyqgis_data/polygon8.shp")

bbox = pol1.total_bounds

p1 = Point(bbox[0], bbox[3])
p2 = Point(bbox[2], bbox[3])
p3 = Point(bbox[2], bbox[1])
p4 = Point(bbox[0], bbox[1])

np1 = (p1.coords.xy[0][0], p1.coords.xy[1][0])
np2 = (p2.coords.xy[0][0], p2.coords.xy[1][0])
np3 = (p3.coords.xy[0][0], p3.coords.xy[1][0])
np4 = (p4.coords.xy[0][0], p4.coords.xy[1][0])

bb_polygon = Polygon([np1, np2, np3, np4])

df2 = gpd.GeoDataFrame(gpd.GeoSeries(bb_polygon), columns=['geometry'])

intersections2 = gpd.overlay(df2, pol8, how='intersection')

plt.ion()
intersections2.plot()

và kết quả là giống hệt nhau.


21

Bạn có thể sử dụng cxphương thức trên geodataframe để chọn các hàng trong hộp giới hạn. Đối với khung ví dụ của bạn:

xmin, ymin, xmax, ymax = df_sussex.total_bounds
sac_sussex = df_sac.cx[xmin:xmax, ymin:ymax]

Từ http://geopandas.org/indexing.html :

Ngoài các phương thức gấu trúc tiêu chuẩn, GeoPandas cũng cung cấp lập chỉ mục dựa trên tọa độ với bộ chỉ mục cx , lát cắt sử dụng hộp giới hạn. Hình học trong GeoSeries hoặc GeoDataFrame giao với khung giới hạn sẽ được trả về.


Giải pháp này đã làm việc cho tôi. Cảm ơn bạn. Tuy nhiên, tôi đã tự hỏi nếu có một cách nhanh hơn để thực hiện. Lọc sử dụng đất OSM và các địa điểm nằm trong phạm vi giới hạn của tỉnh.
EFL

Lưu ý rằng .cxthực hiện một cái gì đó hơi khác so với gpd.overlaygiải pháp: nó chọn các hàng giao nhau với khung giới hạn nhưng vẫn giữ nguyên hình học, trong khi gpd.overlaygiải pháp sẽ chỉ trả về các phần của hình học trong hộp giới hạn. Tùy thuộc vào tình huống bạn có thể muốn cái này hay cái khác.
danvk
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.