예제 #1
0
 /// <summary>
 /// Adds a new tile.
 /// </summary>
 /// <param name="tile"></param>
 /// <returns></returns>
 public void Add(Tile tile)
 {
     if (tile.Zoom < _range.Zoom && _range.Zoom - tile.Zoom < 3)
     { // add this tile to all the subtiles.
         var subTiles = tile.GetSubTiles(_range.Zoom);
         foreach (var subTile in subTiles)
         {
             if (_range.Contains(subTile))
             { // ok, this tile is in this range.
                 this.Add(subTile.Id, tile);
             }
         }
     }
     else if (tile.Zoom > _range.Zoom && tile.Zoom - _range.Zoom < 3)
     { // find the tile that this subtile belongs to.
         foreach (var rangedTile in _range)
         {
             if (rangedTile.Overlaps(tile))
             { // add this this tile here.
                 this.Add(rangedTile.Id, tile);
                 // this tile can only belong in one place.
                 return;
             }
         }
     }
     if (_range.Contains(tile))
     { // this tile is already the correct zoom.
         this.Add(tile.Id, tile);
     }
 }
예제 #2
0
        public void TestTileId()
        {
            var tile0 = new Tile(0, 0, 0);
            Assert.AreEqual(0, tile0.Id);

            var tile1_0_0 = new Tile(0, 0, 1);
            Assert.AreEqual(1, tile1_0_0.Id);

            var tile2_0_0 = new Tile(0, 0, 2);
            Assert.AreEqual(5, tile2_0_0.Id);

            var tile3_0_0 = new Tile(0, 0, 3);
            Assert.AreEqual(5 + 16, tile3_0_0.Id);

            var tile4_0_0 = new Tile(0, 0, 4);
            Assert.AreEqual(5 + 16 + 64, tile4_0_0.Id);

            var tile2_1_1 = new Tile(1, 1, 2);
            Assert.AreEqual(5 + 1 + 4, tile2_1_1.Id);

            var tile2_1_1_fromId = new Tile(5 + 1 + 4);
            Assert.AreEqual(tile2_1_1.Zoom, tile2_1_1_fromId.Zoom);
            Assert.AreEqual(tile2_1_1.X, tile2_1_1_fromId.X);
            Assert.AreEqual(tile2_1_1.Y, tile2_1_1_fromId.Y);

            for (ulong id = 0; id < 1000; id++)
            {
                Tile tile = new Tile(id);
                Assert.AreEqual(id, tile.Id);
            }
        }
예제 #3
0
        public void TestTileCreation()
        {
            // 51.27056&lon=4.78849
            // http://tile.deltamedia.local/tile/16/33639/21862.png
            Tile tile = new Tile(33639, 21862, 16);
            Tile tile2 = Tile.CreateAroundLocation(tile.Box.Center, 16);

            Assert.AreEqual(tile.X, tile2.X);
            Assert.AreEqual(tile.Y, tile2.Y);
            Assert.AreEqual(tile.Zoom, tile2.Zoom);
        }
예제 #4
0
        private static byte[] Download(string url, Tile tile)
        {
            // load the tile.
            url = url.Replace("{z}", tile.Zoom.ToString())
                    .Replace("{x}", tile.X.ToString())
                    .Replace("{y}", tile.Y.ToString());

            var request = (HttpWebRequest)HttpWebRequest.Create(
                              url);
            request.Accept = "text/html, image/png, image/jpeg, image/gif, */*";
            request.UserAgent = "OsmSharp/4.0";

            OsmSharp.Logging.Log.TraceEvent(string.Empty, TraceEventType.Information, "Request tile@" + url);

            return ReadToEnd(request.GetResponse().GetResponseStream());
        }
예제 #5
0
        public void TestTileBox()
        {
            Tile tile = new Tile(33639, 21862, 16);

            for (double longitude = tile.Box.MinLon; longitude < tile.Box.MaxLon;
                longitude = longitude + tile.Box.DeltaLon / 100)
            {
                for (double latitude = tile.Box.MinLat; latitude < tile.Box.MaxLat;
                    latitude = latitude + tile.Box.DeltaLon / 100)
                {
                    Tile tile2 = Tile.CreateAroundLocation(new GeoCoordinate(
                        latitude, longitude), tile.Zoom);

                    Assert.AreEqual(tile.X, tile2.X);
                    Assert.AreEqual(tile.Y, tile2.Y);
                    Assert.AreEqual(tile.Zoom, tile2.Zoom);
                }
            }
        }
