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

StackOverflow https://stackoverflow.com/questions/120283

Pregunta

Estoy deseando encontrar la distancia entre dos puntos diferentes.Yo sé que esto se puede lograr con la gran círculo de distancia.http://www.meridianworlddata.com/Distance-calculation.asp

Una vez hecho esto, con un punto de distancia y me gustaría encontrar el punto de que la distancia al norte, y que la distancia al este con el fin de crear un cuadro alrededor del punto.

¿Fue útil?

Solución

Hemos tenido éxito en el uso OpenMap para trazar un montón de los datos de posición.Hay un LatLonPoint la clase que tiene algunas funciones básicas, como la distancia.

Otros consejos

Aquí es una implementación Java de Haversine la leche de fórmula.Yo uso esto 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;
    }

O usted podría utilizar SimpleLatLng.Con licencia Apache 2.0 y se utiliza en un sistema de producción, que yo sepa:de la mina.

Cuento corto:

Yo estaba buscando una simple geo de la biblioteca y no pude encontrar uno que se adapte a mis necesidades.Y el que quiera escribir y probar y depurar estas pequeñas herramientas de geo, una y otra vez en todas las aplicaciones?Tiene que haber una manera mejor!

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

Sé que estoy a dos años es demasiado tarde para ayudar a que el cartel original, pero mi objetivo es ayudar a la gente como yo que veo esta pregunta en una búsqueda.Me encantaría tener algunas personas lo utilizan y contribuyen a la prueba y la visión de este pequeño ligero de utilidad.

Para una información más precisa de la distancia (0,5 mm) también puede utilizar el Vincenty aproximación:

/**
 * 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 fue libremente adaptado de http://www.movable-type.co.uk/scripts/latlong-vincenty.html

Corregido Haversine fórmula de la Distancia....

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;
}   

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);
    }

Usted puede utilizar el Java Geodesia la Biblioteca para GPS, utiliza el Vincenty de fórmulas que tiene en cuenta la superficie terrestre de la curvatura.

La aplicación va como esto:

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();

El resultado de la distancia en metros.

Sé que hay muchas respuestas, pero haciendo algunas investigaciones sobre este tema, he encontrado que la mayoría de las respuestas aquí el uso de la fórmula de Haversine, pero la Vincenty fórmula es en realidad más precisa.Hubo un post que adapta el cálculo de una versión de Javascript, pero es muy difícil de manejar.He encontrado una versión que es superior porque:

  1. También cuenta con una licencia abierta.
  2. Utiliza los principios de la programación orientada a objetos.
  3. Tiene mayor flexibilidad para elegir el elipsoide que desea utilizar.
  4. Tiene más métodos para permitir diferentes cálculos en el futuro.
  5. Está bien documentado.

VincentyDistanceCalculator

Este método podría ayudar a encontrar la distancia entre la ubicación geográfica en el 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;
}

Yo normalmente uso de MATLAB con el Asignación De Caja De Herramientas, y , a continuación, utilice el código en mi Java utilizando MATLAB Builder JA. Esto hace mi vida mucho más fácil.Dado que la mayoría de las escuelas tienen para el libre acceso de los estudiantes, usted puede probarlo (o conseguir la versión de prueba de obtener más de su trabajo).

Para Android, hay un método sencillo.

 public static float getDistanceInMeter(LatLng start, LatLng end) { 
    float[] results = new float[1];
    Location.distanceBetween(start.latitude, start.longitude, end.latitude, end.longitude, results);
    return results[0];

}

;

https://developer.android.com/reference/android/location/Location#distanceBetween(lat1,lng1,lat2,lng2,output[])

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top