uniapp 中使用天地图,安卓端、h5

news/2025/2/23 6:33:35

 

背景:项目需要将高德地图换成天地图,pc端已经更换,但app端用uniapp写的,就有点茫然了,毕竟uniapp官方给出的地图组件也不支持啊,网上找吧,也没什么例子,算了,自己写吧。

 思路:使用 uniapp中 renderjs 来引入使用天地图;注意:renderjs中不能使用任何uniapp的api,h5中可能没事 但app就不行了。网上也有使用 <web-view> 直接引入地图的,但看他们说样式不好改,就没使。

代码如下:

  1.html 中创建地图容器

<template>
	<view>
     <!--地图容器-->
     <view id="mapDiv" style="width:100vw;height:100vh,z-index:1}"></view>
    

     <!--详情-->
	<view class="detail-wrap" v-if="isShow">
		<view class="detail-title">
			<text class="text">{{obj.name}}</text>
			</view>
			<view class="detaile-content">
				<text class="text">微站编码:{{obj.mn}}</text>
			</view>
				
	</view>
   
    <!--renderjs-->
    <!--向renderjs 传递 token属性-->
	<view class="" :prop="token" :change:prop="renderScript.tokenChange"></view>
    <!--点击时 触发renderjs  getInfo()方法-->
	<view id="info" @click="renderScript.getInfo"></view>
</view>
</template>

  2.普通 js 

<script>
 export default {
   data(){
     return {
        obj:{},
        token:uni.getStorageSync("token")
     }
   },
   methods:{
		markerClick(item){
			this.obj = item
			this.isShow = true;
		},
   		errorMsg({code,msg}){
			
			uni.showToast({
				icon: "none",
				title: msg
			})
			
		},
   }
 }
</script>

 3.renderjs 接受变量值,并获取数据 渲染地图

<script  module="renderScript" lang="renderjs">
  import axios from 'axios';   // 调接口用
  import {exchangeGdToTdt} from "@/utils/index.js";   // 坐标转换
  export default {
	data() {
	  return {
		token:'',
	  }
    },
    mounted(){
	  // 加载地图必须放到异步执行,否则地图放大后会没有标注图层,不知道为什么
	  setTimeout(()=> {
		this.initMap()   // 初始化地图
	  }, 0);
			
	},
	methods: {
         //接受普通js 传递的token值,因为我这里接口需要token
	    tokenChange(newValue, oldValue, ownerVm, vm) { 
			this.token = newValue  // 它会早于mounted执行
		},
		
		// 引入天地图API脚本
		initMap() {
			
			const script = document.createElement('script');
			script.src = "http://api.tianditu.gov.cn/api?v=4.0&tk=你的天地图密钥";  
			script.onload = () => {
				this.createMap();
			};
			document.body.appendChild(script);
					
		},
        // 初始化地图
		createMap() {
			
			this.map = new T.Map('mapDiv',{
				zoom:11,
				maxZoom:18,
				minZoom:10,
				center:new T.LngLat(116.68098, 40.14166)
			});
			// 点聚合配置		
			this.markerClusterer = new T.MarkerClusterer(this.map,{
				girdSize:40,  // 每个聚合区域大小为 40,默认60,越小分的越精细聚合点越多
				maxZoom:3,
			}) 
			const that = this;
			this.map.on('zoomend', function(e) {
			    const zoom = that.map.getZoom()
		// 天地图最大缩放级别 18,但到达18时,好多聚合点还没展开呢,所以手动缩小网格区域,使聚合点展开
			    if(zoom>=17){
				    that.markerClusterer.setGridSize(3)
				}else{
					if(that.markerClusterer.getGridSize()<40){
					    that.markerClusterer.setGridSize(40)
					}
				}
			})
			// 获取页面数据  
            // 这样触发 getInfo方法 是为了获取 ownerInstance对象,如果使用this.getInfo() 获取不到
			document.getElementById("info").click()
		
		},
       // 获取页面点数据
         async getInfo(event, ownerInstance) {
            let res = await axios({
		        method: "post",
				url: outletMapData,
				data,
				headers: {
					'Authorization': 'Bearer' + ' ' + this.token
				},
					
			})
				
			if (res.data.code == 202) {
				// 触发普通js errorMsg 方法		
				ownerInstance.callMethod('errorMsg', {code:res.data.code,msg:''})
			}
			if (res.data.code !== 200) {
				ownerInstance.callMethod('errorMsg', {code:res.data.code,msg:res.data.msg})
				return
			}
			const arr = res.data.data;
			this.positions = arr.map(item => {
                // 高德地图转天地图坐标
				const obj = exchangeGdToTdt(item.lnggcj,item.latgcj)
				item.lnggcj = obj.lnggcj;
				item.latgcj = obj.latgcj;
				return {
					id: item.outletid,
					...item
				}
			})
			if (this.positions.length > 0 && this.positions[0].latgcj && this.positions[0].lnggcj) {
				this.latitude = this.positions[0].latgcj;
				this.longitude = this.positions[0].lnggcj;
						
				this.map.centerAndZoom(new T.LngLat(this.longitude,this.latitude),11)
			}
            // 清空聚合数据
			if(this.markerClusterer){
				this.markerClusterer.clearMarkers()
			}
            //渲染数据						
			if (this.positions.length > 0) { 
				this.addMarkers(this.positions,ownerInstance)
			} 
        },
        // 创建marker标记
        addMarkers(positions,ownerInstance) {
			
			const markers = []
				for(let item of positions){
				    const marker = new T.Marker(
					    new T.LngLat(item.lnggcj,item.latgcj),
					    {
							icon:	new T.Icon({
									iconUrl:require("../../../static/riverOutfall/dingweixiao.png"),
							iconSize: new T.Point(28, 34),
							}),
							title:item.name,
							item:{...item}
							}
						)
						marker.on('click', function(e) {
					
							const data = e.target.options
							const lnglat = e.lnglat
							const item = data.item
                            // 触发普通js markerClick 方法 传参:item		
							ownerInstance.callMethod('markerClick', item)
						})
						markers.push(marker)	
					}
				
				this.markerClusterer.addMarkers(markers)
			},
 }

}
</script>

 4.坐标转换

