ThinkGeo.com    |     Blog    |     Wiki    |     Support

How to use GetLegendGraphic wms request or other alternation get the Legend as image

 Hi All,


I'm using Thinkgeo WMS server edition to build new WMS plugin. For our wms service we need to show legend of style we used to colour features.
 
I could not receive the legend as an image when I send standard GetLegendGraphic request as bellow.
(localhost:51967/thinkWMSService/WmsHandler.axd?request=GetLegendGraphic&format=image/png&width=20&height=20&layer=amila)
 
Could you direct me to the example which use GetLegendGraphic request?
 
If ThinkGeo doesn’t support this wms request, what are the other alternations available? If LegendAdornmentLayer is a one of option, when I add it into the MapConfiguration, it shows multiple legends on the map per each tile I have in my map. How could I add LegendAdornmentLayer to only show in some corner in the map but not per each tile? 
 
Thanks and Regards
Amila
 

 Hi Amila,



Sorry that there isn’t built-in functionality to support “GetLegendGraphic” now, but the workaround is following the installation sample “SecureServerRequestsWmsHandler.cs” or “ThrottleUserRequestsWmsHandler.cs” to overwrite the ”ProcessRequestCore” method of the “WmsHandler”, it which, we can use the “DrawSample” method to create LegendGraphic. Following is the demo code, please let me know if there is any other parameters required:





    public class SecureServerRequestsWmsHandler : WmsHandler
    {
        public SecureServerRequestsWmsHandler()
        {
        }

        protected override void ProcessRequestCore(HttpContext context)
        {
            // Grab the clientId and signiture from the query string
            NameValueCollection nameValueCollection = context.Request.QueryString;
            string requestType= nameValueCollection["REQUEST"].ToUpperInvariant();

            if (requestType.Equals("GetLegendGraphic", StringComparison.OrdinalIgnoreCase))
            {
            }
            else
            {
                base.ProcessRequestCore(context);
            }
        }

        private void GetLegendGraphic(string layerName, int width, int height, ImageFormat imageFormat)
        {
            // Todo: implement the get legendGraphic using Style.DrawSample() method
        }
    }


 


Thanks,


Johnny 



HI Jhonny, 
  
 This is a good work around. But I was not able to get a bitmap. I think issue should be with my  canvas.BeginDrawing() method rectangle parameter or style.DrawSample() method DrawingRectangleF parameter. I have no idea on these two parameters.  
  
 I have posted my sample code below. Could you please show me the issue with this method. 
  
 
bitmap = new Bitmap(500, 500);
                    GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();

                  //  RectangleShape rect = new RectangleShape(12523442.7125, 1252344.27125, 13775786.98375, -0.0000000016298145055771);
                    RectangleShape rect = new RectangleShape(-155.733, 95.6, 104.42, -81.9);
                    canvas.BeginDrawing(bitmap, rect,GeographyUnit.DecimalDegree);

                   // RectangleShape rect = new RectangleShape(-155.733, 95.6, 104.42, -81.9);
                    DrawingRectangleF dd = new DrawingRectangleF(0,0, 500, 500);
                    requestedStyle.DrawSample(canvas, dd);

                   // PointShape centerPoint = rect.GetCenterPoint();
                  //  canvas.DrawTextWithWorldCoordinate("Watermark", new GeoFont("Arial", 11, DrawingFontStyles.Bold), new GeoSolidBrush(new GeoColor(100, GeoColor.StandardColors.Red)), centerPoint.X, centerPoint.Y, DrawingLevel.LevelOne);

                    canvas.EndDrawing();
                   // bitmap = (Bitmap)canvas.NativeImage;

                    stream = new MemoryStream();
                    bitmap.Save(stream, imageFormat);
                 //   bitmap.Save(@"D:\Works\wmsCache\1.bmp");
                    context.Response.ContentType = nameValueCollection["FORMAT"];
                    context.Response.BinaryWrite(stream.GetBuffer());
 
 
  
 Thanks 
 Amila

 


 
Hi Amila,
 
Seems that there isn't any problem with your code, I guess maybe missed registered the new Handler and runs into nothing, following are the steps i did, please check it out:
 
1. Implement GetLegendGraphic method shown as below:

