Obecnie używam poniższej funkcji i nie działa ona poprawnie. Według Google Maps odległość między tymi współrzędnymi (od 59.3293371,13.4877472
do 59.3225525,13.4619422
) to 2.2
kilometry, podczas gdy funkcja zwraca 1.6
kilometry. Jak sprawić, by ta funkcja zwracała prawidłową odległość?
function getDistanceFromLatLonInKm(lat1, lon1, lat2, lon2) {
var R = 6371; // Radius of the earth in km
var dLat = deg2rad(lat2-lat1); // deg2rad below
var dLon = deg2rad(lon2-lon1);
var a =
Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) *
Math.sin(dLon/2) * Math.sin(dLon/2)
;
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km
return d;
}
function deg2rad(deg) {
return deg * (Math.PI/180)
}
jsFiddle: http://jsfiddle.net/edgren/gAHJB/
javascript
coordinates
distance
Airikr
źródło
źródło
Odpowiedzi:
To, czego używasz, nazywa się formułą haversine , która oblicza odległość między dwoma punktami na kuli w linii prostej . Podany przez Ciebie link do Map Google pokazuje odległość jako 2,2 km, ponieważ nie jest to linia prosta.
Wolphram Alpha to świetne źródło do wykonywania obliczeń geograficznych, a także pokazuje odległość 1,652 km między tymi dwoma punktami .
Jeśli szukasz odległości w linii prostej (jak pliki wrona), twoja funkcja działa poprawnie. Jeśli chcesz pokonać odległość (lub odległość jazdy rowerem, odległość transportu publicznego lub odległość pieszo), musisz użyć interfejsu API mapowania ( najpopularniejsze są Google lub Bing ), aby uzyskać odpowiednią trasę, która będzie zawierać odległość.
Nawiasem mówiąc, interfejs API Map Google zapewnia spakowaną metodę odległości sferycznej w swojej
google.maps.geometry.spherical
przestrzeni nazw (szukajcomputeDistanceBetween
). To prawdopodobnie lepsze niż toczenie własnym (na początek używa dokładniejszej wartości promienia Ziemi).Dla wybrednych z nas, kiedy mówię „odległość w linii prostej”, mam na myśli „linię prostą na kuli”, która jest w rzeczywistości linią zakrzywioną (tj. Ortodromą), oczywiście.
źródło
Podobne równanie napisałem wcześniej - przetestowałem i też dostałem 1,6 km.
Twoje mapy Google pokazywały odległość JAZDY.
Twoja funkcja oblicza w linii prostej (odległość w linii prostej).
alert(calcCrow(59.3293371,13.4877472,59.3225525,13.4619422).toFixed(1)); //This function takes in latitude and longitude of two location and returns the distance between them as the crow flies (in km) function calcCrow(lat1, lon1, lat2, lon2) { var R = 6371; // km var dLat = toRad(lat2-lat1); var dLon = toRad(lon2-lon1); var lat1 = toRad(lat1); var lat2 = toRad(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)); var d = R * c; return d; } // Converts numeric degrees to radians function toRad(Value) { return Value * Math.PI / 180; }
źródło
Rozwiązanie Dereka działało dobrze dla mnie i właśnie przekonwertowałem je na PHP, mam nadzieję, że komuś pomoże!
function calcCrow($lat1, $lon1, $lat2, $lon2){ $R = 6371; // km $dLat = toRad($lat2-$lat1); $dLon = toRad($lon2-$lon1); $lat1 = toRad($lat1); $lat2 = toRad($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; return $d; } // Converts numeric degrees to radians function toRad($Value) { return $Value * pi() / 180; }
źródło
Spróbuj tego. Znajduje się w VB.net i musisz przekonwertować go na JavaScript. Ta funkcja przyjmuje parametry w minutach dziesiętnych.
Private Function calculateDistance(ByVal long1 As String, ByVal lat1 As String, ByVal long2 As String, ByVal lat2 As String) As Double long1 = Double.Parse(long1) lat1 = Double.Parse(lat1) long2 = Double.Parse(long2) lat2 = Double.Parse(lat2) 'conversion to radian lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0 long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0 lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0 long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0 ' use to different earth axis length Dim a As Double = 6378137.0 ' Earth Major Axis (WGS84) Dim b As Double = 6356752.3142 ' Minor Axis Dim f As Double = (a - b) / a ' "Flattening" Dim e As Double = 2.0 * f - f * f ' "Eccentricity" Dim beta As Double = (a / Math.Sqrt(1.0 - e * Math.Sin(lat1) * Math.Sin(lat1))) Dim cos As Double = Math.Cos(lat1) Dim x As Double = beta * cos * Math.Cos(long1) Dim y As Double = beta * cos * Math.Sin(long1) Dim z As Double = beta * (1 - e) * Math.Sin(lat1) beta = (a / Math.Sqrt(1.0 - e * Math.Sin(lat2) * Math.Sin(lat2))) cos = Math.Cos(lat2) x -= (beta * cos * Math.Cos(long2)) y -= (beta * cos * Math.Sin(long2)) z -= (beta * (1 - e) * Math.Sin(lat2)) Return Math.Sqrt((x * x) + (y * y) + (z * z)) End Function
Edytuj Przekonwertowana funkcja w javascript
function calculateDistance(lat1, long1, lat2, long2) { //radians lat1 = (lat1 * 2.0 * Math.PI) / 60.0 / 360.0; long1 = (long1 * 2.0 * Math.PI) / 60.0 / 360.0; lat2 = (lat2 * 2.0 * Math.PI) / 60.0 / 360.0; long2 = (long2 * 2.0 * Math.PI) / 60.0 / 360.0; // use to different earth axis length var a = 6378137.0; // Earth Major Axis (WGS84) var b = 6356752.3142; // Minor Axis var f = (a-b) / a; // "Flattening" var e = 2.0*f - f*f; // "Eccentricity" var beta = (a / Math.sqrt( 1.0 - e * Math.sin( lat1 ) * Math.sin( lat1 ))); var cos = Math.cos( lat1 ); var x = beta * cos * Math.cos( long1 ); var y = beta * cos * Math.sin( long1 ); var z = beta * ( 1 - e ) * Math.sin( lat1 ); beta = ( a / Math.sqrt( 1.0 - e * Math.sin( lat2 ) * Math.sin( lat2 ))); cos = Math.cos( lat2 ); x -= (beta * cos * Math.cos( long2 )); y -= (beta * cos * Math.sin( long2 )); z -= (beta * (1 - e) * Math.sin( lat2 )); return (Math.sqrt( (x*x) + (y*y) + (z*z) )/1000); }
źródło
const earthsMajorAccess = 6378137.0;
wyeliminowanie potrzeby przydatnych komentarzy (ponieważ nazwa zmiennej wskazuje, czym ona jest)Używając formuły Haversine, źródło kodu :
//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //::: ::: //::: This routine calculates the distance between two points (given the ::: //::: latitude/longitude of those points). It is being used to calculate ::: //::: the distance between two locations using GeoDataSource (TM) prodducts ::: //::: ::: //::: Definitions: ::: //::: South latitudes are negative, east longitudes are positive ::: //::: ::: //::: Passed to function: ::: //::: lat1, lon1 = Latitude and Longitude of point 1 (in decimal degrees) ::: //::: lat2, lon2 = Latitude and Longitude of point 2 (in decimal degrees) ::: //::: unit = the unit you desire for results ::: //::: where: 'M' is statute miles (default) ::: //::: 'K' is kilometers ::: //::: 'N' is nautical miles ::: //::: ::: //::: Worldwide cities and other features databases with latitude longitude ::: //::: are available at https://www.geodatasource.com ::: //::: ::: //::: For enquiries, please contact [email protected] ::: //::: ::: //::: Official Web site: https://www.geodatasource.com ::: //::: ::: //::: GeoDataSource.com (C) All Rights Reserved 2018 ::: //::: ::: //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: function distance(lat1, lon1, lat2, lon2, unit) { if ((lat1 == lat2) && (lon1 == lon2)) { return 0; } else { var radlat1 = Math.PI * lat1/180; var radlat2 = Math.PI * lat2/180; var theta = lon1-lon2; var radtheta = Math.PI * theta/180; var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); if (dist > 1) { dist = 1; } dist = Math.acos(dist); dist = dist * 180/Math.PI; dist = dist * 60 * 1.1515; if (unit=="K") { dist = dist * 1.609344 } if (unit=="N") { dist = dist * 0.8684 } return dist; } }
Przykładowy kod jest objęty licencją LGPLv3.
źródło
Oblicz odległość między dwoma punktami w javascript
function distance(lat1, lon1, lat2, lon2, unit) { var radlat1 = Math.PI * lat1/180 var radlat2 = Math.PI * lat2/180 var theta = lon1-lon2 var radtheta = Math.PI * theta/180 var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta); dist = Math.acos(dist) dist = dist * 180/Math.PI dist = dist * 60 * 1.1515 if (unit=="K") { dist = dist * 1.609344 } if (unit=="N") { dist = dist * 0.8684 } return dist }
Aby uzyskać więcej informacji, zobacz: Link referencyjny
źródło
Napisałem funkcję do znajdowania odległości między dwoma współrzędnymi. Zwróci odległość w metrach.
function findDistance() { var R = 6371e3; // R is earth’s radius var lat1 = 23.18489670753479; // starting point lat var lat2 = 32.726601; // ending point lat var lon1 = 72.62524545192719; // starting point lon var lon2 = 74.857025; // ending point lon var lat1radians = toRadians(lat1); var lat2radians = toRadians(lat2); var latRadians = toRadians(lat2-lat1); var lonRadians = toRadians(lon2-lon1); var a = Math.sin(latRadians/2) * Math.sin(latRadians/2) + Math.cos(lat1radians) * Math.cos(lat2radians) * Math.sin(lonRadians/2) * Math.sin(lonRadians/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; console.log(d) } function toRadians(val){ var PI = 3.1415926535; return val / 180.0 * PI; }
źródło
Odległość po ortodromie - od długości cięciwy
Oto eleganckie rozwiązanie wykorzystujące wzorzec projektowania strategii; Mam nadzieję, że jest wystarczająco czytelny.
TwoPointsDistanceCalculatorStrategy.js :
module.exports = () => class TwoPointsDistanceCalculatorStrategy { constructor() {} calculateDistance({ point1Coordinates, point2Coordinates }) {} };
GreatCircleTwoPointsDistanceCalculatorStrategy.js:
module.exports = ({ TwoPointsDistanceCalculatorStrategy }) => class GreatCircleTwoPointsDistanceCalculatorStrategy extends TwoPointsDistanceCalculatorStrategy { constructor() { super(); } /** * Following the algorithm documented here: * https://en.wikipedia.org/wiki/Great-circle_distance#Computational_formulas * * @param {object} inputs * @param {array} inputs.point1Coordinates * @param {array} inputs.point2Coordinates * * @returns {decimal} distance in kelometers */ calculateDistance({ point1Coordinates, point2Coordinates }) { const convertDegreesToRadians = require('../convert-degrees-to-radians'); const EARTH_RADIUS = 6371; // in kelometers const [lat1 = 0, lon1 = 0] = point1Coordinates; const [lat2 = 0, lon2 = 0] = point2Coordinates; const radianLat1 = convertDegreesToRadians({ degrees: lat1 }); const radianLon1 = convertDegreesToRadians({ degrees: lon1 }); const radianLat2 = convertDegreesToRadians({ degrees: lat2 }); const radianLon2 = convertDegreesToRadians({ degrees: lon2 }); const centralAngle = _computeCentralAngle({ lat1: radianLat1, lon1: radianLon1, lat2: radianLat2, lon2: radianLon2, }); const distance = EARTH_RADIUS * centralAngle; return distance; } }; /** * * @param {object} inputs * @param {decimal} inputs.lat1 * @param {decimal} inputs.lon1 * @param {decimal} inputs.lat2 * @param {decimal} inputs.lon2 * * @returns {decimal} centralAngle */ function _computeCentralAngle({ lat1, lon1, lat2, lon2 }) { const chordLength = _computeChordLength({ lat1, lon1, lat2, lon2 }); const centralAngle = 2 * Math.asin(chordLength / 2); return centralAngle; } /** * * @param {object} inputs * @param {decimal} inputs.lat1 * @param {decimal} inputs.lon1 * @param {decimal} inputs.lat2 * @param {decimal} inputs.lon2 * * @returns {decimal} chordLength */ function _computeChordLength({ lat1, lon1, lat2, lon2 }) { const { sin, cos, pow, sqrt } = Math; const ΔX = cos(lat2) * cos(lon2) - cos(lat1) * cos(lon1); const ΔY = cos(lat2) * sin(lon2) - cos(lat1) * sin(lon1); const ΔZ = sin(lat2) - sin(lat1); const ΔXSquare = pow(ΔX, 2); const ΔYSquare = pow(ΔY, 2); const ΔZSquare = pow(ΔZ, 2); const chordLength = sqrt(ΔXSquare + ΔYSquare + ΔZSquare); return chordLength; }
konwersja-stopni na radian.js:
module.exports = function convertDegreesToRadians({ degrees }) { return degrees * Math.PI / 180; };
Jest to zgodne z odległością wielkiego koła - od długości cięciwy, udokumentowaną tutaj .
źródło
Dodanie tego dla użytkowników Node.JS. Możesz skorzystać z
haversine-distance
modułu, aby to zrobić, więc nie będziesz musiał samodzielnie wykonywać obliczeń. Więcej informacji można znaleźć na stronie npm .Żeby zainstalować:
Z modułu możesz korzystać w następujący sposób:
var haversine = require("haversine-distance"); //First point in your haversine calculation var point1 = { lat: 6.1754, lng: 106.8272 } //Second point in your haversine calculation var point2 = { lat: 6.1352, lng: 106.8133 } var haversine_m = haversine(point1, point2); //Results in meters (default) var haversine_km = haversine_m /1000; //Results in kilometers console.log("distance (in meters): " + haversine_m + "m"); console.log("distance (in kilometers): " + haversine_km + "km");
źródło
Odwiedź ten adres. https://www.movable-type.co.uk/scripts/latlong.html Możesz użyć tego kodu:
JavaScript: const R = 6371e3; // metres const φ1 = lat1 * Math.PI/180; // φ, λ in radians const φ2 = lat2 * Math.PI/180; const Δφ = (lat2-lat1) * Math.PI/180; const Δλ = (lon2-lon1) * Math.PI/180; const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) + Math.cos(φ1) * Math.cos(φ2) * Math.sin(Δλ/2) * Math.sin(Δλ/2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); const d = R * c; // in metres
źródło