检测线(具有多个点)是单独的还是连接到另一条线

时间:2013-12-31 15:56:22

标签: c# .net map gis shapefile

我正在编写代码来检测一条线(有多个点,这些线有曲线)是否是道路网络的一部分。如果有一条无法到达的道路(基本上是隔离的),我需要标记它。

见下面的截图

enter image description here

在通过道路网络扫描时,应标记隔离的线条。

我对解决方案的看法 更新2014年1月14日: Tt有效!然而,它太慢了。运行需要30分钟!

我从左到右排序。然后我将列表中的第一项添加到XYPoints“网络”列表/ hashset。它检查每一行的每个XYPoint是否有连接(同一点),然后将其所有点添加到“网络”并将其从行列表中删除(因为它已经被检查过,无需再次检查)。 / p>

如果折线没有连接到主网络,它仍将保留在我最后所有道路的原始列表中。

好的,代码片段,我会随着我的进步不断更新,随时添加一些想法:

while (true)
{
    int numOflinesBeforeChecking = polylinez.Count;
    for (int i = 0; i < polylinez.Count; i++)
    {
        //scan through each point of each polyline
        foreach (XYPoints xyp in polylinez[i].XYpoints)
        {
            //bool foundAvertice = false;
            if (listOfEndPoints.Contains(xyp))
            {
                //add them as endpoints
                foreach (XYPoints verifiedXYs in polylinez[i].XYpoints)
                {
                    listOfEndPoints.Add(verifiedXYs);
                }
                //add them to the network
                for (var g = 0; g < (polylinez[i].XYpoints.Count - 1); g++)
                {
                    mainHighwaylines.Add(new Line2D(polylinez[i].XYpoints[g], polylinez[i].XYpoints[g + 1]));
                }
                polylinez.RemoveAt(i);
                break; //break out of scanning XYPoints of an individual line/road, hit this again!
            } //end if

        } //end foreach XYPoint loop

    } //end for i loop

    //clearly there are no more lines
    if (numOflinesBeforeChecking == polylinez.Count)
    {
        break;
    }
} //end infinite loop

//check for intersections here
//mainHighway Lines has been generated, now let's check them for intersections
while (true)
{
    int numOflinesBeforeChecking = polylinez.Count;
    for (var i = 0; i < polylinez.Count; i++)
    {
        //smallLines relates to each individual polyline, seperated into even smaller lines
        List<Line2D> smallLines = new List<Line2D>();
        for (var g = 0; g < (polylinez[i].XYpoints.Count - 1); g++)
        {
            smallLines.Add(new Line2D(polylinez[i].XYpoints[g], polylinez[i].XYpoints[g + 1]));
        }
        bool intersectionFound = false;
        foreach (Line2D line in smallLines)
        {
            bool lineIntersection = false;
            foreach (Line2D mainHighwayline in mainHighwaylines)
            {
                if (line.intersectsLine(mainHighwayline))
                {
                    intersectionFound = true;
                    lineIntersection = true;
                    break;
                }
            }
            if (lineIntersection)
            {
                break;
            }
        }
        if (intersectionFound)
        {
            for (var g = 0; g < (polylinez[i].XYpoints.Count - 1); g++)
            {
                mainHighwaylines.Add(new Line2D(polylinez[i].XYpoints[g], polylinez[i].XYpoints[g + 1]));
            }
            polylinez.RemoveAt(i);
        }

    }
    //clearly there are no more lines
    if (numOflinesBeforeChecking == polylinez.Count)
    {
        break;
    }

}

我需要什么

如何加快速度的改进!第二个无限循环占用大部分时间。

带有断点的第二个无限循环检查是否有交叉点(它们可能没有共享的终点,它们可能只是相交)。如果添加了新数据,我会将其保持在无限循环中。

使用if语句使第二个主循环(检查交集循环)无限使其从6分钟变为30.但是有必要捕获某些误报。

1 个答案:

答案 0 :(得分:2)

标准(连续)几何方法似乎不适用于此。从您的图片来看,道路太内向(因此很难或不可能只用一条线(或一堆线)替换)和建模(作为网络的一部分)过于不精确定义的情况,依靠简化。

我能解决这个问题的唯一准确方法是检查给定的道路是否与主网络有共同点。

主要想法:

  1. 存储定义主网络的所有点;所有的 构成其中一部分的每条道路的点。这个系列将是 不断更新每条新路决定成为其中的一部分 网络(如下所述)。
  2. 通过检查所有定义点并确认它们是否属于主网络(最终通过考虑某些“容差错误”)来分析每条道路。次要的 收集将在这里开始,所有的道路连接到 将包括正在分析的道路(一旦被分析的道路是 考虑到连接,所有这些二级道路将自动进行 被视为连接,反之亦然)。
  3. 从逻辑上讲,这是一种可能性最差的方案;您拥有的信息越多,适用的简化程度就越高,计算可能变得越来越蛮力。但是如果您的输入数据看起来像图片中的那个,我就不会在这方面过于乐观了。