Meilleures mesures de distance dans la projection Web Mercator

10

Je travaille avec une pile ESRI, stockant mes couches dans une géodatabase sql-spatial-enabled-SDE (type Geometry, Web Mercator-3857).

Je crée une application de cartographie Web, donc par défaut, les tuiles sont également dans Web Mercator, 3857.

Via des procs stockés, j'utilise STDistance pour interroger les distances entre l'emplacement d'un utilisateur (coordonnées également dans Web Mercator) et les différentes couches.

Le problème est qu'en raison de la distorsion du web mercator, mes calculs de distance sont de plus en plus décalés, plus ils sont éloignés de l'équateur.

J'ai pensé à stocker mes calques en sql-spatial-geography (plutôt qu'en geometry), mais:

  • J'imagine que mes requêtes de distance prendront beaucoup plus de temps (la distance calcule sur une surface sphérique)
  • je devrai réimporter beaucoup de données
  • les services arcgis ne seront pas aussi rapides qu'ils auront besoin de projeter à la volée

Si je vais sur Google Maps et que je fais un calcul de distance, la distance renvoyée est beaucoup plus précise, même dans les régions du nord / sud, donc je suppose que Google doit corriger la distorsion causée par la projection Web Mercator.

Ma question est donc la suivante: existe-t-il une valeur de facteur simple qui peut être appliquée aux calculs de distance effectués dans la projection Web Mercator pour obtenir la distance «correcte»?

Blomster
la source

Réponses:

12

Pour les courtes distances, vous pouvez multiplier la distance calculée par cos(lat), car l'échelle de la projection de Mercator est proportionnelle à la sécante de la latitude (la sécante est 1/cos). Voir également http://en.wikipedia.org/wiki/Mercator_projection#Mathematics_of_the_projection


Addendum grâce à @ jeremiah-england : bien que la correction ci-dessus soit correcte en ce qui concerne les vraies projections Mercator, le Web Mercator (EPSG: 3857) n'est pas un Mercator. EPSG l'appelle un "Pseudo-Mercator". Le problème est qu'il utilise WGS84, un modèle éliptique, et le projette en utilisant des calculs de mercator sphériques (que Google a utilisés parce qu'ils sont plus rapides). Si vous modifiez vos distances 1/cos(phi)avec le Web Mercator, vous bénéficierez d'une réduction d'environ 0,6% à l'équateur. Voir la présentation de Noel Zinn sur Web Mercator pour plus de détails.

Selon la présentation susmentionnée, la méthode suivante pourrait être utilisée pour calculer des distances plus précises à partir des coordonnées Web Mercator. Étant donné dx- différence de coordonnées horizontales (direction WE), et dy- différence de coordonnées verticales (direction SN):

e = 0.081819191
adjustedX = dx * cos(lat) / sqrt(1 - e^2 * sin(lat)^2)
adjustedY = dy * cos(lat) * (1 - e^2) / pow(1 - e^2 * sin(lat)^2, 3/2)
adjustedDistance = hypot(adjustedX, adjustedY)

Le rapport entre cet ajustement et cos(lat)est plus grand dans la direction SN, allant de 0.9933l'équateur aux 1.0034pôles. Le rapport de direction WE commence par 1à l'équateur et se développe aux 1.0034pôles.

Notez que cette correction ne fonctionne raisonnablement bien que pour de courtes distances, où la géométrie planaire de la surface de la Terre peut être supposée.

mkadunc
la source
1
Et pour des distances plus longues, vous pouvez utiliser la latitude moyenne des deux extrémités: cos((l1 + l2)/2)ce qui vous donnera la distance rhumb-line / constant course, plutôt qu'une distance grand cercle.
MerseyViking
cela ne fait que changer le sphéroïde, mais ne donne pas la même précision qu'une projection locale.
falcacibar
1
@falcibar - je ne vois pas comment le choix de la latitude moyenne change le sphéroïde
mkadunc
@MerseyViking: merci, j'ai oublié de mentionner que la meilleure latitude à utiliser pour le calcul serait la moyenne des deux points comparés.
mkadunc
1
+1 pour la réponse. @Mersey: Pourquoi la correction de latitude moyenne fonctionne-t-elle? Après tout, les distorsions dans le Mercator peuvent devenir arbitrairement importantes et les écarts des loxodromes par rapport aux géodésiques peuvent également être importants. Il semble qu'il y ait des erreurs potentiellement énormes qui pourraient être commises pour lesquelles une simple correction ne serait pas fiable.
whuber
6

Je considérerais votre deuxième option de stocker à nouveau vos données dans le GEOGRAPHYformat si vous recherchez des résultats précis sur des données globales.

