wake-up-neo.net

SQL Server 2008 Spatial: Finden Sie einen Punkt im Polygon

Ich verwende räumliche Datentypen von SQL Server 2008. Ich habe eine Tabelle mit allen Staaten (als Polygone) als Datentyp GEOMETRY. Jetzt möchte ich überprüfen, ob die Koordinaten eines Punktes (Breitengrade, Längengrade) als Datentyp GEOGRAPHY in diesem Zustand liegen oder nicht.

Ich konnte kein Beispiel mit den neuen Geodatentypen finden. Derzeit habe ich eine Problemumgehung, die vor vielen Jahren implementiert wurde, hat jedoch einige Nachteile.

Ich habe sowohl SQL Server 2008 als auch 2012. Wenn die neue Version einige Verbesserungen aufweist, kann ich auch damit arbeiten.

Vielen Dank.

UPDATE 1:

Ich füge ein Codebeispiel für mehr Klarheit hinzu.

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
22
Farhan

Ich denke, die geographische Methode STIntersects () wird das tun, was Sie wollen:

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)
28
Ben Thul

Wenn Sie den Datentyp für die gespeicherten Polygone nicht in GEOGRAPHY ändern können, können Sie den Breiten- und Längengrad der Eingabe in GEOMETRY konvertieren und die STContains oder STIntersects gegen den konvertierten Wert verwenden.

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

SELECT @PolygonGeometry.STContains(@PointGeometry);

In die entgegengesetzte Richtung zu gehen - der Versuch, die GEOMETRY-Polygone in GEOGRPAHY umzuwandeln - ist fehleranfällig und wird aus meiner Erfahrung wahrscheinlich versagen.

Wenn Sie versuchen, den GEOMETRY-Punkt direkt aus den Breiten- und Längenwerten zu erstellen, funktioniert STContains (oder STIntersects) nicht (d. H. Gibt keine Übereinstimmung aus, wenn sie sollten).

2
  1. Sie sollten nicht Geometrie und Geografie mischen. Geometrie ist für FLACHE FLÄCHEN, Geografie für SPHEROIDS (wie die Erde).
  2. Sie sollten die SRIDs "abgleichen", um damit umzugehen. Jede SRID (z. B. 2913 = NZG2000) beschreibt eine Transformationsbeziehung. Jede SRID kann zur Zuordnung zu/von einer einheitlichen Kugel verwendet werden. So gelangen Sie von einer zur anderen.
  3. Bis Sie eine "gleiche" SRID für beide Werte erhalten, geben viele für die .STxXX-Funktionen NULL zurück (möglicherweise haben Sie in beiden Fällen den Standardwert 0).
  4. Wenn sie nicht gleich sind, Sie aber so tun, als könnten Sie Fehler in den Edge-Fällen haben.
  5. Wenn Sie einige "Vorkalkulationen" aufwenden, können Sie den oberen/linken und den unteren/rechten Punkt für die betroffenen umgebenden Rechtecke bestimmen (und diese speichern) und diese Werte in Indizes verwenden, um die zu prüfenden Datensätze zu begrenzen/L <BB/R und AB/R> BT/L dürfen sich nicht überlappen. Dies bedeutet, dass eine einfache 4-UND-Nummer-Überprüfung in Ihrem WHERE Ihre STWithin-Prüfungen einschränkt

Hier ist ein Beispiel, das ich in SRID 2193 verwendet habe. Alle Straßen innerhalb eines Radius von 3 km um einen bestimmten Punkt und innerhalb einer bestimmten Schulzone

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
Roger Willcocks
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
Leonel

Wenn Sie über eine Tabelle verfügen (Beispiel: SubsriberGeo), bei der eine der Spalten (Beispiel: Location) geografische Punkte als Werte enthält und Sie alle Punkte aus dieser Tabelle finden möchten, die sich im Polygon befinden, können Sie dies tun:

 WITH polygons
 AS (SELECT 'p1' id, 
            geography::STGeomFromText('polygon ((-113.754429 52.471834 , 1 5, 5 5, -113.754429 52.471834))', 4326) poly
),
 points
 AS (SELECT [SubscriberId],[Location] as p FROM [DatabaseName].[dbo].[SubscriberGeo])
 SELECT DISTINCT 
        points.SubscriberId, 
        points.p.STAsText() as Location
 FROM polygons
      RIGHT JOIN points ON polygons.poly.STIntersects(points.p) = 1
 WHERE polygons.id IS NOT NULL;
0
grabhints