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

MapX VC 設定非地球坐標系 (Non-Earth) 完整代碼方案

     編輯:VC 教學

適用場景

室內地圖、機廠佈局、PCB 版圖、遊戲地圖等無經緯度概念的平面坐標場景,需使用 MapX 的 Non-Earth (米/英尺/自定義單位) 坐標系。關鍵在於 `CoordSys.Set` 必須顯式指定 `MapBounds` (MBR 範圍),否則地圖無法正確顯示與縮放。

環境與前置條件

  • VC6 + MapX 4.5 + Windows 2000 SP3
  • 已準備 `.gst` 地圖配置檔 (含非地球坐標系定義)
  • 知曉資料範圍 MBR:左下 (MinX, MinY)、右上 (MaxX, MaxY)

核心實現代碼 (OnCreate 中)

int CMyGisView::OnCreate(LPCREATESTRUCT lpCreateStruct) {
    if (CView::OnCreate(lpCreateStruct) == -1) return -1;

    // 1. 建立 Map 控制項並載入地圖配置
    m_ctrlMapX.Create(NULL, WS_VISIBLE, CRect(0,0,100,100), this, IDC_MAP);
    m_ctrlMapX.SetGeoSet(_T("Mygst.gst"));

    // 2. 定義非地球坐標系參數
    CMapXRectangle rect;
    CMapXCoordSys coordSys;
    COleVariant vEmpty;  // 選填參數佔位

    if (!rect.CreateDispatch(rect.GetClsid()) ||
        !coordSys.CreateDispatch(coordSys.GetClsid())) {
        TRACE0("COM 物件創建失敗");
        return -1;
    }

    try {
        // 單位:米 (miUnitMeter=5, 亦可用 miUnitFoot=6 等)
        VARIANT vUnit; vUnit.vt = VT_I4; vUnit.lVal = miUnitMeter;

        // 關鍵:設定 MBR 範圍 (從 gst 或資料實際範圍獲取)
        // 範例值:對應 gst 中 GEOSETMBRLOWERLEFT / GEOSETMBRUPPERRIGHT
        rect.Set(-2165.54, 9841.999, 46782.42, 41026.85);

        VARIANT vBounds; vBounds.vt = VT_DISPATCH;
        vBounds.pdispVal = rect.m_lpDispatch;
        vBounds.pdispVal->AddRef();  // 重要:避免過早釋放

        // CoordSys.Set 參數順序 (參考 MapX 文檔):
        // Type, Projection, Units, OriginLat, OriginLong, StdParallel1, StdParallel2,
        // FalseEasting, FalseNorthing, ScaleFactor, Azimuth, LongitudeWrap, Bounds, Affine
        coordSys.Set(0, vEmpty, vUnit, vEmpty, vEmpty, vEmpty,
                     vEmpty, vEmpty, vEmpty, vEmpty, vEmpty, vEmpty,
                     vBounds, vEmpty);

        // 3. 應用至 Map 控制項
        m_ctrlMapX.SetNumericCoordSys(coordSys.m_lpDispatch);
        m_ctrlMapX.SetDisplayCoordSys(m_ctrlMapX.GetNumericCoordSys().m_lpDispatch);
    }
    catch (COleDispatchException* e) { e->ReportError(); e->Delete(); }
    catch (COleException* e) { e->ReportError(); e->Delete(); }

    return 0;
}

CoordSys.Set 關鍵參數對照表

索引參數非地球坐標系典型值
0Type0 = Non-Earth
1ProjectionvEmpty (非地球無投影)
2UnitsmiUnitMeter (5) / miUnitFoot (6) / miUnitCustom (100)
3~11投影參數vEmpty
12Bounds (MBR)**必填** CMapXRectangle 物件
13AffinevEmpty (除非需仿射變換)

常見錯誤與解決

  • 地圖空白/縮放異常 → `Bounds` 未設定或數值錯誤。務必與資料實際範圍一致,建議從資料層 `GetMBR` 獲取。
  • 單位不符 → `Units` 與資料實際單位不一致 (如資料為英尺卻設米),導致比例尺錯誤。
  • COM 例外 → `CreateDispatch` 失敗通常因 MapX 未正確註冊或版本不匹配,檢查 `regsvr32 MapX.ocx`。
  • 記憶體洩漏 → `vBounds.pdispVal->AddRef()` 後需在適當時機 `Release`,或使用智能指標 `_variant_t` 自動管理。

現代化寫法建議 (C++11+)

// 使用 _variant_t 簡化 VARIANT 管理
_variant_t vUnit((long)miUnitMeter);
_variant_t vBounds(rect.m_lpDispatch);  // 自動 AddRef/Release
coordSys.Set(0, vtMissing, vUnit, vtMissing, vtMissing, vtMissing,
             vtMissing, vtMissing, vtMissing, vtMissing, vtMissing, vtMissing,
             vBounds, vtMissing);

結語

MapX 非地球坐標系配置的核心在於 正確設定 `CoordSys.Set` 的 `Units` 與 `Bounds` 兩個參數。本文提供經實測可用的 VC6 完整代碼,涵蓋 COM 物件創建、參數填充、異常處理與資源管理,可直接應用於室內 GIS、工業佈局等平面坐標專案。

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