ThinkGeo.com    |     Documentation    |     Premium Support

Legend

Hi Everybody


Out of classBreakStyles and valueStyles which present features at different colors, how can I set up a layer that will specifically describe what those colors mean? (i.e Adornment or legend layer)
 
How can I set a fore color and font size/weight for my LayerSwitcher?
 
Best Regards,
Vincent

 


Hi, Vincent
 
That adornment or legend layer is not used for this purpose. Can you describe the detail scenario for your web app?
 
If you want to customize the style for OverlaySwitcher control, please refer to the code below:
    <script type="text/javascript">
 
        function OnMapCreated(map) {
            var overlaySwitcher = map.getControlsByClass("OpenLayers.Control.LayerSwitcher")[0];
            
            // Set the position of OverlaySwitcher
            overlaySwitcher.div.style.position = "fixed";
            overlaySwitcher.div.style.right = "200px";
            overlaySwitcher.div.style.top = "200px";
            overlaySwitcher.layersDiv.style.paddingRight = "0px";
            
            // Set the forground color for base layer
            overlaySwitcher.baseLbl.style.color = "red";
            overlaySwitcher.baseLbl.style.fontWeight = "bolder";
            overlaySwitcher.baseLayersDiv.style.color = "blue";
 
            // Set the forground color for none base layers
            overlaySwitcher.dataLbl.style.color = "yellow";
            overlaySwitcher.dataLbl.style.fontWeight = "bold";
            overlaySwitcher.dataLayersDiv.style.color = "black";
        }
 
    </script>
 
Thanks,
 
Khalil

Hi Khalil


Thank you for the reply. Basically in my web application, I have a land parcel shape file which I have linked with my custom database. Using valueStyle, I am now able to display land parcels with outstanding land rent in red color, and those with no outstanding land rent in green color.


Now what I want to do is to set up a legend that with describe what does the red color mean and what does the green color mean, so that the user can easily understand the map. In this case, can you give me a sample code showing how to automatically set up a legend that will work with valueStyle and classBreak.


Best Regards,


Vincent



 


Hi, Vincent
Why don’t you want to use a float description panel to let the users understand what does the map mean? I think it's the best choice. Please see the attached screenshot below which comes from the "DrawThematicFeatures"  sample and pay attention to the panel emphasized with red border, also you can find the source codes for the description panel in the Help folder in our installed samples.

If you want to draw the legend on every feature, and I don’t think it’s not a better choice, because it will decrease performance and increase the load on the server-side.
 
If you still have any quesitons about it please let us know. 
 
Thanks,
 
Khalil

 Is there any sample similar to this for the WPF edition of Map Suite?  I need to do a legend for a thematic layer in there too, but the regular legend adornment layer does not provide the thematic information.


 


thanks.



 


Mikkel,
Normally, the code about Layer in WebEdition can be applied to WpfEdiiton, because both of them have the same logic in this part.
DrawSample method of style can be used to drawing the snapshot, and then create the legend based on your requirements. The attached is a demo about it, please take a look at it.
Thanks,
Johnny

Post8316.zip (13.1 KB)

 Johnny,


Thanks for your reply.  I am working with that example at this point.  My problem came up when I tried running my custom layer through the DrawLegend() Method.  That method only looks at the default styles for each layer, but my layer has custom styles.  I attempted to add the customs styles using the DrawSample() method, as in my code sample below:


 



 


                layer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle.DrawSample(legendCanvas);


                layer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle.DrawSample(legendCanvas);


                layer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle.DrawSample(legendCanvas);


                //also go through any custom styles to get those, if available.


                for (int i = 0; i < layer.ZoomLevelSet.ZoomLevel01.CustomStyles.Count; i++)


                {


                    layer.ZoomLevelSet.ZoomLevel01.CustomStyles.DrawSample(legendCanvas);


                }


 


I add my customs styles in the window that holds the main map, using code that changes the styles based on one or two categories selected by the user in drop down menu.  This was based on the sample code for CachedValueStyle.  Note that the GetInner and Outer Point Styles methods just return a hard-coded list of point styles.  The value ranges work, and refresh on the map correctly.  I've attached a screen shot of what I'm trying to do.  Do I need to do something different to get the custom styles to load in the legend?  I'll also take a look at the thematic style example for the web, and translate that code over if possible.



