Создание отверстий в формах GeoJson - clipperLib

У меня есть несколько перекрывающихся фигур. Я хочу быть в состоянии сделать отверстия в самой большой форме, которая содержит все меньшие формы. отверстия будут представлять меньшие формы в большей форме.

Образец изображения:

Я использую C# версию 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;

но возвращаемая форма - самая большая фигура на картинке выше.

Файл GeoJson: http://s000.tinyupload.com/download.php?file_id=62259172894067221043&t=6225917289406722104327028

1 ответ

Когда вы заявляете, что "хотите иметь возможность делать отверстия в самой большой форме", я думаю, вы неправильно понимаете, как библиотека Clipper управляет / определяет полигональные области. В Clipper полигоны определяются рядом замкнутых контуров вместе с указанным правилом заполнения полигонов - чаще всего это либо EvenOdd, либо NonZero. (Полигоны почти всегда определяются таким образом в библиотеках графического отображения.)

Следовательно, с вашими данными выше, так как вы используете заполнение NonZero, пути "отверстия" должны быть ориентированы в направлении, противоположном ориентации внешнего пути контейнера. Если внутренние пути имеют ту же ориентацию, что и внешний контейнер, то выполнение операции отсечения "разности" с использованием заполнения с нулем будет правильно игнорировать внутренние пути.

Напомним, что при выполнении операции отсечения на одном наборе полигонов (т. Е. Когда нет обтравочных контуров), становится более интуитивно понятным выполнять операцию 'объединения', поскольку пути объекта 'объединены' (как и пути клипа) перед любым отсечением между областями объекта и клипа.

Другие вопросы по тегам