11

I need a function to calculate distance between point A and point B.

Namespace System.Spatial seems to be exactly what I need, but I can't figure how to use it.

IPoint is an interface that provides Latitude and Longitude, both of type double.

First try :

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

That ends with a NotImplementedExceptionon point1.Distance(point2). The message is in french, but basically it says "No operation registered. Please provide operation using property SpatialImplementation.CurrentImplementation.Operations".

Ok, I will try this then :

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

Now I got a NullReferenceException on SpatialImplementation.CurrentImplementation.Operations.

Msdn is not much verbose about this.

Anyone can explain how to get these implementations ?

Johnny5
  • 6,664
  • 3
  • 45
  • 78
  • How are you calling that method, and have you implemented `IPoint` interface with a class ? – Habib Sep 30 '13 at 13:56
  • Sure I have implemented it. It just provides latitude and longitude. The errors are exactly what I said. I'm calling this from unit test for now. – Johnny5 Sep 30 '13 at 13:59

1 Answers1

12

IMHO you shouldn't use System.Spatial. It's an half-baked library created for OData interoperability with Spatial, namely for WCF Data-Services.

You can check here for more information. Also, most of the classes on that library are abstract, hence up-to-you to be implement most-of-it.

Also, and even worse, they're incompatible with Entity Framework spatial support.

I'm not sure what kind of project you're on but I would suggest these guidelines:

  • if you just need to calculate distances between points just copy an implementation of the Haversine Formula or Vincenty's Formula in C#.

  • if you need spatial on DB just go with Entity Framework 5/6.

  • if you need further spatial operations in c# use something like NetTopologySuite. There's a NuGet for it and it's really simple to use.

Adam Maras
  • 26,269
  • 6
  • 65
  • 91
psousa
  • 6,676
  • 1
  • 32
  • 44
  • 1
    I dont need db support, at least for now. All caculation are made in-memory. I used the algorithm from this answer and it seems to give correct result : http://stackoverflow.com/a/6545031/607162. That said, I had preffered a .net provided algorithm. – Johnny5 Sep 30 '13 at 18:16
  • 1
    You can reference the SqlGeography/SqlGeometry types which are included on the Sql Server 2008/2012 types library, even without using a Database. They work perfectly fine on c#. – psousa Oct 01 '13 at 17:42
  • "_most of the classes on that library are abstract, hence up-to-you to be implement most-of-it._" - Hmm, not true at all. It is a bit of pain to create instances (and the docs suck). For anything but points, you need to do `SpatialBuilder.Create()` to get a builder then use the `GeographyPipeline` or `GeometryPipeline`. – mheyman Feb 05 '14 at 22:34