void AddTile(WayTile tile) { if (_tiles.Any(t => t.Id == tile.Id)) { return; } _tiles.Add(tile); var(lon0, lat0, lon1, lat1) = TileMath.GetTileBounds(tile.Id, Zoom); foreach (var node in tile.Nodes) { node.TileId = tile.Id; node.VisitCount = 0; if (_nodeLut.TryGetValue(node.Id, out WayTileNode existingNode)) { // It is possible that both nodes are inside their own tile if they are exactly on the border. Which one wins doesn't matter. var insideNode = existingNode.Inside.HasValue ? existingNode : node; var outsideNode = existingNode.Inside.HasValue ? node : existingNode; // Node id already exists. This is a link between two tiles. The existing node should be outside its tile // and the new one should be inside. Otherwise something is wrong. // 1) Let the node inside its own tile inherit the connections of the other var tileLinkConnections = outsideNode.Conn.Where(id => insideNode.Conn.Any(idOther => idOther == id)).ToList(); insideNode.Conn.AddRange(tileLinkConnections); // 2) Overwrite the old one with the new one in the LUT. _nodeLut[node.Id] = insideNode; } else { _nodeLut[node.Id] = node; } } var outside = _nodeLut.Values.Where(v => !v.Inside.HasValue).ToList(); int loaded = 0; int notLoaded = 0; foreach (var n in outside) { if (!n.Inside.HasValue) { long tileId = TileMath.GetTileId(n.Point.Lon, n.Point.Lat, Zoom); if (_tiles.Any(t => t.Id == tileId)) { loaded++; } else { notLoaded++; } } // all outside nodes should be in tiles NOT loaded. } }
async Task LoadTileAtPoint(GeoCoord point) { long tileId = TileMath.GetTileId(point.Lon, point.Lat, Zoom); await LoadTile(tileId); }