zoukankan      html  css  js  c++  java
  • ArcGis 制图——地图图框整饰的插件式实现(一)C#

    如有插件定制需求或技术交流,欢迎联系QQ 975601416

    写完了自己瞅了一眼都不想看,希望有需要的你能看懂。

    先摆一张效果图:


     下面进入主题,本篇先讲一下地图布局中的对象,正文中会对一些关键词用英文补充说明一下,这可不是作者在显摆,了解下功能的英文表述对查询帮助是很有帮助的。

     直达链接:

    PageLayout 页面布局视图,元素的容器

    Page  版面,用于控制打印纸张

    IElement接口 页面元素

    IFrameElement接口 框架元素,图框、外图框即此

    MapFrame 地图(map)的容器

    FrameElement 地图外框

    MapSurroundFrame  用于管理地图周边元素(MapSurround,比例尺、指北针、图例等)

    ITextElement 标题等文字元素

     


    先介绍一下主要对象类型——容器PageLayout与存放在容器中的Element元素。

    PageLayout对象

    ArcGis数据框有两个视图,“数据视图”(DataView)与“布局视图”(LayoutView)。制图是在“布局视图”里操作,在ArcObject里进行图框整饰就是操作“PageLayout”对象。

    “PageLayout”对象实现了IGraphicsContainer接口,顾名思义,该接口提供了容器,用以存放、管理graphic elements。通过AddElement方法可以将元素(IElement)放入PageLayout,通过DeleteElement方法可以删除元素。

    1 //PageLayout作为容器
    2 IGraphicsContainer pGraphicsContainer = pPageLayout as IGraphicsContainer;
    3 //IElement类型元素放入PageLayout,注意第二参zeorder固定为0(10.1,作者没有研究高版本API是否有改动)。
    4 pGraphicsContainer.AddElement(element,0);
    5 //删除元素,注意这个element是程序运行已经存在内存中的,放入PageLayout的对象
    6 pGraphicsContainer.DeleteElement(element);

    Page对象

    打印纸张的版面控制。

    //单位,一般用厘米
    pPageLayout.Page.Units = esriUnits.esriCentimeters;
    //传入double类型值,设置页面长、宽
    pPageLayout.Page.PutCustomSize(width, height);
    //读取当前版面的长宽值
    double width;
    double height;
    pPageLayout.Page.QuerySize(out width, out height);

     IElement元素

    在 ArcGIS 中显示在视图上的数据有两类:一类是地理要素数据,包括矢量要素数据、栅格数据、 Tin 等表面数据等,存储在 Geodatabase 或数据文件(如shapefile)中,它们是用于 GIS 分析制图的源数据;另一类是元素(Element),元素是一个地图除去要素数据外的部分,即在一幅地图中,除了地理数据外,其余的对象全部都是元素。

    Element对象是一个庞大复杂的对象集合,它分为图形元素(GraphicElement)和框架元素(Frame Element)。图形元素主要包括 TextElement、 MarkerElement、 LineElement、 FillShapeElement、GroupElement 、 PictureElement 等 。 框 架 元 素 主 要 包 括 MapFrame 、MapSurroundFrame、 Table Frames 等。 这些元素都实现了IElement接口。

    地图图框整饰的几个基本元素有图框(Frame)、标题(Title)、比例尺(Scale)、图例(Legend)、指北针(NorthArrow)、其他辅助要素(底部文字等)。

    IFrameElement框架元素

    pageLayout中用于存放地图的MapFrame实现了IMapFrame接口,该接口继承自IFrameElement接口,外框线可以使用FrameElement对象实现。

    图框细分应该会有内图框、外图框。

    MapFrame对象 内框

    MapFrame是一个展示、存放Map图层要素(layers)的地方,直接切换到“布局视图”就可以看到它,内图框是MapFrame的边框。

    内框MapFrame与PageLayout.Page的距离(上、下、侧)需要给定。图框肯定要从纸张边缘往里缩一定距离才是。

    //根据与Page边的距离确定一个Envelpoe,通过它设置地图框架MapFrame的位置
    IFrameElement pFrameElement = pGraphicsContainer.FindFrame(pActiveView.FocusMap);//pGraphicsContainer容器是什么?
    IMapFrame pMapFrame = pFrameElement as IMapFrame; 
    IEnvelope pEnvelopeMapFrame
    = new EnvelopeClass();
    pEnvelopeMapFrame.PutCoords(xmin, ymin, xmax, ymax);
    IElement pElement
    = pFrameElement as IElement;
    pElement.Geometry
    = pEnvelopeMapFrame;

    FrameElement对象 外框

    外图框只用来展示一个粗线框,其几何图形可以是MapFrame的Envelpoe外扩一定距离形成的一个Envelpoe(这里称作pEnvelpoeOuter),将FrameElement的Geometry属性设置为pEnvelpoeOuter,将FrameElement对象的边框(Boder)的线型、宽度设置一下就做出来了。

                //set Outer-border frame
                FrameElement frameElementOuter = new FrameElementClass();
                IFrameElement pFrameElementOuter = frameElementOuter as IFrameElement;
                IElementProperties3 pElementProperties = pFrameElementOuter as IElementProperties3;
                pElementProperties.Name = "OuterBorder";
                IEnvelope pEnvelpoeOuter = new EnvelopeClass();
                pEnvelpoeOuter.PutCoords(xmin - 0.2, ymin - 0.2, xmax + 0.2, ymax + 0.2);
                frameElementOuter.Geometry = pEnvelpoeOuter;
    
                //set Outer-border line style
                ILineSymbol pLineSymbol = DisplayUtils.CartoLineSymbol(3.0, DisplayUtils.RGBColor(0, 0, 0));
                ISymbolBorder pSymbolBorder = new SymbolBorderClass();
                pSymbolBorder.LineSymbol = pLineSymbol;
                IFrameProperties pFramePropertiesOuter = pFrameElementOuter as IFrameProperties;
                pFramePropertiesOuter.Border = pSymbolBorder;
                return frameElementOuter;

    MapSurroundFrame 地图周边元素,实现了IMapSurroundFrame接口,该接口同样继承自IFrameElement接口。

    比例尺、图例、指北针是MapFrame的MapSurround对象,比例尺、图例是明显的与MapFrame相关,是随图层信息动态变化的。
    比例尺:采用文本型比例尺,uid.Value = "esriCarto.ScaleText"。根据MapFrame的Envelpoe与PageLayout的Page的相对位置确定其放置的。
    图例:uid.Value = "esriCarto.Legend"。根据MapFrame的Envelpoe确定其位置。
    指北针: uid.Value = "esriCarto.MarkerNorthArrow"。根据MapFrame的Envelpoe确定其位置。其实质是一个字符,“运行”——输入“charmap”可以打开“字符映射表”,选择ESRI North字体,选择对应的字形可以看到其16进制的CharacterIndex,使用科学计算器计算出10进制的值就可以在程序中使用了。

       public IElement AddNorthArrow(IPageLayout pPageLayout, double distanceToInnerBorder, double size, int characterIndex)
            {
                IUID uid = new UIDClass();
                uid.Value = "esriCarto.MarkerNorthArrow";
                IActiveView pActiveView = pPageLayout as IActiveView;
                IMapFrame pMapFrame = pGraphicsContainer.FindFrame(pActiveView.FocusMap) as IMapFrame;
    
                IMapSurroundFrame pMapSurroundFrame = pMapFrame.CreateSurroundFrame(uid as UID, null);
                pMapSurroundFrame.MapSurround.Name = "NorthArrow";
    
                IMarkerNorthArrow pMarkerNorthArrow = pMapSurroundFrame.MapSurround as IMarkerNorthArrow; 
                IMarkerSymbol pMarkerSymbol = pMarkerNorthArrow.MarkerSymbol;
                ICharacterMarkerSymbol pCharacterMarkerSymbol = pMarkerSymbol as ICharacterMarkerSymbol;
                pCharacterMarkerSymbol.CharacterIndex = characterIndex ;
                pCharacterMarkerSymbol.Size = size;
                pMarkerNorthArrow.MarkerSymbol = pCharacterMarkerSymbol;
    
                double xmin = pEnvelopeMapFrame.XMax - distanceToInnerBorder;
                double ymin = pEnvelopeMapFrame.YMax - distanceToInnerBorder;
                double xmax = pEnvelopeMapFrame.XMax - 1;
                double ymax = pEnvelopeMapFrame.YMax - 1;
                IEnvelope pEnvelope = new EnvelopeClass();
                pEnvelope.PutCoords(xmin, ymin, xmax, ymax);
                IFillSymbol pFillSymbol = DisplayUtils.SimpleFillSymbol(esriSimpleFillStyle.esriSFSSolid, DisplayUtils.CartoLineSymbol(0, DisplayUtils.RGBColor()), DisplayUtils.RGBColor(255, 255, 255));
                pMapSurroundFrame.Background = DisplayUtils.SymbolBackGRound(pFillSymbol );
                IElement pNorthArrowElement  = pMapSurroundFrame as IElement;
                pNorthArrowElement.Geometry = pEnvelope;
                return pNorthArrowElement;
            }

    ITextElement  文字元素,用来设置标题与其他文字元素
    标题

    根据MapFrame的Envelpoe与PageLayout.Page 的宽度(width)、高度(height)确定一个位于MapFrame上方且居中的Envelpoe(这里称作TitleEnvelpoe)。创建一个TextElementClass,设置其样式,然后将其Geometry属性设置为TitleEnvelpoe就可以了。

      public IElement AddTitle(IPageLayout pPageLayout, string title,string font,double size)
            {
                ITextElement pTextElement = new TextElementClass();
                pTextElement.Text = title;
    
                pTextElement.Symbol = DisplayUtils.TextSymbol(font, size,esriTextHorizontalAlignment.esriTHACenter,esriTextVerticalAlignment.esriTVACenter);
               
                double width;
                double height;
                pPageLayout.Page.QuerySize(out width, out height);
    
                double xmin = 0;
                double ymin = pEnvelopeMapFrame.YMax;
                double xmax = width;
                double ymax = height;
                IEnvelope pEnvelope = new EnvelopeClass();
                pEnvelope.PutCoords(xmin, ymin, xmax, ymax);
    
                IElement pElement = pTextElement as IElement;
                IElementProperties3 pElementProperties3 = pElement as IElementProperties3;
                pElementProperties3.Name = "Title";
                pElement.Geometry = pEnvelope;
                return pElement;
            }

    底部文字

    也是是根据MapFrame的Envelpoe与PageLayout.Page的相对位置,分别确定出位于MapFrame左下角、右下角的两个Envelpoe,然后创建两个TextElementClass,设置其样式,分别塞到Envelpoe。

  • 相关阅读:
    BZOJ 3744 Gty的妹子序列
    BZOJ 3872 Ant colony
    BZOJ 1087 互不侵犯
    BZOJ 1070 修车
    BZOJ 2654 tree
    BZOJ 3243 向量内积
    1003 NOIP 模拟赛Day2 城市建设
    CF865D Buy Low Sell High
    CF444A DZY Loves Physics
    Luogu 4310 绝世好题
  • 原文地址:https://www.cnblogs.com/yzhyingcool/p/10065605.html
Copyright © 2011-2022 走看看