Geodatabase介绍

一、概述

(1)Geodatabase是什么?

ArcGIS操作基于GIS文件格式和存储于地理数据库(Geodatabase)中的地理信息。Geodatabase是ArcGIS的本地数据结构,是用于编辑和数据管理的基本数据格式。它并不是一个数据库,只是联系数据库与GIS的一种工具。

空间数据库系统是描述、存储和处理空间数据及其属性数据的数据库系统,按是否对空间数据和属性数据进行一体化组织分为两种:混合型空间数据库和集成性空间数据库。在后者方案中,为实现对空间对象的一条记录(record)变长的非结构化特征在关系型数据库的存储和处理(空间图形数据不能直接采用通用的关系数据管理系统),以及维护空间数据的拓扑关系,在对空间数据和属性数据集成的研究实践中,提出面向对象数据库以及易于实现的较为折中的对象-关系模型数据库。

 

(2)Geodatabase的类型

Geodatabase是面向对象的空间数据存储模型,将地理数据存储在普通的文件File Geodatabase中、Personal database(微软的Access数据库的.mdb文件)中或者多用户的关系数据库Enterprise Geodatabase(比如Oracle, Microsoft SQL Server, 或者IBM DB2)。

目前,结合Oracle对Geodatabase进行开发和管理的方式有两种:1.使用Oracle Spatial的情况下使用Oracle Spatial SQL类型;2.使用ArcSDE SQL类型——ArcSDE是一种基于中间件的对象-关系数据库模型。ArcSDE本身只是一个能在多种DBMS平台上提供高级的、高性能的GIS数据管理借口。

 

(3)术语“地理数据库”在ArcGIS中有多个含义:

  • 地理数据库是ArcGIS的原生数据结构,并且是用于编辑和数据管理的主要数据格式。当ArcGIS使用多个地理信息系统(GIS)文件格式的地理信息时,会使用地理数据库功能。
  • 它是地理信息的物理存储,主要使用数据库管理系统(DBMS)或文件系统。通过ArcGIS或通过使用SQL的数据库管理系统,可以访问和使用数据集集合的此物理实例。
  • 地理数据库具有全面的信息模型,用于表示和管理地理信息。此全面信息模型以一系列用于保存要素类、栅格数据集和属性的表的方式来实现。此外,高级GIS数据对象可添加以下内容:GIS行为;用于管理空间完整性的规则;以及用于处理核心要素、栅格数据和属性的大量空间关系的工具。
  • 地理数据库软件逻辑提供了ArcGIS中使用的通用应用程序逻辑,用于访问和处理各种文件中以及各种格式的所有地理数据。该逻辑支持处理地理数据库,包括处理shapefile、计算机辅助绘图(CAD)文件、不规则三角网(TIN)、格网CAD数据、影像、地理标记语言(GML)文件和大量其他GIS数据源。
  • 地理数据库具有用于管理GIS数据工作流的事务模型。

 

1、地理数据库中的基本数据集

地理数据库是各种类型地理数据集(Geodataset)的集合。数据集是在 ArcGIS 中组织和使用地理信息的主要途径。地理数据库包含三种主要数据集类型:

  • 要素类
  • 栅格数据集

创建这些数据集类型的集合是设计和构建地理数据库的第一步。用户通常是以构建若干上述三种基本数据集来开始构建地理数据库的。然后,用户可以使用更高级的功能(例如添加拓扑、网络或子类型)来添加或扩展地理数据库,以便建模 GIS 行为、维护数据完整性和处理重要的空间关系集。

 

高级地理数据类型实现对要素类、栅格和属性表的扩展

大量的Geodatabase元素用来扩展简单的表,要素类、栅格数据集,包括添加丰富的行为,数据完整性、数据管理等能力。Geodatabase的模式包括定义、完整性规则和行为。其中包括坐标系属性coordinate systems、坐标分辨率coordinate resolution、要素类feature classes、拓扑topologies、网络networks、栅格目录raster catalogs、关系relationships和属性域domains。模式信息存储在DBMS的Geodatabase元数据表的集合中,这些表定义了数据的完整性和行为。

 

另外,Geodatabase(ArcSDE)还支持事务和版本化,除了支持可在超大规模高性能数据库中使用的多种数据类型(如注记、拓扑、网络、地形和地址定位器)以外,还支持功能完善的事务框架,可对多种数据管理工作流程和操作进行管理。

 

2、Geodatabase的存储

Geodatabase存储的数据范围

Geodatabase的存储不仅包括简单的空间坐标和属性数据的表格,还包括这些地理数据集的模式和规则。Geodatabase的三种基础数据集(要素类,属性表和栅格数据集)和其他的Geodatabase元素都以表格的形式存储。在Geodataset中空间表示或者以矢量要素的形式存储,或者以栅格数据存储。几何对象和传统的属性字段一起存储在表的列中。

 

Geodatabase几何要素如何存储?

Geodatabase将地理要素以表格的形式存储,每行记录代表一个要素。在 ArcGIS 中,几何数据类型用于指示表中所存储几何的类型(点、线、面、多点或多面体)。通过 ArcGIS 创建的存储为几何类型的字段称为 SHAPE。空间(图形)信息存储在Shape字段中,数据类型是Geometry(如下表)。例如多边形要素集,在Shape列为每个要素存储了多边形类型,值Polygon用于描述Shape列的几何坐标和几何形状,表示在每一行定义了一个polygon。更多详情参见ArcGIS字段数据类型

 

