ArcGIS Engine开发Geodatabase代码(一)——Cursors

/******************************************/
 * ESRI Developer Summit 2009
 * Developer's Guide to the Geodatabase
 * Code Samples
 * 6 April 2009

/******************************************/

偶然间整理电脑的文件夹,发现在Esri官网上曾经下载过关于Geodatabase开发的相关代码示例,赶紧跟各位共享一下

开发环境:

  • ArcGIS Engine9.3/9.3.1
  • VS2008


说明:该代码适用于ArcGIS Engine初学者,或者对Geodatabase开发感兴趣的朋友,如果你的Engine版本高于9.3.1,可能相关的接口会发生变化,这个需要用户自己来进行修改,但是聪明的用户不会局限于代码的是否允许,也许学习一下人家的接口使用方法,开发模式才是最重要的。

关于版本的接口差别参考:http://help.arcgis.com/en/sdk/10.0/arcobjects_net/conceptualhelp/index.html#/Type_changes_between_9_3_and_10/000100000408000000/

以上代码主要内容就是对ArcGIS Engine中关于Cursor的使用,特别是Search(查询功能),Insert(增加数据),Update(更新数据)等

重点关注:区别去普通Store的保存方法,使用featurecursor.UpdateCursor等


using System;
using System.IO;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace CursorDemo
{
	public class CursorDemo
	{
		public static void Main(string[] args)
		{
			#region Licensing
			// Set up the licencing. NOTE: This sample assumes that you are using ArcInfo Desktop.
			// You will need to adjust this code if using ArcEngine or ArcEditor.
			IAoInitialize aoInitialize = new AoInitializeClass();
			esriLicenseStatus licenseStatus = aoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
			if (licenseStatus != esriLicenseStatus.esriLicenseCheckedOut)
			{
				Console.WriteLine("Unable to check-out an ArcInfo license, error code is {0}", licenseStatus);
				return;
			}
			#endregion

			// If test data exists from a previous run, delete it.
			if (Directory.Exists("CursorDemo.gdb"))
			{
				Directory.Delete("CursorDemo.gdb", true);
			}

			// Copy the test data from this section's Data directory.
			Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
			IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
			IWorkspaceName sourceWorkspaceName = new WorkspaceNameClass
			{
				PathName = @"..\..\..\Data\CursorDemo.gdb",
				WorkspaceFactoryProgID = "esriDataSourcesGDB.FileGDBWorkspaceFactory"
			};
			IWorkspaceName copiedWorkspaceName = null;
			workspaceFactory.Copy(sourceWorkspaceName, Environment.CurrentDirectory, out copiedWorkspaceName);

			// Open the copied data.
			IName copiedName = (IName)copiedWorkspaceName;
			IWorkspace workspace = (IWorkspace)copiedName.Open();
			IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;

			// Open the two feature classes used in this demo.
			IFeatureClass parcelsFeatureClass = featureWorkspace.OpenFeatureClass("Parcels");
			IFeatureClass pipesFeatureClass = featureWorkspace.OpenFeatureClass("Pipes");

			// The first demo, SearchCursorDemo, will display the Parcel IDs of all residential
			// parcels within a certain extent.
			SearchCursorDemo(parcelsFeatureClass);

			// The second demo, UpdateCursorDemo, will change the all parcels zoned as "Manufacturing"
			// to "Commercial".
			UpdateCursorDemo(workspace, parcelsFeatureClass);

			// The third demo, InsertCursorDemo, will create one hundred new pipe features using
			// an insert cursor.
			InsertCursorDemo(workspace, pipesFeatureClass);

			// Shutdown the licensing.
			aoInitialize.Shutdown();
		}

		/// <summary>
		/// This sample queries a feature class of parcels, finding the Parcel IDs of all residential
		/// features that are within a given extent.
		/// </summary>
		/// <param name="featureClass">The feature class to query.</param>
		private static void SearchCursorDemo(IFeatureClass featureClass)
		{
			// Create an envelope that will define the spatial extent of the query.
			IEnvelope envelope = new EnvelopeClass();
			envelope.PutCoords(506000, 684500, 506500, 685000);

			// Create a new spatial filter.
			ISpatialFilter spatialFilter = new SpatialFilterClass
			{
				Geometry = envelope,
				GeometryField = featureClass.ShapeFieldName,
				SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects,
				SubFields = "Parcel_ID",
				WhereClause = "ZONING_S = 'R'"
			};

			// Find the index of the Parcel_ID field. This is required to display the query results.
			int parcelIdIndex = featureClass.FindField("Parcel_ID");

			using (ComReleaser comReleaser = new ComReleaser())
			{
				// Query the feature class to get a feature cursor. We can use a recycling
				// cursor because we're only going to be reading the data.
				IFeatureCursor featureCursor = featureClass.Search(spatialFilter, true);
				comReleaser.ManageLifetime(featureCursor);

				// Iterate through the query results.
				IFeature feature = null;
				while ((feature = featureCursor.NextFeature()) != null)
				{
					// Display the current feature's Parcel ID.
					Console.WriteLine("Parcel found: {0}", feature.get_Value(parcelIdIndex));
				}
				// Display the number of feature matching the query.
				Console.WriteLine("Parcels found: {0}", featureClass.FeatureCount(spatialFilter));
			}
		}

		/// <summary>
		/// This sample re-zones all "Manufacturing" parcels as "Commercial".
		/// </summary>
		/// <param name="workspace">The workspace containing the feature class.</param>
		/// <param name="featureClass">The feature class to update.</param>
		private static void UpdateCursorDemo(IWorkspace workspace, IFeatureClass featureClass)
		{
			// Create a new query filter for the update.
			IQueryFilter queryFilter = new QueryFilterClass { WhereClause = "ZONING_S = 'M'" };

			// Display the feature's zoned as Manufacturing.
			Console.WriteLine("Parcel found zoned as Manufacturing: {0}", featureClass.FeatureCount(queryFilter));

			// Find the index of the Zoning_S field. This is required for the update.
			int zoningIndex = featureClass.FindField("ZONING_S");

			// Start a new edit session and edit operation.
			IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;
			workspaceEdit.StartEditing(true);
			workspaceEdit.StartEditOperation();

			using (ComReleaser comReleaser = new ComReleaser())
			{
				// Query the feature class to get a feature cursor. Since we are performing
				// updates, we should use a non-recycling cursor.
				IFeatureCursor featureCursor = featureClass.Update(queryFilter, false);
				comReleaser.ManageLifetime(featureCursor);

				try
				{
					// Iterate through the query results.
					IFeature feature = null;
					while ((feature = featureCursor.NextFeature()) != null)
					{
						// Change the feature's ZONING_S value to "B" (the code for Business/Commercial).
						feature.set_Value(zoningIndex, "B");

						// Update the feature.
						featureCursor.UpdateFeature(feature);
					}

					// All of the features were successfully updated; stop the edit operation
					// and stop the edit session, saving the changes made in edit operations.
					workspaceEdit.StopEditOperation();
					workspaceEdit.StopEditing(true);
				}
				catch (COMException)
				{
					// An error occurred while editing. Abort the edit operation and stop the
					// edit session, discarding any changes made in edit operations.
					workspaceEdit.AbortEditOperation();
					workspaceEdit.StopEditing(false);
				}

				// Display the feature's zoned as Manufacturing after update.
				Console.WriteLine("Parcel found zoned as Manufacturing after update: {0}", featureClass.FeatureCount(queryFilter));
			}
		}

		/// <summary>
		/// This sample uses an insert cursor to create one hundred new pipe features.
		/// </summary>
		/// <param name="workspace">The workspace containing the feature class.</param>
		/// <param name="featureClass">The feature class to insert new features into.</param>
		private static void InsertCursorDemo(IWorkspace workspace, IFeatureClass featureClass)
		{
			// Find the index of the "Contractor" field. This will be edited in the new features.
			int contractorIndex = featureClass.FindField("CONTRACTOR");

			// Put the feature class into "load-only" mode. In a File GDB, this will disable spatial
			// and attribute indexing, improving performance for data loading.
			IFeatureClassLoad featureClassLoad = (IFeatureClassLoad)featureClass;
			featureClassLoad.LoadOnlyMode = true;

			// Start an edit session and edit operation.
			IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;
			workspaceEdit.StartEditing(true);
			workspaceEdit.StartEditOperation();

			// Open the two text files containing the contractor's data.
			using (StreamReader geometryReader = new StreamReader(@"PipeGeo.csv"))
			using (StreamReader attributeReader = new StreamReader(@"PipeAttr.csv"))
			using (ComReleaser comReleaser = new ComReleaser())
			{
				// Create a new insert cursor with buffering.
				IFeatureCursor featureCursor = featureClass.Insert(true);
				comReleaser.ManageLifetime(featureCursor);

				// Create a feature buffer. This will store the values common to every
				// feature to be installed.
				IFeatureBuffer featureBuffer = featureClass.CreateFeatureBuffer();
				comReleaser.ManageLifetime(featureBuffer);
				featureBuffer.set_Value(contractorIndex, "B Pierce");

				try
				{
					while (!geometryReader.EndOfStream && !attributeReader.EndOfStream)
					{
						// Read the next line from each text file.
						String geometryData = geometryReader.ReadLine();
						String attributeData = attributeReader.ReadLine();

						// Set the geometry and attribute values of the feature buffer.
						featureBuffer.Shape = ConstructGeometryFromString(geometryData);
						PopulateAttributeValues(featureBuffer, attributeData);

						// Insert a new feature using the feature buffer.
						featureCursor.InsertFeature(featureBuffer);
					}

					// Flush the cursor.
					featureCursor.Flush();

					// All of the features were successfully inserted; stop the edit operation
					// and stop the edit session, saving the changes made in edit operations.
					workspaceEdit.StopEditOperation();
					workspaceEdit.StopEditing(true);
				}
				catch (COMException)
				{
					// An error occurred while editing. Abort the edit operation and stop the
					// edit session, discarding any changes made in edit operations.
					workspaceEdit.AbortEditOperation();
					workspaceEdit.StopEditing(false);
				}
			}

			// Take the class out of load-only mode.
			featureClassLoad.LoadOnlyMode = false;
		}

		/// <summary>
		/// This method converts a comma-delimited set of numeric values into a polyline.
		/// </summary>
		/// <param name="input">A string of comma-delimited numeric values.</param>
		/// <returns>A polyline.</returns>
		private static IGeometry ConstructGeometryFromString(String input)
		{
			// Split the input string into individual values.
			String[] inputValues = input.Split(new char[] {','});

			// Create a new polyline.
			IPolyline polyline = new PolylineClass();
			IGeometryCollection geometryCollection = (IGeometryCollection)polyline;

			// Each set of four values represents one segment of a polyline.
			int segmentCount = inputValues.Length / 4;
			int inputValuePosition = 0;
			for (int i = 0; i < segmentCount; i++)
			{
				// This value is required for geometry construction.
				object missingType = Type.Missing;

				// Construct the segment.
				IPoint fromPoint = new PointClass
				{
					X = Double.Parse(inputValues[inputValuePosition++]),
					Y = Double.Parse(inputValues[inputValuePosition++])
				};
				IPoint toPoint = new PointClass
				{
					X = Double.Parse(inputValues[inputValuePosition++]),
					Y = Double.Parse(inputValues[inputValuePosition++])
				};
				IPath path = new PathClass();
				IPointCollection pointCollection = (IPointCollection)path;
				pointCollection.AddPoint(fromPoint, ref missingType, ref missingType);
				pointCollection.AddPoint(toPoint, ref missingType, ref missingType);

				// Add the segment to the collection.
				geometryCollection.AddGeometry(path, ref missingType, ref missingType);
			}

			// Return the constructed polyline.
			return polyline;
		}

		/// <summary>
		/// Populates the inbound feature buffer with the comma-delimited values
		/// in the input string.
		/// </summary>
		/// <param name="featureBuffer">The feature buffer to populate.</param>
		/// <param name="input">A string containing attribute values.</param>
		private static void PopulateAttributeValues(IFeatureBuffer featureBuffer, String input)
		{
			// Split the input string into individual values.
			String[] inputValues = input.Split(new char[] { ',' });

			// Set the values of the Date_Installed, material and diameter fields.
			// For the sake of simplicity, we'll hard-code the values here.
			featureBuffer.set_Value(2, inputValues[0]);
			featureBuffer.set_Value(4, inputValues[1]);
			featureBuffer.set_Value(5, inputValues[2]);
		}
	}
}


