## 一、前言
之前做獲取邊界點的時候,主要採用的是在線地圖的方式,因為在線地圖中直接內置了函數可以根據行政區域的名稱來自動獲取邊界,其實這些邊界就是一些點座標集合連接起來的平滑線,然後形成的輪廓圖,這種方式有個弊端就是隻能在線的時候使用,而我們大部分的應用場景應該是離線的,甚至很多設備永遠是離線的,根本不可能去聯網獲取信息,但是又想要這個各省市區域的輪廓圖怎辦呢,只能事先拿到下載到這些需要的輪廓圖文件才行,這些文件存儲的就是經緯度座標集合,在離線地圖中只需要定義不規則線條繪製傳入這些經緯度座標集合即可。
Qt的瀏覽器控件的交互機制非常方便,所以在在線地圖的時候可以對每個區域的經緯度座標集合發給Qt程序,讓他去存儲到文件,在實際的測試過程中,發現有部分地圖有多個封閉的曲線的,比如散落的島嶼和飛地,這些可不能遺漏呢,所以存儲經緯度座標信息,要按照數組的形式存儲,最開始做的時候按照一個字符串集合存儲的,後面發現部分地方少了甚至不規則,原來是有多個曲線集合,解析的時候根據數組來實例化不規則線條的類即可。
在線地圖默認只能精確到縣城,如果還要更精確的話,就需要自己手動調整邊界點拉動好,然後主動獲取當前邊界點的經緯度座標集合,存儲起來,這就需要一開始設定一個基本的邊界點的形狀,開啟允許編輯屬性,然後自行去調整好位置,最後單擊獲取邊界點座標,保存文件即可,如果需要很多的鄉鎮的輪廓圖,那隻能很有耐心的慢慢的調整獲取咯,當然這種無聊的沒有技術含量的事情也可以交給小姑娘去做啦。
## 二、功能特點
1. 同時支持在線地圖和離線地圖兩種模式。
2. 同時支持webkit內核、webengine內核、IE內核。
3. 支持設置多個標註點,信息包括名稱、地址、經緯度。
4. 可設置地圖是否可單擊、拖動、鼠標滾輪縮放。
5. 可設置協議版本、秘鑰、主題樣式、中心座標、中心城市、地理編碼位置等。
6. 可設置地圖縮放比例和級別,縮略圖、比例尺、路況信息等控件的可見。
7. 支持地圖交互,比如鼠標按下獲取對應位置的經緯度。
8. 支持查詢路線,可設置起點位置、終點位置、路線模式、路線方式、路線方案(最少時間、最少換乘、最少步行、不乘地鐵、最短距離、避開高速)。
9. 可顯示點線面工具,可直接在地圖上劃線、點、矩形、圓形等。
10. 可設置行政區劃,指定某個城市區域繪製圖層,在線地圖自動輸出行政區劃邊界點集合到js文件給離線地圖使用。
11. 可靜態或者動態添加多個覆蓋物。支持點、折線、多邊形、矩形、圓形、弧線、點聚合等。
12. 函數接口友好和統一,使用簡單方便,就一個類。
13. 支持js動態交互添加點、刪除點、清空點、重置點,不需要刷新頁面。
14. 支持任意Qt版本、任意系統、任意編譯器。
## 三、體驗地址
國內站點:[https://gitee.com/feiyangqingyun](https://gitee.com/feiyangqingyun)
國際站點:[https://github.com/feiyangqingyun](https://github.com/feiyangqingyun)
## 四、效果圖
## 五、相關代碼
<code>QStringList
MapBoundary::getResult(const QByteArray &data, quint8 type, const QString &provinceName, const QString &cityName)
{
//處理數據
QStringList
result;
if
(type == 1 && provinceName.isEmpty()) {
return
result;
else if (type == 2 && (provinceName.isEmpty() || cityName.isEmpty())) {
return
result;
}
//採用qt內置的json方法解析
QJsonParseError
error;
QJsonDocument
jsonDoc = QJsonDocument::fromJson(data, &error);
if
(error.error == QJsonParseError::NoError) {
QJsonObject
rootObj = jsonDoc.object();
<< rootObj.keys();
if
(rootObj.contains("province")) {
QJsonArray
province = rootObj.value("province").toArray();
for
(int i = 0; i < province.count(); i++) {
QJsonObject
subObj = province.at(i).toObject();
if
(subObj.contains("name")) {
QString
name = subObj.value("name").toString();
if
(type == 0) {
result
<< name;
else if (type == 1) {
if
(name == provinceName) {
QJsonArray
city = subObj.value("city").toArray();
for
(int j = 0; j < city.count(); j++) {
QJsonObject
nodeObj = city.at(j).toObject();
if
(nodeObj.contains("cityname")) {
QString
cityname = nodeObj.value("cityname").toString();
result
<< cityname;
}
}
//退出查找
break;
}
else if (type == 2) {
if
(name == provinceName) {
bool
exist = false;
QJsonArray
city = subObj.value("city").toArray();
for
(int j = 0; j < city.count(); j++) {
QJsonObject
nodeObj = city.at(j).toObject();
if
(nodeObj.contains("cityname")) {
QString
cityname = nodeObj.value("cityname").toString();
if
(cityname == cityName) {
QJsonArray
countyname = nodeObj.value("countyname").toArray();
for
(int k = 0; k < countyname.count(); k++) {
QString
county = countyname.at(k).toString();
//數據中帶了縣城所在鎮,要過濾
if
(!county.endsWith("鎮")) {
result
<< county;
}
}
exist
=true;
break;
}
}
}
//退出查找
if
(exist) {
break;
}
}
}
}
}
}
}
//採用字符串分割方法解析
QString
temp = data;
QStringList
provice = temp.split("\n");
QString
name, cityname;
for
(int i = 0; i < provice.count(); i++) {
QString
value = provice.at(i);
if
(value.contains(""name"")) {
name
=getValue(value);
if
(type == 0) {
result
<< name;
}
else if (value.contains(""cityname"")) {
cityname
=getValue(value);
bool
exist = false;
if
(name == provinceName) {
exist
=true;
}
if
(type == 1) {
//檢測到是當前省份則來提取市區
if
(exist) {
result
<< cityname;
//當是新的省份以後立即退出
if
(name != provinceName) {
break;
}
}
}
else if (value.contains(""countyname"")) {
if
(type == 2) {
if
(name == provinceName && cityname == cityName) {
QString
county = getValue(value);
county
=county.mid(1, county.length() - 2);
QStringList
countys = county.split(" ");
foreach
(QString county, countys) {
//數據中帶了縣城所在鎮,要過濾
if
(!county.endsWith("鎮")) {
result
<< county;
}
}
break;
}
}
}
}
return
result;
}
/<code>