Geodatabase的一个关键策略就是利用RDBMS来管理从简单要素集到海量数据集,多用户并发操作的GIS数据集。二维表为几何数据集提供了基本的存储机制。SQL语言具有强大的查询和操作表的功能,Geodatabase正是基于想利用这些功能而设计的。

在Geodatabase中,每个要素类(FeatureClass,见下)在一个单独的表中被管理。在要素类表中:每个要素类是一个表;单独的要素被存储为行;Shape存储每个要素的geometry (point, line, polygon);Object ID列存储每个要素的唯一标识符。在ArcSDE Geodatabase中,关系数据库存储每个要素类为一个表。有三种DBMSs(Oracle, DB2,和Informix)提供了SQL访问Geodatabase中的要素的geometry。

 

3、要素类FeatureClass

FeatureClass的概念

ArcGIS是采用Geodatabase作为地理数据模型的,而在Geodatabase中常用的要素类有四种:点、线、多边形和注记,这四种要素类在ArcGIS产品中具有重要概念意义。要素类是具有相同几何类型和属性的要素的集合。对于实际应用中遇到高级地理要素,可以依据属性特点,结合网络模型和拓扑模型进行建模。比如,下水道管线和入孔井盖组成了一个雨水管线网络;相邻的地块共享了公共的边界,大多数地块用户通过使用topology来保持在数据集中共享要素的完整性。

 

如何确定一个要素类?

在ArcGIS中,要素类是具有相同空间参考和属性设置的相同要素的集合。注意:当在Geodatabase中创建一个要素类时,需要设置要素类型以定义要素类的类型(点、线、多边形等等)。通常,要素类是点、线或多边形的集合,具体有7种要素类型。

1)   点-用来表达那些很小且不能用线或多边形来表示的地理要素(如GPS观测站)。

2)   线—用来表达那些长条形的,非常狭窄也不能用多边形表示的地理要素,如街道中心线和溪流。线也可以表达那些有长度却没有面积的要素,如轮廓线和边界。

3)   多边形-是一个封闭的图形,用来表示均质要素的形状和位置,如州、县、土地、土壤类型或者土地利用类型区等。

4)   注记-地图文本,包括文本如何组织的属性;例如,除了每个注记的文本字符串。还包括其他属性,如放置文字形状,字体,字体大小和其他显示属性。注记也可以是feature-linked,也可以包含子类。

5)   维度—一种特殊的注记,它显示具体的长度或距离;例如,为了显示一个建筑物或一块地的一条边的长度,或者两个不同要素之间的距离。维度经常用于GIS设计、工程和工具应用中。

6)   多点—由不止一个点组成的要素。Multipoints通常用于管理大量点集合的数组,如激光雷达点串,它们可以包含几十亿个点。使用一个单独的列表示这样的点几何是不可行的。聚类这些多点行可以使Geodatabase处理大块点集合。

7)   Multipatches—一个3D几何图形用于表达要素的外部表面或者外形,这个要素占用一个离散的二维面积或者三维空间的体积。Multipatches由平面的3D环和三角形组成。Multipatches可以被用于表达任何简单到复杂的对象,如球体和立方体到表面和建筑物。

要素数据集Feature Datasets

要素数据集是共用一个通用坐标系的相关要素类的集合。要素数据集用于按空间或主题整合相关要素类。它们的主要用途是,将相关要素类编排成一个公用数据集,用以构建拓扑、网络数据集、地形数据集或几何网络。Feature Datasets是在FeatureClass之上的一个概念,不同的FeatureClass具有拓扑关系时,应把它们组织在一个Feature Datasets里面,同样在AO开发中是一个很重要的基础性的类/Class。更多参见本文Geodatabase的体系结构

 

4、Geodatabase基本功能/任务

设计一个Geodatabase;

建立一个Geodatabase;

加载数据集和栅格到Geodatabase中;

用高级数据类型扩展要素类;

用域、关联和子类型扩展表;

扩展栅格数据集;

加载和维护Geodatabase中每个数据集的数据;

管理Geodatabase的更新和事务;

管理File或者Personal Geodatabase;

管理ArcSDE Geodatabase。

(1)构建Geodatabase

相关软件:ArcCatalog、ArcMap

说明:用户可轻松创建地理数据库并向其添加行为,并且使用ArcGIS for Desktop中的数据管理工具时不需要进行编程工作。在ArcMap(用于编辑、分析地图和以及根据数据创建地图的应用程序)中查询和编辑地理数据库时,可以很轻松地利用地理数据库中的数据和行为,而无需进行任何自定义。通过创建子类型、验证规则、关系和几何网络将行为添加到地理数据库。可以使用ArcMap通过编辑地理数据库中的一些现有要素并添加一些新要素来利用该行为。

->创建Geodatabase

打开ArcCatalog,并利用Folder Connections连接到地理数据文件位置:

在文件夹图标上右键,选择New选项,新建个人Geodatabase

 

 此时创建的地理数据库myPGdb.mdb是一个空的,需要向里面创建或添加要素及其它内容。一般选择导入,可以用要素类、表、栅格数据集丰富数据库:

 

用户也可以自己新建要素(数据)集,以及表、关系、栅格目录等,随后在新建的项目中编辑或添加相应地理要素,注意添加的数据必须满足自定义的种种规则:

 

 

(2)添加、编辑Geodatabase要素

->将Table添加进Geodatabase

(注:早期版本的Geodatabase与高版本的进行数据交换时有时会发生错误,这时可以在高版本环境下新建数据集,再将坐标系、字段、记录等依次添加进去。)

 

 

->新建并添加要素类

(注:要指定要素类型,如下为线状要素Line Features):

 

接下来设置坐标系,可以选择将已有的坐标系信息导入,此处略;

然后进入字段设计,可以添加需要的字段,编辑其属性,如别称、数据类型、是否为空、默认值等,设计好之后保存。

 

 ->添加/编辑要素数据项

在上面创建的空<线状地物>要素类上右键Load,装载数据:

 

接下来进行字段匹配与编辑:

 

点击完成,可以在Preview查看是否成功。

 

->用域、关联和子类型扩展表

属性域描述字段类型合法值的规则。多个要素类和表可以共享数据库中存储的属性域。例如,在供水管网中,不同用途的支管的压力值可以在不同psi之间。

要素类的子类型:通过创建子类型,可以使各个要素使用各不相同的属性域、默认值或连通性规则,类似于程序设计中的枚举数据类型。

对象之间的关系:对象之间具有1:1,1:n,m:n的关系,例如通过宗地与所有者之间的关系类,在使用ArcMap中的数据时,可以轻松找出哪些所有者拥有哪些宗地。

点击数据库名字前的 + 号,展开数据集,在需要扩展的数据集上右键Properties,打开属性面板:

在本文使用的数据库例子中,字段<BSM>(标识码)代表了不同地块类别,相同类型的地块拥有同一个BSM,故可以用<BSM>建立子类型Subtypes

 

同样,在Subtypes选项卡下面,紧接着,是编辑字段属性域Domain功能(注:Domain选项卡用于设置地理坐标范围,与表字段无关):

 

关系在Geodatabase中作为一种类/Class来设计,用户使用时需要对它进行创建,在数据库上右键New->Relationship Class

 填写关系类名称,选定建立关系的两个要素类:

 

选择关系类型:

 

选择关联字段:

 

(3)将相关要素类组织成要素数据集

要素数据集是一组按空间或主题相关、共享一个通用坐标系的要素类。要素数据集用于保存参与共享拓扑、网络数据集、几何网络或地形的要素类。

必须使用要素数据集来保存参与以下任何地理数据库功能的要素类集合:

  • 拓扑
  • 网络数据集(必须具有ArcGIS Network Analyst扩展模块以供使用)
  • 地形(必须具有ArcGIS 3D Analyst扩展模块以供使用)
  • 几何网络
  • 地籍结构

->新建要素数据集Feature Datasets

 

右键Import,向Feature Datasets添加要素类,这一步是下列操作的前提;

->新建几何网络

右键New->Geometric Network最后一项,

 

选择用于建立几何网络的数据类:

 

->建立拓扑

同样,右键New->Topology,可以建立拓扑:

 

 

(4)在数据库服务器上创建Geodatabase

(注:本文以ArcSDE for Microsoft SQL Server为例。)

->安装SQL Server 2008 R2

采用默认实例名MSSQLSERVER,设置sa用户密码,采用双登录模式。

->创建sde帐户和sde空数据库

安装完成后,以sa用户登录,创建sde帐户,密码使用sde。打开sde帐户属性,赋予其全部最高权限。创建名为sde的数据库以作后用。

->安装ArcSDE for Microsoft SQL Server

安装图解参见另一篇文章<点此链接>

安装成功的标志为esri_sde服务成功启动。查看方法:在计算机图标上右键“管理”,在“服务与应用程序”中找到“服务”,启动ArcSde Service(esri_sde)。

->关联SDE

打开ArcCatalog,双击Database Connection下的Add Spatial Database Connection:

 

成功连接时如下图所示:

 

此时可以把gis-HP sde当作前面讲述的地理数据库,进行新建要素类/数据集。

 

在SQL Server中查看如下:

 

输入SQL语句:SELECT TOP 10 * from sde.dbo.POLYGONFEATURE,结果列出表中前10条记录。

这样就可以在ArcGIS和DBMS中共同管理地理数据了。

二、Geodatabase的体系结构

1、Geodatabase扮演的角色

严格来说,Geodatabase并不是数据库。在ArcGIS和相关的用户系统中,通过Geodatabase这一规范化的地理数据模型,数据库管理系统(DBMS)可以被当作是开放的空间数据库系统,这时通用关系数据模型的简单性和灵活性使数据库管理系统支持的应用程序范围非常广泛。数据的存储和提取由存储层DBMS实现,高端的数据整合和数据处理功能则由应用层ArcGIS提供。

只是向DBMS添加对空间属性的空间类型以及SQL支持并不足以支持GIS,拓扑、网络、线性参考系、栅格目录、注记、terrain、地图图层等都是GIS用以基于DBMS中所存储的简单空间表现形式来实现GIS行为的高级对象。

 

从上面所述,可以看到Geodatabase在应用上的特征:

