/// <summary>
        /// Loads a router db given the OSM file.
        /// </summary>
        /// <param name="osmPbfFile">An OSM-PBF file.</param>
        /// <returns>A loaded router db</returns>
        public static RouterDb LoadFrom(string osmPbfFile)
        {
            var routerDb = new RouterDb();

            using (var stream = File.OpenRead(osmPbfFile))
            {
                var source   = new OsmSharp.Streams.PBFOsmStreamSource(stream);
                var progress = new OsmSharp.Streams.Filters.OsmStreamFilterProgress();
                progress.RegisterSource(source);

                var target = new RouterDbStreamTarget(routerDb);
                target.RegisterSource(progress);
                target.Initialize();

                target.Pull();
            }

            return(routerDb);
        }
Exemple #2
0
        public void TestAddingOneRelation()
        {
            // build source stream.
            var location1 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7835588455200195f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7907257080078125f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2 }
                },
                new Relation()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("type", "to_add")),
                    Members = new RelationMember[]
                    {
                        new RelationMember()
                        {
                            Id   = 1,
                            Role = "some_role",
                            Type = OsmGeoType.Way
                        }
                    }
                }
            };

            // create processor.
            var processors = new ITwoPassProcessor[]
            {
                new SimpleRelationTagProcessor()
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            }, processors: processors);

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();
        }
        public void TestOneWayWithClosedPath()
        {
            // build source stream with one way:
            //
            //         (1)
            //          |
            //          |
            //    (3)--(2)--(5)
            //      \       /
            //       \     /
            //        \   /
            //         (4)
            //
            // this should result in edges:
            //   1-2, 2-2 (along 3-4-5)

            var location1 = new Coordinate()
            {
                Latitude = 51.26118473347939f, Longitude = 4.796192049980164f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.26137943317470f, Longitude = 4.796060621738434f
            };
            var location3 = new Coordinate()
            {
                Latitude = 51.26142810796969f, Longitude = 4.796184003353119f
            };
            var location4 = new Coordinate()
            {
                Latitude = 51.26152881427841f, Longitude = 4.795939922332763f
            };
            var location5 = new Coordinate()
            {
                Latitude = 51.26134754276387f, Longitude = 4.795937240123749f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Node()
                {
                    Id        = 4,
                    Latitude  = location4.Latitude,
                    Longitude = location4.Longitude
                },
                new Node()
                {
                    Id        = 5,
                    Latitude  = location5.Latitude,
                    Longitude = location5.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3, 4, 5, 2 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();

            routerDb.Network.GeometricGraph.Graph.MarkAsMulti();
            var target = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(2, routerDb.Network.VertexCount);
            Assert.AreEqual(2, routerDb.Network.EdgeCount);

            var vertex1 = this.FindVertex(routerDb, location1.Latitude, location1.Longitude);
            var vertex2 = this.FindVertex(routerDb, location2.Latitude, location2.Longitude);

            // verify 1->2
            var edges = routerDb.Network.GetEdgeEnumerator(vertex1);
            var edge  = edges.First(x => x.To == vertex2);

            Assert.IsNotNull(edge);
            var data    = edge.Data;
            var profile = routerDb.EdgeProfiles.Get(data.Profile);
            var meta    = routerDb.EdgeMeta.Get(data.MetaId);

            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location1, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            // verify 2->2
            edges = routerDb.Network.GetEdgeEnumerator(vertex2);
            edge  = edges.First(x => x.To == vertex2);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location2, location3) +
                            Coordinate.DistanceEstimateInMeter(location3, location4) +
                            Coordinate.DistanceEstimateInMeter(location4, location5) +
                            Coordinate.DistanceEstimateInMeter(location5, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            // build source stream with one way:
            //
            //         (1)
            //          |
            //          |
            //         (2)
            //          |
            //          |
            //         (3)
            // the the way contains the following sequence of nodes:
            //  1, 2, 3, 2
            //
            // this should result in edges:
            //   1-2, 2-2 (along 3)

            location1 = new Coordinate()
            {
                Latitude = 51.26118473347939f, Longitude = 4.796192049980164f
            };
            location2 = new Coordinate()
            {
                Latitude = 51.26137943317470f, Longitude = 4.796060621738434f
            };
            location3 = new Coordinate()
            {
                Latitude = 51.26142810796969f, Longitude = 4.796184003353119f
            };
            source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3, 2 }
                }
            };

            // build db from stream.
            routerDb = new RouterDb();
            routerDb.Network.GeometricGraph.Graph.MarkAsMulti();
            target = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });
            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(2, routerDb.Network.VertexCount);
            Assert.AreEqual(2, routerDb.Network.EdgeCount);

            vertex1 = this.FindVertex(routerDb, location1.Latitude, location1.Longitude);
            vertex2 = this.FindVertex(routerDb, location2.Latitude, location2.Longitude);

            // verify 1->2
            edges = routerDb.Network.GetEdgeEnumerator(vertex1);
            edge  = edges.First(x => x.To == vertex2);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location1, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            // verify 2->3
            edges = routerDb.Network.GetEdgeEnumerator(vertex2);
            edge  = edges.First(x => x.To == vertex2);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location2, location3) +
                            Coordinate.DistanceEstimateInMeter(location3, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);
        }
        public void TestPositiveRestriction()
        {
            // build source stream.
            var location1 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7835588455200195f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7907257080078125f
            };
            var location3 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7978925704956050f
            };
            var location4 = new Coordinate()
            {
                Latitude = 51.265106473294075f, Longitude = 4.7907257080078125f
            };
            var location5 = new Coordinate()
            {
                Latitude = 51.264916473294075f, Longitude = 4.7907257080078125f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Node()
                {
                    Id        = 4,
                    Latitude  = location4.Latitude,
                    Longitude = location4.Longitude
                },
                new Node()
                {
                    Id        = 5,
                    Latitude  = location5.Latitude,
                    Longitude = location5.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2 }
                },
                new Way()
                {
                    Id   = 2,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 2, 3 }
                },
                new Way()
                {
                    Id   = 3,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 2, 4 }
                },
                new Way()
                {
                    Id   = 4,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 2, 5 }
                },
                new Relation()
                {
                    Id      = 1,
                    Members = new RelationMember[]
                    {
                        new RelationMember()
                        {
                            Id   = 2,
                            Role = "via",
                            Type = OsmGeoType.Node
                        },
                        new RelationMember()
                        {
                            Id   = 1,
                            Role = "from",
                            Type = OsmGeoType.Way
                        },
                        new RelationMember()
                        {
                            Id   = 2,
                            Role = "to",
                            Type = OsmGeoType.Way
                        }
                    },
                    Tags = new TagsCollection(
                        new Tag("type", "restriction"),
                        new Tag("restriction", "only_straight_on"))
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            }, processRestrictions: true);

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(5, routerDb.Network.VertexCount);
            Assert.AreEqual(4, routerDb.Network.EdgeCount);

            // check for a restriction.
            RestrictionsDb restrictions;

            Assert.IsTrue(routerDb.TryGetRestrictions("motor_vehicle", out restrictions));
            Assert.AreEqual(2, restrictions.Count);
        }
        public void TestTwoWays()
        {
            // build source stream.
            var location1 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7835588455200195f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7907257080078125f
            };
            var location3 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7978925704956050f
            };
            var location4 = new Coordinate()
            {
                Latitude = 51.269567822699510f, Longitude = 4.7907257080078125f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Node()
                {
                    Id        = 4,
                    Latitude  = location4.Latitude,
                    Longitude = location4.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3 }
                },
                new Way()
                {
                    Id   = 2,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 2, 4 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(4, routerDb.Network.VertexCount);
            Assert.AreEqual(3, routerDb.Network.EdgeCount);

            var vertex1 = this.FindVertex(routerDb, location1.Latitude, location1.Longitude);

            Assert.AreNotEqual(uint.MaxValue, vertex1);
            var vertex2 = this.FindVertex(routerDb, location2.Latitude, location2.Longitude);

            Assert.AreNotEqual(uint.MaxValue, vertex2);
            var vertex3 = this.FindVertex(routerDb, location3.Latitude, location3.Longitude);

            Assert.AreNotEqual(uint.MaxValue, vertex3);
            var vertex4 = this.FindVertex(routerDb, location4.Latitude, location4.Longitude);

            Assert.AreNotEqual(uint.MaxValue, vertex4);

            // verify 1->2
            var edges = routerDb.Network.GetEdgeEnumerator(vertex1);
            var edge  = edges.FirstOrDefault();

            Assert.IsNotNull(edge);
            var data    = edge.Data;
            var profile = routerDb.EdgeProfiles.Get(data.Profile);
            var meta    = routerDb.EdgeMeta.Get(data.MetaId);

            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location1, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            edges = routerDb.Network.GetEdgeEnumerator(vertex2);
            Assert.AreEqual(3, edges.Count());

            // verify 2->1
            edge = edges.FirstOrDefault(x => x.To == vertex1);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location1, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            // verify 2->3
            edge = edges.FirstOrDefault(x => x.To == vertex3);
            Assert.IsNotNull(edge);
            edge    = edges.FirstOrDefault();
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location3, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            // verify 2->4
            edge = edges.FirstOrDefault(x => x.To == vertex4);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location4, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            edges = routerDb.Network.GetEdgeEnumerator(vertex3);
            Assert.AreEqual(1, edges.Count());

            // verify 3->2
            edge = edges.FirstOrDefault(x => x.To == vertex2);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location3, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);

            edges = routerDb.Network.GetEdgeEnumerator(vertex4);
            Assert.AreEqual(1, edges.Count());

            // verify 4->2
            edge = edges.FirstOrDefault(x => x.To == vertex2);
            Assert.IsNotNull(edge);
            data    = edge.Data;
            profile = routerDb.EdgeProfiles.Get(data.Profile);
            meta    = routerDb.EdgeMeta.Get(data.MetaId);
            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location4, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);
        }
        public void TestOneWay()
        {
            // build source stream.
            var location1 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7835588455200195f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7907257080078125f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(2, routerDb.Network.VertexCount);
            Assert.AreEqual(1, routerDb.Network.EdgeCount);

            var vertex1 = this.FindVertex(routerDb, 51.265016473294075f, 4.7835588455200195f);

            Assert.AreNotEqual(uint.MaxValue, vertex1);
            var vertex2 = this.FindVertex(routerDb, 51.265016473294075f, 4.7907257080078125f);

            Assert.AreNotEqual(uint.MaxValue, vertex2);

            // get edge-information.
            var edges   = routerDb.Network.GetEdgeEnumerator(vertex1);
            var data    = edges.First().Data;
            var profile = routerDb.EdgeProfiles.Get(data.Profile);
            var meta    = routerDb.EdgeMeta.Get(data.MetaId);

            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location1, location2), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);
        }
        public void TestOneWayIncomplete()
        {
            // build source stream.
            var location1 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7835588455200195f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.265016473294075f, Longitude = 4.7907257080078125f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(1, routerDb.Network.VertexCount);

            var vertex1 = this.FindVertex(routerDb, 51.265016473294075f, 4.7835588455200195f);

            Assert.AreNotEqual(uint.MaxValue, vertex1);

            // another version of the same incomplete way.
            source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 3, 2, 1 }
                }
            };

            // build db from stream.
            routerDb = new RouterDb();
            target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });
            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(0, routerDb.Network.VertexCount);
        }
        public void TestKeepingWayIds()
        {
            // build source stream with two ways:
            //
            //         (1)
            //          |
            //         (2)
            //          |
            //    (4)--(3)--(5)
            //
            // this should result in edges:
            //   1-3, 4-3, 3-5

            var location1 = new Coordinate()
            {
                Latitude = 51.26118473347939f, Longitude = 4.796192049980164f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.26137943317470f, Longitude = 4.796060621738434f
            };
            var location3 = new Coordinate()
            {
                Latitude = 51.26142810796969f, Longitude = 4.796184003353119f
            };
            var location4 = new Coordinate()
            {
                Latitude = 51.26152881427841f, Longitude = 4.795939922332763f
            };
            var location5 = new Coordinate()
            {
                Latitude = 51.26134754276387f, Longitude = 4.795937240123749f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Node()
                {
                    Id        = 4,
                    Latitude  = location4.Latitude,
                    Longitude = location4.Longitude
                },
                new Node()
                {
                    Id        = 5,
                    Latitude  = location5.Latitude,
                    Longitude = location5.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3 }
                },
                new Way()
                {
                    Id   = 2,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 4, 3, 5 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.KeepWayIds = true;
            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(4, routerDb.Network.VertexCount);
            Assert.AreEqual(3, routerDb.Network.EdgeCount);

            var vertex1 = this.FindVertex(routerDb, location1.Latitude, location1.Longitude);
            var vertex3 = this.FindVertex(routerDb, location3.Latitude, location3.Longitude);
            var vertex4 = this.FindVertex(routerDb, location4.Latitude, location4.Longitude);
            var vertex5 = this.FindVertex(routerDb, location5.Latitude, location5.Longitude);

            var wayIds = routerDb.EdgeData.Get <long>("way_id");

            Assert.IsNotNull(wayIds);
            var wayNodeIndices = routerDb.EdgeData.Get <ushort>("way_node_idx");

            Assert.IsNotNull(wayNodeIndices);

            var edge = routerDb.Network.GetEdges(vertex1).First(x => x.To == vertex3).Id;

            Assert.AreEqual(1, wayIds[edge]);
            Assert.AreEqual(0, wayNodeIndices[edge]);
            edge = routerDb.Network.GetEdges(vertex4).First(x => x.To == vertex3).Id;
            Assert.AreEqual(2, wayIds[edge]);
            Assert.AreEqual(0, wayNodeIndices[edge]);
            edge = routerDb.Network.GetEdges(vertex3).First(x => x.To == vertex5).Id;
            Assert.AreEqual(2, wayIds[edge]);
            Assert.AreEqual(1, wayNodeIndices[edge]);
        }
        public void TestOneWayWithAShapePoint()
        {
            // build source stream.
            var location1 = new Coordinate()
            {
                Latitude = 49.8355328612026f, Longitude = 5.754808187484741f
            };
            var location2 = new Coordinate()
            {
                Latitude = 49.83543598213665f, Longitude = 5.755451917648315f
            };
            var location3 = new Coordinate()
            {
                Latitude = 49.83556054090007f, Longitude = 5.756278038024902f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();
            var target   = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(2, routerDb.Network.VertexCount);
            Assert.AreEqual(1, routerDb.Network.EdgeCount);

            var vertex1 = this.FindVertex(routerDb, location1.Latitude, location1.Longitude);

            Assert.AreNotEqual(uint.MaxValue, vertex1);
            var vertex2 = this.FindVertex(routerDb, location3.Latitude, location3.Longitude);

            Assert.AreNotEqual(uint.MaxValue, vertex2);

            // get edge-information.
            var edges   = routerDb.Network.GetEdgeEnumerator(vertex1);
            var data    = edges.First().Data;
            var profile = routerDb.EdgeProfiles.Get(data.Profile);
            var meta    = routerDb.EdgeMeta.Get(data.MetaId);
            var shape   = edges.First().Shape;

            Assert.AreEqual(Coordinate.DistanceEstimateInMeter(location1, location2) +
                            Coordinate.DistanceEstimateInMeter(location2, location3), data.Distance, 0.1);
            Assert.IsTrue(profile.Contains("highway", "residential"));
            Assert.AreEqual(new AttributeCollection(), meta);
            Assert.IsNotNull(shape);
            Assert.AreEqual(1, shape.Count);
            Assert.AreEqual(location2.Latitude, shape[0].Latitude, 0.00001f);
            Assert.AreEqual(location2.Longitude, shape[0].Longitude, 0.00001f);
        }
        public void TestKeepingNodeIds()
        {
            // build source stream with one way:
            //
            //         (1)
            //          |
            //          |
            //    (3)--(2)--(5)
            //      \       /
            //       \     /
            //        \   /
            //         (4)
            //
            // this should result in edges:
            //   1-2, 2-2 (along 3-4-5)

            var location1 = new Coordinate()
            {
                Latitude = 51.26118473347939f, Longitude = 4.796192049980164f
            };
            var location2 = new Coordinate()
            {
                Latitude = 51.26137943317470f, Longitude = 4.796060621738434f
            };
            var location3 = new Coordinate()
            {
                Latitude = 51.26142810796969f, Longitude = 4.796184003353119f
            };
            var location4 = new Coordinate()
            {
                Latitude = 51.26152881427841f, Longitude = 4.795939922332763f
            };
            var location5 = new Coordinate()
            {
                Latitude = 51.26134754276387f, Longitude = 4.795937240123749f
            };
            var source = new OsmGeo[] {
                new Node()
                {
                    Id        = 1,
                    Latitude  = location1.Latitude,
                    Longitude = location1.Longitude
                },
                new Node()
                {
                    Id        = 2,
                    Latitude  = location2.Latitude,
                    Longitude = location2.Longitude
                },
                new Node()
                {
                    Id        = 3,
                    Latitude  = location3.Latitude,
                    Longitude = location3.Longitude
                },
                new Node()
                {
                    Id        = 4,
                    Latitude  = location4.Latitude,
                    Longitude = location4.Longitude
                },
                new Node()
                {
                    Id        = 5,
                    Latitude  = location5.Latitude,
                    Longitude = location5.Longitude
                },
                new Way()
                {
                    Id   = 1,
                    Tags = new TagsCollection(
                        new Tag("highway", "residential")),
                    Nodes = new long[] { 1, 2, 3, 4, 5, 2 }
                }
            };

            // build db from stream.
            var routerDb = new RouterDb();

            routerDb.Network.GeometricGraph.Graph.MarkAsMulti();
            var target = new RouterDbStreamTarget(
                routerDb, new Itinero.Profiles.Vehicle[] {
                Vehicle.Car
            });

            target.KeepNodeIds = true;
            target.RegisterSource(source);
            target.Initialize();
            target.Pull();

            // check result.
            Assert.AreEqual(2, routerDb.Network.VertexCount);
            Assert.AreEqual(2, routerDb.Network.EdgeCount);

            var vertex1 = this.FindVertex(routerDb, location1.Latitude, location1.Longitude);
            var vertex2 = this.FindVertex(routerDb, location2.Latitude, location2.Longitude);

            var nodeIds = routerDb.VertexData.Get <long>("node_id");

            Assert.AreEqual(1, nodeIds[vertex1]);
            Assert.AreEqual(2, nodeIds[vertex2]);
        }
        /// <summary>
        /// Loads a routing network created from OSM data.
        /// </summary>
        public static void LoadOsmDataAndShortcuts(this RouterDb db, OsmStreamSource source, LoadSettings settings,
                                                   params Itinero.Profiles.Vehicle[] vehicles)
        {
            if (!db.IsEmpty)
            {
                throw new ArgumentException(
                          "Can only load a new routing network into an empty router db, add multiple streams at once to load multiple files.");
            }

            if (vehicles == null || vehicles.Length == 0)
            {
                throw new ArgumentNullException("vehicles", "A least one vehicle is needed to load OSM data.");
            }

            if (settings == null)
            {
                settings = new LoadSettings();
            }

            // merge sources if needed.
            var progress = new OsmStreamFilterProgress();

            progress.RegisterSource(source);
            source = progress;

            // make sure the routerdb can handle multiple edges.
            db.Network.GeometricGraph.Graph.MarkAsMulti();

            // load the data.
            var target = new RouterDbStreamTarget(db,
                                                  vehicles, settings.AllCore, processRestrictions: settings.ProcessRestrictions,
                                                  processors: settings.Processors,
                                                  simplifyEpsilonInMeter: settings.NetworkSimplificationEpsilon);

            target.KeepNodeIds = settings.KeepNodeIds;
            target.KeepWayIds  = settings.KeepWayIds;
            target.RegisterSource(source);
            target.Pull();

            foreach (var profile in db.GetSupportedProfiles())
            {
                db.AddIslandData(profile);
            }

            foreach (var vehicleType in db.GetRestrictedVehicleTypes().ToList())
            {
                db.RemoveRestrictions(vehicleType);
            }

            db.Sort();

//            // optimize the network.
            db.RemoveDuplicateEdges();
//            db.SplitLongEdges();
            db.ConvertToSimple();

            AddVelo(db);

//            // optimize the network if requested.
//            if (settings.NetworkSimplificationEpsilon > 0)
//            {
//                db.OptimizeNetwork(settings.NetworkSimplificationEpsilon);
//            }

//            // compress the network.
//            db.Compress();
        }