“指定的输入不代表有效的地理实例”使用 SqlGeographyBuilder 时出现异常
我编写了一个小型应用程序,它从一系列 KML 文件中读取数据,然后使用以下代码将它们转换为 Microsoft.SqlServer.Types.SqlGeography
类型:
private SqlGeography CreateGeographyFromKML( string kml, bool debug )
{
// use SqlGeographyBuilder to help create the SqlGeography type
var geographyBuilder = new SqlGeographyBuilder();
// Get co-ordinates
var xml = XDocument.Parse(kml);
var df = xml.Root.Name.Namespace;
XElement coordinates = xml.Descendants(df + "coordinates").Single();
// set the Spatial Reference Identifiers that will used to create the point
geographyBuilder.SetSrid(_srid);
geographyBuilder.BeginGeography(OpenGisGeographyType.Polygon);
var longLat = coordinates.Value.Split(' ').Select(c => new { Lat = Convert.ToDouble(c.Split(',')[1]), Long = Convert.ToDouble(c.Split(',')[0]) });
Console.Write("Found {0} ", longLat.Count());
foreach (var coord in longLat.Select((x, i) => new { Index = i, Value = x }))
{
if (coord.Index == 0)
{ // First point
if ( debug ) Console.WriteLine("First point: {0},{1}", coord.Value.Lat, coord.Value.Long);
geographyBuilder.BeginFigure(coord.Value.Lat, coord.Value.Long);
}
else
{ // Intermediate points
if (debug) Console.WriteLine("Intermediate point: {0},{1}", coord.Value.Lat, coord.Value.Long);
geographyBuilder.AddLine(coord.Value.Lat, coord.Value.Long);
}
if (coord.Index == longLat.Count() - 1 )
{ // Last point (Close polygon)
if (debug) Console.Write("Last point: ");
// Check not already added
if (longLat.Last().Lat == longLat.First().Lat && longLat.Last().Long == longLat.First().Long)
{
if (debug) Console.Write("Already exists - not adding...");
}
else
{
if (debug) Console.Write("{0},{1}", longLat.Last().Lat, longLat.Last().Long);
geographyBuilder.AddLine(longLat.Last().Lat, longLat.Last().Long);
}
geographyBuilder.EndFigure(); // End figure
}
}
if (debug) Console.WriteLine();
// close the figure and geography class
geographyBuilder.EndGeography();
// get the geography builder to return the sqlgeography type
return geographyBuilder.ConstructedGeography;
}
基本上,此代码检索 Lat 列表/Longs 来自 KML 文件,然后循环遍历它们以创建多边形。
但是,我导入的某些 KML 文件会失败,并出现以下异常:
捕获了 System.ArgumentException Message=24200: 指定的 输入不代表有效的地理实例。
这发生在以下行: return geographyBuilder.ConstructedGeography;
我发现了一些 对此的引用异常,但是在某些情况下,我发现他们是在 SQL Server 中遇到并处理此异常,而不是在 C# 中。
I've written a small application that reads in from a series of KML files and then converts them into the Microsoft.SqlServer.Types.SqlGeography
type using the following code:
private SqlGeography CreateGeographyFromKML( string kml, bool debug )
{
// use SqlGeographyBuilder to help create the SqlGeography type
var geographyBuilder = new SqlGeographyBuilder();
// Get co-ordinates
var xml = XDocument.Parse(kml);
var df = xml.Root.Name.Namespace;
XElement coordinates = xml.Descendants(df + "coordinates").Single();
// set the Spatial Reference Identifiers that will used to create the point
geographyBuilder.SetSrid(_srid);
geographyBuilder.BeginGeography(OpenGisGeographyType.Polygon);
var longLat = coordinates.Value.Split(' ').Select(c => new { Lat = Convert.ToDouble(c.Split(',')[1]), Long = Convert.ToDouble(c.Split(',')[0]) });
Console.Write("Found {0} ", longLat.Count());
foreach (var coord in longLat.Select((x, i) => new { Index = i, Value = x }))
{
if (coord.Index == 0)
{ // First point
if ( debug ) Console.WriteLine("First point: {0},{1}", coord.Value.Lat, coord.Value.Long);
geographyBuilder.BeginFigure(coord.Value.Lat, coord.Value.Long);
}
else
{ // Intermediate points
if (debug) Console.WriteLine("Intermediate point: {0},{1}", coord.Value.Lat, coord.Value.Long);
geographyBuilder.AddLine(coord.Value.Lat, coord.Value.Long);
}
if (coord.Index == longLat.Count() - 1 )
{ // Last point (Close polygon)
if (debug) Console.Write("Last point: ");
// Check not already added
if (longLat.Last().Lat == longLat.First().Lat && longLat.Last().Long == longLat.First().Long)
{
if (debug) Console.Write("Already exists - not adding...");
}
else
{
if (debug) Console.Write("{0},{1}", longLat.Last().Lat, longLat.Last().Long);
geographyBuilder.AddLine(longLat.Last().Lat, longLat.Last().Long);
}
geographyBuilder.EndFigure(); // End figure
}
}
if (debug) Console.WriteLine();
// close the figure and geography class
geographyBuilder.EndGeography();
// get the geography builder to return the sqlgeography type
return geographyBuilder.ConstructedGeography;
}
Basically this code retrieves the list of Lat/Longs from the KML file, then loops through them to create a polygon.
However some of the KML files I'm importing fail with the following exception:
System.ArgumentException was caught Message=24200: The specified
input does not represent a valid geography instance.
This happens on the following line: return geographyBuilder.ConstructedGeography;
I've found some reference to this exception, however in the cases I've found they're encountering and dealing with this exception within SQL Server, rather than C#.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我也遇到了同样的错误,但结果证明是多边形环方向问题。翻转坐标数组的顺序的简单问题就解决了这个问题。
为了说明这一点,这会因上述错误而失败:
而这有效:
请注意,我没有翻转点内的 x,y 对,而是翻转整个点数组的顺序(例如 {pt1, pt2, pt3, pt4 , pt5} 变为 {pt5, pt4, pt3, pt2, pt1}
I had this same error, but it turned out to be a polygon ring orientation problem. A simple matter of flipping the order of the coordinate arrays solved the problem.
To illustrate, this fails with the above error:
whereas this works:
Note that I'm not flipping the x,y pairs within a point, I am flipping the order of the entire point array (e.g. {pt1, pt2, pt3, pt4, pt5} becomes {pt5, pt4, pt3, pt2, pt1}
我遇到了同样的问题,并使用名为 Sql Server Spatial Tools 的项目解决了它(http://sqlspatialtools.codeplex.com )。
它有(以及其他有趣的东西)这两个方法:
它们修改点以使其符合地理限制。
它的效果真的非常好,我已经使用了几个月了,没有任何问题。
I've had the same problem and solved it using a project called Sql Server Spatial Tools (http://sqlspatialtools.codeplex.com).
It has (among other interesting stuff) these two methods:
They modify the points so that it conforms to the geography restrictions.
It works really, really well, and I've used it for several months now without any problem.