×
您的位置: 首页 > 编程笔记

ArcGIS Server操作Mxd文件详细讲解

ArcGIS AR 时间:2010-12-26  查看:439   收藏
摘要:ArcGIS Server发布地图都是基于Mxd去发布的,这点与IMS使用axl文件差不多。一般来说,发布后mxd尽可能不要修改,或者在通过使用arcMap进行编辑后在重新发布。

Server发布地图都是基于Mxd去发布的,这点与IMS使用axl文件差不多。一般来说,发布后mxd尽可能不要修改,或者在通过使用arcMap进行编辑后在重新发布。
修改mxd会导致地图服务发生变化,因此,相对来说是一种危险的操作。但有时客户需要对Mxd进行修改,自定义的添加修改图层,并重新发布服务。
当然,这些苛刻的需求server同样可以应付,但懒羊羊还是不建议这样做。方法总是有的,越危险的事也就越有趣。懒羊羊还是跟大家分享一下这方面的心得吧。

下面函数实现添加一个图层到mxd文件,并设置样式。为更好的表达,函数使用返回操作结果的字符串。
///


/// 添加图层到Mxd文件
///

/// IServerContext
/// 新图层对应的要素集
/// 复合图层的序号
/// mxd所在的路径
/// 用于对图层渲染的图片
///
public string addLayerInMxd(IServerContext serverContext, IFeatureClass nfc, int groupIndex, string mxdPath,string picPath)
{
IMapServer pMapServer = serverContext.ServerObject as IMapServer;
IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;
IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);
bool hasLayer = hasTheLayer(pMap, nfc.AliasName);
if (hasLayer) return "已存在该命名图层,操作未能完成"; //如果图层已经存在了,那就不添加
if (groupIndex >= pMap.LayerCount) return "组合图层序号越界,操作未能完成";
IMapLayers mapLayer = pMap as IMapLayers;
IGroupLayer gLayer = pMap.get_Layer(groupIndex) as IGroupLayer;
IFeatureLayer fl = serverContext.CreateObject("esriCarto.FeatureLayer") as IFeatureLayer;
fl.FeatureClass = nfc;
fl.Name = nfc.AliasName;
//设置样式
ISimpleRenderer pRen = serverContext.CreateObject("esriCarto.SimpleRenderer") as ISimpleRenderer;
IGeoFeatureLayer pGeoLayer = fl as IGeoFeatureLayer;
IPictureMarkerSymbol picMark = serverContext.CreateObject("esriDisplay.PictureMarkerSymbol") as IPictureMarkerSymbol;
picMark.Size = 20;
picMark.CreateMarkerSymbolFromFile(esriIPictureType.esriIPictureBitmap, picPath);
pRen.Symbol = (ISymbol)picMark;
pGeoLayer.Renderer = (IFeatureRenderer)pRen;
mapLayer.InsertLayerInGroup(gLayer, pGeoLayer as ILayer, false, 3);

//获取pMapDocument对象
IMxdContents pMxdC;
pMxdC = pMap as IMxdContents;
IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument") as IMapDocument;
pMapDocument.Open(mxdPath, "");
pMapDocument.ReplaceContents(pMxdC);
if (pMapDocument == null) return "文档为空不能完成操作";
//检查地图文档是否是只读
if (pMapDocument.get_IsReadOnly(mxdPath) == true)
{
return "地图文档只读,未能完成操作";
}
//根据相对的路径保存地图文档
pMapDocument.Save(pMapDocument.UsesRelativePaths, false);
return "操作成功";
}

///
/// 是否存在layerName为别名的图层
///

