//-----------------------------------------------------------------------
//
// 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;
}
}
}
}