ArcEngine鹰眼的实现
2009-11-10 20:30:10 来源:WEB开发网大家都用过百度地图或者google地图吧,在它们主地图的右下角,有个小地图窗口,这就是鹰眼窗口。用鼠标拖动鹰眼里的小窗口,则主地图便移动到相应的位置。下面就介绍鹰眼的实现。
鹰眼和主地图的互动,主要体现在两个方面:一是主地图的地图改变了,则鹰眼里的矩形框要移动到对应的位置,以指示当前地图在整个地图中的位置;二是鹰眼的矩形框移动了,则主地图中显示的地图要移动到相应的位置。
ArcEngine中显示地图的控件叫 ESRI MapControl,这里主要用到了它的OnAfterDraw事件。在主地图的OnAfterDrawMapControl事件中,根据当前地图的大小,改变鹰眼中矩形框的大小;在鹰眼的OnAfterDraw事件中,根据矩形框的位置,确定主地图中地图的位置。google地图的鹰眼还实现了矩形框的拖动,这个也很好实现,呵呵。在鼠标点击到鹰眼控件时,先判断是否在矩形框内,如果在的话,用一个状态量记住这个状态,此时如果鼠标移动,则矩形框跟着相应的移动;若不在矩形框内,则矩形框移动到鼠标点击的位置。下面的代码是基于VC6和ArcEngine9.2实现的。鹰眼矩形框的拖动涉及到的事件比较多,包括OnMouseDownMapControl、OnMouseMoveMapControl、OnMouseUpMapControl事件。
1
2 class CEagleEyeCtrl : public CStatic
3 {
4 // Construction
5 public:
6 CEagleEyeCtrl();
7 CMapControlDefault m_MapCtrl;
8 IFillShapeElementPtr m_ipFillShapeElement;
9 IEnvelopePtr m_ipLastEnvelope;
10 IPointPtr m_ipPoint;
11 int m_nAction;
12 BOOL m_bDrag; // 红框拖动的标记
13 BOOL m_bDragWnd; // 拖动整个鹰眼窗口
14 BOOL m_bShow;
15 CPoint m_point; // 鼠标上一次左键按下的屏幕坐标
16 afx_msg void OnMouseDownMapcontrol(long button, long shift, long X, long Y, double mapX, double mapY);
17 afx_msg void OnMouseMoveMapcontrol(long button, long shift, long X, long Y, double mapX, double mapY);
18 afx_msg void OnMouseUpMapcontrol(long button, long shift, long X, long Y, double mapX, double mapY);
19 afx_msg void OnAfterDrawMapcontrol(const VARIANT FAR& Display, long viewDrawPhase);
20 DECLARE_EVENTSINK_MAP()
21 DECLARE_MESSAGE_MAP()
22 };
23
24 void CEagleEyeCtrl::OnMouseDownMapcontrol(long button, long shift, long X,
25 long Y, double mapX, double mapY)
26{
27 // TODO: Add your control notification handler code here
28 IActiveViewPtr ipActiveView;
29 ipActiveView = m_MapCtrl.GetActiveView();
30 if (ipActiveView == NULL)
31 {
32 return ;
33 }
34
35 IPointPtr ipPoint(CLSID_Point);
36 IRgbColorPtr ipRgbColor(CLSID_RgbColor);
37
38 HRESULT hr = ipPoint->PutCoords(mapX, mapY);
39 hr = ipRgbColor->put_RGB((OLE_COLOR)RGB(255, 0, 0));
40 ASSERT(SUCCEEDED(hr));
41
42 IGraphicsContainerPtr ipGraphicsContainer;
43 ipActiveView->get_GraphicsContainer(&ipGraphicsContainer);
44
45 // 添加矩形
46 IEnvelopePtr ipEnvelope(CLSID_Envelope);
47 ipEnvelope->put_XMax(mapX + 0.0005);
48 ipEnvelope->put_XMin(mapX - 0.0005);
49 ipEnvelope->put_YMax(mapY + 0.0003);
50 ipEnvelope->put_YMin(mapY - 0.0003);
51 IRectangleElementPtr ipRectangleElement(CLSID_RectangleElement);
52 ISimpleFillSymbolPtr ipSimpleFillSymbol(CLSID_SimpleFillSymbol);
53 ISimpleLineSymbolPtr ipSimpleLineSymbol(CLSID_SimpleLineSymbol);
54 ipSimpleFillSymbol->put_Style(esriSFSHollow);
55 ipSimpleLineSymbol->put_Color(ipRgbColor);
56 ipSimpleLineSymbol->put_Style(esriSLSSolid);
57 ipSimpleLineSymbol->put_Width(1.8);
58 ipSimpleFillSymbol->put_Outline(ipSimpleLineSymbol);
59
60 IElementPtr ipElement = ipRectangleElement;
61 ipElement->put_Geometry(ipEnvelope);
62 if (m_ipFillShapeElement != NULL)
63 {
64 IElementPtr ipTempElement = m_ipFillShapeElement;
65 IGeometryPtr ipGeometry = NULL;
66 ipTempElement->get_Geometry(&ipGeometry);
67 esriGeometryType esriType = esriGeometryNull;
68 ipGeometry->get_GeometryType(&esriType);
69 ASSERT(esriType == esriGeometryPolygon);
70 IEnvelopePtr ipEnvelope2 = NULL;
71 IPolygonPtr ipPolygon = ipGeometry;
72 hr = ipPolygon->get_Envelope(&ipEnvelope2);
73 ASSERT(ipEnvelope2 != NULL);
74 double xMin = 0.0;
75 double xMax = 0.0;
76 double yMin = 0.0;
77 double yMax = 0.0;
78 ipEnvelope2->QueryCoords(&xMin, &yMin, &xMax, &yMax);
79 if (mapX >= xMin && mapX <= xMax && mapY >= yMin && mapY <= yMax)
80 {
81 m_bDrag = TRUE;
82 }
83 else
84 {
85 m_bDrag = FALSE;
86 }
87 }
88 }
89
90 void CEagleEyeCtrl::OnMouseMoveMapcontrol(long button, long shift, long X,
91 long Y, double mapX, double mapY)
92 {
93 // TODO: Add your control notification handler code here
94 if (m_bDrag)
95 {
96 if (m_ipFillShapeElement != NULL)
97 {
98 IActiveViewPtr ipActiveView = m_MapCtrl.GetActiveView();
99 if (ipActiveView == NULL || m_ipFillShapeElement == NULL)
100 {
101 return;
102 }
103 IGraphicsContainerPtr ipGraphicsContainer = NULL;
104 HRESULT hr = ipActiveView->get_GraphicsContainer(&ipGraphicsContainer);
105 IRgbColorPtr ipRgbColor(CLSID_RgbColor);
106
107 IElementPtr ipElement = m_ipFillShapeElement;
108 IGeometryPtr ipGeometry = NULL;
109 hr = ipElement->get_Geometry(&ipGeometry);
110 esriGeometryType esriType = esriGeometryNull;
111 ipGeometry->get_GeometryType(&esriType);
112 ASSERT(esriType == esriGeometryPolygon);
113 IEnvelopePtr ipEnvelope(CLSID_Envelope);
114 IPolygonPtr ipPolygon = ipGeometry;
115 hr = ipPolygon->get_Envelope(&ipEnvelope);
116
117 IPointPtr ipPoint(CLSID_Point);
118 ipPoint->PutCoords(mapX, mapY);
119 ipEnvelope->CenterAt(ipPoint);
120 m_ipLastEnvelope = ipEnvelope;
121 IEnvelopePtr ipEnvelope2 = m_MapCtrl.GetExtent();
122 ipActiveView->PartialRefresh(esriViewForeground, NULL, ipEnvelope2);
123 }
124 }
125 }
126
127 void CEagleEyeCtrl::OnMouseUpMapcontrol(long button, long shift, long X,
128 long Y, double mapX, double mapY)
129 {
130 // TODO: Add your control notification handler code here
131 m_bDrag = FALSE;
132
133 IActiveViewPtr ipActiveView = m_MapCtrl.GetActiveView();
134 if (ipActiveView == NULL || m_ipFillShapeElement == NULL)
135 {
136 return;
137 }
138 if (m_ipLastEnvelope != NULL)
139 {
140 m_ipLastEnvelope = NULL;
141 }
142 IGraphicsContainerPtr ipGraphicsContainer = NULL;
143 HRESULT hr = ipActiveView->get_GraphicsContainer(&ipGraphicsContainer);
144 IElementPtr ipElement = m_ipFillShapeElement;
145 IGeometryPtr ipGeometry = NULL;
146 ipElement->get_Geometry(&ipGeometry);
147 esriGeometryType esriType;
148 ipGeometry->get_GeometryType(&esriType);
149 ASSERT(esriType == esriGeometryPolygon);
150 IPolygonPtr ipPolygon = ipGeometry;
151 IEnvelopePtr ipEnvelope = NULL;
152 ipPolygon->get_Envelope(&ipEnvelope);
153 IPointPtr ipPoint(CLSID_Point);
154 ipPoint->PutCoords(mapX, mapY);
155 ipEnvelope->CenterAt(ipPoint);
156 ipElement->put_Geometry(ipEnvelope);
157 m_ipFillShapeElement = ipElement;
158 ipGraphicsContainer->UpdateElement((IElementPtr)m_ipFillShapeElement);
159 ipActiveView->Refresh();
160 // 给父控件发消息,切换视图
161 m_ipPoint = ipPoint;
162 GetParent()->GetParent()->SendMessage(WMU_GIS_EAGLE_NOTIFY, 0, 0);
163 }
164
165
166 void CEagleEyeCtrl::OnAfterDrawMapcontrol(const VARIANT FAR& Display,
167 long viewDrawPhase)
168{
169 // TODO: Add your control notification handler code here
170 if (m_ipLastEnvelope != NULL && m_bDrag)
171 {
172 if (m_ipFillShapeElement != NULL)
173 {
174 IActiveViewPtr ipActiveView = m_MapCtrl.GetActiveView();
175 if (ipActiveView == NULL || m_ipFillShapeElement == NULL)
176 {
177 return;
178 }
179
180 IElementPtr ipElement = m_ipFillShapeElement;
181 IGeometryPtr ipGeometry = NULL;
182 ipElement->get_Geometry(&ipGeometry);
183 esriGeometryType esriType = esriGeometryNull;
184 ipGeometry->get_GeometryType(&esriType);
185 ASSERT(esriType == esriGeometryPolygon);
186 IEnvelopePtr ipEnvelope(CLSID_Envelope);
187 IPolygonPtr ipPolygon = ipGeometry;
188 ipPolygon->get_Envelope(&ipEnvelope);
189
190 CPoint pt;
191 GetCursorPos(&pt);
192 m_MapCtrl.ScreenToClient(&pt);
193 IPointPtr ipPoint = m_MapCtrl.ToMapPoint(pt.x, pt.y);
194 ipEnvelope->CenterAt(ipPoint);
195
196 ISimpleFillSymbolPtr ipSimpleFillSymbol(CLSID_SimpleFillSymbol);
197 ISimpleLineSymbolPtr ipSimpleLineSymbol(CLSID_SimpleLineSymbol);
198 IRgbColorPtr ipRgbColor(CLSID_RgbColor);
199 HRESULT hr = ipRgbColor->put_RGB((OLE_COLOR)RGB(255, 0, 0));
200 ASSERT(SUCCEEDED(hr));
201 ipSimpleFillSymbol->put_Style(esriSFSHollow);
202 ipSimpleLineSymbol->put_Color(ipRgbColor);
203 ipSimpleLineSymbol->put_Style(esriSLSSolid);
204 ipSimpleLineSymbol->put_Width(1.8);
205 ipSimpleFillSymbol->put_Outline(ipSimpleLineSymbol);
206
207 IScreenDisplayPtr ipScreenDisplay = NULL;
208 OLE_HANDLE hDC = NULL;
209 hr = ipActiveView->get_ScreenDisplay(&ipScreenDisplay);
210 ASSERT(SUCCEEDED(hr));
211 hr = ipScreenDisplay->get_hDC(&hDC);
212 ASSERT(SUCCEEDED(hr));
213
214 hr = ipScreenDisplay->StartDrawing(hDC, -1);
215 ASSERT(SUCCEEDED(hr));
216 hr = ipScreenDisplay->SetSymbol((ISymbolPtr)ipSimpleFillSymbol);
217 ASSERT(SUCCEEDED(hr));
218 hr = ipScreenDisplay->DrawRectangle(ipEnvelope);
219 ASSERT(SUCCEEDED(hr));
220 hr = ipScreenDisplay->FinishDrawing();
221 }
222 }
223}
更多精彩
赞助商链接