基于高德地图JS API实现Vue地图选点组件

news2024/11/18 2:31:09

基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能,同时可以进行回显

目录

  • 1 创建key和秘钥
    • 1.1 登录高德地图开放平台
    • 1.2 创建应用
    • 1.3 绑定服务创建秘钥
  • 2 使用组件前准备
    • 2.1 导入loader
    • 2.2 在对应的组件设置秘钥
    • 2.3 引入css样式
  • 3 功能实现
    • 3.1 初始化地图
    • 3.2 增加搜索功能
    • 3.3 暴露增加标记函数
  • 4 全部代码
  • 5 实现效果

1 创建key和秘钥

1.1 登录高德地图开放平台

打开开放平台地址

注册账号 或 申请账号

1.2 创建应用

在这里插入图片描述

1.3 绑定服务创建秘钥

在这里插入图片描述

在这里插入图片描述

2 使用组件前准备

2.1 导入loader

推荐pnpm

pnpm i @amap/amap-jsapi-loader -D

2.2 在对应的组件设置秘钥

<script type="text/javascript" lang="ts">
window._AMapSecurityConfig = {
  securityJsCode: "安全秘钥"
};
</script>

2.3 引入css样式

<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />

3 功能实现

3.1 初始化地图

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";

let map = null;
let aMap = null;
onMounted(() => {
  AMapLoader.load({
    key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }).then(AMap => {
    // 第一参数是对应的div的id
    map = new AMap.Map("container", {
      // 设置地图容器id
      viewMode: "3D", // 是否为3D地图模式
      zoom: 11, // 初始化地图级别
      center: [116.397428, 39.90923] // 初始化地图中心点位置
    });
    aMap = AMap;
  });
});
onUnmounted(() => {
  map?.destroy();
});
</script>
<template>
  <div id="map-box">
    <div id="container" />
    
  </div>
</template>
<style scoped>
#map-box {
  width: 100%;
  height: 450px;
  position: relative;
}
#container {
  width: 100%;
  height: 100%;
}

#myPageTop {
  position: absolute;
  top: 5px;
  right: 10px;
  font-family: "Microsoft Yahei", Pinghei;
  font-size: 14px;
  background: none 0px 0px repeat scroll rgb(255, 255, 255);
  border-width: 1px;
  border-style: solid;
  border-color: rgb(204, 204, 204);
  border-image: initial;
  margin: 10px auto;
  padding: 6px;
}
#panel {
  background-color: white;
  max-height: 400px;
  overflow-y: auto;
}
</style>

3.2 增加搜索功能

function search() {
  const placeSearch = new aMap.PlaceSearch({
    pageSize: 10, // 单页显示结果条数
    pageIndex: 1, // 页码
    map: map, // 展现结果的地图实例
    panel: "panel", // 结果列表将在此容器中进行展示。
    autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
  });
  //关键字查询
  placeSearch.search(keyword.value);
  placeSearch.on("selectChanged", function (e) {
    const data = e.selected.data;
    const temp = {
      province: data.pname,
      provinceCode: data.pcode,
      city: data.cityname,
      cityCode: data.citycode,
      county: data.adname,
      countyCode: data.adcode,
      storeAddr: data.address,
      storeDetailAddr: data.pname + data.cityname + data.adname + data.address,
      longitude: `${data.location.lng}`,
      latitude: `${data.location.lat}`
    };
    // 回调父组件
    emit("change", temp);
  });
}
// 宏注册emit
const emit = defineEmits(["change"]);

const keyword = ref("");
<template>
  <div id="map-box">
    <div id="container" />
    <!-- 增加的部分 -->
    <div id="myPageTop">
      <el-input
        @keyup.enter="search"
        placeholder="请输入地址"
        v-model="keyword"
      >
        <template #prepend>
          <el-button :icon="Search" @click="search" />
        </template>
      </el-input>
      <div id="panel" />
    </div>
  </div>
</template>

3.3 暴露增加标记函数

