Как найти расстояние между координатами gps

Calculate the distance between two coordinates by latitude and longitude, including a Javascript implementation.

West and South locations are negative.
Remember minutes and seconds are out of 60 so S31 30′ is -31.50 degrees.

Don’t forget to convert degrees to radians. Many languages have this function. Or its a simple calculation: radians = degrees * PI / 180.

function degreesToRadians(degrees) {
  return degrees * Math.PI / 180;
}

function distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
  var earthRadiusKm = 6371;

  var dLat = degreesToRadians(lat2-lat1);
  var dLon = degreesToRadians(lon2-lon1);

  lat1 = degreesToRadians(lat1);
  lat2 = degreesToRadians(lat2);

  var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
          Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  return earthRadiusKm * c;
}

Here are some examples of usage:

distanceInKmBetweenEarthCoordinates(0,0,0,0)  // Distance between same 
                                              // points should be 0
0

distanceInKmBetweenEarthCoordinates(51.5, 0, 38.8, -77.1) // From London
                                                          // to Arlington
5918.185064088764

Federico klez Culloca's user avatar

answered Dec 13, 2008 at 22:22

cletus's user avatar

cletuscletus

614k167 gold badges909 silver badges942 bronze badges

11

Look for haversine with Google; here is my solution:

#include <math.h>
#include "haversine.h"

#define d2r (M_PI / 180.0)

//calculate haversine distance for linear distance
double haversine_km(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 6367 * c;

    return d;
}

double haversine_mi(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * d2r;
    double dlat = (lat2 - lat1) * d2r;
    double a = pow(sin(dlat/2.0), 2) + cos(lat1*d2r) * cos(lat2*d2r) * pow(sin(dlong/2.0), 2);
    double c = 2 * atan2(sqrt(a), sqrt(1-a));
    double d = 3956 * c; 

    return d;
}

Jon Winstanley's user avatar

answered Sep 13, 2009 at 5:46

Peter Greis's user avatar

Peter GreisPeter Greis

6395 silver badges2 bronze badges

7

C# Version of Haversine

double _eQuatorialEarthRadius = 6378.1370D;
double _d2r = (Math.PI / 180D);

private int HaversineInM(double lat1, double long1, double lat2, double long2)
{
    return (int)(1000D * HaversineInKM(lat1, long1, lat2, long2));
}

private double HaversineInKM(double lat1, double long1, double lat2, double long2)
{
    double dlong = (long2 - long1) * _d2r;
    double dlat = (lat2 - lat1) * _d2r;
    double a = Math.Pow(Math.Sin(dlat / 2D), 2D) + Math.Cos(lat1 * _d2r) * Math.Cos(lat2 * _d2r) * Math.Pow(Math.Sin(dlong / 2D), 2D);
    double c = 2D * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1D - a));
    double d = _eQuatorialEarthRadius * c;

    return d;
}

Here’s a .NET Fiddle of this, so you can test it out with your own Lat/Longs.

Mike Chamberlain's user avatar

answered Sep 29, 2011 at 10:27

Roman Makarov's user avatar

2

