Geopandas Line Polygon Intersection


11

ฉันกำลังพยายามหาจุดที่หลายเส้นตัดกันรูปหลายเหลี่ยมสำหรับตำแหน่งทางภูมิศาสตร์ที่แตกต่างกันสองแห่ง:

from shapely.geometry import Polygon, LineString
import geopandas as gpd

polygon = Polygon([(0, 0), (1, 0), (1, 1), (0, 1), (0, 0)])
line1 = LineString([(0.5, 0.5), (0.7, 0.7)])
line2 = LineString([(0.9, 0.9), (0.2, 0.6)])


poly_gdf = gpd.GeoDataFrame(geometry=[polygon])
line_gdf = gpd.GeoDataFrame(geometry=[line1, line2])

นี่คือลักษณะทางภูมิศาสตร์ด้านบนที่มีลักษณะ (หนึ่งมีรูปหลายเหลี่ยมและอีกสองบรรทัดมี) ดูเหมือนว่าฉันทั้งสองเส้นตัดกันรูปหลายเหลี่ยม:

รูปหลายเหลี่ยมและเส้น

อย่างไรก็ตามเอาต์พุตตัดกันนั้นสับสนมาก:

print(line_gdf.intersects(poly_gdf))

0 จริง

1 เท็จ

print(line1.intersects(polygon))
print(line2.intersects(polygon))

จริง

จริง

ทำไมgeopandas intersectวิธีการให้แตกต่างกันออกไปตามมาตรฐานshapelyหรือไม่

ฉันใช้ Python 3.5.3 และ Geopandas 0.2.1 ทั้งหมดใน Anaconda


เมื่อคุณบอกว่าprint(line.intersects(polygon))คุณเข้าถึงตัวแปรที่ไม่ได้กำหนดเท่าที่ฉันเห็น คุณได้กำหนดไว้line1และline2ก่อนหน้านี้ในรหัส ฉันไม่รู้ว่าทำไมมันถึงกลับเป็นจริง
Paul

2
ฉันต้องการทราบคำตอบนี้เช่นกัน ดูเหมือนว่าคุณสามารถกำหนดคอลัมน์รูปทรงเรขาคณิตเดียวให้กับโครงสร้างทางภูมิศาสตร์เท่านั้น ฉันคิดว่า line_gdf data frame ของคุณพยายามเพิ่มคอลัมน์เรขาคณิตสองคอลัมน์ ลองดู geopandas.org/data_structures.html#geodataframe
Paul

@ พอลขอโทษของฉันprint(line.intersects(polygon))เป็นตัวพิมพ์ผิด ฉันได้อัปเดตคำถามเพื่ออ้างถึงline1สิ่งที่ฉันหมายถึง แต่เดิม
bgordon

@ พอลฉันเห็นได้จากเอกสารว่าการมีคอลัมน์รูปทรงเรขาคณิตสองคอลัมน์จะทำให้เกิดปัญหาได้อย่างไร แต่ฉันไม่แน่ใจว่าทำไมจึงเพิ่มคอลัมน์รูปทรงเรขาคณิตสองอันในตอนแรก
bgordon

line_gdf.infoยืนยันว่าคุณมีคอลัมน์รูปทรงเรขาคณิตเดียวเท่านั้น ฉันนิ่งงัน ฉันจะติดตามถ้าฉันพบอะไร
Paul

คำตอบ:


7

เมื่อเปรียบเทียบ Geodataframes กับการใช้รูปทรงเรขาคณิตใน Geopandas รูปทรงเรขาคณิตจะถูกจับคู่เป็นครั้งแรกโดยดัชนี ในกรณีที่ไม่มีดัชนีการจับคู่ (เพราะคุณมีเพียงรูปหลายเหลี่ยมเดียวเป็นต้น) Falseแล้วผลจะเป็น

ถ้าเป็นการเปรียบเทียบแต่ละวัตถุในนั้นGeoSeriesคุณจะต้องกลับไปเป็น dataframe แบบสี่เหลี่ยมเต็มรูปแบบของค่าบูลีนและนี่น่าจะไม่มีประสิทธิภาพมาก

หากคุณต้องการเปรียบเทียบรูปทรงเรขาคณิตทั้งหมดคุณมีสองตัวเลือก วิธีแรก (และอาจจะง่ายที่สุด) คือการใช้sjoinวิธีgeopandas :

gpd.sjoin(line_gdf, poly_gdf, op='intersects')

นี่จะคืนค่าใหม่GeoDataFrameด้วยรูปทรงเรขาคณิตสำหรับแต่ละวัตถุบนดาต้าเฟรมซ้ายซ้ำสำหรับแต่ละรูปทรงเรขาคณิตที่ตัดกันทางด้านขวาโดยมีดัชนีของวัตถุทางด้านขวาเช่น:

                        geometry  index_right
0  LINESTRING (0.5 0.5, 0.7 0.7)            0
1  LINESTRING (0.9 0.9, 0.2 0.6)            0

วิธีที่สองคือให้เราใช้applyวิธีการpandas ในการGeoSeriesส่งคืนดาต้าเฟรมที่เป็นรูปสี่เหลี่ยมผืนผ้า:

line_gdf.geometry.apply(lambda g: poly_gdf.intersects(g))

ซึ่งจะส่งกลับ (ด้วยความไร้ประสิทธิภาพที่เพิ่มขึ้นเมื่อ dataframes เติบโตขึ้น):

index_right     0
index_left
0            True
1            True

โดยทั่วไปแล้วถ้าคุณไม่ต้องการเมทริกซ์จตุรัสคำแนะนำของฉันก็คือการใช้sjoinวิธีนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.