/** * Return a polygon which is the union of the given polygons; combines * vertices that form edges that are almost identical, as defined by * vertexMergeRadius. Note: clears the List! */ public static S2Polygon DestructiveUnionSloppy(System.Collections.Generic.ICollection <S2Polygon> polygons, S1Angle vertexMergeRadius) { // Effectively create a priority queue of polygons in order of number of // vertices. Repeatedly union the two smallest polygons and add the result // to the queue until we have a single polygon to return. // map: # of vertices -> polygon //TreeMultimap<Integer, S2Polygon> queue = TreeMultimap.create(); var queue = new MultiMap <int, S2Polygon>(); foreach (var polygon in polygons) { queue.Add(polygon.NumVertices, polygon); } polygons.Clear(); // Java uses a live-view that maps to the underlying structure //Set<Map.Entry<Integer, S2Polygon>> queueSet = queue.entries(); var enumer = queue.SortedValues; while (queue.CountIsAtLeast(2)) { // Pop two simplest polygons from queue. // queueSet = queue.entries(); //Iterator<Map.Entry<Integer, S2Polygon>> smallestIter = queueSet.iterator(); var smallestTwo = enumer.Take(2).ToList(); //Map.Entry<Integer, S2Polygon> smallest = smallestIter.next(); //int aSize = smallest.getKey().intValue(); //S2Polygon aPolygon = smallest.getValue(); //smallestIter.remove(); //smallest = smallestIter.next(); //int bSize = smallest.getKey().intValue(); //S2Polygon bPolygon = smallest.getValue(); //smallestIter.remove(); foreach (var item in smallestTwo) { queue.Remove(item); } // Union and add result back to queue. var unionPolygon = new S2Polygon(); unionPolygon.InitToUnionSloppy(smallestTwo[0].Value, smallestTwo[1].Value, vertexMergeRadius); var unionSize = smallestTwo[0].Key + smallestTwo[1].Key; queue.Add(unionSize, unionPolygon); // We assume that the number of vertices in the union polygon is the // sum of the number of vertices in the original polygons, which is not // always true, but will almost always be a decent approximation, and // faster than recomputing. } if (queue.Count == 0) { return(new S2Polygon()); } else { //return queue.get(queue.asMap().firstKey()).first(); return(queue.SortedValues.First().Value); } }