Sự khác biệt giữa hai lớp trong PostGIS


8

Cách đúng để tính sự khác biệt giữa hai lớp là gì? Tôi đã thử sử dụng cách tiếp cận sau:

SELECT ST_Difference(river.geom, lakes.geom) 
FROM river LEFT JOIN lakes ON ST_Intersects(river.geom, lakes.geom) 

Nhưng trong đầu ra, tôi mất hình học của riverlớp không giao với bất kỳ hình học nào trong đó lakes. Có vẻ như tham gia trái không hoạt động như mong đợi.

Hiện tại, tôi đang sử dụng một phương pháp khác, nhưng tôi không chắc điều này là chính xác:

SELECT ST_Difference(river.geom, lakes.geom) 
FROM river JOIN lakes ON ST_Intersects(river.geom, lakes.geom) 
UNION 
SELECT river.geom 
FROM river JOIN lakes ON NOT ST_Intersects(river.geom, lakes.geom) 

Câu trả lời:


11

Chỉ cần làm điều này:

SELECT COALESCE(ST_Difference(river.geom, lakes.geom), river.geom) As river_geom 
FROM river LEFT JOIN lakes ON ST_Intersects(river.geom, lakes.geom);

đảo ngược

SELECT COALESCE(ST_Difference(river.geom, lakes.geom), lakes.geom) As lake_geom 
FROM lakes LEFT JOIN river ON ST_Intersects(river.geom, lakes.geom);

Đó là những gì COALESCE tồn tại cho. Tôi rất thích giữ ngữ nghĩa của PostGIS theo cách họ đang có. Nó phù hợp với công nghệ được chấp nhận DB quan hệ và nếu chúng ta thực hiện công việc này, chúng ta cần thực hiện nó cho tất cả các chức năng và sau đó kết quả sẽ không thể đoán trước.


Tôi không nghĩ rằng stackexchange đang thực hiện các chỉnh sửa của mình. Điều tôi muốn nói là COALESCE (ST_Difference (river.geom, lake.geom), river.geom) As river_geom ... river LEFT THAM GIA. Nhưng hy vọng bạn có ý tưởng
LR1234567

6

Vấn đề ở đây không phải là sự tham gia trái, mà là hoạt động như mong đợi. Nhưng khi truy vấn đến một con sông không giao nhau với hồ, nó sẽ cung cấp hàm ST_Difference với NULL làm đối số thứ hai dường như trả về null.

/ Nicklas


2
Tôi nghĩ trở về NULL là điều nên làm? Như Paul đã đề cập - nó nên hoạt động như btrim, v.v. Nếu bạn muốn chỉ trả lại đối số đầu tiên khi không có kết quả khớp, bạn sẽ sử dụng COALESCE. Sự tham gia sẽ không trả lại hồ nếu sự khác biệt sẽ trống rỗng. thay đổi hành vi này sẽ phá vỡ rất nhiều mã - vì mọi người dựa vào hành vi này sau đó sẽ phải lo lắng về thứ tự của các đối số và vv. ví dụ: COALESCE (ST_Difference ..., river.geom, the_world); COALESCE cho phép bạn áp dụng số lượng đối số không xác định và là cách lập trình cơ sở dữ liệu chuẩn đối với NULL.
LR1234567

Có, bạn đã đúng, tất nhiên :-) Không nghĩ về điều đó trước đây, tại sao việc tham gia phải trả về một giá trị không xác định thay vì trống hoặc không có gì khi không có kết quả khớp.
Nicklas Avén
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.