ArcGIS Engine基础(2)之各类数据源管理(PersonalGdb)

这个博客主要展示了如何使用C#实现个人地理数据库(PGDB)的单例模式,包括打开、创建工作空间,并获取所有图层名。通过`OpenWorkspace`和`CreateWorkspace`方法,可以打开或创建PGDB,并通过`GetTotalLayerNames`方法获取图层名。此外,还提供了通过OLEDB接口获取图层和数据集名的实现。博客内容涵盖了ArcGIS API的使用和数据库操作技巧。

实现根据字符串获取PersonalGdb个人地理数据工作空间和所有图层名

 private static PersonalGdbDataSource _instance = null;
        // 获取实例互斥锁
        private static readonly object _getInstanceMutexLocker = new object();

        private PersonalGdbDataSource() { }

        public static PersonalGdbDataSource CreateSingleton() {
            if (_instance != null) return _instance;
            lock (_getInstanceMutexLocker) {
                if (_instance == null) _instance = new PersonalGdbDataSource();
            }
            return _instance;
        }

        /// <summary>
        /// 打开PGDB工作空间
        /// </summary>
        /// <param name="workspaceDataSourceString">PGDB全路径</param>
        /// <returns>工作空间</returns>
        public IWorkspace OpenWorkspace(string workspaceDataSourceString) {
            IWorkspace workspace = null;

            if (File.Exists(workspaceDataSourceString)) {
                IWorkspaceFactory workspaceFactory = GetWorkspaceFactory(
                    "esriDataSourcesGDB.AccessWorkspaceFactory");

                try {
                    workspace = workspaceFactory.OpenFromFile(workspaceDataSourceString, 0);
                }
                catch {
                }
            }

            return workspace;
        }

        /// <summary>
        /// 打开PGDB工作空间
        /// </summary>
        /// <param name="workspaceDataSourceString">PGDB全路径</param>
        /// <param name="createIfNotExist">如果PGDB不存在,是否自动新建</param>
        /// <returns>工作空间</returns>
        public IWorkspace OpenWorkspace(string workspaceDataSourceString, bool createIfNotExist) {
            if (File.Exists(workspaceDataSourceString))
                return OpenWorkspace(workspaceDataSourceString);
            else if (createIfNotExist)
                return CreateWorkspace(workspaceDataSourceString);

            return null;
        }

        public IWorkspace CreateWorkspace(string workspaceDataSourceString) {
            IWorkspace workspace = null;
            if (File.Exists(workspaceDataSourceString)) {
                try {
                    File.Delete(workspaceDataSourceString);
                }
                catch {
                    throw;
                }
            }

            try {
                int pos = workspaceDataSourceString.LastIndexOf("\\") + 1;
                string filePath = workspaceDataSourceString.Substring(0, pos);
                string fileName = workspaceDataSourceString.Substring(pos);

                if (filePath.Length < 1 || fileName.Length < 1)
                    return workspace;

                if (Directory.Exists(filePath) == false) Directory.CreateDirectory(filePath);

                // Create an Access workspace factory.
                IWorkspaceFactory workspaceFactory = WorkspaceFactoryWrapper.GetWorkspaceFactory(
                    "esriDataSourcesGDB.AccessWorkspaceFactory");

                // Create an Access workspace and personal geodatabase.
                IWorkspaceName workspaceName = workspaceFactory.Create(filePath, fileName, null, 0);

                // Cast for IName.
                IName name = workspaceName as IName;

                //Open a reference to the Access workspace through the name object.
                workspace = name.Open() as IWorkspace;
            }
            catch {
            }

            return workspace;
        }


        #region 公共方法

        /// <summary>
        /// 通过AO接口获取PGDB文件的所有图层名
        /// </summary>
        /// <param name="sPGDBFile">PGDB文件全路径</param>
        /// <returns>PGDB内的所有图层名。注意:如果PGDB文件打开失败,返回null。</returns>
        public List<string> GetTotalLayerNames(string sPGDBFile) {
            IWorkspace pWorkspace = OpenWorkspace(sPGDBFile);
            try {
                return WorkspaceWrapper.GetTotalLayerNames(pWorkspace);
            }
            catch (Exception ex) {
                throw ex;
            }
            finally {
                ComObject.Release(ref pWorkspace);
            }
        }

        /// <summary>
        /// 通过oledb接口获取PGDB文件的所有图层名
        /// </summary>
        /// <param name="sPGDBFile">PGDB文件全路径</param>
        /// <returns>PGDB内的所有图层名。注意:如果PGDB文件打开失败,返回null。</returns>
        public List<string> GetTotalLayerNames2(string sPGDBFile) {
            List<string> listFeatureDatasetNames = GetTotalDatasets2(sPGDBFile);
            Dictionary<string, int> featureClassNames = GetTotalLayerNames2(sPGDBFile, null);
            foreach (string datasetName in listFeatureDatasetNames) {
                Dictionary<string, int> temporaryFeatureClassNames = GetTotalLayerNames2(
                    sPGDBFile, datasetName);
                foreach (KeyValuePair<string, int> kvp in temporaryFeatureClassNames)
                    featureClassNames.Add(kvp.Key, kvp.Value);
            }
            List<string> listFeatureClassNames = null;
            if (featureClassNames != null) {
                listFeatureClassNames = new List<string>();
                foreach (KeyValuePair<string, int> kvp in featureClassNames) {
                    if (kvp.Value < 100)
                        listFeatureClassNames.Add(kvp.Key);
                }
            }
            return listFeatureClassNames;
        }

        /// <summary>
        /// 通过oledb接口获取PGDB文件的所有图层名
        /// </summary>
        /// <param name="sPGDBFile">PGDB文件全路径</param>
        /// <param name="nameOfDataset">数据集名,如果获取非数据集下的图层,传入null</param>
        /// <returns>PGDB内的所有图层名,如果返回null,表示此文件非PGDB文件</returns>
        /// <remarks>注:这种方式通常比通过AO接口来获取要快</remarks>
        public Dictionary<string, int> GetTotalLayerNames2(string sPGDBFile, string nameOfDataset) {
            Dictionary<string, int> featureClassNames = new Dictionary<string, int>();
            string gdbVersion = GdbVersionParser.GetGdbVersion(sPGDBFile);
            string sql;

            if (string.IsNullOrEmpty(nameOfDataset)) {
                if (gdbVersion.Equals("arcgis10x")) {
                    sql = "select t1.name as fullname, t1.ObjectID as featureClassID, t1.DatasetSubtype2 as geometrytype"
                        + " from gdb_items t1, gdb_itemtypes t2"
                        + " where t1.type=t2.uuid and t2.name='Feature Class' and instr(mid(t1.path,2,2000),'\\')=0"
                        + " order by t1.ObjectID";
                }
                else {
                    sql = "select * from ("
                        + "select t.name as fullname, t.ID as featureClassID, t1.geometrytype as geometrytype"
                        + " from gdb_objectclasses t, gdb_featureclasses t1"
                        + " where t.id = t1.objectclassid and featuretype <> 14 and t.datasetid is null"

                        + " union all"

                        + " select t.name as fullname, t.ID as featureClassID,iif(israsterdataset=1, 101, 100) as geometrytype"
                        + " from gdb_objectclasses t, gdb_featureclasses t1, gdb_rastercatalogs t2"
                        + " where t.id = t1.objectclassid and t.id = t2.objectclassid) order by featureClassID";
                }
            }
            else {
                if (gdbVersion.Equals("arcgis10x")) {
                    sql = string.Format("select t.name as fullname, t.ObjectID as featureClassID,"
                        + " t.DatasetSubtype2 as geometrytype"
                        + " from gdb_items t where mid(t.path, 1, {1})='\\{0}\\'"
                        + " order by t.ObjectID",
                        nameOfDataset, nameOfDataset.Length + 2);
                }
                else {
                    sql = string.Format("select t.name as fullname, t.ID as featureClassID, t1.geometrytype as geometrytype"
                        + " from gdb_objectclasses t, gdb_featureclasses t1 , gdb_featuredataset t2"
                        + " where t.id = t1.objectclassid and featuretype <> 14 and t2.id = t.datasetid and t2.name = '{0}'"
                        + " order by t.ID", nameOfDataset);
                }
            }

            try {
                DataSet ds = AccessFileQueryHelper.ExecuteQuery(sPGDBFile, sql);
                using (ds) {
                    if (ds != null && ds.Tables.Count > 0) {
                        foreach (DataRow dr in ds.Tables[0].Rows) {
                            featureClassNames.Add(Convert.ToString(dr["fullname"]), Convert.ToInt16(dr["geometrytype"]));
                        }
                    }
                }

                return featureClassNames;
            }
            catch {
                return null;
            }
        }

        /// <summary>
        /// 通过oledb接口获取PGDB文件的所有数据集名
        /// </summary>
        /// <param name="sPGDBFile">PGDB文件全路径</param>
        /// <returns>PGDB内的所有数据集名</returns>
        public List<string> GetTotalDatasets2(string sPGDBFile) {
            List<string> listFeatureDatasetNames = new List<string>();
            string gdbVersion = GdbVersionParser.GetGdbVersion(sPGDBFile);
            string sql;

            if (gdbVersion.Equals("arcgis10x"))
                sql = "select t1.name from gdb_items t1, gdb_itemtypes t2"
                    + " where t1.type = t2.uuid and t2.name = 'Feature Dataset'";
            else
                sql = "select name from gdb_featuredataset";

            try {
                DataSet ds = AccessFileQueryHelper.ExecuteQuery(sPGDBFile, sql);
                using (ds) {
                    if (ds != null && ds.Tables.Count > 0) {
                        foreach (DataRow dr in ds.Tables[0].Rows) {
                            listFeatureDatasetNames.Add(Convert.ToString(dr["name"]));
                        }
                    }
                }

                return listFeatureDatasetNames;
            }
            catch {
                return null;
            }

        }

        /// <summary>
        /// 获取所有要素图层
        /// </summary>
        /// <param name="sPGDBFile">PGDB文件全路径</param>
        /// <returns>PGDB内的所有要素图层</returns>
        public List<IFeatureLayer> GetTotalLayers(string sPGDBFile) {
            List<IFeatureLayer> featureLayers = new List<IFeatureLayer>();
            IWorkspace ws = DataSourceWrapper.OpenWorkspace(sPGDBFile);
            List<string> layerNames = PersonalGdbDataSource.CreateSingleton().GetTotalLayerNames2(sPGDBFile);

            foreach (string layerName in layerNames) {
                IFeatureLayer featureLayer = new FeatureLayerClass();
                featureLayer.Name = layerName;
                featureLayer.FeatureClass = WorkspaceWrapper.GetFeatureClass(ws, layerName);
                featureLayers.Add(featureLayer);
            }

            return featureLayers;
        }
        public static IWorkspaceFactory GetWorkspaceFactory(string nameOfWorkspaceFactory)
        {
            IWorkspaceFactory result;
            try
            {
                IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(Type.GetTypeFromProgID(nameOfWorkspaceFactory));
                result = workspaceFactory;
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return result;
        }
        #endregion

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xizhjxust_GIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值