首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

GDI 繪製地圖比例尺:MM_LOMETRIC 映射模式、精度控制、七種樣式完整實作

     編輯:關於VC++

效果展示

比例尺樣式

核心問題:螢幕像素 ↔ 真實距離 精度校準

比例尺意義:**螢幕顯示長度 (ds) / 實際地面距離 (DS) = 1 / m_fScale**。必須確保數字標示與視覺長度嚴格對應。

座標映射模式選擇:MM_LOMETRIC

模式原點X+Y+單位適合性
MM_TEXT左上右下像素不適合 (Y 軸反向、單位非物理)
MM_LOMETRIC左上右**上****0.1 mm****最佳** (類地圖座標系、單位換算簡單)
MM_HIMETRIC左上右上0.01 mm精度過高,數值過大

CFGScaleDraw 類別設計

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);
};

DrawScale 核心邏輯:計算實際地面距離 DS

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 中呼叫

精度控制進階技巧

  1. 單位換算表:預設支援 m、km、nm、mi,依 DS 大小自動選擇最適單位
  2. 數字捨入:DS 四捨五入至合理有效位數 (如 1.23km → 1.2km)
  3. 刻度間距:依字體大小動態計算最小刻度間距,避免文字重疊
  4. 高 DPI 螢幕:`DPtoLP` 自動處理裝置解析度,邏輯座標不變,**零修碼支援 Retina/4K**

參考資源

劉先生《VC6.0 映射模式轉換及如何消除座標誤差》—— **文末方案不可直接採用,需改進**。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved