ol问题总结一

标题一、shpjs将.zip文件转成geoJson

一、npm install shpjs

二、import shp from 'shpjs'

三、

async setLayerSource() {

const geoJsonData = await shp(dataUrl)

}

一直报错:是因为Buffer这个插件一直没找到

 Uncaught Error: nodebuffer is not supported by this browser

解决办法

npm install node-polyfill-webpack-plugin

vue.config.js

const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')

module.exports = {

configureWebpack: (config) => {

config.plugins.push(new NodePolyfillPlugin())

}

}

标题二、source加载 url + format加载图层,获取source数据::source.on('change')

标题三、加载点图层时使用图片::,可设置 new Icon({anchor:[0.5,0.5]})默认是图片中心点和位置点点吻合

标题四、

kml格式的数据,设置的图层样式未生效::有个new KML({extractStyles: true})属性,是否使用kml文件中的样式。默认是true

四 、

根据title获取图层数组后,执行删除后,图层未被删除

removeLayers (title) {
  const layers = this.getLayers({ title })
  for (let i = 0; i < layers.length; i++) {
    if (layers[i]) {
      layers[i]?.getSource()?.clear()
      this.map.removeLayer(layers[i])
    }
  }
// 使用forEach循环删除,是不生效的 layers.forEach(layer => map.removeLayer(layer))
// 修改为 for循环进行图层删除
}

五、将地图导出成图片:1.获取地图上得图层canvas 2.html2canvas将图例等自行写得dom转成canvas

遇到得问题:1.在屏幕做了缩放后,图例dom位置不对 2. 标题等打印出来后,文字底部不全

解决方法:1.根据屏幕缩放比重新计算dom得top、left位置 2. 更换html2canvas版本

其他问题:

1. 文字样式丢失且都变成为最小号字体。

解决方案: 需要截图的节点根样式添加font-variant: normal;

2. 文字向下偏移。

解决方案: 指定html2canvas的版本号为1.0.0-alpha.12

3. 不完整,缺失,留白。

出现情况: 当截图区域超过视图高度,且滚动条未处在顶部时,会出现。

解决方案: 截图之前控制滚动条至顶部。

4. 模糊,不清晰。

出现情况: 通常是图片设置为背景的情况下,截图会比较模糊。

解决方案: 将背景图通过img标签加定位的方式实现

 // 地图图层、标题、比例尺、图例导出
    exportMapLayers(config = {}) {
      let { exportImgName, titleDomId, titleLeft, titleTop, legendDomId, legendLeft, legendTop, isExportScale, scaleLeft, scaleTop } = config
      this.map.once('postrender', () => {
        // openayer做了适配屏幕分辨率,我只取图层类得canvas
        let canvasDom = document.querySelectorAll('.mapContainerClass > .ol-viewport > .ol-layers > .ol-layer > canvas')
        if (canvasDom?.length) {
          let newCanvas = document.createElement('canvas')
          newCanvas.width = canvasDom[0].width
          newCanvas.height = canvasDom[0].height
          newCanvas.backgroundColor = 'rgba(0,0,0,0)'
          for (let i = 0; i < canvasDom.length; i++) {
            if (canvasDom[i]) {
              newCanvas.getContext('2d').drawImage(canvasDom[i], 0, 0)
            }
          }

          let promiseArr = []
          // 动态图标使用overlay实现的,也许导出,还有其他需要导出的overlay,人为加一个class进行区分
          let cloneOverlayDoms = document.querySelector('.ol-overlaycontainer-stopevent').cloneNode(true)
          let cloneChildNodes = cloneOverlayDoms.childNodes
          if (cloneChildNodes?.length) {
            let removeList = []
            cloneChildNodes.forEach((node) => {
              if (!node.classList.contains(exportOverlayStr)) {
                removeList.push(node)
              }
            })
            for (let i = 0; i < removeList.length; i++) {
              cloneOverlayDoms.removeChild(removeList[i])
            }
            document.body.appendChild(cloneOverlayDoms)
            let overlayPromise = this.createPromiseDomToCanvas(cloneOverlayDoms, 0, 0, newCanvas, 'overlay')
            promiseArr.push(overlayPromise)
          }
          if (titleDomId) {
            let titleDom = document.getElementById(titleDomId) // titleId
            if (titleDom) {
              let titlePromise = this.createPromiseDomToCanvas(titleDom, titleLeft, titleTop, newCanvas)
              promiseArr.push(titlePromise)
            }
          }
          if (legendDomId) {
            let legendDom = document.getElementById(legendDomId)
            if (legendDom) {
              let legendPromise = this.createPromiseDomToCanvas(legendDom, legendLeft, legendTop, newCanvas)
              promiseArr.push(legendPromise)
            }
          }
          if (isExportScale) {
            let scaleLineDom = document.querySelector('.ol-scale-line')
            if (scaleLineDom) {
              let scalePromise = this.createPromiseDomToCanvas(scaleLineDom, scaleLeft, scaleTop, newCanvas)
              promiseArr.push(scalePromise)
            }
          }
          if (promiseArr.length) {
            Promise.all(promiseArr).then(() => {
              this.canvasToImage(newCanvas, exportImgName)
            })
          } else {
            this.canvasToImage(newCanvas, exportImgName)
          }
        }
      })
      this.map.renderSync()
    },
