2013-09-30 6 views
5

ho bisogno di una funzione per calcolare la distanza tra il punto A e il punto B.Come utilizzare System.Spatial.GeographyPoint

Namespace System.Spatial sembra essere esattamente quello che mi serve, ma io non riesco a capire come usarlo.

IPoint è un'interfaccia che fornisce Latitude e Longitude, entrambi di tipo double.

Prima prova:

public static double CalculateDistance(IPoint pointA, IPoint pointB) 
    { 
    var gp1 = GeographyPoint.Create(pointA.Latitude, pointA.Longitude); 
    var gp2 = GeographyPoint.Create(pointB.Latitude, pointB.Longitude); 

    return gp1.Distance(gp2) ?? 0; 
    } 

che termina con un NotImplementedException su point1.Distance(point2). Il messaggio è in francese, ma in pratica dice "Nessuna operazione registrata. Fornisci l'operazione utilizzando la proprietà SpatialImplementation.CurrentImplementation.Operations".

Ok, cercherò questo allora:

public static double CalculateDistance(IPoint pointA, IPoint pointB) 
{ 
    var gp1 = GeographyPoint.Create(pointA.Latitude, pointA.Longitude); 
    var gp2 = GeographyPoint.Create(pointB.Latitude, pointB.Longitude); 

    return SpatialImplementation.CurrentImplementation.Operations.Distance(gp1, gp2); 
} 

ora ho un NullReferenceException su SpatialImplementation.CurrentImplementation.Operations.

Msdn non è molto dettagliato.

Chiunque può spiegare come ottenere queste implementazioni?

+0

Come si chiama quel metodo e si è implementata l'interfaccia 'IPoint' con una classe? – Habib

+0

Certo che l'ho implementato. Fornisce solo latitudine e longitudine. Gli errori sono esattamente ciò che ho detto. Sto chiamando questo da unit test per ora. – Johnny5

risposta

4

IMHO non utilizzare System.Spatial. È una libreria semi-cotta creata per l'interoperabilità OData con Spatial, in particolare per WCF Data-Services.

È possibile controllare here per ulteriori informazioni. Inoltre, la maggior parte delle classi su quella libreria sono astratte, quindi up-to-you per essere implementato la maggior parte di esso.

Inoltre, e ancor peggio, sono incompatibili con il supporto spaziale di Entity Framework.

io non sono sicuro di che tipo di progetto si è in ma vorrei suggerire queste linee guida:

  • se avete solo bisogno di calcolare le distanze tra i punti basta copiare e un'implementazione del Haversine Formula o Vincenty's Formula in C#.

  • se avete bisogno di spazio su DB basta andare con Entity Framework 5/6.

  • se sono necessarie ulteriori operazioni spaziali in C# utilizzare qualcosa come NetTopologySuite. C'è un NuGet per questo ed è davvero semplice da usare.

+1

Non ho bisogno del supporto per db, almeno per ora. Tutte le caculazioni sono fatte in memoria. Ho usato l'algoritmo di questa risposta e sembra dare un risultato corretto: http://stackoverflow.com/a/6545031/607162. Detto questo, avevo preffettato un algoritmo fornito da .net. – Johnny5

+1

È possibile fare riferimento ai tipi SqlGeography/SqlGeometry inclusi nella libreria dei tipi di Sql Server 2008/2012, anche senza utilizzare un database. Funzionano perfettamente bene su C#. – psousa

+0

"_most delle classi su quella libreria sono astratte, quindi up-to-you per essere implementato la maggior parte di esso._" - Hmm, non vero affatto.È un po 'difficile creare istanze (e i documenti fanno schifo). Per tutto tranne i punti, devi fare 'SpatialBuilder.Create()' per ottenere un builder quindi usare 'GeographyPipeline' o' GeometryPipeline'. – mheyman