3

Microsoft.SqlServer.Types.SqlGeography一連の KML ファイルから読み取り、次のコードを使用して型に変換する小さなアプリケーションを作成しました。

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

基本的に、このコードは KML ファイルから緯度/経度のリストを取得し、それらをループ処理してポリゴンを作成します。

ただし、インポートしている KML ファイルの一部は、次の例外で失敗します。

System.ArgumentException がキャッチされました Message=24200: 指定された入力は、有効な geography インスタンスを表していません。

これは次の行で発生します。return geographyBuilder.ConstructedGeography;

この例外への参照を見つけましたが、C# ではなく SQL Server 内でこの例外に遭遇し、処理していることがわかりました。

4

2 に答える 2

2

私は同じ問題を抱えていて、Sql Server Spatial Tools ( http://sqlspatialtools.codeplex.com ) というプロジェクトを使用して解決しました。

(他の興味深いものの中でも) 次の 2 つの方法があります。

  • MakeValidGeographyFromGeography
  • MakeValidGeographyFromText (WKT 文字列を受け取ります)

地理的制限に適合するようにポイントを変更します。

それは本当に、本当にうまく機能し、私は何の問題もなく数ヶ月間それを使用しています.

于 2011-11-26T12:59:47.237 に答える