In che modo ArcGIS calcola la distanza tra due punti con una proiezione non equidistante?


10

Questa è una domanda di follow-up alla mia precedente, puoi suggerire alcuni testi introduttivi ben scritti sulle proiezioni del sistema di coordinate?


Supponiamo che sto lavorando con la proiezione cartografica CH1903, che per quanto ne so è conforme, ma non equidistante. Significato, angoli (forma) sono stati conservati, ma non aree, distanze o scala. (Almeno questi non sono stati conservati esattamente ). Fin qui tutto bene.

Mi chiedo che tipo di calcolo esegue ArcGIS quando ora voglio calcolare la distanza tra due punti. In ArcObjects, potrei usare l' IProximityOperatorinterfaccia come segue:

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

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

Domanda: quando lavoro con un sistema di riferimento che non conserva accuratamente le distanze, cosa farebbe ArcGIS quando lo interrogo per la distanza tra due punti (come mostrato sopra)?

  • Fa semplicemente alcuni calcoli pitagorici (a 2 + b 2 = c 2 ) per ottenere la distanza, il che significa che la distanza restituita sarà accurata solo quanto la proiezione lo consente?

  • O farà qualcosa di più complicato, come una qualche forma di riproiezione, per ottenere una distanza più precisa?

( La stessa domanda, ma più in generale: una volta che le geometrie sono state proiettate, ArcGIS esegue tutti i calcoli semplicemente nello spazio euclideo o la proiezione della mappa usata influenza ancora i calcoli di distanze, angoli, aree, ecc.?)


2
Crea una nuova domanda invece di modificare l'originale. Altrimenti, sovvertirai tutti i meccanismi di questo sito: cosa significano le valutazioni quando due o più domande sono in gioco in un thread? Cosa significherebbe contrassegnare una risposta come corretta? Ecc.
whuber

1
@whuber: Anche se tutto ciò che è stato scritto in questo thread è ancora in argomento WRT la domanda originale posta, concordo sul fatto che ora ci sono davvero due domande poste qui. È troppo tardi per cambiarlo adesso, ma terrò a mente i tuoi consigli per la prossima volta.
stakx,

Risposte:


10

Se vuoi un metodo stabile per calcolare le distanze geodetiche, raccomando il wrapper di Richie Carmichael per il motore di proiezione dell'ESRI .

Aggiornamento: ho appena provato il codice di Richie con ArcGIS 10.0 su Vista64 e ottengo un'eccezione dopo aver chiamato LoadLibrary. Ne esaminerò più avanti.

Per ora, però, ecco un po 'di codice in risposta alle domande nei commenti di un'altra risposta.

Il codice confronta IProximityOperator per punti con e senza riferimenti spaziali. Quindi mostra come usare una proiezione equidistante azimutale (con il primo punto è il punto di tangenza) per trovare la grande distanza del cerchio.

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);
}

Ecco l'output:

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

Penso che sarebbe interessante testarlo con il motore di proiezione dll (pe.dll). Pubblicherò i risultati se mai riuscirò a far funzionare il codice di Richie.

Aggiornamento: una volta modificato il codice Richies per la compilazione per x86, l'ho fatto funzionare. Interessante ... la grande distanza del cerchio che mi dà è 1960273.80162999 - una differenza significativa da quella restituita dal metodo equidistante azimutale sopra.


