【问题标题】:Find Intersection Point Between 2 LineStrings查找 2 个线串之间的交点
【发布时间】:2014-02-10 11:32:43
【问题描述】:

我创建了一个公式来在谷歌地球上形成一个网格。我想得到纬度/经度之间的交点。请告诉我如何获得交叉点。我正在使用 SharpKML 库生成 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);
            }

【问题讨论】:

    标签: google-maps kml google-earth sharpkml


    【解决方案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));
        }
    

    【讨论】:

      【解决方案2】:

      我认为DotSpatial 库应该可以满足您的需求,我过去使用过这个库但没有使用intersections 函数:

      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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多