vue3 +百度地图 实现 地点检索,输入联想,经纬度,逆地理编码,创建标记,label等

news2024/11/13 9:29:09

由于百度地图文档确实有点欠缺,在这里记录一下

    • vue3 + 百度地图(js api 3.0)
    • 实现效果如下
    • 实现方式
    • 注意事项

vue3 + 百度地图(js api 3.0)

  • 需求: 地图弹框组件,可以搜索地图点,输入联想,回车定位等
  • 项目:vue3 + ts + 百度地图js api

实现效果如下

在这里插入图片描述
在这里插入图片描述

实现方式

  • 首先引入百度地图
const loadingBMPGL = (ak: string) => {
	return new Promise(function (resolve, reject) {
		window.init = () => resolve(BMapGL);
		const script = document.createElement('script');
		script.type = 'text/javascript';
		script.src = `https://api.map.baidu.com/api?v=3.0&type=webgl&ak=${ak}&callback=init`;
		script.onerror = reject;
		document.head.appendChild(script);
	});
};
  • 初始化地图实例并监听事件
const initMap = (val: any) => {
	loadingBMPGL(val).then((BMapGL: any) => {
		map = new window.BMapGL.Map('mapContainer');
		// 初始化地图,设置中心点坐标和地图级别
		var ac = new window.BMapGL.Autocomplete({
			//建立一个自动完成的对象
			input: 'searchInput',
			location: map,
		});
		ac.setInputValue(searchData.value);
		ac.addEventListener('onhighlight', function (e) {
			var str = '';
			var value = e.fromitem.value;
			if (e.fromitem.index > -1) {
				str =
					value.province +
					' ' +
					value.city +
					' ' +
					value.district +
					' ' +
					value.street +
					' ' +
					value.business;
			}
			var highlight = 'Suggestion: ' + str;
			document.getElementById('searchInput').placeholder = str;
		});
		ac.addEventListener('onconfirm', function (e) {
			var confirmStr =
				e.item.value.province +
				'/' +
				e.item.value.city +
				'/' +
				e.item.value.district +
				'/' +
				e.item.value.street +
				'/' +
				e.item.value.business;
			const address = {
				name: e.item.value.address,
				address: confirmStr,
				point: e.item.value.location,
			};
			selectResult(address);
			console.log('确认选择: ', e, confirmStr);
		});
		// 以天安门为例
		map.centerAndZoom(new window.BMapGL.Point(116.404, 39.915), 11);
		// 启用地图拖拽事件
		map.enableDragging();
		// 启用地图缩放
		map.enableScrollWheelZoom(true);
		// 监听地图点击事件
		map.addEventListener('click', function (e) {
			// 获取点击位置的坐标
			const point = e.latlng;
			// 清除之前的标记
			if (currentMarker) {
				map.removeOverlay(currentMarker);
			}
			map.clearOverlays();
			// 创建标记并添加到地图上
			currentMarker = new window.BMapGL.Marker(point);
			map.addOverlay(currentMarker);
			map.centerAndZoom(point, 35);
			// geolocation.enableSDKLocation();
			// 创建地理编码服务实例
			const geocoder = new window.BMapGL.Geocoder();
			// 使用地理编码服务获取地址
			geocoder.getLocation(point, function (result) {
				if (result) {
					const address = result.content.address + result.content.poi_desc;
					searchData.value = address;
					lat.value = point.lat;
					lng.value = point.lng;
					// 在点击位置显示信息窗口
					const infoWindow = new window.BMapGL.Label(
						'您点击的位置:' + address + '<br>' + '经纬度:' + point.lng + ',  ' + point.lat
					);
					infoWindow.setStyle({
						color: 'black',
						fontSize: '14px',
						backgroundColor: 'white',
						border: '1px solid #ccc',
						padding: '2px',
					});
					currentMarker.setLabel(infoWindow);
				} else {
					console.log('未找到该位置的地址');
				}
			});
		});
		// 0: 成功。表示搜索请求成功,并且结果可以通过 result 对象进行获取和处理。
		// 1: 没有找到匹配的结果。表示搜索关键字没有匹配到任何地点。
		// 2: 请求被拒绝。可能是由于权限问题或请求格式不正确。
		// 3: API 密钥无效。表示使用的 API 密钥不正确或已过期。
		// 4: 发生了未知错误。表示出现了无法预料的问题。

		localSearch.value = new window.BMapGL.LocalSearch(map, {
			// renderOptions: { map: map },
			onSearchComplete: function (result) {
				if (localSearch.value.getStatus() === 0) {
					if (result._pois.length != 0) {
						console.log('Search completed:', localSearch.value, result);
						searchResults.value = result._pois.map(poi => {
							return {
								id: poi.uid,
								name: poi.title,
								address: poi.address,
								point: poi.point,
							};
						});
					}
				} else {
					console.log('Search failed:', result, localSearch.value.getStatus());
				}
			},
		});
		// 初始化搜索一次
		// searchLocation(searchData.value);
	});
};

