我正在用C#编写WinForms应用程序.我需要确保Datarow我Datatable的距离不超过100公里.每行在单独的DataColumns中具有UTM区域,东区和北区.所有坐标都使用相同的数据,但有些具有不同的区域(否则,我会使用pythag数学,因为UTM以米为单位).到目前为止,我正在使用以下代码来执行此操作,但似乎我的DbGeography.PointFromText方法工作得不正常(请参阅代码中的*),因为当代码到达带有'**'的代码行时在它的开头,我得到一个错误说"24201:纬度值必须介于-90和90度之间".我也尝试过:
dtTrap.Rows[i]["TrapGeog"] = DbGeography.PointFromText(pointWellKnownText: "POINT M(" + dtTrap.Rows[i][intEastingIndex].ToString() + " " + dtTrap.Rows[i][intNorthingIndex].ToString() + " " + dtTrap.Rows[i][Zone].ToString() + ")", coordinateSystemId: SRID);
Run Code Online (Sandbox Code Playgroud)
只是让它抱怨"没有列#17"(17是我的UTM区域).
我发现使用这些东西的文档很少......据我所知,我的SRID是正确的(我从这个站点中取出它们).我之前使用Lat + Longs做过这种事情,并且效果非常好.我找不到UTM的正确语法.
using System.Data.Entity.Spatial;
...
DataColumn dcGeog = new DataColumn("TrapGeog", typeof(DbGeography));
dtTrap.Columns.Add(dcGeog);
byte Zone;
Int16 SRID;
for (int i = 0; i < dtTrap.Rows.Count; ++i)
{
if (dtTrap.Rows[i][intZoneIndex] != null
&& dtTrap.Rows[i][intNorthingIndex] != null
&& dtTrap.Rows[i][intEastingIndex] != null
&& byte.TryParse(dtTrap.Rows[i][intZoneIndex].ToString(), out Zone) == true)
{
if (Zone == 15) { SRID = 26915; }
else if (Zone == 16) { SRID = 26916; }
else if (Zone == 17) { SRID = 26917; }
else { SRID = 26918; }
// shove it in:
try
{
*dtTrap.Rows[i]["TrapGeog"] = DbGeography.PointFromText(pointWellKnownText: "POINT(" + dtTrap.Rows[i][intEastingIndex].ToString() + " " + dtTrap.Rows[i][intNorthingIndex].ToString() + ")", coordinateSystemId: SRID);
}
catch (Exception ex)
{
if (ex.InnerException != null)
{
**MessageBox.Show(ex.InnerException.Message);
}
else
{
MessageBox.Show(ex.Message);
}
}
}
}
for (int i = 0; i < dtTrap.Rows.Count - 1; ++i)
{
for (int k = i + 1; k < dtTrap.Rows.Count; ++i)
{
DbGeography iTrap = (DbGeography)dtTrap.Rows[i]["TrapGeog"];
DbGeography kTrap = (DbGeography)dtTrap.Rows[k]["TrapGeog"];
if (iTrap.Distance(kTrap) > 100000)
{
sbErrorsAndWarningsLog.Append(@"Warning: Line number " + (i + 2).ToString() + " on the Trap spreadsheet has coordinates that are at least 100 km away from row " + (k + 2).ToString() + "'s point. Please check that these coordinates are correct.").AppendLine();
boolWarningsFound = true;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的追求摸不着头脑,我偶然发现了这个帖子上的姊妹网站在这里.我认为这DbGeography是基于SQL Server的地理数据类型,DbGeometry同样也是几何数据类型.
一些相关的花絮:
地理数据类型EPSG:4326,以度为单位,这就是您的POINT(257306 142708)失败的原因,因为它超出了(-180,180),( - 90,90)范围.
...
解决方案......使用几何数据类型,即投影,而不是地理.
所以我把我的代码改为:
DataColumn dcGeom = new DataColumn("TrapGeom", typeof(DbGeometry));
...
dtTrap.Rows[i]["TrapGeom"] = DbGeometry.PointFromText(pointWellKnownText: stPoint, coordinateSystemId: SRID);
Run Code Online (Sandbox Code Playgroud)
它似乎解析得很好.虽然,这篇文章的最后部分让我担心:
SQL Server坚持认为存在SRID,即使您实际上无法对其执行任何有用的操作,例如将一个坐标系转换为另一个坐标系.如果您不小心将几何图形与不同的SRID混合在一起会让您感到非常困惑,因为您将无法获得任何结果(没有警告,但这只是一个旁边).
所以,当我最终做到的时候if (Trap1.Distance(Trap2) > 100000)...当我在不同的SRID中有两个不同的点时,我只是期待它出现故障.我会测试并写下我发现的评论.