====== Source Code ServicesEditionSample SpatialJoin CS 090918.zip ====== ====Program.cs==== using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; namespace SpatialJoin { static class Program { /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new TestForm()); } } } ====TestForm.cs==== using System; using System.Drawing; using System.Windows.Forms; using System.Data; using System.IO; using ThinkGeo.MapSuite.Core; using System.Collections.Generic; using System.Collections.ObjectModel; namespace SpatialJoin { public partial class TestForm : Form { private MapEngine mapEngine = new MapEngine(); private Bitmap bitmap = null; ShapeFileFeatureLayer worldLayer = null; ShapeFileFeatureLayer citiesLayer = null; public TestForm() { InitializeComponent(); } private void TestForm_Load(object sender, EventArgs e) { // Set the extent and the background color mapEngine.CurrentExtent = ExtentHelper.GetDrawingExtent(new RectangleShape(-9.63, 61.30, 28.38, 34.07), Map.Width, Map.Height); mapEngine.BackgroundFillBrush = new GeoSolidBrush(GeoColor.GeographicColors.ShallowOcean); // Add the static layers to the MapEngine worldLayer = new ShapeFileFeatureLayer(@"..\..\Data\Countries02.shp", ShapeFileReadWriteMode.ReadOnly); worldLayer.ZoomLevelSet.ZoomLevel01.DefaultAreaStyle = AreaStyles.County1; worldLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("WorldLayer", worldLayer); citiesLayer = new ShapeFileFeatureLayer(@"..\..\Data\worldcapitals.shp", ShapeFileReadWriteMode.ReadOnly); citiesLayer.ZoomLevelSet.ZoomLevel01.DefaultPointStyle = PointStyles.Capital2; citiesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("citiesLayer", citiesLayer); ShapeFileFeatureLayer labelCitiesLayer = new ShapeFileFeatureLayer(@"..\..\Data\worldcapitals.shp", ShapeFileReadWriteMode.ReadOnly); labelCitiesLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("City_name", "Arial", 10, DrawingFontStyles.Regular, GeoColor.SimpleColors.Black, 10, 0); labelCitiesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("labelCitiesLayer", labelCitiesLayer); DrawImage(); } private void btnSpatialJoin_Click(object sender, EventArgs e) { label1.Text = "Creating new shapefile joining atribute data of world layer to cities layer. Please wait..."; label1.Refresh(); //deletes the files for the spatial joined shapefile if they already exist. if (File.Exists(@"..\..\Data\worldcapitals2.shp")) { DeleteSpatialJoinFiles(); } //Gets the collumns from the world layer to add for the spatial join. Here we will add "iso_3digit" and "cntry_name". worldLayer.Open(); Collection dbfColumns = ((ShapeFileFeatureSource)worldLayer.FeatureSource).GetDbfColumns(); Collection dbfColumnsToJoin = new Collection(); dbfColumnsToJoin.Add(dbfColumns[3]); dbfColumnsToJoin.Add(dbfColumns[4]); worldLayer.Close(); //Calls SpatialJoin function to create the new shapefile from the spatial join. ShapeFileFeatureLayer joinedFeatureLayer = SpatialJoin(worldLayer, dbfColumnsToJoin, citiesLayer, @"..\..\Data\worldcapitals2.shp"); mapEngine.StaticLayers.Remove("labelCitiesLayer"); //Adds the new shapefile labeling the both the columns for city name and country abbreviation. ShapeFileFeatureLayer labelCitiesLayer = new ShapeFileFeatureLayer(@"..\..\Data\worldcapitals2.shp", ShapeFileReadWriteMode.ReadOnly); //The column "MergedColumn" does not exist in the dbf but will be used in the CustomColumnFetch. labelCitiesLayer.ZoomLevelSet.ZoomLevel01.DefaultTextStyle = TextStyles.CreateSimpleTextStyle("MergedColumn", "Arial", 10, DrawingFontStyles.Regular, GeoColor.SimpleColors.Black, 10, 0); labelCitiesLayer.ZoomLevelSet.ZoomLevel01.ApplyUntilZoomLevel = ApplyUntilZoomLevel.Level20; mapEngine.StaticLayers.Add("labelCitiesLayer", labelCitiesLayer); //Hooks up the event for CustomColumnFetch used to label two columns. ((ShapeFileFeatureSource)labelCitiesLayer.FeatureSource).CustomColumnFetch += new EventHandler(DisplayShapeMap_CustomColumnFetch); DrawImage(); label1.Text = ""; } private ShapeFileFeatureLayer SpatialJoin(ShapeFileFeatureLayer PolygonShapeFileFeatureLayer, Collection ColumnsToJoin, ShapeFileFeatureLayer PointShapeFileFeatureLayer, string JoinedPointShapeFileFeatureLayerPath) { PolygonShapeFileFeatureLayer.Open(); PointShapeFileFeatureLayer.Open(); //Gets the columns from the Point based shapefile and we add the columns from the polygon shapefile to add. Collection pointDbfColumns = ((ShapeFileFeatureSource)PointShapeFileFeatureLayer.FeatureSource).GetDbfColumns(); foreach (DbfColumn dbfColumn in ColumnsToJoin) { pointDbfColumns.Add(dbfColumn); } //Creates the new shapefile based on new columns. ShapeFileFeatureLayer.CreateShapeFile(ShapeFileType.Point, JoinedPointShapeFileFeatureLayerPath, pointDbfColumns); //Creates the shapefile feature source for adding the features with the info for the columns to join. ShapeFileFeatureSource joinedShapeFileFeatureSource = new ShapeFileFeatureSource(JoinedPointShapeFileFeatureLayerPath, ShapeFileReadWriteMode.ReadWrite); //Gets all the features from the point shapefile to add to the new shapefile. Collection features = PointShapeFileFeatureLayer.FeatureSource.GetAllFeatures(ReturningColumnsType.AllColumns); joinedShapeFileFeatureSource.Open(); joinedShapeFileFeatureSource.BeginTransaction(); foreach (Feature feature in features) { joinedShapeFileFeatureSource.AddFeature(feature); } joinedShapeFileFeatureSource.CommitTransaction(); //Loops thru the features of the point layer to find out to what record of the polygon layer they belong joinedShapeFileFeatureSource.BeginTransaction(); foreach (Feature feature in features) { PointShape pointShape = (PointShape)feature.GetShape(); //Uses the spatial query. Collection spatialQueryResults = PolygonShapeFileFeatureLayer.QueryTools.GetFeaturesContaining(pointShape, ReturningColumnsType.AllColumns); //Adds the atribute info for the columns to add according to the result of the spatial query. Feature currentFeature = joinedShapeFileFeatureSource.GetFeatureById(feature.Id, ReturningColumnsType.AllColumns); foreach (DbfColumn column in ColumnsToJoin) { currentFeature.ColumnValues[column.ColumnName] = spatialQueryResults[0].ColumnValues[column.ColumnName]; } joinedShapeFileFeatureSource.UpdateFeature(currentFeature); } joinedShapeFileFeatureSource.CommitTransaction(); joinedShapeFileFeatureSource.Close(); ShapeFileFeatureLayer joinedShapeFileFeatureLayer = new ShapeFileFeatureLayer(JoinedPointShapeFileFeatureLayerPath); return joinedShapeFileFeatureLayer; } private void DeleteSpatialJoinFiles() { File.Delete(@"..\..\Data\worldcapitals2.shp"); File.Delete(@"..\..\Data\worldcapitals2.ids"); File.Delete(@"..\..\Data\worldcapitals2.idx"); File.Delete(@"..\..\Data\worldcapitals2.dbf"); File.Delete(@"..\..\Data\worldcapitals2.shx"); } //Event used for labeling based on two columns. void DisplayShapeMap_CustomColumnFetch(object sender, CustomColumnFetchEventArgs e) { if (e.ColumnName == "MergedColumn") { ShapeFileFeatureLayer labelCitiesLayer = (ShapeFileFeatureLayer)mapEngine.StaticLayers["labelCitiesLayer"]; Feature currentFeature = labelCitiesLayer.QueryTools.GetFeatureById(e.Id, ReturningColumnsType.AllColumns); e.ColumnValue = currentFeature.ColumnValues["city_name"] + "(" + currentFeature.ColumnValues["iso_3digit"] + ")"; } } 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(); } } }