a)Geodatabase有一个广泛的信息模型来表达和管理地理信息。这个信息模型的实现是通过一系列简单数据表,这些表是存储在要素类、栅格数据集和属性表中的。

b)高级的GIS数据对象通过增加GIS行为、规则来管理空间完整性,以及增加工具来处理要素、栅格和属性表的大量的空间关系

c)Geodatabase可以访问和处理多种数据格式的地理数据。Geodatabase支持Shapefiles, CAD文件, TIN, Grids, CAD数据,imagery,还有其他大量GIS数据源。

d) Geodatabase具有一个事务处理模型来管理GIS的数据工作流。

2、Geodatabase为对象-关系数据模型

Geodatabase采用两层结构:数据存储层和应用层。数据存储层是将GIS数据存储为File、XML、DBMS等多种格式(关系型数据库),而应用层则是维护数据的高级逻辑和行为,例如Feature Classes、Raster Dataset、Topology、Network、Address Locators等等(面向对象的思想)。多层的Geodatabase体系结构被称为object-relational模型/ORDB。

DBMS作为一种存储地理数据集的实现机制而被使用。但是,DBMS并没有完全定义地理数据的语义。因此可以认为:Geodatabase采用两层体系结构,数据存储层和应用层,在数据存储层实现数据存储和检索,在应用层实现高层数据完整性和信息处理。ArcSDE正是基于基于这种思想被设计出来的。

 

3、Geodatabase的存储是如何基于关系原则的?

DBMS管理Geodatabase有何区别吗?

如上所述,Geodatabase的存储模型是以DBMS原则为基础,利用了一系列简单却基本的关系数据库概念。DBMS(File Geodatabase的文件系统)提供了简单而又合适的数据模型存储和操作表。包括以下的关键概念:

  • 数据被组织为表
  • 表包含行,表中所有的行具有相同的列
  • 每一列具有一个类型,如integer, decimal number, character, date等等。
  • 关系类用于一个表中的行和另一个表中的行发生关联,这是以每个表中都有一个公共的列为基础的。
  • 关系完整性规则存在于所有表中。如,每一行总是有相同的列,一个域为每一列指定了有效值或者值范围等等。

对ArcSDE Geodatabases来说,还有大量其他的DBMS功能可以应用:

  • SQL,一系列关系函数和操作符可以用于操作表和表中的元素。
  • SQL操作符同时被设计为可以处理普通的关系数据类型,如integers。

