tierra terrestres que puntos mar longitud latitud geograficos entre distancia coordenadas construya con comparar calcule calcular algoritmo java geocoding latitude-longitude

terrestres - ¿Cómo puedo medir la distancia y crear un cuadro delimitador basado en dos puntos de latitud+longitud en Java?



distancia entre dos puntos geograficos (10)

Estoy queriendo encontrar la distancia entre dos puntos diferentes. Esto sé que se puede lograr con la gran distancia circular. http://www.meridianworlddata.com/Distance-calculation.asp

Una vez hecho, con un punto y una distancia me gustaría encontrar el punto que distancia al norte, y esa distancia hacia el este para crear una caja alrededor del punto.


Aquí hay una implementación Java de la fórmula Haversine . Lo uso en un proyecto para calcular la distancia en millas entre lat / longs.

public static double distFrom(double lat1, double lng1, double lat2, double lng2) { double earthRadius = 3958.75; // miles (or 6371.0 kilometers) double dLat = Math.toRadians(lat2-lat1); double dLng = Math.toRadians(lng2-lng1); double sindLat = Math.sin(dLat / 2); double sindLng = Math.sin(dLng / 2); double a = Math.pow(sindLat, 2) + Math.pow(sindLng, 2) * Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); double dist = earthRadius * c; return dist; }


Este método te ayudaría a encontrar la distancia entre la ubicación geográfica en km.

private double getDist(double lat1, double lon1, double lat2, double lon2) { int R = 6373; // radius of the earth in kilometres double lat1rad = Math.toRadians(lat1); double lat2rad = Math.toRadians(lat2); double deltaLat = Math.toRadians(lat2-lat1); double deltaLon = Math.toRadians(lon2-lon1); double a = Math.sin(deltaLat/2) * Math.sin(deltaLat/2) + Math.cos(lat1rad) * Math.cos(lat2rad) * Math.sin(deltaLon/2) * Math.sin(deltaLon/2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); double d = R * c; return d; }


Fórmula de Haversine Distance corregida ...

public static double HaverSineDistance(double lat1, double lng1, double lat2, double lng2) { // mHager 08-12-2012 // http://en.wikipedia.org/wiki/Haversine_formula // Implementation // convert to radians lat1 = Math.toRadians(lat1); lng1 = Math.toRadians(lng1); lat2 = Math.toRadians(lat2); lng2 = Math.toRadians(lng2); double dlon = lng2 - lng1; double dlat = lat2 - lat1; double a = Math.pow((Math.sin(dlat/2)),2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon/2),2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); return EARTH_RADIUS * c; }


Hemos tenido cierto éxito utilizando OpenMap para trazar una gran cantidad de datos posicionales. Hay una clase LatLonPoint que tiene algunas funciones básicas, incluida la distancia.


Normalmente uso MATLAB con Mapping Toolbox , y luego uso el código en mi Java usando MATLAB Builder JA. Hace mi vida mucho más simple. Dado que la mayoría de las escuelas lo tienen para el acceso gratuito de los estudiantes, puedes probarlo (u obtener la versión de prueba para superar tu trabajo).


O podrías usar SimpleLatLng . Apache 2.0 con licencia y utilizado en un sistema de producción que conozco: el mío.

Cuento:

Estaba buscando una biblioteca geo simple y no pude encontrar una que se ajuste a mis necesidades. ¿Y quién quiere escribir y probar y depurar estas pequeñas herramientas geo una y otra vez en cada aplicación? ¡Tiene que haber una mejor manera!

Así que SimpleLatLng nació como una forma de almacenar datos de latitud y longitud, hacer cálculos de distancia y crear límites en forma.

Sé que tengo dos años de retraso para ayudar al póster original, pero mi objetivo es ayudar a las personas como yo que encuentran esta pregunta en una búsqueda. Me encantaría que algunas personas lo usen y contribuyan a las pruebas y la visión de esta pequeña utilidad liviana.


Para una distancia más precisa (0.5mm) también puede usar la aproximación de Vincenty:

/** * Calculates geodetic distance between two points specified by latitude/longitude using Vincenty inverse formula * for ellipsoids * * @param lat1 * first point latitude in decimal degrees * @param lon1 * first point longitude in decimal degrees * @param lat2 * second point latitude in decimal degrees * @param lon2 * second point longitude in decimal degrees * @returns distance in meters between points with 5.10<sup>-4</sup> precision * @see <a href="http://www.movable-type.co.uk/scripts/latlong-vincenty.html">Originally posted here</a> */ public static double distVincenty(double lat1, double lon1, double lat2, double lon2) { double a = 6378137, b = 6356752.314245, f = 1 / 298.257223563; // WGS-84 ellipsoid params double L = Math.toRadians(lon2 - lon1); double U1 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat1))); double U2 = Math.atan((1 - f) * Math.tan(Math.toRadians(lat2))); double sinU1 = Math.sin(U1), cosU1 = Math.cos(U1); double sinU2 = Math.sin(U2), cosU2 = Math.cos(U2); double sinLambda, cosLambda, sinSigma, cosSigma, sigma, sinAlpha, cosSqAlpha, cos2SigmaM; double lambda = L, lambdaP, iterLimit = 100; do { sinLambda = Math.sin(lambda); cosLambda = Math.cos(lambda); sinSigma = Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (sinSigma == 0) return 0; // co-incident points cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = Math.atan2(sinSigma, cosSigma); sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; cosSqAlpha = 1 - sinAlpha * sinAlpha; cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha; if (Double.isNaN(cos2SigmaM)) cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6) double C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } while (Math.abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0); if (iterLimit == 0) return Double.NaN; // formula failed to converge double uSq = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); double dist = b * A * (sigma - deltaSigma); return dist; }

Este código se adaptó libremente de http://www.movable-type.co.uk/scripts/latlong-vincenty.html


Puede usar la Biblioteca de Geodesia de Java para GPS , utiliza las fórmulas de Vincenty que tiene en cuenta la curvatura de la superficie de la tierra.

La implementación es así:

import org.gavaghan.geodesy.*; ... GeodeticCalculator geoCalc = new GeodeticCalculator(); Ellipsoid reference = Ellipsoid.WGS84; GlobalPosition pointA = new GlobalPosition(latitude, longitude, 0.0); GlobalPosition userPos = new GlobalPosition(userLat, userLon, 0.0); double distance = geoCalc.calculateGeodeticCurve(reference, userPos, pointA).getEllipsoidalDistance();

La distancia resultante está en metros.


Sé que hay muchas respuestas, pero al hacer algunas investigaciones sobre este tema, descubrí que la mayoría de las respuestas aquí usan la fórmula de Haversine, pero la fórmula de Vincenty es en realidad más precisa. Hubo una publicación que adaptó el cálculo de una versión de Javascript, pero es muy difícil de manejar. Encontré una versión que es superior porque:

  1. También tiene una licencia abierta.
  2. Utiliza principios de OOP.
  3. Tiene una mayor flexibilidad para elegir el elipsoide que desea usar.
  4. Tiene más métodos para permitir diferentes cálculos en el futuro.
  5. Está bien documentado.

VincentyDistanceCalculator


http://www.movable-type.co.uk/scripts/latlong.html

public static Double distanceBetweenTwoLocationsInKm(Double latitudeOne, Double longitudeOne, Double latitudeTwo, Double longitudeTwo) { if (latitudeOne == null || latitudeTwo == null || longitudeOne == null || longitudeTwo == null) { return null; } Double earthRadius = 6371.0; Double diffBetweenLatitudeRadians = Math.toRadians(latitudeTwo - latitudeOne); Double diffBetweenLongitudeRadians = Math.toRadians(longitudeTwo - longitudeOne); Double latitudeOneInRadians = Math.toRadians(latitudeOne); Double latitudeTwoInRadians = Math.toRadians(latitudeTwo); Double a = Math.sin(diffBetweenLatitudeRadians / 2) * Math.sin(diffBetweenLatitudeRadians / 2) + Math.cos(latitudeOneInRadians) * Math.cos(latitudeTwoInRadians) * Math.sin(diffBetweenLongitudeRadians / 2) * Math.sin(diffBetweenLongitudeRadians / 2); Double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); return (earthRadius * c); }