其实这里有两种方式实现;

  1. 其一是使用BMapGL.Autocomplete 创建一个自定义对象,需要一个input框来绑定输入框,还有一个地图的区域
<div class="map-container" id="mapContainer" ref="mapContainer"></div>
			<div class="search-box">
				<el-input
					id="searchInput"
					ref="searchdom"
					style="width: 250px"
					v-model="searchData"
					placeholder="搜索地点"
				>
					<!-- @input="searchLocation" -->
					<template #suffix>
						<img class="search-icon" src="@/assets/img/water-works/search.png" alt="" />
					</template>
				</el-input>
				<!-- 显示搜索结果列表 -->
				<!-- <div class="search-list" v-if="searchResults.length">
					<ul>
						<li v-for="result in searchResults" :key="result.id" @click="selectResult(result)">
							<span style="padding: 12px 7px"> {{ result.name }}</span>
						</li>
					</ul>
				</div> -->
			</div>

这里需要注意的是:需要单独设置一下搜索结果列表的层级,不然会遮挡导致看不见,要去掉style标签的 scoped,这样的话重写的css样式才能生效。

.tangram-suggestion {
	z-index: 99999;
}

onhighlightonconfirm 分别设置监听输入联想和选择搜索结果的事件,可以在回调中设置需要的操作

  1. 第二种就是利用BMapGL.LocalSearch 方法,也就是localSearch.value
在输入框上设置  `@input="searchLocation"`
const searchLocation = (keyword: any) => {
	localSearch.value.search(keyword);
};
调用BMapGL.LocalSearch 的回调方法 给searchResults.value 赋值然后将上面的搜索列表注释放开就可以在选中事件中做相应操作,如:
const selectResult = (result: any) => {
	console.log(result);
	// 清空搜索结果列表
	searchResults.value = [];
	// 清空搜索框
	searchData.value = result.address;
	// 获取搜索结果
	const poi = result.point;
	// 在地图上标记位置
	markerPosition.value = poi;
	lat.value = poi.lat;
	lng.value = poi.lng;
	// const icon = new window.BMapGL.Icon('@/assets/img/water-works/marker.svg', new window.BMapGL.Size(20, 20));
	// icon.setImageSize(new window.BMapGL.Size(32,32));
	// const marker = new window.BMapGL.Marker(poi,{ icon: icon });
	const marker = new window.BMapGL.Marker(poi);
	// 创建标签
	const label = new window.BMapGL.Label(
		'名称:' + result.name + '<br>' + '经纬度:' + poi.lng + ',  ' + poi.lat,
		{
			offset: new window.BMapGL.Size(20, -10), // 调整标签位置
		}
	);
	label.setStyle({
		color: 'black',
		fontSize: '14px',
		backgroundColor: 'white',
		border: '1px solid #ccc',
		padding: '2px',
	});
	// 将标签添加到标记
	marker.setLabel(label);
	map.addOverlay(marker);
	map.centerAndZoom(poi, 35);
};

注意事项

  1. vue3 和ts项目中没有直接的BMapGL 对象,所以挂在了Window下面
  2. 注意修改结果列表的层级z-index

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2118685.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

算法-双指针技巧

