示例#1
0
 /// <summary>
 /// Tests the edge matcher in combination with dykstra routing.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="highway"></param>
 /// <param name="vehicle"></param>
 /// <param name="matcher"></param>
 /// <param name="found"></param>
 private void TestResolveOnEdge(string name, string highway,
                                Vehicle vehicle, IEdgeMatcher matcher, bool found)
 {
     this.TestResolveOnEdgeSingle(name, highway, vehicle, null, null, !found);
     this.TestResolveOnEdgeSingle(name, highway, vehicle, matcher, null, !found);
     this.TestResolveOnEdgeSingle(name, highway, vehicle, matcher, name, !found);
 }
示例#2
0
        /// <summary>
        /// Resolves a point.
        /// </summary>
        /// <param name="vehicle">The vehicle profile.</param>
        /// <param name="coordinate">The location of the point to resolve.</param>
        /// <param name="matcher">The matcher containing some matching algorithm.</param>
        /// <param name="matchingTags">Extra matching data.</param>
        /// <returns></returns>
        public RouterPoint Resolve(Vehicle vehicle, GeoCoordinate coordinate, IEdgeMatcher matcher,
                                   TagsCollectionBase matchingTags)
        {
            if (vehicle == null)
            {
                throw new ArgumentNullException("vehicle");
            }
            if (coordinate == null)
            {
                throw new ArgumentNullException("coordinate");
            }
            if (matcher == null)
            {
                throw new ArgumentNullException("matcher");
            }
            if (matchingTags == null)
            {
                throw new ArgumentNullException("matchingTags");
            }

            return(_router.Resolve(vehicle, coordinate, matcher, matchingTags));
        }
示例#3
0
        /// <summary>
        /// Resolves all the given points.
        /// </summary>
        /// <param name="vehicle">The vehicle profile.</param>
        /// <param name="delta">The size of the box to search in.</param>
        /// <param name="coordinates">The location of the points to resolve.</param>
        /// <param name="matcher">The matcher containing some matching algorithm.</param>
        /// <param name="matchingTags">Extra matching data.</param>
        /// <returns></returns>
        public RouterPoint[] Resolve(Vehicle vehicle, float delta, GeoCoordinate[] coordinates,
                                     IEdgeMatcher matcher, TagsCollectionBase[] matchingTags)
        {
            if (vehicle == null)
            {
                throw new ArgumentNullException("vehicle");
            }
            if (coordinates == null)
            {
                throw new ArgumentNullException("coordinates");
            }
            if (matcher == null)
            {
                throw new ArgumentNullException("matcher");
            }
            if (matchingTags == null)
            {
                throw new ArgumentNullException("matchingTags");
            }

            return(_router.Resolve(vehicle, delta, coordinates, matcher, matchingTags));
        }
示例#4
0
        /// <summary>
        /// Tests the edge matcher in combination with dykstra routing.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="highway"></param>
        /// <param name="vehicle"></param>
        /// <param name="matcher"></param>
        /// <param name="pointName"></param>
        /// <param name="notFound"></param>
        private void TestResolveOnEdgeSingle(string name, string highway,
                                             Vehicle vehicle, IEdgeMatcher matcher,
                                             string pointName, bool notFound)
        {
            var fromName = new GeoCoordinate(51.0003, 4.0007);
            var toName   = new GeoCoordinate(51.0003, 4.0008);

            var fromNoname = new GeoCoordinate(51.0, 4.0007);
            var toNoname   = new GeoCoordinate(51.0, 4.0008);

            TagsCollectionBase pointTags = new TagsCollection();

            pointTags["name"] = pointName;

            TagsCollectionBase tags = new TagsCollection();

            tags["highway"] = highway;
            //tags["name"] = name;

            var tagsIndex = new TagsIndex();

            // do the data processing.
            var  data          = new RouterDataSource <Edge>(new Graph <Edge>(), tagsIndex);
            uint vertexNoname1 = data.AddVertex((float)fromNoname.Latitude, (float)fromNoname.Longitude);
            uint vertexNoname2 = data.AddVertex((float)toNoname.Latitude, (float)toNoname.Longitude);

            data.AddEdge(vertexNoname1, vertexNoname2, new Edge()
            {
                Forward = true,
                Tags    = tagsIndex.Add(tags)
            }, null);
            tags            = new TagsCollection();
            tags["highway"] = highway;
            tags["name"]    = name;
            uint vertexName1 = data.AddVertex((float)fromName.Latitude, (float)fromName.Longitude);
            uint vertexName2 = data.AddVertex((float)toName.Latitude, (float)toName.Longitude);

            data.AddEdge(vertexName1, vertexName2, new Edge()
            {
                Forward = true,
                Tags    = tagsIndex.Add(tags)
            }, null);

            IRoutingInterpreter interpreter = new OsmRoutingInterpreter();

            // creates the data.
            IRoutingAlgorithm <Edge> router = new Dykstra();

            var nonameLocation = new GeoCoordinate(
                (fromNoname.Latitude + toNoname.Latitude) / 2.0,
                (fromNoname.Longitude + toNoname.Longitude) / 2.0);
//            var nameLocation = new GeoCoordinate(
//                (fromName.Latitude + toName.Latitude) / 2.0,
//                (fromName.Longitude + toName.Longitude) / 2.0);

            const float delta  = 0.01f;
            var         result = router.SearchClosest(data, interpreter, vehicle, nonameLocation, delta, matcher, pointTags, null);

            if (result.Distance < double.MaxValue)
            { // there is a result.
                Assert.IsFalse(notFound, "A result was found but was supposed not to  be found!");

                if (name == pointName)
                { // the name location was supposed to be found!
                    Assert.IsTrue(result.Vertex1 == vertexName1 || result.Vertex1 == vertexName2);
                    Assert.IsTrue(result.Vertex2 == vertexName1 || result.Vertex2 == vertexName2);
                }
                else
                { // the noname location was supposed to be found!
                    Assert.IsTrue(result.Vertex1 == vertexNoname1 || result.Vertex1 == vertexNoname2);
                    Assert.IsTrue(result.Vertex2 == vertexNoname1 || result.Vertex2 == vertexNoname2);
                }
                return;
            }
            Assert.IsTrue(notFound, "A result was not found but was supposed to be found!");
        }
