一、打开天地图官网
2.在控制台中申请需要的key
3.申请key步骤-创建新应用-应用类型选择浏览器端
二、代码部分
在index.html主文件中引入
<script src="https://api.tianditu.gov.cn/api?v=4.0&tk=你申请的key"></script>
组件文件map.vue 弹出框采用 ant-design-vue 中 a-modal
//map.vue组件
<template>
<a-modal v-model:open="open"
title="选择地址"
width="800px"
:footer="null"
@cancel="closeAddress">
<el-select v-model="searchText"
filterable
remote
placeholder="请输入关键词"
:remote-method="remoteMethod"
@change="changeAddress"
:clearable="true"
style="width: 500px">
<el-option v-for="(item,index) in searchResults"
:key="item.index"
:label="item.name"
:value="item.lonlat"
class="one-text">
<span style="float: left">{{ item.name }}</span>
<span style="float: right; color: #8492a6; font-size: 13px">{{
item.address
}}</span>
</el-option>
<template #empty>
<span class="right-btn">
<el-button size="small"
@click="searchBtn">点击搜索</el-button>
</span>
</template>
</el-select>
<div class="container w" style="position: relative">
<div class="blur-background" v-if="!sureSelAddress"></div>
<div id="map"
class="map radius-md"
style="width: 100%; height: 500px;"></div>
</div>
<div>
<el-button @click="closeAddress">取消</el-button>
<el-button @click="sureAddress">确定</el-button>
</div>
</a-modal>
</template>
<script setup>
import { nextTick } from "vue";
import { message } from 'ant-design-vue';
const map = ref(null);
const lng = ref(117.226367);
const lat = ref(39.089812);
const open = ref(false);
const emit = defineEmits(['change'])
const openModel = () => {
open.value = true;
// keywords.value = ''
nextTick(() => {
initMap();
});
};
let geocoder = null;
let localsearch = null;
let geocode = null;
const intText = ref("");
const searchResults = ref([]);
const initMap = () => {
intText.value = ''
searchText.value = ''
sureSelAddress.value = null
const T = window.T;
// // 坐标
map.value = new T.Map("map");
let point = new T.LngLat(lng.value, lat.value);
map.value.centerAndZoom(point, 10);
// 禁止鼠标滚动缩小放大
// map.value.disableScrollWheelZoom();
// 添加控件
//创建缩放平移控件对象
let control = new T.Control.Zoom();
// control.setPosition(T_ANCHOR_TOP_RIGHT);
//添加缩放平移控件
map.value.addControl(control);
map.value.clearOverLays();
let marker = new T.Marker(point);
map.value.addOverLay(marker);
// 初始化本地搜索服务
// 初始化本地搜索服务
geocoder = new T.Geocoder();
//创建逆解析解析对象
geocode = new T.Geocoder();
var config = {
pageCapacity: 10, //每页显示的数量
onSearchComplete: localSearchResult, //接收数据的回调函数
};
//创建搜索对象
localsearch = new T.LocalSearch(map.value, config);
if(searchText.value) {
addMarker(searchText.value)
}
};
const localSearchResult = (result) => {
//清空地图及搜索列表
clearAll();
//解析建议词信息
suggests(result.getSuggests());
};
//搜索结果
const suggests = (data) => {
console.log(data,'data')
if (Array.isArray(data)) {
searchResults.value = data;
} else {
searchResults.value = [];
searchText.value = ''
}
};
const clearAll = () => {
map.value.clearOverLays();
};
const closeAddress = () => {
open.value = false;
// closeMap()
};
const searchText = ref("");
const remoteMethod = async (query) => {
if (query) {
intText.value = query;
localsearch.search(query, 4);
} else {
searchResults.value = [];
}
};
const changeAddress = (item) => {
addMarker(item);
};
// 地图添加标注
const addMarker = (item) => {
let point = []
if(typeof item == 'string') {
point = item.split(",");
}
const pointObj = {
lat: point[1],
lng: point[0],
};
map.value.panTo(pointObj, 16);
//创建标注对象
var marker = new T.Marker(pointObj);
//向地图上添加标注
map.value.addOverLay(marker);
nijiexi(point)
};
// 逆解析地址,保持选择地址统一
const nijiexi = (point) => {
const newData = new T.dq();//创建标注对象
newData.lat = point[1];
newData.lng = point[0];
geocode.getLocation(newData, analysis);
}
const searchBtn = () => {
map.value.clearOverLays();
geocoder.getPoint(intText.value, searchResult);
};
const searchResult = (result) => {
if (result.getStatus() == 0) {
map.value.panTo(result.getLocationPoint(), 20);
//创建标注对象
var marker = new T.Marker(result.getLocationPoint());
//向地图上添加标注
map.value.addOverLay(marker);
geocode.getLocation(result.getLocationPoint(), analysis);
} else {
alert(result.getMsg());
}
};
const sureSelAddress = ref(null)
const analysis = (result) => {
console.log(result,'result')
sureSelAddress.value = result
}
const clickItem = (item) => {
// 向父组件传值
emit("change", {
address: item.addressComponent.province + item.addressComponent.county + item.addressComponent.address,
lat: item.location.lat,
lng: item.location.lon,
});
open.value = false
};
const sureAddress = () => {
if(!sureSelAddress.value) return message.error('请选择地址')
clickItem(sureSelAddress.value)
}
defineExpose({
openModel,
});
</script>
<style scoped lang="scss">
@import "@/assets/styles/userSideGlobal.scss";
.right-btn {
:deep(.el-button) {
background: $main-color;
color: #fff;
letter-spacing: 1px;
border: none;
}
}
.blur-background {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backdrop-filter: blur(10px);
z-index: 999;
border-radius: 14px;
}
</style>
在需要用到的地方引入该组件 我的组件地址路径为@/components/map/tdt/map.vue
import Map from '@/components/map/tdt/map.vue'
<template>
<div>
<el-button @click="$refs.mapRef.openModel()">打开天地图</el-button>
<Map ref="mapRef"
@change="sureAddress"></Map>
</div>
</template>
<script setup>
import Map from '@/components/map/tdt/map.vue'
const mapRef = ref(null);
const sureAddress = (item) => {
//item中包含经纬度以及地址信息
console.log(item)
};
</script>
三、1.案例图片打开之后遮罩层是自己添加的,因为浏览器获取不到当前定位
2.搜索