Пару лет назад я опубликовал обзор «Международной линии даты» и @jdeolive предложил разделить функции на линии даты. Итак, я попробовал.
Когда я пытаюсь разделить свою спутниковую дорожку с помощью splitWith на линии времени, я возвращаюсь null
. Я знаю, что делю правильно, потому что, когда я делю по линии Гринвича, я получаю ожидаемые результаты.
Кто-нибудь знает, как я могу правильно разделить Linestring программно вдоль строки даты с OpenLayers? Я ищу пример кода, если у вас есть.
Я пытался, wrapDateLine
но он не работает на векторных слоях, несмотря на то, что мой векторный слой выглядит так:
vectorLayer = new OpenLayers.Layer.Vector("GroundTracks", {
renderers: ['Canvas', 'VML'],
wrapDateLine: true}); // <-- shoud be wraping.
Вот мой код:
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);
Мой вопрос не является дубликатом этого вопроса, потому что они хотят знать, как это сделать в ogr2ogr
Обновить:
Вот как выглядит типичный набор данных, с которым я работаю (24-часовой спутниковый трек): Linestring wkt можно найти ЗДЕСЬ .
источник
Ответы:
Проблема в том, что ваша функция не пересекает линию даты с точки зрения OpenLayers, поэтому ваша разделенная линия не пересекает вашу функцию. Пример из ваших данных:
Вы переходите от -178 к 156, и это не пересекает линию даты с точки зрения OpenLayers. Вместо разделения на строку даты, вы должны разделить на минимальное значение X.
Я построил здесь пример, который успешно разделил вашу спутниковую дорожку на 2 функции: http://jsfiddle.net/6XJ5A/
Теперь, чтобы использовать WKT с несколькими строками в своем обновлении, вместо использования прямой линии, вы должны пройти весь набор данных и построить линию разделения со всеми координатами, проходящими через линию даты. Построив небольшую линию внутри мультилинии, вы можете разделить все координаты, которые должны проходить через линию даты. Вот обновленный пример: http://jsfiddle.net/Jc274/
И код:
Это вернет вам разделенную линию по всем точкам, которые «пересекают» линию даты
Обратите внимание, что я также перебираю координаты, чтобы удалить линию, проходящую через карту, чтобы соединить 2 координаты:
Обновление: я обновил первый пример, чтобы добавить только разделенную строку. Я также обновил объяснение соответственно. Этот подход не является пуленепробиваемым с 24-часовой спутниковой трассой, которую вы предоставили, но я работаю над этим.
Обновление 2: я обновил второй пример. Используя мультилинию для разделения и циклический просмотр результата для удаления дополнительных координат, добавленных в результате разделения, мы получаем набор функций, которые никогда не пересекают линию даты.
источник
..., -178.475596 -81.673196, 156.248392 -81.611421,...
абсолютно пересекает график. Смотрите здесьЯ нашел отличное решение на github @Dane. Он называется Arc.js и предназначен для расчета маршрутов по Большому кругу. Мало того, он также разделит линию на линии даты и предоставит вам две линии строк, которые встречаются на линии даты, которые OpenLayers могут легко отобразить. Я надеюсь, что он выходит вперед, чтобы получить награду.
Вот мои результаты:
источник
Функция splitWith не знает о трехмерной форме Земли. Он работает только в двухмерном мире. В вашем случае все ваши
LINESTRING
координаты X находятся в диапазоне от -180 до 180. Таким образом, с двухмерной точки зрения OpenLayers, строка строки никогда не пересекает вашу геометрию разбиения (линию даты), и она сообщает вам об этом, возвращаяnull
.Я считаю, что вам придется написать некоторый пользовательский код, чтобы выполнить разбиение. Я представляю себе алгоритм, который зацикливается на ваших вершинах, создавая строки выходных строк следующим образом:
Одна разумная эвристика для определения того, пересекает ли пара вершин линию даты, состоит в том, чтобы видеть, больше ли разница между координатами X превышает 180 градусов. (Хотя это может быть неправильно, например, в полярных регионах. Может быть, вам повезло, что у вас нет действительно высоких широт.)
Операция разбиения сегмента на две части может быть такой же простой, как линейная интерполяция (если вас не слишком заботит точность трека). Когда вы обнаружите, что сегмент пересекает линию даты, вы делаете копию второй вершины и перемещаете ее координату X (добавляя или вычитая 360 градусов), а затем интерполируете координату Y.
РЕДАКТИРОВАТЬ : Вот JSFiddle, который демонстрирует вышеупомянутый алгоритм на ваших данных: http://jsfiddle.net/85vjS/
источник
Если это работает с Гринвичем, это потому, что вы находитесь за пределами вашего CRS. Поэтому я бы сначала предложил тот же обходной путь, что и в посте, на который вы указываете:
и возможно
для другой стороны.
Другое решение заключается в том, чтобы работать в CRS, который не «вышел за границы» на дату. После этого вы сможете без проблем разделить ваши данные.
источник
LINESTRING(179.99 -89, 179.99 89)
иLINESTRING(-179.99 -89, -179.99 89)
безрезультатно. Что касается CRS, к сожалению, это не сработает для моей цели, потому что я картирую спутниковые треки, которые много раз путешествуют по миру. Таким образом, все CRS где-то разделены, и у меня будет одна и та же проблема, где бы я ни разбил ее. Спасибо за ваш вклад.