it-swarm.com.de

Berechnung der Entfernung zwischen zwei Punkten (Breite, Länge)

Ich versuche die Entfernung zwischen zwei Positionen auf einer Karte zu berechnen. Ich habe in meinen Daten gespeichert: Längengrad, Breitengrad, X-POS, Y-POS.

Ich habe zuvor das folgende Snippet verwendet.

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

Ich vertraue jedoch nicht auf die Daten, die daraus hervorgehen, es scheint, dass sie leicht ungenaue Ergebnisse liefern.

Einige Beispieldaten für den Fall, dass Sie sie benötigen

Latitude        Longitude     Distance 
53.429108       -2.500953     85.2981833133896

Könnte mir jemand mit meinem Code weiterhelfen, es macht mir nichts aus, wenn Sie das, was ich bereits habe, korrigieren möchten, wenn Sie einen neuen Weg haben, dies zu erreichen, der großartig wäre.

Bitte geben Sie an, in welcher Maßeinheit sich Ihre Ergebnisse befinden.

77
Waller

Seit Sie SQL Server 2008 verwenden, steht Ihnen der Datentyp geography zur Verfügung, der genau für diese Art von Daten ausgelegt ist:

DECLARE @source geography = 'POINT(0 51.5)'
DECLARE @target geography = 'POINT(-3 56)'

SELECT @source.STDistance(@target)

Gibt

----------------------
538404.100197555

(1 row(s) affected)

Es ist ungefähr 538 km von (nahe) London nach (nahe) Edinburgh entfernt.

Natürlich wird es eine Menge zu lernen geben, aber wenn Sie es einmal wissen, ist es weitaus einfacher, als Ihre eigene Haversine-Berechnung zu implementieren. Außerdem erhalten Sie eine Menge Funktionalität.


Wenn Sie Ihre vorhandene Datenstruktur beibehalten möchten, können Sie STDistance weiterhin verwenden, indem Sie geeignete geography -Instanzen mit der Methode Point erstellen:

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
114
AakashM

Die folgende Funktion gibt den Abstand zwischen zwei Geokoordinaten in Meilen an.

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 

Die folgende Funktion gibt den Abstand zwischen zwei Geokoordinaten in Kilometern an.

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

Die folgende Funktion gibt den Abstand zwischen zwei Geokoordinaten in Kilometern unter Verwendung von an. Geography Datentyp, der in SQL Server 2008 eingeführt wurde

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);

Verwendung:

select [dbo].[fnCalcDistanceKM](13.077085,80.262675,13.065701,80.258916)

Hinweis: Ref1 , Ref2

38
Durai Amuthan.H

Offenbar hat Microsoft die Köpfe aller anderen Befragten überfallen und sie dazu gebracht, so komplizierte Lösungen wie möglich zu schreiben. Hier ist der einfachste Weg ohne zusätzliche Funktionen/Deklarationsanweisungen:

SELECT geography::Point(LATITUDE_1, LONGITUDE_1, 4326).STDistance(geography::Point(LATITUDE_2, LONGITUDE_2, 4326))

Ersetzen Sie einfach Ihre Daten anstelle von LATITUDE_1, LONGITUDE_1, LATITUDE_2, LONGITUDE_2 z.B.:

SELECT geography::Point(53.429108, -2.500953, 4326).STDistance(geography::Point(c.Latitude, c.Longitude, 4326))
from coordinates c
5
Stalinko

Wenn Sie SQL 2008 oder höher verwenden, empfehlen wir Ihnen, den Datentyp GEOGRAPHY zu überprüfen. SQL hat Unterstützung für Geodatenabfragen eingebaut.

z.B. Sie hätten eine Spalte in Ihrer Tabelle vom Typ GEOGRAPHIE, die mit einer räumlichen Darstellung der Koordinaten gefüllt wäre (Beispiele finden Sie in der oben verlinkten MSDN-Referenz). Dieser Datentyp macht dann Methoden verfügbar, mit denen Sie eine ganze Reihe von Geodatenabfragen durchführen können (z. B. den Abstand zwischen zwei Punkten ermitteln).

4
AdaTheDev
Create Function [dbo].[DistanceKM] 
( 
      @Lat1 Float(18),  
      @Lat2 Float(18), 
      @Long1 Float(18), 
      @Long2 Float(18)
)
Returns Float(18)
AS
Begin
      Declare @R Float(8); 
      Declare @dLat Float(18); 
      Declare @dLon Float(18); 
      Declare @a Float(18); 
      Declare @c Float(18); 
      Declare @d Float(18);
      Set @R =  6367.45
            --Miles 3956.55  
            --Kilometers 6367.45 
            --Feet 20890584 
            --Meters 6367450 


      Set @dLat = Radians(@lat2 - @lat1);
      Set @dLon = Radians(@long2 - @long1);
      Set @a = Sin(@dLat / 2)  
                 * Sin(@dLat / 2)  
                 + Cos(Radians(@lat1)) 
                 * Cos(Radians(@lat2))  
                 * Sin(@dLon / 2)  
                 * Sin(@dLon / 2); 
      Set @c = 2 * Asin(Min(Sqrt(@a))); 

      Set @d = @R * @c; 
      Return @d; 

End
GO

Verwendung:

select dbo.DistanceKM (37.848832506474, 37.848732506474, 27.83935546875, 27.83905546875)

Ausgänge:

0,02849639

Sie können den @ R-Parameter mit kommentierten Gleitkommazahlen ändern.

4
Fatih K.

Zusätzlich zu den vorherigen Antworten können Sie hier die Entfernung in einem SELECT berechnen:

CREATE FUNCTION Get_Distance
(   
    @La1 float , @Lo1 float , @La2 float, @Lo2 float
)
RETURNS TABLE 
AS
RETURN 
    -- Distance in Meters
    SELECT GEOGRAPHY::Point(@La1, @Lo1, 4326).STDistance(GEOGRAPHY::Point(@La2, @Lo2, 4326))
    AS Distance
GO

Verwendung:

select Distance
from Place P1,
     Place P2,
outer apply dbo.Get_Distance(P1.latitude, P1.longitude, P2.latitude, P2.longitude)

Skalarfunktionen funktionieren ebenfalls, sind jedoch bei der Berechnung großer Datenmengen sehr ineffizient.

Ich hoffe das könnte jemandem helfen.

1
Thurfir