ArcGIS如何计算非等距投影的两点之间的距离?


10

这是我上一个问题的后续问题,您能提出一些有关坐标系统投影的写得很好的入门文章吗?


假设我正在使用CH1903地图投影,就我所知,这是共形的,但不是等距的。意思是,保留了角度(形状),但没有保留面积,距离或比例。(至少这些未完全保留)。到目前为止,一切都很好。

我想知道现在要计算两点之间的距离时,ArcGIS会执行哪种计算。在ArcObjects中,我可以使用如下IProximityOperator界面

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

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

问题:当我使用的基准系统无法准确保留距离时,当我查询两点之间的距离时,ArcGIS将如何处理(如上所示)?

  • 它是否只是做一些勾股数学(a 2 + b 2 = c 2)以获取距离,这意味着返回的距离将仅与投影所允许的精度一样?

  • 还是会做一些更复杂的事情(例如某种形式的重新投影)以获得更准确的距离?

这是一个相同的问题,但更笼统地说:一旦投影了几何图形,ArcGIS是否仅在欧几里得空间中执行所有计算,还是使用的地图投影仍然会影响距离,角度,面积等的计算?)


2
请创建一个新问题,而不要修改原始问题。否则,您将破坏该站点上的所有机制:当一个线程中有两个或多个问题在进行时,评分是什么意思?将一个答案标记为正确的意思是什么?等等
ub

1
@whuber:尽管在该线程中编写的所有内容仍是原始WRT主题,但我同意这里确实有两个问题。现在改变这一点为时已晚,但是下次将牢记您的建议。
stakx

Answers:


10

如果您想要一种稳定的测地距离计算方法,我推荐Richie Carmichael的ESRI投影引擎包装器

更新:我刚刚在Vista64上使用ArcGIS 10.0尝试了Richie的代码,并在调用后得到了异常LoadLibrary。我会在以后再研究。

现在,这里是一些代码,用于回答另一个答案的注释中的问题。

该代码比较IProximityOperator是否具有空间参考点。然后说明如何使用方位角等距投影(第一个点为切点)找到大圆弧距离。

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

这是输出:

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

我认为对投影引擎dll(pe.dll)进行测试会很有趣。如果我能使用Richie的代码,它将发布结果。

更新: 将Richies代码更改为针对x86进行编译后,就可以运行它。有趣的是...它给我的大圆弧距离是1960273.80162999-与上面的方位等距方法返回的明显不同。


出现差异的原因可能是因为连接点的线段(在PCS中)不是投影的测地线,投影时测地线是曲线的。因此,您得到的值比您应获得的要小。对该理论进行测试很容易:采用一个简单的测地线(例如赤道),比较测地线上两个相距很远的点之间的距离的两次计算。一种是直接计算,如您的代码所示;另一个将测地线分解成线段,直接计算线段长度,并将其加起来。后者应该更准确。
ub

9

在ArcGIS 10中,检出IGeometryServer2,该IGeometryServer2现在具有GetDistanceGeodesic(两个几何之间的测地距离),GetLengthsGeodesic(返回每个折线的测地线长度)和DensifyGeodesic(通过沿着连接顶点的测地线绘制点来使折线变密,请使用IPolycurve4: :GeodesicDensify)方法。

如其他答案所述,ArcGIS仍然主要使用平面计算。

梅利塔·肯尼迪(Melita Kennedy)


对其他答案的一些评论(尚不足以直接评论!)。

Esri的方位角等距投影支持椭球。GreatCircleDist代码正在创建一个使用基于椭球/椭球的GCS的PCS,因此距中心/原点的距离将是测地距离,而不是大的圆距离。也可以简化。我们知道第一个点的投影坐标,因为它是投影的中心:0,0。因此,仅需要投影第二点。然后可以使用简化的EuclidianDistance函数。

我对照pe.dll的短程测量函数检查了结果,结果是否匹配。看起来Richie的应用程序正在使用球体,因此它在其测试应用程序中返回了很大的圆距离/坐标。这就是为什么结果不匹配的原因。我不认识半径值。我想我需要和他谈谈!


2
梅利塔-很高兴在这里见到你!
Kirk Kuykendall 2010年

1
我同意,欢迎您的光临!
马特·威尔基

8

关于ArcGIS的任何答案的准确性随时可能更改-众所周知,新的过程将在下一个Service Pack中引入,而不会发出警告或提供文档。就是说,无论何时使用投影坐标,ESRI软件都长期使用欧几里得计算(例如,距离的毕达哥拉斯公式)。通常,在像您所说明的那样的计算中,该软件甚至无法访问投影信息,那么还有什么可以做的呢?

您的问题本身似乎表明等距投影的欧几里得距离计算是正确的。没有东西会离事实很远。对于单点等距投影,保证到基点的欧几里得距离等于测地线距离;对于两点等距投影,可以保证到任一基点的欧几里得距离等于测地线距离。作为这些保证的回报,与其他选择相比,所有其他成对点之间的度量失真通常会大大增加。


@whuber:感谢您的回答。关于第一段:我认为ArcGIS可能会使用CH1903地图投影(使用Bessel 1841椭球),然后通过基准将点投影回到该椭球上,然后在椭球上进行距离计算。根据您的回答,我认为ArcGIS不会做所有事情,而是会保留在Euclidean XY空间中进行计算。(其他GIS软件呢?)- 第二段:当然,您是正确的,感谢您阐明了这一点。
stakx

仅当点对象维护对投影的引用时,才可以使用隐藏的重新投影机制。我不相信他们。
ub

@whuber:知道投影所用的椭球是否足够(为了更精确的计算)?在AFAIK中,ArcGIS将每个要素类(数据层)的参考存储到使用的投影中。
stakx 2010年

1
实际上,从IGeometry派生的IPoint具有SpatialReference作为属性。help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp / ...但是,我不认为ReturnDistance使用它。也许值得测试一下是否有所改变。
Kirk Kuykendall,2010年

1
@stakx我已经更新了我的答案,以包含表明设置spacealref对ReturnDistance没有影响的代码。
Kirk Kuykendall
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.