Qt/C++地址轉座標/座標轉地址/逆地址解析/支援百度高德騰訊和天地圖

飞扬青云發表於2024-08-31

一、前言說明

地址和經緯度座標轉換的功能必須線上使用,一般用在導航需求上,比如使用者輸入起點地址和終點地址,查詢路線後,顯示對應的路線,而實際上各大地圖廠家預設支援的是給定經緯度座標來查詢(百度地圖支援傳入地址),但是你讓使用者輸入經緯度座標是不可能的,他肯定不可能知道怎麼去拿到這個座標,所以一般都是要求使用者輸入實際的地址,然後程式轉換成經緯度座標,再呼叫函式傳入兩個座標取查詢路徑。

所有的地圖都會提供這個功能,而且發現一個趨勢,由於這種功能呼叫可能非常頻繁,所以各大地圖廠商目前都有做成服務的形式,也就是傳送http請求拿結果,尤其是騰訊地圖比較激進,直接地圖的js中的對應逆地址解析介面都停用了,必須用http請求方式。其實就算是地圖本身的js中內建的物件處理,估計後臺也是自己去傳送請求拿到的結果。於是需要單獨寫個js函式用於傳送請求返回結果,在js中傳送請求不要太簡單,直接new一個XMLHttpRequest呼叫send方法即可,返回的結果直接在onreadystatechange事件透過responseText屬性獲取。

二、功能特點

  1. 支援多種地圖核心,預設採用百度地圖,可選高德地圖、天地圖、騰訊地圖、谷歌地圖等。
  2. 同時支援線上地圖和離線地圖兩種模式,離線地圖方便在不聯網的場景中使用。
  3. 支援各種地圖控制元件的啟用,比如地圖導航、地圖型別、縮圖、比例尺、全景導航、實時路況、繪圖工具、結果皮膚等。
  4. 支援多種地圖功能的動態啟用禁用,比如地圖拖曳、鍵盤操作、滾輪縮放、雙擊放大、連續縮放、地圖測距等。
  5. 提供眾多js函式介面用於互動,引數極其豐富,能夠想到的應用場景需求都有。
  6. 統一的訊號槽機制,地圖中的結果統一訊號傳送出去,收到後根據type型別區分。
  7. 支援地圖互動,比如滑鼠按下獲取對應位置的經緯度。單擊標註點彈出對應點的資訊。
  8. 支援新增標註、刪除標註、移動標註、清空標註。
  9. 標註點可以指定圖示圖片和尺寸,支援gif動圖,支援指定以圖片中心對齊還是底部中心對齊。可以設定旋轉角度,帶富文字提示資訊。
  10. 標註點事件支援單擊發訊號通知和自己彈框顯示資訊。
  11. 提供地址轉座標和座標轉地址介面。
  12. 支援各種圖形繪製,包括折線圖、多邊形、矩形、圓形、弧線等。
  13. 可顯示懸浮的繪圖工具欄,直接在地圖上劃線、標註點、矩形、圓形等。
  14. 支援各種區域搜尋,比如矩形區域、圓形區域,可以按照關鍵字匹配將搜尋結果顯示在地圖中。
  15. 可動態新增離線的行政區邊界點資料。可以搜尋行政區劃並獲取該區域的邊界點資料。資料可以儲存到檔案以便離線使用。
  16. 支援點聚合功能,多個小標註點合併到一個大標註點,防止點密集導致互動不友好。
  17. 可以新增海量點,每個點都可以單擊獲取對應座標和資訊。
  18. 所有的覆蓋物資訊比如標註點、矩形、多邊形、折線圖等,都可以主動獲取對應的資訊比如座標點和路徑等。
  19. 支援路徑規劃,支援公交路線、自駕路線、步行路線、騎行路線,不同查詢支援不同策略,可選最少時間、最少換乘、不走高架等。
  20. 路徑規劃結果可以顯示在地圖中,也可以獲取到路徑點座標集合。這個資料可以儲存到檔案,以便發給機器人或者無人機做導航用來軌跡移動。
  21. 可以設定不同的地圖檢視比如街道圖、衛星圖、混合圖。
  22. 可以設定不同的樣式,比如午夜藍、青草綠等樣式風格。
  23. 可以設定地圖的旋轉角度和傾斜角度。
  24. 提供經緯度座標糾偏轉換功能,比如傳入的GPS座標需要轉換到百度地圖座標或者高德地圖座標。各種座標系轉換全部離線函式,支援地球座標系WGS-84、火星座標系GCJ-02、百度座標系BD-09之間的互相轉換,涵蓋了各種地圖的座標系。
  25. 提供動態軌跡點移動功能,按照給定的經緯度座標集合平滑移動。
  26. 同時支援qwidget和qml,支援編譯到安卓系統執行。

