Пример #1
0
        /// <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();
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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)
                });
            }
        }
Пример #4
0
        /// <summary>
        /// Gets the edge with the given id.
        /// </summary>
        /// <returns></returns>
        public RoutingEdge GetEdge(uint edgeId)
        {
            var edge = _graph.GetEdge(edgeId);

            var baseEdgeData = Data.Edges.EdgeDataSerializer.Deserialize(
                edge.Data);
            var edgeData = new EdgeData()
            {
                MetaId   = _edgeData[edgeId],
                Distance = baseEdgeData.Distance,
                Profile  = baseEdgeData.Profile
            };

            return(new RoutingEdge(edge.Id, edge.From, edge.To, edgeData, edge.DataInverted, edge.Shape));
        }
Пример #5
0
        public void TestCompress()
        {
            var graph = new GeometricGraph(1, 100);

            graph.AddVertex(0, 0, 0);
            graph.AddVertex(1, 0, 0);
            var edgeId = graph.AddEdge(0, 1, new uint[] { 10 }, new Coordinate()
            {
                Latitude  = 1,
                Longitude = 1
            });

            graph.Compress();

            var edge = graph.GetEdge(edgeId);

            Assert.IsNotNull(edge);
            Assert.AreEqual(0, edge.From);
            Assert.AreEqual(1, edge.To);
            Assert.AreEqual(edgeId, edge.Id);
            Assert.AreEqual(1, edge.Shape.Count);
            Assert.AreEqual(1, edge.Shape.First().Latitude);
            Assert.AreEqual(1, edge.Shape.First().Longitude);
        }
Пример #6
0
        /// <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;
        }
Пример #7
0
        /// <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;
        }
Пример #8
0
        /// <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;
        }
Пример #9
0
        /// <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;
        }