Example #1
0
        /// <summary>
        /// Notifies this layer that the current mapview has changed.
        /// </summary>
        /// <param name="map"></param>
        /// <param name="zoomFactor"></param>
        /// <param name="center"></param>
        /// <param name="view"></param>
        /// <param name="extraView"></param>
        protected internal override void ViewChanged(Map map, float zoomFactor, GeoCoordinate center, View2D view, View2D extraView)
        {
            // calculate the current zoom level.
            var zoomLevel = (int)System.Math.Round(map.Projection.ToZoomLevel(zoomFactor), 0);

            if (zoomLevel >= _minZoomLevel && zoomLevel <= _maxZoomLevel)
            {
                // build the bounding box.
                var viewBox = view.OuterBox;

                // build the tile range.
                var range = TileRange.CreateAroundBoundingBox(new GeoCoordinateBox(map.Projection.ToGeoCoordinates(viewBox.Min[0], viewBox.Min[1]),
                                                                                   map.Projection.ToGeoCoordinates(viewBox.Max[0], viewBox.Max[1])), zoomLevel);

                OsmSharp.Logging.Log.TraceEvent("LayerMBTile", OsmSharp.Logging.TraceEventType.Verbose, string.Format("Requesting {0} tiles for view.", range.Count));

                // request all missing tiles.
                lock (_connection)
                { // make sure the connection is accessed synchronously.
                    // TODO: Investigate the SQLite multithreaded behaviour..
                    // TODO: this a very naive way of loading these tiles. Find a way to query SQLite more efficiently
                    // TODO: find a way to have some cached tiles.
                    foreach (var tile in range.EnumerateInCenterFirst())
                    {
                        Image2D value;
                        if (_cache.TryGet(tile, out value))
                        {
                            // Tile is already in cache. We used TryGet, and not TryPeek, to inform the cache
                            // that we intend to use the datum in question.
                            continue;
                        }
                        Tile invertTile = tile.InvertY();

                        var tiles = _connection.Query <tiles>("SELECT * FROM tiles WHERE zoom_level = ? AND tile_column = ? AND tile_row = ?",
                                                              invertTile.Zoom, invertTile.X, invertTile.Y);
                        foreach (var mbTile in tiles)
                        {
                            var box         = tile.ToBox(_projection);
                            var nativeImage = _nativeImageCache.Obtain(mbTile.tile_data);
                            var image2D     = new Image2D(box.Min[0], box.Min[1], box.Max[1], box.Max[0], nativeImage);
                            image2D.Layer = (uint)(_maxZoomLevel - tile.Zoom);

                            lock (_cache)
                            { // add the result to the cache.
                                _cache.Add(tile, image2D);
                            }
                        }
                    }
                }

                OsmSharp.Logging.Log.TraceEvent("LayerMBTile", Logging.TraceEventType.Information, "Cached tiles: {0}", _cache.Count);
            }
        }
Example #2
0
        /// <summary>
        /// Response the specified myResp and tile.
        /// </summary>
        /// <param name="myResp">My resp.</param>
        /// <param name="tile">Tile.</param>
        private void Response(WebResponse myResp, Tile tile)
        {
            if (_cache == null)
            {
                return;
            }
            try
            {
                Stream stream = myResp.GetResponseStream();
                byte[] image  = null;
                if (stream != null)
                {
                    using (stream)
                    {
                        // there is data: read it.
                        var memoryStream = new MemoryStream();
                        stream.CopyTo(memoryStream);

                        image = memoryStream.ToArray();
                        memoryStream.Dispose();

                        var box         = tile.ToBox(_projection);
                        var nativeImage = _nativeImageCache.Obtain(image);
                        var image2D     = new Image2D(box.Min[0], box.Min[1], box.Max[1], box.Max[0], nativeImage);
                        image2D.Layer = (uint)(_maxZoomLevel - tile.Zoom);

                        lock (_cache)
                        { // add the result to the cache.
                            _cache.Add(tile, image2D);
                        }
                    }

                    if (!_suspended)
                    { // only raise the event when not suspended but do no throw away a tile, that would be a waste.
                        this.RaiseLayerChanged();
                    }
                }
                else
                {
                    OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Error, "No response stream!");
                }
            }
            catch (Exception ex)
            { // don't worry about exceptions here.
                OsmSharp.Logging.Log.TraceEvent("LayerTile", Logging.TraceEventType.Error, ex.Message);
            }
        }