5

以下のデータがあれば、それは可能でしょうか?そうであれば、最初のテーブルの「Shurdington」の場所が与えられた半径の2番目のテーブル内の任意の場所の。地理的半径内のポイント -

GeoData列は「地理」型であるため、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の空間的な特徴に関する私の知識の欠如と関連しているかもしれませんが、それでも私は列 '。STDistance(@p)/ 1609.34'それはマイルで距離を返しますが、途中であるように見えます - それとも私ですか? – Nathan

+0

「STGeomFromText」から「POINT」を作成するときに、緯度/経度を他の方法で入力する必要があります。 long/lat。 – Nathan

+0

@Nathanあなたが正しいです、それに応じて私の答えを更新します – Paddy

1

2点間の距離を計算し、この距離を指定の半径と比較します。

近距離を計算する場合は、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 Sを使用する必要があります。

+0

「SQL Serverの空間的な機能を使用することはオプションですか? – AakashM

+0

@AakashMそれは面白い運動だったので。 –

1

あなたが数学を自分でやりたいのであれば、ピタゴラスに基づいた等角近似を使うことができます。式は、

var x =(lon2-lon1)* Math.cos((lat1 + lat2)/ 2)です。 var y =(lat2-lat1);var d = Math.sqrt(x * x + y * y)* R; SQLの面では

、これは彼らの半径内第一で、あなたのエントリが含まれている、あなたの第二の表のそれらの場所を与える必要があります。

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 
) 

注これは利用できる最も正確な方法はありませんが、可能性が良好であること十分な。世界中を行き来する距離を見ているなら、Googleの「haversine」式が好きかもしれません。

これをPaddyのソリューションと比較して、どれくらいうまく一致していて、どれが最も優れているかを確認する価値があります。

関連する問題