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); }
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); }
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); }
public FBQuadTree() { _rootNode = new FBQuadTreeNode(FBUtils.FBBoundingBoxForMapRect(new MKMapRect().World)); }
public void EnumerateAnnotations(AnnotationEnumDelegate enumFunc) { EnumerateAnnotationsInBox(FBUtils.FBBoundingBoxForMapRect(new MKMapRect().World), _rootNode, enumFunc); }