Como o ArcGIS calcula a distância entre dois pontos com uma projeção não equidistante?

10

Esta é uma pergunta de acompanhamento da minha pergunta anterior. Você pode sugerir alguns textos introdutórios bem escritos sobre as projeções do sistema de coordenadas?


Vamos supor que estou trabalhando com a projeção de mapa CH1903, que, pelo que sei, é conforme, mas não equidistante. Significado, ângulos (forma) foram preservados, mas não áreas, distâncias ou escala. (Pelo menos estes não foram preservados exatamente ). Por enquanto, tudo bem.

Estou imaginando que tipo de cálculo o ArcGIS executa quando agora quero calcular a distância entre dois pontos. No ArcObjects, eu poderia usar a IProximityOperatorinterface da seguinte maneira:

IPoint a = ...,
       b = ...;

double distance = ((IProximityOperator)a).ReturnDistance(b);

Pergunta: Quando estou trabalhando com um sistema de referência que não preserva com precisão as distâncias, o que o ArcGIS faria quando eu consultasse a distância entre dois pontos (como mostrado acima)?

  • Simplesmente faz algumas matemáticas pitagóricas (a 2 + b 2 = c 2 ) para obter a distância, o que significa que a distância retornada será tão precisa quanto a projeção permitir?

  • Ou será algo mais complicado, como alguma forma de re-projeção, para obter uma distância mais precisa?

( A mesma pergunta, mas de maneira mais geral: uma vez que as geometrias foram projetadas, o ArcGIS executa todos os cálculos simplesmente no espaço euclidiano, ou a projeção de mapa usada ainda influencia os cálculos de distâncias, ângulos, áreas etc.?)

stakx
fonte
2
Crie uma nova pergunta em vez de modificar o seu original. Caso contrário, você subverte todos os mecanismos deste site: o que as classificações significam quando duas ou mais perguntas estão em jogo em um tópico? O que significaria marcar uma resposta como correta? Etc.
whuber
1
@ whuber: Embora tudo o que foi escrito neste tópico ainda esteja no tópico WRT, a pergunta original feita, concordo que agora existem realmente duas perguntas aqui. É tarde demais para mudar isso agora, mas manterá seus conselhos em mente para a próxima vez.
stakx

Respostas:

10

Se você deseja um método estável de calcular distâncias geodésicas, recomendo o invólucro de Richie Carmichael para o Projection Engine da ESRI .

Atualização: Eu apenas tentei o código de Richie com o ArcGIS 10.0 no Vista64 e recebi uma exceção depois de ligar LoadLibrary. Vou analisar isso mais tarde.

Por enquanto, porém, aqui está um código em resposta a perguntas nos comentários de outra resposta.

O código compara IProximityOperator para pontos com e sem referências espaciais. Em seguida, mostra como usar uma projeção equidistante azimutal (com o primeiro ponto sendo o ponto de tangência) para encontrar a grande distância do círculo.

private void Test()
{
    IPoint p1 = new PointClass();
    p1.PutCoords(-98.0, 28.0);

    IPoint p2 = new PointClass();
    p2.PutCoords(-78.0, 28.0);

    Debug.Print("Euclidian Distance {0}", EuclidianDistance(p1, p2));
    Debug.Print("Distance with no spatialref {0}", GetDistance(p1, p2));

    ISpatialReferenceFactory srf = new SpatialReferenceEnvironmentClass();
    IGeographicCoordinateSystem gcs =
    srf.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_WGS1984);

    p1.SpatialReference = gcs;
    p2.SpatialReference = gcs;

    Debug.Print("Distance with spatialref {0}", GetDistance(p1, p2));
    Debug.Print("Great Circle Distance {0}", GreatCircleDist(p1, p2));

}
private double GetDistance(IPoint p1, IPoint p2)
{
    return ((IProximityOperator)p1).ReturnDistance(p2);
}

private double EuclidianDistance(IPoint p1, IPoint p2)
{
    return Math.Sqrt(Math.Pow((p2.X - p1.X),2.0) + Math.Pow((p2.Y - p1.Y), 2.0));
}

private double GreatCircleDist(IPoint p1, IPoint p2)
{
    ISpatialReferenceFactory srf = new SpatialReferenceEnvironmentClass();
    IProjectedCoordinateSystem pcs =
    srf.CreateProjectedCoordinateSystem((int)esriSRProjCSType.esriSRProjCS_WGS1984N_PoleAziEqui);
    pcs.set_CentralMeridian(true, p1.X);
    ((IProjectedCoordinateSystem2)pcs).LatitudeOfOrigin = p1.Y;
    p1.SpatialReference = pcs.GeographicCoordinateSystem;
    p1.Project(pcs);
    p2.SpatialReference = pcs.GeographicCoordinateSystem;
    p2.Project(pcs);
    return EuclidianDistance(p1, p2);
}

Aqui está a saída:

Euclidian Distance 20
Distance with no spatialref 20
Distance with spatialref 20
Great Circle Distance 1965015.61318737