Java Version of Haversine Algorithm based on Roman Makarov`s reply to this thread

public class HaversineAlgorithm {

    static final double _eQuatorialEarthRadius = 6378.1370D;
    static final double _d2r = (Math.PI / 180D);

    public static int HaversineInM(double lat1, double long1, double lat2, double long2) {
        return (int) (1000D * HaversineInKM(lat1, long1, lat2, long2));
    }

    public static double HaversineInKM(double lat1, double long1, double lat2, double long2) {
        double dlong = (long2 - long1) * _d2r;
        double dlat = (lat2 - lat1) * _d2r;
        double a = Math.pow(Math.sin(dlat / 2D), 2D) + Math.cos(lat1 * _d2r) * Math.cos(lat2 * _d2r)
                * Math.pow(Math.sin(dlong / 2D), 2D);
        double c = 2D * Math.atan2(Math.sqrt(a), Math.sqrt(1D - a));
        double d = _eQuatorialEarthRadius * c;

        return d;
    }

}

user247702's user avatar

user247702

23.5k15 gold badges110 silver badges157 bronze badges

answered Jan 22, 2013 at 13:30

Paulo Miguel Almeida's user avatar

2

This is very easy to do with geography type in SQL Server 2008.

SELECT geography::Point(lat1, lon1, 4326).STDistance(geography::Point(lat2, lon2, 4326))
-- computes distance in meters using eliptical model, accurate to the mm

4326 is SRID for WGS84 elipsoidal Earth model

answered Feb 1, 2009 at 17:38

Marko Tintor's user avatar

0

Here’s a Haversine function in Python that I use:

from math import pi,sqrt,sin,cos,atan2

def haversine(pos1, pos2):
    lat1 = float(pos1['lat'])
    long1 = float(pos1['long'])
    lat2 = float(pos2['lat'])
    long2 = float(pos2['long'])

    degree_to_rad = float(pi / 180.0)

    d_lat = (lat2 - lat1) * degree_to_rad
    d_long = (long2 - long1) * degree_to_rad

    a = pow(sin(d_lat / 2), 2) + cos(lat1 * degree_to_rad) * cos(lat2 * degree_to_rad) * pow(sin(d_long / 2), 2)
    c = 2 * atan2(sqrt(a), sqrt(1 - a))
    km = 6367 * c
    mi = 3956 * c

    return {"km":km, "miles":mi}

PaulMcG's user avatar

PaulMcG

62k16 gold badges93 silver badges130 bronze badges

answered Aug 9, 2013 at 10:21

1

I needed to calculate a lot of distances between the points for my project, so I went ahead and tried to optimize the code, I have found here. On average in different browsers my new implementation runs 2 times faster than the most upvoted answer.

function distance(lat1, lon1, lat2, lon2) {
  var p = 0.017453292519943295;    // Math.PI / 180
  var c = Math.cos;
  var a = 0.5 - c((lat2 - lat1) * p)/2 + 
          c(lat1 * p) * c(lat2 * p) * 
          (1 - c((lon2 - lon1) * p))/2;

  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

You can play with my jsPerf and see the results here.

Recently I needed to do the same in python, so here is a python implementation:

from math import cos, asin, sqrt
def distance(lat1, lon1, lat2, lon2):
    p = 0.017453292519943295
    a = 0.5 - cos((lat2 - lat1) * p)/2 + cos(lat1 * p) * cos(lat2 * p) * (1 - cos((lon2 - lon1) * p)) / 2
    return 12742 * asin(sqrt(a))

And for the sake of completeness: Haversine on wiki.

answered Dec 27, 2015 at 23:46

Salvador Dali's user avatar

Salvador DaliSalvador Dali

212k146 gold badges696 silver badges752 bronze badges

0

It depends on how accurate you need it to be. If you need pinpoint accuracy, it is best to look at an algorithm which uses an ellipsoid, rather than a sphere, such as Vincenty’s algorithm, which is accurate to the mm.

Tomerikoo's user avatar

Tomerikoo

18.1k16 gold badges45 silver badges60 bronze badges

answered Dec 13, 2008 at 22:28

seanb's user avatar

seanbseanb

6,9492 gold badges32 silver badges34 bronze badges

2

Here it is in C# (lat and long in radians):

double CalculateGreatCircleDistance(double lat1, double long1, double lat2, double long2, double radius)
{
    return radius * Math.Acos(
        Math.Sin(lat1) * Math.Sin(lat2)
        + Math.Cos(lat1) * Math.Cos(lat2) * Math.Cos(long2 - long1));
}

If your lat and long are in degrees then divide by 180/PI to convert to radians.

answered May 27, 2010 at 15:42

Mike Chamberlain's user avatar

Mike ChamberlainMike Chamberlain

39.1k27 gold badges109 silver badges157 bronze badges

1

PHP version:

(Remove all deg2rad() if your coordinates are already in radians.)

$R = 6371; // km
$dLat = deg2rad($lat2-$lat1);
$dLon = deg2rad($lon2-$lon1);
$lat1 = deg2rad($lat1);
$lat2 = deg2rad($lat2);

$a = sin($dLat/2) * sin($dLat/2) +
     sin($dLon/2) * sin($dLon/2) * cos($lat1) * cos($lat2); 

$c = 2 * atan2(sqrt($a), sqrt(1-$a)); 
$d = $R * $c;

answered Jan 29, 2015 at 10:38

quape's user avatar

quapequape

7169 silver badges21 bronze badges

1

A T-SQL function, that I use to select records by distance for a center

Create Function  [dbo].[DistanceInMiles] 
 (  @fromLatitude float ,
    @fromLongitude float ,
    @toLatitude float, 
    @toLongitude float
  )
   returns float
AS 
BEGIN
declare @distance float

select @distance = cast((3963 * ACOS(round(COS(RADIANS(90-@fromLatitude))*COS(RADIANS(90-@toLatitude))+ 
SIN(RADIANS(90-@fromLatitude))*SIN(RADIANS(90-@toLatitude))*COS(RADIANS(@fromLongitude-@toLongitude)),15)) 
)as float) 
  return  round(@distance,1)
END

Bo Persson's user avatar

Bo Persson

90.3k31 gold badges145 silver badges203 bronze badges

answered Jul 13, 2011 at 12:43

Henry Vilinskiy's user avatar

1

I. Regarding «Breadcrumbs» method

  1. Earth radius is different on different Lat. This must be taken into consideration in Haversine algorithm.
  2. Consider Bearing change, which turns straight lines to arches (which are longer)
  3. Taking Speed change into account will turn arches to spirals (which are longer or shorter than arches)
  4. Altitude change will turn flat spirals to 3D spirals (which are longer again). This is very important for hilly areas.

Below see the function in C which takes #1 and #2 into account:

double   calcDistanceByHaversine(double rLat1, double rLon1, double rHeading1,
       double rLat2, double rLon2, double rHeading2){
  double rDLatRad = 0.0;
  double rDLonRad = 0.0;
  double rLat1Rad = 0.0;
  double rLat2Rad = 0.0;
  double a = 0.0;
  double c = 0.0;
  double rResult = 0.0;
  double rEarthRadius = 0.0;
  double rDHeading = 0.0;
  double rDHeadingRad = 0.0;

  if ((rLat1 < -90.0) || (rLat1 > 90.0) || (rLat2 < -90.0) || (rLat2 > 90.0)
              || (rLon1 < -180.0) || (rLon1 > 180.0) || (rLon2 < -180.0)
              || (rLon2 > 180.0)) {
        return -1;
  };

  rDLatRad = (rLat2 - rLat1) * DEGREE_TO_RADIANS;
  rDLonRad = (rLon2 - rLon1) * DEGREE_TO_RADIANS;
  rLat1Rad = rLat1 * DEGREE_TO_RADIANS;
  rLat2Rad = rLat2 * DEGREE_TO_RADIANS;

  a = sin(rDLatRad / 2) * sin(rDLatRad / 2) + sin(rDLonRad / 2) * sin(
              rDLonRad / 2) * cos(rLat1Rad) * cos(rLat2Rad);

  if (a == 0.0) {
        return 0.0;
  }

  c = 2 * atan2(sqrt(a), sqrt(1 - a));
  rEarthRadius = 6378.1370 - (21.3847 * 90.0 / ((fabs(rLat1) + fabs(rLat2))
              / 2.0));
  rResult = rEarthRadius * c;

  // Chord to Arc Correction based on Heading changes. Important for routes with many turns and U-turns

  if ((rHeading1 >= 0.0) && (rHeading1 < 360.0) && (rHeading2 >= 0.0)
              && (rHeading2 < 360.0)) {
        rDHeading = fabs(rHeading1 - rHeading2);
        if (rDHeading > 180.0) {
              rDHeading -= 180.0;
        }
        rDHeadingRad = rDHeading * DEGREE_TO_RADIANS;
        if (rDHeading > 5.0) {
              rResult = rResult * (rDHeadingRad / (2.0 * sin(rDHeadingRad / 2)));
        } else {
              rResult = rResult / cos(rDHeadingRad);
        }
  }
  return rResult;
}

II. There is an easier way which gives pretty good results.

By Average Speed.

Trip_distance = Trip_average_speed * Trip_time

Since GPS Speed is detected by Doppler effect and is not directly related to [Lon,Lat] it can be at least considered as secondary (backup or correction) if not as main distance calculation method.

answered Jan 21, 2014 at 15:36

Tod Samay's user avatar

Tod SamayTod Samay

1722 silver badges1 bronze badge

If you need something more accurate then have a look at this.

Vincenty’s formulae are two related iterative methods used in geodesy
to calculate the distance between two points on the surface of a
spheroid, developed by Thaddeus Vincenty (1975a) They are based on the
assumption that the figure of the Earth is an oblate spheroid, and
hence are more accurate than methods such as great-circle distance
which assume a spherical Earth.

The first (direct) method computes the location of a point which is a
given distance and azimuth (direction) from another point. The second
(inverse) method computes the geographical distance and azimuth
between two given points. They have been widely used in geodesy
because they are accurate to within 0.5 mm (0.020″) on the Earth
ellipsoid.

Chad's user avatar

Chad

19.1k4 gold badges49 silver badges72 bronze badges

answered Aug 22, 2011 at 15:35

dsmelser's user avatar

dsmelserdsmelser

811 silver badge1 bronze badge

If you’re using .NET don’t reivent the wheel. See System.Device.Location. Credit to fnx in the comments in another answer.

using System.Device.Location;

double lat1 = 45.421527862548828D;
double long1 = -75.697189331054688D;
double lat2 = 53.64135D;
double long2 = -113.59273D;

GeoCoordinate geo1 = new GeoCoordinate(lat1, long1);
GeoCoordinate geo2 = new GeoCoordinate(lat2, long2);

double distance = geo1.GetDistanceTo(geo2);

Community's user avatar

answered Jan 19, 2017 at 18:11

Tim Partridge's user avatar

Tim PartridgeTim Partridge

3,3551 gold badge41 silver badges51 bronze badges

here is the Swift implementation from the answer

func degreesToRadians(degrees: Double) -> Double {
    return degrees * Double.pi / 180
}

func distanceInKmBetweenEarthCoordinates(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Double {

    let earthRadiusKm: Double = 6371

    let dLat = degreesToRadians(degrees: lat2 - lat1)
    let dLon = degreesToRadians(degrees: lon2 - lon1)

    let lat1 = degreesToRadians(degrees: lat1)
    let lat2 = degreesToRadians(degrees: lat2)

    let a = sin(dLat/2) * sin(dLat/2) +
    sin(dLon/2) * sin(dLon/2) * cos(lat1) * cos(lat2)
    let c = 2 * atan2(sqrt(a), sqrt(1 - a))
    return earthRadiusKm * c
}

answered Aug 14, 2017 at 8:26

Sai Li's user avatar

Sai LiSai Li

6856 silver badges14 bronze badges

This is version from «Henry Vilinskiy» adapted for MySQL and Kilometers:

CREATE FUNCTION `CalculateDistanceInKm`(
  fromLatitude float,
  fromLongitude float,
  toLatitude float, 
  toLongitude float
) RETURNS float
BEGIN
  declare distance float;

  select 
    6367 * ACOS(
            round(
              COS(RADIANS(90-fromLatitude)) *
                COS(RADIANS(90-toLatitude)) +
                SIN(RADIANS(90-fromLatitude)) *
                SIN(RADIANS(90-toLatitude)) *
                COS(RADIANS(fromLongitude-toLongitude))
              ,15)
            )
    into distance;

  return  round(distance,3);
END;

answered Jul 11, 2012 at 9:30

Maxs's user avatar

MaxsMaxs

1933 silver badges9 bronze badges

2

This Lua code is adapted from stuff found on Wikipedia and in Robert Lipe’s GPSbabel tool:

local EARTH_RAD = 6378137.0 
  -- earth's radius in meters (official geoid datum, not 20,000km / pi)

local radmiles = EARTH_RAD*100.0/2.54/12.0/5280.0;
  -- earth's radius in miles

local multipliers = {
  radians = 1, miles = radmiles, mi = radmiles, feet = radmiles * 5280,
  meters = EARTH_RAD, m = EARTH_RAD, km = EARTH_RAD / 1000, 
  degrees = 360 / (2 * math.pi), min = 60 * 360 / (2 * math.pi)
}

function gcdist(pt1, pt2, units) -- return distance in radians or given units
  --- this formula works best for points close together or antipodal
  --- rounding error strikes when distance is one-quarter Earth's circumference
  --- (ref: wikipedia Great-circle distance)
  if not pt1.radians then pt1 = rad(pt1) end
  if not pt2.radians then pt2 = rad(pt2) end
  local sdlat = sin((pt1.lat - pt2.lat) / 2.0);
  local sdlon = sin((pt1.lon - pt2.lon) / 2.0);
  local res = sqrt(sdlat * sdlat + cos(pt1.lat) * cos(pt2.lat) * sdlon * sdlon);
  res = res > 1 and 1 or res < -1 and -1 or res
  res = 2 * asin(res);
  if units then return res * assert(multipliers[units])
  else return res
  end
end

answered Dec 13, 2008 at 22:26

Norman Ramsey's user avatar

Norman RamseyNorman Ramsey

198k59 gold badges360 silver badges532 bronze badges

    private double deg2rad(double deg)
    {
        return (deg * Math.PI / 180.0);
    }

    private double rad2deg(double rad)
    {
        return (rad / Math.PI * 180.0);
    }

    private double GetDistance(double lat1, double lon1, double lat2, double lon2)
    {
        //code for Distance in Kilo Meter
        double theta = lon1 - lon2;
        double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta));
        dist = Math.Abs(Math.Round(rad2deg(Math.Acos(dist)) * 60 * 1.1515 * 1.609344 * 1000, 0));
        return (dist);
    }

    private double GetDirection(double lat1, double lon1, double lat2, double lon2)
    {
        //code for Direction in Degrees
        double dlat = deg2rad(lat1) - deg2rad(lat2);
        double dlon = deg2rad(lon1) - deg2rad(lon2);
        double y = Math.Sin(dlon) * Math.Cos(lat2);
        double x = Math.Cos(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) - Math.Sin(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(dlon);
        double direct = Math.Round(rad2deg(Math.Atan2(y, x)), 0);
        if (direct < 0)
            direct = direct + 360;
        return (direct);
    }

    private double GetSpeed(double lat1, double lon1, double lat2, double lon2, DateTime CurTime, DateTime PrevTime)
    {
        //code for speed in Kilo Meter/Hour
        TimeSpan TimeDifference = CurTime.Subtract(PrevTime);
        double TimeDifferenceInSeconds = Math.Round(TimeDifference.TotalSeconds, 0);
        double theta = lon1 - lon2;
        double dist = Math.Sin(deg2rad(lat1)) * Math.Sin(deg2rad(lat2)) + Math.Cos(deg2rad(lat1)) * Math.Cos(deg2rad(lat2)) * Math.Cos(deg2rad(theta));
        dist = rad2deg(Math.Acos(dist)) * 60 * 1.1515 * 1.609344;
        double Speed = Math.Abs(Math.Round((dist / Math.Abs(TimeDifferenceInSeconds)) * 60 * 60, 0));
        return (Speed);
    }

    private double GetDuration(DateTime CurTime, DateTime PrevTime)
    {
        //code for speed in Kilo Meter/Hour
        TimeSpan TimeDifference = CurTime.Subtract(PrevTime);
        double TimeDifferenceInSeconds = Math.Abs(Math.Round(TimeDifference.TotalSeconds, 0));
        return (TimeDifferenceInSeconds);
    }

answered Jul 22, 2011 at 11:53

Elanchezhian Babu P's user avatar

2

i took the top answer and used it in a Scala program

import java.lang.Math.{atan2, cos, sin, sqrt}

def latLonDistance(lat1: Double, lon1: Double)(lat2: Double, lon2: Double): Double = {
    val earthRadiusKm = 6371
    val dLat = (lat2 - lat1).toRadians
    val dLon = (lon2 - lon1).toRadians
    val latRad1 = lat1.toRadians
    val latRad2 = lat2.toRadians

    val a = sin(dLat / 2) * sin(dLat / 2) + sin(dLon / 2) * sin(dLon / 2) * cos(latRad1) * cos(latRad2)
    val c = 2 * atan2(sqrt(a), sqrt(1 - a))
    earthRadiusKm * c
}

i curried the function in order to be able to easily produce functions that have one of the two locations fixed and require only a pair of lat/lon to produce distance.

answered Jan 13, 2018 at 21:25

Peter Perháč's user avatar

Peter PerháčPeter Perháč

20.4k21 gold badges120 silver badges152 bronze badges

Here’s a Kotlin variation:

import kotlin.math.*

class HaversineAlgorithm {

    companion object {
        private const val MEAN_EARTH_RADIUS = 6371.008
        private const val D2R = Math.PI / 180.0
    }

    private fun haversineInKm(lat1: Double, lon1: Double, lat2: Double, lon2: Double): Double {
        val lonDiff = (lon2 - lon1) * D2R
        val latDiff = (lat2 - lat1) * D2R
        val latSin = sin(latDiff / 2.0)
        val lonSin = sin(lonDiff / 2.0)
        val a = latSin * latSin + (cos(lat1 * D2R) * cos(lat2 * D2R) * lonSin * lonSin)
        val c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a))
        return MEAN_EARTH_RADIUS * c
    }
}

answered May 24, 2020 at 18:54

Csaba Toth's user avatar

Csaba TothCsaba Toth

9,8065 gold badges75 silver badges119 bronze badges

4

you can find a implementation of this (with some good explanation) in F# on fssnip

here are the important parts:


let GreatCircleDistance<[<Measure>] 'u> (R : float<'u>) (p1 : Location) (p2 : Location) =
    let degToRad (x : float<deg>) = System.Math.PI * x / 180.0<deg/rad>

    let sq x = x * x
    // take the sin of the half and square the result
    let sinSqHf (a : float<rad>) = (System.Math.Sin >> sq) (a / 2.0<rad>)
    let cos (a : float<deg>) = System.Math.Cos (degToRad a / 1.0<rad>)

    let dLat = (p2.Latitude - p1.Latitude) |> degToRad
    let dLon = (p2.Longitude - p1.Longitude) |> degToRad

    let a = sinSqHf dLat + cos p1.Latitude * cos p2.Latitude * sinSqHf dLon
    let c = 2.0 * System.Math.Atan2(System.Math.Sqrt(a), System.Math.Sqrt(1.0-a))

    R * c

answered Aug 22, 2011 at 15:40

Random Dev's user avatar

Random DevRandom Dev

51.7k9 gold badges92 silver badges119 bronze badges

I needed to implement this in PowerShell, hope it can help someone else.
Some notes about this method

  1. Don’t split any of the lines or the calculation will be wrong
  2. To calculate in KM remove the * 1000 in the calculation of $distance
  3. Change $earthsRadius = 3963.19059 and remove * 1000 in the calculation of $distance the to calulate the distance in miles
  4. I’m using Haversine, as other posts have pointed out Vincenty’s formulae is much more accurate

    Function MetresDistanceBetweenTwoGPSCoordinates($latitude1, $longitude1, $latitude2, $longitude2)  
    {  
      $Rad = ([math]::PI / 180);  
    
      $earthsRadius = 6378.1370 # Earth's Radius in KM  
      $dLat = ($latitude2 - $latitude1) * $Rad  
      $dLon = ($longitude2 - $longitude1) * $Rad  
      $latitude1 = $latitude1 * $Rad  
      $latitude2 = $latitude2 * $Rad  
    
      $a = [math]::Sin($dLat / 2) * [math]::Sin($dLat / 2) + [math]::Sin($dLon / 2) * [math]::Sin($dLon / 2) * [math]::Cos($latitude1) * [math]::Cos($latitude2)  
      $c = 2 * [math]::ATan2([math]::Sqrt($a), [math]::Sqrt(1-$a))  
    
      $distance = [math]::Round($earthsRadius * $c * 1000, 0) #Multiple by 1000 to get metres  
    
      Return $distance  
    }
    

answered Oct 25, 2012 at 13:05

TheLukeMcCarthy's user avatar

TheLukeMcCarthyTheLukeMcCarthy

2,2532 gold badges25 silver badges34 bronze badges

Scala version

  def deg2rad(deg: Double) = deg * Math.PI / 180.0

  def rad2deg(rad: Double) = rad / Math.PI * 180.0

  def getDistanceMeters(lat1: Double, lon1: Double, lat2: Double, lon2: Double) = {
    val theta = lon1 - lon2
    val dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) *
      Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta))
    Math.abs(
      Math.round(
        rad2deg(Math.acos(dist)) * 60 * 1.1515 * 1.609344 * 1000)
    )
  }

answered Dec 21, 2014 at 14:18

Przemek's user avatar

PrzemekPrzemek

7,0203 gold badges43 silver badges52 bronze badges

Here’s my implementation in Elixir

defmodule Geo do
  @earth_radius_km 6371
  @earth_radius_sm 3958.748
  @earth_radius_nm 3440.065
  @feet_per_sm 5280

  @d2r :math.pi / 180

  def deg_to_rad(deg), do: deg * @d2r

  def great_circle_distance(p1, p2, :km), do: haversine(p1, p2) * @earth_radius_km
  def great_circle_distance(p1, p2, :sm), do: haversine(p1, p2) * @earth_radius_sm
  def great_circle_distance(p1, p2, :nm), do: haversine(p1, p2) * @earth_radius_nm
  def great_circle_distance(p1, p2, :m), do: great_circle_distance(p1, p2, :km) * 1000
  def great_circle_distance(p1, p2, :ft), do: great_circle_distance(p1, p2, :sm) * @feet_per_sm

  @doc """
  Calculate the [Haversine](https://en.wikipedia.org/wiki/Haversine_formula)
  distance between two coordinates. Result is in radians. This result can be
  multiplied by the sphere's radius in any unit to get the distance in that unit.
  For example, multiple the result of this function by the Earth's radius in
  kilometres and you get the distance between the two given points in kilometres.
  """
  def haversine({lat1, lon1}, {lat2, lon2}) do
    dlat = deg_to_rad(lat2 - lat1)
    dlon = deg_to_rad(lon2 - lon1)

    radlat1 = deg_to_rad(lat1)
    radlat2 = deg_to_rad(lat2)

    a = :math.pow(:math.sin(dlat / 2), 2) +
        :math.pow(:math.sin(dlon / 2), 2) *
        :math.cos(radlat1) * :math.cos(radlat2)

    2 * :math.atan2(:math.sqrt(a), :math.sqrt(1 - a))
  end
end

answered Nov 2, 2018 at 8:20

mroach's user avatar

mroachmroach

2,3831 gold badge21 silver badges28 bronze badges

Dart Version

Haversine Algorithm.

import 'dart:math';

class GeoUtils {

  static double _degreesToRadians(degrees) {
    return degrees * pi / 180;
  }

  static double distanceInKmBetweenEarthCoordinates(lat1, lon1, lat2, lon2) {
    var earthRadiusKm = 6371;

    var dLat = _degreesToRadians(lat2-lat1);
    var dLon = _degreesToRadians(lon2-lon1);

    lat1 = _degreesToRadians(lat1);
    lat2 = _degreesToRadians(lat2);

    var a = sin(dLat/2) * sin(dLat/2) +
        sin(dLon/2) * sin(dLon/2) * cos(lat1) * cos(lat2);
    var c = 2 * atan2(sqrt(a), sqrt(1-a));
    return earthRadiusKm * c;
  }
}

answered Jun 7, 2019 at 19:02

abd3llatif's user avatar

abd3llatifabd3llatif

1601 silver badge6 bronze badges

In Python, you can use the geopy library to compute the geodesic distance using the WGS84 ellipsoid:

from geopy.distance import geodesic
newport_ri = (41.49008, -71.312796)
cleveland_oh = (41.499498, -81.695391)
print(geodesic(newport_ri, cleveland_oh).km)

answered Jun 30, 2021 at 13:33

Dean Mark's user avatar

Dean MarkDean Mark

711 silver badge4 bronze badges

TypeScript Version

export const degreeToRadian = (degree: number) => {
  return degree * Math.PI / 180;
}

export const distanceBetweenEarthCoordinatesInKm = (lat1: number, lon1: number, lat2: number, lon2: number) => {
    const earthRadiusInKm = 6371;

    const dLat = degreeToRadian(lat2 - lat1);
    const dLon = degreeToRadian(lon2 - lon1);

    lat1 = degreeToRadian(lat1);
    lat2 = degreeToRadian(lat2);

    const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

    return earthRadiusInKm * c;
}

answered May 12, 2022 at 3:33

ramzan ali's user avatar

ramzan aliramzan ali

4614 silver badges14 bronze badges

I think a version of the algorithm in R is still missing:

gpsdistance<-function(lat1,lon1,lat2,lon2){

# internal function to change deg to rad

degreesToRadians<- function (degrees) {
return (degrees * pi / 180)
}

R<-6371e3  #radius of Earth in meters

phi1<-degreesToRadians(lat1) # latitude 1
phi2<-degreesToRadians(lat2) # latitude 2
lambda1<-degreesToRadians(lon1) # longitude 1
lambda2<-degreesToRadians(lon2) # longitude 2

delta_phi<-phi1-phi2 # latitude-distance
delta_lambda<-lambda1-lambda2 # longitude-distance

a<-sin(delta_phi/2)*sin(delta_phi/2)+
cos(phi1)*cos(phi2)*sin(delta_lambda/2)*
sin(delta_lambda/2)

cc<-2*atan2(sqrt(a),sqrt(1-a))

distance<- R * cc

return(distance)  # in meters
}

answered Apr 6, 2020 at 11:32

shghm's user avatar

shghmshghm

2402 silver badges8 bronze badges

For java

public static double degreesToRadians(double degrees) {
    return degrees * Math.PI / 180;
}

public static double distanceInKmBetweenEarthCoordinates(Location location1, Location location2) {
    double earthRadiusKm = 6371;

    double dLat = degreesToRadians(location2.getLatitude()-location1.getLatitude());
    double dLon = degreesToRadians(location2.getLongitude()-location1.getLongitude());

    double lat1 = degreesToRadians(location1.getLatitude());
    double lat2 = degreesToRadians(location2.getLatitude());

    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    return earthRadiusKm * c;
}

answered Mar 3, 2021 at 19:16

Lakpriya Senevirathna's user avatar

For anyone searching for a Delphi/Pascal version:

function GreatCircleDistance(const Lat1, Long1, Lat2, Long2: Double): Double;
var
  Lat1Rad, Long1Rad, Lat2Rad, Long2Rad: Double;
const
  EARTH_RADIUS_KM = 6378;
begin
  Lat1Rad  := DegToRad(Lat1);
  Long1Rad := DegToRad(Long1);
  Lat2Rad  := DegToRad(Lat2);
  Long2Rad := DegToRad(Long2);
  Result   := EARTH_RADIUS_KM * ArcCos(Cos(Lat1Rad) * Cos(Lat2Rad) * Cos(Long1Rad - Long2Rad) + Sin(Lat1Rad) * Sin(Lat2Rad));
end;

I take no credit for this code, I originally found it posted by Gary William on a public forum.

answered Apr 8, 2021 at 13:01

bLight's user avatar

bLightbLight

8037 silver badges23 bronze badges

На чтение 5 мин. Просмотров 2.4k. Опубликовано 12.08.2022

Спутниковые координаты не только помогают найти маршрут до нужного места, но и позволяют рассчитать отрезок между двумя любыми точками в пространстве или на данной плоскости. Зная необходимые данные и координаты интересующих объектов, можно найти расстояние в километрах или метрах между этими длинами или отрезками нужной длины. Для этого применяется либо сложная формула для самостоятельного решения, либо онлайн-калькуляторы на сайте или картографические программы, выполняющие работу автоматически.

Содержание

  1. Координаты GPS
  2. Вычисление расстояния между двумя точками через формулу
  3. Формула для нахождения расстояния между точками
  4. Способы решения и нахождения расстояния между точками по координатам
  5. Онлайн-калькулятор для расчета расстояния между точками по координатам
  6. Картографическая программа для нахождения расстояния между точками
  7. Откуда берется погрешность при расчете расстояния между точками

Координаты GPS

Координаты GPS (Global Positioning System) – это цифровые обозначения местоположения устройства в пространстве или на плоскости, указанные в формате соотнесения географических широты и долготы. Данные точки на отрезке определенной длины вычисляются при помощи связи со спутником. Запускается сложная система навигации, которая, помимо указания координат, может определить расстояние между двумя точками в пространстве или на плоскости, проложить маршрут между отрезками длины и рассчитать время перемещения как пешком, так и на разных видах транспорта. В основе работы лежит всемирная система координат WGS 84.

Координаты GPS

Координаты GPS

Чтобы найти местоположение и расстояние между двумя данными точками или отрезками длины в пространстве и на плоскости по координатам GPS, можно пользоваться как специальным навигатором или профессиональным навигационным прибором, так и обычным смартфоном или планшетом.

Вычисление расстояния между двумя точками через формулу

Найти расстояние между двумя точками в пространстве или на плоскости можно как по прямой, так и по маршруту (с учетом расположения дорог, их поворотов, объездов и пр.). В первом случае применима специальная формула, воспользоваться которой можно как в автоматическом режиме, введя известные данные отрезков в калькулятор на сайте, так и самостоятельно, проведя итоговое решение с нужными материалами на бумаге.

Кратчайшим (прямым) расстоянием считается дуга, проходящая по поверхности Земли от точки А в точку Б. Чтобы найти ее длину, применяют так называемую модифицированную формулу гаверсинусов, учитывающую радиус планеты.

Известно, что Земля – не идеальный шар, а несколько приплюснутый, потому и радиус у нее в разных точках различен. Ввиду этого для подсчета кратчайшего расстояния между точками используется усредненное значение радиуса относительно оси (6372.795 км для Земли), что допускает погрешность итогового значения около 0,5 %.

Формула для нахождения расстояния между точками

В формуле, при помощи которой можно найти расстояния между двумя данными точками планеты с использованием координат, присутствуют следующие величины (известные из математики):

  • d – центральный угол (перпендикуляр) между двумя данными точками, лежащими на большом круге (т. е. на окружности, получаемой при сечении центральной части шара плоскостью);
  • r – радиус сферы (т. е. усредненное значение радиуса Земли: 6372.795 км);
  • y₁ и y₂ –  широта двух точек в радианах;
  • x₁ и x₂ – долгота двух точек в радианах.

Получим следующую тригонометрическую формулу, плавно вытекающую из теоремы пифагора (евклидова геометрия), которая равна:

cos(d) = sin(y₁)·sin(y₂) + cos(y₁)·cos(y₂)·cos(x₁ − x₂)

Данное соотношение можно получить из прямоугольного треугольника.

Подставив в формулу заданные значения точек, и получим вычисление.

Для того чтобы найти ответ про расстояние между двумя точками координат в километрах, поможет формула:

L = d·R.

Способы решения и нахождения расстояния между точками по координатам

Чтобы провести решение и получить ответ о расстоянии точек в пространстве или плоскости по координатам GPS, необязательно использовать формулу вручную. Ответ о расстоянии между точками по координатам получим при помощи специальных утилит.

Онлайн-калькулятор для расчета расстояния между точками по координатам

В интернете есть множество сайтов с однотипными формулами в онлайн-калькуляторах для решения и нахождения прямого расстояния между двумя точками по координатам. Для этого нужно узнать широту и долготу двух искомых точек в пространстве или на плоскости и вбить эти данные в соответствующие окошки формулы (чем больше знаков после запятой у каждой точки известно, тем точнее получим значение).

Картографическая программа для нахождения расстояния между точками

Вычислять расстояние между двумя точками на плоскости по координатам и давать точный ответ умеет любое приложение-навигатор и без вычисления по формуле, например:

  • «Карты»;
  • «Google.Maps»;
  • «Google Планета Земля»;
  • «SAS.Планета».

Определение координат объекта в Google Maps на компьютере

Определение координат объекта в Google Maps на компьютере не по формуле

Для определения расстояния между точками не по дорогам и маршрутам, а напрямую по двум точкам, применяется инструмент «Линейка».

Многие из популярных навигаторов способны определять расстояние по координатам двух точек онлайн без формул: это можно сделать на сайте в разделе «Азимут» или «Другие вычисления».

На заметку. Наиболее точные данные между точками предоставляют материалы и таблицы кадастровых справочников, но также в них много информации, лишней для обычного пользователя.

Откуда берется погрешность при расчете расстояния между точками

При вычислении прямого расстояния между координатами двух точек применяется подсчет длины дуги этих точек, для чего берется радиус точек (его приблизительное среднее значение ввиду особенностей формы Земли). Из-за этого возникает погрешность, т. е. мы получим не точную информацию о расстоянии между точками.

Чем больше искомое расстояние, тем больше получим погрешность в расстоянии между точками.

Также неточность между точками получим тогда, когда при вычислениях расстояния между точками берут недостаточно цифр после запятой в координатах: результат будет приблизительным.

Так, между любыми двумя известными точками на чертеже Земли можно проложить как обычное расстояние по дорогам, так и прямую линию, которая соединяет каждую точку. Вычисления точек проводят вручную или автоматически, причем во втором случае даже будет известна возможная погрешность, которую получим при нахождении расстояние между точками, неизбежная при измерении сферы Земли.

Если есть под рукой карта Google, то расстояние между двумя точками с заданными координатами можно определить с помощью инструмента Линейка.

текст при наведении

Если этот инструмент не включен, его необходимо включить в Лаборатории карт (в левом нижнем углу).

текст при наведении

Координаты можно нанести на карту либо через окно Поиск, либо через задание Маршрута.


Кратчайшим расстоянием между двумя точками на сфере является длина дуги большого круга (круга, проходящего через эти две точки и центр сферы). Эта дуга называется ортодромией (имеется в виду наименьшая из двух дуг большого круга).

Кратчайшее расстояние или длина ортодромии определяется формулой:

L = R x Y

где R – радиус сферы,

Y – центральный угол в радианах.

или

L = пR x A/180 град.

где A — центральный угол в градусах (п — «пи»).

Пусть x1, y1 и x2, y2 — широта и долгота двух точек. Тогда центральный угол будет определяться сферическим законом косинусов:

Y = arccos(sin x1 sin x2 + cos x1 cos x2 cos (y2 — y1))

Следует заметить, что при вычислениях с невысокой точностью (а тем более на калькуляторе) по этой формуле особенно при небольших расстояниях между точками, точность результата будет весьма невысока, поскольку центральный угол будет 0,99999999. (На 64-разрядных компьютерах точность может достигать нескольких метров на километр.)

Поэтому для практических целей применялись другие формулы с использованием синус-верзусов (обращенных синусов), которые сыграли важную роль в навигации.

В следующей формуле использован haversine (haversin, гаверсинус) — квадрат синуса половинного угла.

текст при наведении

где переменные: кратчайшее расстояние, радиус сферы, широта и долгота точек соответственно.

Формула гаверсинусов хорошо работает при сравнительно небольших расстояниях, но имеет проблему для антиподов. Формула через арктангенс устраняет эту проблему. Центральный угол равен:

текст при наведении


Для расчета расстояния между двумя точками по GPS-координатам можно написать несложную программу. Вот тут можно «поиграть» с программкой на JavaScript.

Для координат, приведенных в вопросе: L = 751 м. (эта цифра неплохо сходится с результатом, полученным Линейкой в картах Google).


Скрипты: JavaScript, Python

В современном мире широко распространены технические разработки, связанные со спутниковой навигацией. Навигационные системы позволяют не терять ориентацию в незнакомом месте, проложить оптимальный путь от точки до точки, найти ближайший магазин, определить расстояние от одного пункта до другого.

Как вычислить расстояние между координатами gps

С помощью координат определяют местоположение объекта на земном шаре. Координаты обозначаются в градусах по широте и долготе. Широты отсчитываются от линии экватора по обеим сторонам. В Северном полушарии широты положительные, в Южном полушарии – отрицательные. Долгота отсчитывается от начального меридиана либо на восток, либо на запад, соответственно получается либо восточная долгота, либо западная.

Согласно общепринятому положению, за начальный меридиан принят меридиан, который проходит через старую Гринвичскую обсерваторию в Гринвиче. Географические координаты местоположения можно получить с помощью GPS-навигатора. Этот прибор получает сигналы спутниковой системы позиционирования в системе координат WGS-84, единой для всего мира.

Модели навигаторов различаются по производителям, функционалу и интерфейсу. В настоящее время встроенные GPS-навигаторы имеются и в некоторых моделях сотовых телефонов. Но любая модель может записать и сохранить координаты точки.

Для решения практических и теоретических задач в некоторых отраслях производства необходимо уметь определять расстояния между точками по их координатам. Для этого можно использовать несколько способов. Каноническая форма представления географических координат: градусы, минуты, секунды.

Для примера можно определить расстояние между следующими координатами: точка №1 — широта 55°45′07″ с.ш., долгота 37°36′56″ в.д.; точка №2 — широта 58°00′02″ с.ш., долгота 102°39′42″ в.д.

Наиболее простой способ — воспользоваться онлайн-калькулятором для расчета протяженности между двумя точками. В поисковике браузера необходимо задать следующие параметры для поиска: онлайн-калькулятор для расчета расстояния между двумя координатами. В онлайн-калькуляторе вводятся значения широт и долгот в поля запросов для первой и второй координаты. При расчете онлайн-калькулятор выдал результат – 3 800 619 м.

Следующий способ более трудоемкий, но и более наглядный. Необходимо воспользоваться любой доступной картографической или навигационной программой. К программам, в которых можно создать точки по координатам и измерить расстояния между ними, относятся следующие приложения: BaseCamp (современный аналог программы MapSource), «Google Планета Земля», «SAS.Планета».

Все вышеперечисленные программы доступны для любого пользователя сети. К примеру, для расчета расстояния между двумя координатами в программе «Google Планета Земля» необходимо создать две метки с указанием координат первой точки и второй точки. Затем при помощи инструмента «Линейка» нужно соединить линией первую и вторую метки, программа автоматически выдаст результат промера и покажет путь на спутниковом снимке Земли.

В случае с примером, приведенным выше, программа «Google Планета Земля» выдала результат – протяженность расстояния между точкой №1 и точкой №2 составляет 3 817 353 м.

Все расчеты протяженности между координатами основаны на расчете длины дуги. В расчете длины дуги участвует радиус Земли. Но так как форма Земли близка к сплюснутому эллипсоиду, радиус Земли в определенных точках различается. Для расчетов расстояния между координатами принимается среднее значение радиуса Земли, что дает погрешность в измерении. Чем больше измеряемое расстояние, тем больше погрешность.

расстояния между двумя точками на карте

Привет всем! Вчера столкнулся с проблемой определения расстояния между двумя точками на карте по координатам GPS. Т.е. есть у нас начальные координаты точки, есть координаты точки, к которой нам нужно определить расстояние — но как это сделать?

На помощь приходит формула Хаверсина (я не ручаюсь на точность названия — в различных источниках эта формула называется самыми различными образами). Собственно, вникать в теорию не буду — ниже приведу рабочий код на Python, быть может — он вам пригодится. И да — я не претендую на оригинальность в коде — он культурно слямзен с какого-то форума (зачем изобретать велосипед, верно?).

from math import radians, cos, sin, asin, sqrt, atan2
lat1 = начальная широта
lon1 = начальная долгота
lat2 = финальная широта
lon2 = финальная долгота
 
lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
print(lat1, lon1, lat2, lon2)
# haversine formula 
dlon = abs(lon2 - lon1) 
dlat = abs(lat2 - lat1) 
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * atan2(sqrt(a), sqrt(1-a)) 
r = 6371 #Указываем, если нам нужно расстояние в километрах. Если же нужно считать в милях - укажите: 3956
print(c * r)

Больше …

Больше ...

Привет всем! Сегодня — маленький пост по поводу генерации поддельной…

Понравилась статья? Поделить с друзьями:
  • Как составить меню на день по английскому
  • Как найти адреса посещенных сайтов
  • Как найти масу по формуле
  • Как найти спонсора в инстаграмме
  • Как составить севооборот картофеля