uniapp腾讯地图JavaScript Api,H5端和原生APP端可用

news2024/11/17 19:51:27

        因项目需要,在uniapp中集成使用腾讯地图,为了方便维护,希望通过一套代码实现H5和APP同时可用。H5显示相对简单,APP端比较麻烦,记录下实现过程

一、集成步骤

1.使用 renderjs

script标签使用renderjs,因为JavaScript Api需要调用DOM对象,APP需要使用renderjs技术,保证script运行在webview环境,才能调用DOM对象。

<script lang="renderjs" module="test">
</script>

2.引用地图script


导入腾讯地图JS脚本,因为腾讯地图js不是按照uniapp格式编写,所以不能直接import导入,需要包装成一个js插件,使用 Promise,js加载成功,调用resolve,js加载失败,调用reject。

创建loadJs.js 文件

function loadJs(src) {
  return new Promise((resolve,reject)=>{
    let script = document.createElement('script');
    script.type = "text/javascript";
    script.src= src;
    document.body.appendChild(script);
      
    script.onload = ()=>{
      resolve();
    }
    script.onerror = ()=>{
      reject();
    }
  }).catch((e) => {})
}
 
export default loadJs


在页面中使用

<script lang="renderjs" module="test">
    import loadJs from "../../common/loadJs.js"
    
    export default {

        data() {
            return {
                
            }
        },
        mounted(){
            console.log('renderjs初始化完毕')
            loadJs('https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77').then(()=>{
                // 加载成功,进行后续操作
            })
        },
         methods: {
        }
    }
</script>

3.修改js,兼容uniapp

下载腾讯官网的例子,改造成uniapp兼容的格式。有两种方式,

方式一:

将官网例子中 script 封装成一个个的function,定义在 vue文件的 methods 中,这样就可以直接调用。

方式二:

将官网例子中 script 代码全部拷贝到一个js文件中,再把需要调用的 function 通过 export 关键字导出,在vue文件中进行 import 调用。

4.修改监听事件

腾讯官网例子都是web端的,点击事件都是click,H5端运行需要改成touchend,否则点击无响应

Web端

svg.addEventListener('click', this.onClick); web端用click事件

H5端

svg.addEventListener('touchend', this.onClick); // H5端用touchend事件

二、示例

腾讯官网例子

以自定义覆盖物 -> DOMOverlay 为例,实操下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>DOMOverlay</title>
</head>
<script charset="utf-8" src="https://map.qq.com/api/gljs?libraries=tools&v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"></script>
<style type="text/css">
    html,
    body {
        height: 100%;
        margin: 0px;
        padding: 0px;
    }

    #container {
        width: 100%;
        height: 100%;
    }
</style>