let loaded = false; // 判断地图是否完成渲染
const record = []; // 记录地图未加载完成之前的添加标签记录
// 循环渲染之前记录的地址
function loadRecord() {
  record.forEach(item => {
    addMarker(item.longitude, item.latitude, item.content);
  });
}
function addMarker(longitude: number, latitude: number, content: string) {
  if (!loaded) {
    record.push({ longitude, latitude, content });
    return;
  }
  if (!longitude || !latitude) return;
  const marker = new aMap.Marker({
    position: [longitude, latitude],
    icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
    anchor: "bottom-center",
    offset: new aMap.Pixel(0, 0)
  });

  marker.setMap(map);
  marker.setTitle(content);
  // 设置label标签
  // label默认蓝框白底左上角显示,样式className为:amap-marker-label
  marker.setLabel({
    direction: "bottom",
    offset: new aMap.Pixel(0, 0), //设置文本标注偏移量
    content: `<div style='padding:1px 5px;'>${content}</div>` //设置文本标注内容
  });
  map.setZoomAndCenter(11, [longitude, latitude]); //同时设置地图层级与中心点
}
defineExpose({
  addMarker
});

4 全部代码

<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />
<script type="text/javascript" lang="ts">
window._AMapSecurityConfig = {
  securityJsCode: "秘钥"
};
</script>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";

let map = null;
let aMap = null;
let loaded = false;
const record = []; // 记录地图未加载完成之前的添加标签记录
onMounted(() => {
  AMapLoader.load({
    key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }).then(AMap => {
    // 第一参数是对应的div的id
    map = new AMap.Map("container", {
      // 设置地图容器id
      viewMode: "3D", // 是否为3D地图模式
      zoom: 11, // 初始化地图级别
      center: [116.397428, 39.90923] // 初始化地图中心点位置
    });
    aMap = AMap;
    // 地图加载完成后会触发此回调函数
    loaded = true;
    loadRecord();
  });
});
onUnmounted(() => {
  map?.destroy();
});
// 循环渲染之前记录的地址
function loadRecord() {
  record.forEach(item => {
    addMarker(item.longitude, item.latitude, item.content);
  });
}
function addMarker(longitude: number, latitude: number, content: string) {
  if (!loaded) {
    record.push({ longitude, latitude, content });
    return;
  }
  if (!longitude || !latitude) {
  	console.error("缺少必要信息")
  	return;
  }
  const marker = new aMap.Marker({
    position: [longitude, latitude],
    icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
    anchor: "bottom-center",
    offset: new aMap.Pixel(0, 0)
  });

  marker.setMap(map);
  marker.setTitle(content);
  // 设置label标签
  // label默认蓝框白底左上角显示,样式className为:amap-marker-label
  marker.setLabel({
    direction: "bottom",
    offset: new aMap.Pixel(0, 0), //设置文本标注偏移量
    content: `<div style='padding:1px 5px;'>${content}</div>` //设置文本标注内容
  });
  map.setZoomAndCenter(11, [longitude, latitude]); //同时设置地图层级与中心点
}
defineExpose({
  addMarker
});
function search() {
  const placeSearch = new aMap.PlaceSearch({
    pageSize: 10, // 单页显示结果条数
    pageIndex: 1, // 页码
    map: map, // 展现结果的地图实例
    panel: "panel", // 结果列表将在此容器中进行展示。
    autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
  });
  //关键字查询
  placeSearch.search(keyword.value);
  placeSearch.on("selectChanged", function (e) {
    const data = e.selected.data;
    const temp = {
      province: data.pname,
      provinceCode: data.pcode,
      city: data.cityname,
      cityCode: data.citycode,
      county: data.adname,
      countyCode: data.adcode,
      storeAddr: data.address,
      storeDetailAddr: data.pname + data.cityname + data.adname + data.address,
      longitude: `${data.location.lng}`,
      latitude: `${data.location.lat}`
    };
    // 回调父组件
    emit("change", temp);
  });
}
const emit = defineEmits(["change"]);

const keyword = ref("");
</script>

<template>
  <div id="map-box">
    <div id="container" />
    <!-- 增加的部分 -->
    <div id="myPageTop">
      <el-input
        @keyup.enter="search"
        placeholder="请输入地址"
        v-model="keyword"
      >
        <template #prepend>
          <el-button :icon="Search" @click="search" />
        </template>
      </el-input>
      <div id="panel" />
    </div>
  </div>
</template>

<style scoped>
#map-box {
  width: 100%;
  height: 450px;
  position: relative;
}
#container {
  width: 100%;
  height: 100%;
}

