Appearance
地图实现原理
一、地理知识基础
1.1 经纬度
经纬度是经度与纬度组成的坐标系统,是一种利用三度空间的球面来定义地球上的空间的球面坐标系统,能够标示地球上的任何一个位置,比如杭州市的经纬度值大约是东经120°,北纬30°附近。
当使用地图对地理特性进行描述时,经纬度能够很好的描述任一地点的确切位置,而一个点代表一个位置,两个点代表一条直线,数个点即可描绘一个区域,当能够拥有足够多的点来描述一个地区的轮廓时,这些点构成的平面即可表示某一地区的范围。
1.2 墨卡托投影
墨卡托投影,是正轴等角圆柱投影。由荷兰地图学家墨卡托(G.Mercator)于1569年创立。假想一个与地轴方向一致的圆柱切或割于地球,按等角条件,将经纬网投影到圆柱面上,将圆柱面展为平面后,即得本投影。墨卡托投影在切圆柱投影与割圆柱投影中,最早也是最常用的是切圆柱投影。
1.3 GeoJSON
GeoJSON是一种对各种地理数据结构进行编码的格式,基于Javascript对象表示法(JavaScript Object Notation, 简称JSON)的地理空间信息数据交换格式。GeoJSON对象可以表示几何、特征或者特征集合,可理解为一种标准的地理信息数据格式,基于这个数据格式可以描述任一地区的轮廓信息及部分属性。
二、技术方案
由于Echarts等第三方组件库难以满足业务需求,因此组件采用定制开发的模式进行,支持业务性的需求如本级
,支持基础交互的事件暴露如下钻
、返回
、选中
等,同时支持使用者控制地图的加载范围、可交互范围等。
2.1 绘图层
地图采用Zrender作为基础绘图层,其支持在dom上以svg或canvas的形式进行绘图,有利于高效封装业务组件。
2.2 地理数据
地理数据取自阿里Datav平台(数据可视化平台)的地理信息系统,其地图更新较快,杭州市分区调整后即能够在平台上获取新的地图,使用的是其GeoJSON格式的完整数据,为了支持离线部署,这里将所有浙江省范围内的地理数据下载到开发包中进行整合使用。 基于获取的地理GeoJSON数据,封装地理信息基础类Geo,方便地为地图组件提供浙江省范围内各区县的全量、本级地理信息数据。
2.3 省、市本级
省本级、市本级为财政行业概念,在地图上经常以省、市的基础轮廓进行表示。
2.4 状态、事件管理
地图默认加载浙江省地图,支持用户通过点击地区下钻到各市、选中市/区,点击空白处可以取消选中和返回省视图。因此地图对组件提供两种状态:当前地图展示区域code、当前选中地区code。 当地图选中地区发生改变时,常常需要驱动页面的其他部分进行数据的更新,因此这里暴露一个选中地区改变的事件,基于这个事件,使用者可以主动和页面变量绑定以更新其他页面元素的内容。
2.5 自适应缩放
地图采用包围盒计算的方式,计算绘图结束后的最小包围矩形,与当前容器尺寸进行对比,在不溢出容器的原则下进行等比例缩放,保证完整的前提下尽可能大地显示地图信息。
2.6 颜色映射逻辑
地图采用分段填色的逻辑,即定义多段数值区间,分别对应不同的颜色,当地图数据属于颜色区间时,就会使用这个颜色对该地区进行填充,当多个条件同时能够匹配地图数据时,地图会以第一个找到的匹配颜色进行填充。
2.7 浙江省区县地图
有时需要在浙江省范围内显示所有区县的数据情况,此时定义了一种特殊的展现形式,将11个市的地理数据进行集合,整理出浙江省所有区县的数据集,同时进行展示,在此基础上加以各市的描边,即构成了一个浙江省范围内所有区县的地图,这种情况下建议以鼠标悬浮交互的形式显示地图的详细数据,整体以颜色标注的形式提醒用户需要关注哪些地区。
2.8 权限控制
业务场景中往往需要限制只能看某市数据、只能看某区数据的情况,此时组件通过提供地区切换、选中切换的方法支持默认加载时的展示范围及选中设置,再加以提供地区切换前、选中切换前的勾子函数,使用者可根据具体情况限制钩子函数的返回值,当返回值为true时能够正常进行操作,false即为阻止操作,以实现功能的限制。
2.9 附加功能
组件本身支持tooltip(悬浮框)的定义,但只支持html形式的内容,低代码平台使用时隐藏了组件默认支持的悬浮框,而自定义了一个新的悬浮框容器,再结合vue的插槽功能允许用户自定义其dom内容,使其能够更方便地定义悬浮框内容,建议地图上精简显示内容,当需要展示多个内容时结合悬浮框进行定义和使用。
2.10 引用关系
基础组件以项目的形式存在于公司gitlab上,组件打包生成一个静态资源包ZKMap_x.x.x.js
,低代码平台的basetools
租户下有地图项目,其中map-fill-base
页面作为基础页面通过$js函数引入组件包并定义dom,完成组件初始化,同时定义了一些基础功能、方法,再定义了多个部件页面以UIBlock的形式引用该页面,通过自定义setter设置动态面板,允许用户传入参数,且在部件页面中以插槽的形式实现了悬浮框,支持用户自定义悬浮框内容。 因此,当组件版本更新时,可以在map-fill-base
页面更新引用的js包,即可完成所有部件的组件升级,同时若组件需要扩展功能或修改bug,也仅需在这个页面完成即可,有利于组件的维护。