Парсинг координат UTM в DBGeography на языке C#
Я пишу приложение WinForms на C#. Мне нужно убедиться, что никакие два Datarow
s в моем Datatable
не находятся более чем в 100 км друг от друга. Каждая строка имеет зону UTM, Восток и Север в отдельных DataColumn
s. все координаты используют один и тот же датум, но некоторые имеют разные зоны (в противном случае я бы просто использовал математику Пифагора, поскольку 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);
Только для того, чтобы он пожаловался, что" нет столбца № 17 " (17-моя зона UTM).
Я нашел очень мало документации для использования этого материала... насколько я могу судить, мои SRIDs верны (я вытащил их из этого сайта). Я уже делал подобные вещи, используя Lat + Longs раньше, и это сработало замечательно. Я просто не могу найти подходящего синтаксис для UTMs.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;
}
}
}
2 ответа:
В моих поисках, чтобы выяснить это, я наткнулся на этот пост на сестринском сайте здесь. Я полагаю, что
DbGeography
основан на типе данных geography SQL Server, аDbGeometry
- на типе данных geometry.Некоторые уместные лакомые кусочки:
Тип данных geography, EPSG: 4326, находится в градусах, поэтому ваша точка(257306 142708) терпит неудачу, поскольку она выпадает из диапазона (-180,180), (-90,90)....
Решение ... использование геометрического типа данных вместо этого, то есть проектируется, а не географически.
И поэтому я изменил свой код на:
DataColumn dcGeom = new DataColumn("TrapGeom", typeof(DbGeometry)); ... dtTrap.Rows[i]["TrapGeom"] = DbGeometry.PointFromText(pointWellKnownText: stPoint, coordinateSystemId: SRID);
И это, кажется, разбирать просто отлично. Хотя, последняя часть поста меня беспокоит:
SQL Server настаивает на существовании SRID, хотя на самом деле вы не можете сделать с ним ничего полезного, например, преобразовать одну систему координат в другую. Это может стать действительно запутанным, если вы случайно смешаете геометрию с различными Srid, так как вы просто не получите никаких результатов (witout предупреждение, но это в сторону).И так, когда я наконец сделаю
if (Trap1.Distance(Trap2) > 100000)
... тогда я наполовину ожидаю, что он выйдет из строя, когда у меня есть две разные точки в разных Srid. Я проверю и напишу комментарий о том, что я найду.
Для лучшей отладки этой ошибки я рекомендую сначала проверить ваши входные данные.
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); } }
Я предполагаю, что в вашей строке вместо точки или есть некоторая запятая .