Konvertieren Sie Breiten- und Längengrade in einen 2D-Punkt in Java

1. Übersicht

Bei der Implementierung von Anwendungen, die Karten verwenden, tritt normalerweise das Problem der Koordinatenkonvertierung auf. Meistens müssen wir Breiten- und Längengrade in einen 2D-Punkt konvertieren , um sie anzuzeigen . 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

Die Mercator-Projektion ist eine Kartenprojektion, die 1569 vom flämischen Kartographen Gerardus Mercator eingeführt wurde. Eine Kartenprojektion konvertiert Längen- und Breitengradkoordinaten auf der Erde in einen Punkt auf einer ebenen Fläche. Mit anderen Worten, es übersetzt einen Punkt auf der Erdoberfläche in einen Punkt auf einer flachen Karte .

Es gibt zwei Möglichkeiten, die Mercator-Projektion zu implementieren. Die Pseudo-Mercator-Projektion behandelt die Erde als Kugel. Die wahre Mercator-Projektion modelliert die Erde als 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 benötigen wir zwei Radien. Erstens ist der Hauptradius der Abstand vom Erdmittelpunkt zum Äquator . Zweitens ist der kleine Radius der Abstand vom Erdmittelpunkt zum Nord- und Südpol .

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 eine schnelle Abschätzung der genaueren, aber rechnerisch schwereren elliptischen Projektion. Infolgedessen sind die direkten Messungen der Entfernungen in dieser Projektion ungefähr.

Darüber hinaus ändern sich die Proportionen der Formen auf der Karte geringfügig. Infolgedessen bleiben Breitengrad und Formverhältnisse von Objekten auf der Karte wie Ländern, Seen, Flüssen usw. nicht genau erhalten .

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

Lassen Sie uns diesen Ansatz implementieren:

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 den Radius der Erde durch eine Konstante darstellt und nicht durch zwei, wie er wirklich ist. Zweitens können wir sehen, dass wir zwei Funktionen implementiert haben, die für die Konvertierung in x-Achsenprojektion und y-Achsenprojektion verwendet werden . In der obigen Klasse haben wir die von Java bereitgestellte Mathematikbibliothek 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 erwähnenswert, dass diese Projektion Punkte in einen Begrenzungsrahmen (links, unten, rechts, oben) von (-20037508.34, -23810769.32, 20037508.34, 23810769.32) abbildet.

2 .2. Elliptische Mercator-Projektion

Die wahre Projektion modelliert die Erde als Ellipsoid. Diese Projektion liefert genaue Verhältnisse für Objekte überall auf der Erde . Natürlich werden Objekte auf der Karte respektiert, aber nicht 100% genau . Dieser Ansatz wird jedoch nicht am häufigsten verwendet, da er rechenintensiv ist.

Lassen Sie uns diesen Ansatz implementieren:

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 die y-Achse ist. Dies liegt daran, dass die unrunde Erdform berücksichtigt werden sollte. Obwohl der wahre Mercator-Ansatz komplex erscheint, ist er genauer als der sphärische Ansatz, da er den Radius für die Darstellung der Erde in einem Moll und einem Dur verwendet.

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 . Fazit

Wenn wir Längen- und Breitengradkoordinaten in 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 Artikels auf GitHub.