三、使用說明

  1. 在地址文字框中輸入地址,單擊地址轉座標,會查詢到當前地址最近的經緯度座標填入座標文字框中。
  2. 在座標文字框中輸入座標,單擊座標轉地址,會查詢座標文字框中經緯度座標最近的地址填入地址文字框中。

四、相關連結

  1. 體驗地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取碼:o05q 名稱:bin_map.zip
  2. 國內站點:https://gitee.com/feiyangqingyun
  3. 國際站點:https://github.com/feiyangqingyun

五、效果圖

六、相關程式碼

void MapObjBaiDu::addGeocoder()
{
    //初始化解析物件
    html << QString("  var geocoder;");
    html << QString("  function initGeocoder() {");
    html << QString("    if (geocoder) {return}");
    html << QString("    geocoder = new BMap.Geocoder();");
    html << QString("  }");

    //地址解析成座標
    html << QString("  function getPointByAddr(flag, addr) {");
    html << QString("    initGeocoder();");
    html << QString("    geocoder.getPoint(addr, function(result) {");
    html << QString("      if (result) {");
    html << QString("        var point = getPointString(result);");
    html << QString("        receiveData('geocoderresult', flag + '|' + point);");
    html << QString("      }");
    html << QString("    });");
    html << QString("  }");

    //座標解析成地址
    html << QString("  function getAddrByPoint(flag, point) {");
    html << QString("    initGeocoder();");
    html << QString("    geocoder.getLocation(getPoint(point), function(result) {");
    html << QString("      if (result) {");
    html << QString("        var address = result.address;");
    html << QString("        receiveData('geocoderresult', flag + '|' + address);");
    html << QString("      }");
    html << QString("    });");
    html << QString("  }");
}

void MapObjTian::addGeocoder()
{
    //初始化解析物件
    html << QString("  var geocoder;");
    html << QString("  function initGeocoder() {");
    html << QString("    if (geocoder) {return}");
    html << QString("    geocoder = new T.Geocoder();");
    html << QString("  }");

    //地址解析成座標
    html << QString("  function getPointByAddr(flag, addr) {");
    html << QString("    initGeocoder();");
    html << QString("    geocoder.getPoint(addr, function(result) {");
    html << QString("      if (result.getStatus() == 0) {");
    html << QString("        var point = result.getLocationPoint();");
    html << QString("        point = getPointString(point);");
    html << QString("        receiveData('geocoderresult', flag + '|' + point);");
    html << QString("      }");
    html << QString("    });");
    html << QString("  }");

    //座標解析成地址
    html << QString("  function getAddrByPoint(flag, point) {");
    html << QString("    initGeocoder();");
    html << QString("    geocoder.getLocation(getPoint(point), function(result) {");
    html << QString("      if (result.getStatus() == 0) {");
    html << QString("        var address = result.getAddress();");
    html << QString("        receiveData('geocoderresult', flag + '|' + address);");
    html << QString("      }");
    html << QString("    });");
    html << QString("  }");
}

void frmMapDemoMarker::on_btnAddrToPoint_clicked()
{
    QString addr = ui->txtAddr->text().trimmed();
    emit runJs(QString("getPointByAddr('AddrToPoint', '%1')").arg(addr));
}

void frmMapDemoMarker::on_btnPointToAddr_clicked()
{
    QString point = ui->txtPoint->text().trimmed();
    emit runJs(QString("getAddrByPoint('PointToAddr', '%1')").arg(point));
}

相關文章