Hace un par de años publiqué The International Date Line y @jdeolive sugirió que dividiera las funciones en dateLine. Entonces lo intenté.
Cuando trato de dividir mi vía satelital con splitWith en la fecha, regreso null
. Sé que me estoy dividiendo correctamente porque cuando divido en la línea de Greenwich obtengo los resultados esperados.
¿Alguien sabe cómo puedo dividir correctamente una cadena de líneas mediante programación a lo largo de la línea de fecha con OpenLayers? Busco código de ejemplo si lo tienes.
Lo he intentado wrapDateLine
pero no parece estar funcionando en capas vectoriales a pesar de que mi capa vectorial es así:
vectorLayer = new OpenLayers.Layer.Vector("GroundTracks", {
renderers: ['Canvas', 'VML'],
wrapDateLine: true}); // <-- shoud be wraping.
Aquí está mi código:
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);
Mi pregunta no es un duplicado de esta pregunta porque quieren saber cómo hacerlo en ogr2ogr
Actualizar:
Así es como se ve un conjunto de datos típico con el que trabajo (seguimiento satelital de 24 horas): la línea de líneas se puede encontrar AQUÍ .
fuente
Respuestas:
El problema es que su entidad no cruza la línea de fecha desde la perspectiva de OpenLayers, por lo que su línea de división no intersecta su entidad. Ejemplo de sus datos:
Pasas de -178 a 156, y esto no cruza la línea de fecha desde la perspectiva OpenLayers. En lugar de dividir en la línea de fecha, debe dividir en su valor X mínimo.
He creado un ejemplo aquí que dividió con éxito su ruta satelital en 2 características: http://jsfiddle.net/6XJ5A/
Ahora, para usar el WKT con varias líneas en su actualización, en lugar de usar una línea recta, debe recorrer todo el conjunto de datos y construir su línea dividida con todas las coordenadas que atraviesan la línea de fecha. Al construir una pequeña línea dentro de una multilínea, puede dividir todas las coordenadas que deben cruzar la línea de fecha. Aquí está el ejemplo actualizado: http://jsfiddle.net/Jc274/
Y el código:
Esto le devolverá una línea dividida en todos los puntos que "cruzan" la línea de fecha
Tenga en cuenta que también recorro las coordenadas para eliminar la línea que cruza el mapa para conectar las 2 coordenadas:
Actualización: actualicé el primer ejemplo para agregar solo la línea que se dividió. También actualicé la explicación en consecuencia. Este enfoque no es a prueba de balas con la pista satelital de 24 horas que proporcionó, pero estoy trabajando en ello.
Actualización 2: actualicé el segundo ejemplo. Al usar una línea múltiple para dividir y recorrer el resultado para eliminar las coordenadas adicionales agregadas por la división, obtenemos un conjunto de características que nunca pasan por la línea de fecha.
fuente
..., -178.475596 -81.673196, 156.248392 -81.611421,...
cruza absolutamente la fecha. Ver aquíEncontré una gran solución en el github de @Dane. Se llama Arc.js y es para calcular rutas de gran círculo. No solo eso, también dividirá la línea en la línea de fecha y le proporcionará dos cadenas de líneas que se encuentran en la línea de fecha, que OpenLayers puede asignar fácilmente. Espero que se presente para reclamar la recompensa.
Aquí están mis resultados:
fuente
La función splitWith no conoce la forma tridimensional de la tierra. Solo opera en un mundo bidimensional. En su caso, todas sus
LINESTRING
coordenadas X están entre -180 y 180. Entonces, desde la perspectiva bidimensional de OpenLayers, la cadena de línea nunca cruza su geometría dividida (la línea de fecha) y se lo dice al regresarnull
.Creo que tendrá que escribir un código personalizado para hacer la división. Estoy imaginando un algoritmo que recorre tus vértices, creando cadenas de línea de salida como esta:
Una heurística razonable para determinar si un par de vértices cruza la línea de fecha es ver si la diferencia entre las coordenadas X es más de 180 grados. (Aunque esto puede equivocarse, por ejemplo, en las regiones polares. Quizás tenga la suerte de no tener latitudes realmente altas).
La operación de dividir un segmento en dos partes podría ser tan simple como la interpolación lineal (si no le importa demasiado la precisión de la pista). Cuando detecta que el segmento cruza la línea de fecha, hace una copia del segundo vértice y mueve su coordenada X (sumando o restando 360 grados) y luego interpola la coordenada Y.
EDITAR : Aquí hay un JSFiddle que muestra el algoritmo anterior en sus datos: http://jsfiddle.net/85vjS/
fuente
Si funciona con Greenwich, esto se debe a que está dentro de los límites de su CRS. Así que primero sugeriría la misma solución alternativa que en la publicación a la que apunta:
y tal vez
por el otro lado
Otra solución es trabajar en un CRS que no está "fuera de límite" en la fecha. Entonces debería poder dividir sus datos sin problema.
fuente
LINESTRING(179.99 -89, 179.99 89)
y fueLINESTRING(-179.99 -89, -179.99 89)
en vano Con respecto al CRS, desafortunadamente, esto no funcionará para mi propósito porque estoy mapeando pistas satelitales que dan la vuelta al mundo muchas veces. Entonces, todos los CRS se dividen en algún lugar y tendré el mismo problema en cualquier lugar donde lo divida. Gracias por tu contribución.