
比例尺意義:**螢幕顯示長度 (ds) / 實際地面距離 (DS) = 1 / m_fScale**。必須確保數字標示與視覺長度嚴格對應。
| 模式 | 原點 | X+ | Y+ | 單位 | 適合性 |
|---|---|---|---|---|---|
| MM_TEXT | 左上 | 右 | 下 | 像素 | 不適合 (Y 軸反向、單位非物理) |
| MM_LOMETRIC | 左上 | 右 | **上** | **0.1 mm** | **最佳** (類地圖座標系、單位換算簡單) |
| MM_HIMETRIC | 左上 | 右 | 上 | 0.01 mm | 精度過高,數值過大 |
enum FGScaleType {
ST_SINGLELINE, ST_SINGLELINE2, ST_SINGLELINE3,
ST_FILLRECT, ST_FILLRECT2,
ST_STEPPEDLINE, ST_LINERECT
};
class CFGScaleDraw {
FGScaleType m_ScaleType;
float m_fScale; // 比例尺分母 (1:10000 → 10000)
int m_nMinX, m_nMaxX, m_nMinY, m_nMaxY; // 繪製區域 (裝置座標)
public:
void SetScaleType(int type);
void SetScale(float scale);
void SetRect(CRect rect);
void SetRect(int minx, int miny, int maxx, int maxy);
void DrawScale(CDC* pdc);
};
void CFGScaleDraw::DrawScale(CDC* pdc) {
// 1. 切換映射模式
int nOldMode = pdc->SetMapMode(MM_LOMETRIC);
// 2. 裝置座標 → 邏輯座標 (0.1mm)
CPoint p[2];
p[0].x = m_nMinX; p[0].y = m_nMinY;
p[1].x = m_nMaxX; p[1].y = m_nMaxY;
pdc->DPtoLP(p, 2);
// 3. 螢幕顯示長度 (0.1mm)
int ds = p[1].x - p[0].x;
// 4. 實際地面距離 (假設地圖單位為米)
// ds (0.1mm) * m_fScale = 地面距離 (0.1mm)
// 換算為米:/ 10000 (1m = 10000 * 0.1mm)
double DS = ds * m_fScale * 0.00001;
// 5. DS 即為比例尺應顯示的數值 (如 "5 km")
// 以下依 m_ScaleType 繪製不同樣式...
// (單線、雙線、填滿矩形、階梯線、線框矩形等)
pdc->SetMapMode(nOldMode); // 還原
}
| 類型 | 視覺特徵 | 適用場景 |
|---|---|---|
| ST_SINGLELINE | 單線 + 上方數字 | 一般地圖 |
| ST_SINGLELINE2 | 單線 + 上下雙向數字 | 雙單位制 (km/mi) |
| ST_SINGLELINE3 | 單線 + 刻度格 | 精密測圖 |
| ST_FILLRECT | 實心矩形分段著色 | 專題圖、人口密度 |
| ST_FILLRECT2 | 交替填色 (黑白/紅白) | 傳統紙質地圖風格 |
| ST_STEPPEDLINE | 階梯狀線條 | 高程剖面、等值線 |
| ST_LINERECT | 線框矩形 + 刻度 | 導航圖、軍用地圖 |
CFGScaleDraw m_ScaleDraw;
m_ScaleDraw.SetScale(10000); // 1:10000
m_ScaleDraw.SetRect(100, 100, 400, 120); // 裝置座標區域
m_ScaleDraw.SetScaleType(ST_SINGLELINE);
m_ScaleDraw.DrawScale(pDC); // 在 OnDraw/OnPaint 中呼叫
DS 大小自動選擇最適單位DS 四捨五入至合理有效位數 (如 1.23km → 1.2km)劉先生《VC6.0 映射模式轉換及如何消除座標誤差》—— **文末方案不可直接採用,需改進**。