#myPageTop {
  position: absolute;
  top: 5px;
  right: 10px;
  font-family: "Microsoft Yahei", Pinghei;
  font-size: 14px;
  background: none 0px 0px repeat scroll rgb(255, 255, 255);
  border-width: 1px;
  border-style: solid;
  border-color: rgb(204, 204, 204);
  border-image: initial;
  margin: 10px auto;
  padding: 6px;
}
#panel {
  background-color: white;
  max-height: 400px;
  overflow-y: auto;
}
</style>

5 实现效果

回显效果,会自动设置到地图中心
在这里插入图片描述
选点效果
在这里插入图片描述

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

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

相关文章

【C语言】整型提升与算术转换

一、表达式求值 在我们平常的表达式求值的题目中&#xff0c;虽然看似是道很简单的题目&#xff1b;但是出题人总是会埋坑&#xff0c;其中最常见的就是整型提升与算术转换。 二、整型提升 C语⾔中整型算术运算总是⾄少以缺省(默认)整型(int)类型的精度来进⾏的&#xff1b;…

【MySQL基础】MySQL基础操作二

文章目录 &#x1f34e;1.数据库约束&#x1f350;约束类型&#x1f346;1.1NOT NULL&#x1f346;1.2UNIQUE&#x1f346;1.3DEFAULT&#x1f346;1.4PRIMARY KEY&#x1f346;1.5FOREIGN KEY &#x1f34f;2.查询操作&#x1f35f;2.1聚合查询&#x1f354;2.1.1聚合函数&…

视频号电商的风口来了!这个消息还有多少人不知道?

大家好&#xff0c;我是电商糖果 短视频做电商&#xff0c;这几年的热度真的是非常高&#xff0c;就是因为热度太高了&#xff0c;才让视频号也动了电商的心思。 腾讯推出的视频号是为了和抖音对打&#xff0c;这几年靠着微信输送的流量&#xff0c;视频号的日活已经渐渐有赶…

JavaSE-----认识异常【详解】

目录 一.异常的概念与体系结构&#xff1a; 1.1异常的概念&#xff1a; 1.2一些常见的异常&#xff1a; 1.3异常的体系结构&#xff1a; 1.4异常的分类&#xff1a; 二.异常的处理机制&#xff1a; 2.1 抛出异常&#xff1a; 2.2异常的捕获&#xff1a; 2.3try-catch-&…

JavaWeb一些开发问题