npm  i  gcoord;  安装转换插件

使用如下:

import gcoord from 'gcoord';

// 高德地图坐标转天地图坐标
 export function exchangeGdToTdt(lng,lat){
     if(!lng || !lat){
				return {}
			}
      let wgsJson = gcoord.transform(
        [lng,lat],    // 经纬度坐标
        gcoord.GCJ02,      // 当前坐标系  高德 火星坐标
        gcoord.WGS84        // 目标坐标系 天地图
      );
      return {
        lnggcj: wgsJson[0],
        latgcj: wgsJson[1]
      };
    }

普通 js 想调用 renderjs 中的方法,只能通过点击事件;renderjs向普通js传递数据 只能通过 ownerInstance 对象,所以 点击事件关联着 这两种js。目前这是我看到的结果,希望有帮到大家。如果大家有更好的办法,也可以告诉我呀。

一开始不是找半天例子找不着吗,结果 等我写完了,我就看到了个相关的例子。。。额,但我没仔细研究过,链接贴上,也许以后会用到:uni-app如何引入天地图并兼容app_uniapp 天地图-CSDN博客

还有就是,这代码,可能少括号。


http://www.niftyadmin.cn/n/5863127.html

相关文章

图论 之 弗洛伊德算法求解全源最短路径

文章目录 题目1334.阈值距离内邻居最少的城市 Floyd算法适合用于求解多源的最短路径的问题&#xff0c;相比之下&#xff0c;Dijkstra算法适合用于求解单源的最短路径的问题&#xff0c;并且&#xff0c;当边的权值只有1的时候&#xff0c;我们还能使用BFS求解最短路径的问题 …

Uniapp 开发中遇到的坑与注意事项:全面指南

文章目录 1. 引言Uniapp 简介开发中的常见问题本文的目标与结构 2. 环境配置与项目初始化环境配置问题解决方案 项目初始化注意事项解决方案 常见错误与解决方案 3. 页面与组件开发页面生命周期注意事项示例代码 组件通信与复用注意事项示例代码 样式与布局问题注意事项示例代码…

tcpdump 用法示例

server.py 源码&#xff1a; import socket import sys# 这里创建了一个UDP套接字。socket.AF_INET指定了IPv4地址族&#xff0c;socket.SOCK_DGRAM指定了这个套接字是UDP协议的。 sock socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 这里定义了服务器将要监听的地址和…

Docker下的Elastic search

一、安装 &#xff08;一&#xff09;Elastic search 1.创建配置文件 &#xff1a;我是在win系统中&#xff0c;创建文件【G:\dockermount\es\elasticsearch.yml】 添加【http.host: 0.0.0.0】 2. 拉取镜像&#xff1a;docker pull elasticsearch 3. 创建容器(注意我挂载的…

游戏引擎学习第118天

仓库:https://gitee.com/mrxiao_com/2d_game_3 优化工作概述 这次我们正在进行一些非常有趣的工作&#xff0c;主要是对游戏进行优化。这是首次进行优化&#xff0c;我们正在将一个常规的标量C代码例程转换为内建指令&#xff0c;以便利用AIX 64位处理器的SIMD指令集进行加速…

《DAMA数据管理知识体系指南》第十章 参考数据和主数据管理读书笔记

《DAMA数据管理知识体系指南》第十章 参考数据和主数据管理读书笔记 1. 引言 主数据和参考数据是组织跨系统共享的核心资源,其一致性直接影响业务决策和数据质量。主数据(如客户、产品)描述核心业务实体,参考数据(如国家代码、行业分类)提供分类和标准化支持。管理目标…

【Elasticsearch】同一台服务器部署集群

【Elasticsearch】同一台服务器部署集群 1. 同一台服务器搭建ES集群2. 配置不同的node节点3. ES集群中安装IK分词器4. 启动es集群5. Kibana访问集群6. es-head7. 集群中创建索引7.1 什么是分片以及分片的好处7.2 副本&#xff08;Replication&#xff09;7.3 通过es-head创建索…

机器学习 - 投票感知器

一、传统&#xff08;经典&#xff09;感知器的缺点 1、缺点 根据上一篇博文&#xff0c;如果训练数据是线性可分的&#xff0c;那么感知器可以找到一个判别函数来分割不同类的数据。如果间隔 &#x1d6fe; 越大&#xff0c;收敛越快。但是感知器并不能保证找到的判别函数是…