Eu acho que seria interessante testar isso contra a dll do mecanismo de projeção (pe.dll). Vou postar resultados se eu conseguir que o código de Richie funcione.

Atualização: Depois que alterei o código Richies para compilar para o x86, consegui executá-lo. Interessante ... a grande distância do círculo que me dá é 1960273.80162999 - uma diferença significativa da que retornou do método equidistante azimutal acima.

Kirk Kuykendall
fonte
A razão da discrepância é provável porque o segmento de linha (no PCS) que conecta os pontos não é uma geodésica projetada, que seria curvilínea quando projetada. Assim, você obtém um valor menor do que deveria. Um teste dessa teoria é simples: faça uma geodésica simples (como o equador) e compare dois cálculos da distância entre dois pontos amplamente separados na geodésica. Um é o cálculo direto, como no seu código; o outro divide a geodésica em segmentos, calcula diretamente os comprimentos dos segmentos e os soma. Este último deve ser mais preciso.
whuber
9

No ArcGIS 10, confira IGeometryServer2, que agora possui GetDistanceGeodesic (distância geodésica entre duas geometrias), GetLengthsGeodesic (retorna os comprimentos geodésicos de cada polilinha) e DensifyGeodesic (densifica uma polilinha plotando pontos ao longo das linhas geodésicas que conectam os vértices, usa IPolycurve4: : GeodesicDensify).

Como mencionado nas outras respostas, o ArcGIS ainda usa principalmente cálculos planares.

Melita Kennedy


Alguns comentários sobre as outras respostas (ainda não há representante suficiente para comentar diretamente!).

A projeção equidistante azimutal de Esri suporta elipsóides. O código GreatCircleDist está criando um PCS que usa um GCS baseado em elipsóide / esferóide. Assim, as distâncias do centro / ponto de origem serão distâncias geodésicas, e não grandes distâncias de círculo. Também poderia ser simplificado. Conhecemos as cordas projetadas do primeiro ponto, porque é o centro da projeção: 0,0. Portanto, apenas o segundo ponto precisa ser projetado. Uma função EuclidianDistance simplificada poderia então ser usada.

Eu verifiquei os resultados com as funções geodésicas do pe.dll e elas corresponderam. Parece que o aplicativo Richie está usando uma esfera, portanto está retornando grandes distâncias / coordenadas de círculo em seu aplicativo de teste. É por isso que os resultados não coincidem. Não reconheci os valores do raio; Eu acho que preciso falar com ele sobre isso!

mkennedy
fonte
2
Melita - Ótimo te ver aqui!
Kirk Kuykendall
1
Eu concordo, seja bem-vindo a bordo!
Matt Wilkie
8

A precisão de qualquer resposta sobre o ArcGIS está sujeita a alterações a qualquer momento - pelo que sabemos, novos procedimentos serão introduzidos no próximo service pack sem aviso ou documentação. Dito isto, o software ESRI há muito tempo usa cálculos euclidianos ( por exemplo , a fórmula pitagórica para distâncias) sempre que as coordenadas projetadas são usadas. Freqüentemente, em cálculos como o que você ilustra, o software nem sequer tem acesso às informações da projeção, então o que mais pode ser feito?

Sua própria pergunta parece sugerir que os cálculos da distância euclidiana para uma projeção equidistante estão corretos. Nada poderia estar mais longe da verdade. Para uma projeção equidistante de um ponto, a distância euclidiana ao ponto base é garantida como igual à distância geodésica; para uma projeção equidistante de dois pontos, a distância euclidiana a qualquer ponto base é garantida como igual à distância geodésica. Em troca dessas garantias, a distorção métrica entre todos os outros pares de pontos geralmente aumenta muito em comparação com outras projeções que se possa escolher.

whuber
fonte
@ whuber: Obrigado por responder. Com relação ao primeiro parágrafo: achei que o ArcGIS poderia ver que a projeção do mapa CH1903 (que usa o elipsóide Bessel 1841) é usada e, em seguida, projete os pontos de volta nesse elipsóide através do dado e, em seguida, faça os cálculos de distância no elipsóide. Pela sua resposta, entendo que o ArcGIS não fará tudo isso e permanecerá no espaço Euclidiano XY para fazer cálculos. (E quanto a outro software GIS?) - Parágrafo 2: Você está certo, é claro, obrigado por esclarecer esse ponto.
stakx
Um mecanismo de reprojeção oculto é possível apenas se os objetos de ponto mantiverem referências a uma projeção. Eu não acredito que eles fazem.
whuber
@ whuber: Seria suficiente (para cálculos mais precisos) conhecer o elipsóide usado para a projeção? AFAIK, ArcGIS armazena uma referência à projeção usada com cada classe de recurso (camada de dados).
stakx
1
Na verdade, o IPoint, que deriva de IGeometry, tem SpatialReference como uma propriedade. help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/… No entanto, não acho que ReturnDistance o use. Pode valer a pena testar para ver se isso mudou.
precisa saber é o seguinte
1
@stakx Atualizei minha resposta para incluir um código que mostra que a configuração de spatialref não tem impacto em ReturnDistance.
precisa saber é o seguinte