Ejemplo n.º 1
0
        /// <summary>
        /// Decodes the given data into a location reference.
        /// </summary>
        public static PointAlongLineLocation Decode(byte[] data)
        {
            var pointAlongLine = new PointAlongLineLocation();

            // decode first location reference point.
            var first = new LocationReferencePoint();

            first.Coordinate         = CoordinateConverter.Decode(data, 1);
            first.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, 7, 2);
            first.FormOfWay          = FormOfWayConvertor.Decode(data, 7, 5);
            first.LowestFunctionalRoadClassToNext = FunctionalRoadClassConvertor.Decode(data, 8, 0);
            first.Bearing        = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, 8, 3));
            first.DistanceToNext = DistanceToNextConvertor.Decode(data[9]);

            // decode second location reference point.
            var last = new LocationReferencePoint();

            last.Coordinate         = CoordinateConverter.DecodeRelative(first.Coordinate, data, 10);
            last.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, 14, 2);
            last.FormOfWay          = FormOfWayConvertor.Decode(data, 14, 5);
            last.Bearing            = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, 15, 3));

            pointAlongLine.First       = first;
            pointAlongLine.Orientation = OrientationConverter.Decode(data, 7, 0);
            pointAlongLine.SideOfRoad  = SideOfRoadConverter.Decode(data, 14, 0);
            pointAlongLine.PositiveOffsetPercentage = OffsetConvertor.Decode(data, 16);
            pointAlongLine.Last = last;

            return(pointAlongLine);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Builds a location referenced point for the last vertex.
        /// </summary>
        /// <returns></returns>
        public LocationReferencePoint BuildLocationReferencePointLast(ReferencedLine referencedLocation, int before)
        {
            FormOfWay           fow;
            FunctionalRoadClass frc;

            var end = referencedLocation.Vertices.Length - 1;

            // get all coordinates along the sequence starting at 'before' and ending at 'end'.
            var coordinates = referencedLocation.GetCoordinates(this.Graph, before, end - before + 1);

            // create location reference point.
            var locationReferencedPoint = new LocationReferencePoint();

            locationReferencedPoint.Coordinate = this.GetVertexLocation(referencedLocation.Vertices[end]);
            var tags = this.GetTags(referencedLocation.Edges[end - 1].Tags);

            if (!this.TryMatching(tags, out frc, out fow))
            {
                throw new ReferencedEncodingException(referencedLocation,
                                                      "Could not find frc and/or fow for the given tags.");
            }
            locationReferencedPoint.FormOfWay          = fow;
            locationReferencedPoint.FuntionalRoadClass = frc;
            locationReferencedPoint.Bearing            = (int)BearingEncoder.EncodeBearing(coordinates, true).Value;

            return(locationReferencedPoint);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Decodes the given data into a location reference.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        protected override ClosedLineLocation Decode(byte[] data)
        {
            // decode first location reference point.
            var first = new LocationReferencePoint();

            first.Coordinate         = CoordinateConverter.Decode(data, 1);
            first.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, 7, 2);
            first.FormOfWay          = FormOfWayConvertor.Decode(data, 7, 5);
            first.LowestFunctionalRoadClassToNext = FunctionalRoadClassConvertor.Decode(data, 8, 0);
            first.Bearing        = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, 8, 3));
            first.DistanceToNext = DistanceToNextConvertor.Decode(data[9]);

            // calculate the intermediate points count.
            var intermediateList = new List <LocationReferencePoint>();
            int intermediates    = (data.Length - 12) / 7;
            int location         = 10;
            var reference        = first.Coordinate; // the reference for the relative coordinates.

            for (int idx = 0; idx < intermediates; idx++)
            {
                // create an intermediate point.
                var intermediate = new LocationReferencePoint();
                intermediate.Coordinate = CoordinateConverter.DecodeRelative(reference, data, location);
                reference = intermediate.Coordinate;
                location  = location + 4;
                intermediate.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, location, 2);
                intermediate.FormOfWay          = FormOfWayConvertor.Decode(data, location, 5);
                location             = location + 1;
                intermediate.Bearing = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, location, 3));
                intermediate.LowestFunctionalRoadClassToNext = FunctionalRoadClassConvertor.Decode(data, location, 0);
                location = location + 1;
                intermediate.DistanceToNext = DistanceToNextConvertor.Decode(data[location]);
                location = location + 1;

                intermediateList.Add(intermediate);
            }

            // decode last location reference point.
            var last = new LocationReferencePoint();

            // no last coordinates, identical to the first.
            last.Coordinate         = first.Coordinate;
            last.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, location, 2);
            last.FormOfWay          = FormOfWayConvertor.Decode(data, location, 5);
            location = location + 1;
            last.LowestFunctionalRoadClassToNext = FunctionalRoadClassConvertor.Decode(data, location, 0);
            last.Bearing = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, location, 3));
            location     = location + 1;

            // create line location.
            var lineLocation = new ClosedLineLocation();

            lineLocation.First        = first;
            lineLocation.Intermediate = intermediateList.ToArray();
            lineLocation.Last         = last;
            return(lineLocation);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Builds a location referenced point for the vertex at the given start-index.
        /// </summary>
        /// <returns></returns>
        public LocationReferencePoint BuildLocationReferencePoint(ReferencedLine referencedLocation, int start, int end)
        {
            FormOfWay           fow;
            FunctionalRoadClass frc;

            // get all coordinates along the sequence starting at 'start' and ending at 'end'.
            var coordinates = referencedLocation.GetCoordinates(this.Graph, start, end - start + 1);

            // create location reference point.
            var locationReferencePoint = new LocationReferencePoint();

            locationReferencePoint.Coordinate = this.GetVertexLocation(referencedLocation.Vertices[start]);
            var tags = this.GetTags(referencedLocation.Edges[start].Tags);

            if (!this.TryMatching(tags, out frc, out fow))
            {
                throw new ReferencedEncodingException(referencedLocation,
                                                      "Could not find frc and/or fow for the given tags.");
            }
            locationReferencePoint.FormOfWay          = fow;
            locationReferencePoint.FuntionalRoadClass = frc;
            locationReferencePoint.Bearing            = (int)BearingEncoder.EncodeBearing(coordinates).Value;
            locationReferencePoint.DistanceToNext     = (int)coordinates.Length().Value;
            FunctionalRoadClass?lowest = null;

            for (var edge = start; edge < end; edge++)
            {
                tags = this.GetTags(referencedLocation.Edges[edge].Tags);
                if (!this.TryMatching(tags, out frc, out fow))
                {
                    throw new ReferencedEncodingException(referencedLocation,
                                                          "Could not find frc and/or fow for the given tags.");
                }

                if (!lowest.HasValue ||
                    frc < lowest)
                {
                    lowest = frc;
                }
            }
            locationReferencePoint.LowestFunctionalRoadClassToNext = lowest;

            return(locationReferencePoint);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Finds all candidate vertex/edge pairs for a given location reference point.
        /// </summary>
        /// <param name="lrp"></param>
        /// <param name="forward"></param>
        /// <param name="maxVertexDistance"></param>
        /// <returns></returns>
        public virtual SortedSet <CandidateVertexEdge> FindCandidatesFor(LocationReferencePoint lrp, bool forward, Meter maxVertexDistance)
        {
            var vertexEdgeCandidates = new SortedSet <CandidateVertexEdge>(new CandidateVertexEdgeComparer());
            var vertexCandidates     = this.FindCandidateVerticesFor(lrp, maxVertexDistance);

            foreach (var vertexCandidate in vertexCandidates)
            {
                var edgeCandidates = this.FindCandidateEdgesFor(vertexCandidate.Vertex, forward, lrp.FormOfWay.Value, lrp.FuntionalRoadClass.Value, (Degree)lrp.Bearing.Value);
                foreach (var edgeCandidate in edgeCandidates)
                {
                    vertexEdgeCandidates.Add(new CandidateVertexEdge()
                    {
                        Edge         = edgeCandidate.Edge,
                        Vertex       = vertexCandidate.Vertex,
                        TargetVertex = edgeCandidate.TargetVertex,
                        Score        = vertexCandidate.Score * edgeCandidate.Score
                    });
                }
            }
            return(vertexEdgeCandidates);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Decodes the given data into a location reference.
        /// </summary>
        public static PoiWithAccessPointLocation Decode(byte[] data)
        {
            // decode first location reference point.
            var first = new LocationReferencePoint();

            first.Coordinate = CoordinateConverter.Decode(data, 1);
            var orientation = OrientationConverter.Decode(data, 7, 0);

            first.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, 7, 2);
            first.FormOfWay          = FormOfWayConvertor.Decode(data, 7, 5);
            first.LowestFunctionalRoadClassToNext = FunctionalRoadClassConvertor.Decode(data, 8, 0);
            first.Bearing        = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, 8, 3));
            first.DistanceToNext = DistanceToNextConvertor.Decode(data[9]);

            // decode last location reference point.
            var last = new LocationReferencePoint();

            // no last coordinates, identical to the first.
            last.Coordinate = CoordinateConverter.DecodeRelative(first.Coordinate, data, 10);
            var sideOfRoad = SideOfRoadConverter.Decode(data, 14, 0);

            last.FuntionalRoadClass = FunctionalRoadClassConvertor.Decode(data, 14, 2);
            last.FormOfWay          = FormOfWayConvertor.Decode(data, 14, 5);
            last.Bearing            = BearingConvertor.DecodeAngleFromBearing(BearingConvertor.Decode(data, 15, 3));

            // poi details.
            var coordinate = CoordinateConverter.DecodeRelative(first.Coordinate, data, 17);

            // create line location.
            var poiWithAccessPointLocation = new PoiWithAccessPointLocation();

            poiWithAccessPointLocation.First          = first;
            poiWithAccessPointLocation.Last           = last;
            poiWithAccessPointLocation.Coordinate     = coordinate;
            poiWithAccessPointLocation.Orientation    = orientation;
            poiWithAccessPointLocation.PositiveOffset = null;
            poiWithAccessPointLocation.SideOfRoad     = sideOfRoad;
            return(poiWithAccessPointLocation);
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Finds candidate vertices for a location reference point.
 /// </summary>
 /// <param name="lrp"></param>
 /// <returns></returns>
 public override IEnumerable <CandidateVertex> FindCandidateVerticesFor(LocationReferencePoint lrp)
 {
     return(this.FindCandidateVerticesFor(lrp, this.MaxVertexDistance));
 }
