Exemplo n.º 1
0
        /// <summary>
        /// Gets the node with given id.
        /// </summary>
        public Node GetNode(long id)
        {
            var tile  = new Tile(0, 0, 0);
            var index = LoadIndex(OsmGeoType.Node, tile);

            while (index != null &&
                   index.TryGetMask(id, out var mask))
            {
                var subTiles = tile.SubTilesForMask2(mask);
                var subTile  = subTiles.First();

                if (subTile.Zoom == _zoom)
                { // load data and find node.
                    var stream = DatabaseCommon.LoadTile(_path, OsmGeoType.Node, subTile, _compressed);
                    if (stream == null)
                    {
                        Log.Warning($"Could not find subtile, it should be there: {subTile}");
                        return(null);
                    }
                    using (stream)
                    {
                        var source = new OsmSharp.Streams.BinaryOsmStreamSource(stream);
                        while (source.MoveNext(false, true, true))
                        {
                            var current = source.Current();

                            if (current.Id == id)
                            {
                                return(current as Node);
                            }
                        }
                    }
                }

                tile  = subTile;
                index = LoadIndex(OsmGeoType.Node, tile);
            }

            return(null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets a complete tile with complete ways and complete first level relations.
        /// </summary>
        internal IEnumerable <OsmGeo> GetRouteableTile(Tile tile, Stream stream)
        {
            // build a hashset of all nodes in the tile.
            var nodesInTile = new Dictionary <long, Node>();

            using (stream)
            {
                if (stream == null)
                {
                    yield break;
                }
                var source = new OsmSharp.Streams.BinaryOsmStreamSource(stream);
                while (source.MoveNext(false, true, true))
                {
                    var current = source.Current();

                    if (!(current is Node n))
                    {
                        continue;
                    }
                    if (n.Id == null)
                    {
                        continue;
                    }

                    nodesInTile.Add(n.Id.Value, n);
                }
            }

            // go over all ways and also include all nodes between the first/last node in the tile.
            // also include one node before or after the first/last node in the tile.
            var nodesToInclude = new SortedDictionary <long, Node>();

            using (stream = DatabaseCommon.LoadTile(_path, OsmGeoType.Way, tile, _compressed))
            {
                if (stream != null)
                {
                    var source = new OsmSharp.Streams.BinaryOsmStreamSource(stream);
                    while (source.MoveNext(true, false, true))
                    {
                        var current = source.Current();

                        var w = current as Way;
                        if (w?.Nodes == null)
                        {
                            continue;
                        }

                        var first = int.MaxValue;
                        var last  = -1;
                        for (var n = 0; n < w.Nodes.Length; n++)
                        {
                            var nodeId = w.Nodes[n];
                            if (!nodesInTile.ContainsKey(nodeId))
                            {
                                continue;
                            }

                            if (n < first)
                            {
                                first = n;
                            }
                            if (n > last)
                            {
                                last = n;
                            }
                        }

                        if (first == int.MaxValue)
                        {
                            continue;
                        }

                        if (first > 0)
                        {
                            first--;
                        }
                        if (last < w.Nodes.Length - 1)
                        {
                            last++;
                        }
                        for (var n = first; n < last + 1; n++)
                        {
                            var nodeId = w.Nodes[n];

                            // get node from the nodes in the tile.
                            if (nodesInTile.TryGetValue(nodeId, out var node))
                            { // node already there.
                                nodesToInclude[nodeId] = node;
                                continue;
                            }

                            // node is not in the tile, get it from the db if it's not included already..
                            if (!nodesToInclude.ContainsKey(nodeId))
                            { // not not yet there, get it.
                                node = this.GetNode(nodeId);
                                nodesToInclude[nodeId] = node;
                            }
                        }
                    }
                }
            }

            var hasData = nodesToInclude.Count > 0;

            if (!hasData)
            {
                yield break;
            }

            // return all the nodes.
            foreach (var node in nodesToInclude.Values)
            {
                yield return(node);
            }

            // returns all the ways that have at least one node.
            using (stream = DatabaseCommon.LoadTile(_path, OsmGeoType.Way, tile, _compressed))
            {
                if (stream != null)
                {
                    var source = new OsmSharp.Streams.BinaryOsmStreamSource(stream);
                    while (source.MoveNext(true, false, true))
                    {
                        var current = source.Current();

                        var w = current as Way;
                        if (w == null)
                        {
                            continue;
                        }

                        // trim nodes.
                        var trimmedNodes = new List <long>();
                        foreach (var n in w.Nodes)
                        {
                            if (!nodesToInclude.TryGetValue(n, out _))
                            {
                                continue;
                            }

                            trimmedNodes.Add(n);
                        }
                        w.Nodes = trimmedNodes.ToArray();

                        if (w.Nodes.Length == 0)
                        {
                            continue;
                        }

                        yield return(w);
                    }
                }
            }

            // return all relations.
            using (stream = DatabaseCommon.LoadTile(_path, OsmGeoType.Relation, tile, _compressed))
            {
                if (stream != null)
                {
                    var source = new OsmSharp.Streams.BinaryOsmStreamSource(stream);
                    while (source.MoveNext(true, true, false))
                    {
                        var current = source.Current();

                        var r = current as Relation;

                        yield return(r);
                    }
                }
            }
        }