예제 #1
0
        public bool RemoveAnnotation(IMKAnnotation annotation, FBQuadTreeNode fromNode)
        {
            if (!FBUtils.FBBoundingBoxContainsCoordinate(fromNode.BoundingBox, annotation.Coordinate))
            {
                return(false);
            }

            if (fromNode.Annotations.Contains(annotation))
            {
                fromNode.Annotations.Remove(annotation);
                fromNode.Count--;
                return(true);
            }

            if (RemoveAnnotation(annotation, fromNode.NorthEast))
            {
                return(true);
            }
            if (RemoveAnnotation(annotation, fromNode.NorthWest))
            {
                return(true);
            }
            if (RemoveAnnotation(annotation, fromNode.SouthEast))
            {
                return(true);
            }
            if (RemoveAnnotation(annotation, fromNode.SouthWest))
            {
                return(true);
            }

            return(false);
        }
예제 #2
0
        public void EnumerateAnnotationsInBox(FBBoundingBox box, FBQuadTreeNode withNode, AnnotationEnumDelegate enumFunc)
        {
            if (!FBUtils.FBBoundingBoxIntersectsBoundingBox(withNode.BoundingBox, box))
            {
                return;
            }

            List <IMKAnnotation> tempArray = new List <IMKAnnotation>(withNode.Annotations);

            foreach (IMKAnnotation annotation in tempArray)
            {
                if (FBUtils.FBBoundingBoxContainsCoordinate(box, annotation.Coordinate))
                {
                    enumFunc(annotation);
                }
            }

            if (withNode.IsLeaf())
            {
                return;
            }

            EnumerateAnnotationsInBox(box, withNode.NorthEast, enumFunc);
            EnumerateAnnotationsInBox(box, withNode.NorthWest, enumFunc);
            EnumerateAnnotationsInBox(box, withNode.SouthEast, enumFunc);
            EnumerateAnnotationsInBox(box, withNode.SouthWest, enumFunc);
        }
        public void DisplayAnnotations(List <IMKAnnotation> annotations, MKMapView mapView)
        {
            List <IMKAnnotation> before = new List <IMKAnnotation>();

            foreach (IMKAnnotation annotation in mapView.Annotations)
            {
                before.Add(annotation);
            }
//            MKUserLocation userLocation = mapView.UserLocation;
//            if (userLocation != null)
//                before.Remove(userLocation);
            List <IMKAnnotation> after  = new List <IMKAnnotation>(annotations);
            List <IMKAnnotation> toKeep = new List <IMKAnnotation>(before);

            toKeep = FBUtils.Intersect(toKeep, after);
            List <IMKAnnotation> toAdd = new List <IMKAnnotation>(after);

            toAdd.RemoveAll((IMKAnnotation obj) =>
            {
                return(toKeep.Contains(obj));
            });
            List <IMKAnnotation> toRemove = new List <IMKAnnotation>(before);

            toRemove.RemoveAll((IMKAnnotation obj) =>
            {
                return(after.Contains(obj));
            });

            NSOperationQueue.MainQueue.AddOperation(delegate()
            {
                mapView.AddAnnotations(toAdd.ToArray());
                mapView.RemoveAnnotations(toRemove.ToArray());
            }
                                                    );
        }
        public List <IMKAnnotation> ClusteredAnnotationsWithinMapRect(MKMapRect rect, double zoomScale, Dictionary <IMKAnnotation, bool> filter)
        {
            double cellSize = FBCellSizeForZoomScale(zoomScale);

            if (RespondsToSelector != null)
            {
                cellSize *= RespondsToSelector(this);
            }
            double scaleFactor = zoomScale / cellSize;

            int minX = (int)Math.Floor(rect.MinX * scaleFactor);
            int maxX = (int)Math.Floor(rect.MaxX * scaleFactor);
            int minY = (int)Math.Floor(rect.MinY * scaleFactor);
            int maxY = (int)Math.Floor(rect.MaxY * scaleFactor);

            List <IMKAnnotation> clusteredAnnotations = new List <IMKAnnotation>();

            lock (this)
            {
                for (int x = minX; x <= maxX; x++)
                {
                    for (int y = minY; y <= maxY; y++)
                    {
                        MKMapRect     mapRect = new MKMapRect(x / scaleFactor, y / scaleFactor, 1.0 / scaleFactor, 1.0 / scaleFactor);
                        FBBoundingBox mapBox  = FBUtils.FBBoundingBoxForMapRect(mapRect);

                        double totalLatitude  = 0;
                        double totalLongitude = 0;

                        List <IMKAnnotation> annotations = new List <IMKAnnotation>();

                        _tree.EnumerateAnnotationsInBox(mapBox, delegate(IMKAnnotation annotation)
                        {
                            if (filter == null || filter[annotation])
                            {
                                totalLatitude  += annotation.Coordinate.Latitude;
                                totalLongitude += annotation.Coordinate.Longitude;
                                annotations.Add(annotation);
                            }
                        });

                        int count = annotations.Count;
                        if (count == 1)
                        {
                            clusteredAnnotations.AddRange(annotations);
                        }
                        if (count > 1)
                        {
                            CLLocationCoordinate2D coordinate = new CLLocationCoordinate2D(totalLatitude / count, totalLongitude / count);
                            FBAnnotationCluster    cluster    = new FBAnnotationCluster(coordinate);
                            cluster.Annotations = annotations;
                            clusteredAnnotations.Add(cluster);
                        }
                    }
                }
            }

            return(clusteredAnnotations);
        }
        public void Subdivide()
        {
            NorthEast = new FBQuadTreeNode();
            NorthWest = new FBQuadTreeNode();
            SouthEast = new FBQuadTreeNode();
            SouthWest = new FBQuadTreeNode();

            FBBoundingBox box  = BoundingBox;
            double        xMid = (box.xf + box.x0) / 2.0;
            double        yMid = (box.yf + box.y0) / 2.0;

            NorthEast.BoundingBox = FBUtils.FBBoundingBoxMake(xMid, box.y0, box.xf, yMid);
            NorthWest.BoundingBox = FBUtils.FBBoundingBoxMake(box.x0, box.y0, xMid, yMid);
            SouthEast.BoundingBox = FBUtils.FBBoundingBoxMake(xMid, yMid, box.xf, box.yf);
            SouthWest.BoundingBox = FBUtils.FBBoundingBoxMake(box.x0, yMid, xMid, box.yf);
        }
