【天地图】VUE3关于天地图部分功能hooks封装useTdtMap.js
·
2024/08/13更新:使用原生天地图开发更推荐leaflet+天地图,leaflet hooks封装地址:【天地图】VUE3基于Leaflet.js部分功能hooks封装useLeafletMap.js-CSDN博客
仅根据个人习惯封装,仅供参考。
天地图API地址:http://lbs.tianditu.gov.cn/api/js4.0/class.html
该hooks除了需引入天地图外,还需引入开源库图片覆盖物!!!开源库地址:http://lbs.tianditu.gov.cn/api/js4.0/opensource/source.html
各方法详细说明在代码里体现,首先创建一个hooks——useTdtMap.js
/**
* useTdtMap(天地图hooks)
* params:
* id: 天地图绑定的html标签id,具有唯一性
*/
import { createVNode, render } from 'vue'
export const useTdtMap = (id) => {
let map = null // 地图对象
// 地图初始化,请根据个人情况自行配置地图初始化操作
const mapInit = () => {
map = new T.Map(id)
// 设置地图中心点坐标及地图级别
map.centerAndZoom(new T.LngLat(116.40769, 39.89945), 12)
//创建对象
map.disableDoubleClickZoom() // 禁止双击放大地图
// 设置底色
map.setStyle('indigo')
document.getElementsByClassName('tdt-control-copyright tdt-control')[0].style.display = 'none' // 去除天地图logo
return Promise.resolve() // 回调地图初始化完成
}
/**
* setMapCenter(地图平移)
* params:
* coordinate: 中心点经纬度
* 格式:'lng,lat'
* 示例:'116.40769,39.89945'
* 以下coordinate格式同该格式一致
*/
const setMapCenter = (coordinate) => {
let lng = coordinate.split(',')[0]
let lat = coordinate.split(',')[1]
map.panTo(new T.LngLat(lng, lat))
}
// 地图缩放 coordinate:同上 zoom:比例尺级别
const setMapScale = (coordinate, zoom) => {
let lng = coordinate.split(',')[0]
let lat = coordinate.split(',')[1]
map.centerAndZoom(new T.LngLat(lng, lat), zoom)
}
// 地图显示范围 coordinate1:范围点位1 coordinate2:范围点位2
const setMapBounds = (coordinate1, coordinate2) => {
let lng1 = coordinate1.split(',')[0]
let lat1 = coordinate1.split(',')[1]
let lng2 = coordinate2.split(',')[0]
let lat2 = coordinate2.split(',')[1]
map.setMaxBounds(new T.LngLatBounds(new T.LngLat(lng1, lat1), new T.LngLat(lng2, lat2)))
}
// 地图设置显示级别
const setZoomLevels = (minLevels = 1, maxLevels = 18) => {
map.setMinZoom(minLevels)
map.setMaxZoom(maxLevels)
}
/**
* 添加图片覆盖物类
* params:
* coordinate1: 经纬度 格式:'lng,lat'
* coordinate2: 经纬度 格式:'lng,lat'
* imgUrl: 点位显示图标
* option: 图片覆盖物属性,{ opacity: 图片透明度, alt: 如果无法显示图像,浏览器将显示替代文本 }
*/
const addMapImgOverLay = (coordinate1, coordinate2, imgUrl, option = {}) => {
let lng1 = coordinate1.split(',')[0]
let lat1 = coordinate1.split(',')[1]
let lng2 = coordinate2.split(',')[0]
let lat2 = coordinate2.split(',')[1]
let bd = new T.LngLatBounds(new T.LngLat(lng1, lat1), new T.LngLat(lng2, lat2))
let img = new T.ImageOverlay(imgUrl, bd, option)
map.addOverLay(img)
// return img
}
/**
* 地图添加自定义点位并返回该点位对象
* params:
* coordinate: 经纬度 格式:'lng,lat'
* iconUrl: 点位显示图标
* clickEvent: 监听点击事件回调
* iconOptions: 天地图ICON图标配置
* 格式:{
* iconSize: '30,30', 图标大小,非必需配置
* iconAnchor: '15,30' 图标偏移,非必需配置
* }
*/
const addMapMarker = (
coordinate,
iconUrl = '*',
clickEvent = null,
iconOptions = {}
) => {
let marker = getMapMarkerObj(coordinate, iconUrl, iconOptions)
if (clickEvent) {
marker.addEventListener('click', clickEvent)
}
addMapOverLay(marker)
return marker
}
// 生成点标注对象
const getMapMarkerObj = (coordinate, iconUrl, iconOptions) => {
let lng = coordinate.split(',')[0]
let lat = coordinate.split(',')[1]
const option = {
iconSize: iconOptions.iconSize || '30,30',
iconAnchor: iconOptions.iconAnchor || '15,30'
}
// 添加点位图标
let icon = new T.Icon({
iconUrl: iconUrl,
iconSize: new T.Point(option.iconSize.split(',')[0], option.iconSize.split(',')[1]),
iconAnchor: new T.Point(option.iconAnchor.split(',')[0], option.iconAnchor.split(',')[1])
})
let marker = new T.Marker(new T.LngLat(lng, lat), { icon: icon })
return marker
}
/**
* 地图添加自定义线并返回该线对象
* params:
* coordinateList: 线的各点位经纬度数组 格式:[{ lng: 'lng', lat: 'lat' }]
* polylineOption: 线配置项,参考天地图
* clickEvent: 监听点击事件回调
*/
const addMapLine = (coordinateList, polylineOption = null, clickEvent = null) => {
let points = coordinateList.map((item) => {
return new T.LngLat(item.lng, item.lat)
})
let marker = new T.Polyline(points, polylineOption)
if (clickEvent) {
marker.addEventListener('click', clickEvent)
}
addMapOverLay(marker)
return marker
}
/**
* 地图添加自定义面并返回该线对象
* params:
* coordinateList: 面的各点位经纬度数组 格式:[[{ lng: 'lng', lat: 'lat' }], [{ lng: 'lng', lat: 'lat' }]]
* 格式说明:处理面内环情况 外环位置是逆时针定义 内环位置值是顺时针定义
* polylineOption: 面配置项,参考天地图
* clickEvent: 监听点击事件回调
*/
const addMapPolygon = (coordinateList, polygonOption = null, clickEvent = null) => {
let polygon = coordinateList.map((item) => {
return item.map((pointItem) => {
return new T.LngLat(pointItem.lng, pointItem.lat)
})
})
let marker = new T.Polygon(polygon, polygonOption)
if (clickEvent) {
marker.addEventListener('click', clickEvent)
}
addMapOverLay(marker)
return marker
}
/**
* 地图添加自定义窗口并返回窗口对象
* params:
* coordinate: 信息窗口经纬度 格式:'lng,lat'
* infoWindowOption: 信息窗口配置项
* template: 自定义模板组件
* params: 传入组件自定义参数
* clickEvent: 监听点击事件回调
*/
const addMapInfoWindow = (coordinate, infoWindowOption, template, params, clickEvent = null) => {
// 创建虚拟节点并传参
const infoWindowContent = getTemplateNode(template, params)
// 监听组件自定义handleClick事件
clickEvent && infoWindowContent.el.addEventListener('click', clickEvent)
// 创建天地图信息窗口 infoWindowContent.el:test模板dom
let infoWindow = getInfoWindowObj(infoWindowContent.el, coordinate, infoWindowOption)
// 地图添加信息窗口
addMapOverLay(infoWindow)
return infoWindow
}
/**
* 生成一个模板节点并传参
* params:
* template: 自定义模板组件
* params: 传入组件自定义参数
*/
const getTemplateNode = (template, params) => {
// 创建虚拟节点并传参
const infoWindowContent = createVNode(template, params)
let node = document.createElement('div') // 创建一个div节点
render(infoWindowContent, node) // 实例组件挂载到node节点上
return infoWindowContent
}
// 生成信息窗口对象
const getInfoWindowObj = (el, coordinate, infoWindowOption) => {
let lng = coordinate.split(',')[0]
let lat = coordinate.split(',')[1]
let infoWindow = new T.InfoWindow(el, infoWindowOption)
// 设置信息窗口经纬度
infoWindow.setLngLat(new T.LngLat(lng, lat))
return infoWindow
}
// 地图添加覆盖物 obj: 覆盖物对象
const addMapOverLay = (obj) => {
map.addOverLay(obj)
}
// 地图移除覆盖物 obj: 覆盖物对象
const removeMapOverLay = (obj) => {
map.removeOverLay(obj)
}
// 地图移除所有覆盖物
const removeMapAllOverLay = () => {
map.clearOverLays()
}
return {
mapInit,
setMapCenter,
setMapScale,
setMapBounds,
setZoomLevels,
addMapImgOverLay,
addMapMarker,
addMapLine,
addMapPolygon,
addMapInfoWindow,
addMapOverLay,
removeMapOverLay,
removeMapAllOverLay
}
}
引入天地图hooks并初始化地图,以下都为部分关键代码:
<template>
<div id="TdtMap" class="map-div"></div>
</template>
<script setup>
import { useTdtMap } from '@/hooks/useTdtMap'
// 引入
const {
mapInit,
renderArea,
setMapCenter,
setMapScale,
setMapBounds,
setZoomLevels,
addMapImgOverLay,
addMapMarker,
addMapLine,
addMapPolygon,
addMapInfoWindow,
addMapOverLay,
removeMapOverLay,
removeMapAllOverLay
} = useTdtMap('TdtMap')
// 初始化地图
onMounted(() => {
mapInit().then(() => {
// 地图初始化完毕后回调操作
})
})
</script>
<style scoped>
.map-div {
width: 100vw;
height: 100vh;
}
</style>
setMapCenter:手动设置地图平移示例:
setMapCenter('116.40769,39.89945')
setMapScale:手动设置地图中心点及比例尺级别示例:
setMapScale('104.06595,30.57054', 13) // 设置地图缩放
setMapBounds:手动设置地图显示范围示例:
setMapBounds('103.90114,30.49365', '104.23073,30.64736') // 设置地图显示范围
setZoomLevels:手动设置地图显示级别示例:
setZoomLevels(12, 18) // 设置地图级别
addMapImgOverLay:添加地图图片覆盖物示例:
import testImg from '@/assets/image/test.png'
addMapImgOverLay(
'103.8687,30.72825',
'104.27167,30.38782',
testImg,
{
opacity: 100,
alt: ''
}
)
addMapMarker:添加自定义点位并返回该点位对象示例:
import testIcon from '@/assets/image/test.png'
const marker = addMapMarker(
'116.40769,39.89945',
testIcon ,
() => {},
{
iconSize: '30,30',
iconAnchor: '15,30'
}
)
addMapLine:添加自定义线并返回该线对象示例:
const coordinateList = [
{
lng: '116.40769',
lat: '39.89945'
},
{
lng: '116.50769',
lat: '39.99945'
},
{
lng: '116.60769',
lat: '39.79945'
},
{
lng: '116.70769',
lat: '39.69945'
},
{
lng: '116.80769',
lat: '39.59945'
}
]
// 默认线配置
const marker = addMapLine(coordinateList)
addMapPolygon:添加自定义面并返回该面对象示例:
// 蒙层四角 中国四角坐标 外部图层
const smegmaPointList = [
{
lng: '73.0',
lat: '59.0'
},
{
lng: '73.0',
lat: '3.0'
},
{
lng: '136.0',
lat: '3.0'
},
{
lng: '136.0',
lat: '59.0'
},
{
lng: '73.0',
lat: '59.0'
}
]
// 区域范围
const mapCoordinateData = [
{
lng: '104.0325',
lat: '30.56888'
},
{
lng: '104.04353',
lat: '30.56795'
},
{
lng: '104.04375',
lat: '30.53942'
},
{
lng: '104.02315',
lat: '30.53931'
},
{
lng: '104.02164',
lat: '30.54504'
},
{
lng: '104.02542',
lat: '30.55657'
},
{
lng: '104.03053',
lat: '30.56278'
},
{
lng: '104.0325',
lat: '30.56888'
}
]
// 常规画面示例
const marker = addMapPolygon([smegmaPointList])
// 画内环圆示例并配置相关信息
const marker = addMapPolygon(
[smegmaPointList, mapCoordinateData],
{
color: 'black',
weight: 3,
opacity: 0.2,
fillColor: '#0c2940', // 蒙层颜色
fillOpacity: 0.7 // 透明度
},
() => {}
)
addMapInfoWindow:添加自定义信息窗口并返回该窗口对象示例:
// 自定义模块test @/components/test/index.vue
<template>
<div>{{ title }}</div>
<template>
<scropt>
defineProps({
title: {
type: String,
default: ''
}
})
</scropt>
// 自定义信息窗口 关键代码
import TestTemplate from '@/components/test/index.vue'
const infoWindowOption = {
closeButton: false, // 关闭天地图弹框默认关闭图标
offset: new T.Point(0, -15)
}
const infoWindow = addMapInfoWindow('116.40769,39.89945', infoWindowOption, TestTemplate, {
title: '测试文本' })
addMapOverLay:添加覆盖物示例:
addMapOverLay(marker) // marker同上示例
removeMapOverLay:移除覆盖物示例:
removeMapOverLay(marker) // marker同上示例
removeMapAllOverLay:移除天地图所有覆盖物示例:
removeMapAllOverLay()
更多推荐
已为社区贡献3条内容
所有评论(0)