.. In my load points method


            innerWellsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();


            outerWellsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();


            RadComboBoxItem innerSelection = (RadComboBoxItem)wellSymbology1.InnerSymbology.SelectedValue;


            RadComboBoxItem outerSelection = (RadComboBoxItem)wellSymbology1.OuterSymbology.SelectedValue;


            innerWellsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(GetCustomLayerStyle(true, innerSelection.Content.ToString()));


            outerWellsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(GetCustomLayerStyle(false, outerSelection.Content.ToString()));


..continue with setting layers visible and refresh map...



 private CachedValueStyle GetCustomLayerStyle(bool isInner, string classificationCategory)


        {


            List<PointStyle> pointStyles ;


            if (isInner)


                pointStyles = GetInnerPointStyles();


            else


                pointStyles = GetOuterPointStyles();


... determine and set unique values in the layer...

 
            for (int i = 0; i < uniqueValues.Count; i++)
            {
                string uVal = uniqueValues;
                cachedValueStyle.ValueItems.Add(uVal, new ValueItem(uVal, pointStyles));
            }
            return cachedValueStyle;
        }




 



 


Hi Mikkel,
 
I think there is a misunderstanding in the usage of method “DrawSample”, like: “layer.ZoomLevelSet.ZoomLevel01.CustomStyles.DrawSample(legendCanvas)”. CustomStyles is a collection including one or more styles, and you should loop and drawSample for each style in it. Here is the code to create the legend image for each style.
 
GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();
int i=0;
foreach (ThinkGeo.MapSuite.Core.Style style in innerWellsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles)
{
    using (Bitmap bitmap = new Bitmap(40, 20))
    {
                                //Here is the filePath of legend image, you can define it you want.
        string filePath = string.Format(@".\LegendImage\{0}.jpg",i);
        canvas.BeginDrawing(bitmap, new RectangleShape(0, bitmap.Width, bitmap.Height, 0), GeographyUnit.DecimalDegree);
                                if(style is PointStyle)
                                {
                                                PointStyle pointStyle=style as PointStyle;
                                                pointStyle.DrawSample(canvas);
                                                canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);
                                                    // Todo:
                                                bitmap.Save(filePath);
                                                i++;
                                }
    }
}
 
When legend images are created, you can use image control to display them.
 
Thanks,

Johnny



 Thanks for your reply - I was distracted with other issues for a couple days there, but finally have gotten back to this project...


In your code sample, I can't get the following line to compile:


canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);


The draw screen image method needs a GeoImage object, rather than a bitmap, and I can't find a simple way to convert the bitmap to the GeoImage.  Am I just missing something here?  It looks fairly simple, but still won't work.


I'd also be happy to take the sample images and put them on a canvas that would display over the map, rather than on an adornment layer, if there is a sample of that.


Thanks



 


Hi Mikkel,
Just as shown in the previous post, the canvas should be the GdiPlusGeoCanvas raster than the abstract class GeoCanvas, so we can give bitmap value. Here is the signature of the GdiPlusGeoCanvas.DrawScreenImageWithoutScaling:
DrawScreenImageWithoutScaling(Bitmap image, float centerXInScreen, float centerYInScreen, DrawingLevel drawingLevel, float xOffset, float yOffset, float rotateAngle);
Please replace the code of method “CreateLegendImage” in the demo attached by us before with the one in previous post.
Sorry that I didn’t understood you clearly, in the demo posted before, we did put the sample images on a wpf canvas which overlays on the map, rather than on an adornmentlayer. Here is the demo posted before gis.thinkgeo.com/Portals/1/a...st8316.zip, please try it again.
Thanks,
Johnny

 I have code working now that will create a legend swatch for each of my layers, and also for each of my custom categories.  The problem I'm having now is that the legend swatches have a duplicate of the image i want in the upper left of the created swatch. I've attached a couple example images to show what I mean.  It happens for line types layers as well as point types.


Does anyone have any idea why this is happening?  My method that creates the images is listed below.


 



 public string CreateLegendImages(ThinkGeo.MapSuite.Core.Style style, string uVal, bool isInner)


        {


            GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();


 


            string legendBaseDir = Path.Combine(LMTO.WPF.Business.ProjectInfo.ProjectFolderPath, "LegendImage");


            if (!Directory.Exists(legendBaseDir))


                Directory.CreateDirectory(legendBaseDir);


 


            string filePath = string.Format(@"{0}\{1}.jpg", legendBaseDir, uVal + ((isInner) ? "I" : "O"));


                


            using (Bitmap bitmap = new Bitmap(20, 20))


            {


                //Here is the filePath of legend image, you can define it you want.


                canvas.BeginDrawing(bitmap, new RectangleShape(0, bitmap.Width, bitmap.Height, 0), GeographyUnit.DecimalDegree);


                if (style is CachedValueStyle)


                {


                    PointStyle pointStyle = style as PointStyle;


                    pointStyle.DrawSample(canvas);


                    canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);


                    // Todo:


                    if (!File.Exists(filePath))


                        bitmap.Save(filePath);


                }


                else if (style is PointStyle)


                {


                    PointStyle pointStyle = style as PointStyle;


                    pointStyle.DrawSample(canvas);


                    canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);


                    // Todo:


                    if (!File.Exists(filePath))


                        bitmap.Save(filePath);


                }


                else if (style is LineStyle)


                {


                    LineStyle lineStyle = style as LineStyle;


                    lineStyle.DrawSample(canvas);


                    canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);


                    // Todo:


                    if (!File.Exists(filePath))


                        bitmap.Save(filePath);


                }


                else if (style is AreaStyle)


                {


                    AreaStyle areaStyle = style as AreaStyle;


                    areaStyle.DrawSample(canvas);


                    canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);


                    // Todo:


                    if (!File.Exists(filePath))


                        bitmap.Save(filePath);


                }


            }


 


            return filePath;


        }




SemiannualI.jpg (568 Bytes)
Deep_ConcContour.shpO.jpg (164 Bytes)

Mikkel, 
  
 I would like to ask you about the images what you attached, I cannot find it in the previous post maybe you forgot to attach them. I went over all of the posts above and check the sample application, I have the same question as Johnny, the demo can meet your requirement correctly and what’s the exact implemention you want also I cannot run your code correctly, if it is possible please send your application and images to us again so that we can realize the requirements what you want, 
  
 Thanks, 
  
 Scott,

 I had uploaded the files, but didn't see that they also needed to be attached to the post separately.



SemiannualI.jpg (568 Bytes)
Deep_ConcContour.shpO.jpg (164 Bytes)

Mikkel,


Thanks for your screen shots and I realized where is the problem in the code what you sent, for the CreateLegendImages method please use the following code in your application to instead of your current ones:


 



      public string CreateLegendImages(ThinkGeo.MapSuite.Core.Style style, string uVal, bool isInner)
        {
            GdiPlusGeoCanvas canvas = new GdiPlusGeoCanvas();
            string legendBaseDir = Path.Combine(LMTO.WPF.Business.ProjectInfo.ProjectFolderPath, "LegendImage");

            if (!Directory.Exists(legendBaseDir))
            {
                Directory.CreateDirectory(legendBaseDir);
            }

            string filePath = (@"{0}\{1}.jpg", legendBaseDir, uVal + ((isInner) ? "I" : "O"));
            using (Bitmap bitmap = new Bitmap(20, 20))
            {
                //Here is the filePath of legend image, you can define it you want.
                canvas.BeginDrawing(bitmap, new RectangleShape(0, bitmap.Width, bitmap.Height, 0), GeographyUnit.DecimalDegree);

                PointStyle pointStyle = style as PointStyle;
                pointStyle.DrawSample(canvas);
                canvas.DrawScreenImageWithoutScaling(bitmap, 0, 0, DrawingLevel.LevelOne, 0, 0, 0);
                canvas.Flush();

                // Todo:
                if (!File.Exists(filePath))
                {
                    bitmap.Save(filePath);
                }
            }

            return filePath;
        }
I arranged your source code and changed a little so that the code can work fine, in the original codes you missed this sentence below:


canvas.Flush();


So this is the exact problem in your code and caused it cannot work fine,


If you still have any questions please let me know,


Thanks,


Scott,