Making holes in GeoJson Shapes - clipperLib

2019-08-11 01:58发布

I have several overlapping shapes. I want to be able to make holes in the biggest shape that contains all the smaller shapes. the holes will represent the smaller shapes within the bigger shape.

sample image: enter image description here

I am using the C# version of ClipperLib:

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;

but the shape that gets returned is the biggest shape in the above picture.

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

标签: clipperlib
1条回答
smile是对你的礼貌
2楼-- · 2019-08-11 02:47

When you state that you "want to be able to make holes in the biggest shape", I think you're misunderstanding the way the Clipper library manages/defines polygon regions. In Clipper, polygons are defined by a series of closed paths together with a specified polygon filling rule - most commonly either EvenOdd or NonZero filling. (Polygons are almost always defined in this way in graphics display libraries.)

Hence with your data above, since you're using NonZero filling, the 'hole' paths must be orientated in the opposite direction to the orientation of the container outer path. If the inner paths have the same orientation as the outer container, then performing a 'difference' clipping operation using NonZero filling will correctly ignore the inner paths.

As a side note, when performing a clipping operation on a single set of polygons (ie when there are no clipping paths) it's more intuitive to perform a 'union' operation since subject paths are 'union'-ed (as are clip paths) before any clipping op between subject and clip regions.

查看更多
登录 后发表回答