/// <summary>
        /// Returns all the objects within a given bounding box and filtered by a given filter.
        /// </summary>
        /// <param name="box"></param>
        /// <param name="filter"></param>
        /// <returns></returns>
        public override IList<OsmGeo> Get(GeoCoordinateBox box, Filter filter)
        {
            List<OsmGeo> res = new List<OsmGeo>();

            // load all nodes and keep the ids in a collection.
            HashSet<long> ids = new HashSet<long>();
            foreach (Node node in _nodes.Values)
            {
                if ((filter == null || filter.Evaluate(node)) &&
                    box.Contains(new GeoCoordinate(node.Latitude.Value, node.Longitude.Value)))
                {
                    res.Add(node);
                    ids.Add(node.Id.Value);
                }
            }

            // load all ways that contain the nodes that have been found.
            res.AddRange(this.GetWaysFor(ids).Cast<OsmGeo>()); // the .Cast<> is here for Windows Phone.

            // get relations containing any of the nodes or ways in the current results-list.
            List<Relation> relations = new List<Relation>();
            HashSet<long> relationIds = new HashSet<long>();
            foreach (OsmGeo osmGeo in res)
            {
                IList<Relation> relationsFor = this.GetRelationsFor(osmGeo);
                foreach (Relation relation in relationsFor)
                {
                    if (!relationIds.Contains(relation.Id.Value))
                    {
                        relations.Add(relation);
                        relationIds.Add(relation.Id.Value);
                    }
                }
            }

            // recursively add all relations containing other relations as a member.
            do
            {
                res.AddRange(relations.Cast<OsmGeo>()); // the .Cast<> is here for Windows Phone.
                List<Relation> newRelations = new List<Relation>();
                foreach (OsmGeo osmGeo in relations)
                {
                    IList<Relation> relationsFor = this.GetRelationsFor(osmGeo);
                    foreach (Relation relation in relationsFor)
                    {
                        if (!relationIds.Contains(relation.Id.Value))
                        {
                            newRelations.Add(relation);
                            relationIds.Add(relation.Id.Value);
                        }
                    }
                }
                relations = newRelations;
            } while (relations.Count > 0);

            if (filter != null)
            {
                List<OsmGeo> filtered = new List<OsmGeo>();
                foreach (OsmGeo geo in res)
                {
                    if (filter.Evaluate(geo))
                    {
                        filtered.Add(geo);
                    }
                }
            }

            return res;
        }
Beispiel #2
0
        /// <summary>
        /// Utility method for ensuring a view stays within a bounding box of geo coordinated.
        /// </summary>
        /// <param name="center">The map center we want to move to.</param>
        /// <param name="boundingBox">A GeoCoordinateBox defining the bounding box.</param>
        /// <param name="view" The current view.</param>
        /// <returns>Returns a center geo coordinate that is corrected so the view stays within the bounding box.</returns>
        public GeoCoordinate EnsureViewWithinBoundingBox(GeoCoordinate center, GeoCoordinateBox boundingBox, View2D view)
        {
            double[] mapCenterSceneCoords = this.Projection.ToPixel(center);

            var toViewPort = view.CreateToViewPort(view.Width, view.Height);
            double mapCenterPixelsX, mapCenterPixelsY;
            toViewPort.Apply(mapCenterSceneCoords[0], mapCenterSceneCoords[1], out mapCenterPixelsX, out mapCenterPixelsY);

            //double[] mapCenterPixels = view.ToViewPort(view.Width, view.Height, mapCenterSceneCoords[0], mapCenterSceneCoords[1]);

            var fromViewPort = view.CreateFromViewPort(view.Height, view.Width);
            double leftScene, topScene, rightScene, bottomScene;
            fromViewPort.Apply(mapCenterPixelsX - (view.Width) / 2.0, mapCenterPixelsY - (view.Height) / 2.0, out leftScene, out topScene);

            //double[] topLeftSceneCoordinates = view.FromViewPort(view.Width,
            //                                                    view.Height,
            //                                                    mapCenterPixels[0] - (view.Width) / 2.0,
            //                                                    mapCenterPixels[1] - (view.Height) / 2.0);
            GeoCoordinate topLeft = this.Projection.ToGeoCoordinates(leftScene, topScene);
            //GeoCoordinate topLeft = this.Projection.ToGeoCoordinates(topLeftSceneCoordinates[0], topLeftSceneCoordinates[1]);

            fromViewPort.Apply(mapCenterPixelsX + (view.Width) / 2.0, mapCenterPixelsY + (view.Height) / 2.0, out rightScene, out bottomScene);
            //double[] bottomRightSceneCoordinates = view.FromViewPort(view.Width,
            //                                                    view.Height,
            //                                                    mapCenterPixels[0] + (view.Width) / 2.0,
            //                                                    mapCenterPixels[1] + (view.Height) / 2.0);
            GeoCoordinate bottomRight = this.Projection.ToGeoCoordinates(rightScene, bottomScene);

            // Early exit when the view is inside the box.
            if (boundingBox.Contains(topLeft) && boundingBox.Contains(bottomRight))
                return center;

            double viewNorth = topLeft.Latitude;
            double viewEast = bottomRight.Longitude;
            double viewSouth = bottomRight.Latitude;
            double viewWest = topLeft.Longitude;

            double boxNorth = boundingBox.MaxLat;
            double boxEast = boundingBox.MaxLon;
            double boxSouth = boundingBox.MinLat;
            double boxWest = boundingBox.MinLon;

            //TODO: Check if the view acrually fits the bounding box, if not resize the view.

            // Correct all view bounds if neccecary.
            if (viewNorth > boxNorth)
            {
                viewSouth -= viewNorth - boxNorth;
                viewNorth = boxNorth;
            }
            if (viewEast > boxEast)
            {
                viewWest -= viewEast - boxEast;
                viewEast = boxEast;
            }
            if (viewSouth < boxSouth)
            {
                viewNorth += boxSouth - viewSouth;
                viewSouth = boxSouth;
            }
            if (viewWest < boxWest)
            {
                viewEast += boxWest - viewWest;
                viewWest = boxWest;
            }

            // Compute and return corrected map center
            return new GeoCoordinate(viewSouth + (viewNorth - viewSouth) / 2.0f, viewWest + (viewEast - viewWest) / 2.0f);
        }
Beispiel #3
0
        /// <summary>
        /// Returns true if this point is visible inside the given bounding box.
        /// </summary>
        /// <returns></returns>
        public override bool IsInside(GeoCoordinateBox box)
        {
            if (box == null) { throw new ArgumentNullException(); }

            return box.Contains(this.Coordinate);
        }