Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 地理形状分组_C#_Algorithm_Geometry_Geography_Dundas - Fatal编程技术网

C# 地理形状分组

C# 地理形状分组,c#,algorithm,geometry,geography,dundas,C#,Algorithm,Geometry,Geography,Dundas,我正在使用Dundas地图,并试图绘制一张世界地图,其中国家被划分为特定于业务实施的区域 我有世界上每个国家的形状数据(点和线段)。我可以通过将区域内国家的所有点和分段添加到新的区域形状中,将国家合并到区域中 foreach(var region in GetAllRegions()){ var regionShape = new Shape { Name = region.Name }; foreach(var country in GetCountriesInRegion(r

我正在使用Dundas地图,并试图绘制一张世界地图,其中国家被划分为特定于业务实施的区域

我有世界上每个国家的形状数据(点和线段)。我可以通过将区域内国家的所有点和分段添加到新的区域形状中,将国家合并到区域中

foreach(var region in GetAllRegions()){
    var regionShape = new Shape { Name = region.Name };
    foreach(var country in GetCountriesInRegion(region.Id)){
        var countryShape = GetCountryShape(country.Id);
        regionShape.AddSegments(countryShape.ShapeData.Points, countryShape.ShapeData.Segments);
    }
    map.Shapes.Add(regionShape);
}
问题是,国家边界线仍然显示在一个区域内,我想删除它们,以便只显示区域边界

Dundas多边形必须在同一点开始和结束。这是所有国家形状的情况。现在我需要一种算法,它可以:

  • 确定国家边界与区域边界相交的位置,以便我可以连接区域边界段
  • 确定哪些国家边界不是区域边界,以便我可以丢弃它们
  • 对生成的区域点进行排序,以便它们顺序描述形状边界
下面是我用地图到目前为止的地方。你可以看到国家边界仍然需要被移除。例如,蒙古和中国之间的边界应该放弃,而蒙古和俄罗斯之间的边界应该保留

我需要保留区域边界的原因是,区域颜色在传递信息时非常重要,但相邻区域可能是相同的颜色。区域可以改变以包括或排除国家,这就是为什么区域形成必须是动态的

编辑: 我现在知道我要找的是多边形的并集。David Lean在SQL Server 2008中使用空间函数,这可能是一个选项,但我的工作已经停止,因为生成的多边形并集非常复杂,SQL将其截断为43680个字符。我现在试图找到一种解决方法,或者找到一种在代码中实现联合的方法


在对国家进行分组时,我希望没有重叠——您可以采用一种非常简单的算法来查找共享顶点——一个简单的视图是迭代一个多边形上的点,查看它是否位于任何其他多边形上,并共享相同的下一个或上一个点,以查看是否存在匹配。然后只需删除共享顶点即可创建联盟

假设相邻国家共享公共顶点和边(否则,问题会变得更加困难)

对于每个区域,遍历与该区域中的国家/地区对应的多边形,并创建顶点和边的列表。每个边都应该有指向其端点的两个顶点的指针,每个顶点都应该有指向其端点的边的指针

向列表中添加顶点时,请确保它们是唯一的顶点。换句话说,如果要添加坐标为
(x,y)
的顶点,如果列表中已经有这样的顶点,则不要添加新的顶点。这意味着您可能必须根据列表中已有的顶点检查每个新顶点。您可以通过将区域的边界框拆分为可以存储顶点的容器(例如,
n
x
n
bin)来加速此过程。当一个新顶点进入时,查找它的容器并对照该容器中的其他顶点进行检查

将边添加到边列表时,执行相同的操作-如果正在添加边(v0,v1),请检查是否存在现有边(v0,v1)或(v1,v0)。除此情况外,请从列表中删除现有边,不要添加新边。这是因为这两个边缘相互“抵消”——它们来自邻国。不要忘记删除顶点列表中与已删除边对应的边指针

当你这样做的时候,你应该有一个不被两个国家共享的边缘列表。这些是构成区域边界的边。您还应该有一个顶点列表,一些顶点指向两条边,另一些顶点不指向任何边。前面的顶点位于区域边界上

现在,从“边”列表中拾取一条边,然后从“边”列表中删除它(并从作为其端点的顶点中删除相应的边指针)。转到其中一个顶点端点,它将指向另一条边。这样,您将沿着区域边界从一条边走到另一条边。从edgelist中删除这些边时,将其添加到区域形状。最终,您将返回到第一条边的端点,并形成一个闭合循环

如果edgelist中还有任何边,请再次启动该过程以提取另一个边界循环,并继续进行,直到提取完所有边界循环且edgelist为空


我提到了一个优化,它将顶点按空间组织到容器中,以便您可以更快地测试它们。另一个优化是避免从列表中物理删除边,而只是将它们标记为“已删除”。

的确如此。现在我只需要一个算法。只要把你的答案读几遍,我想我明白你的意思了。现在我来试试。我已经了解了哪些顶点是共享的。只需完成将非共享顶点按正确顺序添加到并集多边形的算法…我会通过迭代点来完成,如果您可以保证点始终按顺时针顺序(例如)排列,这将非常有用,因为您可以边走边构建多边形-从多边形“a”开始,检查是否存在共享顶点,如果找到,则沿该周长以相反方向继续,直到到达另一个具有原始形状的共享顶点(最坏的情况是,它将是您离开的共享顶点),您要删除的是共享线段,而不是共享顶点。仅当共享顶点的两个线段从多边形中删除后,才需要删除顶点。否则,将删除连接两个合成半多边形的顶点。