예제 #6
0
        public void TestTileSubtiles()
        {
            var tile = new Tile(0, 0, 0);

            var subtiles = tile.SubTiles;
            Assert.AreEqual(0, subtiles.XMin);
            Assert.AreEqual(0, subtiles.YMin);
            Assert.AreEqual(1, subtiles.XMax);
            Assert.AreEqual(1, subtiles.YMax);
            Assert.AreEqual(1, subtiles.Zoom);

            subtiles = tile.GetSubTiles(1);
            Assert.AreEqual(0, subtiles.XMin);
            Assert.AreEqual(0, subtiles.YMin);
            Assert.AreEqual(1, subtiles.XMax);
            Assert.AreEqual(1, subtiles.YMax);
            Assert.AreEqual(1, subtiles.Zoom);

            subtiles = tile.GetSubTiles(2);
            Assert.AreEqual(0, subtiles.XMin);
            Assert.AreEqual(0, subtiles.YMin);
            Assert.AreEqual(3, subtiles.XMax);
            Assert.AreEqual(3, subtiles.YMax);
            Assert.AreEqual(2, subtiles.Zoom);

            tile = new Tile(1, 1, 1);

            subtiles = tile.SubTiles;
            Assert.AreEqual(2, subtiles.XMin);
            Assert.AreEqual(2, subtiles.YMin);
            Assert.AreEqual(3, subtiles.XMax);
            Assert.AreEqual(3, subtiles.YMax);
            Assert.AreEqual(2, subtiles.Zoom);

            subtiles = tile.GetSubTiles(2);
            Assert.AreEqual(2, subtiles.XMin);
            Assert.AreEqual(2, subtiles.YMin);
            Assert.AreEqual(3, subtiles.XMax);
            Assert.AreEqual(3, subtiles.YMax);
            Assert.AreEqual(2, subtiles.Zoom);

            subtiles = tile.GetSubTiles(3);
            Assert.AreEqual(4, subtiles.XMin);
            Assert.AreEqual(4, subtiles.YMin);
            Assert.AreEqual(7, subtiles.XMax);
            Assert.AreEqual(7, subtiles.YMax);
            Assert.AreEqual(3, subtiles.Zoom);
        }
예제 #7
0
        public void TestTileOverlaps()
        {
            var tile = new Tile(1, 1, 1);

            Assert.IsTrue(tile.Overlaps(new Tile(1, 1, 1)));
            Assert.IsTrue(tile.Overlaps(new Tile(3, 3, 2)));
            Assert.IsTrue(tile.Overlaps(new Tile(8, 8, 4)));

            Assert.IsFalse(tile.Overlaps(new Tile(0, 0, 3)));
            Assert.IsFalse(tile.Overlaps(new Tile(0, 0, 4)));
        }
        /// <summary>
        /// Renders a tile for the given zoom, x and y.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="zoom"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        protected virtual Stream Render(int x, int y, int scale, ushort zoom, ImageType type)
        {
            var tile = new Tile(x, y, zoom);
            var projection = _map.Projection;
            var zoomFactor = (float)projection.ToZoomFactor(zoom);
            var center = tile.Box.Center;
            var sizeInPixels = scale * 256;

            // get target/image.
            Bitmap image = null;
            Graphics target = null;
            lock(_targetsPerScale)
            {
                Tuple<Bitmap, Graphics> tuple;
                if(!_targetsPerScale.TryGetValue(scale, out tuple))
                { // not there yet!
                    // build the target to render to.
                    image = new Bitmap(sizeInPixels, sizeInPixels);
                    target = Graphics.FromImage(image);
                    target.SmoothingMode = SmoothingMode.HighQuality;
                    target.PixelOffsetMode = PixelOffsetMode.HighQuality;
                    target.CompositingQuality = CompositingQuality.HighQuality;
                    target.InterpolationMode = InterpolationMode.HighQualityBicubic;
                    tuple = new Tuple<Bitmap, Graphics>(image, target);
                    _targetsPerScale[scale] = tuple;
                }
                target = tuple.Item2;
                image = tuple.Item1;
            }

            var stream = new MemoryStream();
            lock (target)
            {
                target.FillRectangle(Brushes.White, 0, 0, sizeInPixels, sizeInPixels);
                var visibleView = _renderer.Create(256, 256, _map, zoomFactor, center, false, true);
                var renderingView = _renderer.Create(256 * 3, 256 * 3, _map, zoomFactor, center, false, true);
                _map.ViewChanged(zoomFactor, center, renderingView, renderingView);
                _renderer.Render(target, _map, visibleView, renderingView, (float)_map.Projection.ToZoomFactor(zoom));

                switch (type)
                {
                    case ImageType.Png:
                        image.Save(stream, ImageFormat.Png);
                        break;
                    case ImageType.Bmp:
                        image.Save(stream, ImageFormat.Bmp);
                        break;
                    case ImageType.Jpeg:
                        image.Save(stream, ImageFormat.Jpeg);
                        break;
                }
            }
            stream.Seek(0, SeekOrigin.Begin);
            return stream;
        }
