uniapp中使用openlayer库

本文介绍了如何在UniApp中结合RenderJS来使用OpenLayers库,详细阐述了从下载OpenLayers资源到在Vue组件中动态引入,并通过RenderJS实现在非H5端操作DOM及通讯的过程,展示了在视图层和逻辑层间的数据交换方法,以及创建地图实例的步骤。

最近需要在uniapp上使用openlayer,于是网上查找相关资料貌似renderjs可以实现,貌似fs,three.js,echart,mapbox库都可以使用renderjs实现,且renderjs可以在app及H5上运行,就顺便及记录下。

renderjs是一个运行在视图层的js。它比WXS更加强大。它只支持app-vue和h5。
renderjs的主要作用有2个:

renderjs可以实现逻辑层和视图层之间的通讯,大幅降低逻辑层和视图层的通讯损耗,提供高性能视图交互能力。renderjs运行在视图层,可以直接操作视图层的元素。

在视图层操作dom,运行for web的js库。uniapp不支持DOM操作(如删除某元素节点)当然H5端除外。非H5端可以渲染后获取某元素的节点信息。使用render技术可以对实现对DOM操作和使用某些window库,如导入jquery,echart。可以实现像开发WebGIS一样开发移动端GIS,极大降低开发难度。

页面和renderjs模块通信

在页面中监听变量cy,当cy变化时,调用renderjs模块中receiveName方法,此时,该方法有这几个参数,newValue, oldValue, ownerVm, vm,其中newValue是值变化后的值。

<view id="olMap" class="olMap" @click="ol.emitData" style="height: 500px;" :cy="cy" :change:cy="ol.receiveName" />

renderjs发送数据给页面

		// 点击renderjs层后发送数据到逻辑层
			emitData(e, ownerVm) {
				ownerVm.callMethod('receiveRenderData', e, this.title)
			},

下面是renderjs上使用openlayer大致步骤:
1.openlayers官网下载openlayer包,地址如https://openlayers.org/download/
2.下载好后,解压文件,将ol.js和ol.css拷贝到uniapp项目的static文件下。
3.在组件引入openlayers,创建视图成层,不要直接import 引用大型类库,否则打包会因为文件过大失败,推荐通过动态创建 script 方式引用。具体如下

<template>
	<view class="content">
		<view class="" @click="changen()">
			点击{{this.cy}}
		</view>
		<!--监听查看 :cy="cy" :change:cy="ol.receiveName" -->
		<view id="olMap" class="olMap" style="height: 500px;" @click="ol.emitData" :cy="cy" :change:cy="ol.receiveName" />
	</view>
</template>
<script>
	//逻辑层操作
	import {
		maptree,
		mapInfo
	} from '@/utils/api/http.js'
	import {
		baseUrl,
		wsUrl
	} from '@/utils/api/global.js'
	export default {
		data() {
			return {
				cy: '我名字',
				num: 0
			}
		},
		methods: {
			//改变cy变量的值,当值改变传递给renderjs
			changen() {
				++this.num;
				this.cy = this.cy + this.num
			},

			// 接收renderjs发回的数据
			receiveRenderData(val) {
				console.log('receiveRenderName', val);
			},
		}
	}
</script>


<script module="ol" lang="renderjs">
	//视图层renderjs操作,注意此层中不能uniapp提供相关接口。
	// import '../../static/openlayer/v6.6.1-dist/ol.js'不支持此导入方式否则,打包失败
	export default {
		data() {
			return {
				title: 'Hello'
			}
		},
		mounted() {
			if (typeof window.ol === 'function') {
				this.initAmap()
			} else {
				const script = document.createElement('script')
				script.src = 'static/ol.js'//可以通过此方式导入jquery,echart库
				script.onload = this.initAmap.bind(this)
				document.head.appendChild(script)
			}
			//可以操作节点
			console.log(document.getElementId('olMap'))
		},
		methods: {
			initAmap() {
				this.map = new ol.Map({
					layers: [
						new ol.layer.Image({
							source: new ol.source.ImageStatic({
								url: 'https://scpic1.chinaz.net/Files/pic/pic9/202108/apic34419_s.jpg',
								projection: new ol.proj.Projection({
									code: 'EPSG:3857',
									extent: [0, 0, 786, 968]
								}),
								imageExtent: [0, 0, 786, 968]
							})
						})
						// new ol.layer.Tile({
						// 	source: new ol.source.OSM()
						// })
					],
					target: "olMap",
					view: new ol.View({
						maxzoom: 18,
						zoom: 2,
						center: [114, 25],
						projection: new ol.proj.Projection({
							code: 'EPSG:3857',
							extent: [0, 0, 786, 968]
						})
					})
				})
			},

			// 点击renderjs层后发送数据到逻辑层
			emitData(e, ownerVm) {
				ownerVm.callMethod('receiveRenderData', e, this.title)
			},

			// 接收逻辑层发送的数据
			receiveName(newValue, oldValue, ownerVm, vm) {
				console.log('newValue', newValue)
				console.log('oldValue', oldValue)
				console.log('ownerVm', ownerVm)
				console.log('vm', vm)
			},
		}
	}
</script>

<style>
	@import url("@/static/ol.css");
	.content {
		width: 100%;
	}

</style>


			addPoint() {
				this.TagSource = new ol.source.Vector({
					wrapX: false
				});
				let currentPoint = new ol.Feature({
					geometry: new ol.geom.Point([0, 0])
				});
				this.TagSource.addFeature(currentPoint);

				this.TagLayer = new ol.layer.Vector({
					source: this.TagSource,
					zIndex: 99,
					style: (feature)=>{
						return this.TagStyle(feature, 0)
					}
				})

				this.map.addLayer(this.TagLayer)

			},

			TagStyle(f, rontation) {
				let textname = '测试'
				return new ol.style.Style({
					image: new ol.style.Icon({
						src: '/static/icon/5ren.png',
						color: '#409EFF'
					}),
					text: new ol.style.Text({
						text: textname,
						offsetY: 14,
						fill: new ol.style.Fill({
							color: '#fff'
						}),
						stroke: new ol.style.Stroke({
							color: '#000',
							width: 3
						}),
						rotation: rontation
					})
				})

			},

参考:
https://blog.youkuaiyun.com/M_Eve/article/details/115497269

https://blog.youkuaiyun.com/qq_43171049/article/details/117773952?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-6.control

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值