जवाबों:
अक्षांश और देशांतर द्वारा दो निर्देशांक के बीच की दूरी की गणना करें , जिसमें एक जावास्क्रिप्ट कार्यान्वयन भी शामिल है।
पश्चिम और दक्षिण स्थान नकारात्मक हैं। याद रखें मिनट और सेकंड 60 से बाहर हैं इसलिए S31 30 '-31.50 डिग्री है।
डिग्री को रेडियंस में बदलना न भूलें । कई भाषाओं में यह कार्य है। या इसकी एक साधारण गणना 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;
}
यहां कुछ उदाहरण दिए गए हैं:
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
Number.prototype.toRad = function() { return this * (Math.PI / 180); };
:। या, जैसा कि नीचे बताया गया है, आप (Math.PI/2)
बढ़े हुए प्रदर्शन के लिए 0.0174532925199433 (... जो भी परिशुद्धता आप आवश्यक समझे हैं) के साथ बदल सकते हैं ।
R
गणित में सामान्य रूप से क्या मतलब है, इसके बारे में सोचें , फिर प्रासंगिक, पृथ्वी से संबंधित मात्राओं को देखें कि क्या संख्याएं मेल खाती हैं।
earthRadiusKm
होना करने के लिए var earthRadiusMiles = 3959;
FYI करें,।
Google के साथ हैवरसाइन की तलाश करें; यहाँ मेरा समाधान है:
#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;
}
हवेर्सिन का सी # संस्करण
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;
}
यहां इसका .NET फिडल दिया गया है , जिससे आप इसे अपने खुद के Lat / Longs के साथ टेस्ट कर सकते हैं।
रोमन माकारोव के इस धागे के उत्तर के आधार पर हेवेरस एल्गोरिथ्म का जावा संस्करण
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;
}
}
0.07149
किमी दिया, जबकि आपके सूत्र ने मुझे दिया था 0.07156
जो कि लगभग 99% की सटीकता है
यह 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 WGS84 एलीपोसाइडल अर्थ मॉडल के लिए SRID है
यहाँ पायथन में एक हेवेरसिन फ़ंक्शन है जिसका मैं उपयोग करता हूं:
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}
यह इस बात पर निर्भर करता है कि आपको इसकी आवश्यकता कितनी सटीक है, अगर आपको पिनपॉइंट सटीकता की आवश्यकता है, तो एक क्षेत्र के बजाय एक दीर्घवृत्त का उपयोग करने वाले एल्गोरिथ्म को देखना सबसे अच्छा है, जैसे कि विन्सेटी का एल्गोरिथ्म, जो मिमी के लिए सटीक है। http://en.wikipedia.org/wiki/Vincenty%27s_algorithm
यहाँ यह C # में है (रेडियन में लम्बे और लंबे):
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));
}
यदि आपका लेट और लॉन्ग डिग्री में है तो रेडियन में बदलने के लिए 180 / PI से विभाजित करें।
मुझे अपनी परियोजना के लिए बिंदुओं के बीच बहुत अधिक दूरी की गणना करने की आवश्यकता थी, इसलिए मैंने आगे बढ़कर कोड को अनुकूलित करने का प्रयास किया, मैंने यहां पाया है। अलग-अलग ब्राउज़रों में औसतन मेरा नया कार्यान्वयन सबसे अधिक उत्तर वाले उत्तर की तुलना में 2 गुना तेज चलता है ।
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
}
आप मेरे jsPerf के साथ खेल सकते हैं और यहां परिणाम देख सकते हैं ।
हाल ही में मुझे अजगर में भी ऐसा करने की आवश्यकता है, इसलिए यहां एक अजगर का कार्यान्वयन है :
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))
और पूर्णता के लिए: विकी पर हैवरसाइन ।
PHP संस्करण:
( deg2rad()
यदि आपके निर्देशांक पहले से ही रेडियन में हैं तो सभी को हटा दें ।)
$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;
एक टी-एसक्यूएल फ़ंक्शन, जिसे मैं एक केंद्र के लिए दूरी से रिकॉर्ड का चयन करने के लिए उपयोग करता हूं
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
अगर आपको कुछ और सटीक चाहिए तो इस पर एक नज़र डालें ।
विन्सेन्टी के सूत्र दो संबंधित पुनरावृत्त विधियाँ हैं जिनका उपयोग जियोडेसी में किया जाता है, जो एक गोलक की सतह पर दो बिंदुओं के बीच की दूरी की गणना करने के लिए थाडडेस विन्सेंटी (1975 ए) द्वारा विकसित की गई है। वे इस धारणा पर आधारित हैं कि पृथ्वी का आंकड़ा एक तिरछा गोलाकार है, और इसलिए ग्रेट-सर्कल दूरी जैसी विधियों से अधिक सटीक हैं जो एक गोलाकार पृथ्वी मानती हैं।
पहली (प्रत्यक्ष) विधि एक बिंदु के स्थान की गणना करती है जो किसी अन्य बिंदु से दी गई दूरी और अज़ीमुथ (दिशा) है। दूसरी (विलोम) विधि भौगोलिक दूरी और अज़ीमुथ की गणना दो दिए गए बिंदुओं के बीच करती है। उनका उपयोग भूगर्भ में व्यापक रूप से किया गया है क्योंकि वे पृथ्वी के दीर्घवृत्ताभ पर 0.5 मिमी (0.020 in) के भीतर सटीक हैं।
I. "ब्रेडक्रंब" विधि के बारे में
नीचे C में फ़ंक्शन देखें जो खाते में # 1 और # 2 लेता है:
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;
}
द्वितीय। एक आसान तरीका है जो बहुत अच्छे परिणाम देता है।
औसत गति से।
Trip_distance = Trip_aiture_speed * Trip_time
चूंकि GPS स्पीड का पता डॉपलर प्रभाव से लगाया जाता है और यह सीधे [लोन, लैट] से संबंधित नहीं है, इसलिए इसे मुख्य दूरी की गणना पद्धति के रूप में नहीं तो कम से कम माध्यमिक (बैकअप या सुधार) माना जा सकता है।
यदि आप .NET का उपयोग कर रहे हैं तो व्हील को रीवाइंड न करें। System.Device.Location देखें । एक अन्य उत्तर में टिप्पणियों में fnx का श्रेय ।
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);
यह Lua कोड विकिपीडिया पर और रॉबर्ट Lipe के GPSbabel टूल में पाए गए सामान से अनुकूलित है :
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
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);
}
यह MySQL और किलोमीटर के लिए अनुकूलित "हेनरी विलिंस्की" से संस्करण है:
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;
MySQL
कहाSomething is wrong in your syntax near '' on line 8
// declare distance float;
यहाँ उत्तर से स्विफ्ट कार्यान्वयन है
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
}
मैंने शीर्ष उत्तर लिया और एक स्काला कार्यक्रम में इसका इस्तेमाल किया
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
}
मैंने कार्य को आसानी से करने के लिए दो स्थानों में से एक को तय करने वाले कार्यों का उत्पादन करने में सक्षम होने के लिए और दूरी बनाने के लिए केवल लैट / लोन की एक जोड़ी की आवश्यकता होती है।
मुझे लगता है कि आप इसे पृथ्वी की वक्रता के साथ चाहते हैं। आपके दो बिंदु और पृथ्वी का केंद्र एक समतल पर है। पृथ्वी का केंद्र उस तल पर एक वृत्त का केंद्र है और उस वृत्त की परिधि पर दो बिंदु (लगभग) हैं। उससे आप यह पता लगाकर दूरी की गणना कर सकते हैं कि एक बिंदु से दूसरे बिंदु पर कोण क्या है।
यदि अंक समान ऊंचाइयां नहीं हैं, या यदि आपको यह ध्यान रखने की आवश्यकता है कि पृथ्वी एक परिपूर्ण क्षेत्र नहीं है, तो यह थोड़ा कठिन हो जाता है।
Fssnip पर F # में आप इसे (कुछ अच्छी व्याख्या के साथ) लागू कर सकते हैं
यहाँ महत्वपूर्ण भाग हैं:
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
मुझे इसे PowerShell में लागू करने की आवश्यकता थी, आशा है कि यह किसी और की मदद कर सकता है। इस विधि के बारे में कुछ नोट्स
मैं हॅवरसाइन का उपयोग कर रहा हूँ, जैसा कि अन्य पोस्टों ने बताया है कि विन्सेन्टी के सूत्र अधिक सटीक हैं
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
}
स्काला संस्करण
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)
)
}
// शायद एक टाइपो त्रुटि?
हमारे पास गेटडायरेक्शन में एक अप्रयुक्त चर डलॉन है,
मैं मानता हूं
double y = Math.Sin(dlon) * Math.Cos(lat2);
// cannot use degrees in Cos ?
होना चाहिए
double y = Math.Sin(dlon) * Math.Cos(dlat);
यहाँ अमृत में मेरा कार्यान्वयन है
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
डार्ट संस्करण
हैवरसाइन एल्गोरिथम।
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;
}
}
मुझे लगता है कि R में एल्गोरिथ्म का एक संस्करण अभी भी गायब है:
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
}
यहाँ एक कोटलिन भिन्नता है:
import kotlin.math.*
class HaversineAlgorithm {
companion object {
private const val MEAN_EARTH_RADIUS = 6371.0
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 EQATORIAL_EARTH_RADIUS * c
}
}