yycGIS

我们曾如此渴望命运的波澜,到最后才发现:人生最曼妙的风景,竟是内心的淡定与从容。 我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系。

Less is more, more is different!

导航

AE(ArcEngine)定制工具Tool工具箱

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Text;
  4 using System.Runtime.InteropServices;
  5 using ESRI.ArcGIS.Geodatabase;
  6 using ESRI.ArcGIS.Geometry;
  7 using ESRI.ArcGIS.Geoprocessing;
  8 using ESRI.ArcGIS.esriSystem;
  9 using ESRI.ArcGIS.DataSourcesFile;
 10 using ESRI.ArcGIS.DataSourcesGDB;
 11 using ESRI.ArcGIS.ADF.CATIDs;
 12  
 13 namespace GPCalculateArea
 14 {
 15  
 16     public class CalculateAreaFunction : IGPFunction2
 17     {  
 18          private string m_ToolName = "CalculateArea"; //Function Name
 19         //Local members
 20         
 21         private string m_metadatafile = "CalculateArea_area.xml";
 22         private IArray m_Parameters;             // Array of Parameters
 23         private IGPUtilities m_GPUtilities;      // GPUtilities object
 24          
 25         public CalculateAreaFunction()
 26         {
 27             m_GPUtilities = new GPUtilitiesClass();
 28         }
 29  
 30         #region IGPFunction Members
 31  
 32         // Set the name of the function tool. 
 33         // This name appears when executing the tool at the command line or in scripting. 
 34         // This name should be unique to each toolbox and must not contain spaces.
 35         public string Name
 36         {
 37             get { return m_ToolName; }
 38         }
 39  
 40         // Set the function tool Display Name as seen in ArcToolbox.
 41         public string DisplayName
 42         {
 43             get { return "Calculate Area"; }
 44         }
 45  
 46         // This is the location where the parameters to the Function Tool are defined. 
 47         // This property returns an IArray of parameter objects (IGPParameter). 
 48         // These objects define the characteristics of the input and output parameters. 
 49         public IArray ParameterInfo
 50         {                 
 51             get
 52             {
 53                 //Array to the hold the parameters  
 54                 IArray parameters = new ArrayClass();
 55  
 56                 //Input DataType is GPFeatureLayerType
 57                 IGPParameterEdit3 inputParameter = new GPParameterClass();
 58                 inputParameter.DataType = new GPFeatureLayerTypeClass();
 59  
 60                 // Default Value object is GPFeatureLayer
 61                 inputParameter.Value = new GPFeatureLayerClass();
 62  
 63                 // Set Input Parameter properties
 64                 inputParameter.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
 65                 inputParameter.DisplayName = "Input Features";
 66                 inputParameter.Name = "input_features";
 67                 inputParameter.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;
 68                 parameters.Add(inputParameter);
 69  
 70                 // Area field parameter
 71                 inputParameter = new GPParameterClass();
 72                 inputParameter.DataType = new GPStringTypeClass();
 73  
 74                 // Value object is GPString
 75                 IGPString gpStringValue = new GPStringClass();
 76                 gpStringValue.Value = "Area";
 77                 inputParameter.Value = (IGPValue)gpStringValue;
 78  
 79                 // Set field name parameter properties
 80                 inputParameter.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;
 81                 inputParameter.DisplayName = "Area Field Name";
 82                 inputParameter.Name = "field_name";
 83                 inputParameter.ParameterType = esriGPParameterType.esriGPParameterTypeRequired; 
 84                 parameters.Add(inputParameter);
 85  
 86                 // Output parameter (Derived) and data type is DEFeatureClass
 87                 IGPParameterEdit3 outputParameter = new GPParameterClass();
 88                 outputParameter.DataType = new GPFeatureLayerTypeClass();
 89  
 90                 // Value object is DEFeatureClass
 91                 outputParameter.Value = new DEFeatureClassClass();
 92                                 
 93                 // Set output parameter properties
 94                 outputParameter.Direction = esriGPParameterDirection.esriGPParameterDirectionOutput;
 95                 outputParameter.DisplayName = "Output FeatureClass";
 96                 outputParameter.Name = "out_featureclass";
 97                 outputParameter.ParameterType = esriGPParameterType.esriGPParameterTypeDerived;
 98  
 99                 // Create a new schema object - schema means the structure or design of the feature class (field information, geometry information, extent)
100                 IGPFeatureSchema outputSchema = new GPFeatureSchemaClass();
101                 IGPSchema schema = (IGPSchema)outputSchema;
102  
103                 // Clone the schema from the dependency. 
104                 //This means update the output with the same schema as the input feature class (the dependency).                                
105                 schema.CloneDependency = true;               
106  
107                 // Set the schema on the output because this tool will add an additional field.
108                 outputParameter.Schema = outputSchema as IGPSchema;
109                 outputParameter.AddDependency("input_features");
110                 parameters.Add(outputParameter);
111  
112                 return parameters;
113             }
114         }
115  
116         // Validate: 
117         // - Validate is an IGPFunction method, and we need to implement it in case there
118         //   is legacy code that queries for the IGPFunction interface instead of the IGPFunction2 
119         //   interface.  
120         // - This Validate code is boilerplate - copy and insert into any IGPFunction2 code..
121         // - This is the calling sequence that the gp framework now uses when it QI's for IGPFunction2..
122         public IGPMessages Validate(IArray paramvalues, bool updateValues, IGPEnvironmentManager envMgr)
123         {
124             if (m_Parameters == null)
125                 m_Parameters = ParameterInfo;
126  
127             // Call UpdateParameters(). 
128             // Only Call if updatevalues is true.
129             if (updateValues == true)
130             {
131                 UpdateParameters(paramvalues, envMgr);
132             }
133  
134             // Call InternalValidate (Basic Validation). Are all the required parameters supplied?
135             // Are the Values to the parameters the correct data type?
136             IGPMessages validateMsgs = m_GPUtilities.InternalValidate(m_Parameters, paramvalues, updateValues, true, envMgr);
137  
138             // Call UpdateMessages();
139             UpdateMessages(paramvalues, envMgr, validateMsgs);
140  
141             // Return the messages
142             return validateMsgs;
143         }
144  
145         // This method will update the output parameter value with the additional area field.
146         public void UpdateParameters(IArray paramvalues, IGPEnvironmentManager pEnvMgr)
147         {
148             m_Parameters = paramvalues;
149  
150             // Retrieve the input parameter value
151             IGPValue parameterValue = m_GPUtilities.UnpackGPValue(m_Parameters.get_Element(0));
152  
153             // Get the derived output feature class schema and empty the additional fields. This will ensure you don't get duplicate entries.
154             IGPParameter3 derivedFeatures = (IGPParameter3)paramvalues.get_Element(2);
155             IGPFeatureSchema schema = (IGPFeatureSchema)derivedFeatures.Schema;
156             schema.AdditionalFields = null;
157  
158             // If we have an input value, create a new field based on the field name the user entered.            
159             if  (parameterValue.IsEmpty() == false)
160             {
161                 IGPParameter3 fieldNameParameter = (IGPParameter3)paramvalues.get_Element(1);
162                 string fieldName = fieldNameParameter.Value.GetAsText();
163                  
164                 // Check if the user's input field already exists
165                 IField areaField = m_GPUtilities.FindField(parameterValue, fieldName);
166                 if (areaField == null)
167                 {
168                     IFieldsEdit fieldsEdit = new FieldsClass();
169                     IFieldEdit fieldEdit = new FieldClass();
170                     fieldEdit.Name_2 = fieldName;
171                     fieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
172                     fieldsEdit.AddField(fieldEdit);
173  
174                     // Add an additional field for the area values to the derived output.
175                     IFields fields = fieldsEdit as IFields;                    
176                     schema.AdditionalFields = fields;
177                 }
178                  
179             }
180         }
181  
182         // Called after returning from the update parameters routine. 
183         // You can examine the messages created from internal validation and change them if desired. 
184         public void UpdateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr, IGPMessages Messages)
185         {
186             // Check for error messages
187             IGPMessage msg = (IGPMessage)Messages;
188             if (msg.IsError())
189                 return;    
190  
191             // Get the first Input Parameter
192             IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0);
193  
194             // UnPackGPValue. This ensures you get the value either form the dataelement or GpVariable (ModelBuilder)
195             IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter);
196  
197             // Open the Input Dataset - Use DecodeFeatureLayer as the input might be a layer file or a feature layer from ArcMap.
198             IFeatureClass inputFeatureClass;
199             IQueryFilter qf;
200             m_GPUtilities.DecodeFeatureLayer(parameterValue, out inputFeatureClass, out qf);
201  
202             IGPParameter3 fieldParameter = (IGPParameter3)paramvalues.get_Element(1);
203             string fieldName = fieldParameter.Value.GetAsText();
204  
205             // Check if the field already exists and provide a warning.
206             int indexA = inputFeatureClass.FindField(fieldName);
207             if (indexA > 0)
208             {
209                 Messages.ReplaceWarning(1, "Field already exists. It will be overwritten.");
210             }
211  
212             return;
213         }
214  
215         // Execute: Execute the function given the array of the parameters
216         public void Execute(IArray paramvalues, ITrackCancel trackcancel, IGPEnvironmentManager envMgr, IGPMessages message)
217         {
218              
219             // Get the first Input Parameter
220             IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0);
221  
222             // UnPackGPValue. This ensures you get the value either form the dataelement or GpVariable (ModelBuilder)
223            IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter);
224  
225             // Open Input Dataset
226             IFeatureClass inputFeatureClass;
227             IQueryFilter qf;
228             m_GPUtilities.DecodeFeatureLayer(parameterValue, out inputFeatureClass, out qf);
229  
230             if (inputFeatureClass == null)
231             {
232                 message.AddError(2, "Could not open input dataset.");
233                 return;
234             } 
235                  
236             // Add the field if it does not exist.
237             int indexA;
238  
239             parameter = (IGPParameter)paramvalues.get_Element(1);
240             string field = parameter.Value.GetAsText();
241  
242              
243             indexA = inputFeatureClass.FindField(field);
244             if (indexA < 0)
245             {
246                 IFieldEdit fieldEdit = new FieldClass();
247                 fieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;
248                 fieldEdit.Name_2 = field;
249                 inputFeatureClass.AddField(fieldEdit);
250             }
251  
252              int featcount = inputFeatureClass.FeatureCount(null);     
253        
254              //Set the properties of the Step Progressor
255             IStepProgressor pStepPro = (IStepProgressor)trackcancel;
256             pStepPro.MinRange = 0;
257             pStepPro.MaxRange = featcount;
258             pStepPro.StepValue = (1);
259             pStepPro.Message = "Calculating Area";
260             pStepPro.Position = 0;
261             pStepPro.Show();
262  
263             // Create an Update Cursor
264             indexA = inputFeatureClass.FindField(field);
265             IFeatureCursor updateCursor = inputFeatureClass.Update(qf, false);
266             IFeature updateFeature = updateCursor.NextFeature();
267             IGeometry geometry;
268             IArea area;
269             double dArea;   
270              
271             while (updateFeature != null)
272             {
273                 geometry = updateFeature.Shape;
274                 area = (IArea)geometry;
275                 dArea = area.Area;
276                 updateFeature.set_Value(indexA, dArea);
277                 updateCursor.UpdateFeature(updateFeature);
278                 updateFeature.Store();
279                 updateFeature = updateCursor.NextFeature();
280                 pStepPro.Step();
281             }
282  
283            pStepPro.Hide();
284              
285             // Release the update cursor to remove the lock on the input data.
286            System.Runtime.InteropServices.Marshal.ReleaseComObject(updateCursor);
287         }
288  
289         // This is the function name object for the Geoprocessing Function Tool. 
290         // This name object is created and returned by the Function Factory.
291         // The Function Factory must first be created before implementing this property.
292         public IName FullName
293         {
294             get
295             {   
296                 // Add CalculateArea.FullName getter implementation
297                 IGPFunctionFactory functionFactory = new CalculateAreaFunctionFactory();
298                 return (IName)functionFactory.GetFunctionName(m_ToolName);
299             }
300         }
301  
302         // This is used to set a custom renderer for the output of the Function Tool.
303         public object GetRenderer(IGPParameter pParam)
304         {
305             return null;
306         }
307  
308         // This is the unique context identifier in a [MAP] file (.h). 
309         // ESRI Knowledge Base article #27680 provides more information about creating a [MAP] file. 
310         public int HelpContext
311         {
312             get { return 0; }
313         }
314  
315         // This is the path to a .chm file which is used to describe and explain the function and its operation. 
316         public string HelpFile
317         {
318             get { return ""; }
319         }
320  
321         // This is used to return whether the function tool is licensed to execute.
322         public bool IsLicensed()
323         {
324             IAoInitialize aoi = new AoInitializeClass();
325             ILicenseInformation licInfo = (ILicenseInformation)aoi;
326  
327             string licName = licInfo.GetLicenseProductName(aoi.InitializedProduct());
328  
329             if (licName == "ArcInfo")
330             {
331                  return true;
332             }
333             else
334                 return false;
335         }
336  
337         // This is the name of the (.xml) file containing the default metadata for this function tool. 
338         // The metadata file is used to supply the parameter descriptions in the help panel in the dialog. 
339         // If no (.chm) file is provided, the help is based on the metadata file. 
340         // ESRI Knowledge Base article #27000 provides more information about creating a metadata file.
341         public string MetadataFile
342         {
343             get { return m_metadatafile; }
344         }
345  
346         // By default, the Toolbox will create a dialog based upon the parameters returned 
347         // by the ParameterInfo property.
348         public UID DialogCLSID
349         {
350             // DO NOT USE. INTERNAL USE ONLY.
351             get { return null; }
352         }
353  
354         #endregion
355     }
356  
357     //////////////////////////////
358     // Function Factory Class
359     ////////////////////////////
360     [
361     Guid("2554BFC7-94F9-4d28-B3FE-14D17599B35A"),
362     ComVisible(true)
363     ]
364     public class CalculateAreaFunctionFactory : IGPFunctionFactory
365     {
366         private const string m_ToolName = "ylArea"; //Function Name
367         // Register the Function Factory with the ESRI Geoprocessor Function Factory Component Category.
368         #region "Component Category Registration"
369         [ComRegisterFunction()]
370         static void Reg(string regKey)
371         {
372              
373             GPFunctionFactories.Register(regKey);
374         }
375  
376         [ComUnregisterFunction()]
377         static void Unreg(string regKey)
378         {
379             GPFunctionFactories.Unregister(regKey);
380         }
381         #endregion
382  
383         // Utility Function added to create the function names.
384         private IGPFunctionName CreateGPFunctionNames(long index)
385         {
386             IGPFunctionName functionName = new GPFunctionNameClass();
387             functionName.MinimumProduct = esriProductCode.esriProductCodeProfessional;
388             IGPName name;
389  
390             switch (index)
391             {
392                 case (0):
393                     name = (IGPName)functionName;
394                     name.Category = "AreaCalculation";
395                     name.Description = "Calculate Area for FeatureClass";
396                     name.DisplayName = "Calculate Area";
397                     name.Name = m_ToolName;                
398                     name.Factory = (IGPFunctionFactory)this;
399                     break;
400             }
401  
402             return functionName;
403         }
404  
405         // Implementation of the Function Factory
406         #region IGPFunctionFactory Members
407  
408         // This is the name of the function factory. 
409         // This is used when generating the Toolbox containing the function tools of the factory.
410         public string Name
411         {
412             get { return m_ToolName; }
413         }
414  
415         // This is the alias name of the factory.
416         public string Alias
417         {
418             get { return "area"; }
419         }
420  
421         // This is the class id of the factory. 
422         public UID CLSID
423         {
424             get
425             {
426                 UID id = new UIDClass();
427                 id.Value = this.GetType().GUID.ToString("B");
428                 return id;
429             }
430         }
431  
432         // This method will create and return a function object based upon the input name.
433         public IGPFunction GetFunction(string Name)
434         {
435             switch (Name)
436             {
437                 case (m_ToolName):
438                     IGPFunction gpFunction = new CalculateAreaFunction();
439                     return gpFunction;
440             }
441  
442             return null;
443         }
444  
445         // This method will create and return a function name object based upon the input name.
446         public IGPName GetFunctionName(string Name)
447         {
448             IGPName gpName = new GPFunctionNameClass();
449  
450             switch (Name)
451             {
452                 case (m_ToolName):
453                     return (IGPName)CreateGPFunctionNames(0);
454                     
455             }
456             return null;
457         }
458  
459         // This method will create and return an enumeration of function names that the factory supports.
460         public IEnumGPName GetFunctionNames()
461         {
462             IArray nameArray = new EnumGPNameClass();
463             nameArray.Add(CreateGPFunctionNames(0));
464             return (IEnumGPName)nameArray;
465         }
466  
467         // This method will create and return an enumeration of GPEnvironment objects. 
468         // If tools published by this function factory required new environment settings, 
469         //then you would define the additional environment settings here. 
470         // This would be similar to how parameters are defined. 
471         public IEnumGPEnvironment GetFunctionEnvironments()
472         {
473             return null;
474         }
475         
476  
477         #endregion
478     }
479  
480 }

 

posted on 2014-04-26 14:35  yycGIS  阅读(1320)  评论(0编辑  收藏  举报