MapWinGIS:SampleCode-C Sharp Net:MergeShapefiles

This is a back-up of the WIKI.
Not all links might work
We're working on a new wiki.

Main Page | Recent changes | View source | Page history | Log in / create account |

Printable version | Disclaimers | Privacy policy

Merge Shapefiles

This code will take two input shapefiles of the same type and append the shapes of the second shapefile to the first and save the result in a new shapefile. The attribute fields with the same name, but a different data type will cause an error. Attribute fields with the same name will be assumed to be a common field.

 // This code requires a reference to MapWinGIS.ocx and MapWinGeoProc.dll
 // MapWinGeoProc is only used for obtaining filenames using a dialog.
 
 using System.Collections.Generic;
 using System.Windows.Forms;
 
 namespace OCXTestCS
 {
     /// <summary>
     /// This class holds code that can merge two shapefiles of the same type.
     /// </summary>
     public class MergeShapefiles
     {
         #region Variables
 
         private MapWinGIS.Shapefile _inSF1;
         private MapWinGIS.Shapefile _inSF2;
         private MapWinGIS.Shapefile _outSF;
 
         private string _inFile1;
         private string _inFile2;
         private string _outFile;
 
         #endregion
 
         #region Constructors
 
         /// <summary>
         /// Creates a new instance of the AppendShapes class
         /// </summary>
         /// <param name="inMap">The map to add the merged shape to</param>
         public MergeShapefiles()
         {
           
         }
         #endregion
 
         #region Methods
 
         /// <summary>
         /// Actually engages the append shapes process
         /// </summary>
         public void DoMergeShapefiles()
         {
             string errorMessage;
             _inSF1 = new MapWinGIS.Shapefile();
             _inSF2 = new MapWinGIS.Shapefile();
             _outSF = new MapWinGIS.Shapefile();
 
             GetFilenames();
 
             if (OpenFiles(out errorMessage) == false)
             {
                 MessageBox.Show(errorMessage,"File Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 return;
             }
 
 
             if (_outSF.StartEditingShapes(true, null) == false)
             {
                 CloseMessage(_outSF.get_ErrorMsg(_outSF.LastErrorCode));
                 return;
             }
 
             // Determine a list of unique fields to add to the output shapefile.
             if (CombineFields(out errorMessage) == false)
             {
                 CloseMessage(errorMessage);
                 return;
             }
 
             if (AddShapes(_inSF1, out errorMessage) == false)
             {
                 CloseMessage(errorMessage);
                 return;
             }
 
             if (AddShapes(_inSF2, out errorMessage) == false)
             {
                 CloseMessage(errorMessage);
                 return;
             }
 
             _inSF2.Close();
             _inSF1.Close();
             if (_outSF.StopEditingShapes(true, true, null) == false)
             {
                 MessageBox.Show(_outSF.get_ErrorMsg(_outSF.LastErrorCode));
                 return;
             }
 
             _outSF.Close();
             MessageBox.Show("Done Merging Shapes.");
 
            
         }
 
         // Close files and show an error message
         private void CloseMessage(string message)
         {
             if(_outSF != null) _outSF.Close();
             if (_inSF1 != null) _inSF1.Close();
             if (_inSF2 != null) _inSF2.Close();
             MessageBox.Show(message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
             
         }
 
 
         // Use a file dialog to obtain the filenames
         private void GetFilenames()
         {
             MapWinGeoProc.Dialogs.GeoProcDialog dialog = new MapWinGeoProc.Dialogs.GeoProcDialog();
 
             //
             // File Element 1
             //
             MapWinGeoProc.Dialogs.FileElement file1 = dialog.Add_FileElement(MapWinGeoProc.Dialogs.GeoProcDialog.ElementTypes.OpenShapefile);
             file1.Caption = "First input shapefile";
             file1.HelpButtonVisible = false;
             //
             // File Element 2
             //
             MapWinGeoProc.Dialogs.FileElement file2 = dialog.Add_FileElement(MapWinGeoProc.Dialogs.GeoProcDialog.ElementTypes.OpenShapefile);
             file2.Caption = "Second input shapefile";
             file2.HelpButtonVisible = false;
             //
             // Out File Element
             //
             MapWinGeoProc.Dialogs.FileElement outFile = dialog.Add_FileElement(MapWinGeoProc.Dialogs.GeoProcDialog.ElementTypes.SaveShapefile);
             outFile.Caption = "Output Shapefile";
             outFile.HelpButtonVisible = false;
 
             // Show a dialog to get the filenames to work with
             if (dialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
 
             _inFile1 = file1.Filename;
             _inFile2 = file2.Filename;
             _outFile = outFile.Filename;
         }
 
         // Try to open the shapefiles, return false if there was a problem 
         private bool OpenFiles(out string errorMessage)
         {
             errorMessage = "No Error";
 
             // Try to open the filenames and test that they are the same type of shapefile
             if (_inSF1.Open(_inFile1, null) == false)
             {
                 errorMessage = _inSF1.get_ErrorMsg(_inSF1.LastErrorCode);
                 return false;
             }
             if (_inSF2.Open(_inFile2, null) == false)
             {
                 _inSF1.Close();
                 errorMessage = _inSF2.get_ErrorMsg(_inSF1.LastErrorCode);
                 return false;
             }
             if (_inSF1.ShapefileType != _inSF2.ShapefileType)
             {
                 _inSF1.Close();
                 _inSF2.Close();
                 errorMessage = "Shape types were incompatible: " + _inSF1.ShapefileType.ToString() + " != " + _inSF2.ShapefileType.ToString();
                 return false;
             }
 
             // Create the output shapefile and prepare it for editing
             if (_outSF.CreateNew(_outFile, _inSF1.ShapefileType) == false)
             {
                 _inSF1.Close();
                 _inSF2.Close();
                 errorMessage = _outSF.get_ErrorMsg(_outSF.LastErrorCode);
                 return false;
             }
             return true;
         }
 
         // Build a list of unique fields for the output file
         private bool CombineFields(out string errorMessage)
         {
             errorMessage = "No Error";
             List<MapWinGIS.Field> fields = new List<MapWinGIS.Field>();
             List<string> names = new List<string>();
             for (int fld = 0; fld < _inSF1.NumFields; fld++)
             {
                 MapWinGIS.Field field = _inSF1.get_Field(fld);
                 fields.Add(field);
                 names.Add(field.Name);
             }
             for (int fld = 0; fld < _inSF2.NumFields; fld++)
             {
                 MapWinGIS.Field field = _inSF2.get_Field(fld);
                 string name = field.Name;
                 if (names.Contains(name) == false)
                 {
                     fields.Add(field);
                     names.Add(name);
                 }
                 else
                 {
                     if (fields[names.IndexOf(name)].Type != field.Type)
                     {
                         errorMessage = "Fields with a common name [" + name + "] did not share the same type.";
                         return false;
                     }
                 }
             }
 
             int fi = 0;
             foreach (MapWinGIS.Field field in fields)
             {
                 if (_outSF.EditInsertField(field, ref fi, null) == false)
                 {
                     errorMessage = _outSF.get_ErrorMsg(_outSF.LastErrorCode);
                     return false;
                 }
                 fi++;
             }
             return true;
         }
 
         // Add the shapes one by one
         private bool AddShapes(MapWinGIS.Shapefile inSF, out string errorMessage)
         {
             errorMessage = "No Error.";
             int outShp = _outSF.NumShapes;
             // Add all the shapes and attributes from the first shapefile
             for (int shp = 0; shp < inSF.NumShapes; shp++)
             {
                 MapWinGIS.Shape shape = inSF.get_Shape(shp);
                 _outSF.EditInsertShape(shape, ref outShp);
                 for (int fld = 0; fld < inSF.NumFields; fld++)
                 {
                     string name = inSF.get_Field(fld).Name;
                     int index = IndexOf(name);
                     if (index == -1)
                     {
                         errorMessage = "Could not find a field in the output shapefile: [" + name + "]";
                         return false;
                     }
                     if (_outSF.EditCellValue(index, outShp, inSF.get_CellValue(fld, shp))==false)
                     {
                         errorMessage = _outSF.get_ErrorMsg(_outSF.LastErrorCode);
                         return false;
                     }
                 }
                 outShp++;
             }
             return true;
            
         }
 
         // Use the string name to test each field in the output shapefile to determine the correct index
         private int IndexOf(string fieldName)
         {
             for (int fld = 0; fld < _outSF.NumFields; fld++)
             {
                 if (_outSF.get_Field(fld).Name == fieldName) return fld;
             }
             return -1;
         }
 
         #endregion
 
     }
 }



                             USING THE CLASS

 using System;
 using System.Windows.Forms;
 
 namespace OCXTestCS
 {
     public partial class Form1 : Form
     {
         private MergeShapefiles ms;
 
         public Form1()
         {
             InitializeComponent();
             ms = new MergeShapefiles();
         }
 
         private void cmdTest_Click(object sender, EventArgs e)
         {
             ms.DoMergeShapefiles();
         }
     }
 }

Code posted 12/3/2008 By Shade1974

Retrieved from "http://mapwindow.org/wiki/index.php/MapWinGIS:SampleCode-C_Sharp_Net:MergeShapefiles"

This page has been accessed 2,021 times. This page was last modified on 3 December 2008, at 17:56.