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);
            }
        }
Exemple #2
0
        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));
            }
        }
Exemple #3
0
        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();
            }
        }
Exemple #6
0
        /// <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);
 }
Exemple #8
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);
                    }
                }
            });
        }
    }