最近,看到打聽鷹眼問題的朋友特別多。AE+C#的鷹眼在網上代碼已經很多了,我今天也放一個版本上 來,主要有以下幾個功能:
1.主地圖窗口視圖范圍改變後,鷹眼窗口繪制一個紅色的框顯示當前區域;
2.主地圖比例尺發生改變後,鷹眼地圖的比例尺也發生改變,只是改變的程度將小而已;(這和網上其 它代碼不同,借鑒google地圖鷹眼的顯示效果)
3.在鷹眼地圖上,用鼠標左鍵可以移動紅色的區域框,松開鼠標後,主窗口地圖視圖范圍更新為移動 後的框的范圍;
4.在鷹眼地圖上,用鼠標右鍵可以拉一個框,主窗口視圖范圍更新為這個框的范圍。
好了,話不多話,全代碼放出:
1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Text;
7 using System.Windows.Forms;
8 using ESRI.ArcGIS.Carto;
9 using ESRI.ArcGIS.Geometry;
10 using ESRI.ArcGIS.Display;
11 using ESRI.ArcGIS.esriSystem;
12
13 namespace WindowsFormsApplication19
14 {
15 public partial class Form1 : Form
16 {
17 public Form1()
18 {
19 InitializeComponent();
20 }
21
22
23 private void Form1_Load(object sender, EventArgs e)
24 {
25 AddLayerToOverViewMap(); //加入地圖到鷹眼裡
26 }
27
28
29 /// <summary>
30 /// 主地圖更換時,更新鷹眼窗口
31 /// </summary>
32 /// <param name="sender"></param>
33 /// <param name="e"></param>
34 private void MainMapControl_OnMapReplaced(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMapReplacedEvent e)
35 {
36 AddLayerToOverViewMap();
37 }
38 /// <summary>
39 /// 把地圖加到鷹眼裡
40 /// </summary>
41 private void AddLayerToOverViewMap()
42 {
43 OverViewMapControl.ClearLayers();
44 for (int i = 0; i < MainMapControl.LayerCount; i++)
45 {
46 IObjectCopy objectcopy = new ObjectCopyClass();
47 object toCopyLayer = MainMapControl.get_Layer (i);
48 object copiedLayer = objectcopy.Copy (toCopyLayer);
49 ILayer C = (new FeatureLayerClass()) as ILayer;
50 object toOverwriteLayer = C;
51 objectcopy.Overwrite(copiedLayer, ref toOverwriteLayer);
52 OverViewMapControl.AddLayer(C, i);
53 }
54 }
55
56 /// <summary>
57 /// 主地圖窗口視圖范圍發生改變後,更新鷹眼上的紅色矩形框
58 /// </summary>
59 /// <param name="sender"></param>
60 /// <param name="e"></param>
61 private void MainMapControl_OnExtentUpdated(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnExtentUpdatedEvent e)
62 {
63 try
64 {
65 IGraphicsContainer pGraphicsContainer = OverViewMapControl.Map as IGraphicsContainer;
66 IActiveView pAv = pGraphicsContainer as IActiveView;
67 pGraphicsContainer.DeleteAllElements();
68 IRectangleElement pRecElement = new RectangleElementClass();
69 IElement pEle = pRecElement as IElement;
70 pEle.Geometry = e.newEnvelope as IEnvelope;
71
72 IEnvelope mm = new EnvelopeClass();
73 mm.XMax = pEle.Geometry.Envelope.XMax + 3;
74 mm.XMin = pEle.Geometry.Envelope.XMin - 3;
75 mm.YMax = pEle.Geometry.Envelope.YMax + 3;
76 mm.YMin = pEle.Geometry.Envelope.YMin - 3;
77 OverViewMapControl.Extent = mm;
78
79 IRgbColor pColor = new RgbColorClass();
80 pColor.Red = 200;
81 pColor.Green = 0;
82 pColor.Blue = 0;
83 pColor.Transparency = 255;
84
85 //產生一個線符號對象
86 ILineSymbol pLineSymbol = new SimpleLineSymbolClass ();
87 pLineSymbol.Width = 2;
88 pLineSymbol.Color = pColor;
89
90 //設置填充符號的屬性
91 IFillSymbol pFillSymbol = new SimpleFillSymbolClass ();
92
93 // 設置透明顏色
94 pColor.Transparency = 0;
95 pFillSymbol.Color = pColor;
96 pFillSymbol.Outline = pLineSymbol;
97
98 //
99 IFillShapeElement pFillShapeElement = pRecElement as IFillShapeElement;
100 pFillShapeElement.Symbol = pFillSymbol;
101
102 pGraphicsContainer.AddElement(pEle, 0);
103 OverViewMapControl.ActiveView.PartialRefresh (esriViewDrawPhase.esriViewGraphics, null, null);
104
105 //
106 }
107 catch (Exception ey)
108 {
109 }
110 }
111
112 /// <summary>
113 /// 鷹眼窗口,用鼠標右鍵拉框,更改主窗口當前視圖范圍
114 /// </summary>
115 /// <param name="sender"></param>
116 /// <param name="e"></param>
117 private void OverViewMapControl_OnMouseDown(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
118 {
119 #region 鷹眼
120 if (e.button == 2)
121 {
122 try
123 {
124 IPoint pPt = new PointClass();
125 pPt.X = e.mapX;
126 pPt.Y = e.mapY;
127 IEnvelope pEnvelope = OverViewMapControl.TrackRectangle();
128 MainMapControl.Extent = pEnvelope;
129 }
130 catch
131 { }
132 }
133 #endregion
134 }
135
136 /// <summary>
137 /// 鷹眼窗口,用鼠標左鍵移動視圖范圍
138 /// </summary>
139 /// <param name="sender"></param>
140 /// <param name="e"></param>
141 private void OverViewMapControl_OnMouseMove(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
142 {
143
144 if (e.button == 1)
145 {
146 try
147 {
148 IPoint pPt = new PointClass();
149 pPt.X = e.mapX;
150 pPt.Y = e.mapY;
151 //
152 IEnvelope pEnvelope = MainMapControl.Extent as IEnvelope;
153 pEnvelope.CenterAt(pPt);
154 IActiveView pAv;
155 IGraphicsContainer pGraphicsContainer = OverViewMapControl.Map as IGraphicsContainer;
156 pAv = pGraphicsContainer as IActiveView;
157 pGraphicsContainer.DeleteAllElements();
158 IRectangleElement pRecElement = new RectangleElementClass();
159 IElement pEle = pRecElement as IElement;
160 pEle.Geometry = pEnvelope;
161 //顏色
162 IRgbColor pColor = new RgbColorClass();
163 pColor.Red = 200;
164 pColor.Green = 0;
165 pColor.Blue = 0;
166 pColor.Transparency = 255;
167
168 //產生一個線符號對象
169 ILineSymbol pLineSymbol = new SimpleLineSymbolClass();
170 pLineSymbol.Width = 2;
171 pLineSymbol.Color = pColor;
172
173 //設置填充符號的屬性
174 IFillSymbol pFillSymbol = new SimpleFillSymbolClass();
175
176 // 設置透明顏色
177 pColor.Transparency = 0;
178 pFillSymbol.Color = pColor;
179 pFillSymbol.Outline = pLineSymbol;
180
181 //
182 IFillShapeElement pFillShapeElement = pRecElement as IFillShapeElement;
183 pFillShapeElement.Symbol = pFillSymbol;
184
185 pGraphicsContainer.AddElement(pEle, 0);
186 OverViewMapControl.ActiveView.PartialRefresh (esriViewDrawPhase.esriViewGraphics, null, null);
187
188 }
189 catch
190 {
191 }
192 }
193
194
195 }
196
197 /// <summary>
198 /// 鷹眼窗口,左鍵移動視圖框後,更新主窗口
199 /// </summary>
200 /// <param name="sender"></param>
201 /// <param name="e"></param>
202 private void OverViewMapControl_OnMouseUp(object sender, ESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseUpEvent e)
203 {
204 #region 鷹眼
205 if (e.button == 1)
206 {
207 try
208 {
209 IPoint pPt = new PointClass();
210 pPt.X = e.mapX;
211 pPt.Y = e.mapY;
212
213 IEnvelope pEnvelope = MainMapControl.Extent as IEnvelope;
214 pEnvelope.CenterAt(pPt);
215 MainMapControl.Extent = pEnvelope;
216 }
217 catch
218 {
219 }
220 }
221 #endregion
222 }
223
224 }
225 }
226
重要:需要注意這一部分代碼:
/// <summary>
/// 把地圖加到鷹眼裡
/// </summary>
private void AddLayerToOverViewMap()
{
OverViewMapControl.ClearLayers();
for (int i = 0; i < MainMapControl.LayerCount; i++)
{
IObjectCopy objectcopy = new ObjectCopyClass();
object toCopyLayer = MainMapControl.get_Layer(i);
object copiedLayer = objectcopy.Copy(toCopyLayer);
ILayer C = (new FeatureLayerClass()) as ILayer;
object toOverwriteLayer = C;
objectcopy.Overwrite(copiedLayer, ref toOverwriteLayer);
OverViewMapControl.AddLayer(C, i);
}
}
一般鷹眼程序裡都是這樣寫:
OverViewMapControl.ClearLayers();
for (int i = 0; i < MainMapControl.LayerCount; i++)
{
OverViewMapControl.AddLayer(MainMapControl.get_Layer (i));
}
這樣的後果可能會導致“"嘗試讀取或寫入受保護的內存,這通常指示其他內存已損壞”這樣的異常。 這是因為,兩個地圖控件裡面的圖層都指向了同一塊內存空間,在操作的時候, 兩個地圖控件進行了不 同的操作,從而導致異常。所以我采用了硬拷貝內存的方法,效果很好!
/// <summary>
/// 把地圖加到鷹眼裡
/// </summary>
private void AddLayerToOverViewMap()
{
OverViewMapControl.ClearLayers();
for (int i = 0; i < MainMapControl.LayerCount; i++)
{
IObjectCopy objectcopy = new ObjectCopyClass();
object toCopyLayer = MainMapControl.get_Layer(i);
object copiedLayer = objectcopy.Copy(toCopyLayer);
ILayer C = (new FeatureLayerClass()) as ILayer;
object toOverwriteLayer = C;
objectcopy.Overwrite(copiedLayer, ref toOverwriteLayer);
OverViewMapControl.AddLayer(C, i);
}
}