Converteer lengte- en breedtegraad naar een 2D-punt in Java

1. Overzicht

Bij het implementeren van applicaties die kaarten gebruiken, zullen we meestal het probleem van coördinatenconversie tegenkomen. Meestal is dat nodig converteer de lengte- en breedtegraad naar een 2D-punt om weer te geven. Gelukkig kunnen we om dit probleem op te lossen de formules van de Mercator-projectie gebruiken.

In deze tutorial behandelen we de Mercator-projectie en leren we hoe we de twee varianten ervan kunnen implementeren.

2. Mercator-projectie

De Mercatorprojectie is een kaartprojectie geïntroduceerd door de Vlaamse cartograaf Gerardus Mercator in 1569. Een kaartprojectie converteert de lengte- en breedtegraadcoördinaten op de aarde naar een punt op een plat oppervlak. Met andere woorden, het vertaalt een punt op het aardoppervlak naar een punt op een platte kaart.

Er zijn twee manieren om de Mercator-projectie te implementeren. De pseudo-Mercator-projectie behandelt de aarde als een bol. De echte Mercator-projectie modelleert de aarde als een ellipsoïde. We zullen beide versies implementeren.

Laten we beginnen met een basisklasse voor beide Mercator-projectie-implementaties:

abstracte klasse Mercator {laatste statische dubbele RADIUS_MAJOR = 6378137.0; laatste statische dubbele RADIUS_MINOR = 6356752.3142; abstracte dubbele yAxisProjection (dubbele invoer); abstracte dubbele xAxisProjection (dubbele invoer); }

Deze klasse geeft ook de grote en de kleine straal van de aarde, gemeten in meters. Het is bekend dat de aarde niet bepaald een bol is. Om die reden hebben we twee radiussen nodig. Ten eerste de grote straal is de afstand van het middelpunt van de aarde tot de evenaar. Ten tweede, de kleine straal is de afstand van het middelpunt van de aarde tot de noord- en zuidpool.

2.1. Sferische Mercator-projectie

Het pseudo-projectiemodel behandelt de aarde als een bol. In tegenstelling tot de elliptische projectie waarbij de aarde op een nauwkeurigere vorm zou worden geprojecteerd. Deze aanpak stelt ons in staat een snelle schatting naar de meer nauwkeurige, maar computationele zwaardere elliptische projectie. Als gevolg daarvan, het directe metingen van afstanden in deze projectie zal bij benadering zijn.

Bovendien zullen de verhoudingen van de vormen op de kaart marginaal veranderen. Als gevolg hiervan zijn de breedtegraad en verhoudingen van vormen van objecten op de kaart zoals landen, meren, rivieren, enz. Dat niet precies bewaard gebleven.

Dit wordt ook wel de Web Mercator-projectie genoemd - vaak gebruikt in webapplicaties, waaronder Google Maps.

Laten we deze aanpak implementeren:

openbare klasse SphericalMercator breidt Mercator uit {@Override dubbele xAxisProjection (dubbele invoer) {retourneer Math.toRadians (invoer) * RADIUS_MAJOR; } @Override dubbele yAxisProjection (dubbele invoer) {return Math.log (Math.tan (Math.PI / 4 + Math.toRadians (invoer) / 2)) * RADIUS_MAJOR; }}

Het eerste dat bij deze benadering moet worden opgemerkt, is het feit dat deze benadering de straal van de aarde door een constante en niet twee zoals het werkelijk is. Ten tweede kunnen we zien dat we twee functies hebben geïmplementeerd om te gebruiken voor het converteren naar x-as projectie en projectie op de y-as. In de bovenstaande klas hebben we gebruikt Wiskunde bibliotheek geleverd door java om ons te helpen onze code eenvoudiger te maken.

Laten we een eenvoudige conversie testen:

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

Het is vermeldenswaard dat deze projectie punten toewijst in een begrenzingsvak (links, onder, rechts, boven) van (-20037508.34, -23810769.32, 20037508.34, 23810769.32).

2.2. Elliptische Mercator-projectie

De echte projectie modelleert de aarde als een ellipsoïde. Deze projectie geeftnauwkeurige verhoudingenvoor objecten overal op aarde. Zeker, het respecteert objecten op de kaart maarniet 100% nauwkeurig. Deze benadering wordt echter niet het meest gebruikt omdat deze rekenkundig complex is.

Laten we deze aanpak implementeren:

klasse EllipticalMercator breidt Mercator uit {@Override double yAxisProjection (dubbele invoer) {input = Math.min (Math.max (input, -89.5), 89.5); dubbele aardeDimensionalRateNormalized = 1.0 - Math.pow (RADIUS_MINOR / RADIUS_MAJOR, 2); dubbele inputOnEarthProj = Math.sqrt (earthDimensionalRateNormalized) * Math.sin (Math.toRadians (invoer)); inputOnEarthProj = Math.pow (((1.0 - inputOnEarthProj) / (1.0 + inputOnEarthProj)), 0.5 * Math.sqrt (earthDimensionalRateNormalized)); dubbele inputOnEarthProjNormalized = Math.tan (0.5 * ((Math.PI * 0.5) - Math.toRadians (input))) / inputOnEarthProj; return (-1) * RADIUS_MAJOR * Math.log (inputOnEarthProjNormalized); } @Override dubbele xAxisProjection (dubbele invoer) {retourneer RADIUS_MAJOR * Math.toRadians (invoer); }}

Hierboven kunnen we zien hoe complex deze benadering is met betrekking tot de projectie op de y-as. Dit komt omdat er rekening moet worden gehouden met de niet-ronde aardvorm. Hoewel de echte Mercator-benadering complex lijkt, is deze nauwkeuriger dan de sferische benadering, aangezien deze de straal gebruikt om de aarde een kleine en een grote weer te geven.

Laten we een eenvoudige conversie testen:

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

Deze projectie zal punten toewijzen aan een begrenzingskader van (-20037508.34, -34619289.37, 20037508.34, 34619289.37).

3. Conclusie

Als we de lengte- en breedtegraadcoördinaten moeten converteren naar een 2D-oppervlak, kunnen we de Mercator-projectie gebruiken. Afhankelijk van de nauwkeurigheid die we nodig hebben voor onze implementatie, kunnen we de bolvormige of elliptische benadering gebruiken.

Zoals altijd kunnen we de code van dit artikel vinden op GitHub.