参考文章
https://blog.csdn.net/m0_67350312/article/details/138578174
https://blog.csdn.net/weixin_36152801/article/details/145037991
天地图接口文档
需求
1、获取某个位置经纬度
2、这个位置,可以通过搜索获取。例如搜索“天安门”,打点并获取其坐标
3、允许手动打点,因为天地图的搜索并不全面
4、可以导航到指定点(能用就行,天地图不好做实时导航,只能弄个样子)
5、之所以用天地图,就是因为免费。公司没有高德这种5w一年的商用服务(已经被高德书面警告过一次,不敢再搞了)
注:原本想做页面内的导航,但h5定位不准+天地图的导航没有高德的好(大家已经用惯了),多少有落差。所以就不做了
最终效果预览(uniapp移动端)
定位页面效果(locate.vue)
uniapp天地图
代码(uniapp移动端)
index.html
<script src="https://api.tianditu.gov.cn/api?v=4.0&tk=你的天地图key"></script>
config.js
export default {
// 系统名称
name: "xxxxxx",
...接口配置,
tiandimap_key: '你的天地图key',
defaultLng: 116.40969,
defaultLat: 38.89945
}
locate.vue
有个算距离的km,我注释掉了,没用上
<template>
<view class="container">
<u-navbar back-text="返回" title="企业定位"></u-navbar>
<view id="mapDiv" style="width: 100%; height: 50%;"></view>
<view class="btn-groups">
<u-input v-model="searchText" :border="true" maxlength="20" placeholder="输入企业名搜索" />
<view class="btn" @click="search()">搜索</view>
<view class="btn" @click="locateMyself()">定位自己</view>
<view class="btn" @click="comfirm()">确定</view>
</view>
<view id="result" style="margin: 20px;"></view>
</view>
</template>
<script>
import config from '@/config.js'
export default {
data() {
return {
searchText: '',
longitude: null,
latitude: null,
localsearch: null,
myCurrentLongitude: null,
myCurrentLatitude: null,
map: null
}
},
onReady() {
// 页面加载完成后初始化地图
this.initMap();
},
methods: {
initMap() {
// 引入天地图API脚本
const script = document.createElement('script');
script.src = "http://api.tianditu.gov.cn/api?v=4.0&tk=" + config.tiandimap_key; // 替换为你的天地图密钥
script.onload = () => {
this.createMap();
};
document.body.appendChild(script);
},
createMap() {
// 初始化地图
this.map = new T.Map('mapDiv');
this.map.centerAndZoom(new T.LngLat(config.defaultLng, config.defaultLat), 11); // 设置中心点和缩放级别
// 添加点击事件监听
this.map.addEventListener('click', (event) => {
this.map.clearOverLays(); // 清空全部覆盖物
const lngLat = event.lnglat; // 获取点击位置的经纬度
this.longitude = lngLat.getLng()
this.latitude = lngLat.getLat()
console.log('经度:', lngLat.getLng(), '纬度:', lngLat.getLat());
//创建标注对象
var marker = new T.Marker(new T.LngLat(lngLat.getLng(), lngLat.getLat()));
//向地图上添加标注
this.map.addOverLay(marker);
});
//创建搜索对象
this.localsearch = new T.LocalSearch(this.map, {
pageCapacity: 10, //每页显示的数量
onSearchComplete: this.localSearchResult //接收数据的回调函数
})
},
comfirm() {
if (!this.longitude || !this.latitude) {
this.$toast('请先选择一个位置,再点【确定】')
return null
}
// TODO 用接口保存经纬度信息
},
search() {
if (!this.searchText) {
this.$toast('请先输入内容')
return null
}
this.localsearch.search(this.searchText, 4)
},
// 接收数据的回调函数
localSearchResult(result) {
//清空地图及搜索列表
this.clearAll()
//解析建议词信息
this.suggests(result.getSuggests())
},
clearAll() {
// map.clearOverLays()
document.getElementById("result").innerHTML = ""
document.getElementById("result").style.display = "none"
},
//解析建议词信息
suggests(obj) {
console.log(obj)
if (obj) {
//建议词提示,如果搜索类型为公交规划建议词或公交站搜索时,返回结果为公交信息的建议词。
var divMarker = document.createElement("div");
// // let km = this.getDistance(this.myCurrentLatitude, this.myCurrentLongitude, lonlatarr[1], lonlatarr[0])
// suggestsHtml += ` <li data-lat=${lonlatarr[1]} data-lon=${lonlatarr[0]}>
// <a class='dizhiname' data-lat=${lonlatarr[1]} data-lon=${lonlatarr[0]}>${obj[i].name}</div>
// <div class='dizhichengshi' data-lat=${lonlatarr[1]} data-lon=${lonlatarr[0]}>${obj[i].address}</div>
// </li>`
// }
const that = this
for (let i = 0; i < obj.length; i++) {
(function(i) {
let a = document.createElement("a")
a.href = "javascript://"
a.innerHTML = `${obj[i].name}(${obj[i].address})`
a.onclick = function() {
that.map.clearOverLays(); // 清空全部覆盖物
let lngLat = obj[i].lonlat.split(',')
//创建标注对象
var marker = new T.Marker(new T.LngLat(lngLat[0], lngLat[1]));
that.longitude = lngLat[0];
that.latitude = lngLat[1];
//向地图上添加标注
that.map.addOverLay(marker);
that.map.centerAndZoom(new T.LngLat(lngLat[0], lngLat[1]), 15)
}
divMarker.appendChild(document.createTextNode((i + 1) + ". "))
divMarker.appendChild(a)
divMarker.appendChild(document.createElement("br"))
})(i)
}
document.getElementById("result").appendChild(divMarker)
document.getElementById("result").style.display = "block"
} else {
document.getElementById("result").style.display = "block"
document.getElementById("result").innerHTML = '未查到信息'
}
},
// 定位自己(不太准)
locateMyself() {
const that = this
that.map.clearOverLays();
var lo = new T.Geolocation();
const fn = function(e) {
if (this.getStatus() == 0) {
that.map.centerAndZoom(e.lnglat, 15)
var marker = new T.Marker(e.lnglat);
that.map.addOverLay(marker);
}
if (this.getStatus() == 1) {
that.map.centerAndZoom(e.lnglat, e.level)
var marker = new T.Marker(e.lnglat);
that.map.addOverLay(marker);
}
}
lo.getCurrentPosition(fn);
},
//计算距离
/**
* 通过经纬度获取两点距离
* @param lat1lng1
* @param lat2lng2
* @returns 距离单位 km
*/
getDistance(lat1, lng1, lat2, lng2) {
const radLat1 = (lat1 * Math.PI) / 180.0
const radLat2 = (lat2 * Math.PI) / 180.0
const a = radLat1 - radLat2
const b = (lng1 * Math.PI) / 180.0 - (lng2 * Math.PI) / 180.0
let s =
2 *
Math.asin(
Math.sqrt(
Math.pow(Math.sin(a / 2), 2) +
Math.cos(radLat1) *
Math.cos(radLat2) *
Math.pow(Math.sin(b / 2), 2)
)
)
s *= 6378.137 // EARTH_RADIUS;
s = Math.round(s * 100) / 100
return s // 调用 return的距离单位为km
}
}
};
</script>
<style lang="scss" scoped>
.container {
// display: flex;
// justify-content: center;
// align-items: center;
height: 100%;
background-color: #fff;
.btn-groups {
display: flex;
.btn {
display: flex;
justify-content: center;
align-items: center;
color: #1890FF;
background-color: #fff;
border: 1rpx solid #1890FF;
border-radius: 10rpx;
font-size: 30rpx;
text-align: center;
width: 150rpx;
}
}
}
</style>