====== 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();
}
}
}