====== Map Suite Style Guide ======
This guide is a work in progress. If you have suggestion or comment please use the discussion tab on this page.
===== Overview ===== ===== What are Styles? ===== Styles are classes which determine how each feature is represented on the map. Styles can be as simple as drawing a thick black line to represent a street to advanced heat styles that represent multiple data points as smooth color gradients. Different styles can be applied to the same data based on the particular map scale. Additionally, with many styles you can use the tabular data associated with the feature to vary their look or even suppress drawing. At their heart styles are where your data and drawing to the map control meet. Map Suite provides a comprehensive set of styles which will cover most mapping requirements. If you find the provided styles do not cover your scenarios then it is easy to create your own custom styles. We have dedicated an entire section to creating your own customer styles below which includes a video and samples. Using custom styles allows you to leverage your own creativity and knowledge of your specific scenarios. Examples of styles include.. * **AreaStyle** - Designed to render areas such as polygons, ellipses and rectangles. * **LineStyle** - Renders lines and multilines. * **PointStyle** - Draws points on the map using various symbols. * **TextStyle** - Labels features on the map. * **ClassBreakStyle** - Used to render feature groups differently based on their data values, ie. 0-100 Red, 100-200 Blue. * **ValueStyle** - Renders features differently based on absolute values in their data, ie. MiddleSchool = Red, HighSchool=Blue. * **Many More..** [[thinkgeo_style_guide#Predefined_Styles|See the complete list below.]]
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png?180px|Sample Area Styles}} \\ Sample Area Styles
{{:Map Suite Services Edition Screenshot Gallery DotDensity.png?180px|Sample Line Styles}} \\ Sample Line Styles
{{:Map Suite Services Edition Screenshot Gallery GreatCircle.png?180px|Sample Point Styles}} \\ Sample Point Styles
The above images depicts a number of different styles created by Map Suite. ===== The Drawing Process ===== ==== Simplified Process ==== The image below depicts a simplified view of how a style works. Data, intended to be drawn, is passed from the layer to the style along with a GeoCanvas. Internally the style calls methods on the GeoCanvas, passing in in pens, brushes and fonts along with the features, to draw the data. Styles can also access tabular data in the feature to make decisions on which pen, colors or other symbols to use based on that data.
{{:Map Suite Style Guide Simplified Drawing Process.png?550px|Sample Area Styles}} \\ Sample Area Styles
==== Actual Process ==== A more complete picture of the drawing process would be... - **Spatial Query** - The Layer does a spatial query to retrieve any features inside of the current extent of the map. - **ZoomLevel** - We determine, through the ZoomLevelSet, which zoom level we will pull styles from based on the maps current scale. - **Check Custom Styles** - We examine the appropriated ZoomLevel determine if there are styles in the CustomStyle collection. If so we draw these. - **Default Styles** - If we do not find custom styles then we examine the default styles to see if they have been changed by the user. If the user has not modified them then we do not use them to draw as their default state is to draw transparently. - **Invoke The Draw** - The layer takes the features it queried along with the GeoCanvas, used to draw on the map, and passes them to each of the styles that were valid. - **Style Internals** - Inside of the Style we typically loop through each feature passed in and if it is of a type we expect, area type for area style, we call drawing methods such as DrawArea on the GeoCanvas passing in the pens, brushes, images, or fonts that is used by the style. - **GeoCanvas** - The GeoCanvas then receives the method calls and then draws, using native methods, onto the device the GeoCanvas was designed to draw upon. For example the SkiaGeoCanvas will draw on a bitmap which the PrinterGeoCanvas call native methods to render to a PDF. ===== Zoom Levels =====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|ZoomLevels}} \\ ZoomLevels
In general styles are applied to a particular ZoomLevel. A ZoomLevel is a particular range, in scale, where you want to style things differently. Zoom levels are part of a ZoomLevelSet which is a collection of non overlapping zoom levels. An analogy would be to think of yourself in space looking down at the earth. At this level your scale might be 1 million. This height, or view, would be represented as a particular ZoomLevel in a ZoomLevelSet ranging from 1, ground level, to 1 million. As you descend towards the earth your scale changes and you would pass through other ZoomLevels on your way down. One thing to note is that as you descend your view of the earth changes and things that were too small to see now come into focus and things that were visible higher are now lost. In the same way your view you change we allow you to set different styles at different ZoomLevels so that you can adjust how things look depending on your current scale. For some layer, like surface streets, you would not even have a style to represent them at scale 1 million. This would cause them not to draw at all but conversely, at this scale, you may draw the capitals of the world as small dots to represent them. As you zoom towards the earth those dots may be replaced by polygons that show the borders of the city etc. At a certain scale you would want to show the surface streets but perhaps just as small thin black lines. As you zoom further still the thin lines would change to thicker black lines with a thin inner line. ==== Default Styles ==== The first, and most common, way is to modify property on what we call 'default styles'. Default styles refer to the styles that are pre ==== Custom Styles ==== ==== Applying Styles Across ZoomLevels ==== It is often the case you need to apply a single set of styles across a number of different ZoomLevels. You may want, for example, surface streets to be drawn as a thin black line from ZoomLevel01 through ZoomLevel05. It would be tedious to set the styles for each ZoomLevel between one through five. To simplify this requirement we allow you to apply styles across ZoomLevels using the ApplyUntilZoomLevel API on the ZoomLevel itself. Let's say you want a particular Style to be visible at ZoomLevel01 through ZoomLevel05. To make that work, we can simply code as follows: //The code below applies all the styles in ZoomLevel01 to every ZoomLevel until ZoomLevel05. In this way you can apply the same styles across a large range of ZoomLevels and save coding each ZoomLevel. Remember to apply the ZoomLevels from smallest, 01, to the largest, 20.// roadsLayer.ZoomLevelSet.ZoomLevel01.DefaultLineStyle = new LineStyle(GeoPens.Black,GeoPens.Red); roadsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level05; ====PresetZoomLevels====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|PresetZoomLevels}} \\ PresetZoomLevels
Styles define the way we visually represent the data, while ZoomLevels define the situation in which we want to display them. The reason why we need ZoomLevels is because we may want to display a small town when we are zoomed into a state, but we definitely don't want to display that town when we are zoomed out and looking at the entire country. We have provided the 20 most common scales, from ZoomLevel01 to ZoomLevel20, at which you may want to change the way your data looks. What is scale? Scale indicates how much the given area has been reduced. If a road is 10,000 inches long in the real world and a map depicts this length as 1 inch on the screen, then we say the scale of this map is 1:10,000. Now let's say ZoomLevel02 uses a scale of 1:500 and ZoomLevel03 uses a scale of 1:1200. This means the map with a current scale of 1:1000 matches ZoomLevel03, the ZoomLevel whose scale is the closest to that. **Default Scales (Truncated)** ^ Scales for ZoomLevels 1-7 ^ Scales for ZoomLevels 8-14 ^ Scales for ZoomLevels 15-20 ^ | 1. 295829513.558921 | 8. 2311168.074679 | 15. 18056.000583 | | 2. 147914756.779460 | 9. 1155584.037340 | 16. 9028.000291 | | 3. 73957378.389730 | 10. 577792.018670 | 17. 4514.000146 | | 4. 36978689.194865 | 11. 288896.009335 | 18. 2257.000073 | | 5. 18489344.597432 | 12. 144448.004667 | 19. 1128.500036 | | 6. 9244672.298716 | 13. 72224.002334 | 20. 564.250018 | | 7. 4622336.149358 | 14. 36112.001167 | | ==== Custom ZoomLevels ==== While we have provided a predefined set of the most common scales there are times where you need to specify your own custom scales. There are two ways to specify your own scales for ZoomLevels depending on your intention. === Modifying Existing ZoomLevels === If you plan to make slight modifications to the existing scales but plan on having less then twenty ZoomLevels total then we suggest you simply modify the ZoomLevelSet. Using this method you change the Scale property on the ZoomLevels you want to adjust. If you want fewer then twenty scales then simply set the unused scales to zero. It is important to note that when you change the scales and set the new ZoomLevelSet to the associated FeatureLayers that you also ensure that map control snaps to the new ZoomLevel set. The process of doing this is described below under [[thinkgeo_style_guide#Third Party ZoomLevelSets (Google, Bing etc.)|Third Party ZoomLevelSets (Google, Bing etc.)]]. //The code below creates a ZoomLevelSet with effectivly three ZoomLevels. By setting the rest of the scales to zero we effectivly turn them off. We have left off the code to turn ZoomLevel 08-20 off to save space// // Change the scales on an existing ZoomLevelSet shapefileFeatureLayer.ZoomLevelSet.ZoomLevel01.Scale = 1000000; shapefileFeatureLayer.ZoomLevelSet.ZoomLevel02.Scale = 500000; shapefileFeatureLayer.ZoomLevelSet.ZoomLevel03.Scale = 250000; shapefileFeatureLayer.ZoomLevelSet.ZoomLevel05.Scale = 0; shapefileFeatureLayer.ZoomLevelSet.ZoomLevel06.Scale = 0; shapefileFeatureLayer.ZoomLevelSet.ZoomLevel07.Scale = 0; // Set the rest of the 20 ZoomLevels to zero as well if they are not needed === Creating New ZoomLevels === Creating new ZoomLevels allows you to create a near infinite number of ZoomLevels to have total control. In this method you create the number of ZoomLevels you want and you add these to the ZoomLevelSet.CustomZoomLevels collection. During the drawing process if we detect that you have populated the collection we will ignore the predefined ZoomLevels and use the items in the collection instead. It is important to note that when you use custom zoom levels that you ensure that map control snaps to the new ZoomLevel set. The process of doing this is described below under [[thinkgeo_style_guide#Third Party ZoomLevelSets (Google, Bing etc.)|Third Party ZoomLevelSets (Google, Bing etc.)]]. //The code below create three new ZoomLevels and adds them to the CustomZoomLevelSet. Normally you would use this technique to create more than twenty ZoomLevels for greater granularity. If, in the real world, we just wanted three ZoomLevels we would use the code above and simple modify the default ZoomLevelSet.// // Create the ZoomLevels ZoomLevel zoomLevel1 = new ZoomLevel(100000); ZoomLevel zoomLevel2 = new ZoomLevel(50000); ZoomLevel zoomLevel3 = new ZoomLevel(25000); // Create a new ZoomLevelSet ZoomLevelSet zoomLevelSet = new ZoomLevelSet(); // Add the ZoomLevels to the ZoomLevelSet zoomLevelSet.CustomZoomLevels.Add(zoomLevel1); zoomLevelSet.CustomZoomLevels.Add(zoomLevel2); zoomLevelSet.CustomZoomLevels.Add(zoomLevel3); // Apply the new ZoomLevelSet to your FeatureLayer shapefileFeatureLayer.ZoomLevelSet = zoomLevelSet; ==== Third Party ZoomLevelSets (Google, Bing etc.) ==== If you are using base maps images such as Bing Maps or Google Maps it is important that you choose the correct ZoomLevelSet for rendering and map snapping. Background map providers typically tile their data at set scales. This means that you want the map to snap to those scales to avoid distorting their images and to ensure your styles render relative to those ZoomLevels. We have provided below a number of ZoomLevelSets specific to the most popular data background map providers. There are usually two steps in setting up your ZoomLevelsSets. The first step is to ensure that every FeatureLayer that you use has the ZoomLevelSet that correspecnds to your background data. This will ensure that all of your styles break at the same scales as the background maps. The code below shows you an example of this. This step is universal across all of the Map Suite products as FeatureLayer is shared in the MapSuiteCore assembly. The snapping of the map control itself varies between Map Suite products so it is important to review the section below appropriate to the product you are using. **Popular ZoomLevelSets** {{section>12.0/apis/thinkgeo.core.zoomlevelset#inheritance_hierarchy}} **Map Suite Desktop for WPF** //Snap the map to the Bing Maps ZoomLevels //Place this code where you setup your map control WpfMap.ZoomLevelSet = new BingMapsZoomLevelSet(); //Use the scales for Bing Maps in FeatureLayer //Place this code where you setup each layer shapefileFeatureLayer.ZoomLevelSet = new BingMapsZoomLevelSet(); ===== Pens, Brushes & Fonts ===== Styles use pens, brushes and fonts to draw your data on the canvas. These tools can be used in various combinations to achieve interesting effects such as a LineStyle using two pens to portray a realistic road or a AreaStyle using a pen and a brush to show a blue river with a thing black outline for the bank. Each style may use different combinations of these tools so it is important to review the properties and constructors of each different style you choose to use. Be aware that many times pens or brushes may be optional or may have properties that control the order in which multiple tools draw. We modeled the many of these classes to be closely follow the API design of the GDI+ in the System.Drawing namespace. We created our own classes, by adding the 'geo' prefix, for three main reasons. The first was so that our API was portable to environment where GDI+ was not available such as Silverlight, WP7, PDF rendering etc. The second was that the GDI+ objects themselves held unmanaged resources so creating many of them was unmanageable and they were not easily serializable. The third is that we felt that many developers would be familiar with concepts of pens, brushes, etc. If you are familiar with the GDI+ classes then you should feel at home with our drawing classes below. ==== GeoPen ====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|Sample Pens}} \\ Sample Pens
The GeoPen class is used to draw lines of various thicknesses, colors, brush types, dash styles, and line caps. A simple pen may consist of simply a black color line with thickness of one. A complex symbol, for a railroad as an example, may use parallel offset lines with **Properties** {{section>12.0/apis/thinkgeo.core.geopen#Public Properties}} [[12.0/apis/thinkgeo.core.geopen|You can find the complete API documentation for the GeoPen here.]] ==== GeoBrush ==== GeoBrushes are typically to fill areas of polygons, ellipses, or rectangle however they can also be used to fill in thick lines on GeoPens. The GeoBrush class itself is abstract and as such cannot be used directly. The GeoBrush is used as a base class to create a family of various brushed that use different ways to fill an area. In most Map Suite APIs we use the abstract class for properties meaning that you can freely use any of the derived brushes. ==== GeoSolidBrush ====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|Sample Solid Brushes}}
The GeoSolidBrush is the easiest to use as it only takes a GeoColor for the fill. As simple as it is the GeoSolidBrush is the most widely used brushes since most items drawn to the screen only require a simple color. **Properties** {{section>12.0/apis/thinkgeo.core.geosolidbrush#Public Properties}} [[12.0/apis/thinkgeo.core.geosolidbrush|You can find the complete API documentation for the GeoSolidBrush here.]] ==== GeoHatchBrush ====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|Sample Hatch Brushes}}
The GeoHatchBrush allows you you to specify that area be filled with a pattern. The patterns are use colors from the background and foreground color properties. Some example patterns are below. * Percentage fills * Diagonal and vertical lines * ZigZags * Plaid * Diamonds * Grids * Bricks * [[12.0/apis/ThinkGeo.Core.GeoHatchStyle|Complete listing here...]] **Properties** {{section>12.0/apis/ThinkGeo.Core.GeoHatchBrush#Public Properties}} [[12.0/apis/ThinkGeo.Core.GeoHatchBrush|You can find the complete API documentation for the GeoHatchBrush here.]] ==== GeoTextureBrush ====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|Sample Texture Brushes}}
The GeoTextureBrush allows you to fill an are with an texture image. You can use this to represent natural effect such as water, sand, forest etc. It is also useful for high impact polygons fills such an area that is currently dangerous having a semitransparent warning tile. It is important to note that there are a number of ways the image tiles can be wrapped or flipped and you can find the details in [[12.0/apis/ThinkGeo.Core.GeoBrushWrapMode|GeoWrapMode]] property. **Properties** {{section>12.0/apis/thinkgeo.core.geotexturebrush#Public Properties}} [[12.0/apis/ThinkGeo.Core.GeoTextureBrush|You can find the complete API documentation for the GeoTextureBrush here.]] ==== GeoLinearGradientBrush ====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|Sample Linear Gradient Brushes}}
The GeoLinearGradientBrush allows you to fill in area going from one color to another color. You specify the angle and wrap mode as well to control precisely how it draws. **Properties** {{section>12.0/apis/ThinkGeo.Core.GeoLinearGradientBrush#Public Properties}} [[12.0/apis/ThinkGeo.Core.GeoLinearGradientBrush |You can find the complete API documentation for the GeoLinearGradientBrush here.]] ==== GeoFont ====
{{:Map Suite Services Edition Screenshot Gallery ChartsGraphs.png ?250|Sample GeoFonts}}
GeoFonts are primary used for labeling int he TextStyle. GeoFonts can also be used with the PointStyle to represent points as font members at various sizes, colors, and styles. **Properties** {{section>12.0/apis/ThinkGeo.Core.GeoFont#Public Properties}} [[12.0/apis/ThinkGeo.Core.GeoFont |You can find the complete API documentation for the GeoFont here.]] ===== Simple Styles ===== ==== AreaStyle ==== ==== LineStyle ==== ==== TextStyle ==== ===== Conditional Styles ===== ==== ClassBreakStyle ==== ==== ValueStyle ==== ==== RegexStyle ==== ===== Advanced Styles ===== ==== ClusterPointStyle ==== ==== DotDensityStyle ==== ==== GradientStyle ==== ==== HeatStyle ==== ==== HueFamilyAreaStyle ==== ==== QualityFamilyAreaStyle ==== ==== IconStyle ==== ==== IconValueStyle ==== ===== Using Tabular Data ===== ==== Concatenating Columns ==== ==== Custom External Data ==== ===== Creating Custom Styles ===== ==== Why Create a Custom Style? ==== ==== Anatomy of a Abstract Style Class ==== Each style in Map Suite inherits from the [[ThinkGeo.MapSuite.Core.Style|Style]] abstract base class. The base class define a simple set of functionality that is typically required by a style and beyond that it is a requirement of the subclass to provide additional functionality. ==== Name ==== The name property is reserved for your use and is not used by the system. You could use it, as an example, to store the style's name if you wanted to build a legend. ==== IsActive ==== This property determines if the style will be used. If you set the style IsActive to false then it will not draw any records. We suggest that if you want to control the drawing of a particular layer then you use the Layer.IsActive and not the Style.IsActive as using the Layer.IsActive is more efficient and uses less resource in the scenario you want to stop a layer from drawing. ==== Draw ==== This method is the concrete wrapper for the abstract method DrawCore. As the wrapper it will call the DrawCore method and do any other tasks such as raise events etc. ==== DrawCore ==== In this method, we take the shapes that are passed in and draw them on the provided canvas. Each style, based on its properties, may draw each shape differently. ==== RequiredColumnNames ==== ==== GetRequiredColumnNames ==== This method is the concrete wrapper for the abstract method GetRequiredColumnNamesCore . As the wrapper it will call the GetRequiredColumnNamesCore method and do any other tasks such as raise events etc. ==== GetRequiredColumnNamesCore ==== ==== DrawSample ==== ==== DrawSampleCore ==== ===== Sample ===== ===== Additional Resources ===== ==== Video ====
I need to consider how to transclude this item from one of the main pages.
^
Topic
^ Attachment ^ Description ^ | Creating Custom Styles | [[http://download.thinkgeo.com/Webinars/ExtendingMapSuiteCreatingCustomStyles.wmv|Video]]\\ \\ [[http://download.thinkgeo.com/Webinars/MapSuiteCreatingCustomStyles.ppt|Presentation]]\\ \\ [[http://download.thinkgeo.com/Webinars/MapSuiteCustomStylesQA.doc|Q&A]]\\ \\ [[http://download.thinkgeo.com/Webinars/ExtendingMapSuiteStyle.zip|Sample]] | This informative, in-depth webinar explores the limitless possibilities for creating your own custom styles with Map Suite. Take a look at the video presentation and download the sample project with source code in both C# and VB.NET. |