在GeoJson形状中打洞 - clipperLib

时间:2015-10-17 11:07:48

标签: clipperlib

我有几个重叠的形状。我希望能够在包含所有较小形状的最大形状上打孔。这些孔将代表较大形状内的较小形状。

示例图片: enter image description here

我正在使用ClipperLib的C#版本:

const double precisionFactor = 1000000000000000.0;

            //precondition: all your polygons have the same orientation 
            //(ie either clockwise or counter clockwise)
            Polygons polys = new Polygons();

            multiPolygon.ForEach(x =>
            {
                Polygon polygon = x.First().Select( y => new IntPoint()
                {
                    X = (long)(y[0] * precisionFactor),
                    Y = (long)(y[1] * precisionFactor)
                }).ToList();

                polys.Add(polygon);
            });

            Polygons solution = new Polygons();
            Clipper c = new Clipper();
            c.AddPaths(polys, PolyType.ptSubject,true);
            c.Execute(ClipType.ctDifference, solution,
                PolyFillType.pftNonZero, PolyFillType.pftNonZero);

            var coordinates = solution.SelectMany(x => x.Select(y=> (IList<double>)new List<double>()
            {
                y.X / precisionFactor,
                y.Y / precisionFactor
            }).ToList()) .ToList();

            return coordinates;

但返回的形状是上图中最大的形状。

GeoJson文件: http://s000.tinyupload.com/download.php?file_id=62259172894067221043&t=6225917289406722104327028

1 个答案:

答案 0 :(得分:1)

当你声明你“希望能够以最大的形状打洞”时,我认为你误解了Clipper图书馆管理/定义多边形区域的方式。在Clipper中,多边形由一系列闭合路径和指定的多边形filling rule定义 - 最常见的是EvenOdd或NonZero填充。 (多边形几乎总是以这种方式在图形显示库中定义。)

因此,根据上面的数据,由于您使用的是NonZero填充,因此“孔”路径必须朝向容器外部路径方向的相反方向。如果内部路径与外部容器具有相同的方向,则使用NonZero填充执行“差异”剪切操作将正确忽略内部路径。

作为旁注,当对单个多边形集执行剪切操作时(即,当没有剪切路径时),执行“联合”操作更直观,因为主题路径是“联合”(如同)剪辑路径)在主题和剪辑区域之间的任何剪辑操作之前。