openlayer 绘制点,圆,矩形,多边形以及选中平移,修改等操作

在这里插入图片描述

当前页面完整代码实现的是单个的绘制,多个绘制一样的 只是我这里绘制完成后在绘制就清除了上一个绘制

<template>
    <div class="map_box">
        <div class="fullScreen">
            <div @click="butClick()">
                <i class="iconfont icon-quanping"></i>
            </div>
        </div>
        <div class="drawType">
            <div class="type_box" v-if="$hasPermision(['element:add'])">
                <ul>
                    <!-- <li :class="{ active: goldForm.graphType === '1' }">
                        <div class="btn" @click="setDrawType('Point', '1')">
                            <i class="el-icon-location-outline"></i>
                            <span>绘制点</span>
                        </div>
                    </li> -->
                    <li>
                        <div class="btn" @click="lineArea">
                            <i class="el-icon-edit-outline"></i>
                            <span>绘制区域</span>
                        </div>
                    </li>
                </ul>
                <ul v-show="isIcon">
                    <li :class="{ active: goldForm.graphType === '2' }">
                        <div class="btn" @click="setDrawType('Circle', '2')">
                            <i class="iconfont icon-yuanxingweixuanzhong-copy"></i>
                            <span>圆形</span>
                        </div>
                    </li>
                    <li :class="{ active: goldForm.graphType === '3' }">
                        <div class="btn" @click="setDrawType('Rectangle', '3')">
                            <i class="iconfont icon-xingzhuang-juxing"></i>
                            <span>矩形</span>
                        </div>
                    </li>
                    <li :class="{ active: goldForm.graphType === '4' }">
                        <div class="btn" @click="setDrawType('Polygon', '4')">
                            <i class="iconfont icon-huaduobianxing"></i>
                            <span>多边形</span>
                        </div>
                    </li>
                </ul>
            </div>
            <div class="wx">
                <ul>
                    <li @click="mapChange">
                        <i class="iconfont icon-diqiu" style="width: 30px;"></i>
                        <span>卫星</span>
                    </li>
                </ul>
            </div>
        </div>
        <div class="drawing" v-show="goldForm.graphType ? true : false">
            <span>正在绘制</span>
            <span style="color:#409eff;cursor: pointer;" @click="dialogClose">退出绘制</span>
        </div>

        <div id="map_ol" class="map_ol" />
        <!-- 弹窗要素 -->
        <div id="popup" class="ol-popup">
            <div class="tit">
                <p>{{ popupData.name }}</p>
                <i class="el-icon-close" @click="hideOverlay"></i>
            </div>
            <div class="info">
                <p>所属组织: {{ popupData.orgName }}</p>
                <p>地理位置: {{ popupData.address }}</p>
            </div>
            <div class="operate">
                <el-link type="primary" :underline="false" @click="showLineLayer(popupData.id)">编辑</el-link>
                <el-link type="danger" :underline="false" @click="deleteClick(popupData.id)">删除</el-link>
            </div>
        </div>
        <el-drawer title="新增/编辑" :before-close="dialogClose" :visible.sync="dialogVisible" :modal-append-to-body="false"
            :modal="false" direction="rtl" custom-class="demo-drawer" ref="drawer" :wrapperClosable="false" :size="420">
            <el-form ref="goldForm" :model="goldForm" :rules="rules" label-width="100px">
                <el-row>
                    <el-col :span="24">
                        <el-form-item label="标注名称:" prop="name">
                            <el-input v-model.trim="goldForm.name" placeholder="请输入标注名称"></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="所属组织:" prop="orgId">
                            <el-cascader v-model="goldForm.orgId" :show-all-levels="false" :options="orgTree"
                                :props="{ checkStrictly: true, emitPath: false, value: 'id', label: 'name', children: 'childrenList' }"
                                clearable style="width: 100%;"></el-cascader>
                        </el-form-item>
                    </el-col>

                    <el-col :span="24">
                        <el-form-item label="中心经度:" prop="lon">
                            <el-input v-model.trim="goldForm.lon" placeholder="请选择中心经度" readOnly></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="中心纬度:" prop="lat">
                            <el-input v-model.trim="goldForm.lat" placeholder="请选择中心纬度" readOnly></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24" v-if="goldForm.graphType === '2' || goldForm.graphType === '1'">
                        <el-form-item label="半径:" prop="radius">
                            <el-input v-model.trim="goldForm.radius" readOnly></el-input>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="图形类型:">
                            <el-tag>{{ getDrawType(goldForm.graphType) }}</el-tag>
                        </el-form-item>
                    </el-col>
                    <el-col :span="24">
                        <el-form-item label="备注:">
                            <el-input v-model.trim="goldForm.remark" type="textarea" placeholder="请输入备注"></el-input>
                        </el-form-item>
                    </el-col>

                </el-row>

            </el-form>
            <div class="dialog-footer">
                <el-button @click="dialogClose">取 消</el-button>
                <el-button type="primary" @click="onSave">确 定</el-button>

            </div>
        </el-drawer>

        <!-- <div id="btn_search" class="btn_view">
            <el-input v-model.trim="searchKey" placeholder="请输入地名搜索" class="input-with-select" style="width: 100%"
                @focus="showSearchPlan = true" @change="searchChange(0)">
                <el-button slot="append" icon="el-icon-search" @click="searchChange(0)" />
            </el-input>
            <div v-show="showSearchPlan" class="search_panel" :style="{ 'max-height': fixedAll ? '400px' : '' }">
                <div v-if="searchRes.searchPageList && searchRes.searchPageList.length">
                    <el-row v-for="(item) of searchRes.searchPageList" :key="item.hotPointID">
                        <el-col :span="20" style="overflow: hidden;">
                            地址:{{ item.address + item.name }}
                        </el-col>
                        <el-col :span="4">
                            <img src="@/assets/img/map/dingweiBlue.png" @click.stop="pointLocation(item)">
                        </el-col>
                    </el-row>
                </div>
                <el-empty v-else description="暂无搜索结果" />
                <div v-show="searchRes.searchPageList && searchRes.searchPageList.length" class="page-bottom">
                    <el-pagination layout="prev, pager, next" :page-size="10" :total="Number(searchRes.count)"
                        @current-change="currentChange" />
                </div>
            </div>
        </div> -->

    </div>
