Melhores medições de distância na projeção Web Mercator

10

Estou trabalhando com uma pilha ESRI, armazenando minhas camadas em um banco de dados geodésico-SDE habilitado para sql-espacial (tipo Geometry, Web Mercator-3857).

Como estou criando um aplicativo de mapeamento da web, por padrão, os blocos também estão no web mercator, 3857.

Via procs armazenados, eu uso STDistance para consultar distâncias da localização de um usuário (coordena também no web mercator) até as várias camadas.

O problema é que, devido à distorção do web mercator, minhas distâncias estão cada vez mais afastadas, quanto mais distantes do equador são feitas.

Eu pensei em armazenar minhas camadas no tipo sql-spatial-geography (em vez de geometry), mas:

  • Imagino que minhas consultas à distância demorem muito mais (distâncias calculadas na superfície esférica)
  • precisarei reimportar muitos dados
  • os serviços arcgis não serão tão rápidos quanto precisarão projetar em tempo real

Se eu for ao Google Maps e fizer um cálculo de distância, a distância retornada será muito mais precisa, mesmo nas regiões Nortern / Southern, por isso presumo que o Google esteja corrigindo as distorções causadas pela projeção do web mercator.

Minha pergunta então: Existe um valor de fator simples que pode ser aplicado aos cálculos de distâncias feitos na projeção do web mercator para obter a distância "correta"?

Blomster
fonte

Respostas:

12

Para distâncias curtas, você pode multiplicar a distância calculada com cos(lat), uma vez que a escala da projeção do mercator é proporcional à secante da latitude (secante é 1/cos). Veja também http://en.wikipedia.org/wiki/Mercator_projection#Mathematics_of_the_projection


Adendo graças a @ jeremiah-england : embora a correção acima esteja correta quando se trata de projeções Mercator verdadeiras, o Web Mercator (EPSG: 3857) não é um Mercator. O EPSG chama isso de "Pseudo-Mercator". O problema é que ele usa o WGS84, um modelo elíptico, e o projeta usando cálculos esféricos de mercator (que o Google usou por serem mais rápidos). Se você dimensionar suas distâncias 1/cos(phi)com a web Mercator, terá cerca de 0,6% de desconto no equador. Veja a apresentação de Noel Zinn no Web Mercator para mais detalhes.

De acordo com a apresentação acima mencionada, o método a seguir pode ser usado para calcular distâncias mais precisas das coordenadas do web mercator. Dada dx- diferença de coordenadas horizontais (direção WE) e dy- diferença de coordenadas verticais (direção SN):

e = 0.081819191
adjustedX = dx * cos(lat) / sqrt(1 - e^2 * sin(lat)^2)
adjustedY = dy * cos(lat) * (1 - e^2) / pow(1 - e^2 * sin(lat)^2, 3/2)
adjustedDistance = hypot(adjustedX, adjustedY)

A razão entre esse ajuste e cos(lat)é maior na direção SN, variando do 0.9933equador aos 1.0034pólos. A relação de direção WE começa com 1no equador e cresce para 1.0034os pólos.

Observe que essa correção ainda funciona razoavelmente bem apenas para distâncias curtas, onde a geometria planar da superfície da Terra pode ser assumida.

mkadunc
fonte
1
E para distâncias maiores, você pode usar a latitude média dos dois pontos finais: o cos((l1 + l2)/2)que fornecerá a distância da linha de rumo / curso constante, em vez de uma distância de grande círculo.
MerseyViking 12/09
isso muda apenas o esferóide, mas não fornece a mesma precisão que uma projeção local.
falcacibar 12/09/11
1
@falcibar - eu não vejo como escolher a latitude média muda o esferóide
mkadunc
@ JerseyViking: obrigado, esqueci de mencionar que a melhor latitude a ser usada no cálculo seria a média dos dois pontos comparados.
mkadunc 12/09
1
+1 para a resposta. @ Jersey: Por que a correção de latitude média funciona? Afinal, as distorções no Mercator podem se tornar arbitrariamente grandes e as partidas dos loxodromos da geodésica também podem ser grandes. Parece que existem alguns erros potencialmente enormes que poderiam ser cometidos pelos quais uma simples correção não seria confiável.
whuber
6

Eu consideraria sua segunda opção de armazenar seus dados no GEOGRAPHYformato novamente se você estiver procurando resultados precisos em dados globais.

