ArcObjects는 ArcGIS의 기반되는 수많은 COM Object입니다. 처음에는 ArcGIS 툴을 설치함으로써 ArcObjects를 사용할 수 있다는 부담이 이었으나 현재는 ArcGIS가 아닌 ArcEngine이라는 개발자 SDK 형태로 ArcObjects만을 설치할 수 있도록 편의를 제공합니다. (이부분은 필자의 추측이므로 틀렸을때는 과감한 하이킥 부탁드립니다) 이번 글에서는 ArcObjects를 이용해 화면상에 표시한 지도를 마우스를 이용하여 확대 또는 축소하거나 이동 시키는 방법에 대해 설명합니다.
이 글은 일단 ArcObjects의 지도 컨트롤에 레이어가 하나 추가되었다고 가정하고 설명합니다. 또한 아래 화면처럼 Zoom In, Zoom Out, Pan, Zoom Full 이라는 텍스트를 가진 버튼이 존재합니다.
각 버튼에 대한 기능을 하나 하나 살펴 보도록 하겠습니다. 먼저 Zoom In 버튼을 클릭했을 때의 코드는 아래와 같습니다.
private void button2_Click(object sender, EventArgs e)
{
// 0: None
// 1: Zoom In Mode
// 2: Zoom Out Mode
// 3: Pan
MapViewMode = 1;
}
MapViewMode는 아래와 같이 정의된 parivate 접근자 클래스 맴버 변수입니다.
// 0: None
// 1: Zoom In Mode
// 2: Zoom Out Mode
// 3: Pan
private int MapViewMode = 0;
private bool bMouseDown = false;
private ESRI.ArcGIS.Geometry.IPoint DownPt = new ESRI.ArcGIS.Geometry.Point();
지도의 확대, 축소, 이동 기능은 마우스 이벤트와 밀접하게 연관되어 있기 때문에 마우스 이벤트 안에서 현재 사용자가 어떤 지도 조작 기능을 원하는지를 저정해 놓을 필요가 있습니다. 바로 MoveViewMode가 현재 지도 조작 모드 값을 담고 있으며 1은 확대 모드, 2는 축소 모드, 3은 이동 모드를 의미합니다. 이외에도 현재 마우스 버튼이 눌려진 상태인지를 나타내는 bMouseDown과 마우스가 눌려진 커서의 위치를 지도 좌표로 저장할 DownPt 변수가 있습니다.
Zoom In 버튼을 눌러 MapViewMode를 1로 설정함으로써 마우스 이벤트에 대해 지도 확대 모드 상태임을 파악할 수 있게 되었습니다. 이제 마우스 이벤트에 대해 살펴보도록 하겠습니다.
private void axMapControl1_OnMouseDown(object sender,
AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
if (MapViewMode == 1)
{
ESRI.ArcGIS.Geometry.IEnvelope pEnv = axMapControl1.TrackRectangle();
axMapControl1.ActiveView.Extent = pEnv;
axMapControl1.ActiveView.Refresh();
}
마우스 다운 이벤트입니다. 지도 확대 모드인MapViewMode가 1에 대해 6, 7, 8번 라인의 코드가 실행됩니다. 여기까지가 지도를 마우스를 통해 사각형 영역을 지정하여 지정된 사각형 영역에 대한 지도 확대 기능입니다.
다음으로 Zoom Out 버튼인 지도 축소 기능에 대해 살펴보겠습니다. 먼저 버튼의 클릭 이벤트의 코드는 아래와 같습니다.
private void button3_Click(object sender, EventArgs e)
{
// 0: None
// 1: Zoom In Mode
// 2: Zoom Out Mode
// 3: Pan
MapViewMode = 2;
}
축소 기능도 확대 기능과 마찬가지로 마우스 다운 이벤트에서 지도 축소 기능을 수행합니다. 아래의 코드는 마우스 다운 이벤트에서 지도 축소 기능에 대한 코드 부분입니다.
private void axMapControl1_OnMouseDown(object sender,
AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
if (MapViewMode == 1)
{
...
}
else if(MapViewMode == 2)
{
ESRI.ArcGIS.Geometry.IEnvelope pEnv = axMapControl1.TrackRectangle();
double OldWidth = axMapControl1.ActiveView.Extent.XMax -
axMapControl1.ActiveView.Extent.XMin;
double TrackWidth = pEnv.XMax - pEnv.XMin;
double RatioWidth = OldWidth / TrackWidth;
double OldHeight = axMapControl1.ActiveView.Extent.YMax -
axMapControl1.ActiveView.Extent.YMin;
double TrackHeight = pEnv.YMax - pEnv.YMin;
double RatioHeight = OldHeight / TrackHeight;
ESRI.ArcGIS.Geometry.IEnvelope pNewEnv = new
ESRI.ArcGIS.Geometry.EnvelopeClass();
pNewEnv.XMin = axMapControl1.ActiveView.Extent.XMin
- (RatioWidth - 1.0) * OldWidth;
pNewEnv.XMax = axMapControl1.ActiveView.Extent.XMax
+ (RatioWidth - 1.0) * OldWidth;
pNewEnv.YMin = axMapControl1.ActiveView.Extent.YMin
- (RatioHeight - 1.0) * OldHeight;
pNewEnv.YMax = axMapControl1.ActiveView.Extent.YMax
+ (RatioHeight - 1.0) * OldHeight;
axMapControl1.ActiveView.Extent = pNewEnv;
axMapControl1.ActiveView.Refresh();
}
MapViewMode가 2인지를 비교하는 if 문이 새로운 코드입니다. 원리는 먼저 현재의 지도 화면 영역의 크기와 사용자가 마우스를 이용해 지정한 사각 영역의 크기의 비율을 이용하여 현재 지도 화면 영역에 이 크기의 비율을 반영해줍니다.
다음으로 지도 이동에 대한 기능에 대해 살펴 보겠습니다. 먼저 Pan 버튼의 클릭 이벤트의 코드는 아래와 같습니다.
private void button4_Click(object sender, EventArgs e)
{
// 0: None
// 1: Zoom In Mode
// 2: Zoom Out Mode
// 3: Pan
MapViewMode = 3;
}
지도 화면의 이동 기능은 확대와 축소 기능처럼 단순히 마우스 다운 이벤트만 사용하는 것이 아닌 마우스 다운 이벤트와 마우스 이동 이벤트 그리고 마우스 업 이벤트를 모두 사용합니다. 먼저 마우스 다운 이벤트를 살펴보겠습니다.
private void axMapControl1_OnMouseDown(object sender,
AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseDownEvent e)
{
bMouseDown = true;
DownPt.X = e.mapX;
DownPt.Y = e.mapY;
if (MapViewMode == 1)
{
...
}
else if(MapViewMode == 2)
{
...
}
else if(MapViewMode == 3)
{
ESRI.ArcGIS.Geometry.IPoint pPt = new ESRI.ArcGIS.Geometry.Point();
pPt.X = e.mapX;
pPt.Y = e.mapY;
axMapControl1.ActiveView.ScreenDisplay.PanStart(pPt);
}
}
먼저 앞서 정의한 클래스 맴버 변수 bMouseDown를 true로 설정하여 마우스 이동 이벤트에서 현재 마우스 버튼이 눌려진 상태임을 알 수 있게 하며 DownPt에 현재 마우스 버튼이 눌려진 위치를 지도 좌표로 저장합니다. 그리고 이동 기능에 대한 코드를 실행합니다. 다음으로 마우스 이동 이벤트는 아래와 같습니다.
private void axMapControl1_OnMouseMove(object sender,
AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseMoveEvent e)
{
if(MapViewMode==3 && bMouseDown)
{
ESRI.ArcGIS.Geometry.IPoint pPt = new ESRI.ArcGIS.Geometry.Point();
pPt.X = e.mapX;
pPt.Y = e.mapY;
axMapControl1.ActiveView.ScreenDisplay.PanMoveTo(pPt);
}
}
마우스 이동 이벤트는 마우스가 이동될때마다 항상 발생하는 이벤트이므로 지도 이동 상태를 잡아 내는 것이 중요합니다. 이 상태를 잡것이 바로 MapViewMode가 3인지와 현재 마우스 버튼이 눌려진 상태인지를 검사하는 것입니다. 이 조건에서만 해당되는 지도 이동 기능을 수행합니다. 다음으로 마우스 업 이벤트는 아래와 같습니다.
private void axMapControl1_OnMouseUp(object sender,
AxESRI.ArcGIS.Controls.IMapControlEvents2_OnMouseUpEvent e)
{
if (MapViewMode == 3 && bMouseDown)
{
ESRI.ArcGIS.Geometry.IEnvelope pEnv =
axMapControl1.ActiveView.ScreenDisplay.PanStop();
if(pEnv != null)
{
axMapControl1.ActiveView.Extent = pEnv;
axMapControl1.ActiveView.Refresh();
}
}
bMouseDown = false;
}
Up 이벤트에서도 지도 이동 모드 인지를 검사하고 조건에 맞을때만 지도 이동 기능을 최종적으로 완료합니다. 이 상으로 지도 화면 조작에 대한 내용을 간단하게 정리해 보았습니다. 이 글에서 설명한 코드는 아래의 링크를 통해 다운로드 하시기 바랍니다.