J'utilise les types de données spatiales SQL Server 2008. J'ai une table avec tous les états (sous forme de polygones) comme type de données GEOMETRY. Maintenant, je veux vérifier si les coordonnées d'un point (latitudes, longitudes) en tant que type de données GEOGRAPHY sont à l'intérieur de cet état ou non.
Je n'ai trouvé aucun exemple utilisant les nouveaux types de données spatiales. Actuellement, j'ai une solution de contournement qui a été mise en œuvre il y a plusieurs années, mais elle présente certains inconvénients.
J'ai à la fois SQL Server 2008 et 2012. Si la nouvelle version comporte des améliorations, je peux aussi commencer à travailler dessus.
Merci.
MISE À JOUR 1:
J'ajoute un exemple de code pour un peu plus de clarté.
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
Je pense que la méthode géographique STIntersects () fera ce que vous voulez:
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)
Si vous ne pouvez pas modifier le type de données pour les polygones stockés en GEOGRAPHY
, vous pouvez convertir la latitude et la longitude en entrée en GEOMETRY
et utiliser le STContains
ou le STIntersects
contre la valeur convertie.
DECLARE @PointGeography GEOGRAPHY = geography::Point(43.365267, -80.971974, 4326)
DECLARE @PointGeometry GEOMETRY = geometry::STGeomFromWKB(@PointGeography.STAsBinary(), 4326);
SELECT @PolygonGeometry.STContains(@PointGeometry);
Aller dans la direction opposée - essayer de convertir les polygones GEOMETRY
en GEOGRPAHY
- est sujet à des erreurs et risque d’échouer de par mon expérience.
Et notez que si vous essayez de créer le point GEOMETRY
directement à partir des valeurs de latitude et de longitude, alors la STContains
(ou STIntersects
) ne fonctionnera pas (c’est-à-dire ne donnera pas de correspondance quand ils le devraient).
Voici un exemple que j'ai utilisé dans SRID 2193. Toutes les routes dans un rayon de 3 km d'un point donné et à l'intérieur d'une zone scolaire spécifique
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
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);
Si vous avez une table (exemple: SubsriberGeo) où l’une des colonnes (exemple: Emplacement) a des points géographiques comme valeurs et que vous souhaitez trouver tous les points de cette table qui sont dans un polygone, voici une façon de le faire:
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;