SQL Server - Daha büyük bir çokgen içine yerleştirilmiş tüm çokgenleri seçin


9

Bu, kutudan çıkmış bir çözüm olacağını düşündüğüm basit bir SQL Server geometri sorusu, ancak bir tane bulmakta şansım yok.

Amacım, bir tablodaki başka bir tablodan daha büyük bir çokgen içinde yuvalanmış (içerilen) çokgenleri olan tüm kayıtları seçmektir. Beklenen işlevler vardı STWithinve STContainsihtiyacım olan çözümler olarak, ancak maalesef her ikisi de, daha büyük çokgenin sınırına değen iç içe çokgenleri değil, yalnızca daha büyük çokgenin içinde iç içe olan çokgenleri tanımlar. Örneğin resme bakın.Hem STWithin hem de STContains işlevlerinden sonuç

İhtiyacım için çalışan alternatif bir seçenekti STIntersection. Ancak bu işlevin sorunu, yalnızca geometri sütununu döndürmesidir! Bunun yerine kayıt kimliğini almak istiyorum. Bunun nasıl yapılabileceğine dair bir önerisi olan var mı?

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'

Düzenle:

Bir öneri atlamak STIntersectionve sadece STIntersectsaşağıdaki gibi kullanmaktı :

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'

Bu yaklaşımla ilgili sorun STIntersects, sadece çok içeride değil, tüm poligonları içeride veya dışarıda ve daha büyük poligona dokunmak gibi görünüyor. Örneğin resme bakın.STIntersects işlevinden sonuç


İçeren çokgeninizde minimum bir arabellek yapmayı deneyebilir ve ardından STContainsveya öğelerinden birini kullanabilirsiniz STWithin. Gerçekten güzel bir hack değil, ama size istediğiniz sonuçları alacak. Diğer seçenek STIntersects'i Kavşak alanı ve çokgenler alanı karşılaştırmasıyla yapmak olacaktır.
MickyT

Ben ... bir sayı vb vb alana dönüştürülen geometri karşılaştırarak bir tavşan deliğine karşılaştırmak ama var bir alan üzerinde çalışmaya başladı
DPSSpatial

Yanıtlar:


8

Teorik olarak, yaptığınız sorgular döndürülmediğini söylediğiniz çokgenleri döndürmelidir. Bu bana SQL Server uzamsal veri türleri ile sahip kayan nokta hata sorunları karşılaşıyor olabilir şüpheli. Bu nedenle sınırlayıcı poligonu minimum miktarda tamponlama hakkındaki yorumum.
Yani aşağıdaki gibi bir şey istediğiniz sonuçları elde etmelidir.

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'

Aşağıda, birkaç mekansal yöntemin beklenen davranışına hızlı bir örnek verilmiştir.

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

Sonuçlar

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

Harika çalışıyor! Tampon boyutunu 0.001'e düşürmek zorunda kaldım, ancak konsept işe yaradı. Sorunun, sizin bahsettiğiniz beklenen sonuçtan kaynaklanma nedenini açıklayan gis.usa_10_mkt_definition tablo geometrilerinin gis.usa_10_block_group ile aynı topolojiden türetilmediğinden şüpheleniyorum. Aynı topolojiyi paylaşan iki tablo kullanarak STWithin kullanımını test ettim ve tampon gerekmedi.
user1185790

2

Kavşak sorgusu şöyle görünmelidir (tüm kayıtları 'a'dan geri istediğinizi varsayarsak):

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'

A'nın b ile kesişen alanlarını (yani kırpma a'dan b'ye) istiyorsanız, STIntersection'ı ekleyin

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'

Ama bu size henüz b içindeki çokgenleri getirmiyor ...

Bu çokgen-çokgen türü, sınırlar ve içgüdüleri ile çok testidir - 'İçinde' olmak için, bir 'nin sınırları, b'nin sınırları ile çelişemez - aynı' İçerir 'için de geçerlidir.

Bu tanımlara göre, a'daki çokgenlerinizden kaç tanesi aslında b ... içinde?

Yani içindeki bir çokgenleri seçmeden önce b'yi arabelleğe almak istiyor musunuz? Veya bir?

Burada kesin cevabın ne olduğundan emin değilim ...


Neden bunun peşinde olduğumun tam olmadığını görmek için düzenlemeye bakın
user1185790

Ne yapmaya çalıştığınızı görüyorum ... şimdi bir şey üzerinde çalışıyor ...
DPSSpatial
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.