Convertir la latitude et la longitude en un point 2D en Java

Convertir la latitude et la longitude en un point 2D en Java

 

1. Vue d'ensemble

Lors de la mise en œuvre d'applications utilisant des cartes, nous rencontrons généralement le problème de la conversion de coordonnées. La plupart du temps, nous avons besoin deconvert latitude and longitude to a 2D point to display. Heureusement, pour résoudre ce problème, nous pouvons utiliser les formules de la projection de Mercator.

Dans ce didacticiel, nous aborderons la projection Mercator et apprendrons à mettre en œuvre ses deux variantes.

2. Projection Mercator

LeMercator projection est une projection cartographique introduite par le cartographe flamand Gerardus Mercator en 1569. Une projection cartographique convertit les coordonnées de latitude et de longitude de la Terre en un point situé sur une surface plane. En d'autres termes,it translates a point on the surface of the earth to a point on a flat map.

Il existe deux manières de mettre en œuvre la projection de Mercator. The pseudo Mercator projection treats the Earth as a sphere. The true Mercator projection models the Earth as an ellipsoid. Nous allons implémenter les deux versions.

Commençons par une classe de base pour les deux implémentations de projection Mercator:

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);
}

Cette classe fournit également le rayon majeur et le rayon mineur de la Terre mesurés en mètres. Il est bien connu que la Terre n’est pas exactement une sphère. Pour cette raison, nous avons besoin de deux rayons. Premièrement, lesmajor radius is the distance from the center of the earth to the equator. Deuxièmement, lesminor radius is the distance from the center of the earth to the north and south poles.

2.1. Projection sphérique de Mercator

Le modèle de pseudo-projection traite la Terre comme une sphère. Contrairement à la projection elliptique où la Terre serait projetée sur une forme plus précise. Cette approche nous permet unquick estimation pour la projection elliptique plus précise, mais plus lourde de calcul. En conséquence, lesmeasurements of distances directs dans cette projection seront approximatifs.

De plus, les proportions des formes sur la carte seront légèrement modifiées. En raison de cette latitude et des ratios de formes d'objets sur la carte tels que des pays, des lacs, des rivières, etc. ne sont pasprecisely preserved.

Ceci est également appelé la projectionWeb Mercator - couramment utilisée dans les applications Web, y compris Google Maps.

Mettons en œuvre cette approche:

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;
    }
}

La première chose à noter sur cette approche est le fait que cette approche représente lesradius de la Terre parone constant et non par deux tels qu'ils sont réellement. Deuxièmement, nous pouvons voir que nous avons implémenté deux fonctions à utiliser pour la conversion enx-axis projection ety-axis projection. Dans la classe ci-dessus, nous avons utilisé la bibliothèqueMath fournie par java pour nous aider à simplifier notre code.

Testons une conversion simple:

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

Il est à noter que cette projection mappera des points dans une boîte englobante (gauche, bas, droite, haut) de (-20037508.34, -23810769.32, 20037508.34, 23810769.32).

2.2. Elliptical Mercator Projection

La vraie projection modélise la terre comme un ellipsoïde. This projection givesaccurate ratiosfor objects anywhere on Earth. Certainement,it respects objects on the map butnot 100% accurate. Cependant, cette approche n’est pas la plus fréquemment utilisée car elle est complexe en calcul.

Mettons en œuvre cette approche:

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);
    }
}

Ci-dessus, nous pouvons voir à quel point cette approche est complexe en ce qui concerne la projection sur l'axe des ordonnées. En effet, il convient de prendre en compte la forme de la terre non ronde. Bien que la véritable approche de Mercator semble complexe, elle est plus précise que l’approche sphérique car elle utilise le rayon pour représenter la Terre d’un mineur et d’un majeur.

Testons une conversion simple:

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

Cette projection cartographiera les points dans une boîte englobante de (-20037508.34, -34619289.37, 20037508.34, 34619289.37).

3. Conclusion

Si nous devons convertir les coordonnées de latitude et de longitude sur une surface 2D, nous pouvons utiliser la projection de Mercator. Selon la précision dont nous avons besoin pour notre mise en œuvre, nous pouvons utiliser l'approche sphérique ou elliptique.

Comme toujours, on retrouve le code de cet articleover on GitHub.