====== Source Code ServicesEditionSample CachedValueStyle CS 090728.zip ======
====CachedValueStyle.cs====
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace CachedValueStyle
{
// Mark the class Serializable so that it workes in SQL Server state
// and in every serialization context
[Serializable]
public class CachedValueStyle : Style
{
private string columnName;
private Dictionary valueItems = new Dictionary();
private Dictionary valuesCache = new Dictionary();
public CachedValueStyle()
: this(string.Empty, new Dictionary())
{ }
public CachedValueStyle(string columnName, Dictionary valueItems)
{
this.columnName = columnName;
this.valueItems = valueItems;
}
public string ColumnName
{
get { return columnName; }
set { columnName = value; }
}
// We use a dictionary now instead of a collection to make lookups faster.
public Dictionary ValueItems
{
get { return valueItems; }
}
// Here you can pre-load all of the values by feature Id.
// The key is the Feature.Id and the value is the value to match the
// value on.
public Dictionary ValuesCache
{
get { return valuesCache; }
}
protected override void DrawCore(IEnumerable features, GeoCanvas canvas, Collection labelsInThisLayer, Collection labelsInAllLayers)
{
foreach (Feature feature in features)
{
string fieldValue = string.Empty;
// If we have items field value in the cache then let's use them!
// If not then get the value from the feature's column values
if (valuesCache.Count == 0)
{
fieldValue = feature.ColumnValues[columnName].Trim();
}
else
{
if (!ValuesCache.TryGetValue(feature.Id, out fieldValue))
{
fieldValue = string.Empty;
}
}
ValueItem valueItem = null;
// Check if the there is a value item in the dictionary that matches
// our field value.
if (valueItems.ContainsKey(fieldValue))
{
valueItem = valueItems[fieldValue];
}
// If we cannot find a matcing value item in the collection do not draw anything.
if (valueItem != null)
{
// Call the draw on all of the default styles of the value item and also
// check if there are custom styles
Feature[] tmpFeatures = new Feature[1] { feature };
if (valueItem.CustomStyles.Count == 0)
{
valueItem.DefaultAreaStyle.Draw(tmpFeatures, canvas, labelsInThisLayer, labelsInAllLayers);
valueItem.DefaultLineStyle.Draw(tmpFeatures, canvas, labelsInThisLayer, labelsInAllLayers);
valueItem.DefaultPointStyle.Draw(tmpFeatures, canvas, labelsInThisLayer, labelsInAllLayers);
valueItem.DefaultTextStyle.Draw(tmpFeatures, canvas, labelsInThisLayer, labelsInAllLayers);
}
else
{
foreach (Style style in valueItem.CustomStyles)
{
style.Draw(tmpFeatures, canvas, labelsInThisLayer, labelsInAllLayers);
}
}
}
}
}
protected override Collection GetRequiredColumnNamesCore()
{
Collection requiredFieldNames = new Collection();
// If we have provided cached values then there is no need to fetch the
// column from our feature source.
if (valuesCache.Count == 0)
{
requiredFieldNames.Add(columnName);
}
foreach (ValueItem valueItem in valueItems.Values)
{
// Check if we need any columns from custom styles
foreach (Style style in valueItem.CustomStyles)
{
Collection tmpCollection = style.GetRequiredColumnNames();
foreach (string name in tmpCollection)
{
if (!requiredFieldNames.Contains(name))
{
requiredFieldNames.Add(name);
}
}
}
// Check if we need any columns from the DefaultTextStyle
Collection fieldsInTextStyle = valueItem.DefaultTextStyle.GetRequiredColumnNames();
foreach (string fieldName in fieldsInTextStyle)
{
if (!requiredFieldNames.Contains(fieldName))
{
requiredFieldNames.Add(fieldName);
}
}
// Check if we need any columns from the DefaultPointStyle
Collection fieldsInPointStyle = valueItem.DefaultPointStyle.GetRequiredColumnNames();
foreach (string fieldName in fieldsInPointStyle)
{
if (!requiredFieldNames.Contains(fieldName))
{
requiredFieldNames.Add(fieldName);
}
}
// Check if we need any columns from the DefaultLineStyle
Collection fieldsInLineStyle = valueItem.DefaultLineStyle.GetRequiredColumnNames();
foreach (string fieldName in fieldsInLineStyle)
{
if (!requiredFieldNames.Contains(fieldName))
{
requiredFieldNames.Add(fieldName);
}
}
// Check if we need any columns from the DefaultAreaStyle
Collection fieldsInAreaStyle = valueItem.DefaultAreaStyle.GetRequiredColumnNames();
foreach (string fieldName in fieldsInAreaStyle)
{
if (!requiredFieldNames.Contains(fieldName))
{
requiredFieldNames.Add(fieldName);
}
}
}
return requiredFieldNames;
}
}
}
====Program.cs====
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace CachedValueStyle
{
static class Program
{
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new TestForm());
}
}
}
====TestForm.cs====
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace CachedValueStyle
{
public partial class TestForm : Form
{
private MapEngine mapEngine = new MapEngine();
private Bitmap bitmap = null;
private ShapeFileFeatureLayer worldLayer = null;
public TestForm()
{
InitializeComponent();
}
private void TestForm_Load(object sender, EventArgs e)
{
// Set the full extent and the background color
mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height);
mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean);
// Add the static layers to the MapEngine
worldLayer = new ShapeFileFeatureLayer(@"..\..\Data\Countries02.shp", ShapeFileReadWriteMode.ReadOnly);
worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1;
worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
mapEngine.StaticLayers.Add("WorldLayer", worldLayer);
ShapeFileFeatureLayer worldCapitalsLayer = new ShapeFileFeatureLayer(@"..\..\Data\WorldCapitals.shp", ShapeFileReadWriteMode.ReadOnly);
CachedValueStyle cachedValueStyle = new CachedValueStyle();
cachedValueStyle.ColumnName = "pop_rank";
// Build the cache. Normally this would come from SQl or someplace else
worldCapitalsLayer.Open();
Collection features = worldCapitalsLayer.FeatureSource.GetAllFeatures(new string[] { "pop_rank" });
foreach (Feature feature in features)
{
cachedValueStyle.ValuesCache.Add(feature.Id, feature.ColumnValues["pop_rank"].ToString());
}
worldCapitalsLayer.Close();
cachedValueStyle.ValueItems.Add("1", new ValueItem("1", PointStyles.Capital1));
cachedValueStyle.ValueItems.Add("2", new ValueItem("2", PointStyles.Capital2));
cachedValueStyle.ValueItems.Add("3", new ValueItem("3", PointStyles.Capital3));
worldCapitalsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
worldCapitalsLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(cachedValueStyle);
worldCapitalsLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
mapEngine.StaticLayers.Add("WorldCapitals", worldCapitalsLayer);
DrawImage();
}
private void DrawImage()
{
if (bitmap != null) { bitmap.Dispose(); }
bitmap = new Bitmap(Map.Width, Map.Height);
mapEngine.OpenAllLayers();
mapEngine.DrawStaticLayers(bitmap, GeographyUnit.DecimalDegree);
mapEngine.DrawDynamicLayers(bitmap, GeographyUnit.DecimalDegree);
mapEngine.CloseAllLayers();
Map.Image = bitmap;
}
private void ToolBar_ButtonClick(object sender, ToolBarButtonClickEventArgs e)
{
switch (e.Button.Tag.ToString())
{
case "Zoom In":
mapEngine.CurrentExtent.ScaleDown(50);
break;
case "Zoom Out":
mapEngine.CurrentExtent.ScaleUp(50);
break;
case "Full Extent":
mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-180.0, 83.0, 180.0, -90.0), Map.Width, Map.Height);
break;
case "Pan Left":
mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Left, 20);
break;
case "Pan Right":
mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Right, 20);
break;
case "Pan Up":
mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Up, 20);
break;
case "Pan Down":
mapEngine.CurrentExtent = ExtentHelper.Pan(mapEngine.CurrentExtent, PanDirection.Down, 20);
break;
default:
break;
}
DrawImage();
}
private void btnClose_Click(object sender, EventArgs e)
{
this.Close();
}
}
}