ThinkGeo.com    |     Documentation    |     Premium Support

Design question

It appears that drawing color is layer specific.  I have a project with many feature types (roads, buildings, property lines, etc.) and I want each feature to display in a different color.  In some cases, a single feature type may appear in multiple colors based on a database value.  This implies a number of queries equal to the sum of the number of colors for each feature type.  Is there a practical limit to the number of layers in a WinFormMap window?  Is there another approach, using fewer layers, to acheive the same result?



Charles, 
  
   This is a good question!  For this post I am going to assume that since you said database queries you are working with a spatial database and not shape files.  This distinction is slight there are some differences in the approach.  Let me know if I am wrong on this and I can tweak my solutions. 
  
   The short answer is that you have allot of options.  While there is not limit to the number of layers you can have however there, are as you intuited, a practical limit depending on how fast you want maps to render.  Since you are using a database you were right to guess that each layer would be a separate query against the database.  For performance you want to minimize the number of queries sent and try and increase the payload of each query.  All the experience you may have in the SQL world translates nicely to spatial stuff as well. 
  
   While you are correct that colors are based on layers, actually Styles are inside the layers to be more precise, you have many options for types of Styles you can use.  A Style is, in a nutshell , not just how you want the features to draw but they can also contain logic based on any number of factors to determine if they need to draw at all.  An example is the ValueStyle.  In a ValueStyle you specify a database column, or group of columns, you want to base your rules on.  Next you add to the ValueStyle a number of ValueItems.  Each item has a field where you can specify what the matching value will be to trigger that ValueItem.  In each ValueItem you add, you can specify another Style, this is the Style you want to use of the value matches.  So you can have Styles in Styles.  The first style is a decision maker and the inner Style is a reflection of how you want the feature to look.  See my example below, and not it wont compile it is just off the top of my head but shows the point. 
  
 ValueStyle buildingTypeStyle = new ValueStyle(“BuildingType”); ← The parameter is the DB column. 
 ValueItem metalBuilding = new ValueItem(“Metal”); <— This is the value in the column you want to match 
 metalBuilding.DefaultAreaStyle = ….  Some AreaStyle 
 ValueItem woodenBuilding = new ValueItem(“Wood”); 
 woodenBuilding.DefaultAreaStyle = …. 
  
 buildingTypeStyle.Values.Add(metalBuilding); 
 buildingTypeStyle.Values.Add(woodBuilding); 
  
   Tip:  If you have some logic that needs to combine data from type columns you can use brackets around the column names and we will combine them at runtime.  For example you have a column in the database for SchoolType and one for BuildingType.  The school types are Private and Public and the Building types are Metal or Wooden.  You can add a string like “[SchoolType][BuildingType]” and when it resolves at runtime the sting will resolve like “PrivateMetal”.  You can all other characters or space to it it as well like.  “All [SchoolType] schools are [BuldingType].” which would resolve to “All Private schools are Metal.”.  Very cool right? 
  
   That’s it, now add the buildingTypeStyle to your ZoomLevel on the Layer and away you go.  At runtime we will determine for you based on all of your Styles what columsn to fetch form the database and apply the logic for drawing.  We have a good sample of this and other Styles in the Sample apps that are online and come with the evaluation. 
  
   The above was just one kind of decision type of Style.  There are others such as ClassBreakStyle, this works on number ranges such as 100-200.  There is the very flexible RegexStyle which you can specify regular expressions to match complex string data.  You also have the option to write your own Style.  This may seem daunting at first but it is really very simple and we have had a number of users write their own to accomplish all kind of cool effect.  We have some white papers in the developers blog forum that show you some examples. 
  
   Something else to consider is how you want to add your Styles to the ZoomLevels.  You have two choices.  The first choice is to use the handy properties directly on each ZoomLevel.  These are the DefaultAreaStyle, DefautLineStyle etc.  These are single styles you can use.  We added these as the majority of cases people only need one style to represent their features.  The other option is to use the CustomStyles collection on the ZoomLevels.  This takes any number of Styles and allows you to stack Styles.  Note that once you use the CustomStyles collection we will ignore all the the DefaultStyle properties.  Using the collection you can add a ValueStyle based on one column and a ClassBreakStyle based on other columns.  At runtime we evaluate each Style in order so all of them get a chance to draw.  Using this you can come up with complex results such as using a ValueStyle to draw Private schools one way but exclude PublicSchools from the ValueStyle.  Then for PublicSchools they are drawn based on a ClassBreakStyle using StudentEnrollment.  This is very flexible and powerful so play around with it. 
  
   Getting back to the main point.  I have a few suggestions.  I would try to limit the number of layers that you use for performance.  Possibly use one layer per type of feature you have.  This might be like polygons, lines, points etc.  You may even break this up between lines that are roads and lines that are rivers.  You will have to see what performance is like as I don’t know how many types of features you have.  I would then use on of the Value, ClassBreak or Regex Styles to determine based on feature data how to draw it.  For really complex cases I would suggest you write your own Style to get maximum control and to design the properties of the Styles how you want them. 
  
   Another note is that if you decide to create your own style remember that inside of the DrawCore you can always initialize a new style in there and call it’s DrawCore passing in the parameters that were sent to your DrawCore.  In this way you can chain things together. 
  
   A note on caching.  We are working on better caching of data from spatial database so if you let me know which one you plan to use I can help you  with that as well.  Caching can happen at a number of different levels.  We can cache features retrieved from the database.  We can also cache tiles of images already rendered.  Doing a mixture of caching with smart layer management can get you the some good performance results even though your data is over a network.  
  
   I hope this helps.  It is allot of information to take in but it at least gives us a frame of reference to have further discussions.  Many of the topics may seem advanced but like other users find there are really simple once you get the hang of it and once you do there will be no stopping you.  You will fee so empowered once you get the basics down. 
  
 David

Thank you for the detailed post on this. It is something that I had wondered about. (Thanks Charles for asking your question.) 
  
 You mentioned that it ignores the default styles when you add a custom style. I actually got a runtime error when I tried to use both.

Thanks for the help.  Is there any news on Map Suite Desktop Edition Beta 3?

Sorry, that should read Beta 2 an I see that it is available for download.

Yes, it was ready yesterday, please check it and let us know how you think about it. 
  
 Ben