tính phần trăm diện tích giao lộ trong đó mệnh đề


15

Tôi có một bảng đa giác (nhóm khối điều tra dân số) trong postgres. Tôi muốn gắn thẻ cho từng nhóm khối với thị trấn (một bảng đa giác khác) mà nó chủ yếu nằm trong đó. Điều này có thể không? Tôi nghĩ rằng về cơ bản tôi cần tạo ra một cái gì đó như:

select b.*,t.name  
from blockgroups b, towns t  
where (st_area(st_intersection(b.wkb_geometry, t.wkb_geometry))/st_area(b.wkb_geometry)) > .5  

nhưng truy vấn này mất nhiều thời gian (tôi có khoảng 5.000 nhóm khối và 375 thị trấn ...). Bất kỳ đề xuất nào về cách làm cho truy vấn này hoạt động cả nếu nó không chính xác hoặc nhanh hơn nếu nó đúng?


Âm thanh như bạn muốn gắn thẻ các nhóm khối dựa trên sự chồng chéo tối đa? Nếu vậy, hãy xem câu trả lời này . Nếu 'thị trấn của bạn cũng là khu vực địa lý điều tra dân số (MCD hoặc Địa điểm, có thể không cần tính toán phần trăm trùng lặp.
dbaston

Câu trả lời:


22

Cách bạn đang làm sẽ hoạt động nhưng sẽ mất quá nhiều thời gian, vì postgis đang cố gắng tạo hình học của giao điểm của mọi kết hợp "blockgroup vs town", ngay cả khi họ thậm chí không chạm vào.

Thêm một kiểm tra điều kiện khác vào mệnh đề WHERE của bạn để kiểm tra xem hai hình học có chặn hay không và đặt nó trước mệnh đề hiện có:

select b.*,t.name
from blockgroups b, towns t
where st_intersects(b.wkb_geometry, t.wkb_geometry) and    
    (st_area(st_intersection(b.wkb_geometry, t.wkb_geometry))/st_area(b.wkb_geometry)) > .5

Trong SQL nếu bạn có một danh sách các điều kiện trong mệnh đề WHERE, chúng được kiểm tra theo thứ tự chúng được viết. Nếu một FALSE được trả về trong một trong các hoạt động đầu tiên, querie sẽ bỏ qua các điều kiện khác để kiểm tra, vì kết quả sẽ luôn là FALSE.

Ngoài ra, hãy đảm bảo bạn có các chỉ mục không gian trên blockgroups.wkb_geometry và town.wkb_geometry.


1
Thêm ST_Intersectslà cách đúng đắn để đi đến đây, nhưng người lập kế hoạch có thể hoặc không thể thực hiện các điều kiện theo thứ tự họ đã viết. Xem tài liệu Postgres để biết chi tiết về điều này. ST_IntersectsST_Intersectioncó cùng chi phí cho cài đặt của tôi (100), vì vậy thành thật mà nói tôi không chắc người lập kế hoạch đang làm gì, nhưng dường như nó luôn làm đúng ở đây.
dbaston

À ... tôi đã cho rằng các điều kiện sẽ được kiểm tra như trong các ngôn ngữ khác. Nhưng tôi đoán nó cung cấp cho người lập kế hoạch một lựa chọn khác.
Alexandre Neto

9

Thêm vào câu trả lời rất hữu ích của Alexandre, nếu một số đơn vị điều tra dân số của bạn có thể trải dài ba thị trấn của bạn (và do đó bạn không thể đảm bảo hơn 50% rơi vào bất kỳ thị trấn nào), bạn có thể làm điều này:

select distinct on (b.id)
b.*,t.name,
(st_area(st_intersection(b.wkb_geometry, t.wkb_geometry))/st_area(b.wkb_geometry)) as proportion
from blockgroups b, towns t
where st_intersects(b.wkb_geometry, t.wkb_geometry) 
order by b.id, proportion desc;

Điều này về cơ bản bảo vệ chống lại tình huống sau - trong đó các khu vực màu xanh lam sẽ biến mất: nhập mô tả hình ảnh ở đây


1
Tôi hoàn toàn ngưỡng mộ nó khi vấn đề đầu tiên tôi gặp phải với câu trả lời SO được giải quyết bằng câu trả lời tiếp theo. Chúc mừng, @RobinL!
wfgeo

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.