private void GetLegendGraphic(HttpContext context)
{
    // Todo: implement the get legendGraphic using Style.DrawSample() method
    Bitmap bitmap = new Bitmap(500, 500);
    GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();

    RectangleShape rect = new RectangleShape(-155.733, 95.6, 104.42, -81.9);
    canvas.BeginDrawing(bitmap, rect, GeographyUnit.DecimalDegree);

    DrawingRectangleF dd = new DrawingRectangleF(0, 0, 500, 500);

    AreaStyle requestedStyle = AreaStyles.Sand1;
    requestedStyle.DrawSample(canvas, dd);
    canvas.EndDrawing();

    MemoryStream stream = new MemoryStream();
    bitmap.Save(stream, ImageFormat.Png);
    bitmap.Save(@"c:\temp\1.bmp");
    context.Response.ContentType = "image/png";
    context.Response.BinaryWrite(stream.GetBuffer());
}

2. Register the new "WmsHanlder" in Web.config, just like below:

<httpHandlers>
<add path="SecureServerRequestsWmsHandler.axd" verb="GET" type="ThinkGeo.MapSuite.WmsServerEdition.SecureServerRequestsWmsHandler"/>


3. Request the "Legend Grpahic" using URL 
localhost:59387/SecureServerRequestsWmsHandler.axd?STYLES=DEFAULT&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetLegendGraphic . it shows the screen as below:
 
 
Thanks,
Johnny

Hi Johnny, 
  
 Thanks for the reply. It seems like ClassBreakStyle DrawSample method does not produce a image. I tried with other styles and it work fine. 
 I have given my method below. Please advice to use DrawSample method with ClassBreakStyle. 
  
 
private void _GetLegendGraphic(HttpContext context)
        {
            Bitmap bitmap = new Bitmap(150, 600);
            GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();

            RectangleShape rect = new RectangleShape();
            canvas.BeginDrawing(bitmap, rect, GeographyUnit.DecimalDegree);

            AreaStyle style1 = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Red, 10), new GeoSolidBrush(GeoColor.SimpleColors.Blue));
            AreaStyle style2 = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Gold, 10), new GeoSolidBrush(GeoColor.SimpleColors.Green));
            AreaStyle style3 = new AreaStyle(new GeoPen(GeoColor.SimpleColors.Yellow, 10), new GeoSolidBrush(GeoColor.SimpleColors.Orange));
            AreaStyle style4 = new AreaStyle(new GeoPen(GeoColor.StandardColors.Cyan, 10), new GeoSolidBrush(GeoColor.StandardColors.Fuchsia));

            ClassBreakStyle clBreakStyle = new ClassBreakStyle();

            ClassBreak clBreak1 = new ClassBreak(2, style1);
            clBreakStyle.ClassBreaks.Add(clBreak1);

            ClassBreak clBreak2 = new ClassBreak(4, style2);
            clBreakStyle.ClassBreaks.Add(clBreak2);

            ClassBreak clBreak3 = new ClassBreak(6, style3);
            clBreakStyle.ClassBreaks.Add(clBreak3);

            ClassBreak clBreak4 = new ClassBreak(8, style4);
            clBreakStyle.ClassBreaks.Add(clBreak4);

            // style3.DrawSample(canvas);
            clBreakStyle.DrawSample(canvas);
            
            canvas.EndDrawing();

            MemoryStream stream = new MemoryStream();
            bitmap.Save(stream, ImageFormat.Png);
            bitmap.Save(@"D:\Works\wmsCache\legend.bmp");
            context.Response.ContentType = "image/png";
            context.Response.BinaryWrite(stream.GetBuffer());
        }
 
  
 Thanks 
 Amila

Hi Amila, 
  
 After checking the source code, we found it’s a missing feature in our release version but works fine in our development version. Now, we have added into the release version and please get the latest release version 6.0.0.291  or later to have a try. 
  
 Regards, 
  
 Johnny

Hi Johnny, 
  
 Thanks for reply. I tested with the version 6.0.0.291 dlls and it works to some extent. 
  
 However I used native .net Graphics class to draw legend. Thanks for the quick fix. 
  
 Regards 
 Amila

Hi Amila,  
  
 You are so welcome, we are working on this feature these days, hopefully, we can add it into our upcoming 7.0 release. 
  
 Thanks, 
 Johnny

Hi,

We are using WMS Server edition 9.0.685 and not able to find this feature / override available “GetLegendGraphic”. Is this feature implemented in currently or any previous versions?

Thanks,

Hi Udaya,

The “GetLegendGraphic” hadn’t been added in original versions.

We will release a new product named GIS server, which will contains the WMS server. That’s why the WMS server edition hadn’t been include in our V10. I think the 3 optionally features for WMS provider should be included in the new product.

Because we had stopped to introduce new feature for V9, so I think for now you should want to choose the same workaround from Johnny.

Regards,

Don