<body onload="initMap()">
	<div id="container"></div>
	<script>
		var SVG_NS = 'http://www.w3.org/2000/svg';
		// 自定义环状饼图 - 继承DOMOverlay
		function Donut(options) {
			TMap.DOMOverlay.call(this, options);
		}

		Donut.prototype = new TMap.DOMOverlay();

		// 初始化
		Donut.prototype.onInit = function(options) {
			this.position = options.position;
			this.data = options.data;
			this.minRadius = options.minRadius || 0;
			this.maxRadius = options.maxRadius || 50;
		};

		// 销毁时需解绑事件监听
		Donut.prototype.onDestroy = function() {
			if (this.onClick) {
				this.dom.removeEventListener(this.onClick);
			}
		};

		// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
		Donut.prototype.createDOM = function() {
			let svg = document.createElementNS(SVG_NS, 'svg');
			svg.setAttribute('version', '1.1');
			svg.setAttribute('baseProfile', 'full');

			let r = this.maxRadius;
			svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' '));
			svg.setAttribute('width', r * 2);
			svg.setAttribute('height', r * 2);
			svg.style.cssText = 'position:absolute;top:0px;left:0px;';

			let donut = createDonut(this.data, this.minRadius, this.maxRadius);
			svg.appendChild(donut);
          
          	// click事件监听
          	this.onClick = () => {
				// DOMOverlay继承自EventEmitter,可以使用emit触发事件
				this.emit('click');
			};
			// pc端注册click事件,移动端注册touchend事件
          	svg.addEventListener('click', this.onClick);
			return svg;
		};

		// 更新DOM元素,在地图移动/缩放后执行
		Donut.prototype.updateDOM = function() {
			if (!this.map) {
				return;
			}

			// 经纬度坐标转容器像素坐标
			let pixel = this.map.projectToContainer(this.position);

			// 使饼图中心点对齐经纬度坐标点
			let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
			let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
			this.dom.style.transform = `translate(${left}, ${top})`;
		};

		// 使用SVG创建环状饼图
		function createDonut(data, minRadius, maxRadius) {
			const colorList = [
				'#7AF4FF',
				'#67D7FF',
				'#52B5FF',
				'#295BFF'
			];
			let sum = data.reduce((prev, curr) => prev + curr, 0);
			let angle = 0;

			let group = document.createElementNS(SVG_NS, "g");
			data.forEach((d, i) => {
				let delta = d / sum * Math.PI * 2;
					color = colorList[i],
					r = maxRadius,
					startAngle = angle,
					endAngle = angle + delta;
				angle += delta;

				// 对每个数据创建一个扇形
				let fanShape = document.createElementNS(SVG_NS, 'path');
				fanShape.setAttribute('style', `fill: ${color};`);
				fanShape.setAttribute('d', [
					'M0 0',
					`L${r * Math.sin(startAngle)} ${-r * Math.cos(startAngle)}`,
					`A${r} ${r} 0 ${delta > Math.PI ? 1 : 0} 1 ${r * Math.sin(endAngle)} ${-r * Math.cos(endAngle)}`,
				].join(' ') + ' z');
				group.appendChild(fanShape);
			});

			// 在中心创建一个圆形
			let circleShape = document.createElementNS(SVG_NS, 'circle');
			circleShape.setAttribute('style', 'fill: #FFFFFF');
			circleShape.setAttribute('cx', 0);
			circleShape.setAttribute('cy', 0);
			circleShape.setAttribute('r', minRadius);
			group.appendChild(circleShape);

			// 绘制文字
			let textShape = document.createElementNS(SVG_NS, 'text');
			textShape.setAttribute('x', 0);
			textShape.setAttribute('y', '0.3em');
			textShape.setAttribute('text-anchor', 'middle');
			textShape.innerHTML = sum;
			group.appendChild(textShape);

			return group;
		}

		window.Donut = Donut;
	</script>
	<script type="text/javascript">
		var map;
        function initMap() {
            // 初始化地图
            map = new TMap.Map("container", {
                zoom:12, // 设置地图缩放级别
                center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
			});

			let donutList = [
				new Donut({
					map,
					position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
					data: [12, 24],
					minRadius: 13,
					maxRadius: 20
				}),
				new Donut({
					map,
					position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
					data: [23, 99, 101, 400],
					minRadius: 25,
					maxRadius: 35
				}),
				new Donut({
					map,
					position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
					data: [18, 41, 50],
					minRadius: 20,
					maxRadius: 28
				})
			];

			donutList.forEach((donut, index) => {
				donut.on('click', () => {
					console.log(`第${index}个环形图被点击,位置为${donut.position}`);
				});
			});
		}
    </script>
</body>

</html>

适配后uniapp代码

主要三个文件 DOMOverlay.js、loadJs.js、map.vue

DOMOverlay.js 

一般来说先把script 全部复制到一个单独js文件,然后直接运行,运气好直接正常使用,运气不好就哪里报错改哪里,DOMOverlay.js文件修改过我都加了注释“适配uniapp修改过的”

var SVG_NS = 'http://www.w3.org/2000/svg';
// 自定义环状饼图 - 继承DOMOverlay
function Donut(options) {
	TMap.DOMOverlay.call(this, options);
}


/** 
 * ----------------适配uniapp修改过的----------------
 * 
 * 因为 TMap 对象依赖于 https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77 
 * 所以要封装一个方法,在加载完依赖脚本后,再运行
 */
