SQL Server - Chọn tất cả các đa giác được lồng trong một đa giác lớn hơn


9

Đây là một câu hỏi hình học SQL Server có vẻ đơn giản mà tôi nghĩ sẽ có một giải pháp vượt trội, nhưng tôi không gặp may mắn khi tìm thấy một câu hỏi.

Mục đích của tôi là chọn tất cả các bản ghi trong một bảng có đa giác được lồng (chứa) trong một đa giác lớn hơn từ một bảng khác. Tôi đã có các chức năng mong đợi STWithinSTContainslà giải pháp tôi cần, nhưng thật không may, cả hai chỉ xác định các đa giác bên trong trong các đa giác được lồng trong đa giác lớn hơn, chứ không phải các đa giác lồng nhau chạm vào ranh giới của đa giác lớn hơn. Xem hình ảnh chẳng hạn.Kết quả từ cả hai hàm STWithin và STContains

Một lựa chọn thay thế phù hợp với nhu cầu của tôi là STIntersection. Tuy nhiên, vấn đề với chức năng này là nó chỉ trả về cột hình học! Tôi muốn lấy ID hồ sơ thay thế. Có ai có một đề nghị về cách này có thể được thực hiện?

STWithin:

select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STWithin(b.shape) = 1
where b.mktname = 'Loop'

STContains:

select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on b.shape.STContains(a.shape) = 1
where b.mktname = 'Loop'

STIntersection:

select a.shape.STIntersection(b.shape)
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

Biên tập:

Một gợi ý là bỏ qua STIntersectionvà chỉ sử dụng STIntersectsnhư sau:

STIntersects:

select a.bg10
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

Vấn đề với cách tiếp cận này, là STIntersectsdường như chọn tất cả các đa giác trong hoặc ngoài và chạm vào đa giác lớn hơn, không chỉ những đa giác bên trong. Xem hình ảnh chẳng hạn.Kết quả từ chức năng STIntersects


Bạn có thể thử thực hiện một bộ đệm tối thiểu trên đa giác chứa của bạn và sau đó sử dụng STContainshoặc STWithin. Không thực sự là một hack tốt, nhưng sẽ mang lại cho bạn kết quả bạn muốn. Tùy chọn khác sẽ là thực hiện STIntersects với việc so sánh khu vực Giao lộ và khu vực đa giác.
MickyT

Tôi bắt đầu làm việc trên một khu vực so sánh nhưng đã vào một lỗ thỏ với việc so sánh hình học được chuyển đổi thành khu vực thành một số, v.v ...
DPSSpatial

Câu trả lời:


8

Về lý thuyết, các truy vấn mà bạn đã thực hiện sẽ trả về các đa giác mà bạn nói chưa được trả về. Điều đó khiến tôi nghi ngờ rằng bạn có thể gặp phải các vấn đề lỗi dấu phẩy động mà SQL Server gặp phải với các loại dữ liệu không gian. Do đó nhận xét của tôi về việc đệm đa giác giới hạn với số lượng tối thiểu.
Vì vậy, một cái gì đó như sau sẽ nhận được kết quả bạn muốn.

SELECT a.bg10 
FROM gis.usa_10_block_group a
    JOIN gis.usa_10_mkt_definition b
        ON a.shape.STWithin(b.shape.STBuffer(0.0001)) = 1
WHERE b.mktname = 'Loop'

Đây là một ví dụ nhanh về hành vi dự kiến ​​của một vài phương pháp không gian.

SELECT Geometry::STGeomFromText(WKT,0), Description
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STIntersects(Geometry::STGeomFromText(WKT,0)) Intersects
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STContains(Geometry::STGeomFromText(WKT,0)) Contained
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STOverlaps(Geometry::STGeomFromText(WKT,0)) Overlaps
    , Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0).STTouches(Geometry::STGeomFromText(WKT,0)) Touches
FROM (VALUES
    ('POLYGON((0 0, 20 0, 20 20, 0 20, 0 0))'            ,'Interior corner')
    ,('POLYGON((90 90, 100 90, 100 100, 90 100, 90 90))' ,'Interior corner')
    ,('POLYGON((20 20, 40 20, 40 40, 20 40, 20 20))'     ,'Interior')
    ,('POLYGON((50 0, 70 0, 70 20, 50 20, 50 0))'        ,'Interior edge')
    ,('POLYGON((50 80, 70 80, 70 100, 50 100, 50 80))'   ,'Interior edge')
    ,('POLYGON((80 50, 100 50, 100 70, 80 70, 80 50))'   ,'Interior edge')
    ,('POLYGON((90 0, 110 0, 110 20, 90 20, 90 0))'      ,'Overlap')
    ,('POLYGON((100 50, 120 50, 120 70, 100 70, 100 50))','Exterior edge')
    )P(WKT,Description)
UNION ALL 
SELECT Geometry::STGeomFromText('POLYGON((0 0, 100 0, 100 100, 0 100, 0 0))',0),'Bounding Area',null,null,null,null

Các kết quả

Description     Intersects Contained Overlaps Touches
--------------- ---------- --------- -------- -------
Interior corner 1          1         0        0
Interior corner 1          1         0        0
Interior        1          1         0        0
Interior edge   1          1         0        0
Interior edge   1          1         0        0
Interior edge   1          1         0        0
Overlap         1          0         1        0
Exterior edge   1          0         0        1
Bounding Area   NULL       NULL      NULL     NULL

Điều này làm việc tuyệt vời! Tôi đã phải giảm kích thước bộ đệm xuống 0,001, nhưng khái niệm này đã hoạt động. Tôi nghi ngờ vấn đề là hình học của bảng gis.usa_10_mkt_def định không xuất phát từ cùng một cấu trúc liên kết như gis.usa_10_block_group, giải thích lý do tại sao nó đi lạc khỏi kết quả mong đợi mà bạn đề cập. Tôi đã thử nghiệm việc sử dụng STWithin bằng hai bảng DO có chung cấu trúc liên kết và không cần bộ đệm.
dùng1185790

2

Truy vấn giao lộ sẽ trông như thế này (giả sử bạn muốn tất cả các bản ghi trở lại từ 'a'):

select a.* --get all columns from table 'a'
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'

Nếu bạn chỉ muốn các khu vực của a giao nhau b (nghĩa là cắt a đến b), sau đó bạn thêm STIntersection

select a.bg10
, a.STIntersection(b.geom) --clipped geometry from a against b
    from gis.usa_10_block_group a
    join gis.usa_10_mkt_definition b
    on a.shape.STIntersects(b.shape) = 1
    where b.mktname = 'Loop'

Nhưng điều này không giúp bạn có được các đa giác trong b ...

Loại đa giác đa giác này rất thử thách với các ranh giới và sự trùng hợp của chúng - để trở thành 'Trong vòng', các ranh giới của một không thể trùng với ranh giới của b - tương tự với 'Chứa'.

Theo các định nghĩa này, có bao nhiêu đa giác của bạn trong một thực sự nằm trong b ...?

Vì vậy, bạn có muốn đệm b trước khi bạn chọn đa giác trong một trong đó không? Hoặc làm một bộ đệm tiêu cực trên một?

Không chắc câu trả lời chính xác ở đây là ...


Xem chỉnh sửa để được giải thích đầy đủ lý do tại sao đây không hoàn toàn là những gì tôi đang theo dõi
user1185790

Tôi thấy những gì bạn đang cố gắng làm ... làm việc gì đó ngay bây giờ ...
DPSSpatial
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.