Пример #1
0
        public Bitmap CreateImage(HttpRequestBase httpRequest)
        {
            var markers      = GetMarkers(httpRequest);
            var paths        = GetPaths(httpRequest);
            var otherMapProp = GetOtherQueryStringParams(httpRequest);

            var center = WebMercator.LatLngToPixels(otherMapProp.Latitude, otherMapProp.Longitude, otherMapProp.Zoom);

            var leftEdge = center["x"] - otherMapProp.Width / 2;
            var topEdge  = center["y"] - otherMapProp.Height / 2;
            var tilePos  = WebMercator.PixelsToTile(center["x"], center["y"]);

            var pos    = WebMercator.PositionInTile(center["x"], center["y"]);
            var neTile = WebMercator.PixelsToTile(center["x"] + otherMapProp.Width / 2, center["y"] + otherMapProp.Height / 2);
            var swTile = WebMercator.PixelsToTile(center["x"] - otherMapProp.Width / 2, center["y"] - otherMapProp.Height / 2);

            // Now download all the tiles
            var tiles    = new Dictionary <string, Dictionary <string, Stream> >();
            var urls     = new Dictionary <string, Dictionary <string, string> >();
            var numTiles = 0;

            for (double x = swTile["x"]; x <= neTile["x"]; x++)
            {
                if (!tiles.ContainsKey(x.ToString()))
                {
                    tiles.Add(x.ToString(), new Dictionary <string, Stream>());
                    urls.Add(x.ToString(), new Dictionary <string, string>());
                }
                for (double y = swTile["y"]; y <= neTile["y"]; y++)
                {
                    var url = UrlForTile(x, y, otherMapProp.Zoom, otherMapProp.TileService);
                    tiles[x.ToString()].Add(y.ToString(), null);
                    urls[x.ToString()].Add(y.ToString(), url);
                    numTiles++;
                }
            }

            foreach (var rowUrls in urls)
            {
                foreach (var url in rowUrls.Value)
                {
                    try
                    {
                        tiles[rowUrls.Key][url.Key] = System.Net.WebRequest.Create(url.Value).GetResponse().GetResponseStream();
                    }
                    catch (Exception ex)
                    {
                        throw new Exception($"Calling {url.Value} is failed.", ex);
                    }
                }
            }

            // Assemble all the tiles into a new image positioned as appropriate
            var main     = new Bitmap(otherMapProp.Width, otherMapProp.Height);
            var graphics = Graphics.FromImage(main);

            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            foreach (var ytiles in tiles)
            {
                foreach (var ytile in ytiles.Value)
                {
                    var x  = int.Parse(ytiles.Key);
                    var y  = int.Parse(ytile.Key);
                    var ox = ((x - tilePos["x"]) * TILE_SIZE) - pos["x"] + (otherMapProp.Width / 2);
                    var oy = ((y - tilePos["y"]) * TILE_SIZE) - pos["y"] + (otherMapProp.Height / 2);
                    if (ytile.Value != null)
                    {
                        graphics.DrawImage(Image.FromStream(ytile.Value), Convert.ToSingle(ox), Convert.ToSingle(oy), 256.0f, 256.0f);
                    }
                }
            }

            if (paths.Count > 0)
            {
                // Draw the path with ImageMagick because GD sucks as anti-aliased lines
                foreach (var path in paths)
                {
                    var color  = ColorTranslator.FromHtml("#" + path.Color);
                    var pen    = new Pen(color, Convert.ToSingle(path.Weight));
                    var points = new List <Point>();

                    for (int i = 0; i < path.Coordinates.Count; i++)
                    {
                        var to = WebMercator.LatLngToPixels(double.Parse(path.Coordinates[i].Latitude), double.Parse(path.Coordinates[i].Longitude), otherMapProp.Zoom);
                        points.Add(new Point(Convert.ToInt32(to["x"] - leftEdge), Convert.ToInt32(to["y"] - topEdge)));
                    }
                    graphics.DrawPolygon(pen, points.ToArray());
                }
            }

            // Add markers
            foreach (var marker in markers)
            {
                // Icons with a shadow are centered at the bottom middle pixel.
                // Icons with no shadow are centered in the center pixel.
                var   px  = WebMercator.LatLngToPixels(double.Parse(marker.Coordinate.Latitude), double.Parse(marker.Coordinate.Longitude), otherMapProp.Zoom);
                var   img = Image.FromFile(marker.IconImg);
                float x   = Convert.ToSingle(px["x"] - leftEdge - Math.Round(img.Width / 2.0));
                float y   = Convert.ToSingle(px["y"] - topEdge - img.Height);
                graphics.DrawImage(img, x, y);
            }

            return(main);
        }
Пример #2
0
        public OtherMapProperties GetOtherQueryStringParams(HttpRequestBase httpRequest)
        {
            var otherMapProp    = new OtherMapProperties();
            var queryStringColl = httpRequest.QueryString;

            var defaultLatitude  = bounds["minLat"] + ((bounds["maxLat"] - bounds["minLat"]) / 2);
            var defaultLongitude = bounds["minLng"] + ((bounds["maxLng"] - bounds["minLng"]) / 2);

            if (httpRequest["latitude"] != null)
            {
                otherMapProp.Latitude  = double.Parse(httpRequest["latitude"].ToString());
                otherMapProp.Longitude = double.Parse(httpRequest["longitude"].ToString());
            }
            else
            {
                otherMapProp.Latitude  = defaultLatitude;
                otherMapProp.Longitude = defaultLongitude;
            }

            otherMapProp.Width  = httpRequest["width"] == null ? (short)300 : short.Parse(httpRequest["width"]);
            otherMapProp.Height = httpRequest["height"] == null ? (short)300 : short.Parse(httpRequest["height"]);

            // If no zoom is specified, choose a zoom level that will fit all the markers and the path
            if (httpRequest["zoom"] != null)
            {
                otherMapProp.Zoom = short.Parse(httpRequest["zoom"]);
            }
            else
            {
                // start at max zoom level (18)
                short fitZoom    = 18;
                var   doesNotFit = true;
                while (fitZoom > 1 && doesNotFit)
                {
                    var center = WebMercator.LatLngToPixels(otherMapProp.Latitude, otherMapProp.Longitude, fitZoom);
                    // check if the bounding rectangle fits within width/height
                    var sw        = WebMercator.LatLngToPixels(bounds["minLat"], bounds["minLng"], fitZoom);
                    var ne        = WebMercator.LatLngToPixels(bounds["maxLat"], bounds["maxLng"], fitZoom);
                    var fitHeight = Math.Abs(ne["y"] - sw["y"]);
                    var fitWidth  = Math.Abs(ne["x"] - sw["x"]);
                    if (fitHeight <= otherMapProp.Height && fitWidth <= otherMapProp.Width)
                    {
                        doesNotFit = false;
                    }
                    fitZoom--;
                }
                otherMapProp.Zoom = fitZoom;
            }

            //First check tileUrl from constructor
            if (string.IsNullOrWhiteSpace(tileService))
            {
                var tileServices = GetDefaultTileServices();
                //if tileUrl is not in constructor, try to get from querystring
                if (httpRequest["basemap"] != null && tileServices.ContainsKey(httpRequest["basemap"]))
                {
                    otherMapProp.TileService = tileServices[httpRequest["basemap"]][0];
                }
                else
                {
                    //if tileUrl is not in constructor and not in querystring, get default from defined list
                    otherMapProp.TileService = tileServices["osm"][0];
                }
            }
            else
            {
                otherMapProp.TileService = tileService;
            }
            return(otherMapProp);
        }