<template>
	<view class="openlayer-map-draw">
		<view :pos="position" :change:pos="olMap.createPolygon" style="display: none;"></view>
		<view :domId="mapId" :change:domId="olMap.initMap" style="display: none;"></view>
		<view :id="mapId" class="map"></view>
		<view class="btns">
			<button class="btn" type="default" @tap="olMap.handleStart">开始绘制</button>
			<button class="btn" type="default" @tap="olMap.handleClear">清除绘制</button>
			<button class="btn" type="default" @tap="olMap.handleSubmit">完成绘制</button>
		</view>
	</view>
</template>

<script>
	export default {
		name: "openlayer-map-draw",
		props: {
			coordinates: {
				type: Array,
				required: false,
				default: () => {
					return []
				}
			}
		},
		data() {
			return {
				position: [],
				mapId: 'ol-map' + ('000000' + Math.floor(Math.random() * 999999)).slice(-6),
			};
		},
		methods: {
			//给renderJS调用的方法
			methodForRenderJs: async function(val) {
				if (val.type === 'startInitOlMap') {
					uni.showLoading({
						title: "地图加载中..."
					})
				}
				// 地图初始化完成，绘制传入坐标
				if (val.type === 'changeSize') {
					this.position = this.coordinates;
					uni.hideLoading()
				}
				if (val.type === 'isStop') {
					uni.$msg('已有范围，请先清除后重新绘制')
				}
				if (val.type === 'needStart') {
					uni.$msg('请先绘制范围')
				}
				if (val.type === 'submit') {
					uni.$msg('提交')
					console.log(val.coords)
					if(val.coords && val.coords.length){
						this.$emit('onSubmit', val.coords)
					}
				}
			}
		}
	}
</script>