///
///
///
public bool hasTheLayer(IMap pMap, string layerName)
{
for (int i = 0; i {
ILayer pLayer = pMap.get_Layer(i);
if (pLayer.Name == layerName)
return true;
if (pLayer is ICompositeLayer)
{
ICompositeLayer comLayer = pLayer as ICompositeLayer;
for (int j = 0; j {
ILayer cLayer = comLayer.get_Layer(j);
if (cLayer.Name == layerName)
return true;
}
}
}
return false;
}

下面是根据图层名删除图层的操作
public string removeLayerFromMxd(IServerContext serverContext, layerName,string mxdPath)
{
IMapServer pMapServer = serverContext.ServerObject as IMapServer;
IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;
IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);
IMapLayers pMapLayers = pMap as IMapLayers;

ILayer removeLayer = getLayerByName(serverContext, layerName);
if (removeLayer == null)
return "操作失败,找不到要删除的图层";
pMapLayers.DeleteLayer(removeLayer);
//获取pMapDocument对象
IMxdContents pMxdC = pMap as IMxdContents; ;
IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument") as IMapDocument;
pMapDocument.Open(mxdPath, "");
pMapDocument.ReplaceContents(pMxdC);
if (pMapDocument == null) return "操作失败,地图文档为空";
//检查地图文档是否是只读
if (pMapDocument.get_IsReadOnly(mxdPath) == true)
{
return "操作失败,地图文档只读";
}
//根据相对的路径保存地图文档
pMapDocument.Save(pMapDocument.UsesRelativePaths, false);
return "操作成功";
}

///


/// 是否存在layerName为别名的图层
///

///
///
///
public bool hasTheLayer(IMap pMap, string layerName)
{
for (int i = 0; i {
ILayer pLayer = pMap.get_Layer(i);
if (pLayer.Name == layerName)
return true;
if (pLayer is ICompositeLayer)
{
ICompositeLayer comLayer = pLayer as ICompositeLayer;
for (int j = 0; j {
ILayer cLayer = comLayer.get_Layer(j);
if (cLayer.Name == layerName)
return true;
}
}
}
return false;
}


从上面的函数可看出,对添加删除图层这些操作,步骤大概就是 获取图层对要素集,设置图层样式,打开当前地图,插入图层,保存Mxd,
所有的这些都是AO的操作,对于习惯使用AE的人来说,这些都很熟悉,唯一不同的是,Server不能用new去创建对象,细心人会发现在创建
地图文档的时候,使用的是CreateObject的方式,如下面语句
IMapDocument pMapDocument = serverContext.CreateObject("esriCarto.MapDocument") as IMapDocument;

  • Add and delete server object configurations
  • Update a server object configurations properties
  • Start, stop and pause server object configurations
  • Report the status of a server object configuration
  • Get all server object configurations and their properties
  • Get all server object types and their properties
Administer aspects of the server itself:
  • Add and remove server container machines
  • Get all server container machines
  • Add and remove server directories
  • Get all server directories
  • Configure the servers logging properties

实际上,上述的操大多数都是常规的操作,AE程序员都能轻松搞定。但细微的地方还是要注意的,例如Server环境下创建新对象,文件的权限设置等等
对server的一些特性也必须了解。例如mxd更新以后必须重启服务,确保当前服务与地图文档一致,不然就可能导致灾难性的出错。

前面漏掉的一个函数现在补上
///


/// 通过图层名称返回图层
///

/// 地图控件
/// 图层名称
///
public static ILayer getLayerByName(IServerContext pSOC, string LayerName)
{
IMapServer pMapServer = pSOC.ServerObject as IMapServer;
IMapServerObjects pMapServerObjs = pMapServer as IMapServerObjects;
IMap pMap = pMapServerObjs.get_Map(pMapServer.DefaultMapName);
//获取所有的图层
for (int i = 0; i {
ILayer lyr = pMap.get_Layer(i);
if (lyr.Name == LayerName)
{
return lyr;
}
else if (lyr is ICompositeLayer)
{
//图层为复合图层,查找其子图层
ICompositeLayer comLayer = lyr as ICompositeLayer;
for (int j = 0; j {
ILayer cLayer = comLayer.get_Layer(j);
if (cLayer.Name == layerName)
return cLayer;
}
}
}
return null;
}

 

0% (0)
0% (0)