Soru SQL Server 2008 Spatial: çokgen içinde bir nokta bulmak


SQL Server 2008 mekansal veri türlerini kullanıyorum. GEOMETRY veri türü olarak tüm devletleri (çokgenler olarak) içeren bir tablom var. Şimdi bir nokta koordinatlarının (enlem, boylam) GEOGRAPHY veri türü olarak bu Devletin içinde olup olmadığını kontrol etmek istiyorum.

Yeni mekansal veri türlerini kullanarak herhangi bir örnek bulamadım. Şu anda, yıllar önce uygulanan bir çözümüm var, ancak bazı dezavantajları var.

Hem SQL Server 2008 hem de 2012 oldum. Yeni sürümde bazı geliştirmeler varsa, ben de çalışmaya başlayabilirim.

Teşekkürler.

GÜNCELLEME 1:

Biraz daha açıklık için bir kod örneği ekliyorum.

declare @s geometry  --GeomCol is of this type too.
declare @z geography --GeogCol is of this type too.

select @s = GeomCol
from AllStates
where STATE_ABBR = 'NY'

select @z = GeogCol
from AllZipCodes
where ZipCode = 10101

21
2018-06-15 15:51


Menşei


Veritabanında büyük kayıtlar varsa performans zayıf, bu sorguyu 1600000'den fazla kaydettim ve tamamlaması 2 dakika gecikti. - Jitendra Pancholi


Cevaplar:


Ben STIntersects () coğrafya yöntemini istediğinizi yapacağını düşünüyorum:

DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))', 4326);
SET @h = geography::Point(47.653, -122.358, 4326)

SELECT @g.STIntersects(@h)

27
2018-06-15 18:11



Teşekkürler. Ama poligonum, Devletler, bir GEOMETRY veri tipindedir. Önce bir COĞRAFYA değişkenine değiştirmeli miyim? - Farhan
Ah ... whoops. O kısmını özledim. Eyaletlerinizin (coğrafi veriler) geometrik veriler olarak depolanmasının bir nedeni var mı? - Ben Thul
Aslında bunun için bir sebep yok. Bazı öğreticilerden geçerken, GEOGRAPHY veri tipinin koordinatlar / noktalar için olduğunu ve GEOMETRY'nin bölgeler / çokgenler için olduğunu varsaydım. - Farhan
Bunu söylemek gerekirse, bir poligonu GEOMETRİ'den COĞRAFYA'ya nasıl dönüştürebiliriz? - Farhan
Bu çalıştı: coğrafya :: STGeomFromText (cast (varchar olarak Maxmcool) (max), 4326) - Farhan


Depolanan çokgenler için veri türünü değiştiremezseniz GEOGRAPHY daha sonra giriş enlem ve boylamı GEOMETRY ve kullan STContains veya STIntersects dönüştürülmüş değere karşı.

DECLARE @PointGeography GEOGRAPHY = geography::Point(43.365267, -80.971974, 4326)
DECLARE @PointGeometry GEOMETRY = geometry::STGeomFromWKB(@PointGeography.STAsBinary(), 4326);

SELECT @PolygonGeometry.STContains(@PointGeometry);

Ters yöne gitmek - GEOMETRY çokgenler GEOGRPAHY - Hataya eğilimli ve deneyimlerimden başarısız olması muhtemel.

Ve şunu oluşturmaya çalışırsanız GEOMETRY doğrudan enlem ve boylam değerlerinden gelin STContains (veya STIntersects) çalışmaz (yani, gerektiğinde bir eşleşme vermeyeceklerdir).


2
2017-09-18 15:22





declare @g geometry
set @g=geometry::STGeomFromText('POLYGON((-33.229869 -70.891988, -33.251124 -70.476616, -33.703094 -70.508045, -33.693931 -70.891052,-33.229869 -70.891988))',0)

DECLARE @h geometry;

SET @h = geometry::STGeomFromText('POINT(-33.3906300 -70.5725020)', 0);
SELECT @g.STContains(@h);

0
2017-11-10 13:49





  1. Geometri ve Coğrafya'yı karıştırmamalısınız. Geometri, DÜZ UÇUŞLAR içindir, Coğrafya, SPHEROIDS içindir (Dünya gibi).
  2. Bununla başa çıkmak için SRID'leri mutabık kılmalısınız. Her bir SRID (ör. 2913 = NZG2000) bir dönüşüm ilişkisini açıklar. Her bir SRID, tekdüze bir küre ile eşleştirmek için kullanılabilir;
  3. Her iki değerde de "aynı" bir SRID'e ulaşıncaya kadar .STxXX işlevleri için birçoğu NULL (her iki durumda da varsayılan 0'a sahip olabilirsiniz)
  4. Eğer aynı değillerse ama onlar gibi davranıyorsanız, kenarlarda hatalar olabilir.
  5. Bazı "precalc" süresi harcarsanız, ilgili sınırlayıcı rect'ler için üst / sol ve alt / sağ noktaları belirleyebilir (ve bunları saklayabilirsiniz) ve bu değerleri, kontrol edilecek kayıtları sınırlamak için endekslerde kullanabilirsiniz. Bir T / L <B B / R ve A B / R> B T / L, üst üste gelemezse, WHERE'inizde basit bir 4 VE sayısal kontrol anlamına gelir, STWithin kontrollerini sınırlar

İşte SRID 2193'te kullandığım bir örnek. Belirli bir noktanın 3 km'lik yarıçapındaki ve belirli bir okul bölgesi içindeki tüm yollar

DECLARE @g geometry

SELECT @g = GEO2193 FROM dbo.schoolzones WHERE schoolID = 319

SELECT DD.full_road_name, MIN(convert(int,  dd.address_number)), MAX(convert(int,  dd.address_number))
FROM (

select A.* from dbo.[street-address] A

WHERE (((A.Shape_X - 1566027.50505) * (A.Shape_X - 1566027.50505)) + ((A.Shape_Y - 5181211.81675) * (A.Shape_Y - 5181211.81675))) < 9250000

and a.shape_y > 5181076.1943481788

and a.shape_y < 5185097.2169968253

and a.shape_x < 1568020.2202472512

and a.shape_x > 1562740.328937705

and a.geo2193.STWithin(@g) = 1
) DD
GROUP BY DD.full_road_name
ORDER BY DD.full_road_name

0
2017-10-04 11:23