前言

本想在soe中进行sde for sqlserver数据获取。由于soe的调试不方便,为了测试的简便,先在桌面上写了个arcengine连接sde for sqlserver的程序,但是本以为是很简单的工作,但是由于对sde知识的缺乏,还是耽误了些时间,现在把结果总结,mark一下!

环境

arcgis sde 10.1 for sqlserver,arcengine 10.1,vs2010

sde for sqlserver相关

作者写博客的态度非常的欣赏,让我们完全安装他的流程可以实现。努力使自己的博客也这样,在记录自己学习成果的同时,也可以对外分享帮助更多的人。

在整个的过程中,我犯了个对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中连接服务器上的数据库,但是怎么都连接不上,后来才知道是由于自己没有装客户端的原因。

ArcEngine 连接sql server sde(转载)_数据库 图1

SDE for sqlserver直连的ArcEngine访问

Ae中的数据的连接实质还是采用服务连接的方式。连接代码如下:

ArcEngine 连接sql server sde(转载)_客户端_02

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); }

ArcEngine 连接sql server sde(转载)_客户端_02

其中主要问题在,"instance"这个参数,这个参数确实把我弄晕了。在直接连接的时候个instance参数,可以是服务器的计算机名或者ip地址,如图一。

由于没有sde的基础,对这个instance参数很不了解,查看arcengine的官方帮助文档中,从中得出instance是端口号或者是网络服务名。但是后面的一句话,如下:


  • This is an optional property that remains in the connection properties for legacy reasons,这是个连接选项中可选参数,由于遗留原因保存下来。但没有这个参数就是没有连接到sde

它的说法误导我,我就一直以为这个参数可以不填。自从做了技术支持,对官方和老美半信半疑。通过阅读上面的两篇文章,知道了instance的正确写法。

服务连接


服务端连接是传统的连接方式,采用服务连接,顾名思义,需要具有sde服务。

创建服务,主要的麻烦之处,在于命令行的使用,需要通过命令行创建和开启服务。

ArcEngine 连接sql server sde(转载)_客户端_04图二

在10.1中可以通过create arcsde connection file 工具可以创建连接文件,通过连接文件。其中方式也是服务连接,在创建连接服务前,需要创建和开启sde服务。

但是有个有趣的事情,如果service参数使用的默认的端口号5151,则必须在创建连接文件之前必须创建和开启sde服务,而如果使用 sde:sqlserver:ip地址或计算机名,则不需要创建和开启服务。

ArcEngine 连接sql server sde(转载)_图层_05 图三

SDE for sqlserver 服务连接的AE访问

方法1.通过连接sde文件

如果创建完sde 文件,在ae中也可以,通过打开sde文件的形式,从sde数据库中获取数据,代码如下:

ArcEngine 连接sql server sde(转载)_客户端_02

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);         }

ArcEngine 连接sql server sde(转载)_客户端_02

方法二:不通过连接文件

采用改方式,需要创建sde服务,且需要保持sde服务连接的开启


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

​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接口获取图层信息。


代码如下:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

​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);​​​​​​​​}​