错误备忘_ASP.NET_ArcGIS_ASP.NET 开发 GIS 时按经纬度范围内导出空间图层数据涉及的 GIS 证书问题

本文内容

  • 背景
  • 开发环境
  • 问题描述
  • 解决方案

背景

08 年毕业时,参加一个项目,由好几家公司共同开发,我们公司做数据仓库部分,包括建立数据仓库和开发之上的数据库仓库管理系统。由于涉及地理信息,需要 GIS 功能,如用户在查看空间数据时,框选经纬度范围,将该空间图层数据导出,并打包下载到本地。本文只讨论导出问题。

开发环境

开发环境如下:

  • 客户端:Windows 2003 Server、IE 6+、VS 2005
  • 服务器端:Windows 2003 Server、IIS 6、ArcGIS SDE 9.3.2、ArcGIS Server

问题描述

导出的功能虽然实现了,但有次突然导出抛出异常,说证书有问题,无法正常创建 ESRI.ArcGIS.Geodatabase.IFeatureWorkspace 接口。于是,查了相关资料,在导出前后,加入“打开”和“关闭”证书的代码,问题就解决了。

解决方案

定义 BaseLayerData 类

只要在获得 ESRI.ArcGIS.Geodatabase.IFeatureWorkspace 接口的前后,“打开”和“关闭”证书就能行。下面 BaseLayerData 基类,代码如下:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Text;
   4: using System.Configuration;
   5:  
   6: namespace DownLoad.GIS
   7: {
   8:     public class BaseLayerData
   9:     {
  10:         #region 私有变量
  11:         private string _id;
  12:  
  13:         private ESRI.ArcGIS.Geodatabase.IFeatureWorkspace _pFeatureWorkspace;
  14:         private ESRI.ArcGIS.esriSystem.IPropertySet _propertySet ;
  15:         private ESRI.ArcGIS.esriSystem.IAoInitialize _aoInit;
  16:  
  17:         private string _layerTableName;
  18:         private string _minx;
  19:         private string _maxy;
  20:         private string _maxx;
  21:         private string _miny;
  22:  
  23:         private string _filePath;
  24:         private string _fileNameNonExtension;
  25:         #endregion
  26:  
  27:         #region 公开属性
  28:         public virtual string Id
  29:         {
  30:             get { return this._id; }
  31:             set { this._id = value; }
  32:         }
  33:         public ESRI.ArcGIS.Geodatabase.IFeatureWorkspace PFeatureWorkspace
  34:         {
  35:             get
  36:             {
  37:                 if (this.MyPropertySet != null)
  38:                 {
  39:                     if (this._pFeatureWorkspace == null)
  40:                     {
  41:                         this.OpenLicense();
  42:  
  43:                         ESRI.ArcGIS.Geodatabase.IWorkspaceFactory pWorkspaceFactory = null;
  44:                         pWorkspaceFactory = new ESRI.ArcGIS.DataSourcesGDB.SdeWorkspaceFactoryClass();
  45:                         ESRI.ArcGIS.Geodatabase.IWorkspace pWorkspace = pWorkspaceFactory.Open(this.MyPropertySet, 0);
  46:                         this._pFeatureWorkspace = pWorkspace as ESRI.ArcGIS.Geodatabase.IFeatureWorkspace;
  47:  
  48:                         this.CloseLicense();
  49:                         return this._pFeatureWorkspace;
  50:                     }
  51:                     return this._pFeatureWorkspace;
  52:                 }
  53:                 return null;
  54:             }
  55:         }
  56:         protected ESRI.ArcGIS.esriSystem.IPropertySet MyPropertySet
  57:         {
  58:             get
  59:             {
  60:                 if (this._propertySet == null)
  61:                 {
  62:                     this._propertySet = new ESRI.ArcGIS.esriSystem.PropertySetClass();
  63:                     this._propertySet.SetProperty("SERVER", ConfigurationManager.AppSettings["SERVER"]);
  64:                     this._propertySet.SetProperty("INSTANCE", ConfigurationManager.AppSettings["INSTANCE"]);
  65:                     this._propertySet.SetProperty("DATABASE", ConfigurationManager.AppSettings["DATABASE"]);
  66:                     this._propertySet.SetProperty("USER", ConfigurationManager.AppSettings["USER"]);
  67:                     this._propertySet.SetProperty("PASSWORD", ConfigurationManager.AppSettings["PASSWORD"]);
  68:                     this._propertySet.SetProperty("VERSION", ConfigurationManager.AppSettings["VERSION"]);
  69:                     return this._propertySet;
  70:                 }
  71:                 return this._propertySet ;
  72:             }
  73:         }
  74:  
  75:         protected string LayerTableName
  76:         {
  77:             get { return this._layerTableName; }
  78:             set { this._layerTableName = value; }
  79:         }
  80:         protected string Minx
  81:         {
  82:             get { return this._minx; }
  83:             set { this._minx = value; }
  84:         }
  85:         protected string Maxy
  86:         {
  87:             get { return this._maxy; }
  88:             set { this._maxy = value; }
  89:         }
  90:         protected string Maxx
  91:         {
  92:             get { return this._maxx; }
  93:             set { this._maxx = value; }
  94:         }
  95:         protected string Miny
  96:         {
  97:             get { return this._miny; }
  98:             set { this._miny = value; }
  99:         }
 100:  
 101:         /// <summary>
 102:         /// 文件路径
 103:         /// </summary>
 104:         protected string FilePath
 105:         {
 106:             get { return this._filePath; }
 107:             set { this._filePath = value; }
 108:         }
 109:         /// <summary>
 110:         /// 文件名,无扩展名
 111:         /// </summary>
 112:         protected string FileNameNonExtension
 113:         {
 114:             get { return this._fileNameNonExtension; }
 115:             set { this._fileNameNonExtension = value; }
 116:         }
 117:         #endregion
 118:  
 119:         public BaseLayerData()
 120:         {
 121:         }
 122:         public BaseLayerData(string layerTableName,
 123:             string minx, string maxy, string maxx, string miny,
 124:             string filePath, string fileNameNonExtension)
 125:         {
 126:             this._layerTableName = layerTableName;
 127:             this._minx = minx;
 128:             this._maxy = maxy;
 129:             this._maxx = maxx;
 130:             this._miny = miny;
 131:             this._filePath = filePath;
 132:             this._fileNameNonExtension = fileNameNonExtension;
 133:  
 134:             
 135:         }
 136:         /// <summary>
 137:         /// 
 138:         /// </summary>
 139:         /// <returns></returns>
 140:         public virtual bool Export()
 141:         {
 142:             return false;
 143:         }
 144:         /// <summary>
 145:         /// 创建图层
 146:         /// </summary>
 147:         /// <returns></returns>
 148:         protected ESRI.ArcGIS.Carto.IFeatureLayer CreateLayer()
 149:         {
 150:             ESRI.ArcGIS.Carto.IFeatureLayer pFLayer = new ESRI.ArcGIS.Carto.FeatureLayerClass();
 151:             try
 152:             {
 153:                 ESRI.ArcGIS.Geodatabase.IFeatureClass pFC = this.PFeatureWorkspace.OpenFeatureClass(this.LayerTableName);
 154:                 pFLayer.FeatureClass = pFC;
 155:                 pFLayer.Name = pFC.AliasName;
 156:                 return pFLayer;
 157:             }
 158:             catch
 159:             {
 160:                 return null;
 161:             }
 162:         }
 163:         /// <summary>
 164:         /// 创建证书
 165:         /// </summary>
 166:         public void OpenLicense()
 167:         {
 168:             this._aoInit = null;
 169:             this._aoInit = new ESRI.ArcGIS.esriSystem.AoInitializeClass();
 170:             this._aoInit.Initialize(ESRI.ArcGIS.esriSystem.esriLicenseProductCode.esriLicenseProductCodeEngine);
 171:         }
 172:         /// <summary>
 173:         /// 关闭证书
 174:         /// </summary>
 175:         public void CloseLicense()
 176:         {
 177:             if (this._aoInit != null)
 178:             {
 179:                 this._aoInit.Shutdown();
 180:                 this._aoInit = null;
 181:             }
 182:         }
 183:         /// <summary>
 184:         /// 创建导出图层过滤条件
 185:         /// </summary>
 186:         /// <param name="minx"></param>
 187:         /// <param name="maxy"></param>
 188:         /// <param name="maxx"></param>
 189:         /// <param name="miny"></param>
 190:         /// <returns></returns>
 191:         protected string CreateExpCondition(string minx, string maxy, string maxx, string miny)
 192:         {
 193:             string whereClause;
 194:             int isPass = this.ValidateArea(minx, maxy, maxx, miny);
 195:             if (isPass == 0)
 196:             {
 197:                 whereClause = @"sde.st_geometry.st_minx(shape)>" + minx + " and " +
 198:                                    " sde.st_geometry.st_maxx(shape)<" + maxx + " and  " +
 199:                                    " sde.st_geometry.st_miny(shape)>" + miny + " and  " +
 200:                                    " sde.st_geometry.st_maxy(shape)<" + maxy;
 201:             }
 202:             else if (isPass == 1)
 203:             {
 204:                 whereClause = @"sde.st_geometry.st_minx(shape)>100 and 
 205:                                     sde.st_geometry.st_maxx(shape)<110 and 
 206:                                     sde.st_geometry.st_miny(shape)>10 and 
 207:                                     sde.st_geometry.st_maxy(shape)<20";
 208:             }
 209:             else { whereClause = null; }
 210:             return whereClause;
 211:         }
 212:         /// <summary>
 213:         /// 验证经纬度坐标
 214:         /// </summary>
 215:         /// <param name="minx"></param>
 216:         /// <param name="maxy"></param>
 217:         /// <param name="maxx"></param>
 218:         /// <param name="miny"></param>
 219:         /// <returns>-1为非法;0为合法;1为全是空</returns>
 220:         private int ValidateArea(string minx, string maxy, string maxx, string miny)
 221:         {
 222:             if (minx != null && maxy != null && maxx != null && miny != null)
 223:             {
 224:                 if (minx.Length == 0 && maxy.Length == 0 && maxx.Length == 0 && miny.Length == 0)
 225:                 {
 226:                     return 1;
 227:                 }
 228:                 else
 229:                 { return 0; }
 230:             }
 231:             return -1;
 232:         }
 233:     }
 234: }

