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 SwineFlu { 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.Drawing; using System.Globalization; using System.Windows.Forms; using System.IO; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using ThinkGeo.MapSuite.Core; using ZedGraph; namespace SwineFlu { public partial class TestForm : Form { private delegate Bitmap ToUIThreadDelegate(ZedGraphDrawingEventArgs e); private MapEngine mapEngine = new MapEngine(); private Bitmap bitmap = null; ShapeFileFeatureLayer worldLayer = null; ShapeFileFeatureLayer swineFluLayer = 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,90,180,-90), 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.Name = "Countries02"; worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1; worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("WorldLayer", worldLayer); // Add the point based shapefile for swine flu. swineFluLayer = new ShapeFileFeatureLayer(@"..\..\Data\h1n1-070609.shp", ShapeFileReadWriteMode.ReadOnly); swineFluLayer.Name = "h1n1-070609"; //Add Class break style for swine flu layer by confirmed cases. ClassBreakStyle classBreakStyle = new ClassBreakStyle("CONFIRMED"); classBreakStyle.ClassBreaks.Add(new ClassBreak(double.MinValue, PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.LightPink,8))); classBreakStyle.ClassBreaks.Add(new ClassBreak(18, PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Pink, 8))); classBreakStyle.ClassBreaks.Add(new ClassBreak(71, PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Red, 8))); classBreakStyle.ClassBreaks.Add(new ClassBreak(178, PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.DarkRed, 8))); classBreakStyle.ClassBreaks.Add(new ClassBreak(347, PointStyles.CreateSimpleCircleStyle(GeoColor.StandardColors.Brown, 8))); swineFluLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(classBreakStyle); swineFluLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("SwineFluLayer", swineFluLayer); DrawImage(); } private void btnProcess_Click(object sender, EventArgs e) { label1.Text = "Creating new shapefile joining atribute data of swine flue point based layer to the country layer. Please wait..."; label1.Refresh(); //deletes the files for the spatial joined shapefile if they already exist. if (File.Exists(@"..\..\Data\swineflucountries.shp")) { DeleteSpatialJoinFiles(); } //Gets the collumns from the swine flu layer to add for the spatial join. Here we will add "confirmed","fatal" and "suspected". swineFluLayer.Open(); Collection<DbfColumn> dbfColumns = ((ShapeFileFeatureSource)swineFluLayer.FeatureSource).GetDbfColumns(); Collection<DbfColumn> dbfColumnsToJoin = new Collection<DbfColumn>(); dbfColumnsToJoin.Add(dbfColumns[1]); dbfColumnsToJoin.Add(dbfColumns[6]); dbfColumnsToJoin.Add(dbfColumns[14]); swineFluLayer.Close(); worldLayer.Open(); Collection<DbfColumn> worldDbfColumns = ((ShapeFileFeatureSource)worldLayer.FeatureSource).GetDbfColumns(); DbfColumn polygonJoiningDBFColumn = worldDbfColumns[2]; DbfColumn pointJoiningDBFColumn = dbfColumns[2]; worldLayer.Open(); //Calls SpatialJoin function to create the new country layer with swine flu info. ShapeFileFeatureLayer joinedFeatureLayer = SpatialJoinOnPolygonLayer(worldLayer, swineFluLayer, dbfColumnsToJoin, @"..\..\Data\swineflucountries.shp", polygonJoiningDBFColumn, pointJoiningDBFColumn); mapEngine.StaticLayers.Remove("SwineFluLayer"); mapEngine.StaticLayers.Remove("Countries02"); //Adds the new layer. ClassBreakStyle classBreakStyle = new ClassBreakStyle("CONFIRMED"); classBreakStyle.ClassBreaks.Add(new ClassBreak(double.MinValue, AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.LightGray, GeoColor.StandardColors.Black))); classBreakStyle.ClassBreaks.Add(new ClassBreak(1, AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.LightPink, GeoColor.StandardColors.Black))); classBreakStyle.ClassBreaks.Add(new ClassBreak(250, AreaStyles.CreateSimpleAreaStyle(GeoColor.FromArgb(255,255,79,79), GeoColor.StandardColors.Black))); classBreakStyle.ClassBreaks.Add(new ClassBreak(1250, AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Red, GeoColor.StandardColors.Black))); classBreakStyle.ClassBreaks.Add(new ClassBreak(4080, AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.Brown, GeoColor.StandardColors.Black))); classBreakStyle.ClassBreaks.Add(new ClassBreak(9000, AreaStyles.CreateSimpleAreaStyle(GeoColor.StandardColors.DarkRed, GeoColor.StandardColors.Black))); joinedFeatureLayer.ZoomLevelSet.ZoomLevel01.CustomStyles.Add(classBreakStyle); joinedFeatureLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("SwineFluWorldLayer", joinedFeatureLayer); DrawImage(); label1.Text = ""; pctBoxLegend.Visible = true; btnProcess.Enabled = false; } //This function basically allows to create a new country layer with the additional information based on the swine flu layer. //The resulting country layer will have three new columns from the swine flu layer, "confirmed","fatal" and "suspected". //We determine what swine flu cases belong to what country by first doing a SQL query using common key columns for both layer //(the 2 digit country code) for speed. //If we get no results from the SQL query, then we do the Spatial Query to determine what point belongs to what polygon. //It is more time consuming. //Finally we get the sum of all three columns for all the point features (swine flu case) for each polygon feature (country). //The result is a country layer that has the sum of all the "confirmed","fatal" and "suspected" cases by country. private ShapeFileFeatureLayer SpatialJoinOnPolygonLayer(ShapeFileFeatureLayer PolygonShapeFileFeatureLayer, ShapeFileFeatureLayer PointShapeFileFeatureLayer, Collection<DbfColumn> ColumnsToJoin, string JoinedPolygonShapeFileFeatureLayerPath, DbfColumn PolygonJoiningDBFColumn, DbfColumn PointJoiningDBFColumn) { PolygonShapeFileFeatureLayer.Open(); PointShapeFileFeatureLayer.Open(); //Gets the columns from the Point based shapefile and we add the columns from the polygon shapefile to add. Collection<DbfColumn> dbfColumns = ((ShapeFileFeatureSource)PolygonShapeFileFeatureLayer.FeatureSource).GetDbfColumns(); Collection<DbfColumn> totalDbfColumns = ((ShapeFileFeatureSource)PolygonShapeFileFeatureLayer.FeatureSource).GetDbfColumns(); foreach (DbfColumn dbfColumn in ColumnsToJoin) { dbfColumn.Length = 12; dbfColumn.ColumnType = DbfColumnType.Integer; totalDbfColumns.Add(dbfColumn); } //Creates the new shapefile based on new columns. ShapeFileFeatureLayer.CreateShapeFile(ShapeFileType.Polygon, JoinedPolygonShapeFileFeatureLayerPath, totalDbfColumns); //Creates the shapefile feature source for adding the features with the info for the columns to join. ShapeFileFeatureSource joinedShapeFileFeatureSource = new ShapeFileFeatureSource(JoinedPolygonShapeFileFeatureLayerPath, ShapeFileReadWriteMode.ReadWrite); //Gets all the features from the point shapefile to add to the new shapefile. Collection<Feature> features = PolygonShapeFileFeatureLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns); joinedShapeFileFeatureSource.Open(); joinedShapeFileFeatureSource.BeginTransaction(); //Loops thru all the features of the polygon based layer. foreach (Feature feature in features) { MultipolygonShape multiPolygonShape = (MultipolygonShape)feature.GetShape(); //Adds the columns of the polygon layer. Dictionary<string, string> Columns = new Dictionary<string, string>(); foreach (DbfColumn dbfColumn in dbfColumns) { Columns.Add(dbfColumn.ColumnName, feature.ColumnValues[dbfColumn.ColumnName]); } //Finds the features of the point based layer in common with the current polygon feature. //First, we do a regular SQL with the key columns common to both layers. If there is no match, we do a spatial query. DataTable dataTable = PointShapeFileFeatureLayer.QueryTools.ExecuteQuery("Select * From " + PointShapeFileFeatureLayer.Name + " Where " + PointJoiningDBFColumn.ColumnName + " = '" + feature.ColumnValues[PolygonJoiningDBFColumn.ColumnName] + "'"); //If result from SQL query. if (dataTable.Rows.Count > 0) { foreach (DbfColumn dbfColumn in ColumnsToJoin) { DataTable dataTable2 = PointShapeFileFeatureLayer.QueryTools.ExecuteQuery("Select Sum(" + dbfColumn.ColumnName + ") From " + PointShapeFileFeatureLayer.Name + " Where Country = '" + feature.ColumnValues["ISO_2DIGIT"] + "'"); Columns.Add(dbfColumn.ColumnName, System.Convert.ToString(dataTable2.Rows[0].ItemArray[0])); } } //If not result from SQl query, we do the Spatial Query to find what points are inside each polygon feature. else { Collection<Feature> distFeatures = PointShapeFileFeatureLayer.QueryTools.GetFeaturesWithinDistanceOf(multiPolygonShape, GeographyUnit.DecimalDegree, DistanceUnit.Kilometer, 50, ReturningColumnsType.AllColumns); foreach (DbfColumn dbfColumn in ColumnsToJoin) { int total = 0; foreach (Feature distFeature in distFeatures) { total = total + Convert.ToInt32(distFeature.ColumnValues[dbfColumn.ColumnName]); } Columns.Add(dbfColumn.ColumnName, System.Convert.ToString(total)); } } joinedShapeFileFeatureSource.AddFeature(multiPolygonShape,Columns); } joinedShapeFileFeatureSource.CommitTransaction(); joinedShapeFileFeatureSource.Close(); ShapeFileFeatureLayer joinedShapeFileFeatureLayer = new ShapeFileFeatureLayer(JoinedPolygonShapeFileFeatureLayerPath); return joinedShapeFileFeatureLayer; } private void DeleteSpatialJoinFiles() { File.Delete(@"..\..\Data\swineflucountries.shp"); File.Delete(@"..\..\Data\swineflucountries.ids"); File.Delete(@"..\..\Data\swineflucountries.idx"); File.Delete(@"..\..\Data\swineflucountries.dbf"); File.Delete(@"..\..\Data\swineflucountries.shx"); } 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(); } } }