// 将dom元素转成canvas
    createPromiseDomToCanvas(dom, domLeft, domTop, newCanvas,type) {
      let tp = document.documentElement.clientTop
      let lt = document.documentElement.clientLeft

      //屏幕缩放比
      const screenScale = getScreenScale()
      return new Promise((resolve) => {
        html2canvas(dom, { backgroundColor: null, allowTaint: true, useCORS: true, scrollY: 0, scrollX: 0 }).then((domCanvas) => {
          let ctx = newCanvas.getContext('2d')
          domCanvas.backgroundColor = 'rgba(0,0,0,0)'

          if (type === 'overlay') {
            ctx.drawImage(domCanvas, 0, 0)
            document.body.removeChild(dom)
          } else {
            let mapDomBounding = document.querySelector('.mapContainerClass')?.getBoundingClientRect()
            let mapTopToView = mapDomBounding?.top || 0 // 地图元素距离视窗顶部的的距离
            let mapLeftToView = mapDomBounding?.left || 0 // 地图元素左边框距离视窗左边的的距离

            let domRect = dom?.getBoundingClientRect()
            let domTopToView = domRect?.top // 元素上边框距离视窗顶部的的距离
            let domLeftToView = domRect?.left // 元素左边框距离视窗左边的的距离
            let finalX = (isNullText(domLeft) ? domLeftToView - lt - mapLeftToView : domLeft) * screenScale
            let finalY = (isNullText(domTop) ? domTopToView - tp - mapTopToView : domTop) * screenScale
            ctx.drawImage(domCanvas, finalX, finalY)
          }
          resolve('success')
        })
      })
    },
    // 将canvas元素转成图片
    canvasToImage(newCanvas, exportImgName) {
      var url = newCanvas.toDataURL('image/jpeg')
      var a = document.createElement('a')
      a.href = url
      var event = new MouseEvent('click')
      // 指定下载图片的名称
      a.download = exportImgName || new Date().getTime() + '.jpg'
      a.dispatchEvent(event)
    },

utils.js
//获取屏幕缩放比例
export const getScreenScale = () => {
  var screenScale = 1
  var screen = window.screen
  var ua = navigator.userAgent.toLowerCase()
  //设备像素比
  if (window.devicePixelRatio !== undefined) {
    screenScale = window.devicePixelRatio
    //IE11以下版本浏览器
  } else if (ua.indexOf('msie') > -1) {
    if (screen.deviceXDPI && screen.logicalXDPI) {
      screenScale = screen.deviceXDPI / screen.logicalXDPI
    }
    //浏览器自身缩放
  } else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
    screenScale = window.outerWidth / window.innerWidth
  }
  if (screenScale) {
    screenScale = Math.round(screenScale * 100) / 100
  }
  return screenScale
}

六、增加一个指南针图片,图片旋转跟地图旋转做联动

 

data() {     return {       isMovingMouse: false, // 鼠标是否在移动 originPoint: {}, // 旋转前的点位置 finalPoint: {}, // 旋转后的点位置 rotateCount: 0     } } mounted(){ this.map.on( 'moveend', debounce((evt) => { this.mapMoveEnd(evt) }, 600), this )     // 点击了openlayer得controls中rotate,角度复位后触发得     let rotateIconDom = document.querySelector('.ol-rotate-reset') if (rotateIconDom) { rotateIconDom.addEventListener('click', () => { this.setCompassIconRotateDeg(0) }) } } methods:{ // 地图移动/zoom变化结束 mapMoveEnd(evt) { if (evt.dragging) { return } let mapRotation = this.map?.getView()?.getRotation() // 为数值,单位不是度,180度对应数值PI let compassIconDeg = (mapRotation / Math.PI) * 180 this.setCompassIconRotateDeg(compassIconDeg) }, // 按下图标 handleIconDown(e) { e.preventDefault() e.stopPropagation() this.isMovingMouse = true if (this.rotateCount < 1) { this.originPoint = { x: e.pageX, y: e.pageY } this.rotateCount++ } document.onmousemove = (event) => { event.preventDefault() event.stopPropagation() if (this.isMovingMouse) { this.finalPoint = { x: event.pageX, y: event.pageY } let allRotateDeg = (Math.atan2(this.finalPoint.y - this.originPoint.y, this.finalPoint.x - this.originPoint.x) * 180) / Math.PI if (this.setCompassIconRotateDeg(allRotateDeg)) { let mapRotation = (allRotateDeg / 180) * Math.PI this.map.getView().setRotation(mapRotation) } } } }, // 鼠标从指北针图标上抬起 handleIconUp() { this.isMovingMouse = false }, // 设置指北针图标的旋转角度 setCompassIconRotateDeg(deg) { let compassIconDom = document.querySelector('.compassIcon') if (compassIconDom) { compassIconDom.style.transform = 'rotate(' + deg + 'deg)' } return compassIconDom } }

你可能感兴趣的:(vue.js,前端,shpjs)