谷歌地图和高德地图JSAPI宝典(Vue2和Vu3通用)

坐标系简介

WGS84:

WGS 84是全球定位系统(GPS)的基准坐标系统,广泛应用于全球定位和导航。它采用十进制度表示经度和纬度。

GCJ02:

中国国家测绘局加密坐标 , 又称为火星坐标系 , 由中国国家测绘局制定的地理坐标系统 , 在中国境内进行定位和地图制作 , 必须使用该坐标。

在中国境内 , 手机获取的 GPS 坐标 , 是 WGS 84 坐标 , 这是准确的坐标 , 但是如果想要显示在地图上的正确位置 , 需要 加入非线性随机偏差中国国家测绘局加密坐标

文档

谷歌文档

文档首页:https://developers.google.com/maps/documentation?hl=zh-cn
JSAPI文档:https://developers.google.com/maps/documentation/javascript?hl=zh-cn
JSAPI示例:https://developers.google.com/maps/documentation/javascript/examples/

高德文档

文档首页:https://lbs.amap.com/api
JSAPI文档:https://lbs.amap.com/api/javascript-api-v2/summary
JSAPI示例:https://lbs.amap.com/demo/list/js-api-v2

安装:

npm install @googlemaps/js-api-loader
npm install @amap/amap-jsapi-loader

代码:

import coordtransform from 'coordtransform'//坐标系转换,高德地图时需要转换经纬度
import { getLanguage} from "@/utils/auth";//根据语言来判断是显示高德地图还是谷歌地图
import { Loader } from '@googlemaps/js-api-loader';
import AMapLoader from "@amap/amap-jsapi-loader";
import point from '@/assets/lockIcon/point.png';
import start from '@/assets/lockIcon/start.png';
import end from '@/assets/lockIcon/end.png';
let map;
let polyline;
let polyEditor;
let markers=[];
let labelsLayer;
let infowindow;
export default {data() {return {isAmap: getLanguage() == "zh",center : getLanguage() == "zh"?[116.397428, 39.90923]:{ lat: 37.7749, lng: 116.397428 },polylineEditable:true,path: [],}},mounted() {this.loadMap();},methods: {/** 构建地图 */async loadGmap (){this.path = [];if(this.isAmap){AMapLoader.reset();await AMapLoader.load({key: 'xxx',version: '2.0',}).then(() => {map = new window.AMap.Map('map-container', {center: this.center,zoom: 15,zooms:[3,20],});map.plugin(['AMap.ToolBar','AMap.Scale','AMap.MapType'],function(){map.addControl(new window.AMap.ToolBar());map.addControl(new window.AMap.Scale());map.addControl(new window.AMap.MapType());});// 添加地图点击事件监听器if(this.isNewVersion()){map.on('click',(e) => {console.log("lat:"+e.lnglat.getLat()+",lng:"+e.lnglat.getLng());// 将点击坐标加入多边形路径if(this.polylineEditable===true){this.path.push([e.lnglat.getLng(), e.lnglat.getLat()]);}this.createLine(this.polylineEditable);console.log('点击地图回调');});}else{window.AMap.event.addListener(map, 'click', (e) => {console.log("lat:"+e.lnglat.getLat()+",lng:"+e.lnglat.getLng());// 将点击坐标加入多边形路径if(this.polylineEditable===true){this.path.push([e.lnglat.getLng(), e.lnglat.getLat()]);}this.createLine(this.polylineEditable);console.log('点击地图回调');});}console.log("加载地图成功");}).catch(e => {console.log("加载地图失败",e);});}else{const loader = new Loader({apiKey: 'xxx',version: 'weekly',language:'en-US',//libraries: ['places'] // 如果需要加载额外的库,比如 'places'});await loader.load().then(() => {map = new google.maps.Map(document.getElementById('map-container'), {center: new google.maps.LatLng(this.center.lat, this.center.lng),zoom: 15,zooms:[3,20],});});map.addListener("click", (event) => {console.log("点击前",this.path)if(this.polylineEditable===true){this.path.push(event.latLng);console.log("点击后",this.path)}this.createLine(this.polylineEditable);console.log('点击地图回调');});console.log("加载地图")}},/** 创建线条 */createLine (editable) {this.clearPolylineByMap();// 创建新的折线if(this.isAmap){polyline = new window.AMap.Polyline({path: this.path,editable: editable,draggable: false,strokeColor: "#009aff",strokeWeight: 3,strokeOpacity: 0.8,});}else{polyline = new google.maps.Polyline({path: this.path,editable: editable,draggable: editable,strokeColor: "#009aff",strokeWeight: 3,strokeOpacity: 0.8,});const googlePath = polyline.getPath();googlePath.addListener('set_at', (event) =>{console.log('Path point updated at index:', event);console.log('Updated path:', googlePath.getArray());let currPath= googlePath.getArray();this.path=[];for (let i = 0; i < currPath.length; i++) {this.path.push(currPath[i]);}console.log("设置",this.path)});googlePath.addListener('insert_at', (event) =>{console.log('Path point inserted at index:', event);console.log('Updated path:', googlePath.getArray());let currPath= googlePath.getArray();this.path=[];for (let i = 0; i < currPath.length; i++) {this.path.push(currPath[i]);}console.log("插入",this.path)});googlePath.addListener('remove_at', (event)=> {console.log('Path point removed at index:', event);console.log('Updated path:', googlePath.getArray());let currPath= googlePath.getArray();this.path=[];for (let i = 0; i < currPath.length; i++) {this.path.push(currPath[i]);}console.log("移除",this.path)});// polyline.addListener("dragend", (event) => {//   let currPath= googlePath.getArray();//   this.path=[];//   for (let i = 0; i < currPath.length; i++) {//     this.path.push(currPath[i]);//   }//   console.log("拖拽",this.path)// });}polyline.setMap(map);if(this.isAmap){//高德地图需要引入PolylineEditor进行编辑if(!editable){return;}map.plugin(['AMap.PolylineEditor'],()=>{polyEditor=new window.AMap.PolylineEditor(map,polyline);polyEditor._selectStyle.strokeColor="#009aff";polyEditor._selectStyle.strokeWeight=3;polyEditor._selectStyle.borderWeight=0;polyEditor.setTarget(polyline);polyEditor.open();// 编辑事件polyEditor.on('addnode',(e)=>{let currPath=polyline.getPath();console.log("添加"+currPath)this.path=[];for (let i = 0; i < currPath.length; i++) {this.path.push([currPath[i].lng, currPath[i].lat]);}});// 编辑事件polyEditor.on('removenode',(e)=>{let currPath=polyline.getPath();console.log("移除"+currPath)this.path=[];for (let i = 0; i < currPath.length; i++) {this.path.push([currPath[i].lng, currPath[i].lat]);}});// 编辑事件polyEditor.on('adjust',(e)=>{let currPath=polyline.getPath();console.log("移动"+currPath)this.path=[];for (let i = 0; i < currPath.length; i++) {this.path.push([currPath[i].lng, currPath[i].lat]);}});});}console.log("创建线条完成");},/** 闭合 */closePolyline () {if (this.path.length < 3) {return;}// 判断路径是否闭合if (this.path[0]==this.path[this.path.length - 1]) {return;}// 添加最后一个点,使路径闭合this.path.push(this.path[0]);this.createLine(true);},/** 清除 */clearPolylineAndPath (){// 清除之前的折线this.path = [];this.clearPolylineByMap();},clearPolylineByMap(){// 移除折线if (polyline) {polyline.setMap(null);}if (polyEditor) {polyEditor.setTarget(null);polyEditor.close();}},/** 根据后台接口经纬度数据显示线条在地图上 */showPolyline (val,editable) {if (val == null || val == "") {return}this.saveId = val.id;if (val.detail == null || val.detail == "" ||!Array.isArray(val.detail) || val.detail.length==0) {return}this.polylineEditable=editable;// 清除之前的折线this.clearPolylineAndPath();// currAreaColor=val.color;let latLngs = [];for (let i = 0; i < val.detail.length; i++) {if(this.isAmap){let gcj02=coordtransform.wgs84togcj02(val.detail[i].lng, val.detail[i].lat);//将坐标系转成高德坐标系latLngs.push({lng:gcj02[0],lat:gcj02[1]});}else{latLngs.push(val.detail[i]);}}for (let i = 0; i < latLngs.length; i++) {if(this.isAmap){this.path.push([latLngs[i].lng, latLngs[i].lat]);}else{this.path.push(new google.maps.LatLng(latLngs[i].lat, latLngs[i].lng))}}this.createLine(editable);this.showMarker(latLngs);if(this.isAmap){map.setFitView();//根据图形自适应缩放级别}else{if(this.path.length>0){var bounds = new google.maps.LatLngBounds();      //声明一个boundsfor(let i=0;i<latLngs.length;i++){bounds.extend(new google.maps.LatLng(latLngs[i].lat, latLngs[i].lng));}map.fitBounds(bounds);//根据图形自适应缩放级别}}},/** 将地图上线条的经纬度数据保存到数据库 */savePolyline() {this.closePolyline();let reqPath = [];//转换数据for (let i = 0; i < this.path.length; i++) {if (this.isAmap) {reqPath.push({lng: this.path[i][0],lat: this.path[i][1]});} else {reqPath.push({lat: this.path[i].lat(),lng: this.path[i].lng()});}}if(reqPath.length<=0){return;}let latLngs= [];for (let i = 0; i < reqPath.length; i++) {if(this.isAmap){let wgs84 = coordtransform.gcj02towgs84(reqPath[i].lng, reqPath[i].lat);//将坐标系还原成GPS通用坐标系latLngs.push({lng: wgs84[0],lat: wgs84[1]});}else{latLngs.push(reqPath[i]);}}updateLatLngs({id:1,latLngs:latLngs}).then(() => {this.$modal.msgSuccess(this.$t('common.updateSuccess'));this.getList();}).finally(() => {this.buttonLoading = false;});},showMarker(data) {if(this.isAmap){console.log("加载点:"+data.length);if (markers && markers.length > 0) {labelsLayer.remove(markers);markers = []}if (data && data.length > 0) {const icon = {type: 'image', // 图标类型,现阶段只支持 image 类型image: point, // 图片 urlsize: [25, 25], // 图片尺寸anchor: 'center' // 图片相对 position 的锚点,默认为 bottom-center};for (let i = 0; i < data.length; i++) {if (data[i].lng && data[i].lat && !(data[i].lng == 0 && data[i].lat == 0)) {data[i].num = i + 1;let marker = new window.AMap.LabelMarker({position: [data[i].lng, data[i].lat],icon: icon,data: data[i],zIndex: 101});marker.on('click', this.markerClick);markers.push(marker);}}// console.log(markers);if (data.length >= 2) {const iconStart = {type: 'image', // 图标类型,现阶段只支持 image 类型image: start, // 图片 urlsize: [30, 33], // 图片尺寸offset: [0, -16.5],anchor: 'center' // 图片相对 position 的锚点,默认为 bottom-center};const iconEnd = {type: 'image', // 图标类型,现阶段只支持 image 类型image: end, // 图片 urloffset: [0, -16.5],size: [30, 33], // 图片尺寸anchor: 'center' // 图片相对 position 的锚点,默认为 bottom-center};let markerStart = new window.AMap.LabelMarker({position: [data[0].lng, data[0].lat],icon: iconStart,data: data[0],zIndex: 102});let markerEnd = new window.AMap.LabelMarker({position: [data[data.length - 1].lng, data[data.length - 1].lat],icon: iconEnd,data: data[data.length - 1],zIndex: 103});markerStart.on('click', this.markerClick);markerEnd.on('click', this.markerClick);markers.push(markerStart);markers.push(markerEnd);}labelsLayer.add(markers);}}else{if (markers && markers.length > 0) {map.remove(markers);}for (let i = 0; i < data.length; i++) {if (data[i].lng && data[i].lat && !(data[i].lng == 0 && data[i].lat == 0)) {data[i].num = i + 1let marker = new google.maps.Marker({position: {lat: data[i].lat, lng: data[i].lng},icon: {url: point,size: new google.maps.Size(28, 28),anchor: new google.maps.Point(14, 14)},zIndex: 101,map: map});markers.push(marker);google.maps.event.addListener(marker, 'click', () => {this.markerClick(null,marker, data[i])});}}if (data.length >= 2) {let markerStart = new google.maps.Marker({position: {lat: data[0].lat, lng: data[0].lng},icon: {url: start,size: new google.maps.Size(60, 66),scaledSize: new google.maps.Size(30, 33),anchor: new google.maps.Point(15, 16.5)},zIndex: 102,map: map});let markerEnd = new google.maps.Marker({position: {lat: data[data.length - 1].lat, lng: data[data.length - 1].lng},icon: {url: end,size: new google.maps.Size(60, 66),scaledSize: new google.maps.Size(30, 33),anchor: new google.maps.Point(15, 16.5)},zIndex: 103,map: map});google.maps.event.addListener(markerStart, 'click', () => {this.markerClick(null,markerStart, data[0])});google.maps.event.addListener(markerEnd, 'click', () => {this.markerClick(null,markerEnd, data[data.length - 1])});markers.push(markerStart);markers.push(markerEnd);}}},async markerClick (e,marker, data){if(this.isAmap){data = e.target._originOpts.data;}let template =`<div style='font-size: 15px'><p style='margin-left: 10px'>No.` + data.num + `</p> <p style='margin-left: 10px'>` + this.$t('map.longitude') + `:` + data.lng + `</p><p style='margin-left: 10px'>` + this.$t('map.latitude') + `:` + data.lat + `</p><p style='margin-left: 10px'>` + this.$t('map.gps_time') + `:` + this.parseTime(data.positionTime, '{y}/{m}/{d} {h}:{i}:{s}') + `</p></div>`;if(this.isAmap){infowindow  = new window.AMap.InfoWindow({content: template});infowindow .open(map, e.lnglat);}else{infowindow.setContent(template);infowindow.open(map, marker);}},}
}

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

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

相关文章

保姆级教程,免费短链平台

神行短链 开源代码: https://github.com/EASTCATV/openShortLink.git 保姆级教程,5分钟打造属于自己的短链 免费短链平台 免费使用 短链生成 免费使用 地址: short.godsdo.com short.godsdo.com 打包命令 sbt clean && sbt packagedocker run -d \ --name shot…

三十六、Python基础语法(JSON操作)

JSON&#xff08;JavaScript Object Notation&#xff09;是一种基于文本&#xff0c;轻量级的数据交换格式。它易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;在自动化测试中经常用来存放测试数据。 JSON的特点&#xff1a; 基于文本&#xff0c;不包含图…

linux基础-完结(详讲补充)

linux基础-完结 一、Linux目录介绍 二、基础命令详细讲解 1. ls&#xff08;列出目录内容&#xff09; 2. cd&#xff08;更改目录&#xff09; 3. clear&#xff08;清除终端屏幕&#xff09; 4. pwd(显示你当前所在的目录) 5. vim(文本编辑器) 6. touch&#xff08;创…

【SAP】关于权限的继承

关于权限的父role和子role的权限继承&#xff0c;既可以 从子role主动去父role那里“取”。从父role“推”到子role 我自己之前一直用的是方法1&#xff0c;但由于子role很多&#xff0c;一个一个手工维护花了不少时间。 后来得知有方法2&#xff0c;特此测试。 我准备了父R…

信息安全数学基础(46)域和Galois理论

域详述 定义&#xff1a; 域是一个包含加法、减法、乘法和除法&#xff08;除数不为零&#xff09;的代数结构&#xff0c;其中加法和乘法满足交换律、结合律&#xff0c;并且乘法对加法满足分配律。同时&#xff0c;域中的元素&#xff08;通常称为数&#xff09;在加法和乘法…

时序约束进阶五:Set_Max_Delay与Set_Min_Delay详解

目录 一、背景 二、Max/Min_delay约束 2.1 约束设置参数 2.2 约束说明 三、场景说明 3.1 路径分段 3.1.1 无效的约束对象 3.1.2 设计代码 3.2 有效的约束对象 3.3 datapath only 3.3.1 工程设计 3.3.2 datapath only报告 3.4 clock group约束优先级 3.4.1 MAX/MIN…

搭建实验仪器知识库:从产品手册到智慧资源的飞跃

在科研、教学及工业生产领域&#xff0c;实验仪器作为探索未知、验证理论、提升效率的重要工具&#xff0c;其重要性不言而喻。然而&#xff0c;随着技术的不断进步和仪器的日益复杂化&#xff0c;如何高效、准确地使用这些仪器成为了科研人员、技术人员及学生面临的共同挑战。…

OA项目 python + vue3

准备工作 创建django项目 在setting.py进行数据库的配置&#xff1a; DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: , #数据库名字USER: , #连接的数据库的用户名PASSWORD: ,HOST: 127.0.0.1,PORT: 3306,} }安装app&#xff1a; rest_framwork: 关闭csrf…

婚礼纪 9.5.57 | 解锁plus权益的全能结婚助手,一键生成结婚请柬

婚礼纪是一款结婚服务全能助手&#xff0c;深受9000万新人信赖的一站式结婚服务平台。解锁plus权益后&#xff0c;用户可以享受部分VIP会员功能。应用提供了丰富的结婚筹备工具和服务&#xff0c;包括一键生成结婚请柬、婚礼策划、婚纱摄影、婚宴预订等。婚礼纪旨在为新人提供全…

树形结构数据

树形结构数据 树形结构数据是一种基础且强大的数据结构&#xff0c;广泛应用于计算机科学和软件开发的各个领域。它模拟了自然界中树的层级关系&#xff0c;通过节点和它们之间的连接来组织数据。在本文中&#xff0c;我们将深入探讨树形结构数据的概念、特点、类型以及它们在…

洛古---越狱问题【快速幂】

今天和大家讲一个洛古的算法题&#xff0c;我觉得还是比较有含金量的&#xff0c;今天给大家分享一下 题目描述 监狱有 &#x1d45b;n个房间&#xff0c;每个房间关押一个犯人&#xff0c;有 &#x1d45a; 种宗教&#xff0c;每个犯人会信仰其中一种。如果相邻房间的犯人的宗…

【论文笔记】Parameter-Efficient Transfer Learning for NLP

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Parameter-Efficient Tran…

《PyTorch深度学习快速入门教程》学习笔记(第20周)

目录 摘要 Abstract 1. 池化层原理 2. 二维池化层 3. 二维最大池化 4. 填充、步幅与多个通道 5. 平均池化层 6. 理论总结 7. 池化层处理数据 8. 池化层处理图片 摘要 本周报的目的在于汇报《PyTorch深度学习快速入门教程》课程第六周的学习成果&#xff0c;主要聚焦于…

C# 实现对指定句柄的窗口进行键盘输入的实现

在C#中实现对指定句柄的窗口进行键盘操作&#xff0c;可以通过多种方式来实现。以下是一篇详细的指南&#xff0c;介绍如何在C#中实现这一功能。 1. 使用Windows API函数 在C#中&#xff0c;我们可以通过P/Invoke调用Windows API来实现对指定窗口的键盘操作。以下是一些关键的…

c语言简单编程练习10

1、typedef和#define的区别 在用作数据类型替换时的区别&#xff1a; #include <stdio.h> #include <unistd.h>typedef char * A; //typedef需要&#xff1b; #define B char *int main(int argc, char *argv[]) {A a,b;B c,d;printf("a_size%ld\n"…

题目讲解15 合并两个排序的链表

原题链接&#xff1a; 合并两个排序的链表_牛客题霸_牛客网 思路分析&#xff1a; 第一步&#xff1a;写一个链表尾插数据的方法。 typedef struct ListNode ListNode;//申请结点 ListNode* BuyNode(int x) {ListNode* node (ListNode*)malloc(sizeof(ListNode));node->…

【freertos】FreeRTOS任务管理

FreeRTOS任务管理 一、任务的创建和删除1、函数xTaskCreate2、函数xTaskCreateStatic3、函数xTaskCreateRestricted4、函数vTaskDelete 二、任务的挂起和恢复1、函数vTaskSuspend2、函数vTaskResume3、函数vTaskResumeFromISR4、函数vTaskSuspendAll5、函数xTaskResumeAll 三、…

FreeRTOS 20:互斥量(互斥信号量)操作

互斥信号量其实就是一个拥有优先级继承的二值信号量&#xff0c;在同步的应用中&#xff08;任务与任务或中断与任务之间的同步&#xff09;二值信号量最适合。互斥信号量适合用于那些需要互斥访问的应用中。在互斥访问中互斥信号量相当于一把钥匙&#xff0c; 当任务想要访问共…

MongoDB笔记03-MongoDB索引

文章目录 一、前言1.1 概述1.2 MongoDB索引使用B-Tree还是BTree&#xff1f;1.3 B 树和 B 树的对比1.4 总结 二、索引的类型2.1 单字段索引2.2 复合索引2.3 其他索引 三、索引的管理操作3.1 索引的查看3.2 索引的创建3.2.1 单字段索引3.2.2 复合索引 3.3 索引的移除3.3.1 指定索…

肿瘤治疗评价指标太多?一文帮你梳理清楚!|个人观点·24-11-09

小罗碎碎念 如何延长癌症患者存活时间、提高生存质量、减轻肿瘤带来的痛苦&#xff0c;是评价抗癌药物的重要标准&#xff0c;而把这些标准落在数据上就诞生了各项“评价指标”。 在肿瘤治疗领域&#xff0c;有OS、PFS、RFS、TTP、TTF、ORR、DCR、DDC等各项评价指标。对于大部…