User Tools

Site Tools


source_code_mvcedition_projecttemplates_usdemographicmap_cs.zip

Source Code MvcEdition ProjectTemplates UsDemographicMap CS.zip

DefaultController.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Xml.Linq;
using ThinkGeo.MapSuite.Core;
using ThinkGeo.MapSuite.MvcEdition;
using ThinkGeo.MapSuite.USDemographicMap;
namespace MapSuiteUsDemographicMap.Controllers
{
    public class DefaultController : Controller
    {
        public ActionResult Index()
        {
            // Initialize map
            Map map = new Map("Map1", new System.Web.UI.WebControls.Unit(100, System.Web.UI.WebControls.UnitType.Percentage), new System.Web.UI.WebControls.Unit(100, System.Web.UI.WebControls.UnitType.Percentage));
            InitializeMap(map);
            // Load categories from xml file
            ViewData["Categories"] = LoadCategories();
            return View(map);
        }
        [MapActionFilter]
        public string IdentifyFeature(Map map, GeoCollection<object> args)
        {
            string callbackResult = string.Empty;
            if (map != null)
            {
                JsonCallbackRequest callbackRequest = JsonSerializer.Deserialize<JsonCallbackRequest>(args[0].ToString());
                callbackResult = GetIdentifiedFeatureInfo(callbackRequest, map);
            }
            return callbackResult;
        }
        [MapActionFilter]
        public string ApplyStyle(Map map, GeoCollection<object> args)
        {
            string callbackResult = string.Empty;
            if (map != null)
            {
                // Replace the "$=" with ">=", because the ">=" is not allowed in AJAX Content
                string jsonParameters = args[0].ToString();
                if (jsonParameters.Contains("$"))
                {
                    jsonParameters = jsonParameters.Replace("$", ">=");
                }
                JsonCallbackRequest callbackRequest = JsonSerializer.Deserialize<JsonCallbackRequest>(jsonParameters);
                callbackResult = UpdateMapAndLegend(callbackRequest, map).ToString();
            }
            return callbackResult;
        }
        private string GetIdentifiedFeatureInfo(JsonCallbackRequest callbackRequest, Map map)
        {
            // Get the requested sub-categories
            Category selectedCategory = null;
            Collection<CategoryItem> selectedCategoryItems = new Collection<CategoryItem>();
            if (callbackRequest.StyleBuildType == DemographicStyleBuilderType.PieChart)
            {
                selectedCategoryItems = GetCategoryItemByAlias(callbackRequest.SelectedCategoryItems, ref selectedCategory);
            }
            else
            {
                selectedCategoryItems = GetCategoryItemByAlias(new Collection<string>() { callbackRequest.RequestColumnAlias }, ref selectedCategory);
            }
            // Get the selected columns
            Collection<string> selectedColumns = new Collection<string>();
            foreach (CategoryItem categoryItem in selectedCategoryItems)
            {
                selectedColumns.Add(categoryItem.ColumnName);
            }
            selectedColumns.Add("Name");
            // Find the identified feature with specified columns
            ShapeFileFeatureLayer statesLayer = map.DynamicOverlay.Layers["usStatesLayer"] as ShapeFileFeatureLayer;
            statesLayer.Open();
            Feature identifiedFeature = statesLayer.FeatureSource.GetFeatureById(callbackRequest.SelectedFeatureId, selectedColumns);
            // Format the inner-html of the popup
            StringBuilder popupHtml = new StringBuilder("<table>");
            popupHtml.Append(string.Format("<tr><td class='popupTitle'>{0}</td></tr>", identifiedFeature.ColumnValues["Name"]));
            popupHtml.Append("<tr><td><div class='hrLine'></div></td></tr>");
            for (int i = 0; i < selectedColumns.Count - 1; i++)
            {
                string formatedString = DemographicStyleTextFormatter.GetFormatedString(selectedColumns[i], double.Parse(identifiedFeature.ColumnValues[selectedColumns[i]));
                popupHtml.Append(string.Format("<tr class='popupText'><td>{0}</td></tr>", formatedString));
            }
            popupHtml.Append("</table>");
            return popupHtml.ToString();
        }
        private bool UpdateMapAndLegend(JsonCallbackRequest callbackRequest, Map map)
        {
            // Get the requested sub-categories
            Category selectedCategory = null;
            Collection<CategoryItem> selectedCategoryItems = new Collection<CategoryItem>();
            if (callbackRequest.StyleBuildType == DemographicStyleBuilderType.PieChart)
            {
                selectedCategoryItems = GetCategoryItemByAlias(callbackRequest.SelectedCategoryItems, ref selectedCategory);
            }
            else
            {
                selectedCategoryItems = GetCategoryItemByAlias(new Collection<string>() { callbackRequest.RequestColumnAlias }, ref selectedCategory);
            }
            DemographicStyleBuilder demographicStyle = null;
            switch (callbackRequest.StyleBuildType)
            {
                case DemographicStyleBuilderType.PieChart:
                    demographicStyle = new PieChartDemographicStyleBuilder();
                    foreach (CategoryItem categoryItem in selectedCategoryItems)
                    {
                        ((PieChartDemographicStyleBuilder)demographicStyle).SelectedColumnAliases.Add(categoryItem.Alias);
                    }
                    if (!string.IsNullOrEmpty(callbackRequest.StartColor))
                    {
                        ((PieChartDemographicStyleBuilder)demographicStyle).Color = GeoColor.FromHtml(callbackRequest.StartColor);
                    }
                    break;
                case DemographicStyleBuilderType.Thematic:
                    demographicStyle = new ThematicDemographicStyleBuilder();
                    if (!string.IsNullOrEmpty(callbackRequest.StartColor))
                    {
                        ((ThematicDemographicStyleBuilder)demographicStyle).StartColor = GeoColor.FromHtml(callbackRequest.StartColor);
                    }
                    if (!string.IsNullOrEmpty(callbackRequest.EndColor))
                    {
                        ((ThematicDemographicStyleBuilder)demographicStyle).EndColor = GeoColor.FromHtml(callbackRequest.EndColor);
                    }
                    if (!string.IsNullOrEmpty(callbackRequest.ColorWheelDirection))
                    {
                        ((ThematicDemographicStyleBuilder)demographicStyle).ColorWheelDirection = callbackRequest.ColorWheelDirection.Equals("Clockwise") ? ColorWheelDirection.Clockwise : ColorWheelDirection.CounterClockwise;
                    }
                    break;
                case DemographicStyleBuilderType.DotDensity:
                    demographicStyle = new DotDensityDemographicStyleBuilder();
                    if (!string.IsNullOrEmpty(callbackRequest.StartColor))
                    {
                        ((DotDensityDemographicStyleBuilder)demographicStyle).Color = GeoColor.FromHtml(callbackRequest.StartColor);
                    }
                    if (callbackRequest.SliderValue > 0)
                    {
                        ((DotDensityDemographicStyleBuilder)demographicStyle).DotDensityValue = 50 * (callbackRequest.SliderValue / 3.0);
                    }
                    break;
                case DemographicStyleBuilderType.ValueCircle:
                    demographicStyle = new ValueCircleDemographicStyleBuilder();
                    if (!string.IsNullOrEmpty(callbackRequest.StartColor))
                    {
                        ((ValueCircleDemographicStyleBuilder)demographicStyle).Color = GeoColor.FromHtml(callbackRequest.StartColor);
                    }
                    if (callbackRequest.SliderValue > 0)
                    {
                        ((ValueCircleDemographicStyleBuilder)demographicStyle).RadiusRatio = callbackRequest.SliderValue / 3.0;
                    }
                    break;
                default:
                    break;
            }
            foreach (CategoryItem categoryItem in selectedCategoryItems)
            {
                demographicStyle.SelectedColumns.Add(categoryItem.ColumnName);
            }
            ShapeFileFeatureLayer statesLayer = map.DynamicOverlay.Layers["usStatesLayer"] as ShapeFileFeatureLayer;
            statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Clear();
            ThinkGeo.MapSuite.Core.Style selectedStyle = demographicStyle.GetStyle(statesLayer.FeatureSource);
            statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(selectedStyle);
            statesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            map.DynamicOverlay.Redraw();
            // update the legend based on the selected style
            UpdateLegend(demographicStyle, map);
            return true;
        }
        private Collection<CategoryItem> GetCategoryItemByAlias(Collection<string> requestAliases, ref Category queriedCategory)
        {
            Collection<CategoryItem> queriedItems = new Collection<CategoryItem>();
            Dictionary<string, Category> categories = LoadCategories();
            foreach (var category in categories)
            {
                foreach (var item in category.Value.Items)
                {
                    if (requestAliases.Contains(item.Alias))
                    {
                        queriedCategory = category.Value;
                        queriedItems.Add(item);
                    }
                }
            }
            return queriedItems;
        }
        private void InitializeMap(Map map)
        {
            map.MapUnit = GeographyUnit.DecimalDegree;
            map.MapTools.Logo.Enabled = true;
            map.MapBackground.BackgroundBrush = new GeoSolidBrush(GeoColor.FromHtml("#E5E3DF"));
            map.CurrentExtent = new RectangleShape(-128.17864375, 56.9286546875, -69.11614375, 20.1903734375);
            // base map layers
            WorldMapKitWmsWebOverlay worldMapKitOverlay = new WorldMapKitWmsWebOverlay();
            map.CustomOverlays.Add(worldMapKitOverlay);
            // us states layer
            ShapeFileFeatureLayer statesLayer = new ShapeFileFeatureLayer(Server.MapPath(ConfigurationManager.AppSettings["UsShapefilePath"]));
            ThematicDemographicStyleBuilder selectedStyle = new ThematicDemographicStyleBuilder(new Collection<string>() { "Population" });
            statesLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(selectedStyle.GetStyle(statesLayer.FeatureSource));
            statesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20;
            map.DynamicOverlay.Layers.Add("usStatesLayer", statesLayer);
            // highlight layers
            map.HighlightOverlay.HighlightStyle = new FeatureOverlayStyle(GeoColor.FromArgb(150, GeoColor.FromHtml("#449FBC")), GeoColor.FromHtml("#014576"), 1);
            map.HighlightOverlay.Style = new FeatureOverlayStyle(GeoColor.SimpleColors.Transparent, GeoColor.SimpleColors.Transparent, 0);
            statesLayer.Open();
            foreach (Feature feature in statesLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.NoColumns))
            {
                map.HighlightOverlay.Features.Add(feature.Id, feature);
            }
            statesLayer.Close();
            // Add hover-popup
            CloudPopup featureinfoPopup = new CloudPopup("featureInfoPopup", new PointShape(-300, -200), "State Info"); // make the popup out of map view temporarily
            featureinfoPopup.AutoSize = true;
            map.Popups.Add(featureinfoPopup);
            // Add Legend adorment overlay
            LegendAdornmentLayer legendAdornmentLayer = new LegendAdornmentLayer();
            legendAdornmentLayer.Location = AdornmentLocation.LowerLeft;
            legendAdornmentLayer.XOffsetInPixel = 10;
            legendAdornmentLayer.Title = new LegendItem();
            legendAdornmentLayer.Title.ImageJustificationMode = LegendImageJustificationMode.JustifyImageRight;
            legendAdornmentLayer.Title.TopPadding = 10;
            legendAdornmentLayer.Title.BottomPadding = 10;
            legendAdornmentLayer.Title.TextStyle = new TextStyle("Population", new GeoFont("Segoe UI", 12), new GeoSolidBrush(GeoColor.SimpleColors.Black));
            map.AdornmentOverlay.Layers.Add(legendAdornmentLayer);
            ThematicDemographicStyleBuilder initDemographicStyle = new ThematicDemographicStyleBuilder(new Collection<string>() { "Population" });
            UpdateLegend(initDemographicStyle, map);
        }
        private void UpdateLegend(DemographicStyleBuilder styleBuilder, Map map)
        {
            LegendAdornmentLayer legendAdornmentLayer = map.AdornmentOverlay.Layers[0] as LegendAdornmentLayer;
            legendAdornmentLayer.LegendItems.Clear();
            if (styleBuilder is ThematicDemographicStyleBuilder)
            {
                AddThematicLegendItems(styleBuilder, legendAdornmentLayer, map);
            }
            else if (styleBuilder is DotDensityDemographicStyleBuilder)
            {
                AddDotDensityLegendItems(styleBuilder, legendAdornmentLayer, map);
            }
            else if (styleBuilder is ValueCircleDemographicStyleBuilder)
            {
                AddValueCircleLegendItems(styleBuilder, legendAdornmentLayer, map);
            }
            else if (styleBuilder is PieChartDemographicStyleBuilder)
            {
                AddPieGraphLegendItems(styleBuilder, legendAdornmentLayer, map);
            }
            legendAdornmentLayer.ContentResizeMode = LegendContentResizeMode.Fixed;
            legendAdornmentLayer.Height = GetLegendHeight(legendAdornmentLayer);
            legendAdornmentLayer.Width = GetLegendWidth(legendAdornmentLayer);
        }
        private void AddPieGraphLegendItems(DemographicStyleBuilder styleBuilder, LegendAdornmentLayer legendAdornmentLayer, Map map)
        {
            ShapeFileFeatureLayer statesLayer = map.DynamicOverlay.Layers["usStatesLayer"] as ShapeFileFeatureLayer;
            PieZedGraphStyle zedGraphStyle = (PieZedGraphStyle)styleBuilder.GetStyle(statesLayer.FeatureSource);
            foreach (KeyValuePair<string, GeoColor> item in zedGraphStyle.PieSlices)
            {
                LegendItem legendItem = new LegendItem();
                legendItem.ImageWidth = 20;
                legendItem.TextRightPadding = 5;
                legendItem.RightPadding = 5;
                legendItem.ImageStyle = new AreaStyle(new GeoSolidBrush(item.Value));
                legendItem.TextStyle = new TextStyle(item.Key, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));
                legendAdornmentLayer.LegendItems.Add(legendItem);
            }
        }
        private void AddValueCircleLegendItems(DemographicStyleBuilder styleBuilder, LegendAdornmentLayer legendAdornmentLayer, Map map)
        {
            ShapeFileFeatureLayer statesLayer = map.DynamicOverlay.Layers["usStatesLayer"] as ShapeFileFeatureLayer;
            ValueCircleStyle valueCircleStyle = (ValueCircleStyle)styleBuilder.GetStyle(statesLayer.FeatureSource);
            int[] circleAreas = new int[] { 160, 320, 640, 1280 };
            foreach (int circleArea in circleAreas)
            {
                LegendItem legendItem = new LegendItem();
                double radius = Math.Sqrt(circleArea / Math.PI);
                legendItem.ImageStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(valueCircleStyle.InnerColor), new GeoPen(new GeoSolidBrush(valueCircleStyle.OuterColor)), (int)(radius * 2));
                AreaStyle maskStyle = new AreaStyle(new GeoPen(GeoColor.StandardColors.LightGray, 1), new GeoSolidBrush(GeoColor.SimpleColors.Transparent));
                legendItem.ImageMask = maskStyle;
                legendItem.ImageWidth = 48;
                legendItem.TextTopPadding = 16;
                legendItem.TextRightPadding = 5;
                legendItem.BottomPadding = 16;
                legendItem.TopPadding = 16;
                legendItem.RightPadding = 5;
                double drawingRadius = circleArea / valueCircleStyle.DrawingRadiusRatio * valueCircleStyle.BasedScale / valueCircleStyle.DefaultZoomLevel.Scale;
                double ratio = (valueCircleStyle.MaxValidValue - valueCircleStyle.MinValidValue) / (valueCircleStyle.MaxCircleAreaInDefaultZoomLevel - valueCircleStyle.MinCircleAreaInDefaultZoomLevel);
                double resultValue = (drawingRadius - valueCircleStyle.MinCircleAreaInDefaultZoomLevel) * ratio + valueCircleStyle.MinValidValue;
                string text = DemographicStyleTextFormatter.GetFormatedStringForLegendItem(valueCircleStyle.ColumnName, resultValue);
                legendItem.TextStyle = new TextStyle(text, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));
                legendAdornmentLayer.LegendItems.Add(legendItem);
            }
        }
        private void AddDotDensityLegendItems(DemographicStyleBuilder styleBuilder, LegendAdornmentLayer legendAdornmentLayer, Map map)
        {
            ShapeFileFeatureLayer statesLayer = map.DynamicOverlay.Layers["usStatesLayer"] as ShapeFileFeatureLayer;
            CustomDotDensityStyle dotDensityStyle = (CustomDotDensityStyle)styleBuilder.GetStyle(statesLayer.FeatureSource);
            int[] pointCounts = new int[] { 5, 10, 20, 50 };
            foreach (int pointCount in pointCounts)
            {
                LegendItem legendItem = new LegendItem();
                legendItem.ImageMask = new AreaStyle(new GeoPen(GeoColor.StandardColors.LightGray, 1), new GeoSolidBrush(GeoColor.SimpleColors.Transparent));
                legendItem.ImageWidth = 48;
                legendItem.TextTopPadding = 16;
                legendItem.TextRightPadding = 5;
                legendItem.BottomPadding = 16;
                legendItem.TopPadding = 16;
                legendItem.RightPadding = 5;
                CustomDotDensityStyle legendDotDensityStyle = (CustomDotDensityStyle)dotDensityStyle.CloneDeep();
                legendDotDensityStyle.DrawingPointsNumber = pointCount;
                legendItem.ImageStyle = legendDotDensityStyle;
                string text = string.Format(CultureInfo.InvariantCulture, "{0:0.####}", DemographicStyleTextFormatter.GetFormatedStringForLegendItem(dotDensityStyle.ColumnName, (pointCount / dotDensityStyle.PointToValueRatio)));
                legendItem.TextStyle = new TextStyle(text, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));
                legendAdornmentLayer.LegendItems.Add(legendItem);
            }
        }
        private void AddThematicLegendItems(DemographicStyleBuilder styleBuilder, LegendAdornmentLayer legendAdornmentLayer, Map map)
        {
            ShapeFileFeatureLayer statesLayer = map.DynamicOverlay.Layers["usStatesLayer"] as ShapeFileFeatureLayer;
            ClassBreakStyle thematicStyle = (ClassBreakStyle)styleBuilder.GetStyle(statesLayer.FeatureSource);
            for (int i = 0; i < thematicStyle.ClassBreaks.Count; i++)
            {
                LegendItem legendItem = new LegendItem();
                if (i < thematicStyle.ClassBreaks.Count)
                {
                    legendItem.ImageStyle = thematicStyle.ClassBreaks[i].DefaultAreaStyle;
                    legendItem.ImageWidth = 20;
                    legendItem.TextRightPadding = 5;
                    legendItem.RightPadding = 5;
                    string text = string.Empty;
                    if (i != thematicStyle.ClassBreaks.Count - 1)
                    {
                        text = string.Format("{0:#,0.####} ~ {1:#,0.####}",
                            DemographicStyleTextFormatter.GetFormatedStringForLegendItem(thematicStyle.ColumnName, thematicStyle.ClassBreaks[i].Value),
                            DemographicStyleTextFormatter.GetFormatedStringForLegendItem(thematicStyle.ColumnName, thematicStyle.ClassBreaks[i|+ 1].Value));
                    }
                    else
                    {
                        text = string.Format("> {0:#,0.####}",
                            DemographicStyleTextFormatter.GetFormatedStringForLegendItem(thematicStyle.ColumnName, thematicStyle.ClassBreaks[i].Value));
                    }
                    legendItem.TextStyle = new TextStyle(text, new GeoFont("Segoe UI", 10), new GeoSolidBrush(GeoColor.SimpleColors.Black));
                }
                legendAdornmentLayer.LegendItems.Add(legendItem);
            }
        }
        public float GetLegendWidth(LegendAdornmentLayer legendAdornmentLayer)
        {
            GdiPlusGeoCanvas gdiPlusGeoCanvas = new GdiPlusGeoCanvas();
            LegendItem title = legendAdornmentLayer.Title;
            float width = gdiPlusGeoCanvas.MeasureText(title.TextStyle.TextColumnName, new GeoFont("Segoe UI", 12)).Width
               + title.ImageWidth + title.ImageRightPadding + title.ImageLeftPadding + title.TextRightPadding + title.TextLeftPadding + title.LeftPadding + title.RightPadding;
            foreach (LegendItem legendItem in legendAdornmentLayer.LegendItems)
            {
                float legendItemWidth = gdiPlusGeoCanvas.MeasureText(legendItem.TextStyle.TextColumnName, new GeoFont("Segoe UI", 10)).Width
                    + legendItem.ImageWidth + legendItem.ImageRightPadding + legendItem.ImageLeftPadding + legendItem.TextRightPadding + legendItem.TextLeftPadding + legendItem.LeftPadding + legendItem.RightPadding;
                if (width < legendItemWidth)
                {
                    width = legendItemWidth;
                }
            }
            return width;
        }
        public float GetLegendHeight(LegendAdornmentLayer legendAdornmentLayer)
        {
            GdiPlusGeoCanvas gdiPlusGeoCanvas = new GdiPlusGeoCanvas();
            LegendItem title = legendAdornmentLayer.Title;
            float legendHeight = Math.Max(gdiPlusGeoCanvas.MeasureText(title.TextStyle.TextColumnName, new GeoFont("Segoe UI", 12)).Height, title.ImageHeight);
            legendHeight = Math.Max(legendHeight, title.Height);
            float height = legendHeight + Math.Max(title.ImageTopPadding, title.TextTopPadding) + title.TopPadding + Math.Max(title.ImageBottomPadding, title.TextBottomPadding) + title.BottomPadding;
            foreach (LegendItem legendItem in legendAdornmentLayer.LegendItems)
            {
                float itemLegendHeight = Math.Max(gdiPlusGeoCanvas.MeasureText(legendItem.TextStyle.TextColumnName, new GeoFont("Segoe UI", 10)).Height, legendItem.ImageHeight);
                float itemHeight = itemLegendHeight + Math.Max(legendItem.ImageTopPadding, legendItem.TextTopPadding) + legendItem.TopPadding + Math.Max(legendItem.ImageBottomPadding, legendItem.TextBottomPadding) + legendItem.BottomPadding;
                height += itemHeight;
            }
            return height;
        }
        private Dictionary<string, Category> LoadCategories()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + ConfigurationManager.AppSettings["CategoryFilePath"];
            var xDoc = XDocument.Load(path);
            var elements = from category in xDoc.Element("DemographicMap").Elements("Category")
                           select category;
            Dictionary<string, Category> categories = new Dictionary<string, Category>();
            foreach (var element in elements)
            {
                Category category = new Category();
                category.Title = element.Attribute("name").Value;
                category.CategoryImage = string.Format(@"Content\{0}", element.Attribute("icon").Value);
                foreach (var item in element.Elements("item"))
                {
                    CategoryItem categoryItem = new CategoryItem();
                    categoryItem.ColumnName = item.Element("columnName").Value;
                    categoryItem.Alias = item.Element("alias").Value;
                    category.Items.Add(categoryItem);
                }
                categories.Add(category.Title, category);
            }
            return categories;
        }
    }
}