普通的编辑方法

using System;
using System.IO;
using System.Runtime.InteropServices;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;

namespace EditingDemo
{
	public class EditingDemo
	{
		public static void Main(string[] args)
		{
			#region Licensing
			// Set up the licencing. NOTE: This sample assumes that you are using ArcInfo Desktop.
			// You will need to adjust this code if using ArcEngine or ArcEditor.
			IAoInitialize aoInitialize = new AoInitializeClass();
			esriLicenseStatus licenseStatus = aoInitialize.Initialize(esriLicenseProductCode.esriLicenseProductCodeArcInfo);
			if (licenseStatus != esriLicenseStatus.esriLicenseCheckedOut)
			{
				Console.WriteLine("Unable to check-out an ArcInfo license, error code is {0}", licenseStatus);
				return;
			}
			#endregion

			// If test data exists from a previous run, delete it.
			if (Directory.Exists("EditingDemo.gdb"))
			{
				Directory.Delete("EditingDemo.gdb", true);
			}

			// Copy the test data from this section's Data directory.
			Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.FileGDBWorkspaceFactory");
			IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
			IWorkspaceName sourceWorkspaceName = new WorkspaceNameClass();
			sourceWorkspaceName.PathName = @"..\..\..\Data\EditingDemo.gdb";
			sourceWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.FileGDBWorkspaceFactory";
			IWorkspaceName copiedWorkspaceName = null;
			workspaceFactory.Copy(sourceWorkspaceName, Environment.CurrentDirectory, out copiedWorkspaceName);

			// Open the copied data.
			IName copiedName = (IName)copiedWorkspaceName;
			IWorkspace workspace = (IWorkspace)copiedName.Open();
			IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace;
			IFeatureClass featureClass = featureWorkspace.OpenFeatureClass("Points");

			// Create two points: one with valid coordinates, one with invalid coordinates.
			// Note that the data uses a geographic coordinate system.
			IPoint validPoint = new PointClass { X = 45, Y = 45 };
			IPoint invalidPoint = new PointClass { X = 1000, Y = -1000 };

			// Start an edit session and an edit operation.
			IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)workspace;
			workspaceEdit.StartEditing(true);
			workspaceEdit.StartEditOperation();

