Konverter Latitude og Longitude til et 2D-punkt i Java
1. Oversigt
Når vi implementerer applikationer, der bruger kort, løber vi typisk ind i problemet med koordinatkonvertering. Det meste af tiden er vi nødt til det konvertere breddegrad og længdegrad til et 2D-punkt, der skal vises. Heldigvis, for at løse dette problem, kan vi bruge formlerne til Mercator-projektionen.
I denne vejledning dækker vi Mercator Projection og lærer at implementere de to varianter.
2. Mercator-projektion
Mercator-projektionen er en kortprojektion, der blev introduceret af den flamske kartograf Gerardus Mercator i 1569. En kort projektion konverterer bredde- og længdegradskoordinater på Jorden til et punkt på en plan overflade. Med andre ord, det oversætter et punkt på jordens overflade til et punkt på et fladt kort.
Der er to måder at implementere Mercator-projektionen på. Den pseudo Mercator-projektion behandler Jorden som en sfære. Den sande Mercator-projektion modellerer Jorden som en ellipsoid. Vi implementerer begge versioner.
Lad os starte med en basisklasse til begge implementeringer af Mercator-projektion:
abstrakt klasse Mercator {endelig statisk dobbelt RADIUS_MAJOR = 6378137.0; endelig statisk dobbelt RADIUS_MINOR = 6356752.3142; abstrakt dobbelt yAxisProjection (dobbelt input); abstrakt dobbelt xAxisProjection (dobbelt input); }
Denne klasse giver også jordens store og mindre radius målt i meter. Det er velkendt, at Jorden ikke ligefrem er en sfære. Af den grund har vi brug for to radier. For det første hovedradius er afstanden fra centrum af jorden til ækvator. For det andet, den mindre radius er afstanden fra jordens centrum til nord- og sydpolen.
2.1. Sfærisk Mercator-projektion
Pseudoprojektionsmodellen behandler jorden som en sfære. I modsætning til den elliptiske projektion, hvor Jorden ville blive projiceret på en mere nøjagtig form. Denne tilgang giver os en hurtig estimering til den mere præcise, men beregningsmæssige tungere elliptiske projektion. Som et resultat af det er det direkte målinger af afstande i denne projektion vil være omtrentlige.
Desuden vil proportionerne af figurerne på kortet ændre sig marginalt. Som et resultat af denne breddegrad og forholdet mellem former for objekter på kortet som lande, søer, floder osv. Ikke er nøjagtigt bevaret.
Dette kaldes også Web Mercator-projektion - ofte brugt i webapplikationer inklusive Google Maps.
Lad os implementere denne tilgang:
offentlig klasse SphericalMercator udvider Mercator {@Override dobbelt xAxisProjection (dobbelt input) {returner Math.toRadians (input) * RADIUS_MAJOR; } @ Override dobbelt yAxisProjection (dobbelt input) {returner Math.log (Math.tan (Math.PI / 4 + Math.toRadians (input) / 2)) * RADIUS_MAJOR; }}
Den første ting at bemærke om denne tilgang er det faktum, at denne tilgang repræsenterer radius af jorden ved en konstant og ikke to som det virkelig er. For det andet kan vi se, at vi har implementeret to funktioner, der skal bruges til konvertering til x-akse projektion og y-akse projektion. I klassen ovenfor har vi brugt Matematik bibliotek leveret af java for at hjælpe os med at gøre vores kode enklere.
Lad os teste en simpel konvertering:
Assert.assertEquals (2449028.7974520186, sfæriskMercator.xAxisProjection (22)); Assert.assertEquals (5465442.183322753, sfæriskMercator.yAxisProjection (44));
Det er værd at bemærke, at denne projektion kortlægger punkter i et afgrænsningsfelt (venstre, nederst, højre, øverst) på (-20037508.34, -23810769.32, 20037508.34, 23810769.32).
2.2. Elliptisk Mercator-projektion
Den sande projektion modellerer jorden som en ellipsoid. Denne fremskrivning givernøjagtige forholdtil genstande overalt på Jorden. Sikkert, det respekterer objekter på kortet, menikke 100% nøjagtig. Denne fremgangsmåde er dog ikke den hyppigst anvendte, fordi den er kompleks beregningsmæssigt.
Lad os implementere denne tilgang:
klasse EllipticalMercator udvider Mercator {@Override dobbelt yAxisProjection (dobbelt input) {input = Math.min (Math.max (input, -89.5), 89.5); dobbelt earthDimensionalRateNormalized = 1.0 - Math.pow (RADIUS_MINOR / RADIUS_MAJOR, 2); dobbelt inputOnEarthProj = Math.sqrt (earthDimensionalRateNormalized) * Math.sin (Math.toRadians (input)); inputOnEarthProj = Math.pow (((1.0 - inputOnEarthProj) / (1.0 + inputOnEarthProj)), 0.5 * Math.sqrt (earthDimensionalRateNormalized)); dobbelt inputOnEarthProjNormalized = Math.tan (0,5 * ((Math.PI * 0,5) - Math.toRadians (input))) / inputOnEarthProj; returnere (-1) * RADIUS_MAJOR * Math.log (inputOnEarthProjNormalized); } @ Override dobbelt xAxisProjection (dobbelt input) {return RADIUS_MAJOR * Math.toRadians (input); }}
Ovenfor kan vi se, hvor kompleks denne tilgang er med hensyn til projektionen på y-aksen. Dette skyldes, at det skal tage hensyn til den ikke-runde jordform. Selvom den ægte Mercator-tilgang virker kompleks, er den mere nøjagtig end den sfæriske tilgang, da den bruger radius til at repræsentere jorden en mindre og en stor.
Lad os teste en simpel konvertering:
Assert.assertEquals (2449028.7974520186, elliptiskMercator.xAxisProjection (22)); Assert.assertEquals (5435749.887511954, elliptiskMercator.yAxisProjection (44));
Denne projektion kortlægger punkter i en afgrænsningsboks med (-20037508.34, -34619289.37, 20037508.34, 34619289.37).
3. Konklusion
Hvis vi har brug for at konvertere bredde- og længdegradskoordinater til en 2D-overflade, kan vi bruge Mercator-projektionen. Afhængigt af den nøjagtighed, vi har brug for til vores implementering, kan vi bruge den sfæriske eller elliptiske tilgang.
Som altid kan vi finde koden til denne artikel på GitHub.