function initDonut(){
	Donut.prototype = new TMap.DOMOverlay();
	
	// 初始化
	Donut.prototype.onInit = function(options) {
		this.position = options.position;
		this.data = options.data;
		this.minRadius = options.minRadius || 0;
		this.maxRadius = options.maxRadius || 50;
	};
	
	// 销毁时需解绑事件监听
	Donut.prototype.onDestroy = function() {
		if (this.onClick) {
			this.dom.removeEventListener(this.onClick);
		}
	};
	
	// 创建DOM元素,返回一个DOMElement,使用this.dom可以获取到这个元素
	Donut.prototype.createDOM = function() {
		let svg = document.createElementNS(SVG_NS, 'svg');
		svg.setAttribute('version', '1.1');
		svg.setAttribute('baseProfile', 'full');
	
		let r = this.maxRadius;
		svg.setAttribute('viewBox', [-r, -r, r * 2, r * 2].join(' '));
		svg.setAttribute('width', r * 2);
		svg.setAttribute('height', r * 2);
		svg.style.cssText = 'position:absolute;top:0px;left:0px;';
	
		let donut = createDonut(this.data, this.minRadius, this.maxRadius);
		svg.appendChild(donut);
	  
		// click事件监听
		this.onClick = () => {
			// DOMOverlay继承自EventEmitter,可以使用emit触发事件
			this.emit('click');
		};
		// ----------------适配uniapp修改过的----------------
		// pc端注册click事件,移动端注册touchend事件
		// svg.addEventListener('click', this.onClick); web端用click事件
		svg.addEventListener('touchend', this.onClick); // H5端用touchend事件
		return svg;
	};
	
	// 更新DOM元素,在地图移动/缩放后执行
	Donut.prototype.updateDOM = function() {
		if (!this.map) {
			return;
		}
	
		// 经纬度坐标转容器像素坐标
		let pixel = this.map.projectToContainer(this.position);
	
		// 使饼图中心点对齐经纬度坐标点
		let left = pixel.getX() - this.dom.clientWidth / 2 + 'px';
		let top = pixel.getY() - this.dom.clientHeight / 2 + 'px';
		this.dom.style.transform = `translate(${left}, ${top})`;
	};
}

// 使用SVG创建环状饼图
function createDonut(data, minRadius, maxRadius) {
	const colorList = [
		'#7AF4FF',
		'#67D7FF',
		'#52B5FF',
		'#295BFF'
	];
	let sum = data.reduce((prev, curr) => prev + curr, 0);
	let angle = 0;

	let group = document.createElementNS(SVG_NS, "g");
	data.forEach((d, i) => {
		let delta = d / sum * Math.PI * 2;
			let color = colorList[i],
			r = maxRadius,
			startAngle = angle,
			endAngle = angle + delta;
		angle += delta;

		// 对每个数据创建一个扇形
		let fanShape = document.createElementNS(SVG_NS, 'path');
		fanShape.setAttribute('style', `fill: ${color};`);
		fanShape.setAttribute('d', [
			'M0 0',
			`L${r * Math.sin(startAngle)} ${-r * Math.cos(startAngle)}`,
			`A${r} ${r} 0 ${delta > Math.PI ? 1 : 0} 1 ${r * Math.sin(endAngle)} ${-r * Math.cos(endAngle)}`,
		].join(' ') + ' z');
		group.appendChild(fanShape);
	});

	// 在中心创建一个圆形
	let circleShape = document.createElementNS(SVG_NS, 'circle');
	circleShape.setAttribute('style', 'fill: #FFFFFF');
	circleShape.setAttribute('cx', 0);
	circleShape.setAttribute('cy', 0);
	circleShape.setAttribute('r', minRadius);
	group.appendChild(circleShape);

	// 绘制文字
	let textShape = document.createElementNS(SVG_NS, 'text');
	textShape.setAttribute('x', 0);
	textShape.setAttribute('y', '0.3em');
	textShape.setAttribute('text-anchor', 'middle');
	textShape.innerHTML = sum;
	group.appendChild(textShape);

	return group;
}

window.Donut = Donut;

var map;
function initMap() {
    // ----------------适配uniapp修改过的----------------
    // 调用封装后的initDount()
	initDonut()
	
	// 初始化地图
	map = new TMap.Map("mapContainer", {
		zoom:12, // 设置地图缩放级别
		center: new TMap.LatLng(39.984104, 116.307503) // 设置地图中心点坐标
	});

	let donutList = [
		new Donut({
			map,
			position: new TMap.LatLng(39.96030543872138, 116.25809083213608),
			data: [12, 24],
			minRadius: 13,
			maxRadius: 20
		}),
		new Donut({
			map,
			position: new TMap.LatLng(39.9986945980902, 116.33598362780685),
			data: [23, 99, 101, 400],
			minRadius: 25,
			maxRadius: 35
		}),
		new Donut({
			map,
			position: new TMap.LatLng(40.02906301748584, 116.25499991104516),
			data: [18, 41, 50],
			minRadius: 20,
			maxRadius: 28
		})
	];

	donutList.forEach((donut, index) => {
		donut.on('click', () => {
			console.log(`第${index}个环形图被点击,位置为${donut.position}`);
			alert(`第${index}个环形图被点击,位置为${donut.position}`)
		});
	});
}

/**
 * ----------------适配uniapp修改过的----------------
 * 导出initMap方法
 */ 
export {
	initMap
}
loadJs.js

用来加载第三方js

