• ArcGIS 10.1 发布使用ArcEngine自定义的GP服务


    1. 新建立GP模型

    在VS2010中新建一个普通的程序及,引入ArcEngine相关的dll。在该DLL中定义一个或多个GP类和一个GP工厂类。GP类要继承IGPFunction2接口,GP工厂类要继承IGPFunctionFactory接口。

    下面是各个接口的一些实现方法

    IGPFunction2

    接口

    接口意义

    UID DialogCLSID { get; }

    对话框的类标识,该方法在实现时直接返回为空即可。

    public UID DialogCLSID{ get{ return null; }}

    string DisplayName { get; }

    该GP工具显示的名字 显示的名字和FullName中设置的一致。

    IName FullName { get; }

    IGPFunctionName functionName = new GPFunctionNameClass();

    functionName.MinimumProduct = esriProductCode.esriProductCodeAdvanced;

    IGPName name;

    name = (IGPName)functionName;

    name.Category = "AreaCalculation0";//分组名称

    name.Description = "Calculate Area for FeatureClass0";//GP工具的描述信息

    name.DisplayName = "Calculate Area0";//GP工具显示的名称

    name.Name = "CalculateArea0";//GP工具的名称

    name.Factory = new 所属的工厂类//GP工具所属的工厂类

    int HelpContext { get; }

    帮助文件的上下文 直接返回0即可。

    string HelpFile { get; }

    帮助文件路径,直接返回空字符串即可。

    string MetadataFile { get; }

    元数据文件,返回空字符串即可。

    string Name { get; }

    返回GP工具的名字,名字和fullName中设置的名字一致

    IArray ParameterInfo { get; }

    参数列表,定义系统输入和输出的参数

    //定义参数列表

    IArray myParameters = new ArrayClass();

    //定义一个输入参数

    IGPParameterEdit myP1 = new GPParameterClass();

    myParameters.Add(myP1);

    myP1.DataType = new GPFeatureLayerTypeClass();

    myP1.Value = new GPFeatureLayerClass();

    myP1.Direction = esriGPParameterDirection.esriGPParameterDirectionInput;

    myP1.DisplayName = "Input Features";

    myP1.Name = "Input_Features";

    myP1.ParameterType = esriGPParameterType.esriGPParameterTypeRequired;

    //定义一个输出

    IGPParameterEdit myP2 = new GPParameterClass();

    myParameters.Add(myP2);

    myP2.DataType = new GPDoubleTypeClass();

    myP2.Direction = esriGPParameterDirection.esriGPParameterDirectionOutput;

    myP2.ParameterType = esriGPParameterType.esriGPParameterTypeDerived;

    myP2.DisplayName = "Out FeatureCount";

    myP2.DisplayOrder = 0;

    myP2.Name = "Out_FeatureCount";

    return myParameters;

    void Execute(IArray paramvalues, ITrackCancel TrackCancel, IGPEnvironmentManager envMgr, IGPMessages message);

    代码执行

    //得到第一个参数

    IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0);

    //IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter);

    // 获取参数值

    IFeatureClass inputFeatureClass;

    IQueryFilter qf;

    m_GPUtilities.DecodeFeatureLayer(parameterValue, out inputFeatureClass, out qf);

    if (inputFeatureClass == null)

    {

    message.AddError(2, "Could not open input dataset.");

    return;

    }

    // 下面就是处理逻辑的代码了

    int indexA;

    parameter = (IGPParameter)paramvalues.get_Element(1);

    string field = parameter.Value.GetAsText();

    indexA = inputFeatureClass.FindField(field);

    if (indexA < 0)

    {

    IFieldEdit fieldEdit = new FieldClass();

    fieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;

    fieldEdit.Name_2 = field;

    inputFeatureClass.AddField(fieldEdit);

    }

    int featcount = inputFeatureClass.FeatureCount(null);

    //设置进度信息

    IStepProgressor pStepPro = (IStepProgressor)trackcancel;

    pStepPro.MinRange = 0;

    pStepPro.MaxRange = featcount;

    pStepPro.StepValue = (1);

    pStepPro.Message = "Calculating Area0";

    pStepPro.Position = 0;

    pStepPro.Show();

    // Create an Update Cursor

    indexA = inputFeatureClass.FindField(field);

    IFeatureCursor updateCursor = inputFeatureClass.Update(qf, false);

    IFeature updateFeature = updateCursor.NextFeature();

    IGeometry geometry;

    IArea area;

    double dArea;

    while (updateFeature != null)

    {

    geometry = updateFeature.Shape;

    area = (IArea)geometry;

    dArea = area.Area;

    updateFeature.set_Value(indexA, dArea);

    updateCursor.UpdateFeature(updateFeature);

    updateFeature.Store();

    updateFeature = updateCursor.NextFeature();

    pStepPro.Step();

    }

    pStepPro.Hide();

    //释放资源

    System.Runtime.InteropServices.Marshal.ReleaseComObject(updateCursor);

    object GetRenderer(IGPParameter pParam);

    根据指定的参数返回自定义的渲染器

    实现时 返回Null即可。

    bool IsLicensed();

    验证许可是否通过

    IAoInitialize aoi = new AoInitializeClass();

    ILicenseInformation licInfo = (ILicenseInformation)aoi;

    string licName = licInfo.GetLicenseProductName(aoi.InitializedProduct());

    if (licName == "Advanced")

    {

    return true;

    }

    else

    {

    return false;

    }

    void UpdateMessages(IArray paramvalues, IGPEnvironmentManager pEnvMgr, IGPMessages Messages

    给定参数值之后,验证参数信息,并设置返回的消息

    IGPMessage msg = (IGPMessage)Messages;

    if (msg.IsError())

    return;

    // Get the first Input Parameter

    IGPParameter parameter = (IGPParameter)paramvalues.get_Element(0);

    // UnPackGPValue. This ensures you get the value either form the dataelement or GpVariable (ModelBuilder)

    IGPValue parameterValue = m_GPUtilities.UnpackGPValue(parameter);

    // Open the Input Dataset - Use DecodeFeatureLayer as the input might be a layer file or a feature layer from ArcMap.

    IFeatureClass inputFeatureClass;

    IQueryFilter qf;

    m_GPUtilities.DecodeFeatureLayer(parameterValue, out inputFeatureClass, out qf);

    IGPParameter3 fieldParameter = (IGPParameter3)paramvalues.get_Element(1);

    string fieldName = fieldParameter.Value.GetAsText();

    // Check if the field already exists and provide a warning.

    int indexA = inputFeatureClass.FindField(fieldName);

    if (indexA > 0)

    {

    Messages.ReplaceWarning(1, "Field already exists. It will be overwritten.");

    }

    return;

    void UpdateParameters(IArray paramvalues, IGPEnvironmentManager pEnvMgr);

    更新输入参数

    m_Parameters = paramvalues;

    // Retrieve the input parameter value

    IGPValue parameterValue = m_GPUtilities.UnpackGPValue(m_Parameters.get_Element(0));

    // Get the derived output feature class schema and empty the additional fields. This will ensure you don't get duplicate entries.

    IGPParameter3 derivedFeatures = (IGPParameter3)paramvalues.get_Element(2);

    IGPFeatureSchema schema = (IGPFeatureSchema)derivedFeatures.Schema;

    schema.AdditionalFields = null;

    // If we have an input value, create a new field based on the field name the user entered.

    if (parameterValue.IsEmpty() == false)

    {

    IGPParameter3 fieldNameParameter = (IGPParameter3)paramvalues.get_Element(1);

    string fieldName = fieldNameParameter.Value.GetAsText();

    // Check if the user's input field already exists

    IField areaField = m_GPUtilities.FindField(parameterValue, fieldName);

    if (areaField == null)

    {

    IFieldsEdit fieldsEdit = new FieldsClass();

    IFieldEdit fieldEdit = new FieldClass();

    fieldEdit.Name_2 = fieldName;

    fieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble;

    fieldsEdit.AddField(fieldEdit);

    // Add an additional field for the area values to the derived output.

    IFields fields = fieldsEdit as IFields;

    schema.AdditionalFields = fields;

    }

    }

    IGPMessages Validate(IArray paramvalues, bool updateValues, IGPEnvironmentManager envMgr);

    验证信息

    if (m_Parameters == null)

    m_Parameters = ParameterInfo;

    // Call UpdateParameters().

    // Only Call if updatevalues is true.

    if (updateValues == true)

    {

    UpdateParameters(paramvalues, envMgr);

    }

    // Call InternalValidate (Basic Validation). Are all the required parameters supplied?

    // Are the Values to the parameters the correct data type?

    IGPMessages validateMsgs = m_GPUtilities.InternalValidate(m_Parameters, paramvalues, updateValues, true, envMgr);

    // Call UpdateMessages();

    UpdateMessages(paramvalues, envMgr, validateMsgs);

    // Return the messages

    return validateMsgs;

    IGPFunctionFactory

     

    方法

    说明

    string Alias { get; }

    别名

    UID CLSID { get; }

    public UID CLSID

    {

    get

    {

    UID id = new UIDClass();

    //后面的B很重要

    id.Value = this.GetType().GUID.ToString("B");

    return id;

    }

    }

    string Name { get; }

    名称

    IGPFunction GetFunction(string Name);

    根据GP的名称得到GP对象

    IEnumGPEnvironment GetFunctionEnvironments();

    如果没有设置全局环境的话,可以返回null。

    IGPName GetFunctionName(string Name);

    根据名称返回GPName,就是返回GP的 FullName

    每次调用都重新实例化对象返回即可

    IEnumGPName GetFunctionNames();

    返回这个工厂所包含的GPName

    每次调用都重新实例化对象返回即可

    2. DLL注册

    把代码编译成dll,如果在机器上已经安装了ArcGIS Desctop,鼠标右键点击dll文件,出现[register]按钮,点击该按钮,系统会弹出注册对话框,对话框如下:

    clip_image002

    点击注册按钮即可完成注册。

    注册完毕后,打开ArcCatalog,在自定义的ToolBox中右键点击添加Tool按钮,就可以把刚才我们注册的dll中包含的GP工具添加到ToolBox中。

    clip_image004

    点击Tool菜单按钮后,出现选择Gp工具对话框,如下图所示:

    clip_image006

    打勾的就是我们自己发布的GP工具,点击确定,即可添加到自定义的ToolBox中。

    clip_image008

    双击一个工具即可使用。

    clip_image010

    3. 如果发布GP服务

    ArcGIS 10.1为了保证发布的GP服务能够正确运行,只能在运行一次后,在运行结果里面点击该工具进行发布。我们运行一下我们开发的GP工具,该GP工具的功能是得到一个要素类中的要素的个数。

    clip_image012

    点击[OK]按钮。

    clip_image014

    运行结果界面如上图所示,输出参数 FeatureCount的值是5,也就是说刚才我们选的文件中有5个要素。

    下面右键点击界面上的工具,发布GP服务。如下图所示:

    clip_image016

    点击按钮,弹出发布对话框

    clip_image018

    选择是发布一个服务,还是保存成一个服务文件,还是覆盖现有的服务。我们选择发布一个新的服务,点击下一步。

    clip_image020

    选择要发布的服务器服务和设置服务的名称,点击下一步。

    clip_image022

    选择发布的目录,是在根目录下,还是在某个文件夹下面,也可以自己新建文件夹。点击继续。

    clip_image024

    在这儿设置一下发布的参数,在点击最后一个按钮发布的时候,系统会检查我们填写信息的完整性,如果不完整,系统会给出提示,按照提示修改即可。

    clip_image026

    上面就是我们没做任何修改,点击发布时,系统提示的错误信息。一个是缺少描述信息,;另一个错误我也不知道咋回事,但设置完一些描述信息后,错误和警告都没了。

    点击分析看下有没有错误,没有的话 点击发布即可。

    clip_image028

    任务发布成果后提示的信息。

    clip_image030

    在ArcServer的服务管理界面,我们就可以看到我们发布的服务。

    clip_image032

    下面查看下服务。

    clip_image034

    在浏览器中查看。

    clip_image036

  • 相关阅读:
    上海汉得面试:
    二叉树的遍历
    操作系统知识总结
    mysql单表查询&&多表查询(职员表14+9)
    数据库查询
    数据库设计三大范式及事务
    某硕笔试题mysql数据库部分(较为全面)
    java 读取excel 将数据插入到数据库
    java 读取excel 正常 xls
    java 读取excel(Map结构)xls
  • 原文地址:https://www.cnblogs.com/xzbluemap/p/3715937.html
Copyright © 2020-2023  润新知