目錄
前言
一、天地圖在線檢索
1、在線檢索功能
2、再談后后接口
二、Leaflet多層級實現實例
1、層級調用實現原理
2、Leaflet中多層級調用
3、成果展示
三、總結
前言
????????“地圖是世界的索引,而地名則是索引中的索引。”當互聯網地圖進入 Web 2.0 時代,開發者不再滿足于“看得見”的瓦片,更希望“問得準”——輸入一個模糊的地名,就能在毫秒之間鎖定它在全球、全國、省市、區縣乃至鄉鎮的多級位置。天地圖作為國家地理信息公共服務平臺的官方出口,提供了完全符合國標的行政區劃與興趣點(POI)檢索能力;而輕量級的 Leaflet 則在前端以極簡的 API 哲學,讓地圖可視化回歸“純粹的快樂”。當兩者相遇,我們便有了“用 200 行代碼完成一個國家級別地名搜索引擎”的可能。本文所記錄的,正是這樣一次“小而美”的實戰:如何以 Leaflet 為殼、天地圖為芯,逐級剖開中國行政體系的“套娃式”結構,把“模糊輸入–多級聯想–精準定位”做成一套可復用的前端組件。在WebGIS的可視化效果中,在省級節點中展示統計數量,隨著地圖的深入逐級進行細化,將地名逐漸呈現在大家的面前。
????????在之前的博客中曾經對如何調用天地圖的檢索API進行了詳細的介紹。但是如何進行詳細層級展示沒有進行詳細的說明,因此有朋友留言表示希望可以對層級展示進行一個具體的說明。本文即在此背景下產生。
????????閱讀全文并運行示例后,你將掌握:
如何正確調用天地圖全部檢索接口;
如何為 Leaflet 編寫一個“可復用”的入口,支持調用天地圖的地名檢索接口;
如何在Javascript中處理層級展示問題;
如何實現下鉆的行政區檢索。
一、天地圖在線檢索
????????本節將詳細的介紹天地圖的在線檢索功能,分別介紹天地圖的搜索功能和后端接口。通過參考學習天地圖的地圖展現形式,為我們后面的技術和頁面實現提供參考。
1、在線檢索功能
????????為了展示天地圖的多層級展示功能,首先我們來看一下其官方網站的實例。大家可以訪問天地圖后,點擊“在線”地圖的tab標簽頁,從而跳轉到在線地圖,如下圖所示:
?????????在其頁面的左上角就有一個輸入框,在這個輸入框中輸入相應的信息就可以完成信息的檢索。比如在輸入框中輸入“自然”,點擊檢索,在界面上就可以看到以下的展示:
????????可以看到包含了自然的地名最多的省級行政區劃是浙江省,共有599616條記錄。第二名是廣東省,約有3307條記錄,第三名是江蘇省,大約有2842條記錄。
2、再談后后接口
????????為了照顧第一次看博文的朋友,這里將天地圖的檢索接口API給大家詳細的介紹一下,讓大家了解后臺的數據接口和服務,在下一節的多層級調用展示過程實現提供技術基礎。
????????輸入參數說明
參數值 | 參數說明 | 參數類型 | 是否必備 | 備注(值域) |
keyWord | 搜索的關鍵字 | String | 必填 | 無 |
specify | 指定行政區的國標碼(行政區劃編碼表)嚴格按照行政區劃編碼表中的(名稱,gb碼) | String | 必填 | 下載行政區劃編碼表。9位國標碼,如:北京:156110000或北京。 |
queryType | 服務查詢類型參數 | String | 必填 | 12:行政區劃區域搜索服務。 |
start | 返回結果起始位(用于分頁和緩存)默認0 | String | 必填 | 0-300,表示返回結果的起始位置。 |
count | 返回的結果數量(用于分頁和緩存) | String | 必填 | 1-300,返回結果的條數。 |
dataTypes | 數據分類(分類編碼表) | String | 可選 | 下載分類編碼表,參數可以分類名稱或分類編碼。多個分類用","隔開(英文逗號)。 |
show | 返回poi結果信息類別 | String | 可選 | 取值為1,則返回基本poi信息; 取值為2,則返回詳細poi信息 |
????????返回參數說明
參數值 | 參數說明 | 參數類型 | 返回條件 | 備注(值域) | ||
resultType | 返回結果類型 | Int | 必返回 | 取值1-5,對應不同的響應類型: 1(普通POI),2(統計),3(行政區),4(建議詞搜索),5(線路結果) | ||
count | 返回總條數 | Int | 必返回 | |||
keyword | 搜索關鍵詞 | String | 必返回 | 搜索的關鍵字。 | ||
pois | 針對點(類型1)集合返回 | Pois Json數組 | resultType=1 | |||
name | Poi點名稱 | String | 必返回 | |||
phone | 電話 | String | ||||
address | 地址 | String | ||||
lonlat | 坐標 | String | 必返回 | 坐標 x,y | ||
poiType | poi類型 | Int | 必返回 | 101:POI數據 102:公交站點 | ||
eaddress | 英文地址 | String | ||||
ename | poi點英文名稱 | String | ||||
hotPointID | poi熱點ID | String | 必返回 | 熱點id | ||
province | 所屬省名稱 | String | ||||
provinceCode | 省行政區編碼 | String | ||||
city | 所屬城市名稱 | String | ||||
cityCode | 市行政區編碼 | String | ||||
county | 所屬區縣名稱 | String | ||||
countyCode | 區縣行政區編碼 | String | ||||
source | 數據信息來源 | String | 必返回 | |||
typeCode | 分類編碼 | String | ||||
typeName | 分類名稱 | String | ||||
stationData | 車站信息結構體 數據 | Json 數組 | poiType=102 | |||
lineName | 線路名稱 | String | 必返回 | |||
uuid | 線路的id | String | 必返回 | |||
stationUuid | 公交站uuid | String | 必返回 | |||
statistics | 針對統計(類型2)集合返回 | Json 數組 | resultType=2 | |||
count | 本次統計POI總數量 | Int | 必返回 | |||
adminCount | 行政區數量 | Int | 必返回 | |||
priorityCitys | 推薦行政區名稱 | Json數組 | 必返回 | |||
name | 行政區名稱 | String | 必返回 | |||
count | 城市數量 | Int | 必返回 | |||
lonlat | 行政區經緯度 | String | 必返回 | 坐標 x,y | ||
ename | 英文行政名稱 | String | 必返回 | |||
adminCode | 城市國標碼 | Int | 必返回 | 9位國標碼。 | ||
allAdmins | 各省包含信息集合 | Json數組 | 必返回 | |||
name | 行政名稱 | String | 必返回 | |||
count | 包含數量 | Int | 必返回 | |||
lonlat | 行政區經緯度 | String | 必返回 | 坐標x,y | ||
adminCode | 省國標碼 | String | 必返回 | |||
ename | 英文行政名稱 | String | 必返回 | |||
isleaf | 有無下一級行政區 | boolean | 必返回 | 有則false,無則true |
????????在官網的調用示例中,使用瀏覽器的調試工具來看一下數據返回的結果:
?????????請特別注意以上的接口返回值,這里取其中的一個值對象信息如下:
{"adminName": "浙江省","ename": "Zhejiang Province","count": 599616,"adminCode": 156330000,"isleaf": false,"lonlat": "120.06772699999999,29.174674999999997"
}
????????這里返回的adminCode參數非常重要,在后面的層級調用中其實就是依賴這個adminCode來進行多層級實現的。
二、Leaflet多層級實現實例
????????本節將具體詳述如何使用Leaflet來調用天地圖的檢索API和實現多層級調用,可以在Leafelt中實現我們自己的邏輯,可以展示省-市-POI詳情等信息,最后給大家展示一些實際的效果。
1、層級調用實現原理
????????關于如何實現層級調用,在前面一節中也進行了簡單說明。其實就是一個遞歸的調用,在進行API調用時,首先需要判斷返回的數據類型是什么?如果從接口中返回的類型是1表示是poi數據,直接展示即可,如果是2表示是展示統計數據,再從統計數據中獲取所有的信息,循環統計信息中的行政區劃信息,然后再遞歸調用其行政區劃的編碼實現向下檢索。實現的核心代碼展示如下:
/**
* 調用天地圖查詢
*/
function callTdtSearch(keyWord,specify){var queryUrl = "http://api.tianditu.gov.cn/v2/search?postStr={'keyWord':'"+ keyWord +"','queryType':12,'start':0,'count':10,'specify':'" + specify + "','show':'2'}&type=query&tk="+tdt_client_key;$.ajax({type: "get",url:queryUrl,data: {},success: function(rsData) {// 移除所有圖層myLayerGroup.clearLayers();var rsObj = rsData; var loc_info = rsObj.location;var resultType = rsObj.resultType;switch(resultType){case 1 :showPoi(rsObj);break;case 2:showStatistics(rsObj);break;default:console.log("不詳");}map.addLayer(myLayerGroup); }});
}
2、Leaflet中多層級調用
????????根據接口中返回的類型不一樣來進行個性化的展示,以此達到區別展示的效果。這里重點介紹如何來進行統計信息的展示和如何調用下一層級的POI信息,核心方法如下:
//點擊還可以進行查詢
function buildStatHtml(stat,index){var html = "";html += "<div class='marsBlackPanel' style='background:#ff9800;' animation-spaceInDown>";html += "<div class='marsBlackPanel-text' style='' onclick='execQueryByCode("+stat.adminCode+")'>" + (index +1) + "、" +stat.adminName + "(" + stat.count + ")</div>";html += "</div>";return html;
}
function showStatistics(rsObj){var statistics = rsObj.statistics.allAdmins;for(var i = 0;i<statistics.length;i++){var stat = statistics[i];var lonlat = stat.lonlat;var lonlatStr = lonlat.split(",");var marker = L.marker([lonlatStr[1], lonlatStr[0]], {icon: L.divIcon({iconSize: null,className: '',popupAnchor:[5,5],shadowAnchor:[5,5],html: buildStatHtml(stat,i)})}).addTo(myLayerGroup);}map.fitBounds(myLayerGroup.getBounds());
}
????????這里實現的關鍵就是在自定義的標注中,綁定了一個執行查詢的方法,然后再這個執行方法中又可以進行下一個層級的調用。 關鍵的方法如下:
function execQueryByCode(specify){var keyWord = $("#address").val();callTdtSearch(keyWord,specify);
}
????????這樣就實現了層次的調用,當返回的值是具體的POI時,直接展示。反之則會進行省份的標注,同時可以點擊當前省份,從而實現多層級的調用和展示。
3、成果展示
????????下面結合一些實際的例子來展示一下成果,具體是如何來進行相關的實現的。
????????在Web瀏覽器中輸入請求地址,可以看到以上的界面效果。這樣就基本模擬省份這個層級的統計展示。 需要說明的是,通過POI檢索API的數據結果與官網的檢索結果之前還是有一丟丟的區別,比如官網返回的結果是599616,而通過我們的接口調用,返回的結果是:596756;下面將結果整理一個表示,供大家參考,具體出現差異的原因可能需要咨詢客服人員:
序號 | 省份 | 官方返回結果 | 自主調用結果 | 差額 |
1 | 浙江省 | 599616 | 596756 | 2860 |
2 | 廣東省 | 3307 | 3103 | 204 |
3 | 江蘇省 | 2842 | 2519 | 323 |
4 | 江西省 | 2271 | 1918 | 353 |
5 | 湖南省 | 2230 | 1895 | 335 |
????????由此可以看出,搜索的結果還是存在一定的區別的。
????????下面來看一個有意思的地方,包含舒服兩個字的最多的省份是湖北省。
????????而在湖北省中,武漢又是最多的,有41個地方包含舒服,
????????來看看具體包含舒服的地名都在武漢的哪些地方,
?????????最后來看看天地圖中包含火鍋的最多的省份是哪里?
????????可以看到,出現火鍋最多的地方居然是江蘇省,在大家的印象里,江浙應該都是甜口居多。而喜好火鍋的云貴川桔田前三都擠不進去,第四名為重慶,第六名四川。前三中,除江蘇外,第二名是山東省,第三名是河南省,有沒有出乎你的意料呢?
????????在江蘇省中,蘇州市的火鍋又是地第一名的,有2028個, 如下:
????????確實基本上都是火鍋了,這個確實沒有想到,大蘇州的火鍋居然這么多。?
三、總結
????????以上就是本文的主要內容,本文所記錄的,正是這樣一次“小而美”的實戰:如何以 Leaflet 為殼、天地圖為芯,逐級剖開中國行政體系的“套娃式”結構,把“模糊輸入–多級聯想–精準定位”做成一套可復用的前端組件。在WebGIS的可視化效果中,在省級節點中展示統計數量,隨著地圖的深入逐級進行細化,將地名逐漸呈現在大家的面前。本文不僅詳細的介紹了如何在Leaflet中進行層級展示的實現,并且基于實際的地名進行了實際的檢索展示,如果大家感興趣,不妨來這里看看。行文倉促,定有不足之處,歡迎各位朋友在評論區批評指正,不勝感激。