2013-09-30 2 views
5

Ich brauche eine Funktion Abstand zwischen Punkt A zu berechnen und zu Punkt B.So verwendet System.Spatial.GeographyPoint

Namespace System.Spatial scheint genau das zu sein, was ich brauche, aber ich kann nicht verstehen, wie es zu benutzen.

IPoint ist eine Schnittstelle, die Latitude und Longitude beide vom Typ double bietet.

Erster Versuch:

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

, die mit einem NotImplementedException auf point1.Distance(point2) endet. Die Nachricht ist in Französisch, aber im Grunde sagt es "Keine Operation registriert. Bitte bieten Sie Betrieb mit Eigenschaft SpatialImplementation.CurrentImplementation.Operations".

Ok, werde ich dies dann versuchen:

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

Jetzt habe ich eine NullReferenceException auf SpatialImplementation.CurrentImplementation.Operations.

Msdn ist nicht viel wortreich darüber.

Jeder kann erklären, wie man diese Implementierungen bekommt?

+0

Wie rufen Sie diese Methode an, und haben Sie die "IPoint" -Schnittstelle mit einer Klasse implementiert? – Habib

+0

Sicher habe ich es implementiert. Es bietet nur Breiten- und Längengrad. Die Fehler sind genau das, was ich gesagt habe. Ich rufe das jetzt aus dem Komponententest an. – Johnny5

Antwort

4

IMHO sollten Sie nicht System.Spatial verwenden. Es handelt sich um eine halbfertige Bibliothek, die für die Interoperabilität von OData mit Spatial erstellt wurde, nämlich für WCF Data-Services.

Sie können here für weitere Informationen überprüfen. Außerdem sind die meisten Klassen in dieser Bibliothek abstrakt, daher ist es am wichtigsten, sie am meisten zu implementieren.

Außerdem und noch schlimmer, sie sind nicht mit der räumlichen Unterstützung von Entity Framework kompatibel.

Ich bin mir nicht sicher, welche Art von Projekt sind Sie auf, aber ich würde diese Richtlinien empfehlen:

  • , wenn Sie müssen nur Abstände zwischen den Punkten berechnen nur eine Implementierung der Haversine Formula oder Vincenty's Formula kopieren in C#.

  • Wenn Sie Spatial auf DB benötigen, gehen Sie einfach mit Entity Framework 5/6.

  • Wenn Sie weitere räumliche Operationen in C# benötigen, verwenden Sie so etwas wie NetTopologySuite. Es gibt ein NuGet dafür und es ist wirklich einfach zu benutzen.

+1

Ich brauche nicht db Unterstützung, zumindest für jetzt. Alle Berechnungen werden im Speicher ausgeführt. Ich habe den Algorithmus aus dieser Antwort verwendet und es scheint das richtige Ergebnis zu geben: http://stackoverflow.com/a/6545031/607162. Allerdings hatte ich einen .net bereitgestellten Algorithmus vorgezogen. – Johnny5

+1

Sie können auf die SqlGeography/SqlGeometry-Typen verweisen, die in der Sql Server 2008/2012-Typenbibliothek enthalten sind, auch ohne eine Datenbank zu verwenden. Sie funktionieren perfekt auf C#. – psousa

+0

"_meisten der Klassen in dieser Bibliothek sind abstrakt, daher ist es am wichtigsten, das meiste davon zu implementieren._" - Hmm, stimmt überhaupt nicht.Es ist ein bisschen mühsam, Instanzen zu erstellen (und die Docs saugen). Für alles außer Punkte müssen Sie 'SpatialBuilder.Create()' ausführen, um einen Builder zu erhalten, und dann die 'GeographyPipeline' oder' GeometryPipeline' verwenden. – mheyman

Verwandte Themen