ArcEngine 連接sql server sde


前言

本想在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);


        }

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM