ThinkGeo.com    |     Documentation    |     Premium Support

How do I assign colors to each shape

I am working on the drawing tools piece and I am looking for a way to allow the user to set the color for each item they are drawing as well as line size and other things. I was thinking that a way to do this could be using the columns and add these attributes to the database. That is as far as I got. I don’t know how I would apply this in a style.



Any suggestions?

Hi Scott, 
  
 If you want to put all features in same layer, you can set your valueStyle and dynamic add ValuItem to valueStyle.ValueItems. 
  
 You can use featureID as value of ValueItem, if user modify the feature, find corresponding ValueItem in collection, and replace its style. 
  
 I think it should works. 
  
 Does save to database necessary in your scenario? 
  
 Regards, 
  
 Don

Hello Don,

I am not sure if saving to the database would be necessary, we are saving the drawing to a shape file and loading it back next time the app is run. Using ValueItems can I still do this? Next time the app is run where would the style info come from? Do you have any examples of using value items? 



Thanks, 



Scott

Hi Don, 

I ran into another thing while working on this. I have a custom line style added to my map and things sort of work. The problem I am having is, when I first start drawing a line I get the default blue line showing me where I am drawing. After I finish drawing a line and the DrawEnded event fires I set the custom style. Now the next line I start to draw has no visible line showing me where I am drawing, even though when I double click to terminate the line it will then show the line I just finished drawing.



Any idea where the line has gone?


GranularStyle lineStyle = new GranularStyle();
lineStyle.RequiredColumnNames.Add("Width");
lineStyle.RequiredColumnNames.Add("Color");
defaultZoomLevel.CustomStyles.Add(lineStyle);
defaultZoomLevel.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;




public class GranularStyle : LineStyle
    {
        protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<SimpleCandidate> labelsInAllLayers)
        {
            double customWidth = 1;
            int customOpacity = 255;
            GeoColor customColor = GeoColor.SimpleColors.Red;
            foreach (Feature feature in features)
            {
                double width;
               if (double.TryParse(feature.ColumnValues["Width"], out width))
               {
                   customWidth = width;
               }
                //customOpacity = (int)(Convert.ToInt32(feature.ColumnValues["Opacity"]) * 2.55);
               if (feature.ColumnValues.Any(a => a.Key == "Color") && 
                   !string.IsNullOrEmpty(feature.ColumnValues.First(b => b.Key == "Color").Value))
                {
                    customColor = GeoColor.FromHtml(feature.ColumnValues["Color"]);
                }
 
                    canvas.DrawLine(feature,
                                    new GeoPen(GeoColor.FromArgb(customOpacity, customColor), (float)customWidth),
                                    DrawingLevel.LabelLevel);
                
            }
        }
    }



Posted By Scott on 01-16-2014 10:09 AM


Hello Don,

I am not sure if saving to the database would be necessary, we are saving the drawing to a shape file and loading it back next time the app is run. Using ValueItems can I still do this? Next time the app is run where would the style info come from? Do you have any examples of using value items? 



Thanks, 



Scott


Hi Scott,



I ask about database because you mentioned that in your first post. I think save to shape file and load back is ok.



How to render it is not related how to save it. So please don’t worry about that.



Here we have a sample about ValueStyle, please view it.

wiki.thinkgeo.com/wiki/Sourc…110218.zip



Regards,



Don


Posted By Scott on 01-16-2014 05:36 PM


Hi Don, 

I ran into another thing while working on this. I have a custom line style added to my map and things sort of work. The problem I am having is, when I first start drawing a line I get the default blue line showing me where I am drawing. After I finish drawing a line and the DrawEnded event fires I set the custom style. Now the next line I start to draw has no visible line showing me where I am drawing, even though when I double click to terminate the line it will then show the line I just finished drawing.



Any idea where the line has gone?


GranularStyle lineStyle = new GranularStyle();
lineStyle.RequiredColumnNames.Add(“Width”);
lineStyle.RequiredColumnNames.Add(“Color”);
defaultZoomLevel.CustomStyles.Add(lineStyle);
defaultZoomLevel.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;




public class GranularStyle : LineStyle
    {
        protected override void DrawCore(IEnumerable<feature> features, GeoCanvas canvas, System.Collections.ObjectModel.Collection<simplecandidate> labelsInThisLayer, System.Collections.ObjectModel.Collection<simplecandidate> labelsInAllLayers)
        {
            double customWidth = 1;
            int customOpacity = 255;
            GeoColor customColor = GeoColor.SimpleColors.Red;
            foreach (Feature feature in features)
            {
                double width;
               if (double.TryParse(feature.ColumnValues[“Width”], out width))
               {
                   customWidth = width;
               }
                //customOpacity = (int)(Convert.ToInt32(feature.ColumnValues[“Opacity”]) * 2.55);
               if (feature.ColumnValues.Any(a => a.Key == “Color”) && 
                   !string.IsNullOrEmpty(feature.ColumnValues.First(b => b.Key == “Color”).Value))
                {
                    customColor = GeoColor.FromHtml(feature.ColumnValues[“Color”]);
                }
 
                    canvas.DrawLine(feature,
                                    new GeoPen(GeoColor.FromArgb(customOpacity, customColor), (float)customWidth),
                                    DrawingLevel.LabelLevel);
                
            }
        }
    }

Hi Scott,



Sorry I haven’t found problem in your code snippet. I think TrackOverlay won’t related with your custom style, because you should move your feature to your own layer after track end each time. And your custom style should works for your own layer only.



Could you please create a really simple sample which can reproduce this problem so that I can help you find the problem?



Regards,



Don


Hi Don, thank you for your reply. I had a look at the value style piece and it looks like you can have multiple preset styles that are applied to different things, but it does not seam that I can have dynamic ones. One of my requirements are, the user has a color wheel and is able to select any color and apply it to the line being drawn. So that would be far to many colors to make predefined styles for.



As for the other issue I was having I can try moving the drawn item to my own layer, but it would have been nice for the preview line being drawn could reflect the color the user has chosen from the color wheel. .



Also with the custom style I put above even though it is a line style when using the drawing tools and I try and draw a polygon it will crash because my style is a line style. Now I assume I also need to create another custom style that inherits AreaStyle. Is there a way to make this work?

Hi Scott, 
  
 We used to render shape by preset styles, but you can try getting the style back and set value to it dynamic. We can try to find another solution if that don’t works there. 
  
 For your another issue, I haven’t reproduced it via your code snippet, so I am not sure how it looks like for now. 
  
 If you want to support area shape, please create spearated area style, and add that to custom style. And I think put area style to a single layer is better. 
  
 Regards, 
  
 Don

Hi Don, I have been making progress with this issue, but another thing that has come up, is on a style like the sample above, I am using canvas.DrawTextWithWorldCoordinate() method to add the styled text to the map. I want to be able to input the angle of this. I see I can do it with canvas.DrawText(), but this method only takes a screen point and of course will move while the map is panning.  
  
 Any suggestions on this?

Hi Scott, 
  
 Please call ExtentHelper.ToScreenCoordinate function to get sceen coordinate of your upperLeftXInWorld and upperLeftYInWorld. 
  
 Then you can create an array like this: 
  
 ScreenPointF[] screenPoints = new ScreenPointF[] { new ScreenPointF((float)yourX, (float)yourY) }; 
  
 And call DrawText function. 
  
 Regards, 
  
 Don