20240422
This commit is contained in:
commit
e0afef912e
1285 files changed
+83219
No files matched your search
@@ -0,0 +1,277 @@
|
||||
//-----------------------------------------------------------------------
|
||||
// <copyright file="Tile.cs" company="Mapbox">
|
||||
// Copyright (c) 2016 Mapbox. All rights reserved.
|
||||
// </copyright>
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace Mapbox.Map
|
||||
{
|
||||
using System;
|
||||
using Mapbox.Platform;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Mapbox.Unity.Utilities;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A Map tile, a square with vector or raster data representing a geographic
|
||||
/// bounding box. More info <see href="https://en.wikipedia.org/wiki/Tiled_web_map">
|
||||
/// here </see>.
|
||||
/// </summary>
|
||||
public abstract class Tile : IAsyncRequest
|
||||
{
|
||||
|
||||
|
||||
private CanonicalTileId _id;
|
||||
private List<Exception> _exceptions;
|
||||
private State _state = State.New;
|
||||
private IAsyncRequest _request;
|
||||
private Action _callback;
|
||||
|
||||
/// <summary> Tile state. </summary>
|
||||
public enum State
|
||||
{
|
||||
/// <summary> New tile, not yet initialized. </summary>
|
||||
New,
|
||||
/// <summary> Loading data. </summary>
|
||||
Loading,
|
||||
/// <summary> Data loaded and parsed. </summary>
|
||||
Loaded,
|
||||
/// <summary> Data loading cancelled. </summary>
|
||||
Canceled,
|
||||
/// <summary> Data has been loaded before and got updated. </summary>
|
||||
Updated
|
||||
}
|
||||
|
||||
/// <summary> Gets the <see cref="T:Mapbox.Map.CanonicalTileId"/> identifier. </summary>
|
||||
/// <value> The canonical tile identifier. </value>
|
||||
public CanonicalTileId Id
|
||||
{
|
||||
get { return _id; }
|
||||
set { _id = value; }
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Flag to indicate if the request was successful</summary>
|
||||
public bool HasError
|
||||
{
|
||||
get
|
||||
{
|
||||
return _exceptions == null ? false : _exceptions.Count > 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Exceptions that might have occured during creation of the tile. </summary>
|
||||
public ReadOnlyCollection<Exception> Exceptions
|
||||
{
|
||||
get { return null == _exceptions ? null : _exceptions.AsReadOnly(); }
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Messages of exceptions otherwise empty string. </summary>
|
||||
public string ExceptionsAsString
|
||||
{
|
||||
get
|
||||
{
|
||||
if (null == _exceptions || _exceptions.Count == 0) { return string.Empty; }
|
||||
return string.Join(Environment.NewLine, _exceptions.Select(e => e.Message).ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets the error message.
|
||||
/// </summary>
|
||||
/// <param name="errorMessage"></param>
|
||||
internal void AddException(Exception ex)
|
||||
{
|
||||
if (null == _exceptions) { _exceptions = new List<Exception>(); }
|
||||
_exceptions.Add(ex);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current state. When fully loaded, you must
|
||||
/// check if the data actually arrived and if the tile
|
||||
/// is accusing any error.
|
||||
/// </summary>
|
||||
/// <value> The tile state. </value>
|
||||
public State CurrentState
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public HttpRequestType RequestType { get { return _request.RequestType; } }
|
||||
|
||||
|
||||
public bool IsCompleted
|
||||
{
|
||||
get
|
||||
{
|
||||
return _state == State.Loaded;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the <see cref="T:Mapbox.Map.Tile"/> object. It will
|
||||
/// start a network request and fire the callback when completed.
|
||||
/// </summary>
|
||||
/// <param name="param"> Initialization parameters. </param>
|
||||
/// <param name="callback"> The completion callback. </param>
|
||||
public void Initialize(Parameters param, Action callback)
|
||||
{
|
||||
Cancel();
|
||||
|
||||
_state = State.Loading;
|
||||
_id = param.Id;
|
||||
_callback = callback;
|
||||
_request = param.Fs.Request(MakeTileResource(param.TilesetId).GetUrl(), HandleTileResponse, tileId: _id, tilesetId: param.TilesetId);
|
||||
}
|
||||
|
||||
internal void Initialize(IFileSource fileSource, CanonicalTileId canonicalTileId, string tilesetId, Action p)
|
||||
{
|
||||
Cancel();
|
||||
|
||||
_state = State.Loading;
|
||||
_id = canonicalTileId;
|
||||
_callback = p;
|
||||
_request = fileSource.Request(MakeTileResource(tilesetId).GetUrl(), HandleTileResponse, tileId: _id, tilesetId: tilesetId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="T:System.String"/> that represents the current
|
||||
/// <see cref="T:Mapbox.Map.Tile"/>.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.String"/> that represents the current
|
||||
/// <see cref="T:Mapbox.Map.Tile"/>.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return Id.ToString();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Cancels the request for the <see cref="T:Mapbox.Map.Tile"/> object.
|
||||
/// It will stop a network request and set the tile's state to Canceled.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// // Do not request tiles that we are already requesting
|
||||
/// // but at the same time exclude the ones we don't need
|
||||
/// // anymore, cancelling the network request.
|
||||
/// tiles.RemoveWhere((T tile) =>
|
||||
/// {
|
||||
/// if (cover.Remove(tile.Id))
|
||||
/// {
|
||||
/// return false;
|
||||
/// }
|
||||
/// else
|
||||
/// {
|
||||
/// tile.Cancel();
|
||||
/// NotifyNext(tile);
|
||||
/// return true;
|
||||
/// }
|
||||
/// });
|
||||
/// </code>
|
||||
/// </example>
|
||||
public void Cancel()
|
||||
{
|
||||
if (_request != null)
|
||||
{
|
||||
_request.Cancel();
|
||||
_request = null;
|
||||
}
|
||||
|
||||
_state = State.Canceled;
|
||||
}
|
||||
|
||||
|
||||
// Get the tile resource (raster/vector/etc).
|
||||
internal abstract TileResource MakeTileResource(string tilesetId);
|
||||
|
||||
|
||||
// Decode the tile.
|
||||
internal abstract bool ParseTileData(byte[] data);
|
||||
|
||||
|
||||
// TODO: Currently the tile decoding is done on the main thread. We must implement
|
||||
// a Worker class to abstract this, so on platforms that support threads (like Unity
|
||||
// on the desktop, Android, etc) we can use worker threads and when building for
|
||||
// the browser, we keep it single-threaded.
|
||||
List<string> ids = new List<string>();
|
||||
private void HandleTileResponse(Response response)
|
||||
{
|
||||
|
||||
if (response.HasError)
|
||||
{
|
||||
if (!ids.Contains(_id.ToString()))
|
||||
ids.Add(_id.ToString());
|
||||
else
|
||||
return;
|
||||
|
||||
response.Exceptions.ToList().ForEach(e => AddException(e));
|
||||
}
|
||||
else
|
||||
{
|
||||
// only try to parse if request was successful
|
||||
|
||||
// current implementation doesn't need to check if parsing is successful:
|
||||
// * Mapbox.Map.VectorTile.ParseTileData() already adds any exception to the list
|
||||
// * Mapbox.Map.RasterTile.ParseTileData() doesn't do any parsing
|
||||
ParseTileData(response.Data);
|
||||
}
|
||||
|
||||
// Cancelled is not the same as loaded!
|
||||
if (_state != State.Canceled)
|
||||
{
|
||||
if (response.IsUpdate)
|
||||
{
|
||||
_state = State.Updated;
|
||||
}
|
||||
else
|
||||
{
|
||||
_state = State.Loaded;
|
||||
}
|
||||
}
|
||||
_callback();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parameters for initializing a Tile object.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code>
|
||||
/// var parameters = new Tile.Parameters();
|
||||
/// parameters.Fs = MapboxAccess.Instance;
|
||||
/// parameters.Id = new CanonicalTileId(_zoom, _tileCoorindateX, _tileCoordinateY);
|
||||
/// parameters.TilesetId = "mapbox.mapbox-streets-v7";
|
||||
/// </code>
|
||||
/// </example>
|
||||
public struct Parameters
|
||||
{
|
||||
/// <summary> The tile id. </summary>
|
||||
public CanonicalTileId Id;
|
||||
|
||||
/// <summary>
|
||||
/// The tileset ID, usually in the format "user.mapid". Exceptionally,
|
||||
/// <see cref="T:Mapbox.Map.RasterTile"/> will take the full style URL
|
||||
/// from where the tile is composited from, like mapbox://styles/mapbox/streets-v9.
|
||||
/// </summary>
|
||||
public string TilesetId;
|
||||
|
||||
/// <summary> The data source abstraction. </summary>
|
||||
public IFileSource Fs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user