程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> ArcEngine鷹眼的實現

ArcEngine鷹眼的實現

編輯:關於VC++

大家都用過百度地圖或者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}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved