天天看點

C#開發讀取Geodatabase10的XML值

ArcGIS10已經推出快一年的時間了,在去年的使用者大會上關于Geodatabase10的新特性上描述我們的相關Schema也發生了本質的變化,從原來的30多張表,變成現在的6張,那麼最本質的變化就是相關的對象使用XML進行存儲,這對我們開發者來說是一個好消息,因為我們可以通過XML結構來得知每一個對象是怎麼定義的,而且我們也可以使用SQL來讀取XML的值而不用使用ArcObject來讀取。

關于Geodatabase10新特性可以參考:http://wenku.baidu.com/view/94721478168884868762d668.html

那麼今天就給大家介紹一下怎麼使用C#來通路這些值,其實抛開ArcGIS的知識,一個純IT的開發人員隻要了解XML的都會很容易的來獲得這些資訊。

首先看一下一個要素類為DLTB的XML格式

<DEFeatureClassInfo xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:typens="http://www.esri.com/schemas/ArcGIS/10.0" xsi:type="typens:DEFeatureClassInfo">

<CatalogPath>/sde.SDE.czdj/sde.SDE.dltb</CatalogPath>

<Name>sde.SDE.dltb</Name>

<ChildrenExpanded>false</ChildrenExpanded>

<DatasetType>esriDTFeatureClass</DatasetType>

<DSID>8</DSID>

<Versioned>false</Versioned>

<CanVersion>false</CanVersion>

<ConfigurationKeyword />

<HasOID>true</HasOID>

<OIDFieldName>OBJECTID</OIDFieldName>

<GPFieldInfoExs xsi:type="typens:ArrayOfGPFieldInfoEx">

<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">

<Name>OBJECTID</Name>

<ModelName>OBJECTID</ModelName>

<FieldType>esriFieldTypeOID</FieldType>

<IsNullable>false</IsNullable>

<Required>true</Required>

<Editable>false</Editable>

</GPFieldInfoEx>

<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">

<Name>Shape</Name>

<ModelName>Shape</ModelName>

<FieldType>esriFieldTypeGeometry</FieldType>

<IsNullable>true</IsNullable>

<Required>true</Required>

</GPFieldInfoEx>

<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">

<Name>Shape.area</Name>

<ModelName>Shape.area</ModelName>

<FieldType>esriFieldTypeDouble</FieldType>

<IsNullable>false</IsNullable>

<Required>true</Required>

<Editable>false</Editable>

</GPFieldInfoEx>

<GPFieldInfoEx xsi:type="typens:GPFieldInfoEx">

<Name>Shape.len</Name>

<ModelName>Shape.len</ModelName>

<FieldType>esriFieldTypeDouble</FieldType>

<IsNullable>false</IsNullable>

<Required>true</Required>

<Editable>false</Editable>

</GPFieldInfoEx>

</GPFieldInfoExs>

<CLSID>{52353152-891A-11D0-BEC6-00805F7C4268}</CLSID>

<EXTCLSID />

<RelationshipClassNames xsi:type="typens:Names" />

<AliasName />

<ModelName />

<HasGlobalID>false</HasGlobalID>

<GlobalIDFieldName />

<RasterFieldName />

<ExtensionProperties xsi:type="typens:PropertySet">

<PropertyArray xsi:type="typens:ArrayOfPropertySetProperty" />

</ExtensionProperties>

<ControllerMemberships xsi:type="typens:ArrayOfControllerMembership">

<ControllerMembership xsi:type="typens:TopologyMembership">

<TopologyName>sde.SDE.czdj_Topology</TopologyName>

<Weight>5</Weight>

<XYRank>1</XYRank>

<ZRank>1</ZRank>

<EventNotificationOnValidate>false</EventNotificationOnValidate>

</ControllerMembership>

</ControllerMemberships>

<FeatureType>esriFTSimple</FeatureType>

<ShapeType>esriGeometryPolygon</ShapeType>

<ShapeFieldName>Shape</ShapeFieldName>

<HasM>false</HasM>

<HasZ>false</HasZ>

<HasSpatialIndex>true</HasSpatialIndex>

<AreaFieldName>Shape.area</AreaFieldName>

<LengthFieldName>Shape.len</LengthFieldName>

<Extent xsi:type="typens:EnvelopeN">

<XMin>506464.78390000015</XMin>

<YMin>3842861.5803999994</YMin>

<XMax>516750</XMax>

<YMax>3849454.2771000005</YMax>

<SpatialReference xsi:type="typens:ProjectedCoordinateSystem">

