/ / SQL Server: Consulta espacial - servidor SQL, geometría, geoespacial

SQL Server: consulta espacial - sql-server, geometry, geoespacial

Tenga en cuenta que tenemos algunas áreas y varios puntos se almacenan en dos tablas en SQL Server:

CREATE TABLE [dbo].[Areas](
[Id] [int] NOT NULL,
[Location] [geometry] NOT NULL)


CREATE TABLE [dbo].[Points](
[Id] [int] NOT NULL,
[Location] [geometry] NOT NULL)

Sé que la función que STIntersects usa para verificar si un polígono contiene un punto o no.
¿Hay alguna forma de encontrar puntos en áreas para cada área usando una sola consulta?
No sé cómo encontrar puntos en áreas porque hay varias áreas. ¿Debo usar el cursor o para la iteración? En caso afirmativo, ¿cómo?

Respuestas

2 para la respuesta № 1

Interesante. Nunca he usado el tipo de datos de geometría. Pero aquí es mi primera suposición.

Puede usar el método de geometría STWithin del campo Geometría del punto y pasar el objeto de geometría del área para ver si el punto está o no "dentro" del área

declare @Areas table ( AreaID int identity(1,1), Description varchar(50), Area geometry)
declare @Points table ( PointID int identity(1,1), Description varchar(50), Point geometry )

insert @Areas ( Description, Area )
select "Area 1", geometry::STGeomFromText("POLYGON((0 0, 0 3, 3 3, 3 0, 0 0))", 0)

insert @Areas ( Description, Area )
select "Area 2", geometry::STGeomFromText("POLYGON((10 10, 10 15, 15 15, 15 10, 10 10))", 0)

insert @Points ( Description, Point )
select "Point 1", geometry::STPointFromText("POINT(2 2)", 0)

insert @Points ( Description, Point )
select "Point 2", geometry::STPointFromText("POINT(4 4)", 0)

insert @Points ( Description, Point )
select "Point 3", geometry::STPointFromText("POINT(12 13)", 0)


select a.Description, p.Description, case when p.Point.STWithin(a.Area) = 1 then "Yes" else "No" end as PointWithin
from @Areas a, @Points p

Resultados:

Description Description PointWithin
----------- ----------- -----------
Area 1      Point 1     Yes
Area 2      Point 1     No
Area 1      Point 2     No
Area 2      Point 2     No
Area 1      Point 3     No
Area 2      Point 3     Yes

Espero que esto ayude


1 para la respuesta № 2

Necesita una forma de comparar cada punto a cada área. Una unión cruzada logra eso. Así que algo como esto:

select a.Id as [AreaId]
, p.Id as [PointId]
from dbo.Areas as a
cross join dbo.Points as p
where a.Location.STContains(p.Location) = 1