一、Restful package com.example.crudtest1.pojo;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data NoArgsConstructor AllArgsConstructor public class Result {private Integer code;//响应码&#xff0c;1 代表成功; 0 代表失…

浅易理解:卷积神经网络(CNN)

浅易理解卷积神经网络流程 本文的目录&#xff1a; 1 什么卷积神经网络 2 输入层 3 卷积层 4 池化层 5 全连接层 传统的多层神经网络只有 输入层、隐藏层、输出层 卷积神经网络&#xff08;CNN)&#xff1a; 在多层神经网络的基础上&#xff0c;加入了更加有效的特征学习部分…

315曝光黑灰产业链:主板机

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 315晚会曝光主板机黑灰产业链&#xff0c;主板机是什么呢?可能很多人还不知道。在这里松松给大家普及一下&#xff0c;也欢迎大家关注卢松松哟! 主板机是什么呢? 通过报废手机的主板&#xff0c;拆出来后组装成主…

【Linux进程状态】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、直接谈论Linux的进程状态 看看Linux内核源代码怎么说 1.1、R状态 -----> 进程运行的状态 1.2、S状态 -----> 休眠状态(进程在等待“资源”就绪) 1.3、T状…

NFTScan 正式上线 Blast NFTScan 浏览器和 NFT API 数据服务

2024 年 3 月 15 号&#xff0c;NFTScan 团队正式对外发布了 Blast NFTScan 浏览器&#xff0c;将为 Blast 生态的 NFT 开发者和用户提供简洁高效的 NFT 数据搜索查询服务。NFTScan 作为全球领先的 NFT 数据基础设施服务商&#xff0c;Blast 是继 Bitcoin、Ethereum、BNBChain、…

Linux 系统调用函数fork、vfork、clone详解

文章目录 1 fork1.1 基本介绍1.2 fork实例1.2.1多个fork返回值1.2.2 C语言 fork与输出1.2.3 fork &#x1f4a3; 2 vfork2.1 基本介绍2.2 验证vfork共享内存 3 clone3.1 基本介绍3.2 clone使用 1 fork 1.1 基本介绍 #include <sys/types.h> #include <unistd.h>p…

2024年【危险化学品经营单位主要负责人】找解析及危险化学品经营单位主要负责人模拟考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 危险化学品经营单位主要负责人找解析考前必练&#xff01;安全生产模拟考试一点通每个月更新危险化学品经营单位主要负责人模拟考试题目及答案&#xff01;多做几遍&#xff0c;其实通过危险化学品经营单位主要负责人…

Grok的开源的一些想法

Grok是埃隆马斯克的人工智能团队开发的大模型&#xff0c;自马斯克发布消息称将开源大模型&#xff0c;其热度就居高不下。Grok的开源能迅速帮助国内建立起AI应用的能力。 从xAI公布的数据来看&#xff0c;Grok在主流的测试方法中均已超过GPT-3.5&#xff0c;而其是开源发展速度…

如何使用Python进行数据可视化:Matplotlib和Seaborn指南【第123篇—Matplotlib和Seaborn指南】

如何使用Python进行数据可视化&#xff1a;Matplotlib和Seaborn指南 数据可视化是数据科学和分析中不可或缺的一部分&#xff0c;而Python中的Matplotlib和Seaborn库为用户提供了强大的工具来创建各种可视化图表。本文将介绍如何使用这两个库进行数据可视化&#xff0c;并提供…

高可用系统有哪些设计原则

1.降级 主动降级&#xff1a;开关推送 被动降级&#xff1a;超时降级 异常降级 失败率 熔断保护 多级降级2.限流 nginx的limit模块 gateway redisLua 业务层限流 本地限流 gua 分布式限流 sentinel 3.弹性计算 弹性伸缩—K8Sdocker 主链路压力过大的时候可以将非主链路的机器给…

性能测试工具——wrk的安装与使用

前言 想和大家来聊聊性能测试&#xff0c;聊到了性能测试必须要说的是性能测试中的工具&#xff0c;在这些工具中我今天主要给大家介绍wrk。 ​介绍 wrk是一款开源的性能测试工具 &#xff0c;简单易用&#xff0c;没有Load Runner那么复杂&#xff0c;他和 apache benchmar…

【Unity】读取Json的三种方法(JsonUtility,LitJson,Newtonsoft)

介绍 在Unity开发过程中&#xff0c;Json是比较常用的一种数据存储文本&#xff0c;尤其是在和第三方交互中&#xff0c;基本都是json格式。 先给出一个Json示例&#xff0c;我们来看看是如何解析的。 {"Player": [{"id": 1001,"name": "…

Linux网络编程: IP协议详解

一、TCP/IP五层模型 物理层&#xff08;Physical Layer&#xff09;&#xff1a;物理层是最底层&#xff0c;负责传输比特流&#xff08;bitstream&#xff09;以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流&#xff0c;例如通过电缆、光纤或无线传输等。…

湖南麒麟SSH服务漏洞

针对湖南麒麟操作系统进行漏洞检测时&#xff0c;会报SSH漏洞风险提醒&#xff0c;具体如下&#xff1a; 针对这些漏洞&#xff0c;可以关闭SSH服务&#xff08;前提是应用已经部署完毕不再需要通过SSH远程访问传输文件的情况下&#xff0c;此时可以通过VNC远程登录方法&#x…

RocketMQ学习笔记四(黑马)项目

课程地址&#xff1a; 1.Rocket第二章内容介绍_哔哩哔哩_bilibili &#xff08;视频35~88&#xff0c;搭建了一个电商项目&#xff09; 待学&#xff0c;待完善。

linux网络服务学习(1):nfs

1.什么是nfs NFS&#xff1a;网络文件系统。 *让客户端通过网络访问服务器磁盘中的数据&#xff0c;是一种在linux系统间磁盘文件共享的方法。 *nfs客户端可以把远端nfs服务器的目录挂载到本地。 *nfs服务器一般用来共享视频、图片等静态数据。一般是作为被读取的对象&…