文章目录 算法概述奇偶数字归位寻找重复数字接雨水救生艇问题 算法概述 设置两个指针的技巧&#xff0c;其实这种说法很宽泛&#xff0c;似乎没什么可总结的 有时候所谓的双指针技巧&#xff0c;就单纯是代码过程用双指针的形式表达出来而已。 没有单调性(贪心)方面的考虑有时…

基于Python的网络编程

现代的应用程序都离不开网络&#xff0c;网络编程是非常重要的技术。Python提供了两个不同层次的网络编程API&#xff1a;基于Socket的低层次网络编程和基于URL的高层次网络编程。Sockrt采用TCP、UDP等协议&#xff0c;这些协议属于低层次的通信协议&#xff1b;URL采用HTTP和H…

4G工业路由器:SR700的智能连接解决方案

在现代工业环境中&#xff0c;网络连接的稳定性和速度是确保生产效率和数据安全的关键。SR700 4G工业路由器凭借其卓越的性能和多样的功能&#xff0c;成为了工业自动化和物联网应用中的理想选择。本文将详细介绍SR700的产品特点&#xff0c;并结合一个真实的项目案例&#xff…

网络传输的基本流程

目录 0.前言 1.TCP/IP四层协议模型的认识 2.数据传输的大致流程 3.局域网通信的原理 4.同一网段下两台主机之间的通信 5.不同网段下两台主机之间的通信 0.前言 不知道你有没有这样的疑问&#xff0c;为什么不同的设备之间能够进行数据的发送和接收&#xff1f;不同的通信…

小米嵌入式面试题目RTOS面试题目 嵌入式面试题目

第一章-非RTOS bootloader工作流程 MCU启动流程 通信协议&#xff0c;SPI IIC MCU怎么选型&#xff0c;STM32F1和F4有什么区别 外部RAM和内部RAM区别&#xff0c;怎么分配 外部总线和内部总线区别 MCU上的固件&#xff0c;数据是怎么分配的 MCU启动流程 IAP是怎么升级的…

​​MEPA(Maximum Efficiency Per Ampere)控制

一.控制目的 与MTPA控制相比&#xff0c;没有忽略电机的铁耗&#xff0c;以电能损耗最小为目的优化电流。 分析思路与MTPA控制类似&#xff0c;在此省略。 二. 推导过程

【前端】读取csv文件,将数据转换为对象。spilce与slice的区别

一. 解决思路 解决思路&#xff1a;将csv文件的第一行作为key&#xff0c;后续的每一行作为value存入对象数组。 二. 代码写法 2 .1 JS写法 2.1.1 数组.map(function(item, index,arr){}) Item: 这个表示的是每一项对应的索引。 index: 这个表示的是每一项对应的索引。 a…

LTE PSS主同步信号PSS搜索阶段频偏估计

频偏的影响: 本期要讲到PSS搜索阶段,整数倍频偏和小数倍频偏的估计方法,整数倍频偏指的是子载波间隔的整数倍比如15k、30k等,小数倍频偏指的是一个子载波间隔以内的。在OFDM通信系统中,频偏是一个比较敏感的词,正常如果频偏估不准会带来一系列的问题,比如OFDM信号的正交…

高校大模型实验室大模型应用平台

大模型应用平台是一款专为高校大模型应用场景教学和科研打造的知识库问答系统。该平台易于使用&#xff0c;知识库支持常见的txt、doc、pdf、md等数据文件上传&#xff0c;同时提供了简洁易懂的操作配置界面&#xff0c;使用户可以轻松地搭建和训练AI应用&#xff0c;并快速进行…

Selenium:设置元素等待、上传文件、下载文件

前言&#xff1a;在工作和学习selenium自动化过程中记录学习知识点&#xff0c;深化知识点 1. 设置元素等待 元素定位之元素等待-- WebDriver提供了两种类型的等待&#xff1a;显示等待和隐式等待。 1.1 显示等待 显式等待使WebDriver等待某个条件处理时继续执行&#xff…

mycat双主高可用架构部署-mycat安装