예제 #6
0
        public bool InsertAnnotation(IMKAnnotation annotation, FBQuadTreeNode toNode)
        {
            if (!FBUtils.FBBoundingBoxContainsCoordinate(toNode.BoundingBox, annotation.Coordinate))
            {
                return(false);
            }

            if (toNode.Count < FBConsts.kNodeCapacity)
            {
                toNode.Annotations.Add(annotation);
                toNode.Count++;
                return(true);
            }

            if (toNode.IsLeaf())
            {
                toNode.Subdivide();
            }

            if (InsertAnnotation(annotation, toNode.NorthEast))
            {
                return(true);
            }
            if (InsertAnnotation(annotation, toNode.NorthWest))
            {
                return(true);
            }
            if (InsertAnnotation(annotation, toNode.SouthEast))
            {
                return(true);
            }
            if (InsertAnnotation(annotation, toNode.SouthWest))
            {
                return(true);
            }

            return(false);
        }
예제 #7
0
 public FBQuadTree()
 {
     _rootNode = new FBQuadTreeNode(FBUtils.FBBoundingBoxForMapRect(new MKMapRect().World));
 }
예제 #8
0
 public void EnumerateAnnotations(AnnotationEnumDelegate enumFunc)
 {
     EnumerateAnnotationsInBox(FBUtils.FBBoundingBoxForMapRect(new MKMapRect().World), _rootNode, enumFunc);
 }