移动端使用openlayers加载手绘地图

除了二维平面图、卫星图外,三维地图、手绘地图等新地图形式也开始出现在各应用中。手绘地图能够快速定制化的呈现出特定区域的路线、交通、建筑、景点等,对于景区导览、旅游观光和规划等场景,具有良好的应用前景。最近做了个关于手绘地图的项目,使用 openlayers 渲染,加载速度和渲染效果都很不错。

参考资料:
openlayers 文档地址:https://openlayers.org/en/latest/apidoc/


一、手绘地图绘制、参数设置

绘图人员绘制完地图并配准后,发布到 GeoServer(一款基于 java 的开源 GIS 工具集),需在 GeoServer 上设置好投影坐标系(EPSG:3857即墨卡托坐标系,EPSG:4326即WGS84坐标系)、地图瓦片格式、坐标轴范围、地图原点、地图层级、分辨率等参数,一般由后台人员设置。

注意:以上地图参数一般由后台人员通过接口传给前端,但有时传过来的数据可能不全,此时必须问清楚或者自己去 GeoServer 上看,加载地图时如果出现问题基本是因为漏了参数或者参数错误。

二、openlayers 加载手绘地图

1、项目引入 openlayers
首先npm 安装 openlayers

npm install ol

注意,在 vue 中必须逐一声明所需的 openlayers 库的对象和方法才能正常使用

import Map from 'ol/Map.js'        // 无法像普通库那样直接 import ol from 'ol' 后调用里面的对象和方法 
import View from 'ol/View.js'
import Vectors from 'ol/layer/Vector.js'
import { asString } from 'ol/color'
import { fromLonLat, Projection } from 'ol/proj.js'

2、加载手绘地图
手绘地图以 WMTS (Web Map Tile Service, Web 地图瓦片形式)加载,先创建一个类型为 WMTS 的图层资源,再将其放入创建的 Map 对象的图层资源集合中。

// 单独引入要使用的对象和方法
import Map from 'ol/Map.js'
import View from 'ol/View.js'
import { fromLonLat, Projection } from 'ol/proj.js'
import { WMTS, Vector } from 'ol/source.js'
import WMTSTileGrid from 'ol/tilegrid/WMTS.js'
import TileLayer from 'ol/layer/Tile.js'


/*配置 WMTS 图层资源参数
 *@param{object}  data  后台接口传过来的地图参数
 *@return {object} 返回创建的 WMTS 图层资源对象
*/
initWMTSLayer(data) {
    const projection = new Projection({         // 地图的投影坐标系
    code: 'EPSG:4326',               // 类型可以是墨卡托坐标系或WGS84坐标系
    units: 'm',                              // 坐标单位
        axisOrientation: 'neu'           // 坐标轴方向
    })
    // 设置分辨率数组,这里后台传过来的是以逗号分隔的字符串
    const resolutions = data.layerCoordinates.split(',').map(item => +item)
    // 设置地图瓦片矩阵Id
    const gridIds = data.gridsetIds.split(',').map(item => item.replace(/\s+/g, '')
    const tilesGrid = new WMTSTileGrid({            // 地图瓦片网格对象
         tileSize: [256, 256],              // 瓦片大小
         origin: [-2.003750834E7, 2.003750834E7],            // 切片原点
         resolutions: resolutions,
         matrixIds: gridIds
    }),
    // 创建 WMTS 图层资源
    const source = new WMTS({
        url: data.url              // 地图服务的地址
        layer: data.layerName           // 地图图层的名称
        matrixSet: data.gridsetName      // 地图瓦片矩阵
        format: 'image/png'       // 地图瓦片的格式,可以接口传过来也可以前端写死
        projection: projection,
        tileGrid: tilesGrid,
        wrapX: true         
    })
    return source
}


/*创建 Map 对象,将配置好的 WMTS 图层资源加入到图层合集中
*@param{object}  data  后台接口传过来的地图参数
*/
initMap(data) {
    const projection = new Projection({         // 地图的投影坐标系
    code: 'EPSG:4326',               // 类型可以是墨卡托坐标系或WGS84坐标系
    units: 'm',                              // 坐标单位
        axisOrientation: 'neu'           // 坐标轴方向
    })
    // 设置地图可拖动的范围
    const leftBottom = data.leftBottom.split(',')
    const rightTop = data.rightTop.split(',')
    // 创建地图对象
    this.map = new Map({          
        target: 'map',
        interactions: defaultInteractions({       // 禁止旋转
            altShiftDragRotate: false,
            pinchRotate: false
        }),
        view: new View({
        center: data.center.split(','),                // 设置地图中心坐标
        zoom: data.minLevel || data.defaultLevel,          // 设置地图打开默认的层级
        minZoom: data.minLevel,                 // 设置最小缩放层级
        maxZoom: data.maxLevel,               // 设置最大缩放层级
            projection: projection,             // 设置投影坐标系
            extent: [+leftBottom[0], +leftBottom[1], +rightTop[0], +rightTop[1]]  // 拖动范围
        }),
        layers: [                   // 将创建好的 WMTS 图层资源放入地图图层合集中
            new TileLayer({
            source: this.initWMTSLayer(data)
          })
        ]
    })
    // 地图打开后移动到要显示的位置
    this.map.getView().animate({
        center: data.location.split(','),          // 目标位置的坐标
        duration: data.duration,               // 移动动画时长
        zoom: data.minLevel || data.defaultLevel      // 地图缩放层级 
    })
}

以上,实现加载手绘地图后,移动至指定经纬度。


手绘地图.png

这样就完成了手绘地图底图的加载,后续如何为地图添加标注(含聚合标注)、覆盖物及路线等,可以查看我的另一篇文章:https://www.jianshu.com/p/4af2a52a0fc6

你可能感兴趣的:(移动端使用openlayers加载手绘地图)