如何使用System.Spatial.GeographyPoint

How to use System.Spatial.GeographyPoint
2021-06-10
  •  译文(汉语)
  •  原文(英语)

我需要一个函数来计算A点和B点之间的距离.

命名空间System.Spatial似乎正是我所需要的,但是我不知道如何使用它.

IPoint是,提供了一个接口LatitudeLongitude,这两个类型的double.

第一次尝试 :

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

NotImplementedExceptionon结尾point1.Distance(point2).该消息以法语显示,但基本上显示为"未注册任何操作.请使用属性SpatialImplementation.CurrentImplementation.Operations提供操作".

好的,那我可以试试看:

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

现在,我得到了一个NullReferenceExceptionSpatialImplementation.CurrentImplementation.Operations.

Msdn对此并不十分冗长.

任何人都可以解释如何获得这些实现?

速聊1:
您如何调用该方法,并实现了IPoint与类的接口?
速聊2:
当然,我已经实施了.它仅提供纬度和经度.错误正是我所说的.我现在从单元测试中称呼它.
解决过程1

恕我直言,你不应该使用System.Spatial.它是为OData与Spatial的互操作性而创建的半生库,即为WCF数据服务而创建的.

您可以在此处查看更多信息.同样,该库上的大多数类都是抽象的,因此您可以自行实现大多数.

而且,甚至更糟的是,它们与Entity Framework空间支持不兼容.

我不确定您正在从事哪种项目,但我建议您遵循以下准则:

  • 如果只需要计算点之间的距离,则只需复制C#中Haversine公式Vincenty公式的实现即可.

  • 如果您需要DB上的空间,请使用Entity Framework 5/6.

  • 如果需要在C#中进行进一步的空间运算,请使用NetTopologySuite之类的东西.有一个NuGet,它的使用非常简单.

速聊1:
我不需要数据库支持,至少现在是这样.所有计算都在内存中进行.我从这个答案中使用了算法,它似乎给出了正确的结果:stackoverflow.com/a/6545031/607162.就是说,我喜欢.net提供的算法.
速聊2:
即使不使用数据库,也可以引用SqlServer 2008/2012类型库中包含的SqlGeography / SqlGeometry类型.他们在C#上运行良好.
速聊3:
"该库上的大多数类都是抽象的,因此要由您来实现大部分."-嗯,一点都不正确.创建实例(文档很烂)有点麻烦.对于除点以外的任何内容,您都需要SpatialBuilder.Create()获取构建器,然后使用GeographyPipelineGeometryPipeline.

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 ?

Talk1:
How are you calling that method, and have you implemented IPoint interface with a class ?
Talk2:
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.
Solutions1

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.

Talk1:
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 : stackoverflow.com/a/6545031/607162. That said, I had preffered a .net provided algorithm.
Talk2:
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#.
Talk3:
"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.
转载于:https://stackoverflow.com/questions/19095985/how-to-use-system-spatial-geographypoint

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入