/// <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));
            }
        }
Beispiel #2
0
        /// <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));
                }
            }
        }
Beispiel #5
0
 /// <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)); }
 }