Há alguns anos, publiquei o The International Date Line e o @jdeolive sugeriu que eu dividisse os recursos no dateLine. Então eu tentei.
Quando tento dividir minha faixa de satélite com splitWith na linha de dados, volto null
. Sei que estou me dividindo corretamente porque, quando me divido na linha de Greenwich, obtenho os resultados esperados.
Alguém sabe como eu posso dividir corretamente uma Linestring programaticamente ao longo da linha da data com o OpenLayers? Eu procuro um código de exemplo, se você o tiver.
Eu tentei, wrapDateLine
mas ele não parece estar trabalhando em camadas vetoriais, apesar de minha camada vetorial ser assim:
vectorLayer = new OpenLayers.Layer.Vector("GroundTracks", {
renderers: ['Canvas', 'VML'],
wrapDateLine: true}); // <-- shoud be wraping.
Aqui está o meu 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);
Minha pergunta não é uma duplicata desta pergunta, porque eles querem saber como fazê-lo no ogr2ogr
Atualizar:
É assim que parece um conjunto de dados típico com o qual trabalho (faixa de satélite de 24 horas): O Linestring wkt pode ser encontrado AQUI .
fonte
Respostas:
O problema é que seu recurso não cruza a linha da data da perspectiva do OpenLayers; portanto, sua linha de divisão não cruza seu recurso. Exemplo de seus dados:
Você vai de -178 a 156, e isso não cruza a linha da data da perspectiva do OpenLayers. Em vez de dividir na linha da data, você deve dividir no seu valor mínimo de X.
Criei um exemplo aqui que dividiu com êxito sua trilha de satélite em 2 recursos: http://jsfiddle.net/6XJ5A/
Agora, para usar o WKT com várias linhas na sua atualização, em vez de usar uma linha reta, você deve percorrer todo o conjunto de dados e criar sua linha de divisão com todas as coordenadas que atravessam a linha de dados. Ao criar uma linha pequena dentro de uma multilinha, você pode dividir todas as coordenadas que devem atravessar a linha de dados. Aqui está o exemplo atualizado: http://jsfiddle.net/Jc274/
E o código:
Isso retornará uma linha dividida em todos os pontos que "cruzam" a linha de dados
Observe que eu também percorro as coordenadas para remover a linha que atravessa o mapa para conectar as 2 coordenadas:
Atualização: atualizei o primeiro exemplo para adicionar apenas a linha que foi dividida. Também atualizei a explicação de acordo. Essa abordagem não é à prova de balas com a faixa de satélite de 24 horas que você forneceu, mas estou trabalhando nela.
Atualização 2: atualizei o segundo exemplo. Ao usar uma multilinha para dividir e repetir o resultado para remover coordenadas extras adicionadas pela divisão, obtemos um conjunto de recursos que nunca passam pela linha de dados.
fonte
..., -178.475596 -81.673196, 156.248392 -81.611421,...
atravessa absolutamente a linha de dados. Veja aquiEncontrei uma ótima solução no github do @Dane. Chama-se Arc.js e serve para calcular rotas de círculo grande. Além disso, ele também dividirá a linha na linha de dados e fornecerá duas cadeias de linhas que se encontram na linha de dados, que os OpenLayers podem facilmente mapear. Espero que ele se apresente para reivindicar a recompensa.
Aqui estão os meus resultados:
fonte
A função splitWith não sabe sobre a forma tridimensional da Terra. Só opera em um mundo bidimensional. No seu caso, todas as suas
LINESTRING
coordenadas X estão entre -180 e 180. Portanto, da perspectiva bidimensional do OpenLayers, a sequência de linhas nunca cruza sua geometria dividida (a linha da data) e informa isso retornandonull
.Acredito que você precisará escrever um código personalizado para fazer a divisão. Estou imaginando um algoritmo que circula seus vértices, construindo seqüências de linhas de saída como esta:
Uma heurística razoável para determinar se um par de vértices cruza a linha da data é verificar se a diferença entre as coordenadas X é superior a 180 graus. (Embora isso possa dar errado, por exemplo, nas regiões polares. Talvez você tenha sorte o suficiente para não ter latitudes realmente altas.)
A operação de dividir um segmento em duas partes pode ser tão simples quanto a interpolação linear (se você não se importa muito com a precisão da pista). Quando você detecta que o segmento cruza a linha da data, copia o segundo vértice e move sua coordenada X (adicionando ou subtraindo 360 graus) e interpola a coordenada Y.
EDIT : Aqui está um JSFiddle que demonstra o algoritmo acima em seus dados: http://jsfiddle.net/85vjS/
fonte
Se funcionar com Greenwich, é porque você está dentro dos limites do seu CRS. Então, primeiro sugiro a mesma solução alternativa que você está apontando para a postagem:
e talvez
para o outro lado.
Outra solução é trabalhar em um CRS que não esteja "fora do limite" na linha de dados. Você deve poder dividir seus dados sem problemas.
fonte
LINESTRING(179.99 -89, 179.99 89)
eLINESTRING(-179.99 -89, -179.99 89)
sem sucesso. Com relação ao CRS, infelizmente, isso não funcionará para o meu propósito, porque estou mapeando trilhas de satélites que percorrem o mundo muitas vezes. Portanto, todos os CRSs estão divididos em algum lugar e terei o mesmo problema em qualquer lugar. Obrigado pela sua contribuição.