示例#5
0
        /// <summary>
        /// Resolves all the given points.
        /// </summary>
        /// <param name="vehicle">The vehicle profile.</param>
        /// <param name="delta">The size of the box to search in.</param>
        /// <param name="coordinates">The location of the points to resolve.</param>
        /// <param name="matcher">The matcher containing some matching algorithm.</param>
        /// <param name="matchingTags">Extra matching data.</param>
        /// <returns></returns>
        public RouterPoint[] Resolve(Vehicle vehicle, float delta, GeoCoordinate[] coordinates, 
			IEdgeMatcher matcher, TagsCollectionBase[] matchingTags, CancellationToken cancellationToken = new CancellationToken())
        {
            if (vehicle == null) { throw new ArgumentNullException("vehicle"); }
            if (coordinates == null) { throw new ArgumentNullException("coordinates"); }
            if (matcher == null) { throw new ArgumentNullException("matcher"); }
            if (matchingTags == null) { throw new ArgumentNullException("matchingTags"); }

            return _router.Resolve(vehicle, delta, coordinates, matcher, matchingTags, cancellationToken);
        }
        /// <summary>
        /// Calculates a matrix of weights between all given points.
        /// </summary>
        /// <param name="operation">The operation request.</param>
        /// <param name="router">The router.</param>
        /// <param name="matcher">Contains an algorithm to match points to the route network.</param>
        /// <returns></returns>
        private RoutingResponse DoManyToMany(
            RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher)
        {
            // create the response.
            var response = new RoutingResponse();

            // resolve the points and do the routing.
            var routerPoints = new List<RouterPoint>();
            var unroutableHooks = new List<RoutingHook>(); // save the unroutable hooks.
            for (int idx = 0; idx < operation.Hooks.Length; idx++)
            {
                // routing hook tags.
                IDictionary<string, string> tags = operation.Hooks[idx].Tags.ConvertToDictionary();

                // resolve the point.
                RouterPoint routerPoint = router.Resolve(operation.Vehicle, new GeoCoordinate(
                    operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, tags);

                // check the result.
                if (routerPoint == null)
                {
                    // this hook is not routable.
                    unroutableHooks.Add(operation.Hooks[idx]);
                }
                else
                {
                    // a point to hook on was found!
                    // check if the router point is routable.
                    if (router.CheckConnectivity(operation.Vehicle, routerPoint, 200))
                    {
                        // the point is routable.

                        // add the new router point to the list.
                        routerPoint.Tags.Add(new KeyValuePair<string, string>("id", routerPoints.Count.ToString(
                            System.Globalization.CultureInfo.InvariantCulture)));
                        routerPoints.Add(routerPoint);
                    }
                    else
                    {
                        // this hook is not routable.
                        unroutableHooks.Add(operation.Hooks[idx]);
                    }
                }
            }

            // add the unroutable hooks.
            response.UnroutableHooks = unroutableHooks.ToArray();

            // calculate and fill the response.
            response.Weights = router.CalculateManyToManyWeight(operation.Vehicle, routerPoints.ToArray(),
                routerPoints.ToArray());

            // report succes!
            response.Status = OsmSharpServiceResponseStatusEnum.Success;
            response.StatusMessage = string.Empty;

            return response;
        }
示例#7
0
 /// <summary>
 /// Tests the edge matcher in combination with dykstra routing.
 /// </summary>
 /// <param name="name"></param>
 /// <param name="highway"></param>
 /// <param name="vehicle"></param>
 /// <param name="matcher"></param>
 /// <param name="found"></param>
 private void TestResolveOnEdge(string name, string highway,
     Vehicle vehicle, IEdgeMatcher matcher, bool found)
 {
     this.TestResolveOnEdgeSingle(name, highway, vehicle, null, null, !found);
     this.TestResolveOnEdgeSingle(name, highway, vehicle, matcher, null, !found);
     this.TestResolveOnEdgeSingle(name, highway, vehicle, matcher, name, !found);
 }
示例#8
0
        /// <summary>
        /// Tests the edge matcher in combination with dykstra routing.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="highway"></param>
        /// <param name="vehicle"></param>
        /// <param name="matcher"></param>
        /// <param name="pointName"></param>
        /// <param name="notFound"></param>
        private void TestResolveOnEdgeSingle(string name, string highway, 
            Vehicle vehicle, IEdgeMatcher matcher, 
            string pointName, bool notFound)
        {
            var fromName = new GeoCoordinate(51.0003, 4.0007);
            var toName = new GeoCoordinate(51.0003, 4.0008);

            var fromNoname = new GeoCoordinate(51.0, 4.0007);
            var toNoname = new GeoCoordinate(51.0, 4.0008);

            TagsCollection pointTags = new SimpleTagsCollection();
            pointTags["name"] = pointName;

            TagsCollection tags = new SimpleTagsCollection();
            tags["highway"] = highway;
            //tags["name"] = name;

            var tagsIndex = new SimpleTagsIndex();

            // do the data processing.
            var data = new DynamicGraphRouterDataSource<LiveEdge>(tagsIndex);
            uint vertexNoname1 = data.AddVertex((float)fromNoname.Latitude, (float)fromNoname.Longitude);
            uint vertexNoname2 = data.AddVertex((float)toNoname.Latitude, (float)toNoname.Longitude);
            data.AddArc(vertexNoname1, vertexNoname2, new LiveEdge()
            {
                Forward = true,
                Tags = tagsIndex.Add(tags)
            }, null);
            tags = new SimpleTagsCollection();
            tags["highway"] = highway;
            tags["name"] = name;
            uint vertexName1 = data.AddVertex((float)fromName.Latitude, (float)fromName.Longitude);
            uint vertexName2 = data.AddVertex((float)toName.Latitude, (float)toName.Longitude);
            data.AddArc(vertexName1, vertexName2, new LiveEdge()
            {
                Forward = true,
                Tags = tagsIndex.Add(tags)
            }, null);

            IRoutingInterpreter interpreter = new OsmRoutingInterpreter();

            // creates the data.
            IBasicRouter<LiveEdge> router = new DykstraRoutingLive();

            var nonameLocation = new GeoCoordinate(
                (fromNoname.Latitude + toNoname.Latitude) / 2.0,
                (fromNoname.Longitude + toNoname.Longitude) / 2.0);
            //            var nameLocation = new GeoCoordinate(
            //                (fromName.Latitude + toName.Latitude) / 2.0,
            //                (fromName.Longitude + toName.Longitude) / 2.0);

            const float delta = 0.01f;
            SearchClosestResult result = router.SearchClosest(data, interpreter, vehicle, nonameLocation, delta, matcher, pointTags);
            if (result.Distance < double.MaxValue)
            { // there is a result.
                Assert.IsFalse(notFound, "A result was found but was supposed not to  be found!");

                if (name == pointName)
                { // the name location was supposed to be found!
                    Assert.IsTrue(result.Vertex1 == vertexName1 || result.Vertex1 == vertexName2);
                    Assert.IsTrue(result.Vertex2 == vertexName1 || result.Vertex2 == vertexName2);
                }
                else
                { // the noname location was supposed to be found!
                    Assert.IsTrue(result.Vertex1 == vertexNoname1 || result.Vertex1 == vertexNoname2);
                    Assert.IsTrue(result.Vertex2 == vertexNoname1 || result.Vertex2 == vertexNoname2);
                }
                return;
            }
            Assert.IsTrue(notFound, "A result was not found but was supposed to be found!");
        }
示例#9
0
 /// <summary>
 /// Resolves a point.
 /// </summary>
 /// <param name="vehicle">The vehicle profile.</param>
 /// <param name="coordinate">The location of the point to resolve.</param>
 /// <param name="matcher">The matcher containing some matching algorithm.</param>
 /// <param name="matchingTags">Extra matching data.</param>
 /// <returns></returns>
 public RouterPoint Resolve(Vehicle vehicle, GeoCoordinate coordinate, IEdgeMatcher matcher,
                            TagsCollectionBase matchingTags)
 {
     return(_router.Resolve(vehicle, coordinate, matcher, matchingTags));
 }
示例#10
0
        /// <summary>
        /// Resolves all the given points.
        /// </summary>
        /// <param name="vehicle">The vehicle profile.</param>
        /// <param name="coordinates">The location of the points to resolve.</param>
        /// <param name="matcher">The matcher containing some matching algorithm.</param>
        /// <param name="matchingTags">Extra matching data.</param>
        /// <returns></returns>
        public RouterPoint[] Resolve(Vehicle vehicle, GeoCoordinate[] coordinates, IEdgeMatcher matcher, 
            TagsCollectionBase[] matchingTags)
        {
            if (vehicle == null) { throw new ArgumentNullException("vehicle"); }
            if (coordinates == null) { throw new ArgumentNullException("coordinates"); }
            if (matcher == null) { throw new ArgumentNullException("matcher"); }
            if (matchingTags == null) { throw new ArgumentNullException("matchingTags"); }

            return _router.Resolve(vehicle, coordinates, matcher, matchingTags);
        }
示例#11
0
 /// <summary>
 /// Searches the data for a point on an edge closest to the given coordinate.
 /// </summary>
 /// <param name="graph"></param>
 /// <param name="vehicle"></param>
 /// <param name="coordinate"></param>
 /// <param name="delta"></param>
 /// <param name="matcher"></param>
 /// <param name="pointTags"></param>
 /// <param name="interpreter"></param>
 public SearchClosestResult SearchClosest(IBasicRouterDataSource <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle,
                                          GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollection pointTags)
 {
     return(this.SearchClosest(graph, interpreter, vehicle, coordinate, delta, matcher, pointTags, false));
 }
示例#12
0
 /// <summary>
 /// Resolves a point.
 /// </summary>
 /// <param name="vehicle">The vehicle profile.</param>
 /// <param name="coordinate">The location of the point to resolve.</param>
 /// <param name="matcher">The matcher containing some matching algorithm.</param>
 /// <param name="matchingTags">Extra matching data.</param>
 /// <returns></returns>
 public RouterPoint Resolve(Vehicle vehicle, GeoCoordinate coordinate, IEdgeMatcher matcher, 
     TagsCollectionBase matchingTags)
 {
     return _router.Resolve(vehicle, coordinate, matcher, matchingTags);
 }
示例#13
0
        /// <summary>
        /// Searches the data for a point on an edge closest to the given coordinate.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="vehicle"></param>
        /// <param name="coordinate"></param>
        /// <param name="delta"></param>
        /// <param name="matcher"></param>
        /// <param name="pointTags"></param>
        /// <param name="interpreter"></param>
        /// <param name="verticesOnly"></param>
        /// <param name="parameters"></param>
        public SearchClosestResult <TEdgeData> SearchClosest(IRoutingAlgorithmData <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle,
                                                             GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollectionBase pointTags, bool verticesOnly, Dictionary <string, object> parameters)
        {
            Meter distanceEpsilon = .1; // 10cm is the tolerance to distinguish points.

            var closestWithMatch = new SearchClosestResult <TEdgeData>(double.MaxValue, 0);
            GeoCoordinateBox closestWithMatchBox = null;
            var closestWithoutMatch = new SearchClosestResult <TEdgeData>(double.MaxValue, 0);
            GeoCoordinateBox closestWithoutMatchBox = null;

            double searchBoxSize = delta;
            // create the search box.
            var searchBox = new GeoCoordinateBox(new GeoCoordinate(
                                                     coordinate.Latitude - searchBoxSize, coordinate.Longitude - searchBoxSize),
                                                 new GeoCoordinate(
                                                     coordinate.Latitude + searchBoxSize, coordinate.Longitude + searchBoxSize));

            // get the arcs from the data source.
            var edges = graph.GetEdges(searchBox);

            if (!verticesOnly)
            { // find both closest arcs and vertices.
                // loop over all.
                while (edges.MoveNext())
                {
                    //if (!graph.TagsIndex.Contains(edges.EdgeData.Tags))
                    //{ // skip this edge, no valid tags found.
                    //    continue;
                    //}

                    // test the two points.
                    float  fromLatitude, fromLongitude;
                    float  toLatitude, toLongitude;
                    double distance;
                    if (graph.GetVertex(edges.Vertex1, out fromLatitude, out fromLongitude) &&
                        graph.GetVertex(edges.Vertex2, out toLatitude, out toLongitude))
                    { // return the vertex.
                        var vertex1Coordinate = new GeoCoordinate(fromLatitude, fromLongitude);
                        var vertex2Coordinate = new GeoCoordinate(toLatitude, toLongitude);

                        if (edges.EdgeData.ShapeInBox)
                        { // ok, check if it is needed to even check this edge.
                            var edgeBox        = new GeoCoordinateBox(vertex1Coordinate, vertex2Coordinate);
                            var edgeBoxOverlap = false;
                            if (closestWithoutMatchBox == null ||
                                closestWithoutMatchBox.Overlaps(edgeBox))
                            { // edge box overlap.
                                edgeBoxOverlap = true;
                            }
                            else if (closestWithMatchBox == null ||
                                     closestWithMatchBox.Overlaps(edgeBox))
                            { // edge box overlap.
                                edgeBoxOverlap = true;
                            }
                            if (!edgeBoxOverlap)
                            { // no overlap, impossible this edge is a candidate.
                                continue;
                            }
                        }

                        var arcTags        = graph.TagsIndex.Get(edges.EdgeData.Tags);
                        var canBeTraversed = vehicle.CanTraverse(arcTags);
                        if (canBeTraversed)
                        { // the edge can be traversed.
                            distance = coordinate.DistanceEstimate(vertex1Coordinate).Value;
                            if (distance < distanceEpsilon.Value)
                            { // the distance is smaller than the tolerance value.
                                var diff = coordinate - vertex1Coordinate;
                                closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                              new GeoCoordinate(coordinate - diff));
                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                    distance, edges.Vertex1);
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                {
                                    closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                               new GeoCoordinate(coordinate - diff));
                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                        distance, edges.Vertex1);
                                    break;
                                }
                            }

                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller for the without match.
                                var diff = coordinate - vertex1Coordinate;
                                closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                              new GeoCoordinate(coordinate - diff));
                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                    distance, edges.Vertex1);
                            }
                            if (distance < closestWithMatch.Distance)
                            { // the distance is smaller for the with match.
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, graph.TagsIndex.Get(edges.EdgeData.Tags)))
                                {
                                    var diff = coordinate - vertex1Coordinate;
                                    closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                               new GeoCoordinate(coordinate - diff));
                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                        distance, edges.Vertex1);
                                }
                            }

                            distance = coordinate.DistanceEstimate(vertex2Coordinate).Value;
                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller for the without match.
                                var diff = coordinate - vertex2Coordinate;
                                closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                              new GeoCoordinate(coordinate - diff));
                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                    distance, edges.Vertex2);
                            }
                            if (distance < closestWithMatch.Distance)
                            { // the distance is smaller for the with match.
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                {
                                    var diff = coordinate - vertex2Coordinate;
                                    closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                               new GeoCoordinate(coordinate - diff));
                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                        distance, edges.Vertex2);
                                }
                            }
                            // search along the line.
                            var coordinatesArray         = new ICoordinate[0];
                            var distanceTotal            = 0.0;
                            var arcValueValueCoordinates = edges.Intermediates;
                            if (arcValueValueCoordinates != null)
                            { // calculate distance along all coordinates.
                                coordinatesArray = arcValueValueCoordinates.ToArray();
                            }

                            // loop over all edges that are represented by this arc (counting intermediate coordinates).
                            var previous = vertex1Coordinate;
                            GeoCoordinateLine line;
                            var distanceToSegment = 0.0;
                            if (arcValueValueCoordinates != null)
                            {
                                for (int idx = 0; idx < coordinatesArray.Length; idx++)
                                {
                                    var current = new GeoCoordinate(
                                        coordinatesArray[idx].Latitude, coordinatesArray[idx].Longitude);
                                    var edgeBox        = new GeoCoordinateBox(previous, current);
                                    var edgeBoxOverlap = false;
                                    if (closestWithoutMatchBox == null ||
                                        closestWithoutMatchBox.Overlaps(edgeBox))
                                    { // edge box overlap.
                                        edgeBoxOverlap = true;
                                    }
                                    else if (closestWithMatchBox == null ||
                                             closestWithMatchBox.Overlaps(edgeBox))
                                    { // edge box overlap.
                                        edgeBoxOverlap = true;
                                    }
                                    if (edgeBoxOverlap)
                                    { // overlap, possible this edge is a candidate.
                                        line     = new GeoCoordinateLine(previous, current, true, true);
                                        distance = line.DistanceReal(coordinate).Value;

                                        if (distance < closestWithoutMatch.Distance)
                                        { // the distance is smaller.
                                            var projectedPoint = line.ProjectOn(coordinate);

                                            // calculate the position.
                                            if (projectedPoint != null)
                                            {     // calculate the distance.
                                                if (distanceTotal == 0)
                                                { // calculate total distance.
                                                    var pCoordinate = vertex1Coordinate;
                                                    for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++)
                                                    {
                                                        var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude);
                                                        distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value;
                                                        pCoordinate   = cCoordinate;
                                                    }
                                                    distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value;
                                                }

                                                var distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                                var position      = distancePoint / distanceTotal;

                                                var diff = coordinate - new GeoCoordinate(projectedPoint);
                                                closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                                              new GeoCoordinate(coordinate - diff));
                                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                                    distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray);
                                            }
                                        }
                                        if (distance < closestWithMatch.Distance)
                                        {
                                            var projectedPoint = line.ProjectOn(coordinate);

                                            // calculate the position.
                                            if (projectedPoint != null)
                                            {     // calculate the distance
                                                if (distanceTotal == 0)
                                                { // calculate total distance.
                                                    var pCoordinate = vertex1Coordinate;
                                                    for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++)
                                                    {
                                                        var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude);
                                                        distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value;
                                                        pCoordinate   = cCoordinate;
                                                    }
                                                    distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value;
                                                }

                                                var distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                                var position      = distancePoint / distanceTotal;

                                                if (matcher == null ||
                                                    (pointTags == null || pointTags.Count == 0) ||
                                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                                {
                                                    var diff = coordinate - new GeoCoordinate(projectedPoint);
                                                    closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                                               new GeoCoordinate(coordinate - diff));
                                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                                        distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray);
                                                }
                                            }
                                        }
                                    }

                                    // add current segment distance to distanceToSegment for the next segment.
                                    distanceToSegment = distanceToSegment + previous.DistanceEstimate(current).Value;

                                    // set previous.
                                    previous = current;
                                }
                            }

                            // check the last segment.
                            line = new GeoCoordinateLine(previous, vertex2Coordinate, true, true);

                            distance = line.DistanceReal(coordinate).Value;

                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller.
                                var projectedPoint = line.ProjectOn(coordinate);

                                // calculate the position.
                                if (projectedPoint != null)
                                {     // calculate the distance
                                    if (distanceTotal == 0)
                                    { // calculate total distance.
                                        var pCoordinate = vertex1Coordinate;
                                        for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++)
                                        {
                                            var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude);
                                            distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value;
                                            pCoordinate   = cCoordinate;
                                        }
                                        distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value;
                                    }

                                    double distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                    double position      = distancePoint / distanceTotal;

                                    var diff = coordinate - new GeoCoordinate(projectedPoint);
                                    closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                                  new GeoCoordinate(coordinate - diff));
                                    closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                        distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray);
                                }
                            }
                            if (distance < closestWithMatch.Distance)
                            {
                                var projectedPoint = line.ProjectOn(coordinate);

                                // calculate the position.
                                if (projectedPoint != null)
                                {     // calculate the distance
                                    if (distanceTotal == 0)
                                    { // calculate total distance.
                                        var pCoordinate = vertex1Coordinate;
                                        for (int cIdx = 0; cIdx < coordinatesArray.Length; cIdx++)
                                        {
                                            var cCoordinate = new GeoCoordinate(coordinatesArray[cIdx].Latitude, coordinatesArray[cIdx].Longitude);
                                            distanceTotal = distanceTotal + cCoordinate.DistanceReal(pCoordinate).Value;
                                            pCoordinate   = cCoordinate;
                                        }
                                        distanceTotal = distanceTotal + vertex2Coordinate.DistanceReal(pCoordinate).Value;
                                    }

                                    double distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                    double position      = distancePoint / distanceTotal;

                                    if (matcher == null ||
                                        (pointTags == null || pointTags.Count == 0) ||
                                        matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                    {
                                        var diff = coordinate - new GeoCoordinate(projectedPoint);
                                        closestWithMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                                   new GeoCoordinate(coordinate - diff));
                                        closestWithMatch = new SearchClosestResult <TEdgeData>(
                                            distance, edges.Vertex1, edges.Vertex2, position, edges.EdgeData, coordinatesArray);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            { // only find closest vertices.
                // loop over all.
                while (edges.MoveNext())
                {
                    float fromLatitude, fromLongitude;
                    float toLatitude, toLongitude;
                    if (graph.GetVertex(edges.Vertex1, out fromLatitude, out fromLongitude) &&
                        graph.GetVertex(edges.Vertex2, out toLatitude, out toLongitude))
                    {
                        var    vertexCoordinate = new GeoCoordinate(fromLatitude, fromLongitude);
                        double distance         = coordinate.DistanceReal(vertexCoordinate).Value;
                        if (distance < closestWithoutMatch.Distance)
                        { // the distance found is closer.
                            var diff = coordinate - vertexCoordinate;
                            closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                          new GeoCoordinate(coordinate - diff));
                            closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                distance, edges.Vertex1);
                        }

                        vertexCoordinate = new GeoCoordinate(toLatitude, toLongitude);
                        distance         = coordinate.DistanceReal(vertexCoordinate).Value;
                        if (distance < closestWithoutMatch.Distance)
                        { // the distance found is closer.
                            var diff = coordinate - vertexCoordinate;
                            closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                          new GeoCoordinate(coordinate - diff));
                            closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                distance, edges.Vertex2);
                        }

                        var arcValueValueCoordinates = edges.Intermediates;
                        if (arcValueValueCoordinates != null)
                        { // search over intermediate points.
                            var arcValueValueCoordinatesArray = arcValueValueCoordinates.ToArray();
                            for (int idx = 0; idx < arcValueValueCoordinatesArray.Length; idx++)
                            {
                                vertexCoordinate = new GeoCoordinate(
                                    arcValueValueCoordinatesArray[idx].Latitude,
                                    arcValueValueCoordinatesArray[idx].Longitude);
                                distance = coordinate.DistanceReal(vertexCoordinate).Value;
                                if (distance < closestWithoutMatch.Distance)
                                { // the distance found is closer.
                                    var diff = coordinate - vertexCoordinate;
                                    closestWithoutMatchBox = new GeoCoordinateBox(new GeoCoordinate(coordinate + diff),
                                                                                  new GeoCoordinate(coordinate - diff));
                                    closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                        distance, edges.Vertex1, edges.Vertex2, idx, edges.EdgeData, arcValueValueCoordinatesArray);
                                }
                            }
                        }
                    }
                }
            }

            // return the best result.
            if (closestWithMatch.Distance < double.MaxValue)
            {
                return(closestWithMatch);
            }
            return(closestWithoutMatch);
        }