예제 #9
0
        /// <summary>
        /// Chooses the best tile(s) for the given tile.
        /// </summary>
        /// <param name="tile">The tile to search tiles for.</param>
        /// <param name="higherFirst">Choose tiles with a higher zoom level first, otherwise choose lower first.</param>
        /// <returns></returns>
        public IEnumerable<Tile> ChooseBest(Tile tile, bool higherFirst)
        {
            var tiles = new List<Tile>(this.Get(tile.Id));
            tiles.Sort(delegate(Tile x, Tile y)
            {
                return TileRangeIndex.TileWeight(tile.Zoom, x.Zoom, higherFirst).CompareTo(
                    TileRangeIndex.TileWeight(tile.Zoom, y.Zoom, higherFirst));
            });

            return tiles;
        }
예제 #10
0
 /// <summary>
 /// Returns true if this tiles cache contains the given tile.
 /// </summary>
 /// <param name="tile">The tile.</param>
 /// <param name="scale">The scale.</param>
 /// <param name="type">The type of image.</param>
 /// <returns></returns>
 public bool Has(Tile tile, int scale, ImageType type)
 {
     var fileInfo = this.GetTileFile(tile, scale, type);
     lock (fileInfo.FullName)
     {
         return fileInfo.Exists && (DateTime.Now - fileInfo.CreationTime).TotalMilliseconds < _maxAge;
     }
 }
예제 #11
0
 /// <summary>
 /// Returns a file info object for a given tile.
 /// </summary>
 /// <param name="tile">The tile.</param>
 /// <param name="scale">The scale.</param>
 /// <param name="type">The type of image.</param>
 /// <returns></returns>
 private FileInfo GetTileFile(Tile tile, int scale, ImageType type)
 {
     string extension = string.Empty;
     switch (type)
     {
         case ImageType.Png:
             extension = ".png";
             break;
         case ImageType.Bmp:
             extension = ".bmp";
             break;
         case ImageType.Jpeg:
             extension = ".jpg";
             break;
     }
     if(scale != 0)
     { // add scale if needed.
         extension = string.Format("{0}x", scale) + extension;
     }
     return new FileInfo(Path.Combine(_cacheDir.FullName, tile.Zoom.ToString(), tile.X.ToInvariantString(), tile.Y.ToInvariantString() + extension));
 }
예제 #12
0
 /// <summary>
 /// Writes a new file to cache.
 /// </summary>
 /// <param name="tile"></param>
 /// <param name="scale"></param>
 /// <param name="type"></param>
 /// <param name="image"></param>
 public void Write(Tile tile, int scale, ImageType type, Stream image)
 {
     var fileInfo = this.GetTileFile(tile, scale, type);
     lock (fileInfo.FullName)
     {
         if (fileInfo.Exists)
         {
             fileInfo.Delete();
         }
         if (!fileInfo.Directory.Exists)
         {
             fileInfo.Directory.Create();
         }
         using (var outputStream = fileInfo.OpenWrite())
         {
             CopyStream(image, outputStream);
         }
     }
 }