Il motivo della discrepanza è probabilmente dovuto al fatto che il segmento di linea (nel PCS) che collega i punti non è una geodetica proiettata, che sarebbe curvilinea quando proiettata. Di conseguenza, ottieni un valore inferiore a quello che dovresti. Un test di questa teoria è semplice: prendere un geodetico semplice (come l'equatore) e confrontare due calcoli della distanza tra due punti ampiamente separati sul geodetico. Uno è il calcolo diretto, come nel tuo codice; l'altro divide il geodetico in segmenti, calcola direttamente le lunghezze del segmento e le somma. Quest'ultimo dovrebbe essere più preciso.
whuber

9

In ArcGIS 10, controlla IGeometryServer2 che ora ha GetDistanceGeodesic (distanza geodetica tra due geometrie), GetLengthsGeodesic (restituisce le lunghezze geodetiche di ciascuna polilinea) e DensifyGeodesic (densifica una polilinea tracciando punti lungo le linee geodetiche che collegano i vertici, usa IPolycurve: : GeodesicDensify) metodi.

Come menzionato nelle altre risposte, ArcGIS utilizza ancora calcoli prevalentemente planari.

Melita Kennedy


Alcuni commenti sulle altre risposte (non ancora abbastanza rappresentante per commentare direttamente!).

La proiezione equidistante azimutale di Esri supporta gli ellissoidi. Il codice GreatCircleDist sta creando un PCS che utilizza un GCS basato su ellissoide / sferoide, pertanto le distanze dal centro / punto di origine saranno distanze geodetiche, non grandi distanze del cerchio. Potrebbe anche essere semplificato. Conosciamo le coordinate proiettate del primo punto perché è il centro della proiezione: 0,0. Quindi è necessario proiettare solo il secondo punto. È quindi possibile utilizzare una funzione semplificata di EuclidianDistance.

Ho controllato i risultati con le funzioni geodetiche del pe.dll e ho trovato una corrispondenza. Sembra che l'app di Richie stia usando una sfera, quindi sta restituendo grandi distanze / coordinate del cerchio nella sua applicazione di test. Ecco perché i risultati non corrispondono. Non ho riconosciuto i valori del raggio; Penso di averne bisogno di parlargli!


2
Melita - Fantastico vederti qui!
Kirk Kuykendall,

1
Sono d'accordo, benvenuto a bordo!
Matt Wilkie,

8

L'accuratezza di qualsiasi risposta su ArcGIS è soggetta a modifiche in qualsiasi momento: per quanto ne sappiamo, nel prossimo service pack verranno introdotte nuove procedure senza preavviso o documentazione. Detto questo, il software ESRI ha usato a lungo i calcoli euclidei ( ad es . La formula pitagorica per le distanze) ogni volta che vengono utilizzate le coordinate proiettate. Spesso, in calcoli come quello illustrato, il software non ha nemmeno accesso alle informazioni di proiezione, quindi cos'altro si può fare?

La tua stessa domanda sembra suggerire che i calcoli della distanza euclidea per una proiezione equidistante siano corretti. Nulla potrebbe essere più lontano dalla verità. Per una proiezione equidistante di un punto, la distanza euclidea dal punto base è garantita uguale alla distanza geodetica; per una proiezione equidistante a due punti, la distanza euclidea da uno dei due punti di base è garantita per eguagliare la distanza geodetica. In cambio di tali garanzie, la distorsione metrica tra tutte le altre coppie di punti è in genere notevolmente aumentata rispetto ad altre proiezioni che si potrebbero scegliere.


@whuber: Grazie per aver risposto. Per quanto riguarda il primo paragrafo: immaginavo che ArcGIS potesse vedere che veniva usata la proiezione cartografica CH1903 (che utilizza l'ellissoide di Bessel 1841), quindi proiettare i punti su quell'ellissoide tramite il riferimento, quindi fare calcoli di distanza sull'ellissoide. Dalla tua risposta prendo che ArcGIS non farà tutto questo e rimarrà nello spazio Euclideo XY per fare calcoli. (Che ne dici di altri software GIS?) - 2 ° paragrafo: Hai ragione ovviamente, grazie per aver chiarito questo punto.
stakx,

Un meccanismo di riproiezione nascosto è possibile solo se gli oggetti punto mantengono riferimenti a una proiezione. Non credo che lo facciano.
whuber

@whuber: Sarebbe sufficiente (per calcoli più precisi) conoscere l'ellissoide utilizzato per la proiezione? AFAIK, ArcGIS memorizza un riferimento alla proiezione utilizzata con ciascuna classe di caratteristiche (livello dati).
stakx,

1
In realtà IPoint, che deriva da IGeometry, ha SpatialReference come proprietà. help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/… Tuttavia, non credo che ReturnDistance lo utilizzi. Potrebbe valere la pena testarlo per vedere se è cambiato però.
Kirk Kuykendall,

1
@stakx Ho aggiornato la mia risposta per includere il codice che mostra che l'impostazione di spatialref non ha alcun impatto su ReturnDistance.
Kirk Kuykendall,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.