一、概述
(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)將相關要素類組織成要素數據集
要素數據集是一組按空間或主題相關、共享一個通用坐標系的要素類。要素數據集用於保存參與共享拓撲、網絡數據集、幾何網絡或地形的要素類。
必須使用要素數據集來保存參與以下任何地理數據庫功能的要素類集合:
->新建要素數據集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 }