/// <summary> /// Get tile envelope in WGS-84 coordinates /// </summary> /// <param name="x">x index</param> /// <param name="y">y index</param> /// <param name="zoom">zoom</param> /// <returns>Envelope in WGS-84</returns> private static Envelope GetTileEnvelope(int x, int y, int zoom) { var currTopLeftPixXY = TileCalculator.TileXYToTopLeftPixelXY(x, y); var currTopLeftCoord = TileCalculator.PixelXYToLatLong((int)currTopLeftPixXY.X, (int)currTopLeftPixXY.Y, zoom); var currBtmRightPixXY = TileCalculator.TileXYToBottomRightPixelXY(x, y); var currBtmRightCoord = TileCalculator.PixelXYToLatLong((int)currBtmRightPixXY.X, (int)currBtmRightPixXY.Y, zoom); return(new Envelope(currTopLeftCoord, currBtmRightCoord)); }
/// <summary> /// /// </summary> /// <param name="coord"></param> /// <param name="zoom"></param> /// <returns></returns> public Tile GetTileFromLatLong(Coordinate coord, int zoom) { var tileXY = TileCalculator.LatLongToTileXY(coord, zoom); //Figure out the extent of the tile so that it can be made into MWImageData var tileTopLeftXY = TileCalculator.TileXYToTopLeftPixelXY((int)tileXY.X, (int)tileXY.Y); var tileBottomRightXY = TileCalculator.TileXYToTopLeftPixelXY((int)tileXY.X + 1, (int)tileXY.Y + 1); var tileTopLeft = TileCalculator.PixelXYToLatLong((int)tileTopLeftXY.X, (int)tileTopLeftXY.Y, zoom); var tileBottomRight = TileCalculator.PixelXYToLatLong((int)tileBottomRightXY.X, (int)tileBottomRightXY.Y, zoom); var envelope = new Envelope(tileTopLeft, tileBottomRight); return(GetTile(tileXY, envelope, zoom)); }
public Tiles GetTiles(Envelope envelope, Rectangle bounds, BackgroundWorker bw) { var mapTopLeft = envelope.TopLeft(); var mapBottomRight = envelope.BottomRight(); //Clip the coordinates so they are in the range of the web mercator projection mapTopLeft.Y = TileCalculator.Clip(mapTopLeft.Y, TileCalculator.MinLatitude, TileCalculator.MaxLatitude); mapTopLeft.X = TileCalculator.Clip(mapTopLeft.X, TileCalculator.MinLongitude, TileCalculator.MaxLongitude); mapBottomRight.Y = TileCalculator.Clip(mapBottomRight.Y, TileCalculator.MinLatitude, TileCalculator.MaxLatitude); mapBottomRight.X = TileCalculator.Clip(mapBottomRight.X, TileCalculator.MinLongitude, TileCalculator.MaxLongitude); var zoom = TileCalculator.DetermineZoomLevel(envelope, bounds); var topLeftTileXY = TileCalculator.LatLongToTileXY(mapTopLeft, zoom); var btmRightTileXY = TileCalculator.LatLongToTileXY(mapBottomRight, zoom); var tileMatrix = new Bitmap[(int)(btmRightTileXY.X - topLeftTileXY.X) + 1, (int)(btmRightTileXY.Y - topLeftTileXY.Y) + 1]; var po = new ParallelOptions { MaxDegreeOfParallelism = -1 }; Parallel.For((int)topLeftTileXY.Y, (int)btmRightTileXY.Y + 1, po, (y, loopState) => Parallel.For((int)topLeftTileXY.X, (int)btmRightTileXY.X + 1, po, (x, loopState2) => { if (bw.CancellationPending) { loopState.Stop(); loopState2.Stop(); return; } var currEnv = GetTileEnvelope(x, y, zoom); tileMatrix[x - (int)topLeftTileXY.X, y - (int)topLeftTileXY.Y] = GetTile(x, y, currEnv, zoom); } )); return(new Tiles(tileMatrix, GetTileEnvelope((int)topLeftTileXY.X, (int)topLeftTileXY.Y, zoom), // top left tile = tileMatrix[0,0] GetTileEnvelope((int)btmRightTileXY.X, (int)btmRightTileXY.Y, zoom) // bottom right tile = tileMatrix[last, last] )); }
/// <summary> /// /// </summary> /// <param name="envelope"></param> /// <param name="bounds"></param> /// <returns></returns> public Tile[,] GetTiles(Envelope envelope, Rectangle bounds) { Coordinate mapTopLeft = envelope.TopLeft(); Coordinate mapBottomRight = envelope.BottomRight(); //Clip the coordinates so they are in the range of the web mercator projection mapTopLeft.Y = TileCalculator.Clip(mapTopLeft.Y, TileCalculator.MinLatitude, TileCalculator.MaxLatitude); mapTopLeft.X = TileCalculator.Clip(mapTopLeft.X, TileCalculator.MinLongitude, TileCalculator.MaxLongitude); mapBottomRight.Y = TileCalculator.Clip(mapBottomRight.Y, TileCalculator.MinLatitude, TileCalculator.MaxLatitude); mapBottomRight.X = TileCalculator.Clip(mapBottomRight.X, TileCalculator.MinLongitude, TileCalculator.MaxLongitude); int zoom = TileCalculator.DetermineZoomLevel(envelope, bounds); Point topLeftTileXY = TileCalculator.LatLongToTileXY(mapTopLeft, zoom); Point btmRightTileXY = TileCalculator.LatLongToTileXY(mapBottomRight, zoom); var tileMatrix = new Tile[(int)(btmRightTileXY.X - topLeftTileXY.X) + 1, (int)(btmRightTileXY.Y - topLeftTileXY.Y) + 1]; Parallel.For((int)topLeftTileXY.Y, (int)btmRightTileXY.Y + 1, y => Parallel.For((int)topLeftTileXY.X, (int)btmRightTileXY.X + 1, x => { var currTopLeftPixXY = TileCalculator.TileXYToTopLeftPixelXY(x, y); var currTopLeftCoord = TileCalculator.PixelXYToLatLong((int)currTopLeftPixXY.X, (int)currTopLeftPixXY.Y, zoom); var currBtmRightPixXY = TileCalculator.TileXYToBottomRightPixelXY(x, y); var currBtmRightCoord = TileCalculator.PixelXYToLatLong((int)currBtmRightPixXY.X, (int)currBtmRightPixXY.Y, zoom); var currEnv = new Envelope(currTopLeftCoord, currBtmRightCoord); var tile = GetTile(x, y, currEnv, zoom); tileMatrix[x - (int)topLeftTileXY.X, y - (int)topLeftTileXY.Y] = tile; } )); return(tileMatrix); }
/// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="envelope"></param> /// <param name="zoom"></param> /// <returns></returns> public Tile GetTile(int x, int y, Envelope envelope, int zoom) { Bitmap bitmap = _tileCache.Get(zoom, x, y); if (null == bitmap) { bitmap = GetViaBrutile(x, y, zoom, envelope); } if (null != bitmap) { var tile = new Tile(x, y, zoom, envelope, bitmap); return(tile); } try { string url = _tileServerUrl; if (url.Contains("{key}")) { string quadKey = TileCalculator.TileXYToBingQuadKey(x, y, zoom); url = url.Replace("{key}", quadKey); } else { url = url.Replace("{zoom}", zoom.ToString()); url = url.Replace("{x}", x.ToString()); url = url.Replace("{y}", y.ToString()); } var client = new WebClient(); var stream = client.OpenRead(url); if (stream != null) { bitmap = new Bitmap(stream); } var tile = new Tile(x, y, zoom, envelope, bitmap); if (stream != null) { stream.Flush(); stream.Close(); } //Put the tile in the cache _tileCache.Put(tile); return(tile); } catch (Exception ex) { // We may see a 400 (Bad Request) when the user is zoomed in too far. Debug.WriteLine(ex.Message); //Return a No Data Available tile var noDataTile = new Tile(x, y, zoom, envelope, resources.NoDataTile); return(noDataTile); } }