CustomDotDensityStyle.cs

using System;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    [Serializable]
    class CustomDotDensityStyle : DotDensityStyle
    {
        private int drawingPointsNumber;
        public CustomDotDensityStyle()
            : base()
        { }
        public int DrawingPointsNumber
        {
            get { return drawingPointsNumber; }
            set { drawingPointsNumber = value; }
        }
        protected override void DrawSampleCore(GeoCanvas canvas, DrawingRectangleF drawingExtent)
        {
            base.DrawSampleCore(canvas, drawingExtent);
            PointShape upperLeftPoint = ExtentHelper.ToWorldCoordinate(canvas.CurrentWorldExtent, drawingExtent.CenterX - drawingExtent.Width / 2, drawingExtent.CenterY - drawingExtent.Height / 2, canvas.Width, canvas.Height);
            PointShape lowerRightPoint = ExtentHelper.ToWorldCoordinate(canvas.CurrentWorldExtent, drawingExtent.CenterX + drawingExtent.Width / 2, drawingExtent.CenterY + drawingExtent.Height / 2, canvas.Width, canvas.Height);
            RectangleShape rectangle = new RectangleShape(upperLeftPoint, lowerRightPoint);
            rectangle.ScaleDown(10);
            // Here draw the points on Legend Image
            Random random = new Random(DateTime.Now.Millisecond);
            Collection<BaseShape> drawingPoints = new Collection<BaseShape>();
            for (int i = 0; i < DrawingPointsNumber; i++)
            {
                double x = rectangle.LowerLeftPoint.X + random.NextDouble() * (rectangle.Width);
                double y = rectangle.LowerLeftPoint.Y + random.NextDouble() * (rectangle.Height);
                drawingPoints.Add(new PointShape(x, y));
            }
            TextStyle textStyle = new TextStyle(DrawingPointsNumber.ToString(), new GeoFont("Arial", 20, DrawingFontStyles.Bold), new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.FromHtml("#d3d3d3"))));
            textStyle.DrawSample(canvas, drawingExtent);
            CustomPointStyle.Draw(drawingPoints, canvas, new Collection<SimpleCandidate>(), new Collection<SimpleCandidate>());
        }
    }
}