<script lang="renderjs" module="olMap">
	import Map from 'ol/Map.js';
	import View from 'ol/View.js';
	import {
		defaults as defaultControls
	} from 'ol/control.js';
	import {
		getWidth,
		getTopLeft
	} from 'ol/extent.js';
	import TileLayer from 'ol/layer/Tile.js';
	import {
		get as getProjection
	} from 'ol/proj.js';
	import {
		fromLonLat
	} from "ol/proj";
	import WMTS from 'ol/source/WMTS.js';
	import WMTSTileGrid from 'ol/tilegrid/WMTS.js';
	import Feature from 'ol/Feature';
	import Point from 'ol/geom/Point';
	import Polygon from 'ol/geom/Polygon';
	import {
		Icon,
		Style
	} from 'ol/style';
	import VectorSource from 'ol/source/Vector';
	import {
		Vector as VectorLayer
	} from 'ol/layer';
	import Fill from 'ol/style/Fill';
	import Text from 'ol/style/Text';
	import Stroke from 'ol/style/Stroke';
	import Circle from 'ol/style/Circle';
	import { Draw } from "ol/interaction";

	export default {
		name: "openlayer-map",
		data() {
			return {
				map: null,
				points: [],
				polygonLayer: null,
				pointsLayer: null,
				drawStatus: 'start',
				drawSource: null,
				draw: null
			};
		},
		methods: {
			WMTS_Layer(url) {
				if (!url) return null
				let projection = getProjection('EPSG:4326')
				let extent = projection.getExtent()
				let width = getWidth(extent)

				let resolutions = [],
					matrixIds = []
				for (let z = 1; z < 19; z++) {
					resolutions[z] = width / (256 * Math.pow(2, z))
					matrixIds[z] = z
				}
				let tileGrid = new WMTSTileGrid({
					origin: getTopLeft(extent),
					resolutions,
					matrixIds
				})

				// 匹配坐标系、图层类型
				let type = url.match(new RegExp(/\/(.{3})_(c|w)\//))
				return new TileLayer({
					source: new WMTS({
						crossOrigin: 'anonymous',
						url: url,
						layer: type[1],
						matrixSet: type[2],
						format: 'tiles',
						style: 'default',
						wrapX: true,
						projection: projection,
						tileGrid
					})
				})
			},
			initMap(domId) {
				var webKey = '15f7b01aababbb39ab568f4ba12ea21c';
				let wmtsUrl_1 = 'http://t{0-7}.tianditu.gov.cn/vec_c/wmts?tk=' + webKey;
				let wmtsUrl_2 = 'http://t{0-7}.tianditu.gov.cn/cva_c/wmts?tk=' + webKey;
				let center = [104.93616806129798, 33.38784018924233]
				this.$ownerInstance.callMethod('methodForRenderJs', {
					type: 'startInitOlMap'
				});
				setTimeout(() => {
					this.map = new Map({
						target: domId,
						view: new View({
							projection: 'EPSG:4326',
							center: center,
							zoom: 16,
							maxZoom: 22,
							minZoom: 1
						}),
						controls: defaultControls({
							zoom: false,
							rotate: false,
							attribution: false
						})
					});
					let layer = this.WMTS_Layer(wmtsUrl_1)
					this.map.addLayer(layer)
					let layer1 = this.WMTS_Layer(wmtsUrl_2)
					this.map.addLayer(layer1)
					this.map.updateSize()
					// 先注册一下绘制面图层
					this.drawSource = new VectorSource({});
					this.map.addLayer(new VectorLayer({
						source: this.drawSource
					}))
					this.$ownerInstance.callMethod('methodForRenderJs', {
						type: 'changeSize'
					});
				}, 3000);
			},
			handleClear() {
				this.drawStatus = 'clear'
				this.map.removeLayer(this.polygonLayer)
				this.map.removeLayer(this.pointsLayer)
				this.map.removeInteraction(this.draw)
				this.draw = null
				this.polygonLayer = null
				this.pointsLayer = null
				this.drawSource.clear()
			},
			handleSubmit() {
				if(!this.draw || this.drawStatus !== 'start'){
					this.$ownerInstance.callMethod('methodForRenderJs', {
						type: 'needStart'
					});
					return;
				}
				this.draw.finishDrawing()
				let features = this.drawSource.getFeatures()
				if(!features.length){
					this.$ownerInstance.callMethod('methodForRenderJs', {
						type: 'needStart'
					});
					return;
				}
				let coords = features[0].getGeometry().getCoordinates()
				this.$ownerInstance.callMethod('methodForRenderJs', {
					type: 'submit',
					coords: coords
				});
				this.drawStatus = 'stop'
			},
			handleStart() {
				if(this.drawStatus === 'stop'){
					this.$ownerInstance.callMethod('methodForRenderJs', {
						type: 'isStop'
					});
					return;
				}
				this.draw = new Draw({
					source: this.drawSource,
					type: 'Polygon',
					style: new Style({
						stroke: new Stroke({
							color: 'red',
							width: 2
						}),
						fill: new Fill({
							color: 'pink'
						})
					})
				})
				this.map.addInteraction(this.draw);
				this.draw.on("drawend", (evt) => {
				  console.log("结束绘制");
				  console.log(evt);
				});
				this.drawStatus = 'start'
			},
			createPolygon(coordinates) {
				if (!coordinates.length || !this.map) {
					return
				}
				this.drawStatus = 'stop'
				this.points = JSON.parse(JSON.stringfy(coordinates))
				// 绘制顶点
				let pointStyle = new Style({
					image: new Circle({
						radius: 20,
						fill: new Fill({
							color: 'yellow'
						})
					})
				})
				let pointsVector = new VectorSource({});
				coordinates.forEach(item => {
					let pointFeature = new Feature({
						geometry: new Point(item)
					});
					pointFeature.setStyle(pointStyle)
					pointsVector.addFeature(pointFeature)
				})
				this.pointsLayer = new VectorLayer({
					source: pointsVector
				});
				this.map.addLayer(this.pointsLayer);

				// 绘制面
				var iconFeature = new Feature({
					geometry: new Polygon(coordinates)
				});
				var iconStyle = new Style({
					fill: new Fill({
						color: 'pink'
					})
				});
				iconFeature.setStyle(iconStyle);
				var vectorSource = new VectorSource({});
				vectorSource.addFeature(iconFeature)
				this.polygonLayer = new VectorLayer({
					source: vectorSource
				});
				this.map.addLayer(this.polygonLayer);
			}
		},
		beforeUnmount() {
			this.map && this.map.dispose();
			this.map = null;
		}
	}
</script>

<style lang="scss" scoped>
	.openlayer-map-draw {
		width: 100%;
		height: 100%;
		position: relative;

		.map {
			width: 100%;
			height: 100%;
		}

		.btns {
			position: absolute;
			bottom: 0;
			right: 0;
			width: 100%;
			display: flex;
			justify-content: space-between;
			align-items: center;

			.btn {
				height: 35px;
				line-height: 35px;
				flex: 0 0 30%;
			}
		}
	}
</style>