ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
ThinkGeo Cloud
ThinkGeo UI Controls
ThinkGeo Open Source
Help and Support
External Resources
using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace DissolveWithStatistics { static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TestForm()); } } }
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Drawing; using System.IO; using System.Windows.Forms; using ThinkGeo.MapSuite.Core; namespace DissolveWithStatistics { public partial class TestForm : Form { private MapEngine mapEngine = new MapEngine(); private Bitmap bitmap = null; private enum StatisticsType { Sum, Count, Average }; //structure to define the type of statistics for the different columns. struct StatisticsField { public string column; public StatisticsType statisticsType; public string outputColumn; public double value; public StatisticsField(string Column, StatisticsType StatisticsType, string OutputColumn) { this.column = Column; this.statisticsType = StatisticsType; this.outputColumn = OutputColumn; this.value = 0; } } 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(-128,52,-63,20), Map.Width, Map.Height); mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean); // Add the states shapefile to the MapEngine LoadStateShapeFile(); DrawImage(); } private void btnDissolve_Click(object sender, EventArgs e) { //deletes the files for the dissolved shapefile if they already exist. if (File.Exists(@"..\..\Data\USregions.shp")) { DeleteDissolveFiles(); } //Sets the columns to do statistics on for the dissolving. Collection<StatisticsField> statisticsFields = new Collection<StatisticsField>(); statisticsFields.Add(new StatisticsField("Pop1990",StatisticsType.Sum,"Pop1990")); statisticsFields.Add(new StatisticsField("State_name", StatisticsType.Count, "StateCount")); statisticsFields.Add(new StatisticsField("Pop90_sqmi", StatisticsType.Average, "Pop90Sqmi")); //Creates the dissolved shapefile to the mapEngine. ShapeFileFeatureLayer dissolveLayer = DissolveShapeFile((ShapeFileFeatureLayer)mapEngine.StaticLayers[0], "sub_region", @"..\..\Data\USRegions.shp", statisticsFields); //Adds the dissolved shapefile to the mapEngine. mapEngine.StaticLayers.Clear(); ShapeFileFeatureLayer.BuildIndexFile(@"..\..\Data\USRegions.shp", BuildIndexMode.DoNotRebuild); dissolveLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1; dissolveLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("USregionLayer", dissolveLayer); //Adds the dissolved shapefile for labeling the columns sub_region and the columns with statistics results (pop1990,statecount and pop90sqmi). ShapeFileFeatureLayer labelDissolveLayer = new ShapeFileFeatureLayer(@"..\..\Data\USRegions.shp", ShapeFileReadWriteMode.ReadOnly); //TextStyle for the first line, sub_region and Statecount. labelDissolveLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(TextStyles.CreateSimpleTextStyle("MergedColumn", "Arial", 8, DrawingFontStyles.Regular, GeoColor.StandardColors.Black, 0, 15)); //TextStyle for the second line, pop1990 and pop90sqmi. labelDissolveLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(TextStyles.CreateSimpleTextStyle("MergedColumn2", "Arial", 8, DrawingFontStyles.Italic, GeoColor.StandardColors.Black, 0, 0)); labelDissolveLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("labelUSregionLayer", labelDissolveLayer); //Hooks up the event for CustomColumnFetch used to label the different columns. ((ShapeFileFeatureSource)labelDissolveLayer.FeatureSource).CustomColumnFetch += new EventHandler<CustomColumnFetchEventArgs>(labelDissolveLayer_CustomColumnFetch); DrawImage(); btnDissolve.Enabled = false; } private ShapeFileFeatureLayer DissolveShapeFile(ShapeFileFeatureLayer shapeFileFeatureLayer, string column, string DissolvedShapeFilePath, Collection<StatisticsField> StatisticsFields) { shapeFileFeatureLayer.Open(); //Gets all the distinct values for the column the dissolve is going to be based on. DataTable tempDataTable = shapeFileFeatureLayer.FeatureSource.ExecuteQuery("Select distinct " + column + " from " + Path.GetFileName(shapeFileFeatureLayer.ShapePathFileName)); //Adds the column the dissolve is going to be based on. Collection<DbfColumn> DbfColumns = new Collection<DbfColumn>(); DbfColumn nameDbfColumn = new DbfColumn(column, DbfColumnType.String, 30, 0); DbfColumns.Add(nameDbfColumn); //Adds the columns for the statistics. foreach (StatisticsField statisticField in StatisticsFields) { DbfColumnType dbfColumnType; int decimalLength; if (statisticField.statisticsType == StatisticsType.Count){ dbfColumnType = DbfColumnType.Integer;decimalLength = 0;} else {dbfColumnType = DbfColumnType.Double;decimalLength = 4;} DbfColumn dbfColumn = new DbfColumn(statisticField.outputColumn, dbfColumnType, 30, decimalLength); DbfColumns.Add(dbfColumn); } //creates the shapefile for the dissolve. ShapeFileFeatureSource.CreateShapeFile(shapeFileFeatureLayer.GetShapeFileType(), DissolvedShapeFilePath, DbfColumns ); //new DbfColumn[] { NameColumn }); ShapeFileFeatureSource dissolveFeatureSource = new ShapeFileFeatureSource(DissolvedShapeFilePath, ShapeFileReadWriteMode.ReadWrite); dissolveFeatureSource.Open(); dissolveFeatureSource.BeginTransaction(); foreach (DataRow dataRow in tempDataTable.Rows) { Collection<AreaBaseShape> polygonShapes = new Collection<AreaBaseShape>(); Collection<Feature> features = shapeFileFeatureLayer.FeatureSource.GetFeaturesByColumnValue(column, System.Convert.ToString(dataRow[0])); //Loops thru all the features with the same column value and add their shape to the polygonShapes collection. foreach (Feature feature in features) { AreaBaseShape polygonShape = (AreaBaseShape)feature.GetShape(); polygonShapes.Add(polygonShape); } //Uses the PolygonShape.Union static method to union all the shapes in one step. MultipolygonShape multiPolygonShape = PolygonShape.Union(polygonShapes); //Adds the resulting feature from the dissolve operation to the dissolve shapefile. Dictionary<string, string> Columns = new Dictionary<string, string>(); Columns.Add(column, System.Convert.ToString(dataRow[0])); //Loops thru the statisticsfields and do SQL to set the column value. foreach (StatisticsField statisticField in StatisticsFields) { DataTable datatable; string SQLvar = ""; switch (statisticField.statisticsType) { case StatisticsType.Sum: SQLvar = "Sum(" + statisticField.column + ")"; break; case StatisticsType.Average: SQLvar = "Avg(" + statisticField.column + ")"; break; case StatisticsType.Count: SQLvar = "Count(*)"; break; } datatable = shapeFileFeatureLayer.QueryTools.ExecuteQuery("Select " + SQLvar + " From " + shapeFileFeatureLayer.Name + " Where " + column + " = '" + System.Convert.ToString(dataRow[0]) + "'"); Columns.Add(statisticField.outputColumn, System.Convert.ToString(datatable.Rows[0].ItemArray[0])); } Feature newFeature = new Feature(multiPolygonShape, Columns); dissolveFeatureSource.AddFeature(newFeature); } //Commits and closes the open resources. dissolveFeatureSource.CommitTransaction(); dissolveFeatureSource.Close(); shapeFileFeatureLayer.Close(); //Creates the dissolved shapefile to return. ShapeFileFeatureLayer dissolveShapeFile = new ShapeFileFeatureLayer(DissolvedShapeFilePath, ShapeFileReadWriteMode.ReadOnly); return dissolveShapeFile; } //Event used for labeling based on the different columns. void labelDissolveLayer_CustomColumnFetch(object sender, CustomColumnFetchEventArgs e) { //For the first TextStyle. if (e.ColumnName == "MergedColumn") { ShapeFileFeatureLayer labelVolcanoLayer = (ShapeFileFeatureLayer)mapEngine.StaticLayers["labelUSregionLayer"]; Feature currentFeature = labelVolcanoLayer.QueryTools.GetFeatureById(e.Id, ReturningColumnsType.AllColumns); e.ColumnValue = currentFeature.ColumnValues["Sub_region"] + ", state count:" + currentFeature.ColumnValues["Statecount"]; } //For the second TextStyle. else if (e.ColumnName == "MergedColumn2") { ShapeFileFeatureLayer labelVolcanoLayer = (ShapeFileFeatureLayer)mapEngine.StaticLayers["labelUSregionLayer"]; Feature currentFeature = labelVolcanoLayer.QueryTools.GetFeatureById(e.Id, ReturningColumnsType.AllColumns); e.ColumnValue = "(pop: " + currentFeature.ColumnValues["Pop1990"] + ", density: " + currentFeature.ColumnValues["Pop90sqmi"] + ")"; } } private void DeleteDissolveFiles() { File.Delete(@"..\..\Data\USregions.shp"); File.Delete(@"..\..\Data\USregions.ids"); File.Delete(@"..\..\Data\USregions.idx"); File.Delete(@"..\..\Data\USregions.dbf"); File.Delete(@"..\..\Data\USregions.shx"); } private void LoadStateShapeFile() { ShapeFileFeatureLayer stateLayer = new ShapeFileFeatureLayer(@"..\..\Data\States.shp", ShapeFileReadWriteMode.ReadOnly); stateLayer.Name = "States"; ShapeFileFeatureLayer.BuildIndexFile(@"..\..\Data\States.shp", BuildIndexMode.DoNotRebuild); stateLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1; stateLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("StateLayer", stateLayer); } private void DrawImage() { if (bitmap != null) { bitmap.Dispose(); } bitmap = new Bitmap(Map.Width, Map.Height); mapEngine.OpenAllLayers(); mapEngine.DrawStaticLayers(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(); } } }