17

Jul

[GIS] Calcolare la distanza tra due coordinate GPS

Ciao a tutti

approfitto del periodo estivo per condividere alcuni tip utili per chi si diletta a sviluppare codice per applicazioni che fanno uso frequente della geografia terrestre

 

 

in questo primo tip voglio condividere una funzione di base per calcolare la distanza tra due punti terrestri in metri (in C# e SQL):

 

C#

public static double CalculateDistanceInMeters(double lat1, double lon1, double lat2, double lon2)
{
    //Authalic radius in km http://en.wikipedia.org/wiki/Earth_radius
    double rad = 6371.0072; //Earth radius in Km

    //Convert to radians
    double p1X = lat1 / 180 * Math.PI;
    double p1Y = lon1 / 180 * Math.PI;
    double p2X = lat2 / 180 * Math.PI;
    double p2Y = lon2 / 180 * Math.PI;

    return Math.Acos(Math.Sin(p1Y) * Math.Sin(p2Y) + Math.Cos(p1Y) * Math.Cos(p2Y) * Math.Cos(p2X - p1X)) * rad * 1000;
}

 

demo:

static void Main(string[] args)
{
    var milano = new { lat = 45.464194D, lon = 9.188132D };
    var roma = new { lat = 41.904321D, lon = 12.491455D };

    var s = new Stopwatch();
    s.Start();
    var distance = CalculateDistanceInMeters(milano.lat, milano.lon, roma.lat, roma.lon) / 1000D;
    s.Stop();

    Console.Write("Milano to Roma = {0:N3}km in {1:N0}ms", distance, s.ElapsedMilliseconds);
    Console.ReadLine();
}

 

 

SQL:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[udfGetDistanceInMeters]
(
    @lat1 float,
    @lon1 float,
    @lat2 float,
    @lon2 float
)
RETURNS float
AS
BEGIN

--Authalic radius in km http://en.wikipedia.org/wiki/Earth_radius
declare @rad float = 6371.0072;

--Convert to radians
declare @p1X float = @lat1 / 180 * PI();
declare @p1Y float = @lon1 / 180 * PI();
declare @p2X float = @lat2 / 180 * PI();
declare @p2Y float = @lon2 / 180 * PI();

RETURN Acos(Sin(@p1Y) * Sin(@p2Y) + Cos(@p1Y) * Cos(@p2Y) * Cos(@p2X - @p1X)) * @rad * 1000;
END

 

demo:


--milano -> roma:
select dbo.udfGetDistanceInMeters(45.464194, 9.188132, 41.904321, 12.491455)

 

a presto

by Antonio Esposito on 7/17/2012