2025年4月18日 星期五 乙巳(蛇)年 正月十九 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > JavaScript

Vue 3 + 天地图 + D3.js 绘制行政区划

时间:02-17来源:作者:点击数:18

vue+天地图+d3.js绘制行政区划

天地图提供了与可视化库D3.js的快速集成,方便于我们进行开发

以下是我的效果,以天津市滨海新区为例

那么在vue项目中,我们该如何使用,下面以Vue3+Ts项目为例

引入天地图 API
  • 在 index.html 文件中引入天地图 API 4.0 版本。
  • 获取天地图 API 密钥并将其添加到脚本源中。
  • <script src="http://api.tianditu.gov.cn/api?v=4.0&tk=你的秘钥" type="text/javascript"></script>
初始化地图
  • 创建一个名为 mapDiv 的容器,并设置样式。
  • 在 Vue 组件中使用 onMounted 生命周期钩子初始化天地图实例。
  • 设置地图类型为矢量图,并设置中心点和缩放级别。

然后在页面中渲染天地图

  • <template>
  •    <div id="mapDiv" :style="Style"></div>
  • </template>
  • <script setup lang="ts">
  •    import { ref, onMounted, nextTick, defineProps, defineExpose, defineEmits } from "vue";
  •    let map: any = null;
  •    let T: any = (window as any).T;
  •    const d3 = (window as any).d3
  •    const TMAP_VECTOR_MAP = (window as any).TMAP_VECTOR_MAP
  •    let countriesOverlay = new T.D3Overlay(inits,redraw);
  •    //初始化地图
  •    const initTiandituMap = () => {
  •        map = new T.Map("mapDiv");
  •        map.setMapType(TMAP_VECTOR_MAP);
  •        map.centerAndZoom(new T.LngLat(117.711000,39.003101), 10);
  •        map.setStyle('block')
  •   };
  •    onMounted(() => {
  •        nextTick(()=> {
  •            initTiandituMap()
  •       })
  •   })
  • </script>
  • <style scoped lang="scss">
  • ::v-deep(.tdt-label){
  •    background: none;
  •    border: none;
  •    color: #fff;
  •    -webkit-box-shadow: none;
  •    box-shadow: none;
  •    padding: 0;
  •    line-height: 0.6vw;
  •    font-size: 0.6vw;
  • }
  • </style>

这样就可以渲染出天地图了

那我们要进行行政区划呢,就需要用到d3.js绘制图形了,官网也是有示例的

首先,我们要拿到各自区域的地图json,如没有可去

DataV.GeoAtlas地理小工具系列

进行取点区域信息等。

引入 D3.js
  • 在 index.html 文件中引入 D3.js 库及其扩展 D3SvgOverlay.js
  •    <script src="/src/utils/d3/d3.js" charset="utf-8"></script>
  •    <script src="/src/utils/d3/D3SvgOverlay.js"></script>
加载行政区划数据
  • 从外部文件导入滨海新区的 GeoJSON 数据。
  • 使用 D3.js 的 D3Overlay 组件来绘制行政区划。
  • 定义 inits 函数来初始化路径元素,并设置样式。
  • 定义 redraw 函数来更新路径元素的位置。
  • <template>
  •    <div id="mapDiv" :style="Style"></div>
  • </template>
  • <script setup lang="ts">
  •    import mapJson from '@/utils/tjbhJson';
  •    import { ref, onMounted, nextTick, defineProps, defineExpose, defineEmits } from "vue";
  •    let map: any = null;
  •    let T: any = (window as any).T;
  •    const d3 = (window as any).d3
  •    const TMAP_VECTOR_MAP = (window as any).TMAP_VECTOR_MAP
  •    let countries: any = [];
  •    let countriesColor: any = [320,498,178,598,420,320,120,120];
  •    const inits = (sel: any, transform: any) => {
  •        let upd = sel.selectAll('path.geojson').data(countries);
  •        upd.enter()
  •           .append('path')
  •           .attr("class", "geojson")
  •           .attr('stroke', '#05CEE5')//边界线颜色
  •           .attr('stroke-width', '2')//边界线宽度
  •           .attr('fill', function (d: any, i: any) {
  •                return d3.hsl(countriesColor[i], 0.9, 0.5)
  •           })//区域填充
  •           .attr('fill-opacity', '0.3')//区域填充透明度
  •   }
  •    const redraw = (sel: any, transform: any) => {
  •        sel.selectAll('path.geojson').each(
  •            function (this: any, i: any) {
  •                d3.select(this).attr('d', transform.pathFromGeojson)
  •           }
  •       )
  •   }
  •    let countriesOverlay = new T.D3Overlay(inits,redraw);
  •    //初始化地图
  •    const initTiandituMap = () => {
  •        map = new T.Map("mapDiv");
  •        map.setMapType(TMAP_VECTOR_MAP);
  •        map.centerAndZoom(new T.LngLat(117.711000,39.003101), 10);
  •        map.setStyle('block')
  •        disProvince()
  •   };
  •    //添加滨海新区图层
  •    const disProvince = () => {
  •        countries = mapJson.features;
  •        map.addOverLay(countriesOverlay)
  •        countriesOverlay.bringToBack();
  •        textJson.forEach((item: any) => {
  •            let coord: any = item.coord.split(",")
  •            let LngLat = new T.LngLat(coord[0], coord[1])
  •       })
  •   }
  •    onMounted(() => {
  •        nextTick(()=> {
  •            initTiandituMap()
  •       })
  •   })
  • </script>
  • <style scoped lang="scss">
  • ::v-deep(.tdt-label){
  •    background: none;
  •    border: none;
  •    color: #fff;
  •    -webkit-box-shadow: none;
  •    box-shadow: none;
  •    padding: 0;
  •    line-height: 0.6vw;
  •    font-size: 0.6vw;
  • }
  • </style>
添加文本标注
  • 遍历文本坐标数据,并使用天地图的 Label 对象添加文本标注到地图上。
  •   const disProvince = () => {
  •        countries = mapJson.features;
  •        map.addOverLay(countriesOverlay)
  •        countriesOverlay.bringToBack();
  •        textJson.forEach((item: any) => {
  •            let coord: any = item.coord.split(",")
  •            let LngLat = new T.LngLat(coord[0], coord[1])
  •            //添加3d文字
  •            var label = new T.Label({text: `<div>${item.text}</div>`, position: LngLat})
  •            map.addOverLay(label);
  •       })
  •   }

通过以上步骤,你可以成功地在 Vue 3 项目中集成天地图和 D3.js,实现行政区划的绘制及文本标注功能。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