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方法可以删除元素。
//PageLayout作为容器
IGraphicsContainer pGraphicsContainer = pPageLayout as IGraphicsContainer;
//IElement类型元素放入PageLayout,注意第二参zeorder固定为0(10.1,作者没有研究高版本API是否有改动)。
pGraphicsContainer.AddElement(element,);
//删除元素,注意这个element是程序运行已经存在内存中的,放入PageLayout的对象
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(, , ));
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 - ;
double ymax = pEnvelopeMapFrame.YMax - ;
IEnvelope pEnvelope = new EnvelopeClass();
pEnvelope.PutCoords(xmin, ymin, xmax, ymax);
IFillSymbol pFillSymbol = DisplayUtils.SimpleFillSymbol(esriSimpleFillStyle.esriSFSSolid, DisplayUtils.CartoLineSymbol(, DisplayUtils.RGBColor()), DisplayUtils.RGBColor(, , ));
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 = ;
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。
ArcGis 制图——地图图框整饰的插件式实现(一)C#的更多相关文章
- ArcGIS制图表达Representation实战篇4-自由式制图表达
ArcGIS制图表达Representation实战篇4-自由式制图表达 by 李远祥 上一章节关于制图表达的控制点中已经介绍过制图表达的编辑功能,利用制图表达的编辑功能,可以实现一些规则以外的效果. ...
- ArcGIS制图技巧系列(3)—让地图更有立体感
ArcGIS制图技巧系列(3)-让地图更有立体感 by 李远祥 在前面的章节中,我们已经介绍过各种的地图效果,如发光效果,山体阴影效果,植被填充效果等,所有的这些效果不外乎是各种技术的叠加和技巧的使用 ...
- (转)ArcGIS制图技巧
ArcGIS制图技巧(转载自新浪博客) 1 引言 1.1 制图的目的 随着GIS在各行各业的深入应用,各信息化部门和生产单位都逐渐建立起自己的GIS的应用,同时积累了大量的地理数据.随着应用深 ...
- ArcGIS制图表达Representation实战篇2-河流渐变与符号旋转
ArcGIS制图表达Representation实战篇2-河流渐变与符号旋转 by 李远祥 上一章节主要是从实战中使用规则和几何效果,如何分解制图规则.本章主要还是通过一些特殊要求如河流线宽渐变和符号 ...
- ArcGIS制图技巧系列(2)地形渲染
ArcGIS制图技巧系列(2)地形渲染 by 李远祥 DEM数据是常见的地形数据,在GIS常规的制图中,DEM一直扮演着增强效果.由于带有高程值,DEM在很多情况下都在三维中显示,但这里主要介绍的是在 ...
- ArcGIS制图技巧系列(1)还原真实的植被
ArcGIS制图技巧系列(1)还原真实的植被 by 李远祥 在GIS数据中,植被一般都是面装要素的形式存在.很多人在使用植被渲染的时候,一般会采用填充符号去渲染.而在ArcGIS中,填充符号要么就是纯 ...
- PIE.NET-SDK插件式二次开发文档
一 PIE.Net开发环境部署 1. 开发环境部署 确保Win7系统已安装SP1 安装Visual Studio2013(支持VS2010/2012/2013/2015) 安装PIESDK.e ...
- (1)从底层设计,探讨插件式GIS框架的实现
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 研一时,听当时的师兄推荐,买了蒋波涛的一本关于GIS插件框架的书.当时 ...
- ArcGIS制图表达Representation实战篇1-边界线和行道树制作
ArcGIS制图表达Representation实战篇1-边界线和行道树制作 by 李远祥 即便是有了一些制图表达的基础,很多人还是对ArcGIS制图表达理解停留在表面,因为没有实际的强化训练是很难体 ...
随机推荐
- CodeForces 632C The Smallest String Concatenation//用string和sort就好了&&string的基础用法
Description You're given a list of n strings a1, a2, ..., an. You'd like to concatenate them togethe ...
- 【Loj116】有源汇有上下界最大流(网络流)
[Loj116]有源汇有上下界最大流(网络流) 题面 Loj 题解 模板题. #include<iostream> #include<cstdio> #include<c ...
- [2017-7-26]Android Learning Day4
RecycleView 恩,学习Fragment的过程中的一个小实践居然用到了RecycleView!坑了我好久有木有!!好气哦,从昨晚到现在.(现在也还是一头雾水,不过照搬也会用了) 这是第一版的代 ...
- LOJ#6277. 数列分块入门 1
分块思想,先把原来的序列分成根号n快,然后对于更新的部分,先操作这个序列边上的部分,然后再中间部分整块操作,这样复杂度就是O(根号N) #include<map> #include< ...
- 【mysql】mysql null值
在数据表我们有时候有些表字段会为null,表示空.其实在mysql中null值是占用空间的. mysql手册如下解释 NULL columns require additional space in ...
- 20165223 《JAVA程序设计》第五周学习总结
教材学习内容总结 第七章要点 内部类 匿名类 异常类 断言 第十章要点 File类 文件字节/字符的输入.输出流 缓冲流 随机流 数组流 数据流 对象流 序列化和对象克隆 使用Scanner解析文件 ...
- CodeForces - 589D(暴力+模拟)
题目链接:http://codeforces.com/problemset/problem/589/D 题目大意:给出n个人行走的开始时刻,开始时间和结束时间,求每个人分别能跟多少人相遇打招呼(每两人 ...
- css 蒙层
蒙层 利用z-index: .mui-backdrop-other { position: fixed; top: 44px; right:; bottom:; left:; z-index:; ba ...
- HEOI2019退役总结
真的很快,一切就都已经尘埃落定了. 其实经历不是很圆满的时候,是不想写这一类游记总结的,但这次其实不太一样,总要让这段经历有始有终. 可能会很啰嗦…… 赛前 收到了若干鼓励,包括老师的手写祝福和学长学 ...
- zabbix监控URL
选在相应主机,并添加Web监控 按照方式新建Web场景 注意: 名称统一规则:web_check_相应的域名 应用集:新建一个,名称为“web状态” 更新间隔:改为30s,默认为1m 尝试次数:改为2 ...