例如,一个要素类以DBMS表的形式存储。每一行代表一个要素,每一行中列描述了该要素的各种特征或属性,表中的某一列存储了该要素的几何形状(如point, line或polygon coordinates)。假设shape字段存储了polygon形状,在DBMS中大量的列类型用于shape字段,可以是典型的binary large object (BLOB)类型或者是扩展的空间类型,它们能够被一些DBMS所支持。如,ESRI提供了一个空间列类型用于在ArcSDE Geodatabases存储要素,支持这种类型的关系数据库有Oracle, IBM DB2, 和Informix。SQL操作表中的行、列。这些列类型(numbers, characters, dates, BLOB's, spatial types等等)在SQL代数中被认为是对象。DBMS管理这些简单的数据类型和表,同时其他应用逻辑实现更复杂的对象行为和完整性约束。

 

Geodatabase空间数据的物理存储形式

DBMS中的地理数据库存储包含两组表:数据集表(用户定义的表)和系统表(元数据)

(1)  数据集表 - 地理数据库中的每个数据集都存储在一个或多个表中。这些数据集表使用系统表管理数据。

(2)  系统表 - 地理数据库系统表用于追踪每个地理数据库的内容。它们实质上描述的是用于指定所有数据集定义、规则和关系的地理数据库方案。这些系统表包含并管理元数据,所有这些元数据均为实现地理数据库属性、数据验证规则和行为所需。

 

ArcGIS 10中有四个主系统表:

GDB_Items:包含地理数据库中的所有项(例如要素类、拓扑和属性域)的列表

GDB_ItemTypes:包含识别的项类型(例如表)的预定义列表

GDB_ItemRelationships:包含各个项之间的方案关联,例如要素数据集中包含哪些要素类

GDB_ItemRelationshipTypes:包含识别的关系类型(例如 DatasetInFeatureDataset)的预定义列表

 

4、地理数据库事务管理

在许多情况下,用户可使用数据库管理系统(DBMS)的事务框架来管理地理数据库的编辑和更新。GIS用户会遇到许多长事务工作流极其关键的情况。在大多数情况下,通过使用多用户DBMS和ArcSDE并利用版本化方法来管理对GIS数据库的更新,可以应对这些情况。

使用基于版本的事务模型的GIS数据编译工作流可以做到:

  • 多个编辑会话 - 单个GIS数据库更新可能需要进行持续数天或数周的涉及多个编辑会话的大量更改。
  • 多用户编辑 - 多个编辑人员经常需要同时更新相同的空间整合要素。每位用户都需要使用各自的数据库状态,从而查看各个更新,而忽略其他编辑人员所做的更新。最后,每位用户需要提交更新并与其他编辑人员进行协调,以识别并解决所有冲突。
  • 检出/检入事务 - 在很多情况下都需要将数据库中与某特定区域或地区对应的那部分数据检出到个人计算机中,然后在可能持续数天或数周的离线会话中更新此信息,甚至带到现场进行移动编辑和更新。这些更新必须提交到主数据库中。
  • 历史 - 有时,在GIS数据库中保留每个要素的历史版本(即使在此特定版本更新后)、在存档中保留已不再使用且发生更改的要素的副本或跟踪各个要素的历史是十分有用的,例如,国家地图数据库中的宗地谱系或要素更新属性。
  • 传输只变更更新 - 企业数据库和空间数据基础设施(其中的信息在各个组织之间共享)的维护需要共同协作,这种协作需要采用定义完善的可扩展标记语言(XML)架构并通过Internet来共享更新,从而在数据库之间共享只变更更新。
  • 分布式地理数据库复本 - 区域数据库可以是总公司GIS数据库中与某特定地理区域对应的那部分数据的副本。这两个数据库必须通过交换更新的方式定期进行同步。
  • DBMS之间的松散耦合复制 - 通常,GIS数据必须在一系列数据库副本(复本)之间保持同步,每个站点将在其本地数据库上执行各自的更新。通常,这些数据库只是定期通过Web进行连接。更新必须定期从每个数据库复本传输到其他数据库,同时自身的内容也会得到更新。在很多情况下,DBMS是不同的-例如,在Microsoft SQL Server、Oracle和IBMDB2之间复制数据集。

基于版本的地理数据库事务模型相对而言十分简单,即把更新记录在变更表中。版本会显式地将地理数据库的对象状态记录在添加表删除表这两个增量表中。

5、Geodatabase XML

地理数据库可扩展标记语言(XML)代表了ESRI的地理数据库与其他外部系统之间开放的信息交换机制。ESRI将完整的地理数据库方案和内容作为XML规范进行公开的发布和维护,并且提供了一些实现示例来阐述如何实现在异类系统之间共享数据更新。

通过使用地理数据库XML规范,极大地简化了地理数据库的XML地理空间信息双向交换。外部应用程序可以接收XML数据流,其中包括:

  • 交换和共享全部(以及部分)地理数据库方案;
  • 交换完整无损的数据集;
  • 交换简单要素集(与shapefile交换非常相似)
  • 使用XML流交换变更(增量)记录集,以在地理数据库和其他外部数据结构之间传送更新和变更。

地理数据库XML是用于在ArcGIS用户和外部用户间共享数据的主要交换机制。

 

三、ArcSDE——空间数据引擎

ArcSDE是数据库系统中管理地理数据库的接口,通过该接口可以往关系数据库中加入空间数据,提供地理要素的空间位置及形状等信息,是ArcGIS与关系数据库之间的GIS通道。它允许用户在多种数据管理系统中管理地理信息,并使所有的ArcGIS应用程序都能够使用这些数据。

1、ArcSDE的具体功能

(1)高性能的DBMS通道

ArcSDE是多种DBMS的通道,它本身不是一个关系数据库或数据存储模型。标准的SQL并不支持空间数据。ArcSDE不但支持每个DBMS提供的独特功能,而且能为底层DBMS提供它们所不具备的功能支持。

(2)开放的DBMS支持

包括:Oracle、Oracle with Spatial or Locator、Microsoft SQL Server、Informix以及IBM DB2,PostgreSQL等。

多用户ArcSDE为用户提供了大型空间数据库支持,并且支持多用户编辑。

(3)连续、可伸缩的数据库

GIS工作流和长事务处理GIS中的数据管理工作流。

(4)丰富的地理信息数据模型

(5)灵活的配置

ArcSDE通道可以让用户在客户端应用程序内,或跨网络、跨计算机地对应用服务器进行多种多层结构的方案配置。

 

2、ArcSDE是基于多层体系结构的应用和存储

数据的存储和提取由存储层DBMS实现,而高端的数据整合和数据处理功能则由应用层ArcGIS提供。

ArcSDE用于高效的存储、索引、访问和维护DBMS中的矢量、栅格、元数据及其他空间数据。

ArcSDE使用DBMS支持的数据类型,以表格的形式管理底层存储的空间数据,并可使用SQL在DBMS中访问这些数据。ArcSDE同时也提供了开放的客户端开发接口(C API和JAVA API),通过这些接口,用户定制的应用程序也可以完全访问底层的空间数据表。

 

3、结合ArcSDE是基于中间件的数据库模型

概述小字部分简要介绍了对象-关系模型数据库ORDB,它是面向对象思想与数据库管理系统结合的一个折中产物。ORDB与GIS结合,具有如下优势:支持基本类型扩充;支持复杂对象;支持继承;支持规则。

通过中间件(如ArcSDE),实现从空间对象模型到数据库存储的映射,可以避免对DBMS内核的直接修改,消除数据库和最终用户间接口的差异。这样子的数据库一般包括用户-中间件-数据存储层的那个3个层次,而中间件的主要任务就是分析并执行空间对象访问命令

四、ArcEngine/AO中的Geodatabase

1、Geodatabase体系结构(AO角度)

(1)要素类Feature Class

表示具有相同几何形状的空间实体,分为点状、线状、面状要素类等。

(2)对象类Object Class

表示非空间实体,不能在地图上直接表示,但与地图上的地图要素直接关联。

要素类和对象类的主要区别是:前者存储了空间信息,对象类则没有。

(3)要素数据集Feature Datasets

由一组具有相同空间参考(Spatial Reference)的要素类组成,用于存放矢量数据。

(4)栅格数据集Raster Datasets

用于存放栅格数据,支持海量数据与影像镶嵌。可建立金字塔索引。

(5)TIN数据集TIN Datasets

由一系列不规则的三角形构成,代表了地表的起伏。

(6)关系类Relationship Class

用于定义两个不同的要素类或对象类之间的关联关系。

(7)属性域Domain

定义属性的有效取值范围。

(8)几何网络Geometric Network

在若干要素类的基础上建立的类,可包括网络的边要素和点要素。

2、Geodatabase对象模型

(1)Geodatabase中的主要类

Geodatabase中的主要类分为工作区部分数据集部分,工作区部分主要负责对Geodatabase中的各种数据源进行宏观管理,而数据集部分主要用于对数据库中各种具体的数据进行描述和管理。

 

WorkspaceFactory

该类可被创建。用于生成Workspace,连接属性一般使用PropertySet对象定义,并提供浏览、管理基于文件系统的Workspace方法。该类实现IWorkspaceFactory和IWorkspaceFactory2两个接口,派生多种特定数据库工作空间类。

IWorkspaceFactory接口提供创建和打开Workspace的方法,如Open方法用于打开ArcSDE数据库。

 

Workspace

Workspace是一个用于存放空间数据和非空间数据的容器,可以存放FeatureDatasets、RasterDatasets和Tables等各种数据。该类实现IWorkspace、IWorkspace2等接口。

一个Workspace可以被看作是文件系统中的目录,也可以被看作一个关系数据库。

 

FeatureDataset组件类

存储同空间参考的多个Feature Class的数据集,可以存储Geometric Network和Relationship Class。实现IFeatureDataset接口,其CreateFeatureClass方法可用于创建新的Feature Class。

 

(2)Geodatabase中的其它常用类

包括与空间数据入库相关的类、与查询相关的类

与空间数据入库相关的类实现了各种数据格式的转换,如FeatureDataConverter、FieldChecker、EnumFieldError等。

与查询相关的类有QueryFilter和SpatialFilter。

 

3、Geodatabase的使用与开发

程序界面设计如下:

运行程序前保证ArcSDE服务ersi_sde开启.

 

部分代码如下:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Text;
  7 using System.Windows.Forms;
  8 using ESRI.ArcGIS.esriSystem;
  9 using ESRI.ArcGIS.Carto;
 10 using ESRI.ArcGIS.Controls;
 11 using ESRI.ArcGIS.SystemUI;
 12 using ESRI.ArcGIS.Geometry;
 13 using ESRI.ArcGIS.Geodatabase;
 14 using ESRI.ArcGIS.DataSourcesFile;
 15 using ESRI.ArcGIS.Display;
 16 using ESRI.ArcGIS.DataSourcesGDB;
 17 using ESRI.ArcGIS.DataSourcesRaster;
 18 
 19 namespace lesson1
 20 {
 21     public partial class Form1 : Form
 22     {
 23         public Form1()
 24         {
 25             InitializeComponent();
 26         }
 27 
 28         private void Form1_Load(object sender, EventArgs e)
 29         {
 30             IAoInitialize pao = new ESRI.ArcGIS.esriSystem.AoInitialize();
 31             pao.Initialize(esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB);
 32 
 33         }
 34         // 工作空间
 35         IWorkspace workspace;
 36         //矢量数据工作空间
 37         IFeatureWorkspace featureWorkspace;
 38         //影像数据工作空间
 39         IRasterWorkspaceEx rasterWorkspace;
 40         //矢量数据集
 41         IFeatureDataset featureDataset;
 42         //影像数据集
 43         IRasterDataset rasterDataset;
 44         private void button1_Click(object sender, EventArgs e)
 45         {
 46             // SDE空间连接属性
 47             IPropertySet propertySet = new PropertySet();
 48             propertySet.SetProperty("server", this.textBox1.Text);
 49             propertySet.SetProperty("instance", this.textBox2.Text);
 50             propertySet.SetProperty("database", this.textBox3.Text);
 51             propertySet.SetProperty("user", this.textBox4.Text);
 52             propertySet.SetProperty("password", this.textBox5.Text);
 53             propertySet.SetProperty("version", "SDE.DEFAULT");
 54             IWorkspaceFactory workspaceFactory = new SdeWorkspaceFactory();
 55             //打开SDE工作空间
 56 
 57             workspace = workspaceFactory.Open(propertySet, 0);
 58             MessageBox.Show("连接SDE空间数据库成功");
 59 
 60         }
 61         //创建数据集(矢量数据集和影像数据集)
 62         private void button2_Click(object sender, EventArgs e)
 63         {
 64             featureWorkspace = workspace as IFeatureWorkspace;
 65             rasterWorkspace = workspace as IRasterWorkspaceEx;
 66             //定义空间参考
 67             ISpatialReferenceFactory spatialReferenceFactory = new SpatialReferenceEnvironment();
 68             ISpatialReference spatialReference = spatialReferenceFactory.CreateGeographicCoordinateSystem((int)esriSRGeoCSType.esriSRGeoCS_Beijing1954);
 69             spatialReference.SetDomain(-1000, -1000, 1000, 1000);
 70 
 71             IEnumDatasetName enumDatasetName;
 72             IDatasetName datasetName;
 73             string dsName = "";
 74             enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTFeatureDataset);
 75             datasetName = enumDatasetName.Next();
 76             bool isExist = false;
 77             //创建矢量数据集
 78             dsName = "SDE." + this.textBox6.Text;
 79             while (datasetName != null)
 80             {
 81                 if (datasetName.Name == dsName)
 82                 {
 83                     isExist = true;
 84                 }
 85                 datasetName = enumDatasetName.Next();
 86             }
 87             if (isExist == false)
 88             {
 89                 featureDataset = featureWorkspace.CreateFeatureDataset(this.textBox6.Text, spatialReference);
 90             }
 91             //创建影像数据集
 92             isExist = false;
 93             enumDatasetName = workspace.get_DatasetNames(esriDatasetType.esriDTRasterDataset);
 94             datasetName = enumDatasetName.Next();
 95 
 96             dsName = "SDE." + this.textBox6.Text;
 97             while (datasetName != null)
 98             {
 99                 if (datasetName.Name == dsName)
100                 {
101                     isExist = true;
102                 }
103                 datasetName = enumDatasetName.Next();
104             }
105             if (isExist == false)
106             {
107                 //设置存储参数
108                 IRasterStorageDef rasterStorageDef = new RasterStorageDef();
109                 rasterStorageDef.CompressionType = esriRasterCompressionType.esriRasterCompressionUncompressed;
110                 rasterStorageDef.PyramidLevel = 1;
111                 rasterStorageDef.PyramidResampleType = rstResamplingTypes.RSP_BilinearInterpolation;
112                 rasterStorageDef.TileHeight = 128;
113                 rasterStorageDef.TileWidth = 128;
114                 //设置坐标系统
115                 IRasterDef rasterDef = new RasterDef();
116                 UnknownCoordinateSystem system = new UnknownCoordinateSystem();
117                 ISpatialReference rasterDpatialRefrence = system as ESRI.ArcGIS.Geometry.ISpatialReference;
118                 rasterDef.SpatialReference = rasterDpatialRefrence;
119 
120                 IGeometryDef geometryDef = new GeometryDef();
121                 IGeometryDefEdit geometryDefedit = (IGeometryDefEdit)geometryDef;
122                 geometryDefedit.AvgNumPoints_2 = 5;
123                 geometryDefedit.GridCount_2 = 1;
124                 geometryDefedit.set_GridSize(0, 1000);
125                 geometryDefedit.GeometryType_2 = esriGeometryType.esriGeometryPolygon;
126 
127                 UnknownCoordinateSystem system2 = new UnknownCoordinateSystem();
128                 ISpatialReference spatialReference2 = system2 as ESRI.ArcGIS.Geometry.ISpatialReference;
129                 geometryDefedit.SpatialReference_2 = spatialReference2;
130                 rasterDataset = rasterWorkspace.CreateRasterDataset(this.textBox7.Text, 1, rstPixelType.PT_LONG, rasterStorageDef, "DEFAULTS", rasterDef, geometryDef);
131 
132             }
133 
134         }
135         //加载矢量数据到SDE数据库
136         private void button3_Click(object sender, EventArgs e)
137         {
138             featureWorkspace = workspace as IFeatureWorkspace;
139             this.openFileDialog1.Filter = "shp file (*.shp)|*.shp";
140             this.openFileDialog1.Title = "打开矢量数据";
141             this.openFileDialog1.Multiselect = false;
142             string fileName = "";
143             if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
144             {
145                 fileName = this.openFileDialog1.FileName;
146                 string filepath;
147                 string file;
148                 int lastIndex;
149                 lastIndex = fileName.LastIndexOf(@"\");
150                 filepath = fileName.Substring(0, lastIndex);
151                 file = fileName.Substring(lastIndex + 1);
152                 //读取SHP数据
153                 IWorkspaceFactory shpwpf = new ShapefileWorkspaceFactory();
154                 IWorkspace shpwp = shpwpf.OpenFromFile(filepath, 0);
155                 IFeatureWorkspace shpfwp = shpwp as IFeatureWorkspace;
156                 IFeatureClass shpfc = shpfwp.OpenFeatureClass(file);
157 
158                 //导入SDE数据库 
159                 IFeatureClass sdeFeatureClass = null;
160                 FeatureClassDescription fClassD = new FeatureClassDescription();
161                 IFeatureClassDescription featureClassDescription = fClassD as IFeatureClassDescription;
162                 IObjectClassDescription objectClassDescription = featureClassDescription as IObjectClassDescription;
163                 IFields fields = shpfc.Fields;
164                 IFieldChecker fieldChecker = new FieldChecker();
165                 IEnumFieldError enumFieldError = null;
166                 IFields validateFields = null;
167                 fieldChecker.ValidateWorkspace = featureWorkspace as IWorkspace;
168                 fieldChecker.Validate(fields, out enumFieldError, out validateFields);
169                 featureDataset = featureWorkspace.OpenFeatureDataset(this.textBox6.Text);
170                 try
171                 {
172                     sdeFeatureClass = featureWorkspace.OpenFeatureClass(shpfc.AliasName);
173                 }
174                 catch (Exception ex)
175                 {
176                 }
177                 //在SDE数据库中创建矢量数据集
178                 if (sdeFeatureClass == null)
179                 {
180                     sdeFeatureClass = featureDataset.CreateFeatureClass(shpfc.AliasName, validateFields, objectClassDescription.InstanceCLSID, objectClassDescription.ClassExtensionCLSID, shpfc.FeatureType, shpfc.ShapeFieldName, "");
181                 }
182                 IFeatureCursor featureCursor = shpfc.Search(null, true);
183                 IFeature feature = featureCursor.NextFeature();
184                 IFeatureCursor sdeFeatureCursor = sdeFeatureClass.Insert(true);
185                 IFeatureBuffer sdeFeatureBuffer;
186                 //添加实体对象
187                 while (feature != null)
188                 {
189                     sdeFeatureBuffer = sdeFeatureClass.CreateFeatureBuffer();
190                     IField shpField = new Field();
191                     IFields shpFields = feature.Fields;
192                     for (int i = 0; i < shpFields.FieldCount; i++)
193                     {
194                         shpField = shpFields.get_Field(i);
195                         int index = sdeFeatureBuffer.Fields.FindField(shpField.Name);
196                         if (index != -1)
197                         {
198                             sdeFeatureBuffer.set_Value(index, feature.get_Value(i));
199                         }
200                     }
201                     sdeFeatureCursor.InsertFeature(sdeFeatureBuffer);
202                     sdeFeatureCursor.Flush();
203                     feature = featureCursor.NextFeature();
204                 }
205                 //加载数据到Mapcontrol
206                 IFeatureLayer sdeFeatureLayer = new FeatureLayer();
207                 sdeFeatureLayer.FeatureClass = sdeFeatureClass;
208                 this.axMapControl1.Map.AddLayer(sdeFeatureLayer as ILayer);
209                 this.axMapControl1.Extent = this.axMapControl1.FullExtent;
210                 this.axMapControl1.Refresh();
211             }
212 
213         }
214         //加载影像数据到SDE数据库
215         private void button4_Click(object sender, EventArgs e)
216         {
217             this.openFileDialog1.Filter = "TIFF file (*.tif)|*.tif";
218             this.openFileDialog1.Title = "打开影像数据";
219             this.openFileDialog1.Multiselect = false;
220             string fileName = "";
221             if (this.openFileDialog1.ShowDialog() == DialogResult.OK)
222             {
223                 fileName = this.openFileDialog1.FileName;
224                 string filepath;
225                 string file;
226                 int lastIndex;
227                 lastIndex = fileName.LastIndexOf(@"\");
228                 filepath = fileName.Substring(0, lastIndex);
229                 file = fileName.Substring(lastIndex + 1);
230 
231                 //导入SDE数据库 
232                 rasterWorkspace = workspace as IRasterWorkspaceEx;
233                 IWorkspaceFactory tifwpf = new RasterWorkspaceFactory();
234                 IWorkspace tifwp = tifwpf.OpenFromFile(filepath, 0);
235                 IRasterWorkspace tifrwp = tifwp as IRasterWorkspace;
236                 IRasterDataset rasterDataset = tifrwp.OpenRasterDataset(file);
237                 IRasterDataset sdeRasterDataset = null;
238                 lastIndex = file.LastIndexOf(@".");
239                 file = file.Substring(0, lastIndex);
240                 try
241                 {
242                     sdeRasterDataset = rasterWorkspace.OpenRasterDataset(file);
243                 }
244                 catch (Exception Ex)
245                 {
246                 }
247                 if (sdeRasterDataset == null)
248                 {
249                     IGeoDataset geoDataset = rasterDataset as IGeoDataset;
250                     IRasterSdeServerOperation rasterSdeServeroperation;
251 
252                     IBasicRasterSdeConnection sdeCon = new BasicRasterSdeLoader();
253                     IPropertySet propertySet = new PropertySet();
254                     propertySet = workspace.ConnectionProperties;
255                     //建立与SDE数据库的连接
256                     sdeCon.ServerName = propertySet.GetProperty("server").ToString();
257                     sdeCon.Instance = propertySet.GetProperty("instance").ToString();
258                     sdeCon.UserName = propertySet.GetProperty("user").ToString();
259                     sdeCon.Password = "sde";
260                     sdeCon.Database = propertySet.GetProperty("database").ToString();
261                     sdeCon.SdeRasterName = file;
262                     sdeCon.InputRasterName = fileName;
263                     rasterSdeServeroperation = sdeCon as IRasterSdeServerOperation;
264                     //保存影像数据到SDE数据库中
265                     rasterSdeServeroperation.Create();
266                     rasterSdeServeroperation.Update();
267                     rasterSdeServeroperation.ComputeStatistics();
268                     IRasterLayer rasterLayer = new RasterLayer();
269                     sdeRasterDataset = rasterWorkspace.OpenRasterDataset(file);
270                     rasterLayer.CreateFromDataset(sdeRasterDataset);
271                     this.axMapControl1.Map.AddLayer(rasterLayer as ILayer);
272                     this.axMapControl1.Extent = this.axMapControl1.FullExtent;
273                     this.axMapControl1.Refresh();
274                 }
275             }
276         }
277 
278     }
279 }
Form1.cs

 

posted on 2013-07-16 11:06  苦恋电波の青春  阅读(8365)  评论(0编辑  收藏  举报

导航