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

来源:互联网 发布:珠海淘宝托管 编辑:程序博客网 时间:2024/04/28 05:55
/******************************************/
 * 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();}}}

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

原创粉丝点击