public void Add(string mapId, CanonicalTileId tileId, CacheItem item, bool forceInsert) { mapId = cleanMapId(mapId); #if MAPBOX_DEBUG_CACHE string methodName = _className + "." + new System.Diagnostics.StackFrame().GetMethod().Name; UnityEngine.Debug.LogFormat("{0} {1} {2} forceInsert:{3}", methodName, mapId, tileId, forceInsert); #endif lock (_lock) { if (!_mbTiles.ContainsKey(mapId)) { initializeMbTiles(mapId); } } MbTilesDb currentMbTiles = _mbTiles[mapId]; if (!currentMbTiles.TileExists(tileId) || forceInsert) { _mbTiles[mapId].AddTile(tileId, item, forceInsert); } }
public IAsyncRequest Request( string uri , Action <Response> callback , int timeout = 10 , CanonicalTileId tileId = new CanonicalTileId() , string mapId = null ) { if (string.IsNullOrEmpty(mapId)) { throw new Exception("Cannot cache without a map id"); } CacheItem cachedItem = null; // go through existing caches and check if we already have the requested tile available foreach (var cache in _caches) { cachedItem = cache.Get(mapId, tileId); if (null != cachedItem) { break; } } var finalUrl = uri + "?" + TelemetryFactory.EventQuery; if (!string.IsNullOrEmpty(_accessToken)) { finalUrl += "&access_token=" + _accessToken; } #if MAPBOX_DEBUG_CACHE string methodName = _className + "." + new System.Diagnostics.StackFrame().GetMethod().Name; #endif // if tile was available call callback with it, propagate to all other caches and check if a newer one is available if (null != cachedItem) { #if MAPBOX_DEBUG_CACHE UnityEngine.Debug.LogFormat("{0} {1} {2} {3}", methodName, mapId, tileId, null != cachedItem.Data ? cachedItem.Data.Length.ToString() : "cachedItem.Data is NULL"); #endif // immediately return cached tile callback(Response.FromCache(cachedItem.Data)); // check for updated tiles online if this is enabled in the settings if (_autoRefreshCache) { // check if tile on the web is newer than the one we already have locally IAsyncRequestFactory.CreateRequest( finalUrl, (Response headerOnly) => { // on error getting information from API just return. tile we have locally has already been returned above if (headerOnly.HasError) { return; } // TODO: remove Debug.Log before PR //UnityEngine.Debug.LogFormat( // "{1}{0}cached:{2}{0}header:{3}" // , Environment.NewLine // , finalUrl // , cachedItem.ETag // , headerOnly.Headers["ETag"] //); // data from cache is the same as on the web: // * tile has already been returned above // * make sure all all other caches have it too, but don't force insert via cache.add(false) // additional ETag empty check: for backwards compability with old caches if (!string.IsNullOrEmpty(cachedItem.ETag) && cachedItem.ETag.Equals(headerOnly.Headers["ETag"])) { foreach (var cache in _caches) { cache.Add(mapId, tileId, cachedItem, false); } } else { // TODO: remove Debug.Log before PR UnityEngine.Debug.LogWarningFormat( "updating cached tile {1} mapid:{2}{0}cached etag:{3}{0}remote etag:{4}{0}{5}" , Environment.NewLine , tileId , mapId , cachedItem.ETag , headerOnly.Headers["ETag"] , finalUrl ); // request updated tile and pass callback to return new data to subscribers requestTileAndCache(finalUrl, mapId, tileId, timeout, callback); } } , timeout , HttpRequestType.Head ); } return(new MemoryCacheAsyncRequest(uri)); } else { // requested tile is not in any of the caches yet, get it #if MAPBOX_DEBUG_CACHE UnityEngine.Debug.LogFormat("{0} {1} {2} not cached", methodName, mapId, tileId); #endif return(requestTileAndCache(finalUrl, mapId, tileId, timeout, callback)); } }
public IAsyncRequest Request( string uri , Action <Response> callback , int timeout = 10 , CanonicalTileId tileId = new CanonicalTileId() , string mapId = null ) { if (string.IsNullOrEmpty(mapId)) { throw new Exception("Cannot cache without a map id"); } byte[] data = null; // go through existing caches and check if we already have the requested tile available foreach (var cache in _caches) { data = cache.Get(mapId, tileId); if (null != data) { break; } } // if tile was available propagate to all other caches and return if (null != data) { foreach (var cache in _caches) { cache.Add(mapId, tileId, data); } callback(Response.FromCache(data)); return(new MemoryCacheAsyncRequest(uri)); } else { // requested tile is not in any of the caches yet, get it var uriBuilder = new UriBuilder(uri); if (!string.IsNullOrEmpty(_accessToken)) { string accessTokenQuery = "access_token=" + _accessToken; if (uriBuilder.Query != null && uriBuilder.Query.Length > 1) { uriBuilder.Query = uriBuilder.Query.Substring(1) + "&" + accessTokenQuery; } else { uriBuilder.Query = accessTokenQuery; } } return(IAsyncRequestFactory.CreateRequest( uriBuilder.ToString(), (Response r) => { // if the request was successful add tile to all caches if (!r.HasError && null != r.Data) { foreach (var cache in _caches) { cache.Add(mapId, tileId, r.Data); } } callback(r); }, timeout)); } }
public void SetUp() { _api = Constants.BaseAPI; _tileId = new CanonicalTileId(0, 0, 0); }
public void Add(string tilesetName, CanonicalTileId tileId, CacheItem item, bool forceInsert = false) { #if MAPBOX_DEBUG_CACHE string methodName = _className + "." + new System.Diagnostics.StackFrame().GetMethod().Name; UnityEngine.Debug.LogFormat("{0} {1} {2} forceInsert:{3}", methodName, tileset, tileId, forceInsert); #endif try { // tile exists and we don't want to overwrite -> exit early if ( TileExists(tilesetName, tileId) && !forceInsert ) { return; } int?tilesetId = null; lock (_lock) { tilesetId = getTilesetId(tilesetName); if (!tilesetId.HasValue) { tilesetId = insertTileset(tilesetName); } } if (tilesetId < 0) { Debug.LogErrorFormat("could not get tilesetID for [{0}] tile: {1}", tilesetName, tileId); return; } //_sqlite.BeginTransaction(); int rowsAffected = _sqlite.InsertOrReplace(new tiles { tile_set = tilesetId.Value, zoom_level = tileId.Z, tile_column = tileId.X, tile_row = tileId.Y, tile_data = item.Data, timestamp = (int)UnixTimestampUtils.To(DateTime.Now), etag = item.ETag }); if (1 != rowsAffected) { throw new Exception(string.Format("tile [{0} / {1}] was not inserted, rows affected:{2}", tilesetName, tileId, rowsAffected)); } } catch (Exception ex) { Debug.LogErrorFormat("Error inserting {0} {1} {2} ", tilesetName, tileId, ex); } finally { //_sqlite.Commit(); } // update counter only when new tile gets inserted if (!forceInsert) { _pruneCacheCounter++; } if (0 == _pruneCacheCounter % _pruneCacheDelta) { _pruneCacheCounter = 0; prune(); } }
/// <summary> /// Checkes all neighbours of the given tile and stitches the edges to achieve a smooth mesh surface. /// </summary> /// <param name="tile"></param> /// <param name="mesh"></param> private void FixStitches(CanonicalTileId tileId, MeshData mesh) { var meshVertCount = mesh.Vertices.Count; _stitchTarget = null; _meshData.TryGetValue(tileId.South, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < _sampleCount; i++) { //just snapping the y because vertex pos is relative and we'll have to do tile pos + vertex pos for x&z otherwise mesh.Vertices[i] = new Vector3( mesh.Vertices[i].x, _stitchTargetMeshData.Vertices[meshVertCount - _sampleCount + i].y, mesh.Vertices[i].z); mesh.Normals[i] = new Vector3(_stitchTargetMeshData.Normals[meshVertCount - _sampleCount + i].x, _stitchTargetMeshData.Normals[meshVertCount - _sampleCount + i].y, _stitchTargetMeshData.Normals[meshVertCount - _sampleCount + i].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.North, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < _sampleCount; i++) { mesh.Vertices[meshVertCount - _sampleCount + i] = new Vector3( mesh.Vertices[meshVertCount - _sampleCount + i].x, _stitchTargetMeshData.Vertices[i].y, mesh.Vertices[meshVertCount - _sampleCount + i].z); mesh.Normals[meshVertCount - _sampleCount + i] = new Vector3( _stitchTargetMeshData.Normals[i].x, _stitchTargetMeshData.Normals[i].y, _stitchTargetMeshData.Normals[i].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.West, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < _sampleCount; i++) { mesh.Vertices[i * _sampleCount] = new Vector3( mesh.Vertices[i * _sampleCount].x, _stitchTargetMeshData.Vertices[i * _sampleCount + _sampleCount - 1].y, mesh.Vertices[i * _sampleCount].z); mesh.Normals[i * _sampleCount] = new Vector3( _stitchTargetMeshData.Normals[i * _sampleCount + _sampleCount - 1].x, _stitchTargetMeshData.Normals[i * _sampleCount + _sampleCount - 1].y, _stitchTargetMeshData.Normals[i * _sampleCount + _sampleCount - 1].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.East, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif for (int i = 0; i < _sampleCount; i++) { mesh.Vertices[i * _sampleCount + _sampleCount - 1] = new Vector3( mesh.Vertices[i * _sampleCount + _sampleCount - 1].x, _stitchTargetMeshData.Vertices[i * _sampleCount].y, mesh.Vertices[i * _sampleCount + _sampleCount - 1].z); mesh.Normals[i * _sampleCount + _sampleCount - 1] = new Vector3( _stitchTargetMeshData.Normals[i * _sampleCount].x, _stitchTargetMeshData.Normals[i * _sampleCount].y, _stitchTargetMeshData.Normals[i * _sampleCount].z); } } _stitchTarget = null; _meshData.TryGetValue(tileId.SouthWest, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[0] = new Vector3( mesh.Vertices[0].x, _stitchTargetMeshData.Vertices[meshVertCount - 1].y, mesh.Vertices[0].z); mesh.Normals[0] = new Vector3( _stitchTargetMeshData.Normals[meshVertCount - 1].x, _stitchTargetMeshData.Normals[meshVertCount - 1].y, _stitchTargetMeshData.Normals[meshVertCount - 1].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.SouthEast, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[_sampleCount - 1] = new Vector3( mesh.Vertices[_sampleCount - 1].x, _stitchTargetMeshData.Vertices[meshVertCount - _sampleCount].y, mesh.Vertices[_sampleCount - 1].z); mesh.Normals[_sampleCount - 1] = new Vector3( _stitchTargetMeshData.Normals[meshVertCount - _sampleCount].x, _stitchTargetMeshData.Normals[meshVertCount - _sampleCount].y, _stitchTargetMeshData.Normals[meshVertCount - _sampleCount].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.NorthWest, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[meshVertCount - _sampleCount] = new Vector3( mesh.Vertices[meshVertCount - _sampleCount].x, _stitchTargetMeshData.Vertices[_sampleCount - 1].y, mesh.Vertices[meshVertCount - _sampleCount].z); mesh.Normals[meshVertCount - _sampleCount] = new Vector3( _stitchTargetMeshData.Normals[_sampleCount - 1].x, _stitchTargetMeshData.Normals[_sampleCount - 1].y, _stitchTargetMeshData.Normals[_sampleCount - 1].z); } _stitchTarget = null; _meshData.TryGetValue(tileId.NorthEast, out _stitchTarget); if (_stitchTarget != null) { #if UNITY_5_5_OR_NEWER _stitchTarget.GetVertices(_stitchTargetMeshData.Vertices); _stitchTarget.GetNormals(_stitchTargetMeshData.Normals); #else _stitchTargetMeshData.Vertices.Clear(); _stitchTargetMeshData.Vertices.AddRange(_stitchTarget.vertices); _stitchTargetMeshData.Normals.Clear(); _stitchTargetMeshData.Normals.AddRange(_stitchTarget.normals); #endif mesh.Vertices[meshVertCount - 1] = new Vector3( mesh.Vertices[meshVertCount - 1].x, _stitchTargetMeshData.Vertices[0].y, mesh.Vertices[meshVertCount - 1].z); mesh.Normals[meshVertCount - 1] = new Vector3( _stitchTargetMeshData.Normals[0].x, _stitchTargetMeshData.Normals[0].y, _stitchTargetMeshData.Normals[0].z); } }
public void SetUp() { this.api = Constants.BaseAPI; this.id = new CanonicalTileId(0, 0, 0); }
//tile here should be totally optional and used only not to have keep a dictionary in terrain factory base public override void FetchData(DataFetcherParameters parameters, bool useMapBox = true) { if (CoroutineParent == null) { CoroutineParent = new GameObject(); CoroutineParent.name = "CoroutineParent"; } var imageDataParameters = parameters as ImageDataFetcherParameters; if (imageDataParameters == null) { return; } RasterTile rasterTile; if (imageDataParameters.mapid.StartsWith("mapbox://", StringComparison.Ordinal)) { rasterTile = imageDataParameters.useRetina ? new RetinaRasterTile() : new RasterTile(); } else { rasterTile = imageDataParameters.useRetina ? new ClassicRetinaRasterTile() : new ClassicRasterTile(); } if (imageDataParameters.tile != null) { imageDataParameters.tile.AddTile(rasterTile); } TileInitializer(rasterTile, _fileSource, imageDataParameters.tile, imageDataParameters.mapid); bool useMaplarge = false; //!useMapBox; if (useMapBox) { RasterTile elevationTile = imageDataParameters.useRetina ? new ClassicRetinaRasterTile() : new ClassicRasterTile(); RasterTile porosityTile = imageDataParameters.useRetina ? new ClassicRetinaRasterTile() : new ClassicRasterTile(); RasterTile thicknessTile = imageDataParameters.useRetina ? new ClassicRetinaRasterTile() : new ClassicRasterTile(); RasterTile TOCTile = imageDataParameters.useRetina ? new ClassicRetinaRasterTile() : new ClassicRasterTile(); RasterTile vShaleTile = imageDataParameters.useRetina ? new ClassicRetinaRasterTile() : new ClassicRasterTile(); TileInitializer(elevationTile, _fileSource, imageDataParameters.tile, "victer.0fd7kryp", Layers.Elevation, true); TileInitializer(porosityTile, _fileSource, imageDataParameters.tile, "victer.2w2lzfug", Layers.Porosity, true); TileInitializer(thicknessTile, _fileSource, imageDataParameters.tile, "victer.3totsqo7", Layers.Thickness, true); TileInitializer(TOCTile, _fileSource, imageDataParameters.tile, "victer.3df23l89", Layers.TOC, true); TileInitializer(vShaleTile, _fileSource, imageDataParameters.tile, "victer.cejjf2l8", Layers.VShale, true); } else if (useMaplarge) { CanonicalTileId tID = imageDataParameters.tile.CanonicalTileId; GameObject temp = new GameObject(); temp.name = "Temp_" + tID; temp.transform.SetParent(CoroutineParent.transform); MonoCoroutine mc = temp.AddComponent <MonoCoroutine>(); string url = enlargeURL.Replace("${X}", tID.X.ToString()) .Replace("${Y}", tID.Y.ToString()) .Replace("${Z}", tID.Z.ToString()); mc.GetGZipExternalMapData(url, InvokeCallback); void InvokeCallback(byte[] data) { LayerRawDataRecieved(imageDataParameters.tile, data, Layers.VShale); } } else { CanonicalTileId tID = imageDataParameters.tile.CanonicalTileId; foreach (Layers layer in (Layers[])Enum.GetValues(typeof(Layers))) { GameObject temp = new GameObject(); temp.name = "Temp_" + layer + "_" + tID; temp.transform.SetParent(CoroutineParent.transform); MonoCoroutine mc = temp.AddComponent <MonoCoroutine>(); string hash; switch (layer) { case Layers.Elevation: hash = ElevationHash; break; case Layers.Porosity: hash = PorosityHash; break; case Layers.Thickness: hash = ThicknessHash; break; case Layers.TOC: hash = TOCHash; break; case Layers.VShale: hash = VShaleHash; break; default: return; } string address = @"https://energy.maplarge.com/Api/ProcessDirect?request={""action"":""tile/getmultitile"",""hash"":" + hash + "}&uParams=x:" + tID.X + ";y:" + tID.Y + ";z:" + tID.Z + ";w:1;h:1;layeronly:true;debug:false"; mc.GetExternalMapData(address, InvokeCallback); void InvokeCallback(byte[] data) { LayerRawDataRecieved(imageDataParameters.tile, data, layer); } } } void TileInitializer(RasterTile tile, IFileSource fileSource, UnityTile uTile, string mapId, Layers layer = Layers.Elevation, bool useLayer = false) { tile.Initialize(fileSource, uTile.CanonicalTileId, mapId, () => { if (uTile.CanonicalTileId != tile.Id) { //this means tile object is recycled and reused. Returned data doesn't belong to this tile but probably the previous one. So we're trashing it. return; } if (tile.HasError) { FetchingError(uTile, tile, new TileErrorEventArgs(uTile.CanonicalTileId, tile.GetType(), uTile, tile.Exceptions)); } else { if (useLayer) { LayerDataRecieved(uTile, tile, layer); } else { DataRecieved(uTile, tile); } } }); } }