</template>
<script>

import Map from 'ol/Map'
import View from 'ol/View'

import { fromLonLat, transform } from 'ol/proj'
import * as olExtent from 'ol/extent'
import Feature from 'ol/Feature.js'
import { always, never, platformModifierKeyOnly, primaryAction } from 'ol/events/condition'
import { Draw, Modify, Translate, Select } from 'ol/interaction'
import { unByKey } from 'ol/Observable.js'
import GeoJSON from 'ol/format/GeoJSON'
import { createBox } from 'ol/interaction/Draw'
import VectorSource from 'ol/source/Vector'
import { defaults } from 'ol/control/defaults'
import VectorLayer from 'ol/layer/Vector'
import { Style, Fill, Stroke, Circle, Icon, Text } from 'ol/style'
import { Circle as GeoCircle, Point } from 'ol/geom'
import Overlay from 'ol/Overlay'
import tileMapLayers from '@/assets/oljs/tileMapLayer'
import { mapState } from 'vuex'
import fullScreen from '@/mixin/fullScreen'
import poinImg from '@/assets/img/map/dingweiBlue.png'
let olLayerCollect = {}
let interaction = {}
export default {
    name: 'OlMapEdit',
    mixins: [fullScreen],
    props: {
        orgTree: {
            type: Array,
            default() {
                return []
            }
        },
        mapLonLat: {
            type: Array,
            default: () => {
                return []
            }
        },
        isReadOnly: {
            type: Boolean,
            default: false
        },
        deleteId: {
            type: String,
            default: ''
        }

    },
    data() {
        return {
            searchKey: '',
            layersMap: null,
            olOsm: null,
            olMap: null,
            car: require('@/assets/img/map/dingwei.png'),
            url: {
                add: '/admin/base/element/add',
                delete: '/admin/base/element/delete',
                detail: '/admin/base/element/detail',
                modify: '/admin/base/element/modify',
                mainDelete: '/admin/base/element/delete'

            },
            mapData: {
                mapCiaLayer: 'cia',
                mapCiaUrl: 'http://t0.tianditu.gov.cn/cia_w/wmts?tk=',
                mapCvaLayer: 'cva',
                mapCvaUrl: 'http://t0.tianditu.gov.cn/cva_w/wmts?tk=',
                mapImgLayer: 'img',
                mapImgUrl: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=',
                mapVecLayer: 'vec',
                mapVecUrl: 'http://t0.tianditu.gov.cn/vec_w/wmts?tk='
            },
            fixedAll: false,
            showSearchPlan: false,
            mapPointName: '',
            pageStart: 0,
            searchRes: {
                searchPageList: [],
                count: 0
            },
            drawType: '', // 绘制类型
            draw: null,
            lineLayer: null,
            goldForm: {
                dotsList: [],
                graphType: '',
                id: '',
                lat: null,
                lon: null,
                name: '',
                orgId: '',
                radius: null,
                remark: ''
            },
            dialogVisible: false,
            rules: {
                name: { required: true, message: '请输入标注名称', trigger: 'blur' },
                orgId: { required: true, message: '请选择所属组织', trigger: 'blur' }
            },

            listenEvent: {},
            isIcon: false,
            DayTileMapLayer: [],
            mapTyped: 'white', // 切换卫星
            addOrEdit: 'add',
            popupData: {}// 弹窗展示属性

        }
    },
    computed: {
        ...mapState(['orgList']),
        getDrawType() {
            return function(type) {
                switch (type) {
                    case '1': return '点'
                    case '2': return '圆形'
                    case '3': return '矩形'
                    case '4': return '多边形'
                }
            }
        }
    },
    watch: {
        operationType: {
            handler(val) {
                this.addOrEdit = val
            }
        },
        deleteId: {
            handler(val) {
                if (val) {
                    this.deleteClick(val)
                }
            }
        }
    },
    created() { },
    mounted() {
        this.$nextTick(() => {
            if (!this.isReadOnly) {
                document.querySelector('#map_ol').addEventListener('mouseenter', () => {
                    this.showSearchPlan = false
                })
                // document.querySelector('#btn_search').addEventListener('mouseenter', () => {
                //     this.showSearchPlan = true
                // })
            }

            this.initMap()
        })
    },
    beforeDestroy() {
        unByKey(this.listenEvent)
        this.olMap = null
    },
    methods: {
        getEleList() {
            this.$ajax.post('/admin/base/element/list').then(res => {
                if (res.code !== 200) return false
                if (Array.isArray(res.data) && res.data.length) {
                    olLayerCollect.pointSource = new VectorSource()
                    res.data.forEach(item => {
                        const feature = new Feature({
                            geometry: new Point(transform([item.lon, item.lat], 'EPSG:4326', 'EPSG:3857')),
                            name: item.name,
                            id: item.id,
                            address: item.address,
                            orgName: item.orgName,
                            type: 'elePoint'

                        }
                        )
                        // feature.setProperties({...item})
                        feature.setStyle(new Style({
                            image: new Icon({
                                src: poinImg,
                                width: 32,
                                height: 32,
                                imgSize: [32, 32]

                            }),
                            text: new Text({
                                font: '10px 黑体',
                                // 基准线
                                textBaseline: 'top',
                                justify: 'center',
                                backgroundFill: new Fill({
                                    color: '#fff'
                                }),
                                backgroundStroke: new Stroke({
                                    color: '#333'
                                }),

                                offsetY: -30,
                                // 文本填充样式 3
                                fill: new Fill({
                                    color: '#333'
                                }),
                                padding: [2, 2, 2, 2],
                                text: item.name
                            })
                        }))
                        olLayerCollect.pointSource.addFeature(feature)
                    })
                }
                olLayerCollect.pointLayer = new VectorLayer({
                    source: olLayerCollect.pointSource

                })
                this.olMap.addLayer(olLayerCollect.pointLayer)
            })
        },
        mapChange() {
            this.mapTyped === 'white' ? this.mapTyped = 'black' : this.mapTyped = 'white'

            this.olMap.removeLayer(this.DayTileMapLayer[0])
            this.olMap.removeLayer(this.DayTileMapLayer[1])

            this.DayTileMapLayer = []
            this.DayTileMapLayer = tileMapLayers(this, this.mapTyped)
            this.olMap.addLayer(this.DayTileMapLayer[0])
            this.olMap.addLayer(this.DayTileMapLayer[1])
        },
        lineArea() {
            if (olLayerCollect.pointSource) {
                olLayerCollect.pointSource.clear()
            }
            if (olLayerCollect.pointLayer) {
                this.olMap.removeLayer(olLayerCollect.pointLayer)
            }
            if (olLayerCollect.overlay) {
                olLayerCollect.overlay.setPosition(null)
            }
            this.isIcon = !this.isIcon
            if (this.isIcon) {
                this.setDrawType('Circle', '2')
            } else {
                this.source.clear()
                this.olMap.removeInteraction(this.draw)
            }
        },
        transform3857To4326(lon, lat) { // 坐标转换
            return transform([Number(lon), Number(lat)], 'EPSG:3857', 'EPSG:4326')
        },
        transform4326To3857(lon, lat) {
            return transform([Number(lon), Number(lat)], 'EPSG:4326', 'EPSG:3857')
        },
        initMap() {
            this.DayTileMapLayer = tileMapLayers(this)
            this.olMap = new Map({
                layers: [...this.DayTileMapLayer],
                target: 'map_ol',
                controls: defaults({ attribution: false, zoom: false, rotate: false }).extend([
                ]),
                view: new View({
                    center: fromLonLat([120.186511, 30.258980]),
                    zoom: 8
                })
            })
            // 弹窗要素

            olLayerCollect.overlay = new Overlay({
                element: document.getElementById('popup'),
                autoPan: true,
                positioning: 'bottom-center',
                offset: [0, -15],
                animation: {
                    duration: 250
                }
            })
            // 添加到map
            this.olMap.addOverlay(olLayerCollect.overlay)

            // 创建源及图层
            this.source = new VectorSource({
                wrapX: false

            })

            this.lineLayer = new VectorLayer({
                source: this.source,
                // 样式
                style: new Style({
                    // 填充
                    fill: new Fill({
                        color: 'rgba(255,255,255,0.2)'
                    }),
                    // 线
                    stroke: new Stroke({
                        color: '#20a0ff',
                        widht: 2
                    }),
                    image: new Circle({
                        radius: 7,
                        fill: new Fill({
                            color: '#20a0ff'
                        })
                    })
                }),
                layerId: 'lineLayer'

            })
            this.olMap.addLayer(this.lineLayer)
            this.getEleList() // 渲染所有围栏的点图层
            this.listenEvent = this.olMap.on('click', this.mapClick)
        },
        mapClick(e) {
            this.olMap.forEachFeatureAtPixel(e.pixel, (feature) => { // 获取图层点击区域
                if (feature) {
                    const properties = feature.getProperties()
                    if (properties.type === 'elePoint') {
                        this.popupData = { ...properties }
                        olLayerCollect.overlay.setPosition(feature.getGeometry().getCoordinates())
                    } else {
                        olLayerCollect.overlay.setPosition(null)
                    }
                }
            })
        },
        // 绘制 多边形
        drawArea(geoData) {
            const geojsonObject = {
                type: 'FeatureCollection',
                crs: {
                    type: 'name',
                    properties: {
                        name: 'EPSG:3857'
                    }
                },
                features: []
            }

            let lonLatList = []
            let geometryType = ''
            let coordinates = []
            let CircleData = null
            switch (this.goldForm.graphType) {
                case '1':
                    geometryType = 'Point'
                    CircleData = new Point(transform([this.goldForm.lon, this.goldForm.lat], 'EPSG:4326', 'EPSG:3857'))
                    break
                case '2':
                    geometryType = 'Circle'
                    const that = this
                    CircleData = new GeoCircle(transform([that.goldForm.lon, that.goldForm.lat], 'EPSG:4326', 'EPSG:3857'), that.goldForm.radius)

                    break
                case '3':
                    geometryType = 'Polygon'
                    lonLatList = Array.isArray(geoData.dotsList) && geoData.dotsList.map((item) => {
                        return transform([item.lon, item.lat], 'EPSG:4326', 'EPSG:3857')
                    })
                    coordinates.push(lonLatList)
                    break
                case '4':
                    geometryType = 'Polygon'
                    lonLatList = Array.isArray(geoData.dotsList) && geoData.dotsList.map((item) => {
                        return transform([item.lon, item.lat], 'EPSG:4326', 'EPSG:3857')
                    })
                    coordinates.push(lonLatList)
                    break
            }

            if (geometryType === 'Polygon') {
                geojsonObject.features.push({
                    type: 'Feature',
                    geometry: {
                        type: geometryType,
                        coordinates: coordinates // 坐标

                    },
                    id: 'lineLayer'
                })

                const featuretest = new GeoJSON().readFeatures(geojsonObject)
                this.source.addFeatures(featuretest)
            } else {
                let feature = new Feature({
                    geometry: CircleData

                })
                feature.setId('lineLayer')

                this.source.addFeature(feature)
            }
            if (this.source?.getFeatures()?.[0]?.getGeometry()) {
                this.olMap.getView().fit(this.source.getFeatures()[0].getGeometry())
            }
        },
        setDrawType(typeName, type) {
            if (this.addOrEdit !== 'edit') {
                this.goldForm = this.$options.data().goldForm
            }
            this.goldForm.graphType = type
            this.source.clear()
            this.olMap.removeInteraction(this.draw)
            this.draw = this.drawing(typeName)
            this.olMap.addInteraction(this.draw)
            unByKey(this.translateend)

            this.drawstart = this.draw.on('drawstart', (e) => {
                this.source.clear()
            })

            // 绘制结束后处理事件
            this.drawend = this.draw.on('drawend', (e) => {
                this.addMoveInteraction()
                this.dialogVisible = true

                setTimeout(_ => {
                    this.source.getFeatures()[0].setId('lineLayer')
                })

                this.getLonLat('drawend', e)

                this.olMap.removeInteraction(this.draw)
            })
            if (type === '1') {
                this.goldForm.radius = 100
            }
        },
        addMoveInteraction() { // 平移交互
            // 先选择在修改.每次只编辑一个图形

            interaction.select = new Select()
            // 传入选中的图形

            // 这样做之后,需要点击选中要素才可以进行编辑
            interaction.modify = new Translate({
                features: interaction.select.getFeatures()
            })

            // 平移结束事件
            this.translateend = interaction.modify.on('translateend', (e) => {
                try {
                    this.getLonLat('translateend', e)
                } catch (e) {
                }
            })

            interaction.select && this.olMap.addInteraction(interaction.select)
            interaction.modify && this.olMap.addInteraction(interaction.modify)
        },
        getLonLat(type, e) {
            let geometry

            if (type === 'drawend') {
                geometry = e.feature.getGeometry()
            } else if (type === 'translateend' || type === 'modifyend') {
                geometry = e.features.item(0).getGeometry()
            }

            let dotsList = geometry.getCoordinates()

            const center = olExtent.getCenter(geometry.getExtent())

            this.goldForm.lon = this.transform3857To4326(center[0], center[1])[0]
            this.goldForm.lat = this.transform3857To4326(center[0], center[1])[1]

            switch (this.goldForm.graphType) {
                case '1': // 点

                    break
                case '2'://this.goldForm.radius = geometry.getRadius()

                    break
                case '3':// 矩形

                    this.goldForm.dotsList = dotsList[0].map((item, index) => {
                        return {
                            lon: this.transform3857To4326(item[0], item[1])[0],
                            lat: this.transform3857To4326(item[0], item[1])[1],
                            seq: index
                        }
                    })

                    break
                case '4': // 多边形

                    this.goldForm.dotsList = dotsList[0].map((item, index) => {
                        return {
                            lon: this.transform3857To4326(item[0], item[1])[0],
                            lat: this.transform3857To4326(item[0], item[1])[1],
                            seq: index
                        }
                    })

                    break
            }
        },
        drawing(typeName) {
            let geometryFunction
            if (typeName === 'Rectangle') {
                typeName = 'Circle'
                geometryFunction = createBox()
            }

            return new Draw({
                type: typeName,
                source: this.source,
                free: false,
                geometryFunction: geometryFunction
            })
        },
        showLineLayer(id) {
            this.source.clear()

            if (id) {
                if (olLayerCollect.pointSource) {
                    olLayerCollect.pointSource.clear()
                }
                if (olLayerCollect.pointLayer) {
                    this.olMap.removeLayer(olLayerCollect.pointLayer)
                }
                if (olLayerCollect.overlay) {
                    olLayerCollect.overlay.setPosition(null)
                }
                this.addOrEdit = 'edit'
                this.getDetail(id)
                this.editPaint()
                this.dialogVisible = true
            }
        },
        getDetail(id) {
            this.$ajax.post(this.url.detail, { id }).then(res => {
                if (res.code !== 200) return false
                this.goldForm = res.data
                this.drawArea(res.data)

                this.olMap.getView().setCenter(transform([Number(this.goldForm.lon), Number(this.goldForm.lat)], 'EPSG:4326', 'EPSG:3857'))
            })
        },
        getParentsById(list, id) {
            for (let i in list) {
                if (list[i].id === id) {
                    // 查询到就返回该数组对象的value
                    return [list[i].id]
                }
                if (list[i].childrenList) {
                    let node = this.getParentsById(list[i].childrenList, id)

                    if (node !== undefined) {
                        // 查询到把父节点加到数组前面
                        node.unshift(list[i].id)
                        return node
                    }
                }
            }
        },
        dialogClose() {
            this.source.clear()
            this.isIcon = false
            if (this.$refs.goldForm) {
                this.$refs.goldForm.resetFields()
            }

            this.goldForm = this.$options.data().goldForm
            if (interaction.modify) {
                this.olMap.removeInteraction(interaction.modify)
            }
            if (interaction.select) {
                this.olMap.removeInteraction(interaction.select)
            }
            if (this.modifystart) {
                unByKey(this.modifystart)
            }
            if (this.modifyend) {
                unByKey(this.modifyend)
            }
            if (this.drawend) {
                unByKey(this.drawend)
            }
            if (this.drawstart) {
                unByKey(this.drawstart)
            }
            if (this.translateend) {
                unByKey(this.translateend)
            }
            this.olMap.removeInteraction(this.draw)
            if (olLayerCollect.pointSource) {
                olLayerCollect.pointSource.clear()
            }
            if (olLayerCollect.pointLayer) {
                this.olMap.removeLayer(olLayerCollect.pointLayer)
            }
            this.dialogVisible = false
            this.getEleList()
        },
        onSave() {
            this.$refs['goldForm'].validate((valid) => {
                if (valid) {
                    const url = this.goldForm.id ? this.url.modify : this.url.add
                    this.$ajax.post(url, this.goldForm).then(res => {
                        if (res.code !== 200) return false
                        this.$message.success('操作成功')
                        this.dialogClose()
                        this.$emit('updatePage')
                    })
                }
            })
        },
        searchPlace(point) {
            const params = {
                lat: point[1],
                lon: point[0]
            }
            this.$ajax.post('/admin/map/word/geocoder', params).then((res) => {
                if (res.code !== 200) return false
            })
        },
        calculateCenter(geometry) {
            let center, coordinates, minRadius
            const type = geometry.getType()
            if (type === 'Polygon') {
                let x = 0
                let y = 0
                let i = 0
                coordinates = geometry.getCoordinates()[0].slice(1)
                coordinates.forEach(function(coordinate) {
                    x += coordinate[0]
                    y += coordinate[1]
                    i++
                })
                center = [x / i, y / i]
            } else if (type === 'LineString') {
                center = geometry.getCoordinateAt(0.5)
                coordinates = geometry.getCoordinates()
            } else {
                center = olExtent.getCenter(geometry.getExtent())
            }
            let sqDistances
            if (coordinates) {
                sqDistances = coordinates.map(function(coordinate) {
                    const dx = coordinate[0] - center[0]
                    const dy = coordinate[1] - center[1]
                    return dx * dx + dy * dy
                })
                minRadius = Math.sqrt(Math.max.apply(Math, sqDistances)) / 3
            } else {
                minRadius = Math.max(olExtent.getWidth(geometry.getExtent()), olExtent.getHeight(geometry.getExtent())) / 3
            }
            return {
                center: center,
                coordinates: coordinates,
                minRadius: minRadius,
                sqDistances: sqDistances
            }
        },
        judgeShape(e) {
            let type = e.getType()
            if (type === 'Polygon') {
                let arr = e.getCoordinates().flat()
                if (arr.length === 5) {
                    const rect = arr.slice(0, 4)
                    if ((rect[0][0] === rect[1][0] && rect[0][1] === rect[3][1]) || (rect[0][1] === rect[1][1] && rect[0][0] === rect[3][0])) {
                        type = 'Rectangle'
                    }
                }
            } else if (type === 'LineString') {
                type = 'Line'
            }
            return type
        },

        editPaint() {
            this.addMoveInteraction()
            const defaultStyle = new Modify({ source: this.source }).getOverlay().getStyleFunction()
            let _this = this
            const modify = new Modify({
                source: this.source,
                condition: function(event) {
                    return primaryAction(event) && !platformModifierKeyOnly(event)
                },
                deleteCondition: never,
                insertVertexCondition: always,
                style: function(feature) {
                    let type = _this.judgeShape(feature.get('geometries')[0])
                    if (type !== 'Line') {
                        feature.get('features').forEach(function(modifyFeature) {
                            const modifyGeometry = modifyFeature.get('modifyGeometry')
                            if (modifyGeometry) {
                                const point = feature.getGeometry().getCoordinates()
                                let modifyPoint = modifyGeometry.point
                                if (!modifyPoint) {
                                    // save the initial geometry and vertex position
                                    modifyPoint = point
                                    modifyGeometry.point = modifyPoint
                                    modifyGeometry.geometry0 = modifyGeometry.geometry
                                    // get anchor and minimum radius of vertices to be used
                                    const result = _this.calculateCenter(modifyGeometry.geometry0)
                                    modifyGeometry.center = result.center
                                    modifyGeometry.minRadius = result.minRadius
                                }

                                const center = modifyGeometry.center
                                const minRadius = modifyGeometry.minRadius
                                let dx, dy
                                dx = modifyPoint[0] - center[0]
                                dy = modifyPoint[1] - center[1]
                                const initialRadius = Math.sqrt(dx * dx + dy * dy)
                                if (initialRadius > minRadius) {
                                    const initialAngle = Math.atan2(dy, dx)
                                    dx = point[0] - center[0]
                                    dy = point[1] - center[1]
                                    const currentRadius = Math.sqrt(dx * dx + dy * dy)
                                    if (currentRadius > 0) {
                                        const currentAngle = Math.atan2(dy, dx)

                                        const geometry = modifyGeometry.geometry0.clone()
                                        geometry.scale(currentRadius / initialRadius, undefined, center)
                                        const typeName = modifyGeometry.geometry0.getType()
                                        if (typeName === 'Polygon') {
                                            let shapeName = _this.judgeShape(modifyGeometry.geometry0)
                                            if (shapeName !== 'Rectangle') {
                                                geometry.rotate(currentAngle - initialAngle, center)
                                            }
                                        } else if (typeName === 'Circle') {
                                            geometry.translate(dx, dy)
                                        } else if (typeName === 'Point') {
                                            geometry.translate(dx, dy)
                                        }
                                        modifyGeometry.geometry = geometry
                                    }
                                }
                            }
                        })
                    }
                    return defaultStyle(feature)
                }
            })
            this.olMap.addInteraction(modify)
            const trans = new Translate({
                condition: function(event) {
                    return primaryAction(event) && platformModifierKeyOnly(event)
                },
                layers: [this.lineLayer]
            })
            this.olMap.addInteraction(trans)
            this.modifystart = modify.on('modifystart', e => {
                let _this = this
                e.features.forEach(function(feature) {
                    let shape = _this.judgeShape(feature.getGeometry())
                    if (shape === 'Line' || shape === 'Polygon' || shape === 'Circle') {
                        // 当类型为线、多边形(矩形除外)、圆形时,允许新增点
                    } else {
                        // 克隆图形,不能新增点
                        feature.set('modifyGeometry', { geometry: feature.getGeometry().clone() }, true)
                    }
                })
            })

            this.modifyend = modify.on('modifyend', e => {
                // let _this = this
                e.features.forEach(function(feature) {
                    const modifyGeometry = feature.get('modifyGeometry')
                    if (modifyGeometry) {
                        feature.setGeometry(modifyGeometry.geometry)
                        feature.unset('modifyGeometry', true)
                    }
                    // let targets = _this.WEvents.get('WGraph(modifyend)')
                    // _this.drawFeature = _this.buildFeature(feature)
                    // feature.set('WTYPE', 'OlDraw')
                    // window.dispatchEvent(targets.costomEvent)
                })

                this.getLonLat('modifyend', e)
            })
        },
        async deleteClick(id) {
            // // 删除操作
            // this.$emit('delete', id)

            const ret = await this.$confirm('确认永久删除此项吗?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).catch(() => { })
            if (ret !== 'confirm') {
                return
            }

            const res = await this.$ajax.post(this.url.mainDelete, { id })
            if (res.code === 200) this.$message.success('操作成功')
            this.$emit('searchMainTable')
            // if (olLayerCollect.pointSource) {
            //     olLayerCollect.pointSource.clear()
            // }
            if (olLayerCollect.overlay) {
                olLayerCollect.overlay.setPosition(null)
            }
            if (olLayerCollect.pointLayer) {
                this.olMap.removeLayer(olLayerCollect.pointLayer)
            }
            this.getEleList()
        },
        hideOverlay() {
            olLayerCollect.overlay.setPosition(null)
        }

    }
}
</script>
<style lang='scss' scoped>
.map_box {
    display: flex;
    flex-direction: column;
    position: relative;

    .fullScreen {
        position: absolute;
        right: 30px;
        top: -40px;
        width: 40px;
        height: 40px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;

        i {
            font-size: 24px;
        }
    }

    .drawType {
        height: 40px;
        position: absolute;
        left: 0;
        top: 0;
        padding: 0 20px;
        z-index: 2;
        width: 100%;
        background-color: #fff;
        display: flex;
        justify-content: space-between;

        .type_box {
            display: flex;
        }

        .active {

            span,
            i {
                color: #20a0ff;
            }

        }

        .wx {
            float: right;
        }

        ul {
            display: flex;
            align-items: center;
            height: 100%;

            li {
                margin-right: 20px;
                cursor: pointer;

                span {
                    font-size: 14px;
                }
            }
        }

        .type_box ul:last-child {
            border-left: 1px solid #ccc;
            padding-left: 20px;
        }
    }

    .map_ol {
        flex: 1;
    }
}

.btn_view {
    position: absolute;
    top: 10px;
    left: 10px;
    width: 200px;
    z-index: 10;
}

.btn_fill {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 10;

}

.fill_all_po {
    position: absolute;
    top: 0;
    left: 0;
    z-index: 9;
}

.search_panel {
    position: relative;
    background-color: #fff;
    max-height: 100px;
    overflow: auto;

    .el-row {
        padding: 4px;
    }

    .el-col {
        &:hover {
            cursor: pointer;
            opacity: 0.8;
        }
    }

    .c_icon {
        font-size: 16px;
    }
}

.page-bottom {
    position: sticky;
    bottom: 0;
    left: 0;
    width: 100%;
    overflow: auto;
}

.common_layout_contain {
    .map_dialog {
        position: relative;
    }

    .el-drawer__wrapper,
    .el-drawer__container {
        position: absolute !important;
        width: 420px !important;
        right: 0 !important;
        top: 40px !important;
        left: auto !important;
        height: calc(100% - 39px);
    }

}

::v-deep .el-drawer {
    .el-drawer__header {
        background-color: #fff;
        margin-bottom: 0;
        padding: 10px;
    }

    .el-drawer__body {
        padding: 0 10px;
    }

    .dialog-footer {
        display: flex;
        justify-content: center;
    }
}

.drawing {
    position: absolute;

    top: 50px;
    left: 50%;
    transform: translate(-50%);
    z-index: 2;
    border: 1px solid #20a0ff;
    background-color: rgba(255, 255, 255, 0.8);
    display: flex;
    padding: 0 10px;

    span {
        display: block;
        padding: 5px 5px;
    }
}

.ol-popup {

    position: relative;
    max-width: 360px;
    min-width: 200px;
    padding: 10px;
    border-radius: 5px;
    border: 1px solid #393939;
    background-color: #fff;

    &::after {
        content: '';
        position: absolute;
        bottom: -20px;
        left: 50%;
        transform: translate(-50%);
        width: 0;
        height: 0;
        border: 10px solid transparent;
        border-top-color: rgb(255, 255, 255);
        z-index: 2;
    }

    &::before {
        content: '';
        position: absolute;
        bottom: -22px;
        left: 50%;
        transform: translate(-50%);
        width: 0;
        height: 0;
        border: 11px solid transparent;
        border-top-color: rgb(38, 38, 38);
        z-index: 1;
    }

    .tit {
        display: flex;
        align-items: flex-start;
        border-bottom: 1px solid #f5f5f5;

        i {
            width: 30px;
            height: 30px;
            display: flex;
            align-items: center;
            justify-content: center;

        }

        p {
            flex: 1;
            font-size: 18px;
            color: #333;
            font-weight: 600;
            word-wrap: break-word;
            max-width: 300px;
        }
    }

    .info {
        font-size: 14px;
        padding: 10px 0;

        border-bottom: 1px solid #f5f5f5;

        P {
            margin-top: 5px;
        }
    }

    .operate {
        display: flex;
        align-items: center;
        justify-content: end;

        .el-link {
            padding: 5px;
        }
    }
}</style>

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值