天天看點

uniapp中使用openlayer庫

最近需要在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是值變化後的值。

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.csdn.net/M_Eve/article/details/115497269

https://blog.csdn.net/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