public void TestGetShape() { var graph = new GeometricGraph(2, 100); graph.AddVertex(0, 0, 0); graph.AddVertex(1, 1, 1); graph.AddVertex(2, 0, 1); graph.AddVertex(3, 0, 2); var edge1 = graph.AddEdge(0, 1, new uint[] { 0, 10 }, new Coordinate(0.25f, 0.25f), new Coordinate(0.50f, 0.50f), new Coordinate(0.75f, 0.75f)); var shape = graph.GetShape(graph.GetEdge(edge1)); Assert.IsNotNull(shape); Assert.AreEqual(5, shape.Count); Assert.AreEqual(0, shape[0].Latitude); Assert.AreEqual(0, shape[0].Longitude); Assert.AreEqual(0.25, shape[1].Latitude); Assert.AreEqual(0.25, shape[1].Longitude); Assert.AreEqual(0.5, shape[2].Latitude); Assert.AreEqual(0.5, shape[2].Longitude); Assert.AreEqual(0.75, shape[3].Latitude); Assert.AreEqual(0.75, shape[3].Longitude); Assert.AreEqual(1, shape[4].Latitude); Assert.AreEqual(1, shape[4].Longitude); shape = graph.GetShape(graph.GetEdgeEnumerator(0).First()); Assert.IsNotNull(shape); Assert.AreEqual(5, shape.Count); Assert.AreEqual(0, shape[0].Latitude); Assert.AreEqual(0, shape[0].Longitude); Assert.AreEqual(0.25, shape[1].Latitude); Assert.AreEqual(0.25, shape[1].Longitude); Assert.AreEqual(0.5, shape[2].Latitude); Assert.AreEqual(0.5, shape[2].Longitude); Assert.AreEqual(0.75, shape[3].Latitude); Assert.AreEqual(0.75, shape[3].Longitude); Assert.AreEqual(1, shape[4].Latitude); Assert.AreEqual(1, shape[4].Longitude); shape = graph.GetShape(graph.GetEdgeEnumerator(1).First(x => x.To == 0)); Assert.IsNotNull(shape); Assert.AreEqual(5, shape.Count); Assert.AreEqual(1, shape[0].Latitude); Assert.AreEqual(1, shape[0].Longitude); Assert.AreEqual(0.75, shape[1].Latitude); Assert.AreEqual(0.75, shape[1].Longitude); Assert.AreEqual(0.5, shape[2].Latitude); Assert.AreEqual(0.5, shape[2].Longitude); Assert.AreEqual(0.25, shape[3].Latitude); Assert.AreEqual(0.25, shape[3].Longitude); Assert.AreEqual(0, shape[4].Latitude); Assert.AreEqual(0, shape[4].Longitude); }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun() { // create dykstra algorithm. // search forward starting from sourcePaths with no restrictions. var dykstra = new Dykstra(_geometricGraph.Graph, _getFactor, v => Constants.NO_VERTEX, _source, _limitInSeconds, false); dykstra.WasEdgeFound += (v1, v2, w1, w2, e, length) => { if (Visit == null) { return(false); } // Calculate weight at start vertex. uint edgeId; if (e > 0) { edgeId = (uint)e - 1; } else { edgeId = (uint)((-e) - 1); } var edge = _geometricGraph.GetEdge(edgeId); var shape = _geometricGraph.GetShape(edge); Visit?.Invoke(e, v1, w1, v2, w2, shape); return(false); // return false, returning true stops the search! }; dykstra.Run(); }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun() { var tiles = new Dictionary <TileIndex, RoutingTile>(); _polygons = new List <Polygon>(); _edgeVisitor.Visit += (path) => { var e = path.Edge; var endWeight = path.Weight; if (e == Constants.NO_EDGE || path.From == null) { return(false); } var startWeight = path.From.Weight; // Calculate weight at start vertex. uint edgeId; if (e > 0) { edgeId = (uint)e - 1; } else { edgeId = (uint)((-e) - 1); } var edge = _graph.GetEdge(edgeId); var shape = _graph.GetShape(edge); this.AddEdgeVisit(tiles, startWeight, endWeight, shape); return(false); }; _edgeVisitor.Run(); var tileList = tiles.Values.ToList(); tileList = UpdateForWalking(tileList, _level, _walkingSpeed, _limits.Max()); foreach (var isochroneLimit in _limits) { var tilesWithin = tileList.Where(t => t.Weight < isochroneLimit).ToList(); var polygonOfTileIndexes = TilesToPolygon.TileSetToPolygon(tilesWithin); _polygons.Add(new Polygon { ExteriorRing = TileHelper.ToWorldCoordinates(polygonOfTileIndexes, _level) }); } }
/// <summary> /// Gets all features inside the given bounding box. /// </summary> public static FeatureCollection GetFeaturesIn(this GeometricGraph graph, float minLatitude, float minLongitude, float maxLatitude, float maxLongitude) { var features = new FeatureCollection(); var vertices = Itinero.Algorithms.Search.Hilbert.HilbertExtensions.Search(graph, minLatitude, minLongitude, maxLatitude, maxLongitude); var edges = new HashSet <long>(); var edgeEnumerator = graph.GetEdgeEnumerator(); foreach (var vertex in vertices) { var attributes = new AttributesTable(); attributes.AddAttribute("id", vertex.ToInvariantString()); var vertexLocation = graph.GetVertex(vertex); features.Add(new Feature(new Point(vertexLocation.ToCoordinate()), attributes)); edgeEnumerator.MoveTo(vertex); edgeEnumerator.Reset(); while (edgeEnumerator.MoveNext()) { if (edges.Contains(edgeEnumerator.Id)) { continue; } edges.Add(edgeEnumerator.Id); var geometry = new LineString(graph.GetShape(edgeEnumerator.Current).ToCoordinatesArray()); attributes = new AttributesTable(); attributes.AddAttribute("id", edgeEnumerator.Id.ToInvariantString()); features.Add(new Feature(geometry, attributes)); } } return(features); }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun(CancellationToken cancellationToken) { var tiles = new Dictionary <TileIndex, RoutingTile>(); _edgeVisitor.Visit += (path) => { var e = path.Edge; var endWeight = path.Weight; if (e == Constants.NO_EDGE) { return(false); } // Calculate weight at start vertex. uint edgeId; if (e > 0) { edgeId = (uint)e - 1; } else { edgeId = (uint)((-e) - 1); } var edge = _graph.GetEdge(edgeId); var shape = _graph.GetShape(edge); var endCoordinate = shape[shape.Count - 1]; var index = TileIndex.WorldToTileIndex(endCoordinate.Latitude, endCoordinate.Longitude, _level); RoutingTile tile; if (!tiles.TryGetValue(index, out tile)) { tile = new RoutingTile { Weight = endWeight, Count = 1, Index = index }; } else { tile.Weight = (tile.Weight * tile.Count + endWeight) / tile.Count + 1; tile.Count++; } tiles[index] = tile; return(false); }; _edgeVisitor.Run(cancellationToken); _result = new HeatmapResult(); _result.Data = new HeatmapSample[tiles.Count]; var max = 0f; var i = 0; foreach (var pair in tiles) { var location = TileIndex.TileIndexToWorld(pair.Key.X, pair.Key.Y, _level); _result.Data[i] = new HeatmapSample() { Latitude = location.Latitude, Longitude = location.Longitude, Value = pair.Value.Weight }; if (max < pair.Value.Weight) { max = pair.Value.Weight; } i++; } _result.Max = max; this.HasSucceeded = true; }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun(CancellationToken cancellationToken) { _edges = new HashSet <uint>(); _treeEdges = new List <TreeEdge>(); _edgeVisitor.Visit += (path) => { var e = path.Edge; var weight2 = path.Weight; if (e == Constants.NO_EDGE) { return(false); } var previousEdgeId = Constants.NO_EDGE; var weight1 = 0f; if (path.From != null) { weight1 = path.From.Weight; if (path.From.Edge > 0) { previousEdgeId = (uint)path.From.Edge - 1; } else { previousEdgeId = (uint)((-path.From.Edge) - 1); } } uint edgeId; if (e > 0) { edgeId = (uint)e - 1; } else { edgeId = (uint)((-e) - 1); } var edge = _graph.GetEdge(edgeId); var shape = _graph.GetShape(edge); if (e < 0) { shape.Reverse(); } var shapeArray = new float[shape.Count][]; for (var i = 0; i < shapeArray.Length; i++) { shapeArray[i] = new float[2]; shapeArray[i][1] = shape[i].Latitude; shapeArray[i][0] = shape[i].Longitude; } var treeEdge = new TreeEdge() { EdgeId = edgeId, PreviousEdgeId = previousEdgeId, Shape = shapeArray, Weight1 = weight1, Weight2 = weight2 }; _treeEdges.Add(treeEdge); if (_max < weight2) { _max = weight2; } return(false); }; _edgeVisitor.Run(cancellationToken); _tree = new Tree() { Edges = _treeEdges.ToArray(), Max = _max }; this.HasSucceeded = true; }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun() { // calculate maxOffset in degrees. var offsettedLocation = (new Coordinate(_latitude, _longitude)).OffsetWithDistances(_maxOffsetInMeter); var latitudeOffset = System.Math.Abs(_latitude - offsettedLocation.Latitude); var longitudeOffset = System.Math.Abs(_longitude - offsettedLocation.Longitude); // get the closest edge. uint[] edgeIds = null; if (_isBetter == null) { // do not evaluate both, just isOk. edgeIds = new uint[2]; edgeIds[0] = _graph.SearchClosestEdge(_latitude, _longitude, latitudeOffset, longitudeOffset, _maxDistance, _isAcceptable); } else { // evaluate both. edgeIds = _graph.SearchClosestEdges(_latitude, _longitude, latitudeOffset, longitudeOffset, _maxDistance, new Func <GeometricEdge, bool>[] { _isAcceptable, (potentialEdge) => { // at least also make sure the edge is acceptable. if (_isAcceptable(potentialEdge)) { return(_isBetter(potentialEdge)); } return(false); } }); } if (edgeIds[0] == Constants.NO_EDGE) { // oeps, no edge was found, too far from road network. this.ErrorMessage = string.Format("Could not resolve point at [{0}, {1}]. Probably too far from closest road or outside of the loaded network.", _latitude.ToInvariantString(), _longitude.ToInvariantString()); return; } // project onto the edge. var edge = _graph.GetEdge(edgeIds[0]); var edgeId = edgeIds[0]; float projectedLatitude, projectedLongitude, projectedDistanceFromFirst, totalLength, distanceToProjected; int projectedShapeIndex; if (!_graph.ProjectOn(edge, _latitude, _longitude, out projectedLatitude, out projectedLongitude, out projectedDistanceFromFirst, out projectedShapeIndex, out distanceToProjected, out totalLength)) { // oeps, could not project onto edge. var points = _graph.GetShape(edge); var previous = points[0]; var bestProjectedDistanceFromFirst = 0.0f; projectedDistanceFromFirst = 0; var bestDistanceToProjected = Coordinate.DistanceEstimateInMeter(previous, new Coordinate(_latitude, _longitude)); projectedLatitude = previous.Latitude; projectedLongitude = previous.Longitude; for (var i = 1; i < points.Count; i++) { var current = points[i]; projectedDistanceFromFirst += Coordinate.DistanceEstimateInMeter(current, previous); distanceToProjected = Coordinate.DistanceEstimateInMeter(current, new Coordinate(_latitude, _longitude)); if (distanceToProjected < bestDistanceToProjected) { bestDistanceToProjected = distanceToProjected; bestProjectedDistanceFromFirst = projectedDistanceFromFirst; projectedLatitude = current.Latitude; projectedLongitude = current.Longitude; } previous = current; } // set best distance. projectedDistanceFromFirst = bestProjectedDistanceFromFirst; } if (_isBetter != null) { // there was a request to search for better edges. if (edgeIds[0] != edgeIds[1] && edgeIds[1] != Constants.NO_EDGE) { // edges are not equal, check if the better edge is acceptable. // project onto the better edge. var edge1 = _graph.GetEdge(edgeIds[1]); float projectedLatitude1, projectedLongitude1, projectedDistanceFromFirst1, totalLength1, distanceToProjected1; int projectedShapeIndex1; if (!_graph.ProjectOn(edge1, _latitude, _longitude, out projectedLatitude1, out projectedLongitude1, out projectedDistanceFromFirst1, out projectedShapeIndex1, out distanceToProjected1, out totalLength1)) { // oeps, could not project onto edge. var points = _graph.GetShape(edge1); var previous = points[0]; var bestProjectedDistanceFromFirst = 0.0f; projectedDistanceFromFirst1 = 0; var bestDistanceToProjected = Coordinate.DistanceEstimateInMeter(previous, new Coordinate(_latitude, _longitude)); projectedLatitude1 = previous.Latitude; projectedLongitude1 = previous.Longitude; for (var i = 1; i < points.Count; i++) { var current = points[i]; projectedDistanceFromFirst1 += Coordinate.DistanceEstimateInMeter(current, previous); distanceToProjected1 = Coordinate.DistanceEstimateInMeter(current, new Coordinate(_latitude, _longitude)); if (distanceToProjected1 < bestDistanceToProjected) { bestDistanceToProjected = distanceToProjected1; bestProjectedDistanceFromFirst = projectedDistanceFromFirst1; projectedLatitude1 = current.Latitude; projectedLongitude1 = current.Longitude; } previous = current; } // set best distance. projectedDistanceFromFirst1 = bestProjectedDistanceFromFirst; } if (distanceToProjected1 <= BetterEdgeThreshold || distanceToProjected1 <= distanceToProjected * BetterEdgeFactor) { // ok, take the better edge. totalLength = totalLength1; edgeId = edgeIds[1]; projectedLatitude = projectedLatitude1; projectedLongitude = projectedLongitude1; projectedDistanceFromFirst = projectedDistanceFromFirst1; } } } var offset = (ushort)((projectedDistanceFromFirst / totalLength) * ushort.MaxValue); _result = new RouterPoint(_latitude, _longitude, edgeId, offset); this.HasSucceeded = true; }
/// <summary> /// Executes the actual algorithm. /// </summary> protected override void DoRun() { _results = new List <RouterPoint>(); // get the closest edge. var edges = _graph.SearchCloserThan(_latitude, _longitude, _maxOffset, _maxDistance, _isAcceptable); if (edges.Count == 0) { // oeps, no edge was found, too far from road network. this.ErrorMessage = string.Format("Could not resolve point at [{0}, {1}]. Probably too far from closest road or outside of the loaded network.", _latitude.ToInvariantString(), _longitude.ToInvariantString()); return; } // project onto the edge. for (var e = 0; e < edges.Count; e++) { var edgeId = edges[e]; var edge = _graph.GetEdge(edgeId); float projectedLatitude, projectedLongitude, projectedDistanceFromFirst, totalLength, distanceToProjected; int projectedShapeIndex; if (!_graph.ProjectOn(edge, _latitude, _longitude, out projectedLatitude, out projectedLongitude, out projectedDistanceFromFirst, out projectedShapeIndex, out distanceToProjected, out totalLength)) { var points = _graph.GetShape(edge); var previous = points[0]; var bestProjectedDistanceFromFirst = 0.0f; projectedDistanceFromFirst = 0; var bestDistanceToProjected = Coordinate.DistanceEstimateInMeter(previous, new Coordinate(_latitude, _longitude)); projectedLatitude = previous.Latitude; projectedLongitude = previous.Longitude; for (var i = 1; i < points.Count; i++) { var current = points[i]; projectedDistanceFromFirst += Coordinate.DistanceEstimateInMeter(current, previous); distanceToProjected = Coordinate.DistanceEstimateInMeter(current, new Coordinate(_latitude, _longitude)); if (distanceToProjected < bestDistanceToProjected) { bestDistanceToProjected = distanceToProjected; bestProjectedDistanceFromFirst = projectedDistanceFromFirst; projectedLatitude = current.Latitude; projectedLongitude = current.Longitude; } previous = current; } // set best distance. projectedDistanceFromFirst = bestProjectedDistanceFromFirst; } var offset = (ushort)((projectedDistanceFromFirst / totalLength) * ushort.MaxValue); _results.Add(new RouterPoint(_latitude, _longitude, edgeId, offset)); } this.HasSucceeded = true; }