예제 #13
0
 /// <summary>
 /// Tries to get a tile and returns true if successfull.
 /// </summary>
 /// <param name="tile"></param>
 /// <param name="scale"></param>
 /// <param name="type"></param>
 /// <param name="image"></param>
 /// <returns></returns>
 public bool TryGet(Tile tile, int scale, ImageType type, out Stream image)
 {
     var fileInfo = this.GetTileFile(tile, scale, type);
     lock (fileInfo.FullName)
     {
         image = null;
         if (fileInfo.Exists && (DateTime.Now - fileInfo.CreationTime).TotalMilliseconds < _maxAge)
         {
             using (var fileStream = fileInfo.OpenRead())
             {
                 image = new MemoryStream();
                 CopyStream(fileStream, image);
                 image.Seek(0, SeekOrigin.Begin);
             }
             return true;
         }
         return false;
     }
 }
예제 #14
0
 /// <summary>
 /// Adds the given tile as the best tile for the given tileId.
 /// </summary>
 /// <param name="tileId"></param>
 /// <param name="tile"></param>
 private void Add(ulong tileId, Tile tile)
 {
     HashSet<Tile> tilesSet;
     if (!_tilesIndex.TryGetValue(tileId, out tilesSet))
     { // create the tiles set.
         tilesSet = new HashSet<Tile>();
         _tilesIndex.Add(tileId, tilesSet);
     }
     tilesSet.Add(tile);
 }
예제 #15
0
파일: Tile.cs 프로젝트: cmberryau/core
        /// <summary>
        /// Returns true if this tile overlaps the given tile.
        /// </summary>
        /// <param name="tile"></param>
        /// <returns></returns>
        public bool Overlaps(Tile tile)
        {
            if (tile == null) { throw new ArgumentNullException("tile"); }

            if (tile.Zoom == this.Zoom)
            { // only overlaps when identical.
                return tile.Equals(this);
            }
            else if (tile.Zoom > this.Zoom)
            { // the zoom is bigger.
                var range = this.GetSubTiles(tile.Zoom);
                return range.Contains(tile);
            }
            return false;
        }
 /// <summary>
 /// Returns a tile for the given zoom, x and y.
 /// </summary>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <param name="zoom"></param>
 /// <param name="scale">Scale parameter, 1 = 256, 2 = 512, ...</param>
 /// <param name="type"></param>
 /// <returns></returns>
 public virtual Stream Get(int x, int y, ushort zoom, int scale, ImageType type = ImageType.Png)
 {
     Stream cachedImage;
     var tile = new Tile(x, y, zoom);
     if (_cache != null &&
         _cache.TryGet(tile, scale, type, out cachedImage))
     { // read from cache.
         OsmSharp.Logging.Log.TraceEvent("RenderingInstance", OsmSharp.Logging.TraceEventType.Information,
             string.Format("Returning cached image @ {0}", tile.ToInvariantString()));
         return cachedImage;
     }
     var renderedImage = this.Render(x, y, scale, zoom, type);
     if(_cache != null)
     { // cache image.
         _cache.Write(tile, scale, type, renderedImage);
         renderedImage.Seek(0, SeekOrigin.Begin);
     }
     OsmSharp.Logging.Log.TraceEvent("RenderingInstance", OsmSharp.Logging.TraceEventType.Information,
         string.Format("Rendered new image @ {0}", tile.ToInvariantString()));
     return renderedImage;
 }
예제 #17
0
 /// <summary>
 /// Returns all data within the given tile
 /// </summary>
 /// <param name="tile">The tile to fetch geometries from</param>
 /// <param name="filter">Filtering options for the results</param>
 /// <returns>An OsmGeoCollection object containing the data within the given tile</returns>
 public virtual OsmGeoCollection GetCollection(Tile tile, Filter filter)
 {
     throw new NotImplementedException();
 }