说明:

  1. BaseLayerData 类是针对图层数据的导出功能;
  2. 第 41 和 第 48 行为调用“打开”和“关闭”证书方法;
  3. 第 166~171 行,为“打开”证书方法;第 175~182 行,为“关闭”证书方法。
定义 LayerData 类

该类继承 BaseLayerData,实现按经纬度导出空间图层数据。代码如下:

using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Configuration;
 
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.ADF.Connection;
using ESRI.ArcGIS.DataSourcesFile;
 
namespace DownLoad.GIS
{
    /// <summary>
    /// 
    /// </summary>
    public class LayerData : BaseLayerData
    {
        public LayerData()
        {
        }
        public LayerData()
        {
        }
        public LayerData(string layerTableName,
                 string minx, string maxy, string maxx, string miny,
                 string filePath, string fileNameNonExtension)
            : base(layerTableName, minx, maxy, maxx, miny, filePath, fileNameNonExtension)
        {
        }
        public override bool Export()
        {
            return this.ExportLayer();
        }
        public bool ExportLayer()
        {
            ESRI.ArcGIS.Carto.IFeatureLayer pFeatureLayer = this.AddMap();
            if (pFeatureLayer != null)
            {
                ESRI.ArcGIS.Geodatabase.IFeatureClass pFeatureClass = pFeatureLayer.FeatureClass;
                bool isSuccess = this.ExportLayer(pFeatureClass);
                return isSuccess;
            }
            return false;
        }
 
        #region 私有方法
        /// <summary>
        /// 添加地图
        /// </summary>
        /// <returns></returns>
        private ESRI.ArcGIS.Carto.IFeatureLayer AddMap()
        {
            ESRI.ArcGIS.Carto.ILayer layer = this.AddLayer();
            if (layer != null)
            {
                ESRI.ArcGIS.Carto.IFeatureLayer featureLayer = layer as ESRI.ArcGIS.Carto.IFeatureLayer;
                return featureLayer;
            }
            return null;
        }
        /// <summary>
        /// 添加图层
        /// </summary>
        /// <returns></returns>
        private ESRI.ArcGIS.Carto.IFeatureLayer AddLayer()
        {
            ESRI.ArcGIS.Carto.IFeatureLayer pFLayer = new FeatureLayerClass();
            ESRI.ArcGIS.Carto.ILayer pLayer = null;
            try
            {
                IFeatureClass pFC = this.PFeatureWorkspace.OpenFeatureClass(this.LayerTableName);
                pFLayer.FeatureClass = pFC;
                pFLayer.Name = pFC.AliasName;
 
                pLayer = pFLayer as ESRI.ArcGIS.Carto.ILayer;
                pLayer.Name = this.LayerTableName;
                return pFLayer;
            }
            catch
            {
                return null;
            }
        }
        /// <summary>
        /// 导出图层文件SHP格式
        /// </summary>
        /// <returns></returns>
        private bool ExportLayer(ESRI.ArcGIS.Geodatabase.IFeatureClass apFeatureClass)
        {
            string whereClause = this.CreateExpCondition(this.Minx, this.Maxy, this.Maxx, this.Miny);
            if (apFeatureClass != null && whereClause != null)
            {
                this.OpenLicense();
                //设置导出要素类的参数
                ESRI.ArcGIS.Geodatabase.IDataset pOutDataset = (ESRI.ArcGIS.Geodatabase.IDataset)apFeatureClass;
                ESRI.ArcGIS.Geodatabase.IFeatureClassName myFeatureClassName = (IFeatureClassName)pOutDataset.FullName;
 
                //创建一个输出shp文件的工作空间
                ESRI.ArcGIS.Geodatabase.IWorkspaceFactory myShpWorkspaceFac = new ShapefileWorkspaceFactoryClass();
                ESRI.ArcGIS.Geodatabase.IWorkspaceName myWorkspaceName = myShpWorkspaceFac.Create(this.FilePath, this.FileNameNonExtension, null, 0);
 
                //创建一个要素集合和类
                ESRI.ArcGIS.Geodatabase.IFeatureClassName pInFeatureClassName = new FeatureClassNameClass();
                ESRI.ArcGIS.Geodatabase.IDatasetName pInDatasetClassName = null;
                pInDatasetClassName = (IDatasetName)pInFeatureClassName;
                pInDatasetClassName.Name = this.FileNameNonExtension;
                pInDatasetClassName.WorkspaceName = myWorkspaceName;
 
                ESRI.ArcGIS.Geodatabase.IQueryFilter myQueryFilter = new QueryFilterClass();
                myQueryFilter.WhereClause = whereClause;
 
                ESRI.ArcGIS.Geodatabase.IFields myFields = null; // 所有字段
                ESRI.ArcGIS.Geodatabase.IEnumFieldError pEnumFieldError = null;
                ESRI.ArcGIS.Geodatabase.IFields pInFields = apFeatureClass.Fields;
                ESRI.ArcGIS.Geodatabase.IFieldChecker pFieldChecker = new ESRI.ArcGIS.Geodatabase.FieldChecker();
                pFieldChecker.Validate(pInFields, out pEnumFieldError, out myFields);
 
                //查找几何字段,获得几何定义,并设置空间参考和网格
                ESRI.ArcGIS.Geodatabase.IField pGeoField = null; // 几何字段
                for (long iCounter = 0; iCounter < myFields.FieldCount; iCounter++)
                {
                    if (myFields.get_Field((int)iCounter).Type == esriFieldType.esriFieldTypeGeometry)
                    {
                        pGeoField = myFields.get_Field((int)iCounter);
                        break;
                    }
                }
                ESRI.ArcGIS.Geodatabase.IGeometryDef myGeometryDef = pGeoField.GeometryDef;
 
 
 
                try
                {
                    ESRI.ArcGIS.Geodatabase.IFeatureDataConverter myFeatureDataConverter = new FeatureDataConverterClass();
                    myFeatureDataConverter.ConvertFeatureClass(myFeatureClassName,
                                                                myQueryFilter,
                                                                null,
                                                                pInFeatureClassName,
                                                                myGeometryDef,
                                                                myFields,
                                                                "", 1000, 0);
                    this.CloseLicense();
                    return true;
                }
                catch
                {
                    this.CloseLicense();
                    return false;
                }
            }
            return false;
        }
        #endregion
    }
}
原文地址:https://www.cnblogs.com/liuning8023/p/2300214.html