示例#14
0
        /// <summary>
        /// Tests the edge matcher in combination with dykstra routing.
        /// </summary>
        /// <param name="name"></param>
        /// <param name="highway"></param>
        /// <param name="vehicle"></param>
        /// <param name="matcher"></param>
        /// <param name="point_name"></param>
        /// <param name="not_found"></param>
        private void TestResolveOnEdgeSingle(string name, string highway, 
            VehicleEnum vehicle, IEdgeMatcher matcher, 
            string point_name, bool not_found)
        {
            GeoCoordinate from_name = new GeoCoordinate(51.0003, 4.0007);
            GeoCoordinate to_name = new GeoCoordinate(51.0003, 4.0008);

            GeoCoordinate from_noname = new GeoCoordinate(51.0, 4.0007);
            GeoCoordinate to_noname = new GeoCoordinate(51.0, 4.0008);

            Dictionary<string, string> point_tags = new Dictionary<string, string>();
            point_tags["name"] = point_name;

            Dictionary<string, string> tags = new Dictionary<string, string>();
            tags["highway"] = highway;
            //tags["name"] = name;

            OsmTagsIndex tags_index = new OsmTagsIndex();

            // do the data processing.
            DynamicGraphRouterDataSource<SimpleWeighedEdge> data =
                new DynamicGraphRouterDataSource<SimpleWeighedEdge>(tags_index);
            uint vertex_noname1 = data.AddVertex((float)from_noname.Latitude, (float)from_noname.Longitude);
            uint vertex_noname2 = data.AddVertex((float)to_noname.Latitude, (float)to_noname.Longitude);
            data.AddArc(vertex_noname1, vertex_noname2, new SimpleWeighedEdge()
            {
                IsForward = true,
                Tags = tags_index.Add(tags),
                Weight = 100
            }, null);
            tags = new Dictionary<string, string>();
            tags["highway"] = highway;
            tags["name"] = name;
            uint vertex_name1 = data.AddVertex((float)from_name.Latitude, (float)from_name.Longitude);
            uint vertex_name2 = data.AddVertex((float)to_name.Latitude, (float)to_name.Longitude);
            data.AddArc(vertex_name1, vertex_name2, new SimpleWeighedEdge()
            {
                IsForward = true,
                Tags = tags_index.Add(tags),
                Weight = 100
            }, null);

            IRoutingInterpreter interpreter = new OsmRoutingInterpreter();

            // creates the data.
            IBasicRouter<SimpleWeighedEdge> router = new DykstraRoutingLive(
                data.TagsIndex);

            GeoCoordinate noname_location = new GeoCoordinate(
                (from_noname.Latitude + to_noname.Latitude) / 2.0,
                (from_noname.Longitude + to_noname.Longitude) / 2.0);
            GeoCoordinate name_location = new GeoCoordinate(
                (from_name.Latitude + to_name.Latitude) / 2.0,
                (from_name.Longitude + to_name.Longitude) / 2.0);

            float delta = 0.01f;
            SearchClosestResult result = router.SearchClosest(data, interpreter, vehicle, noname_location, delta, matcher, point_tags);
            if (result.Distance < double.MaxValue)
            { // there is a result.
                Assert.IsFalse(not_found, "A result was found but was supposed not to  be found!");

                if (name == point_name)
                { // the name location was supposed to be found!
                    Assert.IsTrue(result.Vertex1 == vertex_name1 || result.Vertex1 == vertex_name2);
                    Assert.IsTrue(result.Vertex2 == vertex_name1 || result.Vertex2 == vertex_name2);
                }
                else
                { // the noname location was supposed to be found!
                    Assert.IsTrue(result.Vertex1 == vertex_noname1 || result.Vertex1 == vertex_noname2);
                    Assert.IsTrue(result.Vertex2 == vertex_noname1 || result.Vertex2 == vertex_noname2);
                }
                return;
            }
            Assert.IsTrue(not_found, "A result was not found but was supposed to be found!");
        }
        /// <summary>
        /// Calculates the TSP.
        /// </summary>
        /// <param name="operation">The operation request.</param>
        /// <param name="router">The router.</param>
        /// <param name="matcher">Contains an algorithm to match points to the route network.</param>
        /// <param name="open">Flag indicating the type of TSP problem, open or not.</param>
        /// <returns></returns>
        private RoutingResponse DoTSP(
            RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher, bool open)
        {
            // create the response.
            var response = new RoutingResponse();

            // resolve the points and do the routing.
            var hooksPerRouterPoints = new Dictionary<RouterPoint, List<RoutingHook>>();
            var routerPoints = new List<RouterPoint>();
            var unroutableHooks = new List<RoutingHook>(); // save the unroutable hooks.
            for (int idx = 0; idx < operation.Hooks.Length; idx++)
            {
                // routing hook tags.
                IDictionary<string, string> tags = operation.Hooks[idx].Tags.ConvertToDictionary();

                // resolve the point.
                RouterPoint routerPoint = router.Resolve(operation.Vehicle, new GeoCoordinate(
                    operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, tags);

                // check the result.
                if (routerPoint == null)
                { // this hook is not routable.
                    unroutableHooks.Add(operation.Hooks[idx]);
                }
                else
                { // a point to hook on was found!
                    List<RoutingHook> hooksAtPoint;
                    if (!hooksPerRouterPoints.TryGetValue(routerPoint, out hooksAtPoint))
                    { // the router point does not exist yet.
                        // check if the router point is routable.
                        if (router.CheckConnectivity(operation.Vehicle, routerPoint, 200))
                        {// the point is routable.
                            // create the hooks list at this point.
                            hooksAtPoint = new List<RoutingHook>();
                            hooksPerRouterPoints.Add(routerPoint, hooksAtPoint);

                            // add the new router point to the list.
                            routerPoint.Tags.Add(new KeyValuePair<string, string>("id", routerPoints.Count.ToString(
                                System.Globalization.CultureInfo.InvariantCulture)));
                            routerPoints.Add(routerPoint);

                            // add the hook.
                            hooksAtPoint.Add(operation.Hooks[idx]);
                        }
                        else
                        {// this hook is not routable.
                            unroutableHooks.Add(operation.Hooks[idx]);
                        }
                    }
                    else
                    {
                        // add the hook.
                        hooksAtPoint.Add(operation.Hooks[idx]);
                    }
                }
            }

            // add the unroutable hooks.
            response.UnroutableHooks = unroutableHooks.ToArray();

            // calculate all the weights.
            double[][] weights = router.CalculateManyToManyWeight(operation.Vehicle, routerPoints.ToArray(), routerPoints.ToArray());

            // calculate the TSP.
            var tspSolver = new RouterTSPAEXGenetic(300, 100);
            IRoute tspRoute = tspSolver.CalculateTSP(weights, routerPoints.Select(x => x.Location).ToArray(), 0, !open);

            // calculate the actual route.
            OsmSharpRoute route = null;
            foreach (Edge edge in tspRoute.Edges())
            {
                // calculate the actual edge-route.
                OsmSharpRoute edgeRoute = router.Calculate(operation.Vehicle,
                                                            routerPoints[edge.From], routerPoints[edge.To]);

                // add the routing hook tags.
                List<RoutingHook> fromHooks = hooksPerRouterPoints[routerPoints[edge.From]];
                edgeRoute.Entries[0].Points = new RoutePoint[fromHooks.Count];
                for (int hookIdx = 0; hookIdx < fromHooks.Count; hookIdx++)
                {
                    var hookPoint = new RoutePoint
                                        {
                                            Latitude = fromHooks[hookIdx].Latitude,
                                            Longitude = fromHooks[hookIdx].Longitude,
                                            Tags = fromHooks[hookIdx].Tags.ConvertToList().ConvertFrom()
                                        };

                    edgeRoute.Entries[0].Points[hookIdx] = hookPoint;
                }
                List<RoutingHook> toHooks = hooksPerRouterPoints[routerPoints[edge.To]];
                edgeRoute.Entries[edgeRoute.Entries.Length - 1].Points = new RoutePoint[toHooks.Count];
                for (int hookIdx = 0; hookIdx < toHooks.Count; hookIdx++)
                {
                    var hookPoint = new RoutePoint
                                        {
                                            Latitude = toHooks[hookIdx].Latitude,
                                            Longitude = toHooks[hookIdx].Longitude,
                                            Tags = toHooks[hookIdx].Tags.ConvertToList().ConvertFrom()
                                        };

                    edgeRoute.Entries[edgeRoute.Entries.Length - 1].Points[hookIdx] = hookPoint;
                }

                // concatenate routes.
                if (route == null)
                {
                    route = edgeRoute;
                }
                else
                {
                    route = OsmSharpRoute.Concatenate(route, edgeRoute);
                }
            }

            response.Route = route;

            // set the response as successfull.
            response.Status = OsmSharpServiceResponseStatusEnum.Success;

            return response;
        }
        /// <summary>
        /// Calculates the route from the source to the closest point.
        /// </summary>
        /// <param name="operation">The operation request.</param>
        /// <param name="router">The router.</param>
        /// <param name="matcher">Contains an algorithm to match points to the route network.</param>
        /// <returns></returns>
        private RoutingResponse DoToClosest(
            RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher)
        {
            // create the response.
            var response = new RoutingResponse();

            // resolve the points and do the routing.
            var hooksPerRouterPoints = new Dictionary<RouterPoint, List<RoutingHook>>();
            var routerPoints = new List<RouterPoint>();
            var unroutableHooks = new List<RoutingHook>(); // save the unroutable hooks.
            for (int idx = 0; idx < operation.Hooks.Length; idx++)
            {
                // routing hook tags.
                IDictionary<string, string> tags = operation.Hooks[idx].Tags.ConvertToDictionary();

                // resolve the point.
                RouterPoint routerPoint = router.Resolve(operation.Vehicle, new GeoCoordinate(
                    operation.Hooks[idx].Latitude, operation.Hooks[idx].Longitude), matcher, tags);

                // check the result.
                if (routerPoint == null)
                { // this hook is not routable.
                    if (idx == 0)
                    { // the first point has to be valid!
                        throw new Exception("Cannot resolve source point of a CalculateToClosest() operation.");
                    }
                    unroutableHooks.Add(operation.Hooks[idx]);
                }
                else
                { // a point to hook on was found!
                    List<RoutingHook> hooksAtPoint;
                    if (!hooksPerRouterPoints.TryGetValue(routerPoint, out hooksAtPoint))
                    { // the router point does not exist yet.
                        // check if the router point is routable.
                        if (router.CheckConnectivity(operation.Vehicle, routerPoint, 200))
                        {// the point is routable.
                            // create the hooks list at this point.
                            hooksAtPoint = new List<RoutingHook>();
                            hooksPerRouterPoints.Add(routerPoint, hooksAtPoint);

                            // add the new router point to the list.
                            routerPoint.Tags.Add(new KeyValuePair<string, string>("id", routerPoints.Count.ToString(
                                System.Globalization.CultureInfo.InvariantCulture)));
                            routerPoint.Tags.Add(new KeyValuePair<string, string>("idx", idx.ToString(
                                System.Globalization.CultureInfo.InvariantCulture)));
                            routerPoints.Add(routerPoint);

                            // add the hook.
                            hooksAtPoint.Add(operation.Hooks[idx]);
                        }
                        else
                        {// this hook is not routable.
                            if (idx == 0)
                            { // the first point has to be valid!
                                throw new Exception("Cannot resolve source point of a CalculateToClosest() operation.");
                            }
                            unroutableHooks.Add(operation.Hooks[idx]);
                        }
                    }
                    else
                    {
                        // add the hook.
                        hooksAtPoint.Add(operation.Hooks[idx]);
                    }
                }
            }

            // add the unroutable hooks.
            response.UnroutableHooks = unroutableHooks.ToArray();

            // extract the first point.
            RouterPoint first = routerPoints[0];
            routerPoints.RemoveAt(0);

            // calculate all the weights.
            OsmSharpRoute route = router.CalculateToClosest(operation.Vehicle, first, routerPoints.ToArray());

            if (route != null)
            {
                // add the routerpoint tags.
                string idxClosestString = route.Entries[route.Entries.Length - 1].Points[0].Tags[1].Value;
                int idxClosest = int.Parse(idxClosestString);

                // get the closest point.
                RoutingHook pointClosest = operation.Hooks[idxClosest];

                // get the routerpoint.
                RoutePoint routePoint = route.Entries[route.Entries.Length - 1].Points[0];

                // add the closest point tags.
                routePoint.Latitude = pointClosest.Latitude;
                routePoint.Longitude = pointClosest.Longitude;
                List<KeyValuePair<string, string>> tags = pointClosest.Tags.ConvertToList();
                tags.Add(new KeyValuePair<string, string>("id", pointClosest.Id.ToString())); // add the id-tag.
                routePoint.Tags = tags.ConvertFrom();

                response.Route = route;

                // set the response as successfull.
                response.Status = OsmSharpServiceResponseStatusEnum.Success;
            }

            return response;
        }
        /// <summary>
        /// Calculates a regular route.
        /// </summary>
        /// <param name="operation">The operation request.</param>
        /// <param name="router">The router.</param>
        /// <param name="matcher">Contains an algorithm to match points to the route network.</param>
        /// <returns></returns>
        private RoutingResponse DoRegular(
            RoutingOperation operation, Router<SimpleWeighedEdge> router, IEdgeMatcher matcher)
        {
            // create the response.
            var response = new RoutingResponse();

            OsmSharpRoute route = null;
            RouterPoint previous = null;
            var unroutableHooks = new List<RoutingHook>(); // keep a list of unroutable hooks.
            for (int idx = 0; idx < operation.Hooks.Length - 1; idx++)
            {
                // resolve the next point.
                RouterPoint next = router.Resolve(operation.Vehicle,
                                                  new GeoCoordinate(operation.Hooks[idx].Latitude,
                                                                    operation.Hooks[idx].Longitude), matcher,
                                                  operation.Hooks[idx].Tags.ConvertToDictionary());

                // check the routability.
                if (next != null &&
                    router.CheckConnectivity(operation.Vehicle, next, 200))
                { // the next point is routable.
                    if (previous != null)
                    {
                        // calculate the next part of the route.
                        OsmSharpRoute routePart = router.Calculate(operation.Vehicle,
                                                                 previous, next);
                        // concatenate the route part.
                        if (route == null)
                        {
                            route = routePart;
                        }
                        else
                        {
                            route = OsmSharpRoute.Concatenate(route, routePart);
                        }
                    }

                    // set the next to the previous.
                    previous = next;
                }
                else
                { // add the hook to the unroutable hooks list.
                   unroutableHooks.Add(operation.Hooks[idx]);
                }
            }

            // add the unroutable hooks.
            response.UnroutableHooks = unroutableHooks.ToArray();

            // set the response route.
            response.Route = route;

            // report succes!
            response.Status = OsmSharpServiceResponseStatusEnum.Success;
            response.StatusMessage = string.Empty;

            return response;
        }
示例#18
0
        /// <summary>
        /// Searches the data for a point on an edge closest to the given coordinate.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="vehicle"></param>
        /// <param name="coordinate"></param>
        /// <param name="delta"></param>
        /// <param name="matcher"></param>
        /// <param name="pointTags"></param>
        /// <param name="interpreter"></param>
        /// <param name="verticesOnly"></param>
        public SearchClosestResult SearchClosest(IBasicRouterDataSource <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle,
                                                 GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollection pointTags, bool verticesOnly)
        {
            var closestWithMatch    = new SearchClosestResult(double.MaxValue, 0);
            var closestWithoutMatch = new SearchClosestResult(double.MaxValue, 0);

            double searchBoxSize = delta;
            // create the search box.
            var searchBox = new GeoCoordinateBox(new GeoCoordinate(
                                                     coordinate.Latitude - searchBoxSize, coordinate.Longitude - searchBoxSize),
                                                 new GeoCoordinate(
                                                     coordinate.Latitude + searchBoxSize, coordinate.Longitude + searchBoxSize));

            // get the arcs from the data source.
            KeyValuePair <uint, KeyValuePair <uint, TEdgeData> >[] arcs = graph.GetArcs(searchBox);

            if (!verticesOnly)
            { // find both closest arcs and vertices.
                // loop over all.
                foreach (KeyValuePair <uint, KeyValuePair <uint, TEdgeData> > arc in arcs)
                {
                    TagsCollection arcTags        = graph.TagsIndex.Get(arc.Value.Value.Tags);
                    bool           canBeTraversed = vehicle.CanTraverse(arcTags);
                    if (canBeTraversed)
                    { // the edge can be traversed.
                        // test the two points.
                        float  fromLatitude, fromLongitude;
                        float  toLatitude, toLongitude;
                        double distance;
                        if (graph.GetVertex(arc.Key, out fromLatitude, out fromLongitude) &&
                            graph.GetVertex(arc.Value.Key, out toLatitude, out toLongitude))
                        { // return the vertex.
                            var fromCoordinates = new GeoCoordinate(fromLatitude, fromLongitude);
                            distance = coordinate.Distance(fromCoordinates);

                            if (distance < 0.00001)
                            { // the distance is smaller than the tolerance value.
                                closestWithoutMatch = new SearchClosestResult(
                                    distance, arc.Key);
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                {
                                    closestWithMatch = new SearchClosestResult(
                                        distance, arc.Key);
                                    break;
                                }
                            }

                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller for the without match.
                                closestWithoutMatch = new SearchClosestResult(
                                    distance, arc.Key);
                            }
                            if (distance < closestWithMatch.Distance)
                            { // the distance is smaller for the with match.
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, graph.TagsIndex.Get(arc.Value.Value.Tags)))
                                {
                                    closestWithMatch = new SearchClosestResult(
                                        distance, arc.Key);
                                }
                            }
                            var toCoordinates = new GeoCoordinate(toLatitude, toLongitude);
                            distance = coordinate.Distance(toCoordinates);

                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller for the without match.
                                closestWithoutMatch = new SearchClosestResult(
                                    distance, arc.Value.Key);
                            }
                            if (distance < closestWithMatch.Distance)
                            { // the distance is smaller for the with match.
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                {
                                    closestWithMatch = new SearchClosestResult(
                                        distance, arc.Value.Key);
                                }
                            }

                            // create a line.
                            double distanceTotal = fromCoordinates.Distance(toCoordinates);
                            if (distanceTotal > 0)
                            { // the from/to are not the same location.
                                var line = new GeoCoordinateLine(fromCoordinates, toCoordinates, true, true);
                                distance = line.Distance(coordinate);

                                if (distance < closestWithoutMatch.Distance)
                                { // the distance is smaller.
                                    PointF2D projectedPoint =
                                        line.ProjectOn(coordinate);

                                    // calculate the position.
                                    if (projectedPoint != null)
                                    { // calculate the distance
                                        double distancePoint = fromCoordinates.Distance(projectedPoint);
                                        double position      = distancePoint / distanceTotal;

                                        closestWithoutMatch = new SearchClosestResult(
                                            distance, arc.Key, arc.Value.Key, position);
                                    }
                                }
                                if (distance < closestWithMatch.Distance)
                                {
                                    PointF2D projectedPoint =
                                        line.ProjectOn(coordinate);

                                    // calculate the position.
                                    if (projectedPoint != null)
                                    { // calculate the distance
                                        double distancePoint = fromCoordinates.Distance(projectedPoint);
                                        double position      = distancePoint / distanceTotal;

                                        if (matcher == null ||
                                            (pointTags == null || pointTags.Count == 0) ||
                                            matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                        {
                                            closestWithMatch = new SearchClosestResult(
                                                distance, arc.Key, arc.Value.Key, position);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            { // only find closest vertices.
                // loop over all.
                foreach (KeyValuePair <uint, KeyValuePair <uint, TEdgeData> > arc in arcs)
                {
                    float fromLatitude, fromLongitude;
                    float toLatitude, toLongitude;
                    if (graph.GetVertex(arc.Key, out fromLatitude, out fromLongitude) &&
                        graph.GetVertex(arc.Value.Key, out toLatitude, out toLongitude))
                    {
                        var    vertexCoordinate = new GeoCoordinate(fromLatitude, fromLongitude);
                        double distance         = coordinate.Distance(vertexCoordinate);
                        if (distance < closestWithoutMatch.Distance)
                        { // the distance found is closer.
                            closestWithoutMatch = new SearchClosestResult(
                                distance, arc.Key);
                        }

                        vertexCoordinate = new GeoCoordinate(toLatitude, toLongitude);
                        distance         = coordinate.Distance(vertexCoordinate);
                        if (distance < closestWithoutMatch.Distance)
                        { // the distance found is closer.
                            closestWithoutMatch = new SearchClosestResult(
                                distance, arc.Value.Key);
                        }
                    }
                }
            }

            // return the best result.
            if (closestWithMatch.Distance < double.MaxValue)
            {
                return(closestWithMatch);
            }
            return(closestWithoutMatch);
        }
示例#19
0
 /// <summary>
 /// Searches the data for a point on an edge closest to the given coordinate.
 /// </summary>
 /// <param name="graph"></param>
 /// <param name="vehicle"></param>
 /// <param name="coordinate"></param>
 /// <param name="delta"></param>
 /// <param name="matcher"></param>
 /// <param name="pointTags"></param>
 /// <param name="interpreter"></param>
 /// <param name="parameters"></param>
 public SearchClosestResult <TEdgeData> SearchClosest(IBasicRouterDataSource <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle,
                                                      GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollectionBase pointTags, Dictionary <string, object> parameters)
 {
     return(this.SearchClosest(graph, interpreter, vehicle, coordinate, delta, matcher, pointTags, false, null));
 }
示例#20
0
 /// <summary>
 /// Resolves all the given points.
 /// </summary>
 /// <param name="vehicle">The vehicle profile.</param>
 /// <param name="delta">The size of the box to search in.</param>
 /// <param name="coordinates">The location of the points to resolve.</param>
 /// <param name="matcher">The matcher containing some matching algorithm.</param>
 /// <param name="matchingTags">Extra matching data.</param>
 /// <returns></returns>
 public RouterPoint[] Resolve(Vehicle vehicle, float delta, GeoCoordinate[] coordinates, 
     IEdgeMatcher matcher, TagsCollectionBase[] matchingTags)
 {
     return _router.Resolve(vehicle, delta, coordinates, matcher, matchingTags);
 }
示例#21
0
        /// <summary>
        /// Searches the data for a point on an edge closest to the given coordinate.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="vehicle"></param>
        /// <param name="coordinate"></param>
        /// <param name="delta"></param>
        /// <param name="matcher"></param>
        /// <param name="pointTags"></param>
        /// <param name="interpreter"></param>
        /// <param name="verticesOnly"></param>
        /// <param name="parameters"></param>
        public SearchClosestResult <TEdgeData> SearchClosest(IBasicRouterDataSource <TEdgeData> graph, IRoutingInterpreter interpreter, Vehicle vehicle,
                                                             GeoCoordinate coordinate, float delta, IEdgeMatcher matcher, TagsCollectionBase pointTags, bool verticesOnly, Dictionary <string, object> parameters)
        {
            Meter distanceEpsilon = .1; // 10cm is the tolerance to distinguish points.

            var closestWithMatch    = new SearchClosestResult <TEdgeData>(double.MaxValue, 0);
            var closestWithoutMatch = new SearchClosestResult <TEdgeData>(double.MaxValue, 0);

            double searchBoxSize = delta;
            // create the search box.
            var searchBox = new GeoCoordinateBox(new GeoCoordinate(
                                                     coordinate.Latitude - searchBoxSize, coordinate.Longitude - searchBoxSize),
                                                 new GeoCoordinate(
                                                     coordinate.Latitude + searchBoxSize, coordinate.Longitude + searchBoxSize));

            // get the arcs from the data source.
            var arcs = graph.GetEdges(searchBox);

            if (!verticesOnly)
            { // find both closest arcs and vertices.
                // loop over all.
                while (arcs.MoveNext())
                {
                    if (!graph.TagsIndex.Contains(arcs.EdgeData.Tags))
                    { // skip this edge, no valid tags found.
                        continue;
                    }
                    var arcTags        = graph.TagsIndex.Get(arcs.EdgeData.Tags);
                    var canBeTraversed = vehicle.CanTraverse(arcTags);
                    if (canBeTraversed)
                    { // the edge can be traversed.
                        // test the two points.
                        float  fromLatitude, fromLongitude;
                        float  toLatitude, toLongitude;
                        double distance;
                        if (graph.GetVertex(arcs.Vertex1, out fromLatitude, out fromLongitude) &&
                            graph.GetVertex(arcs.Vertex2, out toLatitude, out toLongitude))
                        { // return the vertex.
                            var fromCoordinates = new GeoCoordinate(fromLatitude, fromLongitude);
                            distance = coordinate.DistanceReal(fromCoordinates).Value;
                            ICoordinateCollection coordinates;
                            ICoordinate[]         coordinatesArray = null;
                            if (!graph.GetEdgeShape(arcs.Vertex1, arcs.Vertex2, out coordinates))
                            {
                                coordinates = null;
                            }
                            if (coordinates != null)
                            {
                                coordinatesArray = coordinates.ToArray();
                            }

                            if (distance < distanceEpsilon.Value)
                            { // the distance is smaller than the tolerance value.
                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                    distance, arcs.Vertex1);
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                {
                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                        distance, arcs.Vertex1);
                                    break;
                                }
                            }

                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller for the without match.
                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                    distance, arcs.Vertex1);
                            }
                            if (distance < closestWithMatch.Distance)
                            { // the distance is smaller for the with match.
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, graph.TagsIndex.Get(arcs.EdgeData.Tags)))
                                {
                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                        distance, arcs.Vertex1);
                                }
                            }
                            var toCoordinates = new GeoCoordinate(toLatitude, toLongitude);
                            distance = coordinate.DistanceReal(toCoordinates).Value;

                            if (distance < closestWithoutMatch.Distance)
                            { // the distance is smaller for the without match.
                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                    distance, arcs.Vertex2);
                            }
                            if (distance < closestWithMatch.Distance)
                            { // the distance is smaller for the with match.
                                if (matcher == null ||
                                    (pointTags == null || pointTags.Count == 0) ||
                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                {
                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                        distance, arcs.Vertex2);
                                }
                            }

                            // search along the line.
                            var distanceTotal            = 0.0;
                            var previous                 = fromCoordinates;
                            var arcValueValueCoordinates = arcs.Intermediates;
                            if (arcValueValueCoordinates != null)
                            { // calculate distance along all coordinates.
                                var arcValueValueCoordinatesArray = arcValueValueCoordinates.ToArray();
                                for (int idx = 0; idx < arcValueValueCoordinatesArray.Length; idx++)
                                {
                                    var current = new GeoCoordinate(arcValueValueCoordinatesArray[idx].Latitude, arcValueValueCoordinatesArray[idx].Longitude);
                                    distanceTotal = distanceTotal + current.DistanceReal(previous).Value;
                                    previous      = current;
                                }
                            }
                            distanceTotal = distanceTotal + toCoordinates.DistanceReal(previous).Value;
                            if (distanceTotal > 0)
                            { // the from/to are not the same location.
                                // loop over all edges that are represented by this arc (counting intermediate coordinates).
                                previous = fromCoordinates;
                                GeoCoordinateLine line;
                                var distanceToSegment = 0.0;
                                if (arcValueValueCoordinates != null)
                                {
                                    var arcValueValueCoordinatesArray = arcValueValueCoordinates.ToArray();
                                    for (int idx = 0; idx < arcValueValueCoordinatesArray.Length; idx++)
                                    {
                                        var current = new GeoCoordinate(
                                            arcValueValueCoordinatesArray[idx].Latitude, arcValueValueCoordinatesArray[idx].Longitude);
                                        line = new GeoCoordinateLine(previous, current, true, true);

                                        distance = line.DistanceReal(coordinate).Value;

                                        if (distance < closestWithoutMatch.Distance)
                                        { // the distance is smaller.
                                            var projectedPoint = line.ProjectOn(coordinate);

                                            // calculate the position.
                                            if (projectedPoint != null)
                                            { // calculate the distance
                                                var distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                                var position      = distancePoint / distanceTotal;

                                                closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                                    distance, arcs.Vertex1, arcs.Vertex2, position, arcs.EdgeData, coordinatesArray);
                                            }
                                        }
                                        if (distance < closestWithMatch.Distance)
                                        {
                                            var projectedPoint = line.ProjectOn(coordinate);

                                            // calculate the position.
                                            if (projectedPoint != null)
                                            { // calculate the distance
                                                var distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                                var position      = distancePoint / distanceTotal;

                                                if (matcher == null ||
                                                    (pointTags == null || pointTags.Count == 0) ||
                                                    matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                                {
                                                    closestWithMatch = new SearchClosestResult <TEdgeData>(
                                                        distance, arcs.Vertex1, arcs.Vertex2, position, arcs.EdgeData, coordinatesArray);
                                                }
                                            }
                                        }

                                        // add current segment distance to distanceToSegment for the next segment.
                                        distanceToSegment = distanceToSegment + line.LengthReal.Value;

                                        // set previous.
                                        previous = current;
                                    }
                                }

                                // check the last segment.
                                line = new GeoCoordinateLine(previous, toCoordinates, true, true);

                                distance = line.DistanceReal(coordinate).Value;

                                if (distance < closestWithoutMatch.Distance)
                                { // the distance is smaller.
                                    var projectedPoint = line.ProjectOn(coordinate);

                                    // calculate the position.
                                    if (projectedPoint != null)
                                    { // calculate the distance
                                        double distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                        double position      = distancePoint / distanceTotal;

                                        closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                            distance, arcs.Vertex1, arcs.Vertex2, position, arcs.EdgeData, coordinatesArray);
                                    }
                                }
                                if (distance < closestWithMatch.Distance)
                                {
                                    var projectedPoint = line.ProjectOn(coordinate);

                                    // calculate the position.
                                    if (projectedPoint != null)
                                    { // calculate the distance
                                        double distancePoint = previous.DistanceReal(new GeoCoordinate(projectedPoint)).Value + distanceToSegment;
                                        double position      = distancePoint / distanceTotal;

                                        if (matcher == null ||
                                            (pointTags == null || pointTags.Count == 0) ||
                                            matcher.MatchWithEdge(vehicle, pointTags, arcTags))
                                        {
                                            closestWithMatch = new SearchClosestResult <TEdgeData>(
                                                distance, arcs.Vertex1, arcs.Vertex2, position, arcs.EdgeData, coordinatesArray);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
            else
            { // only find closest vertices.
                // loop over all.
                while (arcs.MoveNext())
                {
                    float fromLatitude, fromLongitude;
                    float toLatitude, toLongitude;
                    if (graph.GetVertex(arcs.Vertex1, out fromLatitude, out fromLongitude) &&
                        graph.GetVertex(arcs.Vertex2, out toLatitude, out toLongitude))
                    {
                        var    vertexCoordinate = new GeoCoordinate(fromLatitude, fromLongitude);
                        double distance         = coordinate.DistanceReal(vertexCoordinate).Value;
                        if (distance < closestWithoutMatch.Distance)
                        { // the distance found is closer.
                            closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                distance, arcs.Vertex1);
                        }

                        vertexCoordinate = new GeoCoordinate(toLatitude, toLongitude);
                        distance         = coordinate.DistanceReal(vertexCoordinate).Value;
                        if (distance < closestWithoutMatch.Distance)
                        { // the distance found is closer.
                            closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                distance, arcs.Vertex2);
                        }

                        var arcValueValueCoordinates = arcs.Intermediates;
                        if (arcValueValueCoordinates != null)
                        { // search over intermediate points.
                            var arcValueValueCoordinatesArray = arcValueValueCoordinates.ToArray();
                            for (int idx = 0; idx < arcValueValueCoordinatesArray.Length; idx++)
                            {
                                vertexCoordinate = new GeoCoordinate(
                                    arcValueValueCoordinatesArray[idx].Latitude,
                                    arcValueValueCoordinatesArray[idx].Longitude);
                                distance = coordinate.DistanceReal(vertexCoordinate).Value;
                                if (distance < closestWithoutMatch.Distance)
                                { // the distance found is closer.
                                    closestWithoutMatch = new SearchClosestResult <TEdgeData>(
                                        distance, arcs.Vertex1, arcs.Vertex2, idx, arcs.EdgeData, arcValueValueCoordinatesArray);
                                }
                            }
                        }
                    }
                }
            }

            // return the best result.
            if (closestWithMatch.Distance < double.MaxValue)
            {
                return(closestWithMatch);
            }
            return(closestWithoutMatch);
        }
示例#22
0
 /// <summary>
 /// Resolves all the given points.
 /// </summary>
 /// <param name="vehicle">The vehicle profile.</param>
 /// <param name="delta">The size of the box to search in.</param>
 /// <param name="coordinates">The location of the points to resolve.</param>
 /// <param name="matcher">The matcher containing some matching algorithm.</param>
 /// <param name="matchingTags">Extra matching data.</param>
 /// <returns></returns>
 public RouterPoint[] Resolve(Vehicle vehicle, float delta, GeoCoordinate[] coordinates,
                              IEdgeMatcher matcher, TagsCollectionBase[] matchingTags)
 {
     return(_router.Resolve(vehicle, delta, coordinates, matcher, matchingTags));
 }
示例#23
0
        /// <summary>
        /// Resolves a point.
        /// </summary>
        /// <param name="vehicle">The vehicle profile.</param>
        /// <param name="delta">The size of the box to search in.</param>
        /// <param name="coordinate">The location of the point to resolve.</param>
        /// <param name="matcher">The matcher containing some matching algorithm.</param>
        /// <param name="matchingTags">Extra matching data.</param>
        /// <returns></returns>
        public RouterPoint Resolve(Vehicle vehicle, float delta, GeoCoordinate coordinate, 
            IEdgeMatcher matcher, TagsCollectionBase matchingTags)
        {
            if (vehicle == null) { throw new ArgumentNullException("vehicle"); }
            if (coordinate == null) { throw new ArgumentNullException("coordinate"); }
            if (matcher == null) { throw new ArgumentNullException("matcher"); }
            if (matchingTags == null) { throw new ArgumentNullException("matchingTags"); }

            return _router.Resolve(vehicle, delta, coordinate, matcher, matchingTags);
        }