开发者社区> 晚来风急> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

通过配置实现多种需求下的地图展示

简介:
+关注继续查看
1.背景
  对于一般性的地图显示需求,我们只需要知道地图的一个固定URL,然后知道要显示的范围和要显示的级别以及每个级别的scale等即可。
  但是如果我们遇到下面几种情况时,又该如何。
  (1)需要显示的图层的不同级别来自于不同的服务器(URL不同):如前几个级别由一个固定URL提供,后几个级别由另外一个URL提供。
  (2)需要同时叠加几张图层:如需要叠加地形图和注记图,且图层的显示有层级之分。
  (3)需要同时叠加几张图层,并且每个图层初始显示级别不一样。
  (4)需要同时叠加几张图层,图层的URL的请求方式均有不同:如其中一个图层由AGS提供,一个图层是天地图服务提供,还有一个图层是当地城管局提供,最后还有一个图层是由本地未发布的缓存瓦片提供。
  诸如类似于以上的地图显示需求还有很多,如果我们单纯的对每一种情况进行一个代码上的分支当然也是能解决的。但是这并不是最好的一种解决方法,每次新的需求提出时,都需要对代码修改,这不符合设计模式中的开放封闭原则。虽然我们可以用简单工厂等模式来努力改善这种情况,不过如果有更好的方式,不需要修改任何代码,不需要用设计模式,就能解决以上的问题是否更好?
  下面我将给出一种通过数据库配置来实现上面所有问题的解决方案。此方案在多个项目中已经开始使用。
  2.配置(表)的设计
  2.1原理
  首先我们必须对以上多种地图显示的需求进行一个分析,提出他们的共同点。
  (1)对图层开始显示的级别有需求(startLevel)。
  (2)多张图层叠加,并且图层叠加有从上自下的顺序(layerDisplayOrder)。
  (3)图层可能的URL不同(ServiceURL)
  (4)每个图层的URL格式可以不一样,比如URL可能天地图的WMTS格式,可能是AGS发布的请求方式(level\row\col),也有可能是Geoserver发布的WMS格式。并且有的服务提供商还需要token字段来判断是否有权限得到服务,或者不同的服务商提供的WMTS格式中对col和row以及level的表述字段名称不一样(通过这个分析,可以提炼出Xfield、Yfield、LevelFieldName、Token字段来对不同的需求进行配置)。
  (5)所有的图层,如果要叠加,需要用同一个空间参考,同一个瓦片大小,同一个地图起始原点,以及同一套地图比例尺。
  (6)变化的只是URL,其核心瓦片行列号和地图级别是每种瓦片请求URL均需要的。
  2.2设计
  2.2.1图层列表(tcMaplayerList)的设计
  首先我给出图层列表设计的截图:
  (1)每一个图层均有一个图层名
  (2)每一个图层均有自己的图层类型,比如AGS类型的、WMTS类型的等。这是为了程序中对不同的类型的URL进行解析。
  (3)每一个图层有其自己的显示顺序,为了正确的叠加图层之用。
  (4)每一个图层也有自己开始显示的级别。如有的图层想第一级别开始显示,有的图层希望地图放大到第二级别时才开始显示。
  2.2.2图层详细内容列表(tcgismapservicedetail)的设计
  同样,这里先给出表的截图:
  (1)ItemID为每个记录的主码。
  (2)layerName与tcMaplayerList中的图层名是对应的。
  (3)图层级别表示的是该图层在此级别时的信息。
  (4)图层在该级别的URL有一个固定的部分,比如WMTS请求中,变化的只是行列号,而前面的部分均是不定的。
  (5)Token、XFieldName、YFieldName、LevelFieldName均是为扩展之用,当URL需要给行列号以及级别一个固定的名称时等,则配置。否则不用。
  3.工作流程
  3.1流程图
  3.2流程详解
  3.2.1得到需要显示的图层列表
  在显示地图之前,需要先向后台发出请求,此请求的参数主要是layerType,后台根据layerType将tcMapLayerList表中符合需求的内容读出返回。
  3.2.2 解析当前地图级别下的各个图层信息,并顺序显示
  在解析了需要显示的图层列表后,每个图层均会给后台发出自己的信息,信息中包括了此时地图的级别,以及需要得到的瓦片行列号和自己的图层名。
  但是此时的地图级别并不是图层发给后台的级别参数,真是的地图级别是:
  factLayerLevel=layerLevel+startLayerLevel。
  根据factlayerLevel和layerName,在tcgismapservicedetail中找到对应的信息,如果有信息,则表示该图层在此真实级别下是需要显示的,然后根据该图层的layerType将此时的URL拼接出来,下载瓦片然后返回此瓦片。
  如果没有查到数据则不显示此地图级别下的该图层。
  4.成果展示
  4.1测绘局地图+本地瓦片
  4.2 天地图地形图层+天地图注记图层+Geoserver发布的行政区划图层
  4.3测绘局提供的管线WMTS图层+本地AGS发布的地形图层
  5.总结
  通过此配置基本可以实现项目中遇到的绝大部分地图需求。改进后,虽然不再需要对各种需求进行大规模的代码编写,但是针对不同的瓦片类型的URL获取依然是要走分支的,这里可以通过策略模式来让代码更加规范。
  断了一个多月没写博,WebGIS的原理系列会继续写下去的,希望大家持续关注。

最新内容请见作者的GitHub页:http://qaseven.github.io/

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
怎么让 echarts 图表动起来?定时器解决它 —— 大屏展示案例(动态仪表盘、动态柱状图)
怎么让 echarts 图表动起来?定时器解决它 —— 大屏展示案例(动态仪表盘、动态柱状图)
0 0
使用ArcGisJS实现地图管理
使用ArcGisJS开发地图,首先需要引入ArcGis的Js文件和CSS文件,引入方式有两种,一种是官网JS引用,一种是本地JS引用。如下:
0 0
其余功能展示
收银台展示的功能信息: 点击订单详情,展示收银平台显示详细的订单信息:  可以参考官方文档: [url]https://doc.open.alipay.com/doc2/detail.htm?treeId=270&articleId=105901&docType=1[/url]
89 0
动态创建地图文档MXD并发布地图服务
原文:动态创建地图文档MXD并发布地图服务  1、动态创建MXD private bool CreateMxd(string MxdPath, string MxdName) { IMapDocument pMapDocument = CreateObject("esriCarto.
596 0
使用R画地图数据
用R画地图数据 首先,从这里下载中国地图的GIS数据,这是一个压缩包,完全解压后包含三个文件(bou2_4p.dbf、bou2_4p.shp和bou2_4p.shx),将这三个文件解压到同一个目录下。
1207 0
【百度地图API】如何利用自己的数据制作社交地图?只显示可视区域内的标注
原文:【百度地图API】如何利用自己的数据制作社交地图?只显示可视区域内的标注 摘要:如果你自己的数据已经超过1万个,如何进行合理的显示?除了聚合marker外,还有一个办法。那就是,只显示可视区域内的标注。
1092 0
通过配置实现多种需求下的地图展示
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/。 1.背景 对于一般性的地图显示需求,我们只需要知道地图的一个固定URL,然后知道要显示的范围和要显示的级别以及每个级别的scale等即可。
629 0
2013年7月14日-地图展示
1、在newjavascript中编写如下代码: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ dojo.require("esri.map"); dojo.require("esri.tasks.query"); //dojo.
770 0
+关注
文章
问答
文章排行榜
最热
最新
相关电子书
更多
数据展现:可视化报表及嵌入应用
立即下载
复杂环境下的视觉同时定位与地图构建
立即下载
地图场景的LBS智能信息分发技术
立即下载