TSQL География Пространственные данные Polygon Lat/Long Search

TSQL SQL Server 2008 r2

Можно ли сохранить полигон, состоящий из широт и долгот, а затем выполнить поиск в этом полигоне, чтобы выяснить, существует ли данная широта / долгота в этом полигоне?

Если да, то как это сделать?

Если нет, то может ли кто-нибудь предложить наилучший способ решения этой проблемы?

Пример многоугольника

LatLng(55.297622963050465, -4.627166781574488),
LatLng(55.25851203752759, -3.5724792815744877),
LatLng(55.034056344339206, -3.5450134612619877),
LatLng(54.955277168321636, -3.7647400237619877),
LatLng(54.92372217917785, -4.113555941730738),
LatLng(54.96946883538248, -4.561248812824488),
LatLng(55.151935308382306, -4.712310824543238);

Lat / Long для поиска

LatLng(55.10029008969451, -4.100017953449488),

заранее спасибо

2 ответа

Решение

Короче да, это возможно. Я бы посоветовал вам начать со следующей ссылки MSDN и провести небольшое исследование оттуда:

Работа с пространственными данными

В частности, обратите внимание на следующие методы, доступные для использования при получении ответа:

  • STWithin ()
  • STIntersects ()

Обратите внимание, что в SQL 2008 R2 вы ограничены полигонами размером не более одного полушария. Если вам нужна поддержка для больших объектов, я бы рассмотрел SQL 2012 или выше.

Основной пример:

declare @g geography = Geography::STPolyFromText("<WKT Polygon Text>, 4326); -- 4326 is a common SRID
declare @p point = Geography::STPointFromText("<WKT Point Text>, 4326); -- SRID MUST match polygon

select @p.STWithin(@g); -- 1 is true, 0 is false

Благодаря @Jon Bellamy я смог прийти к этому решению

Наряду с помощью Пространственного блога Эда, чтобы "исправить" проблему ориентации кольца многоугольника

IF OBJECT_ID ( 'dbo.SpatialTable', 'U' ) IS NOT NULL 
    DROP TABLE dbo.SpatialTable;
GO

CREATE TABLE SpatialTable 
    ( id INT IDENTITY (1,1),
    GeogCol1 GEOGRAPHY, 
    GeogCol2 AS GeogCol1.STAsText() );
GO

DECLARE @geom GEOMETRY = 'POLYGON(( 55.297622963050465 -4.627166781574488,
                                    55.25851203752759 -3.5724792815744877,
                                    55.034056344339206 -3.5450134612619877,
                                    54.955277168321636 -3.7647400237619877,
                                    54.92372217917785 -4.113555941730738,
                                    54.96946883538248 -4.561248812824488,
                                    55.151935308382306 -4.712310824543238,
                                    55.297622963050465 -4.627166781574488))';

DECLARE @geog GEOGRAPHY = @geom.MakeValid().STUnion(@geom.STStartPoint()).STAsText()

INSERT INTO SpatialTable (GeogCol1) VALUES (@geog)

DECLARE @g GEOGRAPHY 
SET @g = (SELECT GEOGRAPHY::STPolyFromText(GeogCol2, 4326) FROM dbo.SpatialTable); -- 4326 is a common SRID

DECLARE @p GEOGRAPHY
SET @p = GEOGRAPHY::STPointFromText('POINT(55.10029008969451 -4.100017953449488)', 4326); -- SRID MUST match polygon

SELECT @p.STIntersects(@g); -- 1 is true, 0 is false

IF OBJECT_ID ( 'dbo.SpatialTable', 'U' ) IS NOT NULL 
    DROP TABLE dbo.SpatialTable;
GO
Другие вопросы по тегам