Não há nada que o impeça de ter dois campos espaciais em uma tabela - um no Mercator como um GEOMETRYtipo e um no WGS84 como um GEOGRAPHYtipo (pelo menos não no SQL Server, não tenho certeza sobre o ArcSDE).

Você deve conseguir criar um script de geoprocessamento simples que preencherá os dois campos com seus dados originais. Se houver edição e atualizações frequentes em andamento, isso pode não ser uma opção.

Depois de ter os dois campos, você pode continuar usando o Mercator para exibição rápida e converter os pontos inseridos pelo usuário em Lat / Lon para distâncias.

Isso tem duas vantagens principais:

  • você também pode obter áreas e comprimentos de recursos mais precisos com base nas consultas do usuário
  • você não precisa se preocupar em adicionar um código personalizado para cada consulta que lida com medições

As velocidades da consulta serão mais complexas, mas podem ser imperceptíveis para um usuário. Você pode testar com uma classe de recurso antes de decidir sobre uma solução. Você também terá que converter os pontos inseridos pelo usuário no Mercator (o que deve ser trivial e pode ser feito no navegador).

Mesmo com o tipo de região, embora ainda haja uma margem de erro:

A tolerância a erros para os métodos de geografia pode ser tão grande quanto as extensões 1.0e-7 *

Do MSDN

geographika
fonte
Infelizmente, o SDE permitirá apenas uma coluna espacial: help.arcgis.com/en/arcgisdesktop/10.0/help/index.html#//… - Não tentei criar uma exibição e registrá-la na SDE, mas isso pode ser uma abordagem possível.
Allan Adair
@ Allan - bom saber. Outro ponto positivo para usar o SDE então! Uma tabela com apenas a geometria 4326 e uma junção de volta para a tabela original + visão espacial deve alcançar a mesma finalidade
geographika
3

Uma sugestão alternativa da ESRI é usar um "serviço de geometria", que envolve o envio das geometrias para um ArcGIS Server e a devolução do resultado. Se você não espera problemas de gargalo usando um serviço da Web, isso pode ser uma abordagem muito eficaz. Eu usei a mesma abordagem em um aplicativo Silverlight.

Aqui está uma entrada de blog original da ESRI: http://blogs.esri.com/Dev/blogs/arcgisserver/archive/2010/03/05/Measuring-distances-and-areas-when-your-map-uses-the -Mercator-projection.aspx

No blog, há um exemplo de JavaScript simplificado e também um aplicativo de exemplo completo aqui: http://serverapps.esri.com/javascript_examples/compare_measurements.htm

Allan Adair
fonte
0

Como o Google Earth faz, você pode transformar a geometria em uma projeção de zona WGS84 local ou uma projeção WGS84 aprimorada como SIRGAS na América do Sul.

Você pode procurar em http://www.spatialreference.org as coordenadas de quase todas as projeções "zonificadas" e criar uma tabela etc. para transformá-las, dependendo da zona.

Nós imaginamos uma zona de mesa

|   minx     |    miny    |    maxx    |   maxy     |  srid  |
+------------+------------+------------+------------+--------+
|234567.34314|234567.34334|234567.34334|234567.34334|  1234  |

todos os valores minx, miny, maxx, maxy armazenados no Spherical Mercator (Web Mercator). então eu vou usar postgis como exemplo.

SELECT ST_Distance(
         ST_Transform( -- transform/reproject
            ST_SetSRID(geom_line, 3857) -- geom_line with forced srid assignation to web mercator
            , ( -- here we get the first SRID from the spatial position of geom_line
                 SELECT  srid
                 FROM    zones
                 WHERE   ST_Contains(
                           ST_MakeBox2d(ST_Point(minx,miny),ST_Point(maxx,maxy))
                           , geom_line
                         )
                 LIMIT 1
            ))

Espero que isso seja útil, tenha um bom dia.

falcacibar
fonte
Não tenho certeza, mas com base no uso de "STDistance" por Blomster em sua pergunta, parece que ele não está usando o PostGIS. Se o Blomster estiver usando o SQL Server, não haverá funcionalidade ST_Transform.
Allan Adair
Dou o processo e a melhor maneira de resolvê-lo, ele poderia lidar com o resto, de qualquer maneira, ele poderia usar uma reprojeção de software, mas é realmente uma pena que um SQL Server não lide com projeções.
falcacibar 12/09/11
talvez o CLR ativado e o nettopologysuite da biblioteca .net possam ajudar?
falcacibar 12/09