MySQL5.7服务器IP是192.168.31.209及192.168.31.210 1、安装Java运行环境 ELK搭建日志平台里面有Java安装&#xff0c;同样也可以采用yum安装 yum install -y java java -version 2、下载并解压mycat wget http://dl.mycat.org.cn/1.6.7.6/20220524101549/Mycat-server-1.…

支小宝来了!支付宝AI生活管家,让AI帮你“干活“

众所周知&#xff0c;支付宝界面越来越复杂&#xff0c;从最初的一个支付工具逐渐演变成了一个综合性的平台&#xff0c;涵盖了生活中的各个方面。 功能的增加的同时不可避免的就会导致使用不便。 随着大模型的应用&#xff0c;支付宝基于百灵大模型推出了“支小宝”AI生活管家…

盘点4款比pr剪辑简单的视频剪辑工具。

PR剪辑软件对于很多不太懂剪辑的人来说确实有点不太好操作&#xff0c;需要去学习一些剪辑知识使用比较好。如果想要在短时间内掌握一些剪辑技巧&#xff0c;可以选择相对简单一点的剪辑工具。比如下面这4款&#xff0c;不管是新手还是会剪辑的人都可以使用。 1、福昕高效剪辑 …

超有趣,小白专用的python基础到大师人工智能教程!

2017年7月&#xff0c;国务院发布的《新一代人工智能发展规划》提出&#xff0c;要在中小学阶段设置人工智能相关课程&#xff0c;并逐步推广编程教育。 Python 是一种通用型编程语言&#xff0c;它具有良好的可扩展性和适应性&#xff0c;易于学习&#xff0c;被广泛应用于云计…

适合Python练手的8个经典项目,有趣又实用,提升Python编程能力必看!

今天给大家分享的&#xff0c;是一些实战练习的小案例&#xff0c;如果你还是Python小白&#xff0c;可以再看看我前面几篇文章&#xff0c;如果是有了一点基础&#xff0c;那就尝试完成下面这些案例吧&#xff01; 这里插播一条粉丝福利&#xff0c;如果你在学习Python或者有…

阿卡迈 Akamai 逆向分析4 代码分拆3

阿卡迈函数解析10_获取EET数值.js // 这个值如果代码刷新了会变化 EHpvmPAvvbSFFBR7gXeSMA // 后续考虑如何自动化 window global Th \x1F\x0FBA\rw!6M\x03h6\x18\x18\x15\x05P8B3\rz\\\x06 //会变化// 直接在浏览器copy出来的值错误\n会解析错误 // Th "BA\n"…

用户缓冲区

目录 1. 引入问题2. 用户缓冲区2.1 解答上述问题2.2 缓冲区刷新策略 3. 全缓冲案例 1. 引入问题 // 输出信息带换行&#xff0c;调用完后close(1) int main() { const char* s1 "this is fwrite\n"; …

数据手套横向对比:4款手套哪款适合您?

数据手套是与虚拟物体交互、记录手部动作以及制作手部动画的重要工具。数据手套根据类别可分为只传输动作数据的数据手套&#xff0c;拥有触觉震动反馈的触觉手套&#xff0c;带有外骨骼的力反馈手套等。这些手套根据功能性的不同可分别应用于不同行业之中&#xff0c;在本文中…

【项目功能扩展】在线网站 -用户管理功能(用户注册登录修改等、利用cookie存储用户会话状态)

文章目录 0. 前言开发环境 & 涉及技术 1. 宏观结构2. 后端部分① sqlite 管理类② user 管理类 3. 前端部分&#xff08;与后端交互&#xff09;① 登录② 注册③ 查看登录用户的信息④ 更新用户信息⑤ 登出用户 & 注销用户注意 效果演示 0. 前言 源码链接&#xff1a…

【Unity】简易而又实用的概率算法

1.两个数中任选一个&#xff08;抛硬币&#xff09; 基础版本&#xff1a; public int RandomBetweenTwoNumber(int a,int b) {float random Random.Range(0,1f);return radom<0.5f ? a : b ; } 升级版本&#xff08;支持概率调整&#xff09;&#xff1a; /*pa表示“…