找到2个LineStrings之间的交点

时间:2014-02-10 11:32:44

标签: google-maps kml google-earth sharpkml

我创建了一个公式来在Google地球上形成一个网格。我想得到lat / long之间的交点。请告诉我如何获得交集。我使用SharpKML lib生成KML

for (int x = 90; x >= 0; x = x - 15)
                {
                    Placemark placemark = new Placemark();
                    LineString line = new LineString();
                    CoordinateCollection co = new CoordinateCollection();
                    for (int i = 0; i <= 180; i = i + 15)
                    {
                        Vector cords = new Vector()
                            {
                                Latitude = x,
                                Longitude = i,
                                Altitude = 1000
                            };

                        co.Add(cords);
                    }
                    for (int i = -180; i <= 0; i = i + 15)
                    {
                        Vector cords = new Vector()
                        {
                            Latitude = x,
                            Longitude = i,
                            Altitude = 1000
                        };

                        co.Add(cords);
                    }
                    line.Coordinates = co;
                    placemark.Geometry = line;
                    document.AddFeature(placemark);
                }
            for (int x = -90; x <= 0; x = x + 15)
            {
                Placemark placemark = new Placemark();
                LineString line = new LineString();
                CoordinateCollection co = new CoordinateCollection();
                for (int i = 0; i <= 180; i = i + 15)
                {
                    Vector cords = new Vector()
                    {
                        Latitude = x,
                        Longitude = i,
                        Altitude = 1000
                    };

                    co.Add(cords);
                }
                for (int i = -180; i <= 0; i = i + 15)
                {
                    Vector cords = new Vector()
                    {
                        Latitude = x,
                        Longitude = i,
                        Altitude = 1000
                    };

                    co.Add(cords);
                }
                line.Coordinates = co;
                placemark.Geometry = line;
                document.AddFeature(placemark);
            }

            for (int i = 0; i <= 180; i = i + 15)
            {
                Placemark placemark = new Placemark();
                LineString line = new LineString();
                CoordinateCollection co = new CoordinateCollection();
                for (int x = 0; x <= 90; x = x + 15)
                {
                    Vector cords = new Vector()
                    {
                        Latitude = x,
                        Longitude = i,
                        Altitude = 1000
                    };

                    co.Add(cords);
                }
                for (int x = -90; x <= 0; x = x + 15)
                {
                    Vector cords = new Vector()
                    {
                        Latitude = x,
                        Longitude = i,
                        Altitude = 1000
                    };

                    co.Add(cords);
                }
                line.Coordinates = co;
                placemark.Geometry = line;
                document.AddFeature(placemark);
            }
            for (int i = -180; i <= 0; i = i + 15)
            {
                Placemark placemark = new Placemark();
                LineString line = new LineString();
                CoordinateCollection co = new CoordinateCollection();
                for (int x = 0; x <= 90; x = x + 15)
                {
                    Vector cords = new Vector()
                    {
                        Latitude = x,
                        Longitude = i,
                        Altitude = 1000
                    };

                    co.Add(cords);
                }
                for (int x = -90; x <= 0; x = x + 15)

                {
                    Vector cords = new Vector()
                    {
                        Latitude = x,
                        Longitude = i,
                        Altitude = 1000
                    };

                    co.Add(cords);
                }
                line.Coordinates = co;
                placemark.Geometry = line;
                document.AddFeature(placemark);
            }

2 个答案:

答案 0 :(得分:1)

如果问题是如何使用C#找到任意LineString对象与网格的交点,那么Matthew是正确的。在C ++中,您可以在Java中使用GEOS http://trac.osgeo.org/geos/,它将是JTS http://www.vividsolutions.com/jts/JTSHome.htm

但是,如果您自己创建网格,并想要回答更简单的问题,即如何找到我刚刚创建的网格的水平线和垂直线之间的交叉点,答案就是使用您在嵌套循环中用于LineStrings的相同精确纬度,经度值:

Document document = new Document();
for(y = -90; y < 0; y += 15){
  for(x = -180; x < 0; x+= 15){
     Point point = new Point();
     point.Coordinate = new Vector(x, y);
     Placemark placemark = new Placemark();
     placemark.Geometry = point;
     document.AddFeature(placemark);
  }
}

    .. repeat for the other 4 quadrants

