ポリゴンを、穴ができる 1 つの領域にマージしたいと考えています。クリッパーはこれを行うことができますが、結果として得られる 2 つのポリゴンを Google Earth で使用すると、Google Earth がこれらのポリゴンを別々に扱い、それらを互いに重ねるだけであるという問題があります。KML では、ポリゴンの OuterBoundary 要素と InnerBoundary 要素を作成できます。問題は、Clipper の結果を使用して、何が内側で何が外側の境界であるかをどのように知るかということです。言及すべきもう 1 つのこと: 何らかの方法で決定できたとしても、実際の Clipper ユニオン コールでは、数千の円ポリゴンを使用します。したがって、穴のある複数の別々の領域があります。
マージ後:
4 つの単純な形状を含むコードを次に示します。
/*
0 -------
9 | |
8 | 2 |
7 ------- |-----
6 | |---- |
5 | 1 |xx| 3 |
4 | |--| |
3 ------- -------
2 | 4 |
1 | |
0 -------
0123456789012345
*/
IntPolygons polygons = new IntPolygons();
// 1
polygons.Add(new IntPolygon{
new IntPoint { X = 0, Y = 3 },
new IntPoint { X = 6, Y = 3 },
new IntPoint { X = 6, Y = 7 },
new IntPoint { X = 0, Y = 7 }
});
// 2
polygons.Add(new IntPolygon{
new IntPoint { X = 4, Y = 6 },
new IntPoint { X = 10, Y = 6 },
new IntPoint { X = 10, Y = 10 },
new IntPoint { X = 4, Y = 10 }
});
// 3
polygons.Add(new IntPolygon{
new IntPoint { X = 9, Y = 3 },
new IntPoint { X = 15, Y = 3 },
new IntPoint { X = 15, Y = 7 },
new IntPoint { X = 9, Y = 7 }
});
// 4
polygons.Add(new IntPolygon{
new IntPoint { X = 4, Y = 0 },
new IntPoint { X = 10, Y = 0 },
new IntPoint { X = 10, Y = 4},
new IntPoint { X = 4, Y = 4 }
});
Clipper clipper = new Clipper();
foreach (var polygon in polygons)
{
clipper.AddPath(polygon, PolyType.ptSubject, true);
}
IntPolygons mergedPolygons = new IntPolygons();
clipper.Execute(ClipType.ctUnion, mergedPolygons,
PolyFillType.pftNonZero, PolyFillType.pftNonZero);
for (int i = 0; i < mergedPolygons.Count; i++)
{
Console.WriteLine("polygon " + (i + 1));
foreach (var point in mergedPolygons[i])
{
Console.WriteLine("X: " + point.X + "\t\t Y: " + point.Y);
}
}
// Result:
//polygon 1
//X: 10 Y: 3
//X: 15 Y: 3
//X: 15 Y: 7
//X: 10 Y: 7
//X: 10 Y: 10
//X: 4 Y: 10
//X: 4 Y: 7
//X: 0 Y: 7
//X: 0 Y: 3
//X: 4 Y: 3
//X: 4 Y: 0
//X: 10 Y: 0
//polygon 2
//X: 6 Y: 4
//X: 6 Y: 6
//X: 9 Y: 6
//X: 9 Y: 4
// The second polygon is the inner boundary
/*
0
9
8
7
6 x x
5
4 x x
3
2
1
0
0123456789012345
*/
更新: KML には、OuterBoundaries と InnerBoundaries という 2 つのポリゴン リストのセットが常に存在します。ポリゴンを再帰的に解析し、最も外側のポリゴンに内側のポリゴンがあるかどうかを確認しました。最も外側の内側のポリゴンは InnerBoundary です。他のすべての内側のポリゴンは、再び OuterBoundary ポリゴンとして開始されます。非常に大きなポリゴンのセットに関するいくつかの問題を見つけ次第、コードを投稿します。