移动端使用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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349