/// <summary> /// Gets the a routeable tile for the given tile. /// </summary> /// <param name="tile">The tile.</param> /// <returns>An enumerable with all data that should be in a routeable tile.</returns> public IEnumerable <OsmGeo> GetRouteableTile(Tile tile) { if (tile.Zoom != _zoom) { return(null); } var stream = DatabaseCommon.LoadTile(_path, OsmGeoType.Node, tile, _compressed); if (stream == null) { return(null); } return(this.GetRouteableTile(tile, stream)); }
/// <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); }
/// <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); } } } }