实体框架DbGeography未正确计算面积
本文关键字:计算 框架 DbGeography 实体 | 更新日期: 2023-09-27 18:20:24
如果我将WKT格式的多边形定义为(经度/纬度):
string wkt = "POLYGON ((15.981800258159638 45.810693408924287, 15.983624160289764 45.810783148865241, 15.983688533306122 45.809844611497965, 15.981843173503876 45.8096838246252, 15.981800258159638 45.810693408924287))"
并且我创建DbGeography
对象如下:
var polygon = System.Data.Entity.Spatial.DbGeography.FromText(wkt);
Area
属性的值为510065621695499.69
如果我这样使用Postgres和PostGis做同样的事情:
select ST_Area(ST_GeographyFromText(wkt))
结果是15496.7483872527,这应该是正确的值。
如果我通过反转坐标(纬度/经度)创建多边形,则DbGeography
和ST_Area
都返回相同的值(21247.6269483712)
有人能解释一下这里发生了什么吗?
附言:多边形位于克罗地亚的萨格勒布。
这与多边形方向有关。引用文档的话,对于这些空间数据类型,"椭球系统中多边形的内部由左侧规则定义"。请参阅(例如)这个问题,以及毫无疑问的许多其他问题,以获得进一步的阅读和解决这个问题的方法。
如果反转WKT中点的顺序,您将得到一个区域15496.7447813973
(使用对应于WGS84的4326 SRID),这与其他GIS系统提供的非常接近。我想这种差异可能是由于不同的SRID,但我远非专家。
请注意,您得到的错误结果非常接近510072000 km²,即整个地球的表面积-由于DbGeography
使用了它所使用的定向协议,它已经构建了您想要的多边形的外部。
要添加到AakashM的答案中,如果你总是想要更小的区域,你可以这样做:
public double GetArea(string wellKnownText)
{
var sqlGeo = SqlGeography.Parse(wellKnownText);
var normalArea = sqlGeo.STArea().Value;
var reorientedArea = sqlGeo.ReorientObject().STArea().Value;
// just trying to not return almost the whole area of our beloved planet...
return Math.Min(normalArea, reorientedArea);
}