Latitude und Longitude in einen 2D-Punkt in Java konvertieren

Konvertieren Sie Breite und Länge in einen 2D-Punkt in Java

 

1. Überblick

Bei der Implementierung von Anwendungen, die Karten verwenden, tritt normalerweise das Problem der Koordinatenkonvertierung auf. Meistens brauchen wirconvert latitude and longitude to a 2D point to display. Glücklicherweise können wir zur Lösung dieses Problems die Formeln der Mercator-Projektion verwenden.

In diesem Tutorial werden wir die Mercator-Projektion behandeln und lernen, wie die beiden Varianten implementiert werden.

2. Mercator-Projektion

Mercator projection ist eine Kartenprojektion, die der flämische Kartograf Gerardus Mercator 1569 eingeführt hat. Eine Kartenprojektion konvertiert Breiten- und Längengradkoordinaten auf der Erde in einen Punkt auf einer ebenen Fläche. Mit anderen Worten,it translates a point on the surface of the earth to a point on a flat map.

Es gibt zwei Möglichkeiten, die Mercator-Projektion zu implementieren. The pseudo Mercator projection treats the Earth as a sphere. The true Mercator projection models the Earth as an ellipsoid. Wir werden beide Versionen implementieren.

Beginnen wir mit einer Basisklasse für beide Mercator-Projektionsimplementierungen:

abstract class Mercator {
    final static double RADIUS_MAJOR = 6378137.0;
    final static double RADIUS_MINOR = 6356752.3142;

    abstract double yAxisProjection(double input);
    abstract double xAxisProjection(double input);
}

Diese Klasse liefert auch den Haupt- und den Nebenradius der Erde, gemessen in Metern. Es ist bekannt, dass die Erde nicht gerade eine Kugel ist. Aus diesem Grund brauchen wir zwei Radien. Erstens diemajor radius is the distance from the center of the earth to the equator. Zweitens sind dieminor radius is the distance from the center of the earth to the north and south poles.

2.1. Sphärische Mercator-Projektion

Das Pseudoprojektionsmodell behandelt die Erde als Kugel. Im Gegensatz zur elliptischen Projektion, bei der die Erde auf eine genauere Form projiziert würde. Dieser Ansatz ermöglicht uns einquick estimation für die genauere, aber rechnerisch schwerere elliptische Projektion. Infolgedessen sind die direktenmeasurements of distances in dieser Projektion ungefähr.

Darüber hinaus ändern sich die Proportionen der Formen auf der Karte geringfügig. Infolge dieses Breitengrads und des Formverhältnisses von Objekten auf der Karte wie Ländern, Seen, Flüssen usw. sind nichtprecisely preserved.

Dies wird auch alsWeb Mercator-Projektion bezeichnet - häufig in Webanwendungen wie Google Maps verwendet.

Implementieren wir diesen Ansatz:

public class SphericalMercator extends Mercator {

    @Override
    double xAxisProjection(double input) {
        return Math.toRadians(input) * RADIUS_MAJOR;
    }

    @Override
    double yAxisProjection(double input) {
        return Math.log(Math.tan(Math.PI / 4 + Math.toRadians(input) / 2)) * RADIUS_MAJOR;
    }
}

Das erste, was bei diesem Ansatz zu beachten ist, ist die Tatsache, dass dieser Ansatz dieradius der Erde durchone constant darstellt und nicht zwei, wie es wirklich ist. Zweitens können wir sehen, dass wir zwei Funktionen implementiert haben, die für die Konvertierung inx-axis projection undy-axis projection verwendet werden. In der obigen Klasse haben wir die von Java bereitgestellteMath-Bibliothek verwendet, um unseren Code einfacher zu gestalten.

Testen wir eine einfache Konvertierung:

Assert.assertEquals(2449028.7974520186, sphericalMercator.xAxisProjection(22));
Assert.assertEquals(5465442.183322753, sphericalMercator.yAxisProjection(44));

Es ist zu beachten, dass diese Projektion Punkte in einen Begrenzungsrahmen (links, unten, rechts, oben) von (-20037508.34, -23810769.32, 20037508.34, 23810769.32) abbildet.

2.2. Elliptical Mercator Projection

Die wahre Projektion modelliert die Erde als Ellipsoid. This projection givesaccurate ratiosfor objects anywhere on Earth. Sicherlichit respects objects on the map butnot 100% accurate. Dieser Ansatz wird jedoch nicht am häufigsten verwendet, da er rechenintensiv ist.

Implementieren wir diesen Ansatz:

class EllipticalMercator extends Mercator {
    @Override
    double yAxisProjection(double input) {

        input = Math.min(Math.max(input, -89.5), 89.5);
        double earthDimensionalRateNormalized = 1.0 - Math.pow(RADIUS_MINOR / RADIUS_MAJOR, 2);

        double inputOnEarthProj = Math.sqrt(earthDimensionalRateNormalized) *
          Math.sin( Math.toRadians(input));

        inputOnEarthProj = Math.pow(((1.0 - inputOnEarthProj) / (1.0+inputOnEarthProj)),
          0.5 * Math.sqrt(earthDimensionalRateNormalized));

        double inputOnEarthProjNormalized =
          Math.tan(0.5 * ((Math.PI * 0.5) - Math.toRadians(input))) / inputOnEarthProj;

        return (-1) * RADIUS_MAJOR * Math.log(inputOnEarthProjNormalized);
    }

    @Override
    double xAxisProjection(double input) {
        return RADIUS_MAJOR * Math.toRadians(input);
    }
}

Oben sehen wir, wie komplex dieser Ansatz in Bezug auf die Projektion auf der y-Achse ist. Dies liegt daran, dass die unrunde Erdform berücksichtigt werden sollte. Obwohl der wahre Mercator-Ansatz komplex zu sein scheint, ist er genauer als der sphärische Ansatz, der verwendet wird, um die Erde in einem kleinen und einem großen Radius darzustellen.

Testen wir eine einfache Konvertierung:

Assert.assertEquals(2449028.7974520186, ellipticalMercator.xAxisProjection(22));
Assert.assertEquals(5435749.887511954, ellipticalMercator.yAxisProjection(44));

Diese Projektion ordnet Punkte einem Begrenzungsrahmen von (-20037508.34, -34619289.37, 20037508.34, 34619289.37) zu.

3. Conclusion

Wenn wir Breiten- und Längengradkoordinaten auf eine 2D-Oberfläche konvertieren müssen, können wir die Mercator-Projektion verwenden. Abhängig von der Genauigkeit, die wir für unsere Implementierung benötigen, können wir den sphärischen oder elliptischen Ansatz verwenden.

Wie immer finden wir den Code dieses Artikelsover on GitHub.