Ejemplo n.º 8
0
        /// <summary>
        /// Finds candidate vertices for a location reference point.
        /// </summary>
        /// <param name="lrp"></param>
        /// <param name="maxVertexDistance"></param>
        /// <returns></returns>
        public virtual IEnumerable <CandidateVertex> FindCandidateVerticesFor(LocationReferencePoint lrp, Meter maxVertexDistance)
        {
            // convert to geo coordinate.
            var geoCoordinate = new GeoCoordinate(lrp.Coordinate.Latitude, lrp.Coordinate.Longitude);

            // build candidates list.
            var candidates       = new HashSet <long>();
            var scoredCandidates = new List <CandidateVertex>();

            float latitude, longitude;

            // create a search box.
            var box = new GeoCoordinateBox(geoCoordinate, geoCoordinate);

            box = box.Resize(_candidateSearchBoxSize);

            // get arcs.
            var arcs = this.Graph.GetEdges(box);

            foreach (var arc in arcs)
            {
                long vertex = arc.Item1;
                if (!candidates.Contains(vertex))
                {
                    this.Graph.GetVertex(vertex, out latitude, out longitude);
                    var distance = geoCoordinate.DistanceEstimate(new GeoCoordinate(latitude, longitude));
                    if (distance.Value < maxVertexDistance.Value)
                    {
                        candidates.Add(vertex);
                        scoredCandidates.Add(new CandidateVertex()
                        {
                            Score  = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", _maxVertexDistance), (float)System.Math.Max(0, (1.0 - (distance.Value / _maxVertexDistance.Value))), 1), // calculate scoring compared to the fixed max distance.
                            Vertex = vertex
                        });
                    }
                }
                vertex = arc.Item2;
                if (!candidates.Contains(vertex))
                {
                    this.Graph.GetVertex(vertex, out latitude, out longitude);
                    var distance = geoCoordinate.DistanceEstimate(new GeoCoordinate(latitude, longitude));
                    if (distance.Value < maxVertexDistance.Value)
                    {
                        candidates.Add(vertex);
                        scoredCandidates.Add(new CandidateVertex()
                        {
                            Score  = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", _maxVertexDistance), (float)System.Math.Max(0, (1.0 - (distance.Value / _maxVertexDistance.Value))), 1), // calculate scoring compared to the fixed max distance.
                            Vertex = vertex
                        });
                    }
                }
            }

            if (scoredCandidates.Count == 0)
            { // no candidates, create a virtual candidate.
                var closestEdge = this.Graph.GetClosestEdge(geoCoordinate, maxVertexDistance, 0.1);
                if (closestEdge != null)
                {
                    var coordinates = this.Graph.GetCoordinates(closestEdge);

                    OsmSharp.Math.Primitives.PointF2D          bestProjected;
                    OsmSharp.Math.Primitives.LinePointPosition bestPosition;
                    Meter bestOffset;
                    int   bestIndex;
                    if (coordinates.ProjectOn(geoCoordinate, out bestProjected, out bestPosition, out bestOffset, out bestIndex))
                    { // successfully projected, insert virtual vertex.
                        var distance = geoCoordinate.DistanceEstimate(new GeoCoordinate(bestProjected[1], bestProjected[0]));
                        if (distance.Value < maxVertexDistance.Value)
                        {
                            this.Graph.RemoveEdge(closestEdge.Item1, closestEdge.Item2);
                            this.Graph.RemoveEdge(closestEdge.Item2, closestEdge.Item1);

                            var newVertex = this.Graph.AddVertex((float)bestProjected[1], (float)bestProjected[0]);

                            // build distance before/after.
                            var distanceBefore = bestOffset.Value;
                            var distanceAfter  = closestEdge.Item3.Distance - bestOffset.Value;

                            // build coordinates before/after.
                            var coordinatesBefore = new List <GeoCoordinateSimple>(
                                coordinates.GetRange(1, bestIndex).Select(x => new GeoCoordinateSimple()
                            {
                                Latitude  = (float)x.Latitude,
                                Longitude = (float)x.Longitude
                            }));
                            var coordinatesAfter = new List <GeoCoordinateSimple>(
                                coordinates.GetRange(bestIndex + 1, coordinates.Count - 1 - bestIndex - 1).Select(x => new GeoCoordinateSimple()
                            {
                                Latitude  = (float)x.Latitude,
                                Longitude = (float)x.Longitude
                            }));

                            this.Graph.AddEdge(closestEdge.Item1, newVertex, new LiveEdge()
                            {
                                Distance = (float)distanceBefore,
                                Forward  = closestEdge.Item3.Forward,
                                Tags     = closestEdge.Item3.Tags
                            }, coordinatesBefore.Count > 0 ? coordinatesBefore.ToArray() : null);
                            this.Graph.AddEdge(newVertex, closestEdge.Item2, new LiveEdge()
                            {
                                Distance = (float)distanceAfter,
                                Forward  = closestEdge.Item3.Forward,
                                Tags     = closestEdge.Item3.Tags
                            }, coordinatesAfter.Count > 0 ? coordinatesAfter.ToArray() : null);

                            scoredCandidates.Add(new CandidateVertex()
                            {
                                Score = Score.New(Score.VERTEX_DISTANCE,
                                                  string.Format("The vertex score compare to max distance {0}", _maxVertexDistance),
                                                  (float)System.Math.Max(0, (1.0 - (distance.Value / _maxVertexDistance.Value))), 1), // calculate scoring compared to the fixed max distance.
                                Vertex = newVertex
                            });
                        }
                    }
                }
            }
            return(scoredCandidates);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Finds all candidate vertex/edge pairs for a given location reference point.
 /// </summary>
 /// <param name="lrp"></param>
 /// <param name="forward"></param>
 /// <returns></returns>
 public virtual SortedSet <CandidateVertexEdge> FindCandidatesFor(LocationReferencePoint lrp, bool forward)
 {
     return(this.FindCandidatesFor(lrp, forward, _maxVertexDistance));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Finds candidate vertices for a location reference point.
 /// </summary>
 /// <param name="lrp"></param>
 /// <returns></returns>
 public virtual IEnumerable <CandidateVertex> FindCandidateVerticesFor(LocationReferencePoint lrp)
 {
     return(this.FindCandidateVerticesFor(lrp, _maxVertexDistance));
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Finds candidate vertices for a location reference point.
        /// </summary>
        public static IEnumerable <CandidateLocation> FindCandidateLocationsFor(this Coder coder, LocationReferencePoint lrp, float maxVertexDistanceInMeter = 40,
                                                                                float candidateSearchBoxSize = 0.01f)
        {
            // build candidates list.
            var scoredCandidates = new List <CandidateLocation>();
            var lrpCoordinate    = new Itinero.LocalGeo.Coordinate((float)lrp.Coordinate.Latitude, (float)lrp.Coordinate.Longitude);

            // get vertices and check their edges.
            var vertices       = coder.Router.Db.Network.GeometricGraph.Search((float)lrp.Coordinate.Latitude, (float)lrp.Coordinate.Longitude, candidateSearchBoxSize);
            var candidates     = new HashSet <long>();
            var edgeEnumerator = coder.Router.Db.Network.GetEdgeEnumerator();

            foreach (var v in vertices)
            {
                if (candidates.Contains(v))
                { // vertex was already considered.
                    continue;
                }

                var vertexLocation = coder.Router.Db.Network.GetVertex(v);
                var distance       = Itinero.LocalGeo.Coordinate.DistanceEstimateInMeter(vertexLocation, lrpCoordinate);
                if (distance < maxVertexDistanceInMeter)
                {
                    candidates.Add(v);

                    // check if there are edges that can be used for the given profile.
                    edgeEnumerator.MoveTo(v);

                    RouterPoint location;
                    if (coder.Router.Db.TryCreateRouterPointForVertex(v, coder.Profile.Profile, out location))
                    {
                        scoredCandidates.Add(new CandidateLocation()
                        {
                            Score = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", maxVertexDistanceInMeter),
                                              (float)System.Math.Max(0, (1.0 - (distance / maxVertexDistanceInMeter))), 1), // calculate scoring compared to the fixed max distance.
                            Location = location
                        });
                    }
                }
            }

            var candidatesQualityOK = false;

            foreach (var candidate in scoredCandidates)
            {
                if (candidate.Score.Value / candidate.Score.Reference >=
                    System.Math.Min(coder.Profile.ScoreThreshold + coder.Profile.ScoreThreshold, 0.7))
                { // at least one above threshold, keep it.
                    candidatesQualityOK = true;
                }
            }

            if (!candidatesQualityOK)
            { // no candidates, create a virtual candidate.
                var routerPoints = coder.Router.ResolveMultiple(new Itinero.Profiles.Profile[] { coder.Profile.Profile }, lrpCoordinate.Latitude, lrpCoordinate.Longitude, maxVertexDistanceInMeter);
                if (routerPoints.Count == 0)
                {
                    throw new Exception("No candidates found for LRP: Could not resolve a point at the location.");
                }
                foreach (var routerPoint in routerPoints)
                {
                    var distance = Itinero.LocalGeo.Coordinate.DistanceEstimateInMeter(routerPoint.LocationOnNetwork(coder.Router.Db), lrpCoordinate);
                    scoredCandidates.Add(new CandidateLocation()
                    {
                        Score = Score.New(Score.VERTEX_DISTANCE, string.Format("The vertex score compare to max distance {0}", maxVertexDistanceInMeter),
                                          (float)System.Math.Max(0, (1.0 - (distance / maxVertexDistanceInMeter))), 1), // calculate scoring compared to the fixed max distance.
                        Location = routerPoint
                    });
                }
            }
            return(scoredCandidates);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Finds all candidate vertex/edge pairs for a given location reference point.
        /// </summary>
        public static Itinero.Algorithms.Collections.SortedSet <CandidatePathSegment> FindCandidatesFor(this Coder coder, LocationReferencePoint lrp, bool forward, float maxVertexDistance = 40)
        {
            var vertexEdgeCandidates = new Itinero.Algorithms.Collections.SortedSet <CandidatePathSegment>(new CandidateVertexEdgeComparer());
            var vertexCandidates     = coder.FindCandidateLocationsFor(lrp, maxVertexDistance);

            foreach (var vertexCandidate in vertexCandidates)
            {
                var edgeCandidates = coder.FindCandidatePathSegmentsFor(vertexCandidate, forward, lrp.FormOfWay.Value, lrp.FuntionalRoadClass.Value,
                                                                        lrp.Bearing.Value);
                foreach (var edgeCandidate in edgeCandidates)
                {
                    vertexEdgeCandidates.Add(edgeCandidate);
                }
            }
            return(vertexEdgeCandidates);
        }