/// <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); double[] mapCenterPixels = view.ToViewPort(view.Width, view.Height, mapCenterSceneCoords[0], mapCenterSceneCoords[1]); 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(topLeftSceneCoordinates[0], topLeftSceneCoordinates[1]); 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(bottomRightSceneCoordinates[0], bottomRightSceneCoordinates[1]); // 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)); }
/// <summary> /// Builds the scene. /// </summary> /// <param name="map"></param> /// <param name="zoomFactor"></param> /// <param name="center"></param> /// <param name="view"></param> private void BuildScene(Map map, float zoomFactor, GeoCoordinate center, View2D view) { // build the boundingbox. var viewBox = view.OuterBox; var box = new GeoCoordinateBox(map.Projection.ToGeoCoordinates(viewBox.Min [0], viewBox.Min [1]), map.Projection.ToGeoCoordinates(viewBox.Max [0], viewBox.Max [1])); var zoomLevel = (int)map.Projection.ToZoomLevel(zoomFactor); if (_lastBox != null && _lastBox.Contains(box) && zoomLevel == _lastZoom) { return; } _lastBox = box; _lastZoom = zoomLevel; // reset the scene. if (_scene2DSimple == null) { _scene2DSimple = new Scene2DSimple(); } _scene2DSimple.Clear(); // get from the index. this.Scene.BackColor = SimpleColor.FromKnownColor(KnownColor.White).Value; lock (_sync) { _index.Get(_scene2DSimple, view, zoomFactor); } }
/// <summary> /// Returns true if the coordinate is inside the polygon being filtered against. /// </summary> /// <returns></returns> private bool IsInsidePoly(double latitude, double longitude) { if (!_box.Contains(longitude, latitude)) { // use the bounding box checks as a negative-first. return(false); } return(_poly.Contains(new GeoCoordinate(latitude, longitude))); }
public override bool IsInside(GeoCoordinateBox box) { if (box == null) { throw new ArgumentNullException(); } return(box.Contains((PointF2D)this.Coordinate)); }
/// <summary> /// Calculates edge data. /// </summary> /// <param name="tagsIndex"></param> /// <param name="tags"></param> /// <param name="tagsForward"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="edgeInterpreter"></param> /// <param name="intermediates"></param> /// <returns></returns> protected override Edge CalculateEdgeData(IEdgeInterpreter edgeInterpreter, ITagsIndex tagsIndex, TagsCollectionBase tags, bool tagsForward, GeoCoordinate from, GeoCoordinate to, List <GeoCoordinateSimple> intermediates) { if (edgeInterpreter == null) { throw new ArgumentNullException("edgeInterpreter"); } if (tagsIndex == null) { throw new ArgumentNullException("tagsIndex"); } if (tags == null) { throw new ArgumentNullException("tags"); } if (from == null) { throw new ArgumentNullException("from"); } if (to == null) { throw new ArgumentNullException("to"); } uint tagsId = tagsIndex.Add(tags); var shapeInBox = true; if (intermediates != null) { // verify shape-in-box. var box = new GeoCoordinateBox(from, to); for (int idx = 0; idx < intermediates.Count; idx++) { if (!box.Contains(intermediates[idx].Longitude, intermediates[idx].Latitude)) { // shape not in box. shapeInBox = false; break; } } } return(new Edge() { Forward = tagsForward, Tags = tagsId, Distance = (float)from.DistanceEstimate(to).Value, ShapeInBox = shapeInBox }); }
/// <summary> /// Returns all the arcs in the given bbox. /// </summary> /// <param name="box"></param> /// <returns></returns> public Tuple <long, long, TEdge, ICoordinateCollection>[] GetEdges(GeoCoordinateBox box) { var baseArcs = _datasource.GetEdges(box); var arcs = new List <Tuple <long, long, TEdge, ICoordinateCollection> >(); foreach (var baseArc in baseArcs) { // check if the arc was removed. var arc = new Arc() { Vertex1 = baseArc.Vertex1, Vertex2 = baseArc.Vertex2 }; if (!_removedArcs.Contains(arc)) { // the arc was not removed, also return it. arcs.Add(new Tuple <long, long, TEdge, ICoordinateCollection>( baseArc.Vertex1, baseArc.Vertex2, baseArc.EdgeData, baseArc.Intermediates)); } } // also include new arcs. var inBoxNewVertices = new HashSet <long>(); foreach (var newVertex in _newVertices) { if (box.Contains(newVertex.Value)) { inBoxNewVertices.Add(newVertex.Key); } } // check arcs to include. foreach (var newArc in _newEdges) { var arc = new Arc() { Vertex1 = newArc.Key, Vertex2 = newArc.Value.Key }; if (inBoxNewVertices.Contains(arc.Vertex1) || inBoxNewVertices.Contains(arc.Vertex2)) { // ok, vertices are contained. arcs.Add(new Tuple <long, long, TEdge, ICoordinateCollection>( newArc.Key, newArc.Value.Key, newArc.Value.Value.Item1, newArc.Value.Value.Item2)); } } return(arcs.ToArray()); }
/// <summary> /// Builds the scene. /// </summary> /// <param name="map"></param> /// <param name="zoomFactor"></param> /// <param name="center"></param> /// <param name="view"></param> private void BuildScene(Map map, float zoomFactor, GeoCoordinate center, View2D view) { // build the boundingbox. var viewBox = view.OuterBox; var box = new GeoCoordinateBox(map.Projection.ToGeoCoordinates(viewBox.Min[0], viewBox.Min[1]), map.Projection.ToGeoCoordinates(viewBox.Max[0], viewBox.Max[1])); var zoomLevel = (int)map.Projection.ToZoomLevel(zoomFactor); if (_lastBox != null && _lastBox.Contains(box) && zoomLevel == _lastZoom) { return; } _lastBox = box; _lastZoom = zoomLevel; lock (_index) { _primitives = _index.Get(view, zoomFactor); } }
private bool IsInBB(OsmGeo osmGeo) { bool flag = false; switch (osmGeo.Type) { case OsmGeoType.Node: GeoCoordinateBox box = this._box; double? nullable = (osmGeo as Node).Latitude; double latitude = nullable.Value; nullable = (osmGeo as Node).Longitude; double longitude = nullable.Value; GeoCoordinate geoCoordinate = new GeoCoordinate(latitude, longitude); flag = box.Contains((PointF2D)geoCoordinate); break; case OsmGeoType.Way: foreach (long node in (osmGeo as Way).Nodes) { if (this._nodesIn.Contains(node)) { flag = true; break; } } if (flag) { using (List <long> .Enumerator enumerator = (osmGeo as Way).Nodes.GetEnumerator()) { while (enumerator.MoveNext()) { this._nodesToInclude.Add(enumerator.Current); } break; } } else { break; } case OsmGeoType.Relation: if (!this._relationsConsidered.Contains(osmGeo.Id.Value)) { foreach (RelationMember member in (osmGeo as Relation).Members) { switch (member.MemberType.Value) { case OsmGeoType.Node: if (this._nodesIn.Contains(member.MemberId.Value)) { flag = true; continue; } continue; case OsmGeoType.Way: if (this._waysIn.Contains(member.MemberId.Value)) { flag = true; continue; } continue; case OsmGeoType.Relation: if (this._relationIn.Contains(member.MemberId.Value)) { flag = true; continue; } continue; default: continue; } } if (flag) { using (List <RelationMember> .Enumerator enumerator = (osmGeo as Relation).Members.GetEnumerator()) { while (enumerator.MoveNext()) { RelationMember current = enumerator.Current; switch (current.MemberType.Value) { case OsmGeoType.Node: this._nodesToInclude.Add(current.MemberId.Value); continue; case OsmGeoType.Way: this._waysToInclude.Add(current.MemberId.Value); continue; case OsmGeoType.Relation: this._relationsToInclude.Add(current.MemberId.Value); continue; default: continue; } } break; } } else { break; } } else { break; } } return(flag); }
/// <summary> /// Adds the given node. /// </summary> /// <param name="node"></param> public override void AddNode(Node node) { if (!_preIndexMode) { if (_nodesToCache != null && _nodesToCache.Contains(node.Id.Value)) { // cache this node? _dataCache.AddNode(node); } if (_preIndex != null && _preIndex.Contains(node.Id.Value)) { // only save the coordinates for relevant nodes. // save the node-coordinates. // add the relevant nodes. if (_box == null || _box.Contains(new GeoCoordinate((float)node.Latitude.Value, (float)node.Longitude.Value))) { // the coordinate is acceptable. _coordinates[node.Id.Value] = new GeoCoordinateSimple() { Latitude = (float)node.Latitude.Value, Longitude = (float)node.Longitude.Value }; if (_coordinates.Count == _preIndex.Count) { _preIndex.Clear(); _preIndex = null; } if (_bounds == null) { // create bounds. _bounds = new GeoCoordinateBox( new GeoCoordinate(node.Latitude.Value, node.Longitude.Value), new GeoCoordinate(node.Latitude.Value, node.Longitude.Value)); } else { // expand bounds. _bounds.ExpandWith( new GeoCoordinate(node.Latitude.Value, node.Longitude.Value)); } // add the node as a possible restriction. if (_interpreter.IsRestriction(OsmGeoType.Node, node.Tags)) { // tests quickly if a given node is possibly a restriction. List <Vehicle> vehicles = _interpreter.CalculateRestrictions(node); if (vehicles != null && vehicles.Count > 0) { // add all the restrictions. uint vertexId = this.AddRoadNode(node.Id.Value).Value; // will always exists, has just been added to coordinates. uint[] restriction = new uint[] { vertexId }; if (vehicles.Contains(null)) { // restriction is valid for all vehicles. _dynamicGraph.AddRestriction(restriction); } else { // restriction is restricted to some vehicles only. foreach (Vehicle vehicle in vehicles) { _dynamicGraph.AddRestriction(vehicle, restriction); } } } } } } } }
public override IList <OsmGeo> Get(GeoCoordinateBox box, Filter filter) { List <OsmGeo> osmGeoList1 = new List <OsmGeo>(); HashSet <long> longSet1 = new HashSet <long>(); foreach (Node node in this._nodes.Values) { if (filter == null || filter.Evaluate((OsmGeo)node)) { GeoCoordinateBox geoCoordinateBox = box; double? nullable = node.Latitude; double latitude = nullable.Value; nullable = node.Longitude; double longitude = nullable.Value; GeoCoordinate geoCoordinate = new GeoCoordinate(latitude, longitude); if (geoCoordinateBox.Contains((PointF2D)geoCoordinate)) { osmGeoList1.Add((OsmGeo)node); longSet1.Add(node.Id.Value); } } } osmGeoList1.AddRange(this.GetWaysFor((IEnumerable <long>)longSet1).Cast <OsmGeo>()); List <Relation> source = new List <Relation>(); HashSet <long> longSet2 = new HashSet <long>(); foreach (OsmGeo osmGeo in osmGeoList1) { foreach (Relation relation in (IEnumerable <Relation>) this.GetRelationsFor(osmGeo)) { if (!longSet2.Contains(relation.Id.Value)) { source.Add(relation); longSet2.Add(relation.Id.Value); } } } do { osmGeoList1.AddRange(source.Cast <OsmGeo>()); List <Relation> relationList = new List <Relation>(); foreach (OsmGeo osmGeo in source) { foreach (Relation relation in (IEnumerable <Relation>) this.GetRelationsFor(osmGeo)) { if (!longSet2.Contains(relation.Id.Value)) { relationList.Add(relation); longSet2.Add(relation.Id.Value); } } } source = relationList; }while (source.Count > 0); if (filter != null) { List <OsmGeo> osmGeoList2 = new List <OsmGeo>(); foreach (OsmGeo osmGeo in osmGeoList1) { if (filter.Evaluate(osmGeo)) { osmGeoList2.Add(osmGeo); } } } return((IList <OsmGeo>)osmGeoList1); }
/// <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); }
/// <summary> /// Returns true if the given object is relevant in the bounding box. /// </summary> /// <param name="osmGeo"></param> /// <returns></returns> private bool IsInBB(OsmGeo osmGeo) { bool isIn = false; switch (osmGeo.Type) { case OsmGeoType.Node: isIn = _box.Contains(new GeoCoordinate( (osmGeo as Node).Latitude.Value, (osmGeo as Node).Longitude.Value)); break; case OsmGeoType.Way: foreach (long nodeId in (osmGeo as Way).Nodes) { if (_nodesIn.Contains(nodeId)) { isIn = true; break; } } if (isIn) { foreach (long nodeId in (osmGeo as Way).Nodes) { _nodesToInclude.Add(nodeId); } } break; case OsmGeoType.Relation: if (!_relationsConsidered.Contains(osmGeo.Id.Value)) { foreach (RelationMember member in (osmGeo as Relation).Members) { switch (member.MemberType.Value) { case OsmGeoType.Node: if (_nodesIn.Contains(member.MemberId.Value)) { isIn = true; break; } break; case OsmGeoType.Way: if (_waysIn.Contains(member.MemberId.Value)) { isIn = true; break; } break; case OsmGeoType.Relation: if (_relationIn.Contains(member.MemberId.Value)) { isIn = true; break; } break; } } if (isIn) { foreach (RelationMember member in (osmGeo as Relation).Members) { switch (member.MemberType.Value) { case OsmGeoType.Node: _nodesToInclude.Add(member.MemberId.Value); break; case OsmGeoType.Way: _waysToInclude.Add(member.MemberId.Value); break; case OsmGeoType.Relation: _relationsToInclude.Add(member.MemberId.Value); break; } } } } break; } return(isIn); }
/// <summary> /// Calculates edge data. /// </summary> /// <param name="edgeInterpreter"></param> /// <param name="tagsIndex"></param> /// <param name="tags"></param> /// <param name="tagsForward"></param> /// <param name="from"></param> /// <param name="to"></param> /// <param name="intermediates"></param> /// <returns></returns> protected override CHEdgeData CalculateEdgeData(IEdgeInterpreter edgeInterpreter, ITagsIndex tagsIndex, TagsCollectionBase tags, bool tagsForward, GeoCoordinate from, GeoCoordinate to, List <GeoCoordinateSimple> intermediates) { var direction = _vehicle.IsOneWay(tags); var forward = false; var backward = false; if (!direction.HasValue) { // both directions. forward = true; backward = true; } else { // define back/forward. if (tagsForward) { // relatively same direction. forward = direction.Value; backward = !direction.Value; } else { // relatively opposite direction. forward = !direction.Value; backward = direction.Value; } } // add tags. uint tagsId = 0; if (_storeTags) { // yes, store the tags! tagsId = tagsIndex.Add(tags); } // calculate weight including intermediates. var shapeInBox = true; float weight = 0; var previous = from; if (intermediates != null) { var box = new GeoCoordinateBox(from, to); for (int idx = 0; idx < intermediates.Count; idx++) { var current = new GeoCoordinate(intermediates[idx].Latitude, intermediates[idx].Longitude); weight = weight + (float)_vehicle.Weight(tags, previous, current); previous = current; if (!box.Contains(intermediates[idx].Longitude, intermediates[idx].Latitude)) { // shape not in box. shapeInBox = false; } } } weight = weight + (float)_vehicle.Weight(tags, previous, to); // initialize the edge data. var edge = new CHEdgeData(tagsId, tagsForward, forward, backward, weight); edge.ShapeInBox = shapeInBox; return(edge); }
/// <summary> /// Returns all objects in the given bounding box and that pass the given filter. /// </summary> /// <param name="box"></param> /// <param name="filter"></param> /// <returns></returns> public override IList <OsmGeo> Get(GeoCoordinateBox box, OsmSharp.Osm.Filters.Filter filter) { List <OsmGeo> res = new List <OsmGeo>(); // create a range or tiles around the given bounding box. TileRange range = TileRange.CreateAroundBoundingBox(box, 14); // build all redis keys for the given boxes. var hashKeys = new List <string>(); foreach (Tile tile in range) { hashKeys.Add(tile.Id.ToString()); } byte[][] box_members = _client.SUnion(hashKeys.ToArray()); HashSet <string> nodeKeys = new HashSet <string>(); foreach (byte[] box_member in box_members) { long node_id = BitConverter.ToInt64(box_member, 0); string node_key = PrimitiveExtensions.BuildNodeRedisKey(node_id); nodeKeys.Add(node_key); } List <RedisNode> redisNodes = _clientNode.GetValues(new List <string>(nodeKeys)); var nodeIds = new List <long>(); foreach (RedisNode redisNode in redisNodes) { // test if the node is in the given bb. GeoCoordinate coordinate = new GeoCoordinate(redisNode.Latitude.Value, redisNode.Longitude.Value); if (box.Contains(coordinate)) { res.Add(PrimitiveExtensions.ConvertFrom(redisNode)); nodeIds.Add(redisNode.Id.Value); } } // load all ways that contain the nodes that have been found. res.AddRange(this.GetWaysFor(nodeIds)); // 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); // add previous relations-list. 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); }