VUE_Openlayers GIS平台项目架构与简介

VUE_Openlayers GIS平台项目架构与简介

前言:

当今市场上对于vue+openlayers的平台项目的组件化解决方案是一个难题,有的虽然解决了组件化的问题,但地图的相关功能还是主要依靠单页面组件来完成,这不仅造成地图相关组件十分杂乱,而且调试难度也十分大,本文主要从以上问题切入做出阐述。

注:本文只阐述架构思想,不做代码层面的完整阐述。基于vue2。

总论:

在VUE中创建Openlayers地图项目,受前端组件化与虚拟DOM技术影响,在vue中创建大型地图应用是不太容易解决的。这样的问题主要体现在地图实例(map)的生成时机与其他组件在挂载生命周期的前后关系,因为vue的生命周期遵循以下的规则:

挂载阶段的执行顺序为:

父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted

更新阶段的执行顺序为:

父beforeUpdate -> 子beforeUpdate -> 子updated -> 父updated

销毁阶段的执行顺序为:

父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed

由上可知mounted是一个重要节点,且父组件的mounted在子组件的mounted之后,而mounted是组件由虚拟DOM生成真实DOM的关键生命周期节点;而Openlayers实例化地图时必须要一个真实DOM(这个真实DOM是指必须在html文档中,并经过浏览器渲染,可通过DOM API获取的节点,不能是DOM由createElement生成的暂时节点),如果只是需要一个DOM,我们可能会想:“直接在index文件里写一个DOM不就行了“,当然,这种解决方案在大多数地图应用中已经能解决问题了。但另一方面,我们本着对VUE的尊重,不去破坏优雅的index文件,只在组件中编程,还有在创建多地图应用时,这种不足就尤为凸显。所以,如何创建一种动态的、组件化的、打破生命周期限制的GIS平台就十分重要了,本文也旨在说明这种构建思想(如果你需要或者想要了解构建一个多地图应用的基础GIS平台如何搭建,请往下阅读)。

具体实现:

  • 地图组件

首先,我先介绍地图组件的构建过程:

  1. 创建DOM:在地图容纳组件(该组件最好只容纳地图)使用createElement创建一个地图容器DOM,并将其添加到body中;
  2. 创建地图实例(这里我们对Openlayers的map API进行了二次封装,后续会详细介绍):使用创建的DOM创建一个地图实例;
  3. 移动地图容器至当前组件下:尽管VUE不建议我们直接操作DOM,但是为了系统的连续性与组件化,让VUE做出这样的“牺牲“是值得的,况且这样的DOM操作不会影响到VUE分毫;
  4. 调用地图实例的updateSize方法:这个方法在本组件中十分重要,应为发生了DOM的移动,所以其中的canvas节点的size可能会发生改变,所以请保证在DOM移动之后调用此方法。
  • 平台架构思路

        所有的组件分为两层,两层之间互不影响,一个是地图组件层(可能会有多个地图组件,这就是我们说的多地图应用,多地图组件可以是兄弟关系,父子关系,互不影响),另一个是地图工具层(工具层中会有很多工具,之间互不影响)

    1. 首先是平台地图与图层及其他的初始化配置信息的获取(主要是地图与图层的初始化信息),这一步我们要放在实例化VUE之前进行,目的是为了保证地图平台构建过程中的连续性;
    2. 地图组件与工具组件整合到一个组件中,形成一个整体组件,工具组件通过mapContainerId来连接对应的地图组件;
    3. 所有需要通信的地方均使用全局事件总线来进行通信;
    4. 地图组件应该始终在工具组件之前构建(所以请注意组件使用时的顺序)
  • 平台模块的构建

        平台模块主要由map模块、layer模块、draw组件组成,称为平台的三大基础模块这些模块都对openlayers的部分原API进行了二次分装:

  1. map模块:

        该模块是地图应用中最核心的模块,其中封装了ol.map的实例化函数,添加layer的函数,创建view的方法(view可以在多地图应用中实现公用,达到多地图视图联动的效果),以及一个缓存所有地图实例的变量,及其他一些地图相关功能的封装,其中缓存所有地图实例在此平台实现中是非常重要的,此平台实现时,地图实例的一级传输是通过mapContainerId来传递的,这也就是为什么要保证地图组件始终应该在工具组件之前构建,工具组件中获取地图实例都是通过mapContainerId去map模块中拿到缓存来获取地图实例的。

说明:在最初搭建平台时,我曾考虑过使用props传递地图实例,但是由于vue的创建与挂载时的特性(即:vue在解析模板之后props中的数据已被初始化(与data是不同的),要想改变只能等下一轮在update生命周期中进行,这就使得尽管我在地图组件中实例化了地图并将其赋值给对应的props变量,但他已然不会生效),所以在map模块中缓存地图实例在此平台实现中是重要的步骤;

  1. layer模块:

        该模块主要是layer的工厂方法模块,它虽然简单,但却是不可或缺的,在各个项目中都会有适于本项目的layer加载方式和工厂方法,此处不再赘述;

  1. draw组件:

  该组件是对openlayers中的交互接口draw的二次封装,封装原因有以下几点:

  1. openlayers的绘制功能在GIS系统中来说是一个常用的功能,在多需要地图交互的功能中也同样需要;
  2. 这个接口拥有回退点、重绘、选择缓冲等功能需要UI交互;
  3. draw交互工具在使用后要使其失活,方可进行其他操作,所以应该有一个关闭按钮来与用户交互操作(由于openlayers中的draw交互工具创建完成之后不能改变drawType,所以在绘制结束之后就将其从地图上移除,下次需要的时候再次创建)。

综上原因,将draw封装为一个组件是十分有必要的,draw组件中使用了draw模块,该模块主要将openlayers中draw相关的方法封装起来,并提供了缓存draw实例的变量,此变量是为了保证地图上始终只有一个draw实例。

该模块扩展了ol.draw,扩展后的draw模块支持以下内容:

  1. 允许type为空时实例化draw对象,他会默认实例化一个LineString类型的draw,之后可以使用changeType来修改实例的draw;
  2. 封装回退点、重绘、setActive、一次性绑定事件的construct、改变drawType的construct等;

还有就是不继承自olDraw的原因:

  1. 绑定事件不能实现一次绑定;
  2. 不易完成drawType的转换;

后记:

        目前的平台架构已经可以满足大多数应用的开发,并在此基础上博主也实现了,如测量、点查、鹰眼图的二次封装、卷帘等组件的组件式功能开发,其他功能组件也在此基础上进行定制化开发。尽管如此,也需要对此方案进行进一步优化和调整。敬请指正!!!

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值