首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >基于Leaflet调用天地图在线API的多层级地名检索实战

基于Leaflet调用天地图在线API的多层级地名检索实战

原创
作者头像
夜郎King
发布于 2026-11-04 23:49:58
发布于 2026-11-04 23:49:58
670
举报
文章被收录于专栏:LeafletLeaflet

前言

“地图是世界的索引,而地名则是索引中的索引。”当互联网地图进入 Web 2.0 时代,开发者不再满足于“看得见”的瓦片,更希望“问得准”——输入一个模糊的地名,就能在毫秒之间锁定它在全球、全国、省市、区县乃至乡镇的多级位置。天地图作为国家地理信息公共服务平台的官方出口,提供了完全符合国标的行政区划与兴趣点(POI)检索能力;而轻量级的 Leaflet 则在前端以极简的 API 哲学,让地图可视化回归“纯粹的快乐”。当两者相遇,我们便有了“用 200 行代码完成一个国家级别地名搜索引擎”的可能。本文所记录的,正是这样一次“小而美”的实战:如何以 Leaflet 为壳、天地图为芯,逐级剖开中国行政体系的“套娃式”结构,把“模糊输入–多级联想–精准定位”做成一套可复用的前端组件。在WebGIS的可视化效果中,在省级节点中展示统计数量,随着地图的深入逐级进行细化,将地名逐渐呈现在大家的面前。

在之前的博客中曾经对如何调用天地图的检索API进行了详细的介绍。但是如何进行详细层级展示没有进行详细的说明,因此有朋友留言表示希望可以对层级展示进行一个具体的说明。本文即在此背景下产生。

阅读全文并运行示例后,你将掌握:

  1. 如何正确调用天地图全部检索接口;
  2. 如何为 Leaflet 编写一个“可复用”的入口,支持调用天地图的地名检索接口;
  3. 如何在Javascript中处理层级展示问题;
  4. 如何实现下钻的行政区检索。

一、天地图在线检索

本节将详细的介绍天地图的在线检索功能,分别介绍天地图的搜索功能和后端接口。通过参考学习天地图的地图展现形式,为我们后面的技术和页面实现提供参考。

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

在官网的调用示例中,使用浏览器的调试工具来看一下数据返回的结果:

请特别注意以上的接口返回值,这里取其中的一个值对象信息如下:

代码语言:txt
复制
{
  "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表示是展示统计数据,再从统计数据中获取所有的信息,循环统计信息中的行政区划信息,然后再递归调用其行政区划的编码实现向下检索。实现的核心代码展示如下:

代码语言:txt
复制
/**
* 调用天地图查询
*/
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信息,核心方法如下:

代码语言:txt
复制
//点击还可以进行查询
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());
}

这里实现的关键就是在自定义的标注中,绑定了一个执行查询的方法,然后再这个执行方法中又可以进行下一个层级的调用。 关键的方法如下:

代码语言:txt
复制
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中进行层级展示的实现,并且基于实际的地名进行了实际的检索展示,如果大家感兴趣,不妨来这里看看。行文仓促,定有不足之处,欢迎各位朋友在评论区批评指正,不胜感激。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 前言
  • 一、天地图在线检索
    • 1、在线检索功能
    • 2、再谈后后接口
  • 二、Leaflet多层级实现实例
    • 1、层级调用实现原理
    • 2、Leaflet中多层级调用
    • 3、成果展示
  • 三、总结
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档