function loadJs(src) {
  return new Promise((resolve,reject)=>{
    let script = document.createElement('script');
    script.type = "text/javascript";
    script.src= src;
    document.body.appendChild(script);
      
    script.onload = ()=>{
      resolve();
    }
    script.onerror = ()=>{
      reject();
    }
  }).catch((e) => {})
}
 
export default loadJs
map.vue
<template>
	<view id="mapContainer" style="height: 100%;" @click="log">
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			}
		},
		mounted() {
			
		}
		
	}
</script>

<script lang="renderjs" module="test">
	
	import loadJs from "../../common/loadJs.js"
    // 导入适配后的 DOMOverlay.js
	import {initMap} from "../../common/DOMOverlay.js"
	
	export default {

		data() {
		    return {
				
			}
		},
		mounted(){
			console.log("mounted") 
			loadJs('https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77').then(()=>{
				// 调用初始化地图方法
				initMap()
			})
		},
		 methods: {
		}, 
		created() {
			
		}
	}
</script>

<style>
   
</style>

三、适配效果

APP运行效果图,与官网一致

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

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

相关文章

互联网加竞赛 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统 -python

文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#x…

[yolov9]使用python部署yolov9的onnx模型

【框架地址】 https://github.com/WongKinYiu/yolov9 【yolov9简介】 在目标检测领域&#xff0c;YOLOv9 实现了一代更比一代强&#xff0c;利用新架构和方法让传统卷积在参数利用率方面胜过了深度卷积。 继 2023 年 1 月 正式发布一年多以后&#xff0c;YOLOv9 终于来了&a…

NXP实战笔记(八):S32K3xx基于RTD-SDK在S32DS上配置LCU实现ABZ解码

目录 1、概述 2、SDK配置 2.1、IO配置 2.2、TRGMUX配置 2.3、LCU配置 2.4、Trgmux配置 2.5、Emios配置 2.6、代码实现 1、概述 碰到光电编码器、磁编码器等,有时候传出来的位置信息为ABZ的方式,在S32K3里面通过TRGMUX、LCU、Emios结合的方式可以实现ABZ解码。 官方…

Linux快速修改ip地址

Linux修改IP配置 一 、查找ip配置文件 ifcfg-ens33二、编辑 vi ifcfg-ens33文件三、重启网络或者重启系统 一 、查找ip配置文件 ifcfg-ens33 cd /etc/sysconfig/network-scripts/ls //查看network-scripts文件夹下面的文件二、编辑 vi ifcfg-ens33文件 vi ifcfg-ens33注意&…

初始化(挂载)Linux数据盘(小于2TB)

本文中的操作系统以Linux CentOS 7.5 64位操作系统为例&#xff0c;采用fdisk分区工具为数据盘设置分区。 前提条件 已成功挂载云硬盘。 创建磁盘分区 如果数据盘对外呈现为一个磁盘&#xff0c;不需要分区&#xff0c;可以跳过此步骤。 1.登录Linux实例。 2.运行如下命令&…

Rust核心:【所有权】相关知识点

rust在内存资源管理上采用了&#xff08;先进优秀&#xff1f;算吗&#xff09;但特立独行的设计思路&#xff1a;所有权。这是rust的核心&#xff0c;贯穿在整个rust语言的方方面面&#xff0c;并以此为基点来重新思考和重构软件开发体系。 涉及到的概念点&#xff1a;借用&am…

【Vuforia+Unity】AR05-实物3D模型识别功能实现(ModelTarget )

不管是什么类型的识别Vuforia的步骤基本都是: 把被识别的物体转成图、立体图、柱形图,3D模型、环境模型,然后模型生成Vuforia数据库-导入Unity-参考模型位置开始摆放数字内容,然后参考模型自动隐藏-发布APP-识别生活中实物-数字内容叠加上去! 对于3D物体的识别,可以是虚…

鸿蒙原生应用再添一批新丁!看看新闻、 随申办、浙里办、得物、新零售事业群等入局鸿蒙

鸿蒙原生应用再添一批新丁&#xff01;看看新闻、 随申办、浙里办、得物、新零售事业群等入局鸿蒙 来自 HarmonyOS 微博2月22日消息&#xff0c;#鸿蒙千帆起#上海广播电视台旗下 看看新闻KNEWS 宣布启动鸿蒙原生应用开发&#xff0c;上海广播电视台也成为了全国首家推行鸿蒙原…

Linux运维-Web服务器的配置与管理(PHP)

Web服务器的配置与管理(PHP) 项目场景 某企业在CentOS上搭建Web服务系统&#xff0c;以PHP作为网页开发环境&#xff0c;以MySQL为后台数据库。 基础知识 PHP PHP原始为Personal Home Page的缩写&#xff0c;已经正式更名为 “PHP: Hypertext Preprocessor”&#xff08;超…

