Konverter bredde og lengdegrad til et 2D-punkt i Java

1. Oversikt

Når vi implementerer applikasjoner som bruker kart, vil vi vanligvis støte på problemet med koordinatkonvertering. Det meste av tiden må vi konverter breddegrad og lengdegrad til et 2D-punkt som skal vises. Heldigvis, for å løse dette problemet, kan vi bruke formlene til Mercator-projeksjonen.

I denne veiledningen vil vi dekke Mercator Projection og lære hvordan du implementerer de to variantene.

2. Mercator-projeksjon

Mercator-projeksjonen er en kartprojeksjon introdusert av den flamske kartografen Gerardus Mercator i 1569. En kartprojeksjon konverterer bredde- og lengdegradskoordinater på jorden til et punkt på en flat overflate. Med andre ord, det oversetter et punkt på jordens overflate til et punkt på et flatt kart.

Det er to måter å implementere Mercator-projeksjonen på. Den pseudo Mercator-projeksjonen behandler jorden som en kule. Den sanne Mercator-projeksjonen modellerer jorden som en ellipsoid. Vi vil implementere begge versjonene.

La oss starte med en basisklasse for begge Mercator-projeksjonsimplementeringer:

abstrakt klasse Mercator {endelig statisk dobbel RADIUS_MAJOR = 6378137.0; endelig statisk dobbel RADIUS_MINOR = 6356752.3142; abstrakt dobbel yAxisProjection (dobbel inngang); abstrakt dobbel xAxisProjection (dobbel inngang); }

Denne klassen gir også hoved- og mindre radius av jorden målt i meter. Det er velkjent at jorden ikke akkurat er en sfære. Av den grunn trenger vi to radier. For det første, den hovedradius er avstanden fra jordens sentrum til ekvator. For det andre, den mindre radius er avstanden fra sentrum av jorden til nord- og sørpolen.

2.1. Sfærisk Mercator-projeksjon

Pseudoprojeksjonsmodellen behandler jorden som en kule. I motsetning til den elliptiske projeksjonen der jorden ville bli projisert på en mer nøyaktig form. Denne tilnærmingen gir oss en rask estimering til den mer presise, men beregningsmessige tyngre elliptiske projeksjonen. Som et resultat av det, direkte målinger av avstander i denne projeksjonen vil være omtrentlig.

Videre vil proporsjonene til figurene på kartet endre seg marginalt. Som et resultat av at breddegrad og forhold mellom former for objekter på kartet som land, innsjøer, elver, etc. ikke er presist bevart.

Dette kalles også Web Mercator-projeksjonen - ofte brukt i webapplikasjoner, inkludert Google Maps.

La oss implementere denne tilnærmingen:

offentlig klasse SphericalMercator utvider Mercator {@Override doble xAxisProjection (dobbel inngang) {return Math.toRadians (input) * RADIUS_MAJOR; } @Override dobbelt yAxisProjection (dobbel inngang) {return Math.log (Math.tan (Math.PI / 4 + Math.toRadians (input) / 2)) * RADIUS_MAJOR; }}

Det første du må merke deg om denne tilnærmingen er det faktum at denne tilnærmingen representerer radius av jorden ved en konstant og ikke to som det egentlig er. For det andre kan vi se at vi har implementert to funksjoner å bruke for å konvertere til x-akse projeksjon og projeksjon av y-aksen. I klassen ovenfor har vi brukt Matte biblioteket levert av java for å hjelpe oss med å gjøre koden vår enklere.

La oss teste en enkel konvertering:

Assert.assertEquals (2449028.7974520186, sfæriskMercator.xAxisProjection (22)); Assert.assertEquals (5465442.183322753, sfæriskMercator.yAxisProjection (44));

Det er verdt å merke seg at denne projeksjonen vil kartlegge punkter i en avgrensningsboks (venstre, nederst, høyre, topp) av (-20037508.34, -23810769.32, 20037508.34, 23810769.32).

2.2. Elliptisk Mercator-projeksjon

Den sanne projeksjonen modellerer jorden som en ellipsoid. Denne projeksjonen girnøyaktige forholdfor gjenstander hvor som helst på jorden. Sikkert, den respekterer objekter på kartet menikke 100% nøyaktig. Imidlertid er denne tilnærmingen ikke den mest brukte fordi den er beregningsmessig kompleks.

La oss implementere denne tilnærmingen:

klasse EllipticalMercator utvider Mercator {@Override dobbelt yAxisProjection (dobbel inngang) {input = Math.min (Math.max (input, -89.5), 89.5); dobbel earthDimensionalRateNormalized = 1.0 - Math.pow (RADIUS_MINOR / RADIUS_MAJOR, 2); dobbel inputOnEarthProj = Math.sqrt (earthDimensionalRateNormalized) * Math.sin (Math.toRadians (input)); inputOnEarthProj = Math.pow (((1.0 - inputOnEarthProj) / (1.0 + inputOnEarthProj)), 0.5 * Math.sqrt (earthDimensionalRateNormalized)); dobbel inputOnEarthProjNormalized = Math.tan (0,5 * ((Math.PI * 0,5) - Math.toRadians (input))) / inputOnEarthProj; retur (-1) * RADIUS_MAJOR * Math.log (inputOnEarthProjNormalized); } @ Override dobbelt xAxisProjection (dobbel inngang) {retur RADIUS_MAJOR * Math.toRadians (input); }}

Ovenfor kan vi se hvor kompleks denne tilnærmingen er angående projeksjonen på y-aksen. Dette er fordi det bør ta hensyn til den ikke-runde jordformen. Selv om den virkelige Mercator-tilnærmingen virker kompleks, er den mer nøyaktig enn den sfæriske tilnærmingen, da den bruker radius for å representere jorden en mindre og en major.

La oss teste en enkel konvertering:

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

Denne projeksjonen vil kartlegge punkter i en avgrensningsboks med (-20037508.34, -34619289.37, 20037508.34, 34619289.37).

3. Konklusjon

Hvis vi trenger å konvertere bredde- og lengdegradskoordinater til en 2D-overflate, kan vi bruke Mercator-projeksjonen. Avhengig av nøyaktigheten vi trenger for implementeringen, kan vi bruke den sfæriske eller elliptiske tilnærmingen.

Som alltid kan vi finne koden til denne artikkelen på GitHub.


$config[zx-auto] not found$config[zx-overlay] not found