uniapp中使用leaflet

由于B/S端地图采集的经纬度数据使用wgs84坐标系,uniapp提供的原生map组件坐标系为gci02,所以改使用leaflet.js来开发地图功能
在这里插入图片描述

vue2 下

可以采取静态包引入的模式,将leaflet.js下载到本地,放在/static中

APP.vue页面,style中引入leaflet样式


<style>
/*每个页面公共css */
@import url('static/css/leaflet.css');
//leaflet.markercluster.js为点聚合插件根据需要下载引入,
@import url('static/css/MarkerCluster.css');//点聚合
@import url('static/css/MarkerCluster.Default.css');//点聚合
</style>

index.vue页面,引入leaflet组件

<template>
	<view class="content">
		<leaflet></leaflet>
	</view>
</template>

<script>
import leaflet from '../../components/leaflet/leaflet.vue';
export default {
	components: {
		leaflet
	},
	data() {
		return {
			title: 'Hello'
		};
	},
	onLoad() {},
	methods: {}
};
</script>

<style>
.content {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}
</style>

leaflet组件,由于render.js中不能使用uni的相关api,也无法获取store中的值,所以通过监听obj对象,调用receiveMsg方法获取请求到的数据

<template>
	<view>
		<view id="map" :obj="obj" :change:obj="leaflet.receiveMsg"></view>
		<view class="control">
			<button type="primary" @click="addMarker()">10万点</button>
		</view>
	</view>
</template>

<script module="leaflet" lang="renderjs">
import L from 'static/js/leaflet.js';
import 'static/js/leaflet.markercluster.js'
import 'static/js/leaflet.canvas-markers.js';//在canvas
export default {
	data() {
		return {
			map:null,
			canvasLayer:null,
			cluster:null
		};
	},
	mounted() {
		this.initMap();
	},
	methods:{
		// 初始化地图
		initMap(){
			this.map = L.map('map',{
				crs: L.CRS.EPSG3857,	// 地图投影坐标系
			    center:[30.67, 104.07],//地图中心经纬度
			    zoom:17,//当前缩放等级
			    minZoom:5,//最小缩放等级
			    maxZoom:18,//最大缩放等级
			    dragging:true,//是否允许拖拽
			    attributionControl: false,//是否去除右下角标志
			    zoomControl:false//是否显示地图缩放图例
			});
			// 添加图层,天地图影像
			L.tileLayer('https://t{s}.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=6d4deb37bf726665d610b256b2d196c5', {
			   subdomains: ['1', '2', '3', '4', '5', '6', '7']
			}).addTo(this.map);

			let cluster = new L.MarkerClusterGroup()
			this.cluster = cluster
			cluster.markers = []
			// console.log(this.markers)
			this.map.addLayer(cluster)
		},
		createMarkers(data){
			let that=this
			if(this.canvasLayer) this.map.removeLayer(this.canvasLayer);
			this.canvasLayer = L.canvasIconLayer({}).addTo(this.map);
			console.log(48,this.canvasLayer)
			data.forEach(item => {
			    var marker = L.marker([item["latitude"], item["longitude"]], {
			        icon: L.icon({
			            iconUrl: "static/images/marker-icon.png",
			            iconSize: [40, 40],
			            iconAnchor: [20, 20],
			            text: item.AQI,
			            textAnchor: [10, -10],
			            textFont: '14px bold', //设置字体大小和样式
			            textFillStyle: '#FFFFFF'
			        })
			    }).bindPopup("I Am " + item.cityName);
				that.cluster.markers.push(marker)
				that.cluster.addLayer(marker)
			    // that.canvasLayer.addLayer(marker);
			});
		},
		//接受script传递回来的obj,绘制点位
		receiveMsg(newValue, oldValue, ownerVm, vm) {
			console.log(65,newValue)
			if(newValue?.type === "marker"&&newValue?.data.length>0){
				this.createMarkers(newValue?.data)
			}
		},
	}
}
</script>

<script>
export default {
	data() {
		return {
			obj: {
				type: 'marker',
				data: []
			},
			data: []
		};
	},
	mounted() {},
	methods: {
		addMarker() {
			for (let i = 0; i < 50000; i++) {
				let obj = {
					latitude: '30.67',
					cityName: '成都',
					AQI: i,
					longitude: '104.07'
				};

				obj['latitude'] -= (Math.random() * 10).toFixed(2);
				obj['longitude'] -= (Math.random() * 10).toFixed(2);
				this.data.push(obj);
			}
			this.obj = { ...this.obj, data: this.data };
		}
	}
};
</script>

<style lang="scss">
#map {
	height: 60vh;
	width: 100vw;
}
.control {
	width: 100vw;
	height: 40vh;
	padding: 20rpx;
}
</style>

vue3 下

区别在于vue3下不能采用本地引入leaflet.js,会报leaflet没有默认的导出模块错误,只能通过npm的方式或者在mounted中通过cdn方式动态引入,由于项目需要使用点聚合 ,通过cdn方式引入多个script会报错,所以采用npm

  • 监听多个属性
<view
			class="mapBox"
			id="mapId"
			:prop="latlon"
			:change:prop="leaflet.getData"
			:mapMarkerList="mapMarkerList"
			:change:mapMarkerList="leaflet.getMapMarkerList"
			:flyLatlon="flyLatlon"
			:change:flyLatlon="leaflet.flyToZy"
		></view>

注:npm方式引入时,会导致leaflet.js中marker的默认图标路径不可用,得把图片转base64才能用,(H5上可以,打包成app图片裂开)
引入天地图多个底图时可以使用Leaflet.ChineseTmsProviders插件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值