Comment puis-je faire un enveloppement de polyligne dans le monde entier?

14

J'utilise des cartes de dépliants pour créer une représentation d'un défi autour du monde. Je voudrais ajouter une polyligne qui se dirige vers l'est de Tokyo et apparaît ensuite à l'ouest de l'Amérique du Sud sur la carte - mais à la place, j'obtiens une ligne qui traverse la carte dans la direction opposée (voir la ligne jaune).

entrez la description de l'image ici

Je pense que cela est probablement lié aux lignes de données et / ou aux systèmes de coordonnées, mais je suis un peu sommaire sur les détails. Quelqu'un peut-il expliquer la théorie derrière ce que je dois faire pour que cela fonctionne? J'utilise la projection bluemarble de la Nasa:

var bluemarble = new L.TileLayer.WMS("http://demo.opengeo.org/geoserver/wms", {
layers: 'bluemarble',
attribution: "Data © NASA Blue Marble, image service by OpenGeo",
minZoom: 2,
maxZoom: 5
});
codecowboy
la source
2
Vous devez rompre la polyligne au méridien de + -180 degrés. Cela nécessite de trouver la latitude à laquelle la polyligne traverse ce méridien. Votre SIG a probablement des méthodes pour faire le break. Sinon, une solution simple peut être dérivée du code affiché dans un thread associé . Êtes-vous capable d'exécuter du code comme celui-ci sur votre plateforme?
whuber
Je suis d'accord avec whuber. J'ai dû effectuer une tâche similaire avec des polygones croisant + - 180. Vous devez vous diviser en plusieurs polylignes / polygones chaque fois que vous traversez le + -180.
Steve

Réponses:

13

Vous devez rompre la polyligne au méridien de + -180 degrés. Cela nécessite de trouver la latitude à laquelle la polyligne traverse ce méridien. Votre SIG a probablement des méthodes pour faire le break. Sinon, une solution simple peut être dérivée du code affiché dans un thread associé . Voici quelques détails.

  • Une polyligne est représentée comme une séquence de sommets , chacun donné sous forme (lat, lon), avec -180 <= lon <= 180. Vous devez vérifier chaque paire successive pour voir si elle croise le méridien + -180. Il y a un test rapide: si la valeur absolue de la différence de longitudes est de 180 ou plus, il y a un croisement.

  • Dans chaque segment (lat0, lon0) -> (lat1, lon1) qui traverse le méridien + -180, vous devez diviser la polyligne en deux morceaux où elle se croise.

La clé est de trouver la latitude du point de rupture avec une précision raisonnable. Cela se fait plus facilement avec un modèle de terre sphérique: l'erreur (par rapport à un modèle ellipsoïdal plus précis) sera trop faible pour être remarquée.

Laissez le segment en question passer du point 0 en (lat0, lon0) au point 1 en (lat1, lon1). Le point de rupture peut être trouvé en exécutant un segment de ligne droite en 3D entre les deux points comme représenté en coordonnées cartésiennes et en trouvant où la coordonnée y est nulle. Les coordonnées cartésiennes sont

(x0, y0, z0) = (cos(lon0)*sin(lat0), sin(lon0)*sin(lat0), cos(lat0))

et une expression similaire donnant (x1, y1, z1) pour le point 1. Résoudre l'équation

t * y0 + (1-t) * y1 = 0

pour t; C'est,

t = y1 / (y1 - y0).

Les coordonnées de l'intersection sont donc

(x, y, z) = (t * x0 + (1-t) * x1, 0, t * z0 + (1-t) * z1)

Ce point (qui se trouve sous la surface de la terre quelque part sous le méridien + -180) a une latitude égale à

lat2 = ATan(z/x).

Le point d'arrêt doit être représenté de deux manières. Lorsque vous l'attachez après (lat0, lon0) pour terminer la première partie de la polyligne rompue, utilisez (lat2, -180) si lon0 est négatif et sinon utilisez (lat2, 180). Lorsque vous l'attachez avant (lat1, lon1) pour démarrer la deuxième partie de la polyligne rompue, suivez une règle similaire.

Dans des cas exceptionnels, l'un ou les deux des points 0 et 1 peuvent être sur le méridien + -180. En suivant cette procédure, vous placerez un segment de longueur nulle sur l'une des pièces de polyligne que vous créez. Si cela peut provoquer un problème avec le SIG, testez cette condition.

Notez qu'une polyligne peut traverser ce méridien plusieurs fois. Par conséquent, après avoir trouvé la première rupture et brisé la polyligne en deux parties, vous devez traiter la deuxième partie de la même manière.

whuber
la source
1
Ce que Whuber a dit est OK mais je pense qu'il y a une faute de frappe dans la phrase suivante:> Lorsque vous l'attachez après (lat0, lon0) pour terminer la première partie de la polyligne cassée, utilisez (lat2, -180) si lat0 est négatif et sinon utilisez (lat2, 180). Je pense que ça doit être:> utiliser (lat2, -180) si lon0 est négatif et sinon utiliser (lat2, 180)
Georgi
@Georgi Merci d'avoir attrapé cela; Je pense que vous avez raison et je ferai le changement.
whuber
J'ai dû implémenter cela dans Leaflet.js, voici mon code: gist.github.com/mikeatlas/0b69b354a8d713989147
Mike Atlas
Merci, @Mike. J'adore l'illustration en zig-zag: c'est exactement le genre de circonstances que j'envisageais en écrivant cette réponse. Si vous voulez un test vraiment sévère, voyez ce qui arrive à une polyligne qui longe le méridien + -180 degrés lui-même (et traverse les deux pôles)!
whuber
@whuber J'ai peut-être juste besoin d'essayer cela: / Publiera les résultats
Mike Atlas
0

Pour une discussion connexe, ce billet est peut-être intéressant:

"la projection vectorielle au-dessus de la limite d'enroulement est divisée"

https://trac.osgeo.org/grass/ticket/1527

markusN
la source