一、前言說明
在展示地圖的時候,有些常規的操作,比如調整地圖的縮放級別,切換到衛星圖等,希望能夠在地圖上直接操作實現,於是就有了一堆地圖控制元件,可以根據自己的需求動態的新增和刪除,這樣就更直接更快捷,而不是透過函式去設定。幾乎每個地圖廠家都提供了類似的控制元件,儘管命名可能有些差別,常見的地圖控制元件有地圖型別、縮放標尺、縮圖(也叫鷹眼檢視)、比例尺、實時路況等。
記得當初第一版的地圖元件設計的時候,每個地圖控制元件對應一個enable變數,在生成地圖網頁程式碼之前,設定好enable的值,然後根據這個值去決定要不要加入控制元件到地圖中。現在的版本是定義一堆列舉值,每一種控制元件對應一個列舉值,地圖基類中定一個變數mapControl用來控制需要哪些地圖控制元件,列舉值的值依次是1/2/4/8這種,方便於判斷進行設定。縱觀各種第三方輪子,好多都是這種方式。
二、功能特點
2.1 地圖功能
- 支援多種地圖核心,預設採用百度地圖,可選高德地圖、天地圖、騰訊地圖、谷歌地圖等。
- 同時支援線上地圖和離線地圖兩種模式,離線地圖方便在不聯網的場景中使用。
- 支援各種地圖控制元件的啟用,比如地圖導航、地圖型別、縮圖、比例尺、全景導航、實時路況、繪圖工具、結果皮膚等。
- 支援多種地圖功能的動態啟用禁用,比如地圖拖曳、鍵盤操作、滾輪縮放、雙擊放大、連續縮放、地圖測距等。
- 提供眾多js函式介面用於互動,引數極其豐富,能夠想到的應用場景需求都有。
- 統一的訊號槽機制,地圖中的結果統一訊號傳送出去,收到後根據type型別區分。
- 支援地圖互動,比如滑鼠按下獲取對應位置的經緯度。單擊標註點彈出對應點的資訊。
- 支援新增標註、刪除標註、移動標註、清空標註。
- 標註點可以指定圖示圖片和尺寸,支援gif動圖,支援指定以圖片中心對齊還是底部中心對齊。可以設定旋轉角度,帶富文字提示資訊。
- 標註點事件支援單擊發訊號通知和自己彈框顯示資訊。
- 提供地址轉座標和座標轉地址介面。
- 支援各種圖形繪製,包括折線圖、多邊形、矩形、圓形、弧線等。
- 可顯示懸浮的繪圖工具欄,直接在地圖上劃線、標註點、矩形、圓形等。
- 支援各種區域搜尋,比如矩形區域、圓形區域,可以按照關鍵字匹配將搜尋結果顯示在地圖中。
- 可動態新增離線的行政區邊界點資料。可以搜尋行政區劃並獲取該區域的邊界點資料。資料可以儲存到檔案以便離線使用。
- 支援點聚合功能,多個小標註點合併到一個大標註點,防止點密集導致互動不友好。
- 可以新增海量點,每個點都可以單擊獲取對應座標和資訊。
- 所有的覆蓋物資訊比如標註點、矩形、多邊形、折線圖等,都可以主動獲取對應的資訊比如座標點和路徑等。
- 支援路徑規劃,支援公交路線、自駕路線、步行路線、騎行路線,不同查詢支援不同策略,可選最少時間、最少換乘、不走高架等。
- 路徑規劃結果可以顯示在地圖中,也可以獲取到路徑點座標集合。這個資料可以儲存到檔案,以便發給機器人或者無人機做導航用來軌跡移動。
- 可以設定不同的地圖檢視比如街道圖、衛星圖、混合圖。
- 可以設定不同的樣式,比如午夜藍、青草綠等樣式風格。
- 可以設定地圖的旋轉角度和傾斜角度。
- 提供經緯度座標糾偏轉換功能,比如傳入的GPS座標需要轉換到百度地圖座標或者高德地圖座標。各種座標系轉換全部離線函式,支援地球座標系WGS-84、火星座標系GCJ-02、百度座標系BD-09之間的互相轉換,涵蓋了各種地圖的座標系。
- 提供動態軌跡點移動功能,按照給定的經緯度座標集合平滑移動。
- 同時支援qwidget和qml,支援編譯到安卓系統執行。
2.2 其他功能
- 提供離線地圖下載模組,可以選擇不同的地圖核心比如百度地圖或者谷歌地圖,不同的地圖型別比如下載街道圖還是衛星圖,不同的地圖層級,多執行緒極速下載。
- 表格行實時顯示對應的瓦片下載進度,有下載超時時間,重試次數,每個瓦片下載完成都傳送訊號通知,引數包括下載用時。
- 提供省市輪廓圖下載模組,自動下載各個地區的輪廓圖,儲存到指令碼檔案或者文字檔案。
- 支援手動調整不同區域的輪廓邊界,調整後可以主動獲取調整後的邊界點集合。
- 提供動態點位示例,手動在地圖上選點並新增標註,附帶自定義的資訊比如速度和時間等。
- 提供海量點位示例,批次新增標註點、點聚合、海量點。用於測試環境中支援的最大點位效能。
- 提供動態軌跡示例,在地圖上滑鼠按下選擇起點和終點後,查詢路線,獲取路徑軌跡點,模擬軌跡平滑移動。可以篩選資料將過多的路徑點篩選到設定的點數。
- 提供軌跡回放示例,按照指定的軌跡點列表回放,也可以匯入軌跡點資料進行回放。同時支援在街道圖、衛星圖、混合圖中回放軌跡。
- 提供省市區域地圖示例,採用echart元件,同時支援閃爍點圖、遷徙圖、區域地圖、世界地圖、儀表盤等。可以設定標題、提示資訊、背景顏色、文字顏色、線條顏色、區域顏色等各種顏色。
- 省市區域地圖示例,內建世界地圖、全國地圖、省份地圖、地區地圖,可以精確到縣,所有地圖全部離線使用。可設定城市的名稱、值、經緯度集合。
- 內建通用瀏覽器元件,同時支援webkit/webengine/miniblink等核心。提供網頁控制元件示例,演示開啟網頁和本地網頁檔案。
- 支援任意Qt版本、任意系統、任意編譯器。
三、相關連結
- 體驗地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取碼:o05q 檔名:bin_map.zip
- 國內站點:https://gitee.com/feiyangqingyun
- 國際站點:https://github.com/feiyangqingyun
四、效果圖
五、相關程式碼
void MapObjBase::addHead(const QStringList &scripts)
{
//構建網頁頭部
html << QString("<html>");
html << QString("<head>");
html << QString("<title>%1</title>").arg(title);
html << QString("<meta charset=\"utf-8\">");
html << QString("<meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width\">");
//新增網頁樣式
this->addCss();
//新增不同地圖不同的指令碼檔案
foreach (QString script, scripts) {
html << script;
}
//引入Qt中網頁互動用的js檔案
#ifdef webengine
html << QString("<script type=\"text/javascript\" src=\"qrc:/qwebchannel.js\"></script>");
#endif
html << QString("</head>");
}
void MapObjBase::addCss()
{
//構建頁面樣式
html << QString("<style type=\"text/css\">");
//地圖尺寸
html << QString(" #map{height:%1;width:100%;}").arg((mapControl & MapControl_Panel) ? QString("%1px").arg(mapHeight) : "100%");
//結果皮膚樣式
html << QString(" #panel,#panel table{width:100%;font-size:12px;}");
//隱藏左下角的logo
html << QString(" .anchorBL,.amap-logo,.amap-copyright,.tdt-control-copyright{opacity:0;}");
//全域性字型樣式
html << QString(" html,body{font-family:微軟雅黑;height:100%;width:100%;margin:0px;padding:0px;}");
//webkit瀏覽器捲軸樣式
html << QString(" ::-webkit-scrollbar{width:0.8em;}");
html << QString(" ::-webkit-scrollbar-track{background:rgb(241,241,241);}");
html << QString(" ::-webkit-scrollbar-thumb{background:rgb(188,188,188);}");
html << QString("</style>");
}
void MapObjBase::addBody()
{
//構建網頁主體部分內容
html << QString("<body>");
html << QString(" <div id='map'></div>");
//新增結果皮膚/比如路徑查詢和周邊搜尋等結果可以有個皮膚直接展示
panelName = "";
if (mapControl & MapControl_Panel) {
panelName = "panel";
html << QString(" <div id='%1'></div>").arg(panelName);
}
html << QString("</body>");
//引入js檔案
html << QString("<script type=\"text/javascript\">");
#ifdef mapweb
html << QString(" var socket = new WebSocket('ws://127.0.0.1:6001');");
#endif
//通用返回資料函式
html << QString(" function receiveData(type, data) {");
#ifdef mapweb
html << QString(" if (socket) {");
html << QString(" socket.send(type + '_' + data);");
html << QString(" }");
#else
#ifdef webminiblink
html << QString(" objName_receiveData(type, data);");
#else
html << QString(" objName.receiveData(type, data);");
#endif
#endif
html << QString(" }");
//生成QWebChannel通訊物件用於js互動
#ifndef webkit
#ifdef webengine
html << QString(" new QWebChannel(qt.webChannelTransport, function(channel){window.objName = channel.objects.objName;})");
#endif
#endif
}
void MapObjBase::addFun()
{
//沒有啟用新增互動函式則不用繼續/方便測試簡單的網頁內容
MapObjFun::mapCore = mapCore;
if (!mapFun) {
return;
}
this->addLayer();
this->addEvent();
this->addOther();
this->getPoint();
this->getPoints();
this->getMarkers();
this->getPathPoints();
this->getBounds();
this->getCenterAndZoom();
this->setCenterAndZoom();
this->getRotateAndTilt();
this->setRotateAndTilt();
this->setEnable();
this->setMapStyle();
this->setMapType();
this->setAutoView();
//線上地圖才有地址轉換等功能
if (!mapLocal) {
this->addConvertor();
this->addGeocoder();
this->addSearch();
this->addRoute();
this->searchRoute();
}
this->drawRoute();
this->addDrawingTool();
this->addDistanceTool();
this->clearData();
this->clearOverlay();
this->deleteOverlay();
this->editOverlay();
this->getOverlayInfo();
this->getOverlayProperty();
this->setClick();
this->addMarker();
this->setMarker();
this->deleteMarker();
this->initPolyline();
this->setPolyline();
this->deletePolyline();
this->addMove();
this->addLine();
this->moveEvent();
this->findMove();
this->doMove();
this->addPolyline();
this->addPolygon();
this->addRectangle();
this->addCircle();
this->addCurveLine();
this->searchBoundary();
this->getBoundary();
this->addBoundary();
this->addMarkerCluster();
this->addPointCollection();
}
void MapObjBase::addEnd()
{
html << QString("</script>");
html << QString("</html>");
}