1. 天地图API与GeoJSON数据初探第一次接触天地图API时我被它丰富的地理数据资源震撼到了。作为国内权威的在线地图服务天地图不仅提供了基础地图展示功能还开放了强大的开发接口让开发者可以自由调用各类地理数据。其中最实用的功能之一就是支持GeoJSON格式的行政区划数据动态渲染。GeoJSON是一种基于JSON的地理空间数据交换格式用简单的数据结构就能描述点、线、面等地理要素。比如要绘制某个省份的边界传统方式可能需要复杂的多边形坐标计算而使用GeoJSON只需要几行代码就能搞定。这种简洁高效的特点让它成为Web地图开发的首选数据格式。在实际项目中我经常需要展示不同层级的行政区划地图。比如全国概览、省级分布或者市级详情。天地图API配合GeoJSON数据源完美解决了这个问题。你只需要更换数据源URL就能实现从全国到区县的无缝切换完全不需要重写核心代码。2. 快速搭建开发环境2.1 基础HTML结构搭建我们先从最基础的HTML骨架开始。创建一个index.html文件写入以下代码!DOCTYPE html html head meta charsetUTF-8 title天地图GeoJSON示例/title style #map-container { width: 100%; height: 600px; } /style /head body div idmap-container/div /body /html这个简单的结构定义了一个全宽的容器后续我们的地图就会渲染在这个div中。注意给容器设置明确的高度否则地图无法正常显示。2.2 引入必要的JS库接下来需要在head标签内引入天地图API和D3.js库script srchttp://api.tianditu.gov.cn/api?v4.0tk你的密钥/script script srchttps://d3js.org/d3.v7.min.js/script script srchttp://lbs.tianditu.gov.cn/api/js4.0/opensource/openlibrary/D3SvgOverlay.js/script这里有几个关键点需要注意使用天地图API需要先申请开发者密钥替换代码中的你的密钥D3.js建议使用v5以上版本本文示例使用v7D3SvgOverlay.js是天地图提供的扩展库用于在Canvas地图上叠加SVG图层3. 初始化天地图实例3.1 创建基础地图在body标签结束前添加script标签编写地图初始化代码var map new T.Map(map-container); map.centerAndZoom(new T.LngLat(116.404, 39.915), 5);这段代码做了两件事创建地图实例绑定到我们之前定义的容器设置初始中心点和缩放级别这里以北京为中心缩放级别5适合显示全国3.2 添加地图控件为了让地图更实用我们可以添加一些常用控件map.addControl(new T.Control.Zoom()); map.addControl(new T.Control.Scale()); map.addControl(new T.Control.OverviewMap());这些控件分别提供了缩放按钮比例尺显示鹰眼小地图4. 加载GeoJSON数据4.1 获取行政区划数据天地图本身不直接提供GeoJSON数据但我们可以从其他公开数据源获取。阿里云DataV提供了完整的中国行政区划GeoJSON数据var geoJsonUrl https://geo.datav.aliyun.com/areas_v3/bound/100000_full.json;这个URL返回的是全国级别的数据。如果要获取省级数据只需要修改最后的数字代码。比如北京市110000上海市310000广东省4400004.2 使用D3.js加载数据现在我们用D3.js来加载并解析GeoJSON数据d3.json(geoJsonUrl).then(function(data) { renderGeoJson(data); });这里使用了D3的json方法发起网络请求并在回调函数中获取解析后的数据对象。注意这是一个异步操作所以后续处理要写在回调函数内。5. 渲染GeoJSON到地图5.1 创建D3叠加层天地图提供了D3Overlay类专门用于在Canvas地图上叠加SVG元素var overlay new T.D3Overlay(initFunction, redrawFunction);这个类需要两个回调函数initFunction初始化SVG元素redrawFunction当地图移动或缩放时重绘元素5.2 实现初始化函数让我们实现具体的初始化逻辑function initFunction(selection, transform) { selection.selectAll(path) .data(geoJsonData.features) .enter() .append(path) .attr(d, transform.pathFromGeojson) .attr(fill, #3388ff) .attr(fill-opacity, 0.5) .attr(stroke, #ffffff) .attr(stroke-width, 1); }这段代码做了以下工作为每个GeoJSON特征创建SVG路径使用transform对象将地理坐标转换为屏幕坐标设置填充颜色、透明度、边框等样式5.3 实现重绘函数重绘函数相对简单主要处理地图交互时的更新function redrawFunction(selection, transform) { selection.selectAll(path) .attr(d, transform.pathFromGeojson); }当地图移动或缩放时这个函数会被自动调用确保所有SVG元素位置正确。6. 添加交互效果6.1 鼠标悬停高亮为了让地图更生动我们可以添加鼠标交互效果。修改初始化函数中的路径创建代码.append(path) // ...其他属性... .on(mouseover, function() { d3.select(this).attr(fill, #ff0000); }) .on(mouseout, function() { d3.select(this).attr(fill, #3388ff); });这样当鼠标悬停在某个区域时它会变成红色移出后恢复原色。6.2 点击显示详细信息更进一步我们可以实现点击显示区域名称的功能.on(click, function(event, d) { var name d.properties.name; alert(你点击了 name); });这里从GeoJSON的属性中提取了区域名称实际项目中可以用更美观的方式展示比如弹出信息窗口。7. 动态切换行政区划层级7.1 构建层级切换功能真正的威力在于动态切换不同层级的GeoJSON数据。我们先创建一个简单的下拉菜单select idregion-select option value100000全国/option option value110000北京市/option option value310000上海市/option /select然后添加事件监听document.getElementById(region-select).addEventListener(change, function() { var code this.value; loadRegionData(code); });7.2 实现数据加载函数loadRegionData函数负责加载并渲染新数据function loadRegionData(code) { var url https://geo.datav.aliyun.com/areas_v3/bound/${code}_full.json; d3.json(url).then(function(data) { map.removeOverlay(overlay); renderGeoJson(data); }); }关键点根据选择的值构建新的数据URL移除旧的地图叠加层加载并渲染新数据8. 性能优化技巧8.1 简化GeoJSON数据当渲染小区域时原始数据可能过于详细。可以使用地图shp工具简化GeoJSON// 使用mapshaper命令行工具简化 // mapshaper input.json -simplify 10% -o output.json简化后的数据量更小渲染速度更快特别适合移动端使用。8.2 使用缓存机制频繁切换区域时可以缓存已加载的数据var cache {}; function loadRegionData(code) { if(cache[code]) { renderGeoJson(cache[code]); return; } // ...原有加载逻辑... d3.json(url).then(function(data) { cache[code] data; // ...渲染逻辑... }); }这样再次切换时就不需要重新下载数据了。8.3 合理设置地图视野加载新数据后自动调整地图视野到合适范围// 计算GeoJSON的边界框 var bounds d3.geoBounds(data); var sw new T.LngLat(bounds[0][0], bounds[0][1]); var ne new T.LngLat(bounds[1][0], bounds[1][1]); map.setViewport([sw, ne]);这样用户就不需要手动缩放和移动地图了。