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
}

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

 <p class="compassIcon" @mousedown="handleIconDown" @mouseup="handleIconUp">
    <img :src="compassIcon" title="指南针旋转" />
 </p>
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
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值