ThinkGeo.com    |     Documentation    |     Premium Support

Issues with transactions relating to styles and drawstatic layers

Posting on behalf of a customer:


Hi,


We have found the following issues with transactions relating to styles and drawstatic layers.
 
1)      If we have a feature on a map and we start a transaction and move that feature in the transaction without committing it we have a redraw issue with the style stack. That is if we have a text style and an area style the text style does not redraw (or maybe it draws at the incorrect layer) so we no longer see the text. If we commit the transaction before redraw everything is fine.
 
2)      We have a classbreak style on a layer. We start a transaction and move an object on the layer we get an exception thrown (see stack trace). If we commit the transaction before calling drawstatic layers, everything is fine.
 
Stack Trace
 
  at System.ThrowHelper.ThrowKeyNotFoundException()
  at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
  at ThinkGeo.MapSuite.Core.ClassBreakStyle.DrawCore(IEnumerable`1 features, GeoCanvas canvas, Collection`1 labelsInThisLayer, Collection`1 labelsInAllLayers)
  at ThinkGeo.MapSuite.Core.Style.Draw(IEnumerable`1 features, GeoCanvas canvas, Collection`1 labelsInThisLayer, Collection`1 labelsInAllLayers)
  at ThinkGeo.MapSuite.Core.ZoomLevel.DrawCore(GeoCanvas canvas, IEnumerable`1 features, Collection`1 currentLayerLabels, Collection`1 allLayerLabels)
  at ThinkGeo.MapSuite.Core.ZoomLevel.Draw(GeoCanvas canvas, IEnumerable`1 features, Collection`1 currentLayerLabels, Collection`1 allLayerLabels)
  at ThinkGeo.MapSuite.Core.VectorLayer.DrawCore(GeoCanvas canvas, GeographyUnit mapUnit, Collection`1 labelsInAllLayers)
  at ThinkGeo.MapSuite.Core.Layer.Draw(GeoCanvas canvas, GeographyUnit mapUnit, Collection`1 labelsInAllLayers)
  at ThinkGeo.MapSuite.Core.MapEngine.x2a77eb6032362d14(Layer xa1d467ddfe47b178, GeographyUnit x23bf990a35721448, Object x65e9a9c6c5e41d97)
  at ThinkGeo.MapSuite.Core.MapEngine.x68ddaa28fe467d0a(IEnumerable`1 xbc8a920bd17eefdf, Bitmap xe10299f210688dae, GeographyUnit x23bf990a35721448, Boolean xa872403da055b02a)
  at ThinkGeo.MapSuite.Core.MapEngine.DrawStaticLayers(Bitmap gdiPlusBitmap, GeographyUnit mapUnit)
 
 
Oh, can you tell me what the difference is between a dynamic and static layer? I have assumed (hopefully correctly) that a dynamic layer would be used to represent a layer that is refreshed periodically (like to display a moving vehicle on a road). While a static layer displays data that changes infrequently or not at all.

Thanks



We can recreate the issue when updating a feature which does not have the required columns. Here we take an example to see how it happened.
 
Let’s say I have a country data with 2 columns “Name” and “Population”. I use ClassBreakStyle to render the countries differently bases on their population, the larger population it has, the darker the color is.
 
Now I want to update the record from “United Kingdom” to “Great Britain”. What I need to do is to create a new feature with the new column data, and replace the existing one. The code usually like this:
 
---------------------------------------------------
Dictionary newColumnData = new Dictionary< string, string >();
newColumnData.Add(“Name”, “Great Britain”);
……
featureSource.UpdateFeature(new Feature(newShape, newColumnData));
……
DrawMap()
 ----------------------------------------------------
 
However, the above code throws an exception when drawing. That’s because map engine has no idea how to draw the feature, as there is no “Population” column which is REQUIRED for ClassBreakStyle to render the map. Before commit, the new features will stay in an editing buffer, the MapEngine will not check the shape file to get the “lost data” if the buffer data is not completed.
 
Why it goes well when we commit it first and then draw the map? Because after committing, map engine will check the shape file, instead of the objects in editing buffer, to see how to render. The “Population” column is legacy in the shape file, so map engine has no problem to get that info and render based on that.
 
To make it a bit further, can we guess what the result will be if we call AddFeature(newFeature)? If the parameter newFeature doesn’t include the “Population” column, no matter the transaction has been committed or not, it will always throw that exception. That’s because even the changes committed to the shape file, map engine still cannot find enough info for the rendering if we didn’t add them.  
 
About Static layer and Dynamic Layer, you have a good understanding. One small supplementary point about the detail implementation (though I think you already know) is that Dynamic Layers are always drawn on top of the static Layers (if you are using MapEngine to draw). Also, we can draw static Layers or DynamicLayers separately, which let us refresh the only part which might change to improve the performance.
  
 
We have another kind of layer: AdornmentLayer, which is used for things that draw on top of the map such as scale lines, scale bars, north facing arrows and other static items. Currently as we are in beta there is no documentation as of yet. We have a sample in “Moving around the Map” -> “CreateAScalelineAdornmentLayer” showing how to use an existing AdornmentLayer. Please see the post Here for more information.

Ben.