废话不多说,代码端上来

<template>

<div ref="map" id="map">    <div id="contextmenu_container" class="contextmenu">      <ul>        <li @click="drawFeature">          <a href="#">绘制</a>        </li>        <li @click="toHome">          <a href="#">罕用区域</a>        </li>        <li @click="outputJson">          <a href="#">输入Json</a>        </li>        <li @click="measure('distence')">          <a href="#">测距</a>        </li>        <li @click="measure('area')">          <a href="#">测面</a>        </li>        <li @click="measure('angle')">          <a href="#">量角</a>        </li>        <li @click="fullscreen" v-html="textarr">          <a href="#">全屏</a>        </li>        <li @click="clear">          <a href="#">革除</a>        </li>        <li @click="pointPopup">          <a href="#">点坐标</a>        </li>        <li @click="zoomIn">          <a href="#">放大</a>        </li>        <li @click="zoomOut">          <a href="#">放大</a>        </li>        <li @click="refresh">          <a href="#">刷新</a>        </li>      </ul>    </div>    <div id="popup" class="ol-popup">      <a        href="#"        ref="external nofollow"        id="popup-closer"        class="ol-popup-closer"      ></a>      <div id="popup-content"></div>    </div>  </div>

<import>

import 'ol/ol.css'import Map from 'ol/Map'import View from 'ol/View'import VectorSource from 'ol/source/Vector'import OSM from 'ol/source/OSM'import VectorLayer from 'ol/layer/Vector'import TileLayer from 'ol/layer/Tile'import { GeoJSON } from 'ol/format'import { Draw } from 'ol/interaction'import Overlay from 'ol/Overlay'// 线条几何形态。import { LineString } from 'ol/geom'import Feature from 'ol/Feature'// 应用返回的键或import { unByKey } from 'ol/Observable'// 获取几何形态的球形长度和面积import { getLength, getArea, offset } from 'ol/sphere'import Style from 'ol/style/Style'import Stroke from 'ol/style/Stroke'import Fill from 'ol/style/Fill'import Circle from 'ol/style/Circle'import { ScaleLine, defaults as defaultControls } from 'ol/control'import MousePosition from 'ol/control/MousePosition'import { createStringXY } from 'ol/coordinate'import Icon from 'ol/style/Icon'import Text from 'ol/style/Text'import { transform } from 'ol/proj'import { fromLonLat } from 'ol/proj'import Point from 'ol/geom/Point'import ImageSource from 'ol/source/Image'import { fromExtent } from 'ol/geom/Polygon'

重头戏

export default

