Pet*_*ger 3 geography kml geospatial sql-server-2008 sqlgeography
我编写了一个小应用程序,它从一系列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;
}
Run Code Online (Sandbox Code Playgroud)
基本上,此代码从KML文件中检索Lat/Longs列表,然后循环遍历它们以创建多边形.
但是我导入的一些KML文件失败,出现以下异常:
捕获到System.ArgumentException消息= 24200:指定的输入不表示有效的地理实例.
这发生在以下行: return geographyBuilder.ConstructedGeography;
我发现了一些对这个异常的引用,但是在我发现它们在SQL Server中遇到并处理这个异常而不是C#的情况下.
我有同样的错误,但结果是多边形环定向问题.翻转坐标数组顺序的简单问题解决了这个问题.
为了说明,这失败了以上错误:
select geography::STGeomFromText ('Polygon ( (10 10, 10 20, 20 20, 20 10, 10 10))',4326)
Run Code Online (Sandbox Code Playgroud)
这有效:
select geography::STGeomFromText ('Polygon ( (10 10, 20 10, 20 20, 10 20, 10 10))',4326)
Run Code Online (Sandbox Code Playgroud)
请注意,我没有在一个点内翻转x,y对,我正在翻转整个点数组的顺序(例如{pt1,pt2,pt3,pt4,pt5}变为{pt5,pt4,pt3,pt2,pt1 }
归档时间: |
|
查看次数: |
5041 次 |
最近记录: |