ThinkGeo.com    |     Documentation    |     Premium Support

Applying styles to features in a Feature Class

Hi,

I am trying to let users save the styles for some features in a feature class. For example, after loading the Countries02.shp file, the user click on Australia and changes the fill colour to blue. He should be able to save this as an attribute of that shapefile so that that when he loads it the next time, it should be displayed in blue.
For this, I am adding an attribute column COLOR_MAP, where he can save the colour in hexadecimal string format (#FF67B6F9). 


I have gone through the sample code in wiki.thinkgeo.com/wiki/Source_Code_ServicesEditionSample_ValueStyleWithCountries_CS_100123.zip


I wish to loop through all the features (countries) in the file and check if the COLOR_MAP column has a value and apply it on loading the file. How can I get row values of a shapefile before loading it to the map? Something like Features("COLOR_MAP")(i).Value





Once I get it, I can do 



//---------------------------------------

ShapeFileLayer1 = new ShapeFileFeatureLayer("D:/Projects/SampleData/ShapeFiles/Countries02.shp");
ValueStyle valueStyle = new ValueStyle();
valueStyle.ColumnName = "COLOR_MAP";

int FeatCount = ShapeFileLayer1.QueryTools.GetAllFeatures(ReturningColumnsType.NoColumns).Count;
int i=0;


while (i < FeatCount)


{
 valueStyle.ValueItems.Add(new ValueItem(features("COLOR_MAP")(i).Value, AreaStyles.CreateSimpleAreaStyle(features("COLOR_MAP")(i).Value.ToString(),GeoColor.StandardColors.Black)));
i = i + 1;


}


ShapeFileLayer1.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);




//---------------------------------



How do I accomplish this? ie, getting the value for COLOR_MAP column for each row (i).



Thanks and regards,

Jacob











I got it using the following code… 



------------------------------------------------- 

<feature><feature>


Collection<Feature> AllFeatures = ShapeFileLayer1.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns);
foreach (Feature feature in AllFeatures)
 {
valueStyle.ValueItems.Add(new ValueItem(feature.ColumnValues["COLOR_MAP"], AreaStyles.CreateSimpleAreaStyle(GeoColor.FromHtml(feature.ColumnValues["COLOR_MAP"]), GeoColor.GetRandomGeoColor(200, RandomColorType.All))));
 }
  
ShapeFileLayer1.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);



------------------------------------------------- 



Regards, 

Jacob</feature></feature>

Hi Jacob, 
  
 If you saved that in your dbf file, have you tried to find that like this: 
  
 features.ColumnValues["COLOR_MAP"] 
  
 Please let me know if that works for you. 
  
 Regards, 
  
 Don

Hi Jacob,  
  
 Sorry I haven’t refresh the page so haven’t see your update. 
  
 I am glad to hear you solved that. 
  
 Regards, 
  
 Don

Hi Don, 
  
 The shapefile loads and displays the features in the color mentioned in attribute column "COLOR_MAP". After that I click on the feature on the map, populate a grid with the selected feature attributes, I change the color value of "COLOR_MAP" for a feature and save it back to the shapefile attributes. A simple wpfMap1.Refresh() does not reflect the changes in color on the map. When I do a wpfMap1.Refresh(), the feature itself disappears (No style shows up). If I close the application and load it again, it displays the feature in the new color. Is there an easy way to bring in changes? Or is it done by removing the layer and reloading it in the overlays? 
  
 Thanks, 
 Jacob

Hi Jacob, 
  
 If refresh don’t works, please try to build new layer based on modified shape file. 
  
 And I think maybe you can do something like this, use InmemoryFeatureLayer instead of ShapefileFeatureLayer, then get all feature from ShapeFileFeatureLayer and put them into InmemoryFeatureLayer, when you modify anything, you directly modify the column value in InmemoryFeatureLayer and update ShapeFile, it looks like a “buffer”. 
  
 Regards, 
  
 Don

 Hi Don, 



I wish to add more styles based on the attributes of an area feature… I have FillColor, BorderWidth, BorderColor, BorderLineType etc as attributes. How do I add them to the existing code of fillcolor below 
 



Collection AllFeatures = ShapeFileLayer1.QueryTools.GetAllFeatures(ReturningColumnsType.AllColumns); 

foreach (Feature feature in AllFeatures) 



valueStyle.ValueItems.Add(new ValueItem(feature.ColumnValues["FillColor"], AreaStyles.CreateSimpleAreaStyle(GeoColor.FromHtml(feature.ColumnValues["FillColor"]), GeoColor.GetRandomGeoColor(200, RandomColorType.All))));

 } 

ShapeFileLayer1.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(valueStyle);



 
 



Like FillColor I need to cater to other attributes like BorderWidth, BorderColor, BorderLineType etc. Is it not possible? 



Regards, 
Jacob




Hi Jacob, 
  
 For ValueStyle, it need to use one column as "index", but you want to use multiply columns to build style. 
  
 So I think you can choose some column like "ID", then build a customer function to get create custom style based on other columns. 
  
 Regards, 
  
 Don

Hi Don, 
  
 But if I use the ‘ID’ column, wont it mean that a value item would be created for every single feature? For example, if there are 1000 features in a shapefile, wont there be 1000 style value items generated?  
  
 Wont there be performance issues? 
  
 Regards, 
 Jacob 
  
  
  


Hi Jacob, 
  
 For your requirement, you have four variable FillColor, BorderWidth, BorderColor, BorderLineType now, that means you have many different styles, maybe in some cases your each feature have one style. 
  
 I don’t think it will have performance issue, but I haven’t tested that, for avoid that you write code to avoid add duplication value style, that should be helpful I think. 
  
 Regards, 
  
 Don

Hi, 



I am displaying symbols/fonts based on the data value in the shapefile. Now it is based on pixels, that is, at all scales it shows in the same size. Is there an easy way to set it to variable/paper scale. I saw some examples which shows symbol sizes varying according to a change in the scale, but it seems it is not done by just setting a property. Is there an easy way or property to set the font/symbol size to paper scale instead of pixels? 



Thanks in advance, 

Jacob

Hi Jacob, 
  
 I am sorry I think we don’t have easy way or property for dynamic change the symbol and font size. 
  
 As below are two solution for that requirement: 
  
 1. Set different style for each zoomlevel 
 2. Build your custom style, in DrawCore function calculate the font or symbol size dynamic 
  
 Wish that’s helpful. 
  
 Regards, 
  
 Don