Jetson Xavier NX 与笔记本网线连接 ,网络共享,ssh连接到vscode

Jetson Xavier NX 与笔记本网线连接 &#xff0c;网络共享&#xff0c;ssh连接到vscode Jetson Xavier NX桌面版需要连接显示屏、鼠标和键盘&#xff0c;操作起来并不方便&#xff0c;因此常常需要ssh远程连接到本地笔记本电脑&#xff0c;这里介绍一种连接方式&#xff0c;通过…

Cartographer 多分辨率地图和分支定界算法

多分辨率地图 函数调用 PrecomputationGridStack2D 这个图直接让我想起了图像处理中的膨胀操作。膨胀就是求局部最大值的操作,核B与图形卷积,即计算核B覆盖的区域的像素点的最大值,并把这个最大值赋值给参考点指定的像素。 滑窗操作会导致地图变大。 假设原始栅格地图尺寸为[h,…

第一个 Angular 项目 - 添加服务

第一个 Angular 项目 - 添加服务 这里主要用到的内容就是 [Angular 基础] - service 服务 提到的 前置项目在 第一个 Angular 项目 - 动态页面 这里查看 想要实现的功能是简化 shopping-list 和 recipe 之间的跨组件交流 回顾一下项目的结构&#xff1a; ❯ tree src/app/…

第3部分 原理篇2去中心化数字身份标识符(DID)(3)

3.2.2.4. DID文档 (DID Document) 本聪老师&#xff1a;DID标识符和DID URL还都只是ID&#xff0c;必须为它附加一个基本属性才可以证明是该主体独有的。这个就是我们下面介绍的DID文档。 本聪老师&#xff1a;每个DID标识符都唯一对应一个DID文档&#xff0c;也可以说&#x…

什么是负载均衡集群?

目录 1、集群是什么&#xff1f; 2、负载均衡集群技术 3、负载均衡集群技术的实现 4、实现效果如图 5、负载均衡分类 6、四层负载均衡&#xff08;基于IP端口的负载均衡&#xff09; 7、七层的负载均衡&#xff08;基于虚拟的URL或主机IP的负载均衡) 8、四层负载与七层…

Typora+PicGo+super-prefix+阿里云OSS设置图床

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;实用工具 1 TyporaPicGosuper-prefix阿里云OSS设置图床1.1 设置阿里云OSS1.2 以时间戳命名图片1.2.1 安装super-prefix1.2.2 设置配置文件 1.3 批量上传图片遇到的问题1.4 参考资料 2 将ma…

OpenHarmony JS和TS三方组件使用指导

OpenHarmony JS和TS三方组件介绍 OpenHarmony JS和TS三方组件使用的是OpenHarmony静态共享包&#xff0c;即HAR(Harmony Archive)&#xff0c;可以包含js/ts代码、c库、资源和配置文件。通过HAR&#xff0c;可以实现多个模块或者多个工程共享ArkUI组件、资源等相关代码。HAR不…

robots.txt 文件规则

robots.txt 是一种用于网站根目录的文本文件&#xff0c;其主要目的在于指示网络爬虫&#xff08;web crawlers&#xff09;和其他网页机器人&#xff08;bots&#xff09;哪些页面可以抓取&#xff0c;以及哪些页面不应该被抓取。可以看作是网站和搜索引擎机器人之间的一个协议…

Element table 实现表格行、列拖拽功能

安装包 npm install sortablejs --save <template><div class"draggable" style"padding: 20px"><el-table row-key"id" :data"tableData" style"width: 100%" border><el-table-columnv-for"(it…

osg qt5.15 osg3.6.3 osgEarth3.1 编译爬山

Demo演示&#xff1a;Qt5.15.2OSG3.6.3OsgEarth3.1的QtCreator下的msvc2019x64版本 osgQt编译 步骤一&#xff1a;下载解压 步骤二&#xff1a;CMake配置 步骤三&#xff1a;CMake配置添加osg环境 步骤四&#xff1a;CMake配置添加Qt环境 步骤五&#xff1a;CMake修改CMakeLis…

【数据结构】C语言实现图的相关操作

图 图&#xff08;Graph&#xff09;是由顶点的有穷非空集合和顶点之间边的集合组成&#xff0c;通常表示为&#xff1a;G(V,E)&#xff0c;其中&#xff0c;G 表示一个图&#xff0c;V 是图 G 中顶点的集合&#xff0c;E 是图 G 中边的集合。 术语 无向图&#xff1a;每条边…