//----------------------------------------------------------------------- // // Copyright (c) 2016 Mapbox. All rights reserved. // //----------------------------------------------------------------------- namespace Mapbox.Map { using System.Collections.ObjectModel; using Mapbox.Utils; using Mapbox.VectorTile; using Mapbox.VectorTile.ExtensionMethods; using System; /// /// A decoded vector tile, as specified by the /// /// Mapbox Vector Tile specification. /// See available layers and features here. /// The tile might be incomplete if the network request and parsing are still pending. /// /// /// Making a VectorTile request: /// /// var parameters = new Tile.Parameters(); /// parameters.Fs = MapboxAccess.Instance; /// parameters.Id = new CanonicalTileId(_zoom, _tileCoorindateX, _tileCoordinateY); /// parameters.TilesetId = "mapbox.mapbox-streets-v7"; /// var vectorTile = new VectorTile(); /// /// // Make the request. /// vectorTile.Initialize(parameters, (Action)(() => /// { /// if (!string.IsNullOrEmpty(vectorTile.Error)) /// { /// // Handle the error. /// } /// /// // Consume the . /// })); /// /// public sealed class VectorTile : Tile, IDisposable { // FIXME: Namespace here is very confusing and conflicts (sematically) // with his class. Something has to be renamed here. private Mapbox.VectorTile.VectorTile data; bool _isStyleOptimized = false; string _optimizedStyleId; string _modifiedDate; private bool isDisposed = false; /// Gets the vector decoded using Mapbox.VectorTile library. /// The GeoJson data. public Mapbox.VectorTile.VectorTile Data { get { return this.data; } } public VectorTile() { _isStyleOptimized = false; } public VectorTile(string styleId, string modifiedDate) { if (string.IsNullOrEmpty(styleId) || string.IsNullOrEmpty(modifiedDate)) { UnityEngine.Debug.LogWarning("Style Id or Modified Time cannot be empty for style optimized tilesets. Switching to regular tilesets!"); _isStyleOptimized = false; } else { _isStyleOptimized = true; _optimizedStyleId = styleId; _modifiedDate = modifiedDate; } } //TODO: uncomment if 'VectorTile' class changes from 'sealed' //protected override void Dispose(bool disposeManagedResources) //~VectorTile() //{ // Dispose(false); //} public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } //TODO: change signature if 'VectorTile' class changes from 'sealed' //protected override void Dispose(bool disposeManagedResources) public void Dispose(bool disposeManagedResources) { if (!isDisposed) { if (disposeManagedResources) { //TODO implement IDisposable with Mapbox.VectorTile.VectorTile if (null != data) { data = null; } } } } /// /// Gets the vector in a GeoJson format. /// /// This method should be avoided as it fully decodes the whole tile and might pose performance and memory bottle necks. /// /// /// The GeoJson data. /// /// Inspect the GeoJson. /// /// var json = VectorTile.GeoJson; /// Console.Write("GeoJson: " + json); /// /// public string GeoJson { get { return this.data.ToGeoJson((ulong)Id.Z, (ulong)Id.X, (ulong)Id.Y, 0); } } /// /// Gets all availble layer names. /// See available layers and features here. /// /// Collection of availble layers. /// /// Inspect the LayerNames. /// /// var layerNames = vectorTile.LayerNames(); /// foreach (var layer in layerNames) /// { /// Console.Write("Layer: " + layer); /// } /// /// public ReadOnlyCollection LayerNames() { return this.data.LayerNames(); } // FIXME: Why don't these work? /// /// Decodes the requested layer. /// /// Name of the layer to decode. /// Decoded VectorTileLayer or 'null' if an invalid layer name was specified. /// /// Inspect a layer of the vector tile. /// /// var countryLabelLayer = vectorTile.GetLayer("country_label"); /// var count = countryLabelLayer.Keys.Count; /// for (int i = 0; i < count; i++) /// { /// Console.Write(string.Format("{0}:{1}", countryLabelLayer.Keys[i], countryLabelLayer.Values[i])); /// } /// /// public VectorTileLayer GetLayer(string layerName) { return this.data.GetLayer(layerName); } internal override TileResource MakeTileResource(string tilesetId) { return (_isStyleOptimized) ? TileResource.MakeStyleOptimizedVector(Id, tilesetId, _optimizedStyleId, _modifiedDate) : TileResource.MakeVector(Id, tilesetId); } internal override bool ParseTileData(byte[] data) { try { var decompressed = Compression.Decompress(data); this.data = new Mapbox.VectorTile.VectorTile(decompressed); return true; } catch (Exception ex) { AddException(ex); return false; } } } }