| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- <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>
|