天地图(uniapp)搜索、定位自己、获取标记点的经纬度

发布于:2025-02-14 ⋅ 阅读:(10) ⋅ 点赞:(0)

参考文章

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>