Como posso fazer um envoltório de polilinha em todo o mundo?

14

Estou usando mapas de folhetos para criar uma representação de um desafio de volta ao mundo. Gostaria de adicionar uma polilinha que segue para leste a partir de Tóquio e depois aparece a oeste da América do Sul no mapa - mas, em vez disso, recebo uma linha que atravessa o mapa na direção oposta (veja a linha amarela).

insira a descrição da imagem aqui

Eu acho que isso provavelmente está relacionado a datelines e / ou sistemas de coordenadas, mas estou um pouco superficial nos detalhes. Alguém pode explicar a teoria por trás do que eu preciso fazer para que isso funcione? Estou usando a projeção bluemarble da 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
fonte
2
Você precisa quebrar a polilinha no meridiano de + -180 graus. Isso requer encontrar a latitude na qual a polilinha cruza esse meridiano. Seu GIS provavelmente tem métodos para fazer a quebra. Caso contrário, uma solução simples pode ser derivada do código mostrado em um thread relacionado . Você é capaz de executar códigos como este em sua plataforma?
whuber
Eu concordo com o whuber. Eu tive que executar uma tarefa semelhante com polígonos cruzando + - 180. Você precisa se dividir em várias polilinhas / polígonos cada vez que cruza o + -180.
Steve Steve

Respostas:

13

Você precisa quebrar a polilinha no meridiano de + -180 graus. Isso requer encontrar a latitude na qual a polilinha cruza esse meridiano. Seu GIS provavelmente tem métodos para fazer a quebra. Caso contrário, uma solução simples pode ser derivada do código mostrado em um thread relacionado . Aqui estão alguns detalhes.

  • Uma polilinha é representada como uma sequência de vértices , cada um dado na forma (lat, lon), com -180 <= lon <= 180. Você precisa verificar cada par sucessivo para ver se cruza o meridiano + -180. Há um teste rápido: se o valor absoluto da diferença de longitudes for 180 ou superior, haverá um cruzamento.

  • Dentro de cada segmento (lat0, lon0) -> (lat1, lon1) que cruza o meridiano + -180, é necessário dividir a polilinha em duas partes onde ela cruza.

A chave é encontrar a latitude do ponto de interrupção com precisão razoável. Isso é feito com mais facilidade com um modelo de terra esférico: o erro (comparado a um modelo elipsoidal mais preciso) será muito pequeno para ser observado.

Deixe o segmento em questão ir do ponto 0 em (lat0, lon0) ao ponto 1 em (lat1, lon1). O ponto de interrupção pode ser encontrado executando um segmento de linha reta em 3D entre os dois pontos, conforme representado nas coordenadas cartesianas e localizando onde a coordenada y é zero. As coordenadas cartesianas são

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

e uma expressão semelhante dando (x1, y1, z1) para o ponto 1. Resolva a equação

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

para t; isso é,

t = y1 / (y1 - y0).

As coordenadas da interseção são, portanto,

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

Este ponto (que fica abaixo da superfície da Terra em algum lugar abaixo do meridiano + -180) tem latitude igual a

lat2 = ATan(z/x).

O ponto de interrupção precisa ser representado de duas maneiras. Ao anexá-lo após (lat0, lon0) para finalizar a primeira parte da polilinha quebrada, use (lat2, -180) se lon0 for negativo e use (lat2, 180). Ao anexá-lo antes (lat1, lon1) para iniciar a segunda parte da polilinha quebrada, siga uma regra semelhante.

Em casos excepcionais, um ou ambos os pontos 0 e 1 podem estar no meridiano + -180. Seguir este procedimento fará com que você coloque um segmento de comprimento zero em uma das peças de polilinha criadas. Se isso puder causar um problema com o GIS, teste para esta condição.

Observe que uma polilinha pode cruzar esse meridiano mais de uma vez. Portanto, depois de encontrar a primeira quebra e dividir a polilinha em duas partes, é necessário processar a segunda parte da mesma maneira.

whuber
fonte
1
O que o whuber disse está OK, mas acho que há um erro de digitação na seguinte frase:> Ao anexá-lo após (lat0, lon0) para finalizar a primeira parte da polilinha> quebrada, use (lat2, -180) se lat0 for negativo e caso contrário, use (lat2, 180). Eu acho que deve ser:> uso (Lat2, -180) se lon0 é negativo e outro uso (Lat2, 180)
Georgi
@ Georgi Obrigado por capturar isso; Eu acho que você está certo e eu farei a mudança.
whuber
Eu tive que implementar isso no Leaflet.js, aqui está o meu código: gist.github.com/mikeatlas/0b69b354a8d713989147 #
Mike Atlas
Obrigado, Mike. Adoro a ilustração em zigue-zague: esse é exatamente o tipo de circunstância que eu estava imaginando enquanto escrevia essa resposta. Se você deseja um teste realmente severo, veja o que acontece com uma polilinha que percorre o próprio meridiano de + -180 graus (e cruza os dois pólos)!
whuber
@whuber Talvez eu precise tentar isso: / Publicarei resultados #
Mike Atlas
0

Para uma discussão relacionada, talvez esse ticket seja interessante:

"a projeção vetorial sobre o limite da quebra automática é dividida"

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

markusN
fonte