			// Create a new feature using the valid point.
			try
			{
				IFeature feature = featureClass.CreateFeature();
				feature.Shape = validPoint;
				feature.Store();

				// Stop the edit operation.
				workspaceEdit.StopEditOperation();
			}
			catch (COMException comExc)
			{
				Console.WriteLine("An error occurred ({0}): {1}", comExc.ErrorCode, comExc.Message);

				// Abort the edit operation.
				workspaceEdit.AbortEditOperation();
			}

			// Create a new feature using the invalid point.
			try
			{
				IFeature feature = featureClass.CreateFeature();
				feature.Shape = invalidPoint;
				feature.Store();

				// Stop the edit operation.
				workspaceEdit.StopEditOperation();
			}
			catch (COMException comExc)
			{
				Console.WriteLine("An error occurred ({0}): {1}", comExc.ErrorCode, comExc.Message);

				// Abort the edit operation.
				workspaceEdit.AbortEditOperation();
			}

			// Stop the edit operation, saving the changes from any committed edit operations.
			workspaceEdit.StopEditing(true);

			// Shut down the licensing.
			aoInitialize.Shutdown();
		}
	}
}

请点击源代码的下载以及相关测试数据

你可能感兴趣的:(ArcGIS Engine开发Geodatabase代码(一)——Cursors)