/// <summary> Retrieves the image of a certain map tile and returns it as image stream. </summary> /// <param name="x"> X coordinate of the tile. </param> /// <param name="y"> Y coordinate of the tile. </param> /// <param name="zoom"> Zoom factor of the tile. </param> /// <returns> Image stream of the specified tile. </returns> public Stream GetImageStream(int x, int y, int zoom) { string tmpUrl = metaInfo.ImageUrl; tmpUrl = tmpUrl.Replace("{subdomain}", metaInfo.ImageUrlSubDomains[(x ^ y) % metaInfo.ImageUrlSubDomains.Length]); tmpUrl = tmpUrl.Replace("{quadkey}", GeoTransform.TileXYToQuadKey(x, y, zoom)); if (tmpUrl.Contains("{culture}")) { tmpUrl = tmpUrl.Replace("{culture}", Thread.CurrentThread.CurrentUICulture.Name.ToLower()); } // append key if (!string.IsNullOrEmpty(metaInfo.Key)) { tmpUrl = tmpUrl + "&key=" + metaInfo.Key; } // n=z will return 404 if the tile is not available instead of the "no imagery" image. tmpUrl = tmpUrl + "&n=z"; try { var request = (HttpWebRequest)WebRequest.Create(tmpUrl); request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable); request.KeepAlive = false; return(request.GetResponse().GetResponseStream()); } catch (Exception exception) { return(TileExceptionHandler.RenderException(exception, 256, 256)); } }
/// <summary> The function which reads the image stream and adapts the request parameters. </summary> /// <param name="left"> Left bound of the displayed map section. </param> /// <param name="top"> Top bound of the displayed map section. </param> /// <param name="right"> Right bound of the displayed map section. </param> /// <param name="bottom"> Bottom bound of the displayed map section. </param> /// <param name="width"> Width of the displayed map section. </param> /// <param name="height"> Height of the displayed map section. </param> /// <returns> The map image as a stream. </returns> public Stream GetImageStream(double left, double top, double right, double bottom, int width, int height) { try { if (left >= minX && right <= maxX && top >= minY && bottom <= maxY) { return(GetImageStreamInternal(left, top, right, bottom, width, height)); } double leftClipped = Math.Max(left, minX); double rightClipped = Math.Min(right, maxX); double topClipped = Math.Max(top, minY); double bottomClipped = Math.Min(bottom, maxY); double rWidth = width * ((rightClipped - leftClipped) / (right - left)); double rHeight = height * ((bottomClipped - topClipped) / (bottom - top)); if (rWidth < 32 || rHeight < 32) { var ms = new MemoryStream(); Bitmap bmp = new Bitmap(width, height); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); ms.Seek(0, SeekOrigin.Begin); return(ms); } using (var stream = GetImageStreamInternal(leftClipped, topClipped, rightClipped, bottomClipped, (int)rWidth, (int)rHeight)) // bitmapCache has to be converted to png. Silverlight doesn't support gif!? using (var img = Image.FromStream(stream)) using (Bitmap bmp = new Bitmap(width, height)) { using (Graphics g = Graphics.FromImage(bmp)) { double offsetX = (leftClipped - left) / (right - left) * width; double offsetY = (bottomClipped - bottom) / (top - bottom) * height; g.DrawImageUnscaled(img, (int)Math.Ceiling(offsetX), (int)Math.Ceiling(offsetY)); } // save to memory stream var ms = new MemoryStream(); bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png); ms.Seek(0, SeekOrigin.Begin); return(ms); } } catch (Exception exception) { return(TileExceptionHandler.RenderException(exception, width, height)); } }
/// <summary> Retrieves the image of a certain map tile and returns it as image stream. </summary> /// <param name="x"> X coordinate of the tile. </param> /// <param name="y"> Y coordinate of the tile. </param> /// <param name="zoom"> Zoom factor of the tile. </param> /// <returns> Image stream of the specified tile. </returns> public Stream GetImageStream(int x, int y, int zoom) { string tmpUrl = metaInfo.ImageUrl; tmpUrl = tmpUrl.Replace("{subdomain}", metaInfo.ImageUrlSubDomains[(x ^ y) % metaInfo.ImageUrlSubDomains.Length]); tmpUrl = tmpUrl.Replace("{quadkey}", GeoTransform.TileXYToQuadKey(x, y, zoom)); if (tmpUrl.Contains("{culture}")) { tmpUrl = tmpUrl.Replace("{culture}", Thread.CurrentThread.CurrentUICulture.Name.ToLower()); } // append key if (!string.IsNullOrEmpty(metaInfo.Key)) { tmpUrl = tmpUrl + "&key=" + metaInfo.Key; } // n=z will return 404 if the tile is not available instead of the "no imagery" image. tmpUrl = tmpUrl + "&n=z"; try { var request = (HttpWebRequest)WebRequest.Create(tmpUrl); request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable); request.KeepAlive = false; request.Proxy.Credentials = CredentialCache.DefaultCredentials; return(request.GetResponse().GetResponseStream()); } catch (WebException webException) { logger.Writeline(TraceEventType.Error, "WebException occured :" + Environment.NewLine + "Exception Message : " + webException.Message); logger.Writeline(TraceEventType.Error, "URL :" + tmpUrl); logger.Writeline(TraceEventType.Error, string.Format("WebException Status : {0}", webException.Status)); if (webException.Status == WebExceptionStatus.ProtocolError) { logger.Writeline(TraceEventType.Error, string.Format("Status Code : {0}", ((HttpWebResponse)webException.Response).StatusCode)); logger.Writeline(TraceEventType.Error, string.Format("Status Description : {0}", ((HttpWebResponse)webException.Response).StatusDescription)); } return(TileExceptionHandler.RenderException(webException, 256, 256)); } catch (Exception exception) { logger.Writeline(TraceEventType.Error, "Exception occured : " + Environment.NewLine + exception.Message); return(TileExceptionHandler.RenderException(exception, 256, 256)); } }
/// <summary> Retrieves the map image from the xMapServer and returns it as a stream. </summary> /// <param name="left"> Left coordinates. </param> /// <param name="top"> Top coordinates. </param> /// <param name="right"> Right coordinates. </param> /// <param name="bottom"> Bottom coordinates. </param> /// <param name="width"> Width of the image. </param> /// <param name="height"> Height of the image. </param> /// <param name="mapObjects"> Set of map objects. </param> /// <returns> The map image as stream. </returns> public Stream GetStreamInternal(double left, double top, double right, double bottom, int width, int height, out IEnumerable <IMapObject> mapObjects) { mapObjects = null; int trials = 0; while (true) { try { var imageStream = new MemoryStream(TryGetStreamInternal(left, top, right, bottom, width, height, out mapObjects)); if (!needsTransparency) { return(imageStream); } using (var image = System.Drawing.Image.FromStream(imageStream)) { var bmp = image as System.Drawing.Bitmap; // make map background color transparent bmp?.MakeTransparent(System.Drawing.Color.FromArgb(255, 254, 185)); return(SaveAndConvert(bmp)); } } catch (WebException ex) { var res = (HttpWebResponse)ex.Response; if (res != null && res.StatusCode != HttpStatusCode.InternalServerError && res.StatusCode != HttpStatusCode.ServiceUnavailable) { return(TileExceptionHandler.RenderException(ex, width, height)); } if (++trials >= 3) { return(TileExceptionHandler.RenderException(ex, width, height)); } System.Threading.Thread.Sleep(50); } catch (Exception ex) { return(TileExceptionHandler.RenderException(ex, width, height)); } } }
/// <inheritdoc/> public Stream GetImageStream(int tileX, int tileY, int zoom) { try { return(ReadURL(RequestBuilderDelegate(tileX, tileY, zoom))); } catch (Exception exception) { return(TileExceptionHandler.RenderException(exception, 256, 256)); } }