前言
本想在soe中進行sde for sqlserver數據獲取。由於soe的調試不方便,為了測試的簡便,先在桌面上寫了個arcengine連接sde for sqlserver的程序,但是本以為是很簡單的工作,但是由於對sde知識的缺乏,還是耽誤了些時間,現在把結果總結,mark一下!
環境
arcgis sde 10.1 for sqlserver,arcengine 10.1,vs2010
sde for sqlserver相關
安裝和桌面的連接使用,參考esri 成都中一篇文章,http://blog.csdn.net/esrichinacd/article/details/8510224,非常好的一篇文章。作者寫博客的態度非常的欣賞,讓我們完全安裝他的流程可以實現。努力使自己的博客也這樣,在記錄自己學習成果的同時,也可以對外分享幫助更多的人。
在整個的過程中,我犯了個對sde 不熟悉的錯誤,就是沒有分清楚sde的直接連接和服務連接。
在10.1的版本,sde默認是直接連接,而直接連接需要在本機具有相對應的客戶端。官方幫助給出的不同的數據庫不同的客戶端。
- IBM Data Server Run-time Client for DB2
- Informix Connect
- Microsoft SQL Server native client
- Netezza ODBC 驅動程序*
- Oracle Database Client
- PostgreSQL libpq 文件
在這個過程中,必須要注意的是,由於desktop和arcengine是32位的,而arcsde 64,則服務器端為x64,而客戶端為32位機器。這個問題應該是目前sde方面經常出現的問題。
直接連接
直接連接需要安裝客戶端,一開始我的開發機器上沒有客戶端,在arccatalog中連接服務器上的數據庫,但是怎么都連接不上,后來才知道是由於自己沒有裝客戶端的原因。
圖1
SDE for sqlserver直連的ArcEngine訪問
Ae中的數據的連接實質還是采用服務連接的方式。連接代碼如下:
public IWorkspace Getworkspace() { IPropertySet propertySet = new PropertySetClass(); propertySet.SetProperty("SERVER", "jmmmb"); propertySet.SetProperty("INSTANCE", "sde:sqlserver:jmmmb"); propertySet.SetProperty("DATABASE", "sde"); propertySet.SetProperty("USER", "sa"); propertySet.SetProperty("PASSWORD", "jmb"); propertySet.SetProperty("VERSION", "SDE.DEFAULT"); propertySet.SetProperty("AUTHENTICATION_MODE", "DBMS"); Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory"); IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType); return workspaceFactory.Open(propertySet, 0); }
其中主要問題在,"instance"這個參數,這個參數確實把我弄暈了。在直接連接的時候個instance參數,可以是服務器的計算機名或者ip地址,如圖一。
由於沒有sde的基礎,對這個instance參數很不了解,查看arcengine的官方幫助文檔中,從中得出instance是端口號或者是網絡服務名。但是后面的一句話,如下:
- This is an optional property that remains in the connection properties for legacy reasons,這是個連接選項中可選參數,由於遺留原因保存下來。但沒有這個參數就是沒有連接到sde
它的說法誤導我,我就一直以為這個參數可以不填。自從做了技術支持,對官方和老美半信半疑。通過閱讀上面的兩篇文章,知道了instance的正確寫法。
服務連接
服務端連接是傳統的連接方式,采用服務連接,顧名思義,需要具有sde服務。
sqlserver創建服務連接參考上面給出的連接,oracle創建服務連接,參考:http://blog.csdn.net/linghe301/article/details/7661896
創建服務,主要的麻煩之處,在於命令行的使用,需要通過命令行創建和開啟服務。
圖二
在10.1中可以通過create arcsde connection file 工具可以創建連接文件,通過連接文件。其中方式也是服務連接,在創建連接服務前,需要創建和開啟sde服務。
但是有個有趣的事情,如果service參數使用的默認的端口號5151,則必須在創建連接文件之前必須創建和開啟sde服務,而如果使用 sde:sqlserver:ip地址或計算機名,則不需要創建和開啟服務。
圖三
SDE for sqlserver 服務連接的AE訪問
方法1.通過連接sde文件
如果創建完sde 文件,在ae中也可以,通過打開sde文件的形式,從sde數據庫中獲取數據,代碼如下:
private void GetWrokspace() { string connectionString = @"E:\New Folder\ttt.sde"; Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory"); IWorkspaceFactory2 workspaceFactory2 = (IWorkspaceFactory2)Activator.CreateInstance(factoryType); IWorkspace pworkspace=workspaceFactory2.OpenFromFile(connectionString, 1); IFeatureWorkspace pFeaWS=pworkspace as IFeatureWorkspace; IFeatureClass pFeatureClas = pFeaWS.OpenFeatureClass("sde.DBO.Can_Mjr_Cities"); IFeatureLayer pFLr = new FeatureLayerClass(); pFLr.FeatureClass = pFeatureClas; axMapControl1.AddLayer(pFLr as ILayer); }
方法二:不通過連接文件
采用改方式,需要創建sde服務,且需要保持sde服務連接的開啟
public IWorkspace GetSDEWorkspace(String _pServerIP, String _pInstance, String _pDatabase, String _pUser, String _pPassword, string _pVersion)
{
IWorkspace pWkspace = null;
ESRI.ArcGIS.esriSystem.IPropertySet pPropertySet = new ESRI.ArcGIS.esriSystem.PropertySetClass();
pPropertySet.SetProperty("SERVER", _pServerIP);
pPropertySet.SetProperty("INSTANCE", _pInstance);
pPropertySet.SetProperty("DATABASE", _pDatabase);
pPropertySet.SetProperty("USER", _pUser);
pPropertySet.SetProperty("PASSWORD", _pPassword);
pPropertySet.SetProperty("VERSION", _pVersion);
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory");
IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType);
try
{
pWkspace = workspaceFactory.Open(pPropertySet, 0);
}
catch (Exception EX)
{
MessageBox.Show(EX.ToString());
}
return pWkspace;
}
通過Querylayer的形式
從sqlserver 2008開始,sqlserver具有了自己的空間數據存儲類型,geometry或者geography。可以通過arcmap將數據直接到入到sqlserver中,采用其自帶的空間數據存儲類型,而不是通過arcsde的企業級地理數據庫的形式。那么直接存的空間數據,如何使用ArcEngine 進行讀取?
從arcgis 10開始,有了個query layer,查詢圖層的概念。查詢圖層可以將存儲於RDBMS中的數據,以圖層的形式疊加到arcmap中。連接方式還是采用直連的方式。而采用 ISqlWorkspace接口獲取圖層信息。
代碼如下:
public IWorkspace Getworkspace(string dbName) { if (dbName.ToUpper() == "SQLSERVER") { IPropertySet propertySet = new PropertySetClass(); propertySet.SetProperty("SERVER", "jmmmb"); propertySet.SetProperty("INSTANCE", "sde:sqlserver:jmmmb"); propertySet.SetProperty("DATABASE", "sde"); propertySet.SetProperty("USER", "sa"); propertySet.SetProperty("PASSWORD", "jmb"); propertySet.SetProperty("VERSION", "SDE.DEFAULT"); propertySet.SetProperty("AUTHENTICATION_MODE", "DBMS"); Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory"); IWorkspaceFactory workspaceFactory = (IWorkspaceFactory)Activator.CreateInstance(factoryType); return workspaceFactory.Open(propertySet, 0); } } private void button2_Click(object sender, EventArgs e) { IWorkspace pWorkSpace = Getworkspace("sqlserver"); ISqlWorkspace pSqlworkSpace = pWorkSpace as ISqlWorkspace; //獲取存儲的所有表 IQueryDescription queryDescription = pSqlworkSpace.GetQueryDescription("SELECT * FROM sdeNO.dbo.CAN_MJR_CITIES"); string name = ""; pSqlworkSpace.CheckDatasetName("ddd", queryDescription, out name); ITable pTable = pSqlworkSpace.OpenQueryClass(name, queryDescription); IFeatureLayer pFeatureLayer = new FeatureLayerClass(); pFeatureLayer.FeatureClass = pTable as IFeatureClass; axMapControl1.AddLayer(pFeatureLayer); }