私は、地図上の2つの位置の間の距離を計算しようとしています。 私のデータには次のものが格納されています。Longitude, Latitude, X POS, Y POS.
これまでは以下のスニペットを使用していました。
DECLARE @orig_lat DECIMAL
DECLARE @orig_lng DECIMAL
SET @orig_lat=53.381538 set @orig_lng=-1.463526
SELECT *,
3956 * 2 * ASIN(
SQRT( POWER(SIN((@orig_lat - abs(dest.Latitude)) * pi()/180 / 2), 2)
+ COS(@orig_lng * pi()/180 ) * COS(abs(dest.Latitude) * pi()/180)
* POWER(SIN((@orig_lng - dest.Longitude) * pi()/180 / 2), 2) ))
AS distance
--INTO #includeDistances
FROM #orig dest
しかし、私はこのデータを信用していません、それは少し不正確な結果を与えているようです。
サンプルデータが必要な場合は
Latitude Longitude Distance
53.429108 -2.500953 85.2981833133896
誰か私のコードを助けてくれませんか?すでにあるものを修正してくれても構いませんし、新しい方法でこれを実現してくれれば、それは素晴らしいことです。
あなたの結果はどのような単位で表示されますか?
SQL Server 2008を使用しているので、まさにこの種のデータ用に設計されたgeography
データ型が利用できます。
DECLARE @source geography = 'POINT(0 51.5)'
DECLARE @target geography = 'POINT(-3 56)'
SELECT @source.STDistance(@target)
Gives
----------------------
538404.100197555
(1 row(s) affected)
ロンドン(付近)からエジンバラ(付近)まで約538kmであることを教えてくれます。
もちろん、最初は学習が必要ですが、一度知ってしまえば、独自のHaversine計算を実装するよりもはるかに簡単で、しかも多くの機能を手に入れることができます。
既存のデータ構造を維持したい場合は、Point`メソッドを使って適切なgeography
インスタンスを構築することで、STDistance
を使用することができます。
DECLARE @orig_lat DECIMAL(12, 9)
DECLARE @orig_lng DECIMAL(12, 9)
SET @orig_lat=53.381538 set @orig_lng=-1.463526
DECLARE @orig geography = geography::Point(@orig_lat, @orig_lng, 4326);
SELECT *,
@orig.STDistance(geography::Point(dest.Latitude, dest.Longitude, 4326))
AS distance
--INTO #includeDistances
FROM #orig dest
以下の関数は、2つの地理座標間の距離をマイルで表示します***。
create function [dbo].[fnCalcDistanceMiles] (@Lat1 decimal(8,4), @Long1 decimal(8,4), @Lat2 decimal(8,4), @Long2 decimal(8,4))
returns decimal (8,4) as
begin
declare @d decimal(28,10)
-- Convert to radians
set @Lat1 = @Lat1 / 57.2958
set @Long1 = @Long1 / 57.2958
set @Lat2 = @Lat2 / 57.2958
set @Long2 = @Long2 / 57.2958
-- Calc distance
set @d = (Sin(@Lat1) * Sin(@Lat2)) + (Cos(@Lat1) * Cos(@Lat2) * Cos(@Long2 - @Long1))
-- Convert to miles
if @d <> 0
begin
set @d = 3958.75 * Atan(Sqrt(1 - power(@d, 2)) / @d);
end
return @d
end
以下の関数は、2つの地理的座標間の距離を***キロメートル単位で表示します。
CREATE FUNCTION dbo.fnCalcDistanceKM(@lat1 FLOAT, @lat2 FLOAT, @lon1 FLOAT, @lon2 FLOAT)
RETURNS FLOAT
AS
BEGIN
RETURN ACOS(SIN(PI()*@lat1/180.0)*SIN(PI()*@lat2/180.0)+COS(PI()*@lat1/180.0)*COS(PI()*@lat2/180.0)*COS(PI()*@lon2/180.0-PI()*@lon1/180.0))*6371
END
以下の関数は、2つの地理座標間の距離をキロメートル単位で表示します。 sql server 2008で導入されたGeography***データ型を使用しています。
DECLARE @g geography;
DECLARE @h geography;
SET @g = geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656)', 4326);
SET @h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
SELECT @g.STDistance(@h);
用途:
select [dbo].[fnCalcDistanceKM](13.077085,80.262675,13.065701,80.258916)