/**
             * Return the set the unmarked points whose distance to "center" is less
             * than search_radius_, and mark these points. By construction, these points
             * will be contained by one of the vertex neighbors of "center".
             */

            public void Query(S2Point center, System.Collections.Generic.ICollection <S2Point> output)
            {
                output.Clear();

                var neighbors = new List <S2CellId>();

                S2CellId.FromPoint(center).GetVertexNeighbors(_level, neighbors);
                foreach (var id in neighbors)
                {
                    // Iterate over the points contained by each vertex neighbor.
                    foreach (var mp in _delegate[id])
                    {
                        if (mp.IsMarked)
                        {
                            continue;
                        }
                        var p = mp.Point;

                        if (center.Angle(p) <= _searchRadius)
                        {
                            output.Add(p);
                            mp.Mark();
                        }
                    }
                }
            }
Ejemplo n.º 2
0
        /// <summary>
        /// Removes all but mentioned items (i.e. determined by Linq expression) from the specified collection.
        /// <locDE><para />Entfernt alle außer die angegebenen Elemente (z.B. ermittelt durch Linq Ausdruck) von der angegebenen Collection.</locDE>
        /// </summary>
        /// <typeparam name="T">The type of the T.<locDE><para />Generischer Datentyp T.</locDE></typeparam>
        /// <param name="collection">The collection.<locDE><para />Die Collection.</locDE></param>
        /// <param name="condition">The condition.<locDE><para />Die Bedingung.</locDE></param>
        /// <example>
        /// Removes all elements but those with IsSelected property set to true.
        /// <locDE><para />Entfernt alle Elemente außer jenen, deren Eigenschaft IsSelected = true enthält.</locDE>
        /// <code>
        /// var collection = new ObservableCollection&lt;SelectableItem&gt;();
        /// collection.RemoveAllBut(x =&gt; x.IsSelected);
        /// </code>
        /// </example>
        /// <returns>Number of removed items.<locDE><para />Anzahl der entfernten Elemente.</locDE></returns>
        public static int RemoveAllBut <T>(this System.Collections.Generic.ICollection <T> collection, Func <T, bool> condition)
        {
            if (null == collection)
            {
                return(0);
            }

            // .ToList() saves us from "collection was modified" exception
            // .ToList() bewahrt uns vor einer "Collection wurde verändert" Ausnahme.
            var itemsToKeep = collection.Where(condition).ToList();

            int itemsRemoved = collection.Count - itemsToKeep.Count();

            collection.Clear();
            foreach (var itemToKeep in itemsToKeep)
            {
                collection.Add(itemToKeep);
            }

            return(itemsRemoved);
        }
        /**
         * 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);
            }
        }