5

다음 데이터가 주어지면 가능할 수 있습니까? 그렇다면 첫 번째 테이블의 'Shurdington'위치가 해당 위치에 포함되어 있는지를 확인하는 가장 효율적인 방법이 될 수 있습니까? 주어진 반지름의 두 번째 테이블에있는 위치 중 하나.지리적 반경 내의 한 지점 -

GeoData 열은 'geography'유형이므로 SQL Server 공간 함수는 위도와 경도를 사용하는 것은 물론 옵션을 사용합니다.

Location  GeoData  Latitude Longitude 
=========================================================== 
Shurdington XXXXXXXXXX 51.8677979 -2.113189 

ID Location   GeoData  Latitude Longitude Radius 
============================================================================== 
1000 Gloucester  XXXXXXXXXX 51.8907127 -2.274598 10 
1001 Leafield  XXXXXXXXXX 51.8360519 -1.537438 10 
1002 Wotherton  XXXXXXXXXX 52.5975151 -3.061798 5 
1004 Nether Langwith XXXXXXXXXX 53.2275276 -1.212108 20 
1005 Bromley   XXXXXXXXXX 51.4152069 0.0292294 10 

매우 도움이된다.

답변

8

CREATE TABLE #Data (
    Id int, 
    Location nvarchar(50), 
    Latitude decimal(10,5), 
    Longitude decimal(10,5), 
    Radius int 
) 

INSERT #Data (Id,Location,Latitude,Longitude,Radius) VALUES 
(1000,'Gloucester', 51.8907127 ,-2.274598 , 20), -- Increased to 20 
(1001,'Leafield', 51.8360519 , -1.537438 , 10), 
(1002,'Wotherton', 52.5975151, -3.061798 , 5), 
(1004,'Nether Langwith', 53.2275276 , -1.212108 , 20), 
(1005,'Bromley', 51.4152069 , 0.0292294 , 10) 

테스트

는 또 다른 지점의 반경인지 확인하려면 POINT

DECLARE @p GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-2.113189 51.8677979)', 4326); 

로 관심의 포인트를 선언 데이터를 생성합니다 :

-- First create a Point. 
DECLARE @point GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-2.27460 51.89071)', 4326); 
-- Buffer the point (meters) and check if the 1st point intersects 
SELECT @point.STBuffer(50000).STIntersects(@p) 

단일 쿼리로 모든 결합 :

select *, 
     GEOGRAPHY::STGeomFromText('POINT('+ 
      convert(nvarchar(20), Longitude)+' '+ 
      convert(nvarchar(20), Latitude)+')', 4326) 
     .STBuffer(Radius * 1000).STIntersects(@p) as [Intersects] 
from #Data 

을 제공합니다 :

Id   Location Latitude Longitude Radius Intersects 
1000 Gloucester 51.89071 -2.27460 20 1 
1001 Leafield 51.83605 -1.53744 10 0 
1002 Wotherton 52.59752 -3.06180 5 0 
1004 Nether Langwith 53.22753 -1.21211 20 0 
1005 Bromley   51.41521 0.02923   10 0 

재 : 효율성. 일부 올바른 인덱싱을 사용하면 SQL의 공간 인덱스가 매우 빠릅니다.

+0

거리가 이상하게 보일 수도 있지만 이상하게도 SQL Server의 공간적 기능에 대한 지식이 부족한 것일 수도 있지만이 경우에도 열 '.ST 거리 (@p)/1609.34'그것은 마일에서 거리를 반환 할 것입니다, 그래도 벗어나는 것 같습니다 - 아니면 저입니까? – Nathan

+0

'STGeomFromText'에서 'POINT'를 만들 때 위도/경도가 다른 방향으로 입력되어야합니다. long/lat. – Nathan

+0

@ 네이 Tan 네 말이 맞아, 그에 따라 내 대답을 업데이트 할께. – Paddy

1

두 점 사이의 거리를 계산하고이 거리를 주어진 반경과 비교합니다.

근거리 계산에 대해서는 Wikipedia - Geographical distance - Spherical Earth projected to a plane의 수식을 사용할 수 있습니다.이 수식은 "매우 빠르며 작은 거리에 대해 상당히 정확한 결과를 산출합니다"라고합니다.

는 공식에 따라, 당신은 위도와 경도의 차이와 평균 위도

with geo as (select g1.id, g1.latitude as lat1, g1.longitude as long1, g1.radius, 
        g2.latitude as lat2, g2.longitude as long2 
      from geography g1 
      join geography g2 on g2.location = 'shurdington' 
           and g1.location <> 'shurdington') 
    base as (select id, 
        (radians(lat1) - radians(lat2)) as dlat, 
        (radians(long1) - radians(long2)) as dlong, 
        (radians(lat1) + radians(lat2))/2 as mlat, radius 
       from geo) 
    dist as (select id, 
        6371.009 * sqrt(square(dlat) + square(cos(mlat) * dlong)) as distance, 
        radius 
       from base) 
select id, distance 
from dist 
where distance <= radius 

나는 "읽기"계산을 유지하기 위해 중간 단계로 with select의 사용이 필요합니다.

+0

"SQL Server 공간적 기능 사용은 옵션"이라고하는 이유는 무엇입니까? – AakashM

+0

@AakashM 재미있는 운동 이었기 때문에. –

1

수학을 직접 수행하려는 경우 Pythagoras를 기반으로 한 Equirectangular 근사를 사용할 수 있습니다. 공식은 다음과 같습니다.

var x = (lon2-lon1) * Math.cos ((lat1 + lat2)/2); var y = (lat2-lat1); var d = Math.sqrt (x * x + y * y) * R; 이 사용할 수없는 가장 정확한 방법 일뿐 가능성이 좋다고

SELECT * 
FROM Table2 t2 
WHERE EXISTS (
SELECT 1 FROM Table1 t1 
WHERE 
    ABS (
    SQRT (
    (SQUARE((RADIANS(t2.longitude) - RADIANS(t1.longitude)) * COS((RADIANS(t2.Latitude) + RADIANS(t1.Latitude))/2))) + 
    (SQUARE(RADIANS(t1.Latitude) - RADIANS(t2.Latitude))) 
    ) * 6371 --Earth radius in km, use 3959 for miles 
    ) 
    <= t2.Radius 
) 

참고 : SQL의 관점에서

이는 반경 1에 항목을 포함하여 2 표에서 그 위치를 제공해야합니다 충분히. 전 세계로 퍼져 나가는 거리를보고있는 경우 Google의 haversine 공식을 사용하는 것이 좋습니다.

Paddy의 솔루션과 비교하여 이들이 얼마나 잘 맞는지, 가장 잘 수행되는지 확인할 가치가 있습니다.