<WKT>PROJCS["Xian_1980_3_Degree_GK_CM_111E",GEOGCS["GCS_Xian_1980",DATUM["D_Xian_1980",SPHEROID["Xian_1980",6378140.0,298.257]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",111.45],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]</WKT>

<XOrigin>-5123200</XOrigin>

<YOrigin>-10002100</YOrigin>

<XYScale>10000</XYScale>

<ZOrigin>0</ZOrigin>

<ZScale>1</ZScale>

<MOrigin>0</MOrigin>

<MScale>1</MScale>

<XYTolerance>0.001</XYTolerance>

<ZTolerance>0.001</ZTolerance>

<MTolerance>0.001</MTolerance>

<HighPrecision>true</HighPrecision>

</SpatialReference>

</Extent>

<SpatialReference xsi:type="typens:ProjectedCoordinateSystem">

<WKT>PROJCS["Xian_1980_3_Degree_GK_CM_111E",GEOGCS["GCS_Xian_1980",DATUM["D_Xian_1980",SPHEROID["Xian_1980",6378140.0,298.257]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Gauss_Kruger"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],PARAMETER["Central_Meridian",111.45],PARAMETER["Scale_Factor",1.0],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]</WKT>

<XOrigin>-5123200</XOrigin>

<YOrigin>-10002100</YOrigin>

<XYScale>10000</XYScale>

<ZOrigin>-100000</ZOrigin>

<ZScale>10000</ZScale>

<MOrigin>-100000</MOrigin>

<MScale>10000</MScale>

<XYTolerance>0.001</XYTolerance>

<ZTolerance>0.001</ZTolerance>

<MTolerance>0.001</MTolerance>

<HighPrecision>true</HighPrecision>

</SpatialReference>

</DEFeatureClassInfo> 

我們可以看到,這個XML定義了要素類的名稱、字段(字段的相關屬性)、投影資訊、範圍等資訊

------------------------Oracle----------------------------------------------------------------

在Oracle資料庫中的存儲并不是直接存儲在Defination裡面

C#開發讀取Geodatabase10的XML值

而且需要使用sde.sdexmltotext操作符來轉換一下

參考示例代碼

using System.Xml.Linq;

using System.Xml;

using System.Xml.XPath;

using (OracleConnection connection = new OracleConnection())

{

connection.ConnectionString = "User Id=sde;Password=sde;Data Source=orcl;";

connection.Open();

OracleCommand cmd = new OracleCommand();

string sql = "SELECT sde.sdexmltotext(d1.xml_doc) as definition " +

"FROM GDB_ITEMS LEFT OUTER JOIN SDE_XML_DOC1 d1 ON " +

"GDB_ITEMS.definition = d1.sde_xml_id where name='TEST.dltb'";

cmd.CommandText = sql;

cmd.Connection = connection;

using (OracleDataReader dr = cmd.ExecuteReader())

{

while (dr.Read())

{

string def = System.Convert.ToString(dr.GetValue(0));

XDocument xd = XDocument.Parse(def);

StringBuilder str = new StringBuilder();

int i = 1;

foreach (XElement ele in xd.Descendants("GPFieldInfoEx"))

{

string name = ele.Element("Name").Value;

string code = ele.Element("FieldType").Value;

str.Append(i+":"+name + "," + code+"/n");

i++;

}

LSCommonHelper.MessageBoxHelper.ShowMessageBox(str.ToString());

}

}

----------------------------------------------SQL Server----------------------------------

在SQL Server中,完全使用SQL語句直接對XML進行獲得值,而不需要引用C#的類庫

select

definition.value('(/DEFeatureClassInfo/Name)[1]','nvarchar(max)') as "要素類名稱",

definition.value('(/DEFeatureClassInfo/DatasetType)[1]','nvarchar(max)') as "要素類類型",

definition.value('(/DEFeatureClassInfo/GPFieldInfoExs/GPFieldInfoEx/Name)[1]','nvarchar(max)') as "字段1",

definition.value('(/DEFeatureClassInfo/GPFieldInfoExs/GPFieldInfoEx/Name)[2]','nvarchar(max)') as "字段2",

definition.value('(/DEFeatureClassInfo/GPFieldInfoExs/GPFieldInfoEx/Name)[3]','nvarchar(max)') as "字段3"

FROM [sde].[sde].[GDB_ITEMS]

WHERE Name='test.DBO.zd' 

----------------------------------------------Oracle----------------------------------

SELECT
  EXTRACTVALUE(XMLType(Definition), '/DEWorkspace/MajorVersion') AS "Major version",
  EXTRACTVALUE(XMLType(Definition), '/DEWorkspace/MinorVersion') AS "Minor version",
  EXTRACTVALUE(XMLType(Definition), '/DEWorkspace/BugfixVersion') AS "Bug fix version"
FROM
 sde.gdb_items_vw items INNER JOIN
  (SELECT UUID 
   FROM sde.gdb_itemtypes
   WHERE Name = 'Workspace') itemtypes
  ON items.Type = itemtypes.UUID;
           

---------------------------------------File Geodatabase---------------------------------

如果使用者使用FGDB,那麼可以使用FileGDB API來獲得相關的資訊