Shape数据上传至SDE数据库中,动态更新Mapservice的解决方案之一
时间:2010-10-29 来源:风之恋
写这个程序的目的是在不重启MapService的前提下更新数据,并让所有使用这个MapService
的用户能够看到数据更新,但是这个程序有不完善的地方,没有实现注记的上传,这个哪个高手实现了,请告诉我!
数据准备:在Sde中建立类型为”Point Features”的featureclass(这个我是在ArcCatalog中实现的)当然也可以建立其他类型的,如polyline、polygon、annotation的featureclass,本文为方便讲解,只进行point类型的shape文件上传,如果对坐标系统有要求的话,可以选择坐标系,其他默认下一步,到最后一步时,如下图所示
可以点击Imort按钮导入字段参照的模板,这个可以选择对应的shape文件导入,ok,这里就创建完成了,命名为myTestPointFeatureclass
这里完成了第一步,其次创建一个空的MXD文档,将建好的myTestPointFeatureclass作为mxd的一个图层,保存。
最后一个,发布Mapservice,需要注意的是要把timetous中时间调长一些,不要使用默认,因为在使用IServerContant时可能长时间使用不释放,会出现timeout的错误,这只是我自己的理解。
前期的准备工作做完了,简单介绍下参数
假设SDE数据库的连接参数为:
Server:192.168.1.43
Service:5151
UserName:gis_map_sh
Password:gisgis
Verstion:sde.DEFAULT
其他参数:hostName=”localhost”
mapServiceName=”myTestMapService”
下面开始上代码:
获取上下文,在Arcserver开发中IServerContext是非常重要的,很像一个很重要的中转站,缺少它就跑不起来了。
IServerContext servercontext = GetServerContext(configObj.hostname, configObj.mapserviceName);
//创建server的上下文
private IServerContext GetServerContext(string _hostName,string _mapServiceName)
{
try
{
ESRI.ArcGIS.Server.IServerObjectManager pServerObjectManager;
//使用ADF 连接类库
ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsServerConnection =
new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection();
agsServerConnection.Host = _hostName;
agsServerConnection.Connect();
pServerObjectManager = agsServerConnection.ServerObjectManager;
//创建特定Mapservice的mapserver上下文
ESRI.ArcGIS.Server.IServerContext serverContext =
pServerObjectManager.CreateServerContext(_mapServiceName, "MapServer");
return serverContext;
}
catch
{
return null;
}
}
接下来打开shape文件所在的Directory
IWorkspaceFactory wf =servercontext.CreateObject("esriDataSourcesFile.ShapefileWorkspaceFactory") as IWorkspaceFactory;
IFeatureWorkspace fws=wf.OpenFromFile(ShapeFileDirectory,0) as IFeatureWorkspace;
打开shape文件,其中feaname为shape文件名
IFeatureClass pFeatureaClass = fws.OpenFeatureClass(featname);
IQueryFilter queryFilter = new ESRI.ArcGIS.Geodatabase.QueryFilter();
AddFeatureClassToSde(pFeatureaClass, myTestPointFeatureclass, hostname, mapserviceName, this.sdeserver, this.sdeinstance, this.sdeusername, this.sdepassword, this.sdeversion);
下面为AddFeatureClassToSde
public bool AddFeatureClassToSde(IFeatureClass insertFeatureClass, string sdefeaName, string hostname, string mapservicename, string sdeServer, string sdeInstance, string sdeUser, string sdePassWord, string sdeVersion)
{
m_AoInitializa.Initialize(esriLicenseProductCode.esriLicenseProductCodeEngineGeoDB);
IServerContext soc = GetServerContext(hostname, mapservicename);
IPropertySet propSet = new PropertySetClass();
propSet.SetProperty("SERVER", sdeserver);
propSet.SetProperty("INSTANCE", sdeinstance);
propSet.SetProperty("USER", sdeUser);
propSet.SetProperty("PASSWORD", sdepassword);
propSet.SetProperty("VERSION", sdeversion);
try
{
IWorkspaceFactory pwf = (IWorkspaceFactory)soc.CreateObject("esriDataSourcesGDB.SDEWorkspaceFactory");
IFeatureWorkspace pFeatureWorkspace = (IFeatureWorkspace)(pwf.Open(propSet, 0));
IFeatureClass feaClass = pFeatureWorkspace.OpenFeatureClass(sdefeaName);
IFeatureCursor feaCursor = feaClass.Insert(true);
IQueryFilter queryFilter = new QueryFilterClass();
int count = insertFeatureClass.FeatureCount(queryFilter);
InsertFeatureToSde(count, 0, insertFeatureClass, feaClass, feaCursor);
pFeatureWorkspace = null;
return true;
}
catch
{
return false;
}
finally
{
soc.ReleaseContext();
}
}
其中加入了InsertFeatureToSde方法,是因为在上传过程中出现了“The number of points is less than required for feature”的错误,查了很久也没有很好的解决方法,有人说是ESRI的bug,呵呵,但是我们不能让程序因为一条记录出错就停下来,如果需要能够查看出错记录,可以插入日志功能~~
/// <summary>
/// 将Feature插入到SDE中 递归插入,某条数据出错后直接跳入下一条记录
/// </summary>
private void InsertFeatureToSde(int _featurecount, int _startindex, IFeatureClass _insertFeatureClass, IFeatureClass _sdeFeatureClass, IFeatureCursor _featureCursor)
{
int m = _startindex;
try
{
for (; m < _featurecount; m++)
{
IFeature feature = _insertFeatureClass.GetFeature(m);
IFeatureBuffer feaBuffer = _sdeFeatureClass.CreateFeatureBuffer();
IField fld = new FieldClass();
IFields flds = feature.Fields;
for (int i = 0; i < flds.FieldCount; i++)
{
fld = flds.get_Field(i);
int index = feaBuffer.Fields.FindField(fld.Name);
if (index != -1)
{
feaBuffer.set_Value(index, feature.get_Value(i));
}
}
_featureCursor.InsertFeature(feaBuffer);
}
}
catch
{
m = m + 1;
if (m < _featurecount)
{
InsertFeatureToSde(_featurecount, m, _insertFeatureClass, _sdeFeatureClass, _featureCursor);
}
}
}
这里只能是实现shape文件,我一直在找上传annotation featureclass 的方法,但一直无果,希望达人指点