data() {    return {      map: null,      vectorLayer: null,      vectorSource: null,      draw: null,      select: null,      modify: null,      editorBtnText: '编辑',      overlay: null,      textarr: '全屏',      measureType: 'diatence',      tipDiv: null,      pointermoveEvent: null, // 地图pointermove事件      sketchFeature: null, // 绘制的因素      geometryListener: null, // 因素几何change事件      measureResult: '0', // 测量后果      pointLayer: null,    }  },

mounted

var baseLayer = new TileLayer({      source: new OSM(),    })this.vectorSource = new VectorSource({      wrapX: false,    })    this.vectorLayer = new VectorLayer({      source: this.vectorSource,    })    const scaleLineControl = new ScaleLine({      target: 'scalebar',      className: 'ol-scale-line',    })    const mousePositionControl = new MousePosition({      coordinateFormat: createStringXY(4),      projection: 'EPSG:4326',      className: 'custom-mouse-position',      target: document.getElementById('mouse-position'),    })    this.map = new Map({      layers: [baseLayer, this.vectorLayer],      controls: defaultControls({        zoom: false,        // rotate: false,        attribution: false,      }).extend([scaleLineControl, mousePositionControl]),      target: 'map',      view: new View({        projection: 'EPSG:4326',        center: [123.476492, 25.744676],        zoom: 8,      }),    })    this.map.addControl(scaleLineControl)

办法定义

refresh() {      let that = this      that.reload()    },    pointPopup() {      var container = document.getElementById('popup')      var content = document.getElementById('popup-content')      var popupCloser = document.getElementById('popup-closer')      this.overlay = new Overlay({        element: container,        antoPan: true,        autoPanAnimation: {          duration: 250,        },      })      this.map.addOverlay(this.overlay)      let that = this      that.map.on('singleclick', function(evt) {        let coordinate = transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326')        let coordinate2 = evt.coordinate        that.addPoints(coordinate)        content.innerHTML = `          <p>你点击了这里:</p>          <p>坐标:</p>X:${coordinate2[0]} Y:${coordinate2[1]}`        that.overlay.setPosition(coordinate2) //把 overlay 显示到指定的 x,y坐标      })      popupCloser.onclick = function() {        that.overlay.setPosition(undefined)        popupCloser.blur()        return false      }    },    addPoints(coordinate) {      const feature = new Feature({        geometry: new Point(fromLonLat(coordinate)),        name: 'isbig',      })      const iconStyle = new Style({        image: new Icon({          anchor: [0.5, 0.5],          src: 'https://openlayers.org/en/v4.6.5/examples/data/icon.png',        }),      })      feature.setStyle(iconStyle)      const vectorSource = new VectorSource({})      this.pointLayer = new VectorLayer({        source: vectorSource,      })      this.map.addLayer(this.pointLayer)      this.vectorSource.addFeature(feature)      return iconStyle    },    drawFeature() {      this.draw = new Draw({        source: this.vectorSource,        // 用此实例绘制的几何形态类型。        type: 'Polygon',      })      this.map.addInteraction(this.draw)      // 绘制实现      this.draw.on('drawend', () => {        this.map.removeInteraction(this.draw)        this.draw = null      })    },    toHome() {      var to = [120.38, 36.07]      var view = this.map.getView()      view.setZoom(8),        view.animate({          center: to,          duration: 0,        })    },    // 输入矢量图层因素为GeoJson数据    outputJson() {      let features = this.vectorSource.getFeatures()      let jsonObj = new GeoJSON().writeFeatures(features)      console.log('->GeoJson格局数据:', jsonObj)    },    creatDraw(type) {      let maxPoints = null      if (this.measureType == 'angle') maxPoints = 3      else maxPoints = null      // 矢量图层源      let vectorSource = new VectorSource({        wrapX: false,      })      // 矢量图层      this.vectorLayer = new VectorLayer({        source: vectorSource,        style: new Style({          fill: new Fill({            color: 'rgba(252, 86, 49, 0.1)',          }),          stroke: new Stroke({            color: '#fc5531',            width: 3,          }),          image: new Circle({            radius: 0,            fill: new Fill({              color: '#fc5531',            }),          }),        }),        name: '测量图层',      })      this.map.addLayer(this.vectorLayer)      this.draw = new Draw({        source: vectorSource,        type: type,        maxPoints: maxPoints,        style: new Style({          fill: new Fill({            color: 'rgba(252, 86, 49, 0.1)',          }),          stroke: new Stroke({            color: '#fc5531',            lineDash: [10, 10],            width: 3,          }),          image: new Circle({            radius: 0,            fill: new Fill({              color: '#fc5531',            }),          }),        }),        // 绘制时点击处理事件        condition: (evt) => {          // 测距时增加点标注          if (            this.measureResult != '0' &&            !this.map.getOverlayById(this.measureResult) &&            this.measureType == 'distence'          )            this.creatMark(              null,              this.measureResult,              this.measureResult            ).setPosition(evt.coordinate)          return true        },      })      this.map.addInteraction(this.draw)      /**       * 绘制开始事件       */      this.draw.on('drawstart', (e) => {        this.sketchFeature = e.feature        let proj = this.map.getView().getProjection()        //******间隔测量开始时*****//        if (this.measureType == 'distence') {          this.creatMark(null, '终点', 'start').setPosition(            this.map.getCoordinateFromPixel(e.target.downPx_)          )          this.tipDiv.innerHTML = '总长:0 m</br>单击确定地点,双击完结'          this.geometryListener = this.sketchFeature            .getGeometry()            .on('change', (evt) => {              this.measureResult = this.distenceFormat(                getLength(evt.target, {                  projection: 'EPSG:3857',                  radius: 6378137,                })              )              this.tipDiv.innerHTML =                '总长:' + this.measureResult + '</br>单击确定地点,双击完结'            })        }        //******面积测量开始时*****//        else if (this.measureType == 'area') {          this.tipDiv.innerHTML = '面积:0 m<sup>2</sup></br>持续单击确定地点'          this.geometryListener = this.sketchFeature            .getGeometry()            .on('change', (evt) => {              if (evt.target.getCoordinates()[0].length < 4)                this.tipDiv.innerHTML =                  '面积:0m<sup>2</sup></br>持续单击确定地点'              else {                this.measureResult = this.formatArea(                  getArea(evt.target, { projection: proj, radius: 6378137 })                )                this.tipDiv.innerHTML =                  '面积:' + this.measureResult + '</br>单击确定地点,双击完结'              }            })        }        //******角度测量开始时*****//        else if (this.measureType == 'angle') {          this.tipDiv.innerHTML = '持续单击确定顶点'          this.geometryListener = this.sketchFeature            .getGeometry()            .on('change', (evt) => {              if (evt.target.getCoordinates().length < 3)                this.tipDiv.innerHTML = '持续单击确定顶点'              else {                this.measureResult = this.formatAngle(evt.target)                this.tipDiv.innerHTML =                  '角度:' + this.measureResult + '</br>持续单击完结'              }            })        }      })      /**       * 绘制开始事件       */      this.draw.on('drawend', (e) => {        let closeBtn = document.createElement('span')        closeBtn.innerHTML = '×'        closeBtn.title = '革除测量'        closeBtn.style =          'width: 10px;height:10px;line-height: 12px;text-align: center;border-radius: 5px;display: inline-block;padding: 2px;color: rgb(255, 68, 0);border: 2px solid rgb(255, 68, 0);background-color: rgb(255, 255, 255);font-weight: 600;position: absolute;top: -25px;right: -2px;cursor: pointer;'        closeBtn.addEventListener('click', () => {          this.clearMeasure()        })        //******间隔测量完结时*****//        if (this.measureType == 'distence') {          this.creatMark(closeBtn, null, 'close1').setPosition(            e.feature.getGeometry().getLastCoordinate()          )          this.creatMark(            null,            '总长:' + this.measureResult + '',            'length'          ).setPosition(e.feature.getGeometry().getLastCoordinate())          this.map.removeOverlay(this.map.getOverlayById(this.measureResult))        }        //******面积测量完结时*****//        else if (this.measureType == 'area') {          this.creatMark(closeBtn, null, 'close2').setPosition(            e.feature              .getGeometry()              .getInteriorPoint()              .getCoordinates()          )          this.creatMark(            null,            '总面积:' + this.measureResult + '',            'area'          ).setPosition(            e.feature              .getGeometry()              .getInteriorPoint()              .getCoordinates()          )        }        //******角度测量完结时*****//        else if (this.measureType == 'angle') {          this.creatMark(closeBtn, null, 'close3').setPosition(            e.feature.getGeometry().getCoordinates()[1]          )          this.creatMark(            null,            '角度:' + this.measureResult + '',            'angle'          ).setPosition(e.feature.getGeometry().getCoordinates()[1])        }        // 进行测量        this.stopMeasure()      })    },    measure(type) {      if (this.draw != null) return false // 避免在绘制过程再创立测量      this.measureType = type      if (this.vectorLayer != null) this.clearMeasure()      this.tipDiv = document.createElement('div')      this.tipDiv.innerHTML = '单击确定终点'      this.tipDiv.className = 'tipDiv'      this.tipDiv.style =        'width:auto;height:auto;padding:4px;border:1px solid #fc5531;font-size:12px;background-color:#fff;position:relative;top:60%;left:60%;font-weight:600;'      let overlay = new Overlay({        element: this.tipDiv,        autoPan: false,        positioning: 'bottom-center',        id: 'tipLay',        stopEvent: false, //进行事件流传到地图      })      this.map.addOverlay(overlay)      this.pointermoveEvent = this.map.on('pointermove', (evt) => {        overlay.setPosition(evt.coordinate)      })      if (this.measureType == 'distence' || this.measureType == 'angle') {        this.creatDraw('LineString')      } else if (this.measureType == 'area') {        this.creatDraw('Polygon')      }    },    creatMark(markDom, txt, idstr) {      if (markDom == null) {        markDom = document.createElement('div')        markDom.innerHTML = txt        markDom.style =          'width:auto;height:auto;padding:4px;border:1px solid #fc5531;font-size:12px;background-color:#fff;position:relative;top:60%;left:60%;font-weight:600;'      }      let overlay = new Overlay({        element: markDom,        autoPan: false,        positioning: 'bottom-center',        id: idstr,        stopEvent: false,      })      this.map.addOverlay(overlay)      return overlay    },    distenceFormat(length) {      let output      if (length > 100) {        output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km' //换算成km单位      } else {        output = Math.round(length * 100) / 100 + ' ' + 'm' //m为单位      }      return output //返回线的长度    },    formatArea(area) {      let output      if (area > 10000) {        output =          Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>' //换算成km单位      } else {        output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>' //m为单位      }      return output //返回多边形的面积    },    formatAngle(line) {      var coordinates = line.getCoordinates()      var angle = '0°'      if (coordinates.length == 3) {        const disa = getLength(          new Feature({            geometry: new LineString([coordinates[0], coordinates[1]]),          }).getGeometry(),          {            radius: 6378137,            projection: this.map.getView().getProjection(),          }        )        const disb = getLength(          new Feature({            geometry: new LineString([coordinates[1], coordinates[2]]),          }).getGeometry(),          {            radius: 6378137,            projection: this.map.getView().getProjection(),          }        )        const disc = getLength(          new Feature({            geometry: new LineString([coordinates[0], coordinates[2]]),          }).getGeometry(),          {            radius: 6378137,            projection: this.map.getView().getProjection(),          }        )        var cos = (disa * disa + disb * disb - disc * disc) / (2 * disa * disb) // 计算cos值        angle = (Math.acos(cos) * 180) / Math.PI // 角度值        angle = angle.toFixed(2) // 后果保留两位小数      }      if (isNaN(angle)) return '0°'      else return angle + '°' // 返回角度    },    // 进行测量    stopMeasure() {      this.tipDiv = null      this.map.removeInteraction(this.draw)       this.draw = null      this.map.removeOverlay(this.map.getOverlayById('tipLay'))     },    //革除测量    clearMeasure() {      this.vectorLayer.getSource().clear()      this.map.getOverlays().clear()      //移除监听事件      unByKey(this.pointermoveEvent)       unByKey(this.geometryListener)       this.pointermoveEvent = null      this.geometryListener = null      this.measureResult = '0'    },    // 全屏    fullscreen() {      if (this.textarr == '全屏') {        this.textarr = '放大'        let rfs =          this.$refs.map.requestFullScreen ||          this.$refs.map.webkitRequestFullScreen ||          this.$refs.map.mozRequestFullScreen ||          this.$refs.map.msRequestFullScreen        if (typeof rfs !== 'undefined' && rfs) {          rfs.call(this.$refs.map)          console.log('1全屏')        } else if (typeof window.ActiveXObject !== 'undefined') {          // for IE,这里其实就是模仿了按下键盘的F11,使浏览器全屏          // eslint-disable-next-line no-undef          let wscript = new ActiveXObject('WScript.Shell')          console.log(wscript)          if (wscript != null) {            wscript.SendKeys('{F11}')            console.log('3全屏')          }          console.log('2全屏')        }      } else {        // el.webkitExitFullscreen()        this.textarr = '全屏'        let cfs =          document.exitFullscreen ||          document.msExitFullscreen ||          document.mozCancelFullScreen ||          document.webkitCancelFullScreen        console.log(cfs, 'cfs')        if (typeof cfs !== 'undefined' && cfs) {          cfs.call(document)          console.log('4全屏')        } else if (typeof window.ActiveXObject !== 'undefined') {          // for IE,这里和fullScreen雷同,模仿按下F11键退出全屏          // eslint-disable-next-line no-undef          let wscript = new ActiveXObject('WScript.Shell')          console.log('5全屏')          if (wscript != null) {            wscript.SendKeys('{F11}')            console.log('6全屏')          }        }      }      // this.map.addControl(new FullScreen())    },    // 革除    clear() {      this.vectorLayer.getSource().clear()      this.map.getOverlays().clear()    },    zoomIn() {      let view = this.map.getView()      let zoom = view.getZoom()      view.setZoom(zoom + 1)    },    zoomOut() {      let view = this.map.getView()      let zoom = view.getZoom()      view.setZoom(zoom - 1)    },  },

css款式这玩意就不展现了,菜鸟一个,请多指教