天天看点

基于C#的ArcEngine二次开发53: mxd与IPagelayout

目录

Element分类

制作图例

更新比例尺

更改范围

Element分类

Element
 ->|Graphic Element(图形元素)
        |    ->|TextElement
        |      |MarkerElement
        |      |LineElement
        |      |PolygonElement
        |      |GroupElement
        |      |DataElement
        |      |PictureElement
        |      |FillShapeElement
  ->|FrameElement(框架元素)
             ->|MapFrame(数据框)
               |MapSurroundFrame(指北针、比例尺和图例)
               |OLEFRAME(用于放置其它应用程序对象,如Word对象)
               |TableFrame(其他类型,可以放置一个表格对象)
           

ARCGIS_ENGINE10开发手册word版:https://max.book118.com/html/2017/1213/143983980.shtm

制作图例

private void MakeLegend(IActiveView activeView,IPageLayout pageLayout)

      {

          //定义图例UID对象

          UID uid = new UIDClass();

          uid.Value="esriCore.Legend";       

          //设置图例存放的坐标位置                

          //定义单位

          pageLayout.Page.Units = esriUnits.esriCentimeters;

          //得到草图容器对象

          IGraphicsContainer container = pageLayout as IGraphicsContainer;

          //得到当前地图的框架

          IMapFrame frameElement = container.FindFrame(activeView.FocusMap) as IMapFrame;

          IElement mapElement = frameElement as IElement;

 

          IEnvelope mapEnv = mapElement.Geometry.Envelope;   

          IEnvelope envelope = new EnvelopeClass();

          //通过当前地图框架得到相对位置

          envelope.PutCoords(mapEnv.XMin, mapEnv.YMin, mapEnv.XMin + 6.5, mapEnv.YMin + 0.8);

          IMapSurroundFrame frame = frameElement.CreateSurroundFrame(uid, null);            

          ILegend legend = frame.MapSurround as ILegend;

          ILegendFormat format = new LegendFormatClass();

          format.TitlePosition = esriRectanglePosition.esriTopSide;

          format.LayerNameGap=0.0;

          format.TextGap=0.0;

          format.TitleGap=0.0;

          format.HeadingGap=0.0;

          format.HorizontalItemGap=0.0;

          format.VerticalItemGap=0.0;

          format.ShowTitle=true;

          ITextSymbol symbol = new TextSymbolClass();

          symbol.Text="图例";

          System.Drawing.Font ft = new System.Drawing.Font("宋体", 5);

          IFontDisp iFontDispFromFont = (IFontDisp)OLE.GetIFontDispFromFont(ft);

          symbol.Font=iFontDispFromFont;

          symbol.Size = 11.5;

      

          IRgbColor color = (IRgbColor)ESRI.ArcGIS.ADF.Converter.ToRGBColor(Color.Black);

          symbol.Color = color;

          //文字水平方向的对齐方式

          symbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;     

          format.TitleSymbol=symbol;

          legend.Format=format;

          legend.Title="图例";

          legend.FlowRight = true;

          legend.ClearItems();        

          IMap map = activeView.FocusMap;      

          for (int i = 0; i < map.LayerCount; i++)

          {

              IFeatureLayer layer = (IFeatureLayer)map.get_Layer(i) as IFeatureLayer;

              ILegendItem item = new HorizontalLegendItemClass();              

              item.Columns=(short)map.LayerCount;

              item.NewColumn=true;        

              ITextSymbol symbolItem = new TextSymbolClass();            

              symbolItem.Size = 11.5;

              ILegendClassFormat legClsFormat = new LegendClassFormatClass();

              legClsFormat.LabelSymbol = symbolItem;

              legClsFormat.PatchHeight = 40;

              legClsFormat.PatchWidth = 50;                

              item.LegendClassFormat = legClsFormat;

              item.Layer=layer;

              item.KeepTogether=false;

              legend.AddItem(item);

          }               

          frame.MapSurround.Name="myLegend";

          IFrameProperties properties = frame as IFrameProperties;

          ISymbolBorder border = new SymbolBorderClass();

          border.Gap=0.0;

          border.CornerRounding=0;

          IBorder border2 = border;

          properties.Border=border2;

          IFrameDecoration decoration = new SymbolBackgroundClass();

          IRgbColor color1 = (IRgbColor)ESRI.ArcGIS.ADF.Converter.ToRGBColor(Color.LightSeaGreen);

          color1.Transparency = 50;

          decoration.Color = color1;

          decoration.CornerRounding=0;

          decoration.HorizontalSpacing=0.0;

          decoration.VerticalSpacing=0.0;

          properties.Background=((IBackground)decoration);

          IElement element = frame as IElement;         

          element.Geometry=envelope;

          element.Activate(activeView.ScreenDisplay);

          container.AddElement(element, 0);

          activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);

      }
           

