Vue3引入高德地图js API 2.0

2024-04-23 1170阅读

文章目录

  • 前言
  • 一、地图加载
    • 1.本文准备环境
    • 2.引入库
    • 3.加载地图
    • 4.加载地图控件
    • 二、POI搜索
      • 1.什么是poi搜索
      • 2.如何使用
      • 三、绘制点标记与信息窗体
        • 1.场景描述
        • 2.案例
        • 3.信息窗体-链接路由跳转
        • 4.进阶-通过Marker自动触发标记点(非鼠标手动点击)
        • 四、jsApi地图事件
          • 1.官方解释
          • 2.用法

            前言

            本文主要由地图加载、POI检索、绘制点标记、信息窗体、信息窗体中链接的路由跳转、相关事件的使用几部分组成。

            目前网上关于高德js API的文章大多数是vue2.0版本的,这篇文章是基于vue3.0的,我的写法不一定是主流写法,如果有更好的写法,请评论中指正,感谢🙏🙏🙏


            一、地图加载

            1.本文准备环境

            • node 和 git - 项目开发环境
            • pnpm - 速度快、节省磁盘空间的软件包管理器
            • Vite
            • Vue3
            • TypeScript
            • Es6+
            • Vue-Route
            • 高德开发者-获取key和安全密钥
            • 高德JSApi手册
            • 高德JSApi教程
            • 高德JSApi示例

              2.引入库

              代码如下(示例):

              npm i @amap/amap-jsapi-loader --save
              

              3.加载地图

              
              
                
              window._AMapSecurityConfig = {securityJsCode: '准备环境阶段拿到的的安全密钥'} // 引入jsApi 地图Loader import AMapLoader from '@amap/amap-jsapi-loader'; let map = null; onMounted(() => { AMapLoader.load({ key: "", // 申请好的Web端开发者Key,首次调用 load 时必填 version: "2.0", // 指定要加载的 JSAPI 的版本 plugins: ["AMap.Scale", "AMap.ToolBar"], //(按需引用,pc端建议加入AMap.ToolBar,便于操作)需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...'] }) .then((AMap) => { // 加载地图到id为container的容器中 map = new AMap.Map("container", { viewMode: "2D", // 设置地图视图类型,2D / 3D zoom: 11, // 初始化地图级别 center: [116.397428, 39.90923], // 初始化地图中心点位置 }); }) .catch((e) => { console.log(e); }); }); onUnmounted(() => { map?.destroy(); }); // 设置地图容器的大小 #container{ padding:0px; margin: 0px; width: 100%; height: 800px; }

              4.加载地图控件

              
              	// ··· 相关代码已省略
              	let map = null;
              	onMounted(() => {
              	  AMapLoader.load({
              	    key: "", 
              	    version: "2.0",
                      plugins: ["AMap.Scale", "AMap.ToolBar"], //(按需引用,pc端建议加入AMap.ToolBar,便于操作)需要使用的的插件列表,如比例尺'AMap.Scale',支持添加多个如:['...','...']
                	  })
              	    .then((AMap) => {
              	      // 加载地图到id为container的容器中
              	      map = new AMap.Map("container", {
              	        viewMode: "2D", // 设置地图视图类型,2D / 3D
              	        zoom: 11, // 初始化地图级别
              	        center: [116.397428, 39.90923], // 初始化地图中心点位置
              	      });
              	
              		  // 地图加载后,可以加载地图控件。
              		  // 如:创建工具条插件实例。需要在AMapLoader.plugins中引入控件,并map.addControl添加到地图中
              	      var toolbar = new AMap.ToolBar();
              	      map.addControl(toolbar);
              	    })
              	    .catch((e) => {
              	      console.log(e);
              	    });
              	});
              	
              	onUnmounted(() => {
              	  // 页面关闭后及时销毁资源
              	  map?.destroy();
              	});
              
              

              二、POI搜索

              1.什么是poi搜索

              poi检索是高德的地理信息查询服务,即通过关键字获取目标地理信息(如坐标,城市信息等)。其中包含输入提示插件AMap.AutoComplete和POI 搜索插件 AMap.PlaceSearch,如图显示,右上角通过JAC获取多个地点提示信息即输入提示插件,选择匹配信息后,POI 搜索插件会返回多个相关的地理信息,并在地图上添加标记点。

              Vue3引入高德地图js API 2.0

              2.如何使用

                
              // ··· 相关代码已省略 let map = null; onMounted(() => { AMapLoader.load({ key: "", version: "2.0", }) .then((AMap) => { // ··· // map = ··· // 输入提示, var autoOptions = { // 可选参数,你的搜索输入框dom的id(多数场景下只需要这一个参数即可) input: 'keyword', // 可选参数,你的搜索输出框dom的id,用来展示提示的结果(默认的只有图里的文字,如果需要图片等,需要指定output) output: 'your_out_put_id', // 是否强制指定城市,设定city后有效 citylimit: false, // 输入提示时限定城市。可选值:城市名(中文或中文全拼)、citycode、adcode;默认值:“全国” city: '北京', // 默认为true,表示是否在input位于页面较下方的时候自动将输入面板显示在input上方以避免被遮挡 outPutDirAuto:true, // ···其他参数请翻阅文档 }; AMap.plugin(['AMap.PlaceSearch', 'AMap.AutoComplete'], function () { //无需再手动执行 search 方法,autoComplete 会根据传 input 对应的 DOM 动态触发 search var autoComplete = new AMap.AutoComplete(autoOptions); var placeSearch = new AMap.PlaceSearch({ map: map, type: '', // 数据类别 pageIndex: 1, pageSize: 10, }); // 注册监听,当选中某条记录时会触发 autoComplete.on('select', select); function select(e) { // 获取到检索提示信息后,根据提示信息搜索精确地理位置 // 设置查询城市(防止查提示信息所在城市之外的城市) placeSearch.setCity(e.poi.adcode); // 检索地理信息 placeSearch.search(e.poi.name, function (status, result) { // 获取查询到的结果 if (status == 'complete' ){ // 精确地理信息为多条,placeSearch会将地理位置全部添加为地图Marker,如果需要触发点击时获取指定Marker的地理信息,可以添加markerClick事件 console.log(result.poiList.pois); placeSearch.on('markerClick', function(e) { // e.data中即为poi信息(=result.poiList.pois[i]) console.log(e.data) // 当前点击的地图的marker console.log(e.marker) }) } }); } }); }) .catch((e) => { console.log(e); }); }); onUnmounted(() => { // 页面关闭后及时销毁资源 map?.destroy(); });

              一些进阶功能:如指定区域内搜索,指定圆范围搜索,请翻阅高德JSApi教程


              三、绘制点标记与信息窗体

              1.场景描述

              如需要在地图上展示营业网点位置,查看所有设备的定位位置等,需要根据定位物件的坐标,在地图上添加一个标记。

              仅有标记仅仅只能看到所在位置,但是用户是看不到具体这个位置是哪个营业网点(或哪个设备),则需要添加信息窗体来展示当前定位的相关信息。

              Vue3引入高德地图js API 2.0

              2.案例

              注意:绘制点标记与信息窗体都需要指定锚点,具体锚点设置请翻阅高德JSApi教程

                
              // ··· 相关代码已省略 let map = null; onMounted(() => { AMapLoader.load({ key: "", version: "2.0", }) .then((AMap) => { // ··· // map = ··· // 通过mock数据or后端接口获取到的地理位置信息(如营业网点信息,设备定位信息) const mapInfos = await getMapIfo(); // 信息窗体 var infoWindow = new AMap.InfoWindow({ anchor: 'bottom-center', // 信息窗体锚点 offset: new AMap.Pixel(0, -32), //设置点标记偏移量(设置锚点) // 点击地图关闭 closeWhenClickMap: true, // 是否自定义窗体(默认窗体即示例图中效果,底色与边框样式是固定的) isCustom: false, }); // 通用 icon(即示例图中Marker红色的样式) const icon = new AMap.Icon({ size: new AMap.Size(25, 34), //图标尺寸 image: '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png', //Icon 的图像 imageSize: new AMap.Size(25, 34), //根据所设置的大小拉伸或压缩图片 }); // 编辑mapInfos,绘制点标记 mapInfos.forEach((mapInfo) => { // 拿不到完整的坐标信息,则不绘制 if (mapInfo.lng == 0 && mapInfo.lat == 0) { return; } // 创建点标记对象 const marker = new AMap.Marker({ position: new AMap.LngLat(mapInfo.lng, mapInfo.lat), //经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9] icon: icon, offset: new AMap.Pixel(-12.5, -34), //设置点标记偏移量(锚点) }); // 给点标记添加点击事件,点击Marker打开信息窗体 marker.on('click', function (e) { // 点击时获取逆地理编码(由于后端/Mock中拿到的数据为lnglat坐标,用户更想看到的是具体地理位置信息,所以每次点击的时候获取逆地理编码) AMap.plugin('AMap.Geocoder', async function () { var geocoder = new AMap.Geocoder(); var lnglat = [mapInfo.lng, mapInfo.lat]; await geocoder.getAddress(lnglat, function (status, result) { let region = ''; if (status === 'complete' && result.info === 'OK') { // result为对应的地理位置详细信息 region = result.regeocode.formattedAddress; } //实例化信息窗体 const content = `` + region + ``; // 设置信息窗体的内容(dom) infoWindow.setContent(content); // 展示面板,将相关的信息加载到面板中 infoWindow.open(map, [mapInfo.lng, mapInfo.lat]); }); }); }); // 把marker加载到map中 map.add(marker); }); }) .catch((e) => { console.log(e); }); }); onUnmounted(() => { // 页面关闭后及时销毁资源 map?.destroy(); });

              3.信息窗体-链接路由跳转

              上节案例中,可见content的写法是没办法使用vue路由的,vue2.0时还可以使用Vue.extend()去实现,但是vue3.0移除了这个方法,所以考虑在template中写好这个窗体,并加载到marker中,上案例:

                
              {{contentParam.region}} 查看详情-->
              // 获取当前组件的实例对象 const {proxy} = getCurrentInstance(); const contentParam = reactive({ region: '', }) // ··· 相关代码已省略 let map = null; onMounted(() => { AMapLoader.load({ key: "", version: "2.0", }) .then((AMap) => { // ··· // map = ··· // 信息窗体 var infoWindow = new AMap.InfoWindow({ offset: new AMap.Pixel(0, -32), //设置点标记偏移量 // 点击地图关闭 closeWhenClickMap: true, // 当前例子中,重新设计了info窗体,去掉了官方默认窗体的关闭按钮,所以需要开启自定义窗体 isCustom: true, }); // mapInfos.forEach((mapInfo) // const marker = ··· // 将页面当前组件实例中ref='content'的实例绑定到marker.content marker.content = proxy.$refs.content; marker.on('click', function (e) { // 点击时获取逆地理编码 AMap.plugin('AMap.Geocoder', async function () { // 信息框加载出来 var geocoder = new AMap.Geocoder(); var lnglat = [equipmentInfo.lng, equipmentInfo.lat]; await geocoder.getAddress(lnglat, function (status, result) { let region = ''; if (status === 'complete' && result.info === 'OK') { // result为对应的地理位置详细信息 region = result.regeocode.formattedAddress; } contentParam.region = region; contentParam.detailNo = mapInfo.detailNo; // content信息从marker.content中获取 infoWindow.setContent(e.target.content); // 展示面板,将相关的信息加载到面板中 infoWindow.open(map, e.target.getPosition()); }); }); }); }) .catch((e) => { console.log(e); }); }); onUnmounted(() => { // 页面关闭后及时销毁资源 map?.destroy(); }); function toDetail(detailNo) { router.push({ path: '/detail', query: { detailNo: detailNo } }); } .amap-info-sharp, .amap-info-sharp:after { margin-left: -8px; border-left: 8px solid transparent; border-right: 8px solid transparent; } .amap-info-sharp { bottom: 0; left: 50%; border-top: 8px solid #fff; }

              4.进阶-通过Marker自动触发标记点(非鼠标手动点击)

              在第三节案例中,实现了点击窗体中的链接,通过路由跳转到其他vue页面。

              如果打开页面的时候,携带了某个设备信息(or营业网点),想主动打开对应Marker的信息窗体,该怎么做?

              以下为实现案例:

                
              const options = ref([]); // ··· 相关代码已省略 let map = null; onMounted(() => { AMapLoader.load({ key: "", version: "2.0", }) .then((AMap) => { // ··· // map = ··· mapInfos.forEach((mapInfo) => { // 拿不到完整的坐标信息,则不绘制 if (mapInfo.lng == 0 && mapInfo.lat == 0) { return; } // 创建点标记对象 // const marker = ··· // 把marker加载到map中 options.value.push({ label: mapInfo.detailNo, value: marker }); map.add(marker); }); }) .catch((e) => { console.log(e); }); }); onUnmounted(() => { // 页面关闭后及时销毁资源 map?.destroy(); }); function selectDetail(marker) { if(marker) { // 主动触发marker的click事件 marker.emit('click',{ target: marker }); } } .amap-info-sharp, .amap-info-sharp:after { margin-left: -8px; border-left: 8px solid transparent; border-right: 8px solid transparent; } .amap-info-sharp { bottom: 0; left: 50%; border-top: 8px solid #fff; }

              四、jsApi地图事件

              1.官方解释

              jsApi地图事件是对Map底图操作后触发的事件,事件回调中返回MapsEvent对象。该对象包含触发的对象目标、触发所在经纬度等信息。

              2.用法

              	// 在 2.0 版本中所有类型的实例均使用 on/off 方法进行事件的绑定和移除
              	// 给地图绑定click事件
              	map.on("click", function (ev) {
              	  //触发事件的对象
              	  var target = ev.target;
              	  //触发事件的地理坐标,AMap.LngLat 类型
              	  var lnglat = ev.lnglat;
              	  //触发事件的像素坐标,AMap.Pixel 类型
              	  var pixel = ev.pixel;
              	  //触发事件类型
              	  var type = ev.type;
              	});
              
              

              高德地图大部分实例都拥有不少事件,如前三章中用到了以下三种事件,来丰富我们的业务,让地图操作更合理。

              	// poi输入提示插件绑定select事件,选中某项提示后触发的事件
              	autoComplete.on('select', function(e) {});
              	// poi搜索插件绑定markerClick事件,点击地图中placeSearch生成的Marker触发的事件
              	placeSearch.on('markerClick', function(e) {});
              	
              	// 为绘制的点标记绑定click事件,点击点标志触发的事件(我们用来打开信息窗体)
              	marker.on('click', function(e) {});
              
              

              而有一些特殊的场景下,可能需要我们主动触发事件,则需要用到emit函数。如上章末位,主动触发Marker的click事件,来模拟点击Marker。

              	// 第一个参数为事件的类型, 第二个参数为事件回调时返回的数据
              	// 比如案例中要主动触发主动触发Marker的click事件,第一个参数即为click,第二个参数为marker本身,用来获取绑定在marker上的content的
              	marker.emit('click',{target: marker});
              	
              	// 回顾一下marker的click事件的内容
              	marker.content = proxy.$refs.content;
              	
              	marker.on('click', function (e) {
              	  // ···
              	  
              	  // 这里,e.target即对应第二个参数的target
              	  infoWindow.setContent(e.target.content);
              	  infoWindow.open(map, e.target.getPosition());
              	});
              	
              
              

              高德地图的事件,我们可以从高德JSApi手册中查找。

              Vue3引入高德地图js API 2.0

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]