// It's conventional for the root element to be Kml,
// but you could use document instead.
Kml root = new Kml();
root.Feature = document;
XmlFile kml = KmlFile.Create(root, false);

如果您想使用DotSpatial来查找网格和Shapefile之间的交集,可以使用以下源代码。在这种情况下,shapefile具有河流线并且仅产生一个交叉点。请注意,拓扑交集代码有点慢,因此您需要使用范围检查来加快速度。在您的情况下,您可能希望通过使用KMLSharp来读取kml源文件中的线串坐标而不是打开shapefile来构建新功能,但交叉代码将类似。

作为旁注,我不认为看似容易使用的FeatureSet.Intersection方法足够聪明,可以处理线交点产生点特征作为交叉点的情况。它仅适用于输出可能与输入具有相同特征类型的点或多边形。

    using DotSpatial.Controls;
    using DotSpatial.Data;
    using DotSpatial.Topology;
    using DotSpatial.Symbology;


    private FeatureSet gridLines;

    private void buttonAddGrid_Click(object sender, EventArgs e)
    {
        gridLines = new FeatureSet(FeatureType.Line);
        for (int x = -180; x < 0; x += 15)
        {
            List<Coordinate> coords = new List<Coordinate>();
            coords.Add(new Coordinate(x, -90));
            coords.Add(new Coordinate(x, 90));
            LineString ls = new LineString(coords);
            gridLines.AddFeature(ls);
        }
        for (int y = -90; y < 0; y += 15)
        {
            List<Coordinate> coords = new List<Coordinate>();
            coords.Add(new Coordinate(-180, y));
            coords.Add(new Coordinate(180, y));
            LineString ls = new LineString(coords);
            gridLines.AddFeature(ls);
        }

        map1.Layers.Add(new MapLineLayer(gridLines));
    }

    private void buttonIntersect_Click(object sender, EventArgs e)
    {
        if (gridLines == null)
        {
            MessageBox.Show("First add the grid.");
        }

        IFeatureSet river = FeatureSet.Open(@"C:\Data\Rivers\River.shp");
        MapLineLayer riverLayer = new MapLineLayer(river);
        map1.Layers.Add(river);




        List<DotSpatial.Topology.Point> allResultPoints = new List<DotSpatial.Topology.Point>();
        foreach (Feature polygon in river.Features)
        {
            Geometry lineString = polygon.BasicGeometry as Geometry;
            foreach (Feature lineFeature in gridLines.Features)
            {
                // Speed up calculation with extent testing.
                if(!lineFeature.Envelope.Intersects(lineString.Envelope)){
                    continue;
                }
                IFeature intersectFeature = lineFeature.Intersection(lineString);
                if (intersectFeature == null)
                {
                    continue;
                }


                MultiPoint multi = intersectFeature.BasicGeometry as MultiPoint;
                if (multi != null)
                {
                    for(int i = 0; i < multi.NumGeometries; i++)
                    {
                        allResultPoints.Add(intersectFeature.GetBasicGeometryN(i) as DotSpatial.Topology.Point);
                    }
                }
                DotSpatial.Topology.Point single = intersectFeature.BasicGeometry as DotSpatial.Topology.Point;
                {
                    allResultPoints.Add(single);
                }
            }
        }

        FeatureSet finalPoints = new FeatureSet(FeatureType.Point);
        foreach(DotSpatial.Topology.Point pt in allResultPoints){
            finalPoints.AddFeature(pt);
        }
        map1.Layers.Add(new MapPointLayer(finalPoints));
    }

答案 1 :(得分:0)

我认为DotSpatial库应该满足您的需求,我以前使用过这个库但没有使用交叉点函数:

http://dotspatial.codeplex.com/wikipage?title=DotSpatial.Data.FeatureSetExt.Intersection

如果你尝试进行自己的线交叉分析,要知道简单的笛卡尔平面方法会引入误差(当我接近极点时,[我认为]会变得更加明显。)

见这里:http://www.geog.ubc.ca/courses/klink/gis.notes/ncgia/u32.html

在这里:Intersection between two geographic lines