放大镜,在地图的浏览过程中在主地图和次地图中起到很好的辅助作用,
要实现放大镜功能主要就是通过两个mapControl控件,主地图控件是mapControlMain,放大镜控件是UserControl_Magnifier,实现关键点有两点:1、如何使两个控件使用的数据保持一致;2、如何绘制放大镜中的元素框。
一、数据一致
当主地图添加地图图层数据就会触发接口IActiveViewEvents接口中的地图添加事件OnLayerAdded,或者图层的删除等操作,放大镜的控件就会将图层数据添加到放大镜视图中。 mapControl1代表的是放大镜中的地图控件
1 /// <summary>
2 /// 加载事件
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void UserControl_MagnifyingGlass_Load(object sender, EventArgs e)
7 {
8 if (!m_BInitialized) return;
9 load();
10 addElement();
11 IActiveViewEvents activeViewEvents = (IActiveViewEvents)m_ActiveView;
12 activeViewEvents.OnLayerAdded += activeViewEvents_OnLayerAdded;
13 activeViewEvents.OnLayerDeleted += activeViewEvents_OnLayerDeleted;
14 }
15
16 /// <summary>
17 /// OnLayerAdded事件
18 /// </summary>
19 /// <param name="layer"></param>
20 void activeViewEvents_OnLayerAdded(ILayer layer)
21 {
22 load();
23 addElement();
24 }
25 /// <summary>
26 /// 加载函数
27 /// </summary>
28 private void load() {
29 if (!m_BInitialized) return;
30 mapControl1.FocusMap = m_ActiveView.FocusMap.Clone();
31 mapControl1.Extent = m_ActiveView.Extent;
32 mapControl1.ActiveView.DisplayTransformation.MapScale =3; mapControl1.PartialRefresh(ViewDrawPhaseType.ViewAll);
33 }
二、绘制放大镜的显示框
显示框采用的是曲线元素和线元素(ILineElemnet和ICurveElement)。
放大镜的功能主要包括两种操作,第一:当鼠标在主地图上移动的时候,放大镜的范围以鼠标移动的地方为中心按照一定的比例进行显示,圆和十字元素的中心就是放大镜地图的中心,本示例中比例固定设置为3,放大镜地图中的范围显示框跟着变化;第二,主地图的视图范围发生变化时,放大镜地图的显示范围和显示框也会跟着变化。
1、当鼠标在主地图上移动的时候,会触发MouseMove事件,那么放大镜的地图范围就会以鼠标所移动的坐标为中心进行范围显示。
1 /// <summary>
2 /// MouseMove事件
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6 private void mapControl_MouseMove(object sender, MouseEventArgs e)
7 {
8 IMapControl mapControl = m_Application.MapControl;
9 IMapControl mapControl1 = m_Magnifier.GetMapControl();
10 PIE.Geometry.IPoint point = mapControl.ToMapPoint(e.X, e.Y);
11 m_Point = point;
12 mapControl1.CenterAt(point);
13 m_Magnifier.addElement();
14 }
15
16 /// <summary>
17 /// 添加准星函数(绘制放大镜地图中的显示框一个圆和一个十字形)
18 /// </summary>
19 public void addElement() {
20 IEnvelope extent = mapControl1.Extent;
21 IGraphicsContainer graphicsContainer = mapControl1.ActiveView.GraphicsContainer;
22 graphicsContainer.DeleteAllElements();
23
24 IPointCollection line1 = new Polyline();
25 line1.AddPoint((extent.XMin + extent.XMax) / 2, extent.YMin);
26 line1.AddPoint((extent.XMin + extent.XMax) / 2, extent.YMax);
27
28 ILineSymbol symbol = new SimpleLineSymbol();
29 symbol.Color = Color.Red;
30
31 ILineElement lineElement1 = new LineElement();
32 lineElement1.Geometry = line1 as IGeometry;
33 lineElement1.Symbol = symbol;
34
35 IPointCollection line2 = new Polyline();
36 line2.AddPoint(extent.XMin, (extent.YMin + extent.YMax) / 2);
37 line2.AddPoint(extent.XMax, (extent.YMin + extent.YMax) / 2);
38 ILineElement lineElement2 = new LineElement();
39 lineElement2.Geometry = line2 as IGeometry;
40 lineElement2.Symbol = symbol;
41
42 IArc arc = new Arc();
43 arc.PutCoords((extent.XMin + extent.XMax) / 2, (extent.YMin + extent.YMax) / 2);
44 arc.StartAngle = 0;
45 arc.EndAngle = 360;
46 arc.SemiMajor = (extent.XMax - extent.XMin) / 4;
47 arc.SemiMinor = (extent.XMax - extent.XMin) / 4;
48
49 ICurveElement curveElement = new CurveElement();
50 curveElement.Geometry = arc as IGeometry;
51 curveElement.Symbol = symbol;
52
53 graphicsContainer.AddElement(lineElement1);
54 graphicsContainer.AddElement(lineElement2);
55 graphicsContainer.AddElement(curveElement);
56
57 mapControl1.PartialRefresh(ViewDrawPhaseType.ViewAll);
58 }
59 /// <summary>
60 /// OnVisibleBoundsUpdated事件
61 /// </summary>
62 /// <param name="displayTransformation"></param>
63 /// <param name="bVisibleBoundChanged"></param>
64 private void TransformEvent_OnVisibleBoundsUpdated(IDisplayTransformation displayTransformation, bool bVisibleBoundChanged)
65 {
66 IMapControl mapControl1 = m_Magnifier.GetMapControl();
67
68 PIE.Carto.IActiveView activeView = m_HookHelper.ActiveView;
69 PIE.Geometry.IPoint point = (activeView.Extent as PIE.Geometry.IGeometry).Centroid();
70 mapControl1.ActiveView.PanTo(point);
71 mapControl1.ActiveView.DisplayTransformation.MapScale = 3;
72
73 mapControl1.CenterAt(m_Point);
74 m_Magnifier.addElement();
75 mapControl1.PartialRefresh(ViewDrawPhaseType.ViewAll);
76 }
2、当主地图mapControlMain范围发生变化时,会触发OnVisibleBoundsUpdated事件,那么放大镜的显示框的位置和范围应跟着发生变化。
1 ITransformEvents transformEvent = (ITransformEvents)activeView.DisplayTransformation; transformEvent.OnVisibleBoundsUpdated += TransformEvent_OnVisibleBoundsUpdated;
2 /// <summary>
3 /// OnVisibleBoundsUpdated事件
4 /// </summary>
5 /// <param name="displayTransformation"></param>
6 /// <param name="bVisibleBoundChanged"></param>
7 private void TransformEvent_OnVisibleBoundsUpdated(IDisplayTransformation displayTransformation, bool bVisibleBoundChanged)
8 {
9 IMapControl mapControl1 = m_Magnifier.GetMapControl();
10
11 PIE.Carto.IActiveView activeView = m_HookHelper.ActiveView;
12 PIE.Geometry.IPoint point = (activeView.Extent as PIE.Geometry.IGeometry).Centroid();
13 mapControl1.ActiveView.PanTo(point);
14 mapControl1.ActiveView.DisplayTransformation.MapScale = 3;
15
16 mapControl1.CenterAt(m_Point);
17 m_Magnifier.addElement();
18 mapControl1.PartialRefresh(ViewDrawPhaseType.ViewAll);
19 }
代码路径:
项目名称 | 百度云盘地址下/PIE示例程序/13.小工具集锦/地图平移校正/ PIEMapApplication1 |
数据路径 | 百度云盘地址下/PIE示例数据/栅格数据/04.World/World.tif |
视频路径 | 百度云盘地址下/PIE视频教程/13.小工具集锦/地图放大镜.avi |
注意:
在地图初始化的时候,图层树控件需要手动绑定地图控件:
tocControlMain.SetBuddyControl(mapControlMain as PIE.Carto.IPmdContents);