MapX (MapInfo ActiveX) 提供 `CreateCustomTool` 建立自定義工具,配合 `PolyToolUsed` 事件可實現多邊形繪製、測距、測面積等 GIS 交互功能。本文以「測距工具」為例,展示從工具創建、事件響應到距離計算的完整流程。
#define MYTOOL_DISTANCE 100 // 範圍 1~999,避免與內建工具衝突
// miToolTypePoly = 多邊形工具類型,miCrossCursor = 十字光標
m_ctrlMap.CreateCustomTool(MYTOOL_DISTANCE, miToolTypePoly, miCrossCursor);
void CMapXSampleView::OnPolyToolUsedMap(
short ToolNum, long Flags, LPDISPATCH Points,
BOOL bShift, BOOL bCtrl, BOOL FAR* EnableDefault)
{
// 僅處理繪製過程中的本工具事件
if (Flags == miPolyToolInProgress && ToolNum == MYTOOL_DISTANCE) {
CMapXPoints pts;
try {
pts.AttachDispatch(Points, FALSE); // 取得點集合
long n = pts.GetCount();
double dTotalDist = 0.0;
// 累加相鄰兩點球面距離
for (long i = 1; i < n; ++i) {
CMapXPoint pt1 = pts.Item(i);
CMapXPoint pt2 = pts.Item(i + 1);
double d = m_ctrlMapX.Distance(
pt1.GetX(), pt1.GetY(),
pt2.GetX(), pt2.GetY());
dTotalDist += d;
}
// 狀態列顯示 (單位取決於地圖坐標系,通常為米/度)
CString str;
str.Format(_T("總距離:%.2f"), dTotalDist);
((CMainFrame*)AfxGetMainWnd())->m_wndStatusBar.SetPaneText(0, str);
}
catch (COleDispatchException* e) { e->ReportError(); e->Delete(); }
catch (COleException* e) { e->ReportError(); e->Delete(); }
}
}
void CMapXSampleView::OnMapToolDistancetool() {
m_ctrlMapX.SetCurrentTool(MYTOOL_DISTANCE);
}
| 參數 | 含義 |
|---|---|
| ToolNum | 觸發事件的工具 ID,對應 `CreateCustomTool` 第一參數 |
| Flags | `miPolyToolInProgress` (繪製中)、`miPolyToolDone` (完成)、`miPolyToolCancel` (取消) |
| Points | `MapXPoints` 集合,1-based 索引,含用戶點擊的所有頂點 |
| EnableDefault | 設為 TRUE 允許 MapX 繼續預設繪製行為 (如顯示橡皮筋線) |
MapX 自定義工具 + `PolyToolUsed` 事件是實現 GIS 交互量測功能的標準路徑。掌握「創建工具 → 事件解析點集 → 幾何計算 → UI 回饋」四步流程,可快速構建測距、測面積、繪圖編輯等專業功能。