DemographicStyleBuilder.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public abstract class DemographicStyleBuilder
    {
        private GeoColor color;
        private int opacity;
        private Collection<string> selectedColumns;
        protected DemographicStyleBuilder()
            : this(new Collection<string>())
        { }
        protected DemographicStyleBuilder(IEnumerable<string> selectedColumns)
        {
            this.Opacity = 100;
            this.color = GeoColor.FromHtml("#f1f369");
            this.selectedColumns = new Collection<string>(new List<string>(selectedColumns));
        }
        public Collection<string> SelectedColumns
        {
            get { return selectedColumns; }
        }
        public GeoColor Color
        {
            get { return color; }
            set { color = value; }
        }
        public int Opacity
        {
            get { return opacity; }
            set { opacity = value; }
        }
        public Style GetStyle(FeatureSource featureSource)
        {
            return GetStyleCore(featureSource);
        }
        protected abstract Style GetStyleCore(FeatureSource featureSource);
    }
}

DemographicStyleBuilderType.cs

namespace ThinkGeo.MapSuite.USDemographicMap
{
    public enum DemographicStyleBuilderType
    {
        Thematic = 0,
        ValueCircle = 1,
        DotDensity = 2,
        PieChart = 3
    }
}

DemographicStyleTextFormatter.cs

using System;
using System.Globalization;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public static class DemographicStyleTextFormatter
    {
        public static string GetFormatedStringForLegendItem(string columnName, double value)
        {
            string aliasUnitString = GetFormatedString(columnName, value);
            string[] subStrings = aliasUnitString.Split(new string[] { ": " }, StringSplitOptions.None);
            if (subStrings[subStrings.Length|- 1].Contains("%"))
            {
                aliasUnitString = subStrings[subStrings.Length|- 1];
            }
            else
            {
                aliasUnitString = value.ToString("N0", CultureInfo.InvariantCulture);
            }
            return aliasUnitString;
        }
        public static string GetFormatedString(string columnName, double value)
        {
            string result = string.Empty;
            switch (columnName)
            {
                case "Population":
                    result = string.Format("Population : {0} People", value.ToString("N0", CultureInfo.InvariantCulture));
                    break;
                case "PopDensity":
                    result = string.Format("Population Density : {0} People/sq.mi.", value.ToString("N0", CultureInfo.InvariantCulture));
                    break;
                case "Female":
                    result = string.Format("Female : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Male":
                    result = string.Format("Male : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "AREALAND":
                    result = string.Format("Land Area : {0} sq.mi.", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "AREAWATR":
                    result = string.Format("Water Area : {0} sq.mi.", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "White":
                    result = string.Format("White : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Black":
                    result = string.Format("Black : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Indian":
                    result = string.Format("American Indian : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Islander":
                    result = string.Format("Native Pacific Islander : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Asian":
                    result = string.Format("Asian : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Other":
                    result = string.Format("Other : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "MultiRace":
                    result = string.Format("Multiracial : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Under5":
                    result = string.Format("<= 5 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "5to9":
                    result = string.Format("5 ~ 10 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "10to14":
                    result = string.Format("10 ~ 15 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "15to17":
                    result = string.Format("15 ~ 18 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "18to24":
                    result = string.Format("18 ~ 25 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "25to34":
                    result = string.Format("25 ~ 35 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "35to44":
                    result = string.Format("35 ~ 45 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "45to54":
                    result = string.Format("45 ~ 55 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "55to64":
                    result = string.Format("55 ~ 65 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "65to74":
                    result = string.Format("65 ~ 75 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "75to84":
                    result = string.Format("75 ~ 85 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "over85":
                    result = string.Format(">= 85 : {0}%", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                default:
                    result = columnName + " : " + value.ToString("N0", CultureInfo.InvariantCulture);
                    break;
            }
            return result;
        }
    }
}

DotDensityDemographicStyleBuilder.cs

using System.Collections.Generic;
using System.Globalization;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class DotDensityDemographicStyleBuilder : DemographicStyleBuilder
    {
        private double dotDensityValue;
        public DotDensityDemographicStyleBuilder()
            : this(new string[] { })
        { }
        public DotDensityDemographicStyleBuilder(IEnumerable<string> selectedColumns)
            : base(selectedColumns)
        {
            this.Opacity = 255;
            this.DotDensityValue = 50;
            this.Color = GeoColor.SimpleColors.DarkRed;
        }
        public double DotDensityValue
        {
            get { return dotDensityValue; }
            set { dotDensityValue = value; }
        }
        protected override Style GetStyleCore(FeatureSource featureSource)
        {
            double totalValue = 0;
            featureSource.Open();
            int featureCount = featureSource.GetCount();
            for (int i = 0; i < featureCount; i++)
            {
                Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);
                double columnValue;
                double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue);
                totalValue += columnValue;
            }
            featureSource.Close();
            double pointToValueRatio = DotDensityValue / (totalValue / featureCount);
            CustomDotDensityStyle dotDensityStyle = new CustomDotDensityStyle();
            dotDensityStyle.ColumnName = SelectedColumns[0];
            dotDensityStyle.PointToValueRatio = pointToValueRatio;
            dotDensityStyle.CustomPointStyle = new PointStyle(PointSymbolType.Circle, new GeoSolidBrush(GeoColor.FromArgb(Opacity, Color)), 4);
            return dotDensityStyle;
        }
    }
}

PieChartDemographicStyleBuilder.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using ThinkGeo.MapSuite.Core;
using ZedGraph;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class PieChartDemographicStyleBuilder : DemographicStyleBuilder
    {
        private Collection<string> selectedColumnAliases;
        private Collection<GeoColor> pieColors;
        public PieChartDemographicStyleBuilder()
            : base()
        { }
        public PieChartDemographicStyleBuilder(IEnumerable<string> selectedColumns)
            : base(selectedColumns)
        {
            this.Opacity = 200;
            this.Color = GeoColor.SimpleColors.LightBlue;
        }
        public Collection<string> SelectedColumnAliases
        {
            get
            {
                if (selectedColumnAliases == null)
                {
                    selectedColumnAliases = new Collection<string>();
                }
                return selectedColumnAliases;
            }
        }
        protected override Style GetStyleCore(FeatureSource featureSource)
        {
            PieZedGraphStyle zedGraphStyle = new PieZedGraphStyle();
            zedGraphStyle.ZedGraphDrawing += new EventHandler<ZedGraphDrawingEventArgs>(zedGraphStyle_ZedGraphDrawing);
            pieColors = GeoColor.GetColorsInQualityFamily(GeoColor.FromArgb(Opacity, Color), SelectedColumns.Count);
            for (int i = 0; i < SelectedColumns.Count; i++)
            {
                zedGraphStyle.RequiredColumnNames.Add(SelectedColumns[i]);
                zedGraphStyle.PieSlices.Add(SelectedColumnAliases[i], pieColors[i]);
            }
            return zedGraphStyle;
        }
        void zedGraphStyle_ZedGraphDrawing(object sender, ZedGraphDrawingEventArgs e)
        {
            ZedGraphControl zedGraph = new ZedGraphControl();
            zedGraph.Size = new Size(100, 100);
            zedGraph.GraphPane.Fill.Type = FillType.None;
            zedGraph.GraphPane.Chart.Fill.Type = FillType.None;
            zedGraph.GraphPane.Border.IsVisible = false;
            zedGraph.GraphPane.Chart.Border.IsVisible = false;
            zedGraph.GraphPane.XAxis.IsVisible = false;
            zedGraph.GraphPane.YAxis.IsVisible = false;
            zedGraph.GraphPane.Legend.IsVisible = false;
            zedGraph.GraphPane.Title.IsVisible = false;
            for (int i = 0; i < SelectedColumns.Count; i++)
            {
                Color color = System.Drawing.Color.FromArgb(pieColors[i].AlphaComponent, pieColors[i].RedComponent, pieColors[i].GreenComponent, pieColors[i].BlueComponent);
                PieItem pieItem = zedGraph.GraphPane.AddPieSlice(Convert.ToDouble(e.Feature.ColumnValues[SelectedColumns[i]), color, 0.08, "");
                pieItem.LabelDetail.IsVisible = false;
            }
            zedGraph.AxisChange();
            e.Bitmap = zedGraph.GraphPane.GetImage();
        }
    }
}

PieZedGraphStyle.cs

using System.Collections.Generic;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class PieZedGraphStyle : ZedGraphStyle
    {
        private Dictionary<string, GeoColor> pieSlices;
        public PieZedGraphStyle()
            : base()
        { }
        public Dictionary<string, GeoColor> PieSlices
        {
            get
            {
                if (pieSlices == null)
                {
                    pieSlices = new Dictionary<string, GeoColor>();
                }
                return pieSlices;
            }
        }
    }
}

ThematicDemographicStyleBuilder.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class ThematicDemographicStyleBuilder : DemographicStyleBuilder
    {
        private int classBreakCount;
        private GeoColor endColor;
        private ColorWheelDirection colorWheelDirection;
        public ThematicDemographicStyleBuilder()
            : this(new string[] { })
        { }
        public ThematicDemographicStyleBuilder(IEnumerable<string> selectedColumns)
            : base(selectedColumns)
        {
            this.ClassBreaksCount = 10;
            this.Color = GeoColor.SimpleColors.LightBlue;
            this.EndColor = GeoColor.SimpleColors.LightRed;
            this.ColorWheelDirection = ColorWheelDirection.CounterClockwise;
            this.Opacity = 200;
        }
        public int ClassBreaksCount
        {
            get { return classBreakCount; }
            set { classBreakCount = value; }
        }
        public ColorWheelDirection ColorWheelDirection
        {
            get { return colorWheelDirection; }
            set { colorWheelDirection = value; }
        }
        public GeoColor StartColor
        {
            get { return Color; }
            set { Color = value; }
        }
        public GeoColor EndColor
        {
            get { return endColor; }
            set { endColor = value; }
        }
        protected override Style GetStyleCore(FeatureSource featureSource)
        {
            Collection<GeoColor> familyColors = GeoColor.GetColorsInQualityFamily(Color, EndColor, classBreakCount, ColorWheelDirection);
            featureSource.Open();
            int featureCount = featureSource.GetCount();
            double[] values = new double[featureCount];
            for (int i = 0; i < featureCount; i++)
            {
                Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);
                double columnValue;
                double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue);
                values[i] = columnValue;
            }
            featureSource.Close();
            ClassBreakStyle classBreakStyle = new ClassBreakStyle(SelectedColumns[0]) { BreakValueInclusion = BreakValueInclusion.IncludeValue };
            double[] classBreakValues = GetClusterClassBreaks(values, ClassBreaksCount - 1);
            for (int i = 0; i < classBreakValues.Length; i++)
            {
                ClassBreak classBreak = new ClassBreak(classBreakValues[i], AreaStyles.CreateSimpleAreaStyle(new GeoColor(this.Opacity, familyColors[i]), GeoColor.FromHtml("#f05133"), 1));
                classBreakStyle.ClassBreaks.Add(classBreak);
            }
            return classBreakStyle;
        }
        private double[] GetClusterClassBreaks(double[] values, int count)
        {
            var result = new List<double>();
            var orderedValues = values.OrderBy(v => v).ToArray();
            var min = orderedValues[0];
            var max = orderedValues[orderedValues.Length|- 1];
            var classesCount = (int)(orderedValues.Length / count);
            var breakValue = min;
            for (var i = 1; i < count; i++)
            {
                breakValue = orderedValues[i|* classesCount];
                if (!result.Contains(breakValue))
                {
                    result.Add(breakValue);
                }
            }
            result.Insert(0, 0);
            return result.ToArray();
        }
    }
}

ValueCircleDemographicStyleBuilder.cs

using System.Collections.Generic;
using System.Globalization;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class ValueCircleDemographicStyleBuilder : DemographicStyleBuilder
    {
        private double radiusRatio;
        public ValueCircleDemographicStyleBuilder()
            : this(new string[] { })
        { }
        public ValueCircleDemographicStyleBuilder(IEnumerable<string> selectedColumns)
            : base(selectedColumns)
        {
            this.radiusRatio = 1;
            this.Color = GeoColor.SimpleColors.BrightOrange;
            this.Opacity = 160;
        }
        public double RadiusRatio
        {
            get { return radiusRatio; }
            set { radiusRatio = value; }
        }
        protected override Style GetStyleCore(FeatureSource featureSource)
        {
            double minValue = double.MaxValue;
            double maxValue = double.MinValue;
            featureSource.Open();
            for (int i = 0; i < featureSource.GetCount(); i++)
            {
                Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);
                double columnValue;
                if (double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue))
                {
                    if (columnValue < minValue)
                    {
                        minValue = columnValue;
                    }
                    else if (columnValue > maxValue)
                    {
                        maxValue = columnValue;
                    }
                }
            }
            featureSource.Close();
            ValueCircleStyle valueCircleStyle = new ValueCircleStyle();
            valueCircleStyle.ColumnName = SelectedColumns[0];
            valueCircleStyle.DrawingRadiusRatio = radiusRatio;
            valueCircleStyle.MinValidValue = minValue;
            valueCircleStyle.MaxValidValue = maxValue;
            valueCircleStyle.MinCircleAreaInDefaultZoomLevel = 80;
            valueCircleStyle.MaxCircleAreaInDefaultZoomLevel = 10000;
            valueCircleStyle.InnerColor = GeoColor.FromArgb(this.Opacity, Color);
            valueCircleStyle.OuterColor = GeoColor.SimpleColors.White;
            return valueCircleStyle;
        }
    }
}

ValueCircleStyle.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class ValueCircleStyle : Style
    {
        private string columnName;
        private ZoomLevel defaultZoomLevel;
        private double drawingRadiusRatio;
        private GeoColor innerColor;
        private double maxCircleRadiusInDefaultZoomLevel;
        private double maxValidValue;
        private double minCircleRadiusInDefaultZoomLevel;
        private double minValidValue;
        private GeoColor outerColor;
        private double basedScale;
        public ValueCircleStyle()
            : base()
        {
            defaultZoomLevel = (new ZoomLevelSet()).ZoomLevel04;
            drawingRadiusRatio = 1;
            outerColor = GeoColor.FromArgb(255, 10, 20, 255);
            innerColor = GeoColor.FromArgb(100, 10, 20, 255);
            minCircleRadiusInDefaultZoomLevel = 10;
            maxCircleRadiusInDefaultZoomLevel = 100;
            basedScale = (new ZoomLevelSet()).ZoomLevel05.Scale;
        }
        public string ColumnName
        {
            get { return columnName; }
            set { columnName = value; }
        }
        public ZoomLevel DefaultZoomLevel
        {
            get { return defaultZoomLevel; }
            set { defaultZoomLevel = value; }
        }
        public double DrawingRadiusRatio
        {
            get { return drawingRadiusRatio; }
            set { drawingRadiusRatio = value; }
        }
        public GeoColor InnerColor
        {
            get { return innerColor; }
            set { innerColor = value; }
        }
        public double MaxCircleAreaInDefaultZoomLevel
        {
            get { return maxCircleRadiusInDefaultZoomLevel; }
            set { maxCircleRadiusInDefaultZoomLevel = value; }
        }
        public double MaxValidValue
        {
            get { return maxValidValue; }
            set { maxValidValue = value; }
        }
        public double MinCircleAreaInDefaultZoomLevel
        {
            get { return minCircleRadiusInDefaultZoomLevel; }
            set { minCircleRadiusInDefaultZoomLevel = value; }
        }
        public double MinValidValue
        {
            get { return minValidValue; }
            set { minValidValue = value; }
        }
        public GeoColor OuterColor
        {
            get { return outerColor; }
            set { outerColor = value; }
        }
        public double BasedScale
        {
            get { return basedScale; }
        }
        protected override void DrawCore(IEnumerable<Feature> features, GeoCanvas canvas, Collection<SimpleCandidate> labelsInThisLayer, Collection<SimpleCandidate> labelsInAllLayers)
        {
            double dCircleArea = maxCircleRadiusInDefaultZoomLevel - MinCircleAreaInDefaultZoomLevel;
            double dValue = maxValidValue - minValidValue;
            double ratio = dValue / dCircleArea;
            foreach (Feature f in features)
            {
                PointShape center = f.GetShape().GetCenterPoint();
                double value = 0;
                if (!double.TryParse(f.ColumnValues[columnName], out value))
                {
                    continue;
                }
                if (value > maxValidValue || value < minValidValue)
                {
                    continue;
                }
                double drawingDefaultCircleArea = (value - minValidValue) / ratio + minCircleRadiusInDefaultZoomLevel;
                double defaultScale = defaultZoomLevel.Scale;
                double scale = canvas.CurrentScale;
                double graphArea = 0, graphHeght = 0;
                graphArea = drawingDefaultCircleArea * defaultScale / basedScale * drawingRadiusRatio;
                graphHeght = Math.Sqrt(graphArea / Math.PI);
                canvas.DrawEllipse(center, (float)(graphHeght * 2), (float)(graphHeght * 2), new GeoPen(outerColor, 1), new GeoSolidBrush(innerColor), DrawingLevel.LevelOne);
            }
        }
        protected override Collection<string> GetRequiredColumnNamesCore()
        {
            Collection<string> requiredFieldNames = new Collection<string>();
            requiredFieldNames.Add(columnName);
            return requiredFieldNames;
        }
    }
}

Category.cs

using System;
using System.Collections.ObjectModel;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class Category
    {
        private Collection<CategoryItem> items;
        private string title;
        private string categoryImage;
        public Category()
        { }
        public Category(string title, string categoryImage)
        {
            this.Title = title;
            this.CategoryImage = categoryImage;
        }
        public Collection<CategoryItem> Items
        {
            get
            {
                if (items == null)
                {
                    items = new Collection<CategoryItem>();
                }
                return items;
            }
        }
        public string Title
        {
            get { return title; }
            set { title = value; }
        }
        public string CategoryImage
        {
            get { return categoryImage; }
            set { categoryImage = value; }
        }
        public CategoryItem GetCategoryItemByAlias(string alias)
        {
            CategoryItem item = null;
            foreach (var categoryItem in this.Items)
            {
                if (categoryItem.Alias.Equals(alias.Trim(), StringComparison.OrdinalIgnoreCase))
                {
                    item = categoryItem;
                    break;
                }
            }
            return item;
        }
    }
}

CategoryItem.cs

using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class CategoryItem
    {
        private string columnName;
        private string alias;
        public CategoryItem()
        { }
        public CategoryItem(string columnName, string alias)
        {
            this.columnName = columnName;
            this.alias = alias;
        }
        public string ColumnName
        {
            get { return columnName; }
            set { columnName = value; }
        }
        public string Alias
        {
            get { return alias; }
            set { alias = value; }
        }
    }
}

CustomDotDensityStyle.cs

using System;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    [Serializable]
    class CustomDotDensityStyle : DotDensityStyle
    {
        private int drawingPointsNumber;
        public CustomDotDensityStyle()
            : base()
        { }
        public int DrawingPointsNumber
        {
            get { return drawingPointsNumber; }
            set { drawingPointsNumber = value; }
        }
        protected override void DrawSampleCore(GeoCanvas canvas, DrawingRectangleF drawingExtent)
        {
            base.DrawSampleCore(canvas, drawingExtent);
            PointShape upperLeftPoint = ExtentHelper.ToWorldCoordinate(canvas.CurrentWorldExtent, drawingExtent.CenterX - drawingExtent.Width / 2, drawingExtent.CenterY - drawingExtent.Height / 2, canvas.Width, canvas.Height);
            PointShape lowerRightPoint = ExtentHelper.ToWorldCoordinate(canvas.CurrentWorldExtent, drawingExtent.CenterX + drawingExtent.Width / 2, drawingExtent.CenterY + drawingExtent.Height / 2, canvas.Width, canvas.Height);
            RectangleShape rectangle = new RectangleShape(upperLeftPoint, lowerRightPoint);
            rectangle.ScaleDown(10);
            // Here draw the points on Legend Image
            Random random = new Random(DateTime.Now.Millisecond);
            Collection<BaseShape> drawingPoints = new Collection<BaseShape>();
            for (int i = 0; i < DrawingPointsNumber; i++)
            {
                double x = rectangle.LowerLeftPoint.X + random.NextDouble() * (rectangle.Width);
                double y = rectangle.LowerLeftPoint.Y + random.NextDouble() * (rectangle.Height);
                drawingPoints.Add(new PointShape(x, y));
            }
            TextStyle textStyle = new TextStyle(DrawingPointsNumber.ToString(), new GeoFont("Arial", 20, DrawingFontStyles.Bold), new GeoSolidBrush(GeoColor.FromArgb(180, GeoColor.FromHtml("#d3d3d3"))));
            textStyle.DrawSample(canvas, drawingExtent);
            CustomPointStyle.Draw(drawingPoints, canvas, new Collection<SimpleCandidate>(), new Collection<SimpleCandidate>());
        }
    }
}

DemographicStyle.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public abstract class DemographicStyle
    {
        private GeoColor baseColor;
        private int opacity;
        private Collection<string> selectedColumns;
        protected DemographicStyle()
            : this(new Collection<string>())
        { }
        protected DemographicStyle(IEnumerable<string> selectedColumns)
        {
            this.selectedColumns = new Collection<string>(new List<string>(selectedColumns));
            this.baseColor = GeoColor.FromHtml("#f1f369");
            this.Opacity = 180;
        }
        public GeoColor BaseColor
        {
            get { return baseColor; }
            set { baseColor = value; }
        }
        public int Opacity
        {
            get { return opacity; }
            set { opacity = value; }
        }
        public Collection<string> SelectedColumns
        {
            get { return selectedColumns; }
        }
        public Style GetStyle(FeatureSource featureSource)
        {
            return GetStyleCore(featureSource);
        }
        protected abstract Style GetStyleCore(FeatureSource featureSource);
    }
}

DemographicStyleBuilder.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public abstract class DemographicStyleBuilder
    {
        private int opacity;
        private GeoColor color;
        private Collection<string> selectedColumns;
        protected DemographicStyleBuilder()
            : this(new Collection<string>())
        { }
        protected DemographicStyleBuilder(IEnumerable<string> selectedColumns)
        {
            this.Opacity = 100;
            this.color = GeoColor.FromHtml("#f1f369");
            this.selectedColumns = new Collection<string>(new List<string>(selectedColumns));
        }
        public Collection<string> SelectedColumns
        {
            get { return selectedColumns; }
        }
        public GeoColor Color
        {
            get { return color; }
            set { color = value; }
        }
        public int Opacity
        {
            get { return opacity; }
            protected set { opacity = value; }
        }
        public Collection<Style> GetStyles(FeatureSource featureSource)
        {
            return GetStylesCore(featureSource);
        }
        protected abstract Collection<Style> GetStylesCore(FeatureSource featureSource);
    }
}

DemographicStyleBuilderFactory.cs

 

DemographicStyleBuilderType.cs

namespace ThinkGeo.MapSuite.USDemographicMap
{
    public enum DemographicStyleBuilderType
    {
        Thematic = 0,
        ValueCircle = 1,
        DotDensity = 2,
        PieChart = 3
    }
}

DemographicStyleTextFormatter.cs

using System;
using System.Globalization;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public static class DemographicStyleTextFormatter
    {
        public static string GetFormatedStringForLegendItem(string columnName, double value)
        {
            string aliasUnitString = GetFormatedString(columnName, value);
            string[] subStrings = aliasUnitString.Split(new string[] { ": " }, StringSplitOptions.None);
            if (subStrings[subStrings.Length|- 1].Contains("%"))
            {
                aliasUnitString = subStrings[subStrings.Length|- 1];
            }
            else
            {
                aliasUnitString = value.ToString("N0", CultureInfo.InvariantCulture);
            }
            return aliasUnitString;
        }
        public static string GetFormatedString(string columnName, double value)
        {
            string result = string.Empty;
            switch (columnName)
            {
                case "Population":
                    result = string.Format("Population : {0} People", value.ToString("N0", CultureInfo.InvariantCulture));
                    break;
                case "PopDensity":
                    result = string.Format("Population Density : {0} People / sq.mi.", value.ToString("N0", CultureInfo.InvariantCulture));
                    break;
                case "Female":
                    result = string.Format("Female : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Male":
                    result = string.Format("Male : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "AREALAND":
                    result = string.Format("Land Area : {0} sq.mi.", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "AREAWATR":
                    result = string.Format("Water Area : {0} sq.mi.", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "White":
                    result = string.Format("White : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Black":
                    result = string.Format("Black : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Indian":
                    result = string.Format("American Indian : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Islander":
                    result = string.Format("Native Pacific Islander : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Asian":
                    result = string.Format("Asian : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Other":
                    result = string.Format("Other : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "MultiRace":
                    result = string.Format("Multiracial : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "Under5":
                    result = string.Format("<= 5 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "5to9":
                    result = string.Format("5 ~ 10 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "10to14":
                    result = string.Format("10 ~ 15 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "15to17":
                    result = string.Format("15 ~ 18 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "18to24":
                    result = string.Format("18 ~ 25 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "25to34":
                    result = string.Format("25 ~ 35 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "35to44":
                    result = string.Format("35 ~ 45 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "45to54":
                    result = string.Format("45 ~ 55 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "55to64":
                    result = string.Format("55 ~ 65 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "65to74":
                    result = string.Format("65 ~ 75 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "75to84":
                    result = string.Format("75 ~ 85 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                case "over85":
                    result = string.Format(">= 85 : {0} %", value.ToString("N2", CultureInfo.InvariantCulture));
                    break;
                default:
                    result = columnName + " : " + value.ToString("N0", CultureInfo.InvariantCulture);
                    break;
            }
            return result;
        }
    }
}

DotDensityDemographicStyleBuilder.cs

using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using ThinkGeo.MapSuite.Core;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    public class DotDensityDemographicStyleBuilder : DemographicStyleBuilder
    {
        private double dotDensityValue;
        public DotDensityDemographicStyleBuilder()
            : this(new string[] { })
        { }
        public DotDensityDemographicStyleBuilder(IEnumerable<string> selectedColumns)
            : base(selectedColumns)
        {
            Opacity = 255;
            DotDensityValue = 50;
            Color = GeoColor.SimpleColors.DarkRed;
        }
        public double DotDensityValue
        {
            get { return dotDensityValue; }
            set { dotDensityValue = value; }
        }
        protected override Collection<Style> GetStylesCore(FeatureSource featureSource)
        {
            double totalValue = 0;
            featureSource.Open();
            int featureCount = featureSource.GetCount();
            for (int i = 0; i < featureCount; i++)
            {
                Feature feature = featureSource.GetFeatureById((i + 1).ToString(CultureInfo.InvariantCulture), SelectedColumns);
                double columnValue;
                double.TryParse(feature.ColumnValues[SelectedColumns[0], out columnValue);
                totalValue += columnValue;
            }
            featureSource.Close();
            CustomDotDensityStyle dotDensityStyle = new CustomDotDensityStyle();
            dotDensityStyle.ColumnName = SelectedColumns[0];
            dotDensityStyle.PointToValueRatio = DotDensityValue / (totalValue / featureCount);
            dotDensityStyle.CustomPointStyle = PointStyles.CreateSimpleCircleStyle(GeoColor.FromArgb(Opacity, Color), 4);
            return new Collection<Style>() { dotDensityStyle };
        }
    }
}

JsonCallbackRequest.cs

using System.Collections.ObjectModel;
using System.Runtime.Serialization;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    [DataContract]
    public class JsonCallbackRequest
    {
        private string request;
        private string requestStyle;
        private string requestColumnAlias;
        private Collection<string> selectedCategoryItems;
        private string startColor;
        private string endColor;
        private string colorWheelDirection;
        private int sliderValue;
        private string selectedFeatureId;
        public JsonCallbackRequest()
        {
        }
        [DataMember(Name = "request")]
        public string Request
        {
            get { return request; }
            set { request = value; }
        }
        public DemographicStyleBuilderType StyleBuildType
        {
            get
            {
                DemographicStyleBuilderType type = DemographicStyleBuilderType.Thematic;
                switch (requestStyle.ToLowerInvariant())
                {
                    case "pie":
                        type = DemographicStyleBuilderType.PieChart;
                        break;
                    case "thematic":
                        type = DemographicStyleBuilderType.Thematic;
                        break;
                    case "dotdensity":
                        type = DemographicStyleBuilderType.DotDensity;
                        break;
                    case "valuecircle":
                        type = DemographicStyleBuilderType.ValueCircle;
                        break;
                }
                return type;
            }
        }
        [DataMember(Name = "style")]
        private string RequestStyle
        {
            get { return requestStyle; }
            set { requestStyle = value; }
        }
        [DataMember(Name = "alias")]
        public string RequestColumnAlias
        {
            get { return requestColumnAlias; }
            set { requestColumnAlias = value; }
        }
        [DataMember(Name = "selectedItems")]
        public Collection<string> SelectedCategoryItems
        {
            get { return selectedCategoryItems; }
            internal set { selectedCategoryItems = value; }
        }
        [DataMember(Name = "startColor")]
        public string StartColor
        {
            get { return startColor; }
            set { startColor = value; }
        }
        [DataMember(Name = "endColor")]
        public string EndColor
        {
            get { return endColor; }
            set { endColor = value; }
        }
        [DataMember(Name = "colorDirection")]
        public string ColorWheelDirection
        {
            get { return colorWheelDirection; }
            set { colorWheelDirection = value; }
        }
        [DataMember(Name = "sliderValue")]
        public int SliderValue
        {
            get { return sliderValue; }
            set { sliderValue = value; }
        }
        [DataMember(Name = "selectedFeatureId")]
        public string SelectedFeatureId
        {
            get { return selectedFeatureId; }
            set { selectedFeatureId = value; }
        }
    }
}

JsonSerializer.cs

using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace ThinkGeo.MapSuite.USDemographicMap
{
    /// <summary>
    /// Helper class to serialize or deserialize a generic object to/from JSON.
    /// </summary>
    public class JsonSerializer
    {
        /// <summary>
        /// Serializes an object to JSON
        /// </summary>
        /// <typeparam name="T">Type of object to serialize</typeparam>
        /// <param name="obj">Instance of object to serialize</param>
        /// <returns>JSON string</returns>
        public static string Serialize<T>(T obj)
        {
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
            MemoryStream ms = new MemoryStream();
            serializer.WriteObject(ms, obj);
            string retVal = Encoding.Default.GetString(ms.ToArray());
            ms.Dispose();
            return retVal;
        }
        /// <summary>
        /// Deserialize an object from JSON
        /// </summary>
        /// <typeparam name="T">Type of object to deserialize</typeparam>
        /// <param name="json">JSON string to deserialize</param>
        /// <returns>deserialized object</returns>
        public static T Deserialize<T>(string json)
        {
            T obj = Activator.CreateInstance<T>();
            MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
            obj = (T)serializer.ReadObject(ms);
            ms.Close();
            ms.Dispose();
            return obj;
        }
    }
}
source_code_mvcedition_projecttemplates_usdemographicmap_cs.zip.txt · Last modified: 2015/12/01 01:35 by tgwikiupdate