更新比例尺

在AE中,更新Mxd文档的比例尺,比较特殊。写代码以记录,更新比例尺代码如图所示:

[DllImport("User32.dll")]
public static extern int GetDesktopWindow();
/// <summary>
/// 更新比例尺
/// </summary>
/// <param name="pNewMxdFile"></param>
private void UpdataScale(string pNewMxdFile)
{
IMapDocument tMapDocument2 = new MapDocumentClass();
tMapDocument2.Open(pNewMxdFile);
IPageLayout pageLayout = tMapDocument2.PageLayout;
IActiveView activeView2 = (IActiveView)pageLayout;
IMap map = activeView2.FocusMap;
activeView2.Activate(GetDesktopWindow());
map.MapScale = _MapScale;
activeView2.Refresh();
tMapDocument2.Save(true, false);
tMapDocument2.Close();
}
           

注意事项:在这个方法中,好像只能用于更新比例尺的操作。除此之外,如果做其他操作,就会造成莫名奇妙的错误。例如:先让Map缩放到一个特性的Envelope中后,再更新一个比例尺,就有问题。Mxd打开图后,就看不见数据了。相当奇怪,不知道其他的操作会造成什么影响。主要怀疑是函数GetDesktopWindow在作怪。

所以一般把修改比例尺放到一个单独的函数中。如果Mxd中有多个Map,都要更新比例尺,则代码如下所示:

private void UpdataScale(string pNewMxdFile)
{
IMapDocument mapDocument = new MapDocumentClass();
mapDocument.Open(pNewMxdFile);

IPageLayout pageLayout = mapDocument.PageLayout;
IActiveView activeView = (IActiveView)pageLayout;
IMap map = activeView.FocusMap;

activeView = (IActiveView)mapDocument.PageLayout;
activeView.Activate(GetDesktopWindow());

map.MapScale = _MapScale;
activeView.Refresh();

pageLayout.FocusNextMapFrame();
pageLayout = mapDocument.PageLayout;
activeView = (IActiveView)pageLayout;
map = activeView.FocusMap;

activeView = (IActiveView)mapDocument.PageLayout;
activeView.Activate(GetDesktopWindow());

map.MapScale = _MapScale;
activeView.Refresh();

mapDocument.Save(true, true);
}
           

更改范围

更新Mxd的范围代码如下:

/// <summary>
/// 更新缩放范围
/// </summary>
/// <param name="pNewMxdFile"></param>
private void UpdataExtend(string pNewMxdFile,IEnvelope pEnvelope)
{
IMapDocument tMapDocument2 = new MapDocumentClass();
tMapDocument2.Open(pNewMxdFile);
IPageLayout pageLayout = tMapDocument2.PageLayout;
IActiveView activeView2 = (IActiveView)pageLayout;
IEnvelope pEnv = activeView2.Extent;
pEnv = pEnvelope;
//pEnv.CenterAt(point) //指向中心点
activeView2.Extent = pEnv;
activeView2.Refresh();
tMapDocument2.Save(true, false);
tMapDocument2.Close();
}
           

PageLayout 对象

PageLayout 用以显示地图数据,并通过对地图数据进行整饰以便对地图打印输出满足不同行业对GIS 出图功能的需求。PageLayout 和Map 这两个对象看起来非常相似,它们都是视图对象,可以显示地图;也都是图形元素的容器,可以容纳图形元素(Graphics Element)。但是所能够保存的图形类型却是有差别的。

  • PageLayout 除了保存图形元素外,还可以保存诸如MapFrame 的框架元素(FrameElement)。PageLayout 控件上的Map 对象被PageLayout 的MapFrame 对象所管理的。
  • PageLayout 类主要实现了IPageLayout 接口,它定义了用于修改页面版式(layout)的方法和属性。
  • IPageLayout 的方法ZoomToWhole 方法可以让PageLayout 以最大尺寸显示;
  • IPageLayout 的ZoomToPercent 方法可以按照输入的比例显示;
  • IPageLayout 的ZoomToWidth 方法可以让视图显示的范围匹配控件对象的宽度。
  • IPageLayout 的Page 属性用以获取Page 对象
  • IPageLayout 的RulerSettings 属性用以获取RulerSettings 对象
  • IPageLayout 的HorizontalSnapGuides 和VerticalSnapGuides 属性用以获取SnapGuides 对象

继续阅读