简体   繁体   English

在C#中将UTM坐标解析为DBGeography

[英]Parsing UTM coordinates to DBGeography in C#

I'm writing a WinForms app in C#. 我正在用C#编写WinForms应用程序。 I need to ensure no two Datarow s in my Datatable are more than 100 km apart. 我需要确保我的Datatable中没有两个Datarow相距超过100公里。 Each row has a UTM Zone, Easting, and Northing in separate DataColumn s. 每行在单独的DataColumn都有一个UTM Zone,Easting和Northing。 All coordinates use the same datum, but some have different zones (otherwise, I would just use pythag math since UTMs are in metres). 所有坐标都使用相同的数据,但有些具有不同的区域(否则,我会使用pythag数学,因为UTM以米为单位)。 So far, I'm using the following code to do this, but it doesn't seem like my DbGeography.PointFromText method is working quite right (see * in the code), as when the code reaches the line of code with the '**' at the start of it, I get an error saying "24201: Latitude values must be between -90 and 90 degrees". 到目前为止,我使用以下代码来执行此操作,但似乎我的DbGeography.PointFromText方法工作DbGeography.PointFromText正常(请参阅代码中的*),就像代码到达代码行时' **'在它的开头,我得到一个错误说“24201:纬度值必须在-90到90度之间”。 I've also tried: 我也尝试过:

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

Only to have it complain that "There's no column # 17" (17 is my UTM Zone). 只是让它抱怨“没有列#17”(17是我的UTM区域)。

I've found very little documentation for using this stuff... as far as I can tell, my SRIDs are correct (I pulled them from this site ). 我发现使用这些东西的文档很少......据我所知,我的SRID是正确的(我从这个站点中取出它们)。 I've done this kind of thing using Lat+Longs before, and it worked wonderfully. 我之前使用Lat + Longs做过这种事情,并且效果非常好。 I just can't find proper syntax for the UTMs. 我找不到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;
        }
    }
}

In my quest to figure this out, I stumbled upon this post on a sister site here . 在我的追求摸不着头脑,我偶然发现了这个帖子上的姊妹网站在这里 I figure that DbGeography is based on SQL Server's geography data type, and DbGeometry likewise, geometry data type. 我认为DbGeography基于SQL Server的地理数据类型,而DbGeometry同样基于几何数据类型。

Some pertinent tidbits: 一些相关的花絮:

The geography datatype, EPSG:4326, is in degrees, which is why your POINT(257306 142708) is failing, as it falls out of the (-180,180), (-90,90) range. 地理数据类型EPSG:4326,以度为单位,这就是您的POINT(257306 142708)失败的原因,因为它超出了(-180,180),( - 90,90)范围。

... ...

The solution ... to use a geometry datatype instead, ie, projected, not geographic. 解决方案......使用几何数据类型,即投影,而不是地理。

And so I've changed my code to: 所以我把我的代码改为:

DataColumn dcGeom = new DataColumn("TrapGeom", typeof(DbGeometry));
...
dtTrap.Rows[i]["TrapGeom"] = DbGeometry.PointFromText(pointWellKnownText: stPoint, coordinateSystemId: SRID);

And it appears to parse just fine. 它似乎解析得很好。 Though, the last part of the post has me worried: 虽然,这篇文章的最后部分让我担心:

SQL Server insists on there being a SRID, even though you can't actually do anything useful with it, such as convert for one coordinate system to another. SQL Server坚持认为存在SRID,即使您实际上无法对其执行任何有用的操作,例如将一个坐标系转换为另一个坐标系。 It can get really confusing if you accidentally mix geometries with different SRIDs as you will simply get no results (witout warning, but this is an aside). 如果您不小心将几何图形与不同的SRID混合在一起会让您感到非常困惑,因为您将无法获得任何结果(没有警告,但这是暂且不谈的)。

And so, when I finally do if (Trap1.Distance(Trap2) > 100000) ... then I'm half-expecting it to malfunction when I have two different points in different SRIDs. 所以,当我最终做的时候if (Trap1.Distance(Trap2) > 100000) ...然后当我在不同的SRID中有两个不同的点时,我有一半期待它出现故障。 I'll test and write a comment on what I find. 我会测试并写下我发现的评论。

For better debugging of this error I recommend first checking your input data. 为了更好地调试此错误,我建议您先检查输入数据。

string point = "";
try
{
    string point = "POINT(" + dtTrap.Rows[i][intEastingIndex].ToString() + " " + dtTrap.Rows[i][intNorthingIndex].ToString() + ")";

    dtTrap.Rows[i]["TrapGeog"] = DbGeography.PointFromText(pointWellKnownText: point, coordinateSystemId: SRID);
}
catch (Exception ex)
{
    System.Diagnostics.Debug.WriteLine("correct point? " + point);
    if (ex.InnerException != null)
    {
        MessageBox.Show(ex.InnerException.Message + " at " + point);
    }
    else
    {
        MessageBox.Show(ex.Message);
    }
}

My guess is, there is some comma instead of a point or some spaces inside your string. 我的猜测是,你的字符串中有一些逗号而不是一个点一些空格

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM