Пример #1
0
        /// <summary>
        /// Gets a positive offset routerpoint.
        /// </summary>
        public static RouterPoint GetOffsetRouterPoint(this ReferencedLine referencedLine, RouterDb routerDb, float positiveOffsetPercentage)
        {
            var length       = referencedLine.Length(routerDb);
            var lengthOffset = (positiveOffsetPercentage / 100.0f) * length;

            var totalLength = 0f;

            for (var e = 0; e < referencedLine.Edges.Length; e++)
            {
                var directedEdgeId = referencedLine.Edges[e];
                var edge           = routerDb.Network.GetEdge(directedEdgeId);
                var shape          = routerDb.Network.GetShape(edge);
                if (directedEdgeId < 0)
                {
                    shape.Reverse();
                }

                var shapeLength = shape.Length();
                if (lengthOffset < shapeLength + totalLength)
                { // offset is in this edge.
                    var relativeOffset = (lengthOffset - totalLength) / shapeLength;
                    var offset         = (ushort)(ushort.MaxValue * relativeOffset);
                    if (directedEdgeId < 0)
                    {
                        offset = (ushort)(ushort.MaxValue - offset);
                    }
                    var routerPoint = new RouterPoint(0, 0, edge.Id, offset);
                    var location    = routerPoint.LocationOnNetwork(routerDb);
                    return(new RouterPoint(location.Latitude, location.Longitude, edge.Id, offset));
                }
                totalLength += shapeLength;
            }
            return(routerDb.CreateRouterPointForEdge(referencedLine.Edges[referencedLine.Edges.Length - 1], false));
        }
        /// <summary>
        /// Returns the position of the lat/lon in the routerpoint relative to the edge.
        /// </summary>
        /// <returns>Returns left or right.</returns>
        public static RelativeDirectionEnum Direction(this RouterPoint routerPoint, RouterDb routerDb)
        {
            Line segment;
            var  pointOnNetwork = routerPoint.LocationOnNetwork(routerDb, out segment);

            var direction = Itinero.Navigation.Directions.DirectionCalculator.Calculate(
                segment.Coordinate1, pointOnNetwork, routerPoint.Location());

            switch (direction.Direction)
            {
            case RelativeDirectionEnum.Left:
            case RelativeDirectionEnum.SharpLeft:
            case RelativeDirectionEnum.SlightlyLeft:
                return(RelativeDirectionEnum.Left);

            case RelativeDirectionEnum.Right:
            case RelativeDirectionEnum.SharpRight:
            case RelativeDirectionEnum.SlightlyRight:
                return(RelativeDirectionEnum.Right);
            }

            Itinero.Logging.Logger.Log("Extensions", Itinero.Logging.TraceEventType.Warning,
                                       "Cannot determine left or right for routerpoint {1}: {0} was found, taking Left as default.",
                                       direction.Direction, routerPoint.ToInvariantString());
            return(RelativeDirectionEnum.Left);
        }
Пример #3
0
        /// <summary>
        /// Gets a feature collection with features representing the stop links.
        /// </summary>
        /// <returns></returns>
        public static FeatureCollection GetStopLinks(this MultimodalDb db,
                                                     Profile profile, uint stopId)
        {
            var features = new FeatureCollection();

            var stopEnumerator = db.TransitDb.GetStopsEnumerator();

            if (stopEnumerator.MoveTo(stopId))
            {
                var stopLocation = new GeoAPI.Geometries.Coordinate(stopEnumerator.Longitude, stopEnumerator.Latitude);
                var attributes   = new AttributesTable();
                attributes.AddAttribute("stop_id", stopId);
                features.Add(new Feature(new Point(stopLocation), attributes));

                var stopLinksDb = db.GetStopLinksDb(profile).GetEnumerator();
                stopLinksDb.MoveTo(stopId);
                while (stopLinksDb.MoveNext())
                {
                    var routerPoint  = new RouterPoint(0, 0, stopLinksDb.EdgeId, stopLinksDb.Offset);
                    var linkLocation = routerPoint.LocationOnNetwork(db.RouterDb).ToCoordinate();

                    attributes = new AttributesTable();
                    attributes.AddAttribute("edge_id", stopLinksDb.EdgeId.ToInvariantString());
                    attributes.AddAttribute("offset", stopLinksDb.Offset.ToInvariantString());
                    features.Add(new Feature(new Point(linkLocation), attributes));
                    features.Add(new Feature(new LineString(new GeoAPI.Geometries.Coordinate[] { stopLocation, linkLocation }), new AttributesTable()));
                }
            }
            return(features);
        }
Пример #4
0
 /// <summary>
 /// Adds the source.
 /// </summary>
 private void AddSource()
 {
     _shape.Add(_source.LocationOnNetwork(_routerDb));
     _shapeMeta.Add(new Route.Meta()
     {
         Attributes = new AttributeCollection(
             new Attributes.Attribute("profile", _profile.FullName)),
         AttributesDirection = true,
         Shape = _shape.Count - 1
     });
 }
Пример #5
0
        public void TestLocationOnNetwork()
        {
            var routerDb = new RouterDb();

            routerDb.Network.AddVertex(0, 0, 0);
            routerDb.Network.AddVertex(1, .1f, -.1f);
            routerDb.Network.AddEdge(0, 1, new EdgeData()
            {
                Distance = 1000,
                MetaId   = routerDb.EdgeProfiles.Add(new AttributeCollection(
                                                         new Attribute("name", "Abelshausen Blvd."))),
                Profile = (ushort)routerDb.EdgeProfiles.Add(new AttributeCollection(
                                                                new Attribute("highway", "residential")))
            }, new Coordinate(0.025f, -0.025f),
                                     new Coordinate(0.050f, -0.050f),
                                     new Coordinate(0.075f, -0.075f));

            // mock profile.
            var profile = MockProfile.CarMock();

            var point = new RouterPoint(0.04f, -0.04f, 0, (ushort)(0.4 * ushort.MaxValue));

            var location = point.LocationOnNetwork(routerDb);

            Assert.AreEqual(0.04f, location.Latitude, 0.001f);
            Assert.AreEqual(-0.04f, location.Longitude, 0.001f);

            point = new RouterPoint(0.08f, -0.08f, 0, (ushort)(0.8 * ushort.MaxValue));

            location = point.LocationOnNetwork(routerDb);
            Assert.AreEqual(0.08f, location.Latitude, 0.001f);
            Assert.AreEqual(-0.08f, location.Longitude, 0.001f);

            point = new RouterPoint(0, 0, 0, 0);

            location = point.LocationOnNetwork(routerDb);
            Assert.AreEqual(0, location.Latitude, 0.001f);
            Assert.AreEqual(0, location.Longitude, 0.001f);

            point = new RouterPoint(.1f, -.1f, 0, ushort.MaxValue);

            location = point.LocationOnNetwork(routerDb);
            Assert.AreEqual(.1f, location.Latitude, 0.001f);
            Assert.AreEqual(-.1f, location.Longitude, 0.001f);
        }
Пример #6
0
        /// <summary>
        /// Converts this router point to a feature.
        /// </summary>
        public static Feature ToFeature(this RouterPoint routerPoint, RouterDb routerDb)
        {
            var attributes = new AttributesTable();

            attributes.AddAttribute("edge_id", routerPoint.EdgeId.ToInvariantString());
            attributes.AddAttribute("offset", routerPoint.Offset.ToInvariantString());
            if (routerPoint.Attributes != null)
            {
                foreach (var attribute in routerPoint.Attributes)
                {
                    attributes.AddAttribute(attribute.Key, attribute.Value);
                }
            }

            var location = routerPoint.LocationOnNetwork(routerDb).ToGeoAPICoordinate();
            var point    = new Point(location);

            return(new Feature(point, attributes));
        }
Пример #7
0
        /// <summary>
        /// Adds the shape point between from and to and the target location itself.
        /// </summary>
        private void Add(uint from, uint to)
        {
            if (from == Constants.NO_VERTEX &&
                _source.IsVertex())
            { // replace from with the vertex.
                from = _source.VertexId(_routerDb);
            }
            if (to == Constants.NO_VERTEX &&
                _target.IsVertex())
            { // replace to with the vertex.
                to = _target.VertexId(_routerDb);
            }

            if (to == from && to != Constants.NO_VERTEX)
            { // nothing to be done.
                return;
            }

            // get shapepoints and edge.
            var         shape          = new List <Coordinate>(0);
            RoutingEdge edge           = null;
            Coordinate? targetLocation = null;
            var         distance       = 0f;
            var         direction      = true;

            if (from == Constants.NO_VERTEX &&
                to == Constants.NO_VERTEX)
            {     // from is the source and to is the target.
                if (_source.EdgeId != _target.EdgeId)
                { // a route inside one edge but source and target do not match.
                    this.ErrorMessage = "Target and source have to be on the same vertex with a route with only virtual vertices.";
                    return;
                }
                shape          = _source.ShapePointsTo(_routerDb, _target);
                distance       = _source.DistanceTo(_routerDb, _target);
                edge           = _routerDb.Network.GetEdge(_source.EdgeId);
                targetLocation = _target.LocationOnNetwork(_routerDb);
                shape.Add(targetLocation.Value);
            }
            else if (from == Constants.NO_VERTEX)
            { // from is the source and to is a regular vertex.
                edge = _routerDb.Network.GetEdge(_source.EdgeId);
                var toOnEdge = _routerDb.Network.CreateRouterPointForVertex(to,
                                                                            edge.GetOther(to));
                shape          = _source.ShapePointsTo(_routerDb, toOnEdge);
                distance       = _source.DistanceTo(_routerDb, toOnEdge);
                targetLocation = _routerDb.Network.GetVertex(to);
                shape.Add(targetLocation.Value);
            }
            else if (to == Constants.NO_VERTEX)
            { // from is a regular vertex and to is the target.
                edge = _routerDb.Network.GetEdge(_target.EdgeId);
                var fromOnEdge = _routerDb.Network.CreateRouterPointForVertex(from,
                                                                              edge.GetOther(from));
                shape          = fromOnEdge.ShapePointsTo(_routerDb, _target);
                distance       = fromOnEdge.DistanceTo(_routerDb, _target);
                targetLocation = _target.LocationOnNetwork(_routerDb);
                shape.Add(targetLocation.Value);
            }
            else
            { // both are just regular vertices.
                edge      = _routerDb.Network.GetEdgeEnumerator(from).First(x => x.To == to);
                direction = !edge.DataInverted;
                distance  = edge.Data.Distance;
                var shapeEnumerable = edge.Shape;
                if (shapeEnumerable != null)
                {
                    if (edge.DataInverted)
                    {
                        shapeEnumerable = shapeEnumerable.Reverse();
                    }
                    shape.AddRange(shapeEnumerable);
                }
                targetLocation = _routerDb.Network.GetVertex(to);
                shape.Add(targetLocation.Value);
            }

            // get edge details.
            var profile = _routerDb.EdgeProfiles.Get(edge.Data.Profile);
            var speed   = this._profile.Speed(profile);
            var time    = 0f;

            if (speed.Value != 0)
            {
                time = distance / speed.Value;
            }
            var meta       = _routerDb.EdgeMeta.Get(edge.Data.MetaId);
            var attributes = new AttributeCollection(meta);

            attributes.AddOrReplace(profile);
            attributes.AddOrReplace("profile", _profile.FullName);

            // add shape and meta.
            _shape.AddRange(shape);
            var previousMeta = _shapeMeta[_shapeMeta.Count - 1];
            var shapeMeta    = new Route.Meta()
            {
                Shape               = _shape.Count - 1,
                Attributes          = attributes,
                AttributesDirection = direction
            };

            shapeMeta.Distance = distance + previousMeta.Distance;
            shapeMeta.Time     = time + previousMeta.Time;
            _shapeMeta.Add(shapeMeta);
        }
Пример #8
0
        /// <summary>
        /// Builds a point along line location.
        /// </summary>
        public static ReferencedPointAlongLine BuildPointAlongLine(this Coder coder, float latitude, float longitude, out RouterPoint resolvedPoint)
        {
            var routerPoint = coder.Router.TryResolve(coder.Profile.Profile, latitude, longitude);

            if (routerPoint.IsError)
            {
                throw new Exception("Could not build point along line: Could not find an edge close to the given location.");
            }
            resolvedPoint = routerPoint.Value;
            var locationOnNetwork = resolvedPoint.LocationOnNetwork(coder.Router.Db);

            // get edge info.
            var edge = coder.Router.Db.Network.GetEdge(routerPoint.Value.EdgeId);

            // check direction.
            var forward = true;
            var factor  = coder.Profile.Profile.Factor(coder.Router.Db.EdgeProfiles.Get(edge.Data.Profile));

            if (factor.Direction == 2)
            {
                forward = false;
            }

            // build the location with one edge.
            ReferencedPointAlongLine referencedPointAlongLine = null;

            if (forward)
            {
                referencedPointAlongLine = new ReferencedPointAlongLine()
                {
                    Route = new ReferencedLine()
                    {
                        Edges         = new long[] { edge.IdDirected() },
                        Vertices      = new uint[] { edge.From, edge.To },
                        StartLocation = coder.Router.Db.CreateRouterPointForEdgeAndVertex(edge.IdDirected(), edge.From),
                        EndLocation   = coder.Router.Db.CreateRouterPointForEdgeAndVertex(edge.IdDirected(), edge.To)
                    },
                    Latitude    = locationOnNetwork.Latitude,
                    Longitude   = locationOnNetwork.Longitude,
                    Orientation = Orientation.NoOrientation
                };
            }
            else
            {
                referencedPointAlongLine = new ReferencedPointAlongLine()
                {
                    Route = new ReferencedLine()
                    {
                        Edges         = new long[] { -edge.IdDirected() },
                        Vertices      = new uint[] { edge.To, edge.From },
                        StartLocation = coder.Router.Db.CreateRouterPointForEdgeAndVertex(edge.IdDirected(), edge.To),
                        EndLocation   = coder.Router.Db.CreateRouterPointForEdgeAndVertex(edge.IdDirected(), edge.From)
                    },
                    Latitude    = locationOnNetwork.Latitude,
                    Longitude   = locationOnNetwork.Longitude,
                    Orientation = Orientation.NoOrientation
                };
            }

            // expand to valid location.
            referencedPointAlongLine.Route.AdjustToValidPoints(coder);
            referencedPointAlongLine.Route.StartLocation = coder.Router.Db.CreateRouterPointForEdgeAndVertex(
                referencedPointAlongLine.Route.Edges[0], referencedPointAlongLine.Route.Vertices[0]);
            referencedPointAlongLine.Route.EndLocation = coder.Router.Db.CreateRouterPointForEdgeAndVertex(
                referencedPointAlongLine.Route.Edges[referencedPointAlongLine.Route.Edges.Length - 1],
                referencedPointAlongLine.Route.Vertices[referencedPointAlongLine.Route.Vertices.Length - 1]);

            return(referencedPointAlongLine);
        }