protected MapTile AddTile(long id) { var tileId = new MapTileId(id); MapTile tile; if (unusedTiles.Count > 0) { // Grab tile from unused list tile = unusedTiles.Pop(); tile.Init(tileId); } else { // Debug.LogWarning("Creating new tile. Total tiles: " + (tiles.Count + 1)); // Create new tile tile = MapTile.Create(tileId, transform); } tile.name = tileId.ToString(); // Add it to the list tilesMap.Add(id, tile); tilesList.Add(tile); return(tile); }
private bool IsCoveredBySmallerTile(int zoomLevel, int tileX, int tileY, int tileZ) { var id = MapTileId.ToId(tileX, tileY, tileZ, layerId); return(tilesMap.ContainsKey(id) || (zoomLevel == tileZ && !requestedTiles.Contains(id)) || (zoomLevel > tileZ && IsCoveredBySmallerTiles(zoomLevel, tileX, tileY, tileZ))); }
// Check if a tile is covered by other tiles with a smaller zoom private bool IsCoveredByLargerTile(int zoomLevel, int tileX, int tileY, int tileZ) { tileZ--; tileX /= 2; tileY /= 2; return(tilesMap.ContainsKey(MapTileId.ToId(tileX, tileY, zoomLevel, layerId)) || (zoomLevel < tileZ && IsCoveredByLargerTile(zoomLevel, tileX, tileY, tileZ))); }
private void CleanUpOldTiles(int mapZoomLevel, MapTileBounds mapBounds) { // Remove tiles that are 3 levels higher than current zoom level int mapZoomLevelThreshold = mapZoomLevel - MaxZoomLevelDifference; MapTileId anchorId = map.Anchor; float anchorScale = map.TilesToUnits; Vector2 anchorOffset = map.AnchorOffsetInUnits; for (int i = oldTilesList.Count - 1; i >= 0; i--) { var tileId = oldTilesList[i].Id; if (tilesMap.ContainsKey(MapTileId.ToId(tileId.X, tileId.Y, tileId.Z, layerId))) { RemoveTile(oldTilesMap, oldTilesList, i); } else { // Calculate the tile bounds in the map's zoom level float toMapZoom = Mathf.Pow(2, mapZoomLevel - tileId.Z); int tileWest = (int)(tileId.X * toMapZoom); int tileEast = (int)((tileId.X + 1) * toMapZoom); int tileNorth = (int)(tileId.Y * toMapZoom); int tileSouth = (int)((tileId.Y + 1) * toMapZoom); bool inFrustum = tileEast > mapBounds.West && tileWest <mapBounds.East && tileSouth> mapBounds.North && tileNorth < mapBounds.South; if (!inFrustum || tileId.Z < mapZoomLevelThreshold) { RemoveTile(oldTilesMap, oldTilesList, i); } else if (tileId.Z != mapZoomLevel) { if ((tileId.Z > mapZoomLevel && IsCoveredByLargerTile(mapZoomLevel, tileId.X, tileId.Y, tileId.Z)) || (tileId.Z < mapZoomLevel && IsCoveredBySmallerTiles(mapZoomLevel, tileId.X, tileId.Y, tileId.Z))) { RemoveTile(oldTilesMap, oldTilesList, i); } else { MapTile tile = oldTilesList[i]; tile.UpdateTile(anchorId, anchorScale, anchorOffset, Mathf.Pow(2, map.zoom - tile.ZoomLevel), 0.0001f); } } else { MapTile tile = oldTilesList[i]; tile.UpdateTile(anchorId, anchorScale, anchorOffset, Mathf.Pow(2, map.zoom - tile.ZoomLevel), 0.0001f); } } } }
public void UpdateTile(MapTileId anchor, float anchorScale, Vector2 offset, float tileScale, float zOffset = 0f) { int zoomLevelDiff = anchor.Z - tileId.Z; float toMapZoomLevel = Mathf.Pow(2, Mathf.Ceil(zoomLevelDiff)); transform.localPosition = new Vector3( (tileId.X * toMapZoomLevel - anchor.X) * anchorScale + offset.x, (tileId.Y * toMapZoomLevel - anchor.Y) * -anchorScale + offset.y, zoomLevelDiff * 0.00001f + zOffset // A little difference in height to allow higher zoom levels to be on top ); transform.localScale = new Vector3(tileScale, tileScale, 1); }
protected void RequestTile(int x, int y, int zoomLevel, int layerId) { long tileId = MapTileId.CreateWrappedId(x, y, zoomLevel, layerId); // Do not request tiles that already exist (or are being requested) if (!tilesMap.ContainsKey(tileId) && !requestedTiles.Contains(tileId)) { requestedTiles.Add(tileId); // Request the texture for it requestHandler.Add(CreateTileRequest(tileId, RequestFinished)); } }
protected void UpdateTiles() { MapTileId anchorId = map.Anchor; float anchorScale = map.TilesToUnits; Vector2 anchorOffset = map.AnchorOffsetInUnits; for (int i = tilesList.Count - 1; i >= 0; i--) { MapTile tile = tilesList[i]; float tileScale = Mathf.Pow(2, map.zoom - tile.ZoomLevel); tile.UpdateTile(anchorId, anchorScale, anchorOffset, tileScale); } }
private void UpdateAnchor() { // Get the tile Id in the center of the screen (at lon/lat) anchor = GeoCalculator.AbsoluteCoordinateToTile(longitude, latitude, zoomLevel); // Get the upper left corner (in meters) of the anchor tile var anchorMeters = GeoCalculator.AbsoluteTileToMeters(anchor.X, anchor.Y, anchor.Z); // Calculate the offset (in units) between the requested lon/lat and the anchor anchorOffsetInUnits = GeoCalculator.RelativeMetersToPixels(anchorMeters - currentMeters, zoomLevel).ToVector2() * pixelsToUnits; // Also need to update the map bounds UpdateMapBounds(); }
// // Unity Methods // // // Public Methods // public static MapTile Create(MapTileId tileId, Transform parent) { // Create empty GameObject GameObject tileObj = new GameObject(); tileObj.transform.SetParent(parent, false); // Add components MeshFilter meshFilter = tileObj.AddComponent <MeshFilter>(); MeshRenderer meshRenderer = tileObj.AddComponent <MeshRenderer>(); MapTile tile = tileObj.AddComponent <MapTile>(); // Create mesh Mesh mesh = meshFilter.mesh; mesh.vertices = new Vector3[] { new Vector3(0f, 0f, 0.0f), new Vector3(1f, 0f, 0.0f), new Vector3(1f, -1f, 0.0f), new Vector3(0f, -1f, 0.0f), }; mesh.triangles = new int[] { 0, 1, 2, 0, 2, 3 }; mesh.normals = new Vector3[] { Vector3.up, Vector3.up, Vector3.up, Vector3.up }; mesh.uv = new Vector2[] { new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(1f, 0f), new Vector2(0f, 0f) }; // Setup mesh renderer meshRenderer.material = new Material(Shader.Find("Unlit/Texture")); meshRenderer.enabled = false; // Store a reference to the mesh renderer tile.meshRenderer = meshRenderer; tile.Init(tileId); return(tile); }
private void CancelRequests(int mapZoom, MapTileBounds bounds) { var node = requestHandler.PendingRequests.First; var tId = new MapTileId(); while (node != null) { var next = node.Next; var request = node.Value; tId.Set(request.id); if (tId.Z != mapZoom || tId.X < bounds.West || tId.X >= bounds.East || tId.Y < bounds.North || tId.Y >= bounds.South) { request.Cancel(); requestHandler.RemovePending(node); requestedTiles.Remove(request.id); } node = next; } }
// Convert OSM tile coordinates to meters (upper left corner of the tile). public static Distance AbsoluteTileToMeters(MapTileId tileId) { return(AbsoluteTileToMeters(tileId.X, tileId.Y, tileId.Z)); }
// Convert OSM tile coordinates to WGS84 coordinates (lon/lat) (upper left corner of the tile). public static Coordinate AbsoluteTileToCoordinate(MapTileId tileId) { return(AbsoluteTileToCoordinate(tileId.X, tileId.Y, tileId.Z)); }
public void Init(MapTileId tileId) { this.tileId = tileId; }
private void ShowResultTile(MapTileId tileId) { EditorGUILayout.LabelField("Tile ID", tileId.ToString()); }