Rien ne vous empêche d'avoir deux champs spatiaux dans une table - un dans Mercator en tant que GEOMETRYtype et un dans WGS84 en tant que GEOGRAPHYtype (du moins pas dans SQL Server, je ne suis pas sûr d'ArcSDE).

Vous devriez pouvoir créer un script de géotraitement simple qui remplira les deux champs avec vos données d'origine. S'il y a des modifications et des mises à jour fréquentes, cela peut ne pas être une option.

Une fois que vous avez les deux champs, vous pouvez continuer à utiliser votre Mercator pour un affichage rapide et convertir les points entrés par l'utilisateur en Lat / Lon pour les distances.

Cela présente deux avantages majeurs:

  • vous pouvez également obtenir des zones et des longueurs de fonctionnalités plus précises en fonction des requêtes des utilisateurs
  • vous n'avez pas à vous soucier d'oublier d'ajouter du code personnalisé pour chaque requête qui traite des mesures

Les vitesses de requête seront plus complexes, mais elles peuvent être imperceptibles pour un utilisateur. Vous pouvez tester avec une classe d'entités avant de décider d'une solution. Vous devrez également convertir les points entrés par l'utilisateur depuis Mercator (ce qui devrait être trivial et pourrait être fait dans le navigateur).

Même avec le type géographique, il existe toujours une marge d'erreur:

La tolérance d'erreur pour les méthodes géographiques peut être aussi étendue que les extensions 1.0e-7 *

Depuis MSDN

geographika
la source
Malheureusement, SDE ne permettra qu'une seule colonne spatiale: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… - Je n'ai pas essayé de créer une vue et de l'enregistrer avec SDE, mais cela pourrait être une approche possible.
Allan Adair du
@Allan - bon à savoir. Un autre point positif pour utiliser SDE alors! Une table avec seulement la géométrie 4326 et une jointure de retour à la table d'origine + vue spatiale devrait atteindre le même objectif
geographika
3

Une autre suggestion d'ESRI consiste à utiliser un "service de géométrie", qui implique d'envoyer les géométries à un serveur ArcGIS et de renvoyer le résultat. Si vous ne vous attendez pas à des problèmes de goulot d'étranglement en utilisant un service Web, cela peut être une approche très efficace. J'ai utilisé la même approche dans une application Silverlight.

Voici une entrée de blog originale d'ESRI: http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2010/03/05/Measuring-distances-and-areas-when-your-map-uses-the -Mercator-projection.aspx

Dans le blog, il y a un exemple JavaScript simplifié, et il y a aussi un exemple d'application complet ici: http://serverapps.esri.com/javascript_examples/compare_measurements.htm

Allan Adair
la source
0

Comme le fait Google Earth, vous pouvez transformer la géométrie en projection de zone WGS84 locale ou en projection WGS84 améliorée comme SIRGAS en Amérique du Sud.

Vous pouvez rechercher dans http://www.spatialreference.org les coordonnées de presque toutes les projections "zonifiées", et vous pouvez créer un tableau, etc., pour les transformer en fonction de la zone.

On imagine une table zones

|   minx     |    miny    |    maxx    |   maxy     |  srid  |
+------------+------------+------------+------------+--------+
|234567.34314|234567.34334|234567.34334|234567.34334|  1234  |

toutes les valeurs minx, miny, maxx, maxy stockées dans Spherical Mercator (Web Mercator). donc je vais utiliser postgis comme exemple.

SELECT ST_Distance(
         ST_Transform( -- transform/reproject
            ST_SetSRID(geom_line, 3857) -- geom_line with forced srid assignation to web mercator
            , ( -- here we get the first SRID from the spatial position of geom_line
                 SELECT  srid
                 FROM    zones
                 WHERE   ST_Contains(
                           ST_MakeBox2d(ST_Point(minx,miny),ST_Point(maxx,maxy))
                           , geom_line
                         )
                 LIMIT 1
            ))

J'espère que cela vous sera utile, passez une bonne journée.

falcacibar
la source
Je ne peux pas en être certain, mais sur la base de l'utilisation par Blomster de "STDistance" dans sa question, il semble qu'il n'utilise pas PostGIS. Si Blomster utilise SQL Server, il n'y a pas de fonctionnalité ST_Transform.
Allan Adair,
Je donne le processus et la meilleure façon de le résoudre, il pourrait s'occuper du reste, de toute façon il pourrait utiliser une reprojection logicielle, mais c'est vraiment dommage qu'un SQL Server ne traite pas des projections.
falcacibar
peut-être que CLR est activé et que la bibliothèque .net nettopologysuite pourrait aider?
falcacibar,