Beispiel #1
0
 public QuadKey(int x, int y, int zoomLevel, Layer layer)
 {
     this = new QuadKey();
     ZoomLevel = zoomLevel;
     X = x;
     Y = y;
     Layer = layer;
 }
Beispiel #2
0
 public QuadKey(string quadKey)
 {
     int num;
     int num2;
     int num3;
     Layer layer;
     this = new QuadKey();
     QuadKeyToQuadPixel(quadKey, out num, out num2, out num3, out layer);
     ZoomLevel = num3;
     X = num;
     Y = num2;
     Layer = layer;
 }
Beispiel #3
0
 public static Uri GetUri(QuadKey key)
 {
     return GetUri(key.X, key.Y, key.ZoomLevel, key.Layer);
 }
Beispiel #4
0
 /// <summary>
 ///     Determines whether the specified <see cref="QuadKey" /> is within the valid range.
 /// </summary>
 private bool IsValidKey(QuadKey key)
 {
     var x = key.X;
     var y = key.Y;
     if (x < 0 || y < 0)
     {
         return false;
     }
     var tileCount = GetTileCount(key.ZoomLevel);
     return x < tileCount && y < tileCount;
 }
Beispiel #5
0
        /// <summary>
        ///     Calculates a new <see cref="Point" /> represents where the specified <see cref="QuadKey" /> is in the map.
        /// </summary>
        private Point GetViewPortPoint(QuadKey key)
        {
            var x = key.X;
            var y = key.Y;
            var zoomLevel = key.ZoomLevel;
            var tileDimension = AbsoluteTileDimension*_tileScale;
            var tileCount = GetTileCount(zoomLevel);
            var tileNumberToGeoCenter = tileCount/2;
            var modifierX = x >= tileNumberToGeoCenter ? 1 : -1;
            var modifierY = y >= tileNumberToGeoCenter ? 1 : -1;
            var xNumberToGeoCenter = Math.Abs(x - tileNumberToGeoCenter);
            var yNumberToGeoCenter = Math.Abs(y - tileNumberToGeoCenter);
            var geoCenterPoint = Map.LocationToViewportPoint(_centerGeoCoordinate);
            var geoCenterPointX = geoCenterPoint.X;
            var geoCenterPointY = geoCenterPoint.Y;

            var tilePointX = geoCenterPointX + (tileDimension*xNumberToGeoCenter*modifierX);
            var tilePointY = geoCenterPointY + (tileDimension*yNumberToGeoCenter*modifierY);
            var tilePoint = new Point(tilePointX, tilePointY);
            return tilePoint;
        }
Beispiel #6
0
        /// <summary>
        ///     Calculates a new <see cref="QuadKey" /> based on the old key and the differences between the X count and Y count.
        /// </summary>
        private QuadKey GetNewKey(QuadKey oldKey, int diffX, int diffY)
        {
            var x = oldKey.X;
            var y = oldKey.Y;
            var zoomLevel = oldKey.ZoomLevel;
            var tileCount = GetTileCount(zoomLevel);

            var newX = x + diffX;
            if (newX < 0)
            {
                newX = tileCount + x + diffX;
            }
            else if (newX >= tileCount)
            {
                newX = diffX - (tileCount - x);
            }

            var newY = y + diffY;

            return new QuadKey(newX, newY, zoomLevel, oldKey.Layer);
        }
Beispiel #7
0
        /// <summary>
        ///     Gets the image where the specified <see cref="QuadKey" /> is representing.
        /// </summary>
        private void GetImage(QuadKey key, Action<Stream> callback)
        {
            var cachedKeys = GetCachedKeys(key.ZoomLevel);

            // Load the image from storage if it is already cached.
            if (cachedKeys.Contains(key))
            {
                foreach (var cache in _tileImageCache.Where(cache => cache.Key == key))
                {
                    callback(cache.Value);
                    return;
                }
                var file = string.Concat(OfflineTileImagePrefix, key.Key);
                Stream stream = null;
                try
                {
                    stream = _fileStore.OpenFile(file, FileMode.Open);
                    _tileImageCache.Enqueue(new KeyValuePair<QuadKey, Stream>(key, stream));
                }
                catch {}
                finally
                {
                    callback(stream);
                }
                return;
            }

            // Download and store the image.
            try
            {
                var uri = TileSource.GetUri(key);
                var request = WebRequest.Create(uri);
                request.BeginGetResponse(result =>
                {
                    Stream stream = null;
                    try
                    {
                        var file = OfflineTileImagePrefix + key.Key;
                        using (var response = request.EndGetResponse(result))
                        {
                            stream = response.GetResponseStream();

                            using (var fileStream = _fileStore.CreateFile(file))
                            {
                                var bytes = new byte[stream.Length];
                                stream.Read(bytes, 0, bytes.Length);
                                fileStream.Write(bytes, 0, bytes.Length);
                                cachedKeys.Add(key);
                                _tileImageCache.Enqueue(new KeyValuePair<QuadKey, Stream>(key, stream));
                            }
                        }
                    }
                    catch {}
                    finally
                    {
                        UIThread.InvokeAsync(() => callback(stream));
                    }
                }, null);
            }
            catch
            {
                callback(null);
            }
        }
Beispiel #8
0
        /// <summary>
        ///     Updates the geo-location and optionally the image of the specified tile based on the given key.
        /// </summary>
        private void UpdateTile(Pushpin tile, QuadKey key, bool updateImage = true)
        {
            tile.Tag = key;
            var brush = ((ImageBrush) tile.Background);
            brush.ImageSource = null;
            if (!IsValidKey(key))
            {
                return;
            }
            var newPoint = GetViewPortPoint(key);
            var newLocation = Map.ViewportPointToLocation(newPoint);
            tile.Location = newLocation;
            if (!updateImage)
            {
                return;
            }
            GetImage(key, stream =>
            {
                // Only continue updating the image source if the key attached to the tile is still the same key.
                if ((QuadKey) tile.Tag != key)
                {
                    return;
                }

                if (stream == null)
                {
                    return;
                }
                var source = (BitmapImage) brush.ImageSource;
                if (source == null)
                {
                    brush.ImageSource = source = new BitmapImage();
                }
                source.SetSource(stream);
            });
        }
Beispiel #9
0
        /// <summary>
        ///     Rearranges all offline tiles and updates their image according to the current location, zoom level and layer.
        /// </summary>
        private void RefreshOfflineTiles(Pushpin[,] matrix, Layer layer)
        {
            if (_isZooming || !ValidateOfflineZoomLevel())
            {
                return;
            }

            _zoomFloor = (int) Map.ZoomLevel;
            UpdateTileScale();

            // Update all tiles if the zoom level has reached a new floor.
            var centerKey = GetQuadKey(Map.Center, _zoomFloor, layer);

            // Calculate X index and Y index in the matrix of the center tile.
            var centerX = _tileMatrixLengthX/2;
            var centerY = _tileMatrixLengthY/2;

            // Update location and image of tile pushpins.
            for (var x = 0; x < _tileMatrixLengthX; x++)
            {
                for (var y = 0; y < _tileMatrixLengthY; y++)
                {
                    // Create the tile pushpin.
                    var tile = matrix[x, y];

                    // Calculate the differences between this tile's X/Y index and the center tile's X/Y index.
                    var diffX = x - centerX;
                    var diffY = y - centerY;

                    // Calculate the quad key for this current tile.
                    var key = new QuadKey(centerKey.X + diffX, centerKey.Y + diffY, _zoomFloor, layer);

                    // Update this tile with the calculated quad key.
                    UpdateTile(tile, key);
                }
            }
        }