Il y a quelques années, j'ai posté The International Date Line et @jdeolive a suggéré de diviser les fonctionnalités de la dateLine. J'ai donc essayé.
Lorsque j'essaie de diviser ma piste satellite avec splitWith sur la ligne de données, je reviens null
. Je sais que je me sépare correctement parce que lorsque je me divise sur la ligne Greenwich, j'obtiens les résultats attendus.
Quelqu'un sait-il comment diviser correctement une Linestring par programmation le long de la ligne de date avec OpenLayers? Je cherche un exemple de code si vous l'avez.
J'ai essayé, wrapDateLine
mais il ne semble pas fonctionner sur les calques vectoriels malgré le fait que mon calque vectoriel soit comme ceci:
vectorLayer = new OpenLayers.Layer.Vector("GroundTracks", {
renderers: ['Canvas', 'VML'],
wrapDateLine: true}); // <-- shoud be wraping.
Voici mon code:
var features = [];
var format = new OpenLayers.Format.WKT({
'internalProjection': map.baseLayer.projection,
'externalProjection': prjGeographic
});
var satTrack = format.read("LINESTRING (95.538611 13.286511, 94.730711 16.908947, 93.901095 20.528750, 93.043594 24.145177, 92.150978 27.757436, 91.214579 31.364666, 90.223791 34.965899, 89.165364 38.560019, 88.022401 42.145679, 86.772901 45.721205, 85.387568 49.284424, 83.826433 52.832413, 82.033480 56.361087, 79.927797 59.864504, 77.388419 63.333664, 74.227306 66.754285, 70.139140 70.102478, 64.605267 73.335774, 56.712904 76.373458, 44.881134 79.052803, 26.939886 81.047314, 02.704174 81.839241, -21.686285 81.101751, -39.887660 79.141947, -51.906937 76.480894, -59.912477 73.452897, -65.514482 70.225089, -69.645366 66.880243, -72.834535 63.461797, -75.393132 59.994131, -77.512464 56.491789, -79.315407 52.963919, -80.884039 49.416549, -82.275114 45.853820, -83.529088 42.278691, -84.675583 38.693355, -85.736827 35.099503, -86.729876 31.498490, -87.668095 27.891443, -88.562176 24.279331, -89.420849 20.663020, -90.251389 17.043303, -91.059999 13.420926, -91.852092 09.796602, -92.632515 06.171020, -93.405728 02.544857, -94.175960 -01.081217, -94.947343 -04.706542, -95.724045 -08.330456, -96.510402 -11.952298, -97.311065 -15.571400, -98.131162 -19.187081, -98.976502 -22.798638, -99.853829 -26.405335, -100.771148 -30.006378, -101.738172 -33.600889, -102.766925 -37.187866, -103.872602 -40.766117, -105.074803 -44.334175, -106.399366 -47.890158, -107.881153 -51.431559, -109.568417 -54.954914, -111.529886 -58.455253, -113.866668 -61.925160, -116.733085 -65.353081, -120.374635 -68.720132, -125.199754 -71.993642, -131.916790 -75.113368, -141.772276 -77.960803, -156.750096 -80.294831, -178.475596 -81.673196, 156.248392 -81.611421, 135.042323 -80.136505, 120.556535 -77.748172, 111.014840 -74.872356, 104.485504 -71.737081, 99.775637 -68.454400, 96.208126 -65.081545, 93.391438 -61.649716, 91.089380 -58.177038, 89.152970 -54.674643, 87.484294 -51.149703, 86.016609 -47.607042, 84.702947 -44.050030, 83.509299 -40.481112, 82.410411 -36.902133, 81.387093 -33.314533, 80.424442 -29.719485, 79.510644 -26.117981, 78.636145 -22.510889, 77.793053 -18.898997, 76.974710 -15.283040, 76.175371 -11.663718, 75.389950 -08.041709, 74.613831 -04.417680, 73.842693 -00.792294, 73.072378 02.833789, 72.298749 06.459907, 71.517566 10.085391, 70.724342 13.709564, 69.914194 17.331733, 69.081655 20.951185, 68.220447 24.567170, 67.323194 28.178891, 66.381031 31.785476, 65.383084 35.385943, 64.315735 38.979152, 63.161579 42.563725, 61.897893 46.137940, 60.494337 49.699551, 58.909396 53.245525, 57.084691 56.771602, 54.935577 60.271560, 52.334964 63.735923, 49.084320 67.149569, 44.859585 70.487030, 39.107498 73.702694, 30.852243 76.709182, 18.420695 79.329532, -00.339911 81.212453, -25.028018 81.831766)");
var featGreenwichLine = format.read("LINESTRING(0 -89, 0 89)");
var featDateLine = format.read("LINESTRING(180 -89, 180 89)");
features.push(featGreenwichLine);
features.push(featDateLine);
features.push(satTrack);
var resultsGreenwich = satTrack.geometry.splitWith(featGreenwichLine.geometry);
var resultsDateLine = satTrack.geometry.splitWith(featDateLine.geometry);
console.log(resultsGreenwich); //<--RETURNS EXPECTED RESULTS.
console.log(resultsDateLine);//<--RETURNS NULL.
vectorLayer.addFeatures(features);
Ma question n'est pas un double de cette question car ils veulent savoir comment le faire dans ogr2ogr
Mise à jour:
Voici à quoi ressemble un ensemble de données typique avec lequel je travaille (piste satellite 24 heures): Le wkt Linestring peut être trouvé ICI .
la source
Réponses:
Le problème est que votre entité ne traverse pas la ligne de date du point de vue d'OpenLayers, donc votre ligne de séparation ne coupe pas votre entité. Exemple de vos données:
Vous passez de -178 à 156, et cela ne franchit pas la ligne de date du point de vue OpenLayers. Au lieu de diviser sur la ligne de date, vous devez fractionner sur votre valeur X minimale.
J'ai construit un exemple ici qui a réussi à diviser votre piste satellite en 2 fonctionnalités: http://jsfiddle.net/6XJ5A/
Maintenant, pour utiliser le WKT avec plusieurs lignes dans votre mise à jour, au lieu d'utiliser une ligne droite, vous devez parcourir l'ensemble de données et créer votre ligne de séparation avec toutes les coordonnées qui traversent la ligne de données. En construisant une petite ligne à l'intérieur d'une multiligne, vous pouvez diviser toutes les coordonnées qui doivent traverser la ligne de données. Voici l'exemple mis à jour: http://jsfiddle.net/Jc274/
Et le code:
Cela vous renverra une ligne divisée sur tous les points qui "traversent" la ligne de temps
Notez que je boucle également les coordonnées pour supprimer la ligne qui traverse la carte pour connecter les 2 coordonnées:
Mise à jour: j'ai mis à jour le premier exemple pour n'ajouter que la ligne qui a été fractionnée. J'ai également mis à jour l'explication en conséquence. Cette approche n'est pas à l'épreuve des balles avec la piste satellite 24h que vous avez fournie, mais j'y travaille.
Mise à jour 2: j'ai mis à jour le deuxième exemple. En utilisant une multiligne pour diviser et parcourir le résultat pour supprimer les coordonnées supplémentaires ajoutées par la division, nous obtenons un ensemble de fonctionnalités qui ne traversent jamais la ligne de données.
la source
..., -178.475596 -81.673196, 156.248392 -81.611421,...
traverse absolument la ligne de données. Voir iciJ'ai trouvé une excellente solution sur le github de @Dane. Il s'appelle Arc.js et sert à calculer les itinéraires du Grand cercle. Non seulement cela, il divisera également la ligne sur la ligne de données et vous fournira deux chaînes de lignes qui se rencontrent sur la ligne de données, que OpenLayers peut facilement mapper. J'espère qu'il se présente pour réclamer la prime.
Voici mes résultats:
la source
La fonction splitWith ne connaît pas la forme tridimensionnelle de la Terre. Il ne fonctionne que dans un monde à deux dimensions. Dans votre cas, toutes vos
LINESTRING
coordonnées X sont comprises entre -180 et 180. Donc, du point de vue bidimensionnel d'OpenLayers, la chaîne de ligne ne traverse jamais réellement votre géométrie divisée (la ligne de date) et elle vous le dit en revenantnull
.Je pense que vous devrez écrire du code personnalisé pour effectuer le fractionnement. J'imagine un algorithme qui boucle sur vos sommets, créant des chaînes de ligne de sortie comme ceci:
Une heuristique raisonnable pour déterminer si une paire de sommets traverse la ligne de date est de voir si la différence entre les coordonnées X est supérieure à 180 degrés. (Bien que cela puisse se tromper, par exemple, dans les régions polaires. Peut-être avez-vous la chance de ne pas avoir de latitudes vraiment élevées.)
L'opération de division d'un segment en deux parties peut être aussi simple qu'une interpolation linéaire (si vous ne vous souciez pas trop de la précision de la piste). Lorsque vous détectez que le segment traverse la ligne de date, vous faites une copie du deuxième sommet et déplacez sa coordonnée X (en ajoutant ou en soustrayant 360 degrés), puis interpolez la coordonnée Y.
EDIT : Voici un JSFiddle qui démontre l'algorithme ci-dessus sur vos données: http://jsfiddle.net/85vjS/
la source
Si cela fonctionne avec Greenwich, c'est parce que vous êtes dans les limites de votre CRS. Je suggère donc d'abord la même solution de contournement que dans le post que vous pointez:
et peut-être
pour l'autre côté.
Une autre solution consiste à travailler dans un CRS qui n'est pas «hors limites» au niveau de la ligne de données. Vous devriez alors pouvoir diviser vos données sans problème.
la source
LINESTRING(179.99 -89, 179.99 89)
etLINESTRING(-179.99 -89, -179.99 89)
en vain. En ce qui concerne le CRS, malheureusement, cela ne fonctionnera pas pour mon objectif car je mappe des pistes satellites qui font le tour du monde de nombreuses fois. Donc, tous les CRS sont divisés quelque part et j'aurai le même problème partout où je le diviserai. Merci pour votre contribution.