【原】ArcEngine鹰眼的实现
大家都用过百度地图或者googole地图吧,在它们主地图的右下角,有个小地图窗口,这就是鹰眼窗口。用鼠标拖动鹰眼里的小窗口,则主地图便移动到相应的位置。下面就介绍鹰眼的实现...
大家都用过百度地图或者googole地图吧,在它们主地图的右下角,有个小地图窗口,这就是鹰眼窗口。用鼠标拖动鹰眼里的小窗口,则主地图便移动到相应的位置。下面就介绍鹰眼的实现。
鹰眼和主地图的互动,主要体现在两个方面:一是主地图的地图改变了,则鹰眼里的矩形框要移动到对应的位置,以指示当前地图在整个地图中的位置;二是鹰眼的矩形框移动了,则主地图中显示的地图要移动到相应的位置。
ArcEngine中显示地图的控件叫 ESRI MapControl,这里主要用到了它的OnAfterDraw事件。在主地图的OnAfterDrawMapControl事件中,根据当前地图的大小,改变鹰眼中矩形框的大小;在鹰眼的OnAfterDraw事件中,根据矩形框的位置,确定主地图中地图的位置。google地图的鹰眼还实现了矩形框的拖动,这个也很好实现,呵呵。在鼠标点击到鹰眼控件时,先判断是否在矩形框内,如果在的话,用一个状态量记住这个状态,此时如果鼠标移动,则矩形框跟着相应的移动;若不在矩形框内,则矩形框移动到鼠标点击的位置。下面的代码是基于VC6和ArcEngine9.2实现的。鹰眼矩形框的拖动涉及到的事件比较多,包括OnMouseDownMapControl、OnMouseMoveMapControl、OnMouseUpMapControl事件。
1

2
class CEagleEyeCtrl : public CStatic3


{4
// Construction5
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 here28
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
else84

{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 here94
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 here131
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 here170
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
}

浙公网安备 33010602011771号