局域网条件下的瓦片地图应用研究

2017-12-27 17:27谢雨芮刘毅锟
地理空间信息 2017年12期
关键词:图幅瓦片服务器端

周 海,谢雨芮,葛 平,刘毅锟

(1.西安测绘总站,陕西 西安710054)

局域网条件下的瓦片地图应用研究

周 海1,谢雨芮1,葛 平1,刘毅锟1

(1.西安测绘总站,陕西 西安710054)

通过Python网络爬虫获取互联网地图瓦片并存储到本地数据库MongoDB中,在B/S架构下利用Leaflet实现瓦片地图浏览功能,利用Python-PIL在服务器端实现瓦片地图拼接。为适应地图和地图拼接服务高并发的需求,利用Nginx实现多台服务器间的负载均衡。该项研究提供了网络地图瓦片的获取、存储、浏览和拼接方法,服务器端拼接的方式降低了客户端依赖,为局域网条件下瓦片地图应用提供良好的思路。

瓦片地图;爬虫;Leaflet;瓦片拼接

目前,国内外已有很多成熟软件提供瓦片地图的生产、服务发布、访问和拼接功能,如SuperMap、ArcGIS均可用来切割瓦片[1]、服务发布和地图访问,稻歌、水经注和太乐等提供瓦片地图的拼接功能。许多学者开展了瓦片地图存储[2,3]、访问[4]和拼接方面的研究,如韦胜[5]在ArcEngine上结合ArcBruTile(GitHub),利用Win32类库和GDAL两种不同方式实现对地图瓦片的拼接。这些工具和研究对推进瓦片地图应用发挥了重要作用,但仍然存在一些问题:对地图瓦片获取研究较少,不能直接利用Google Map等互联网瓦片地图来构建自己的地图服务;地图拼接工作大都是在C/S架构的Client端完成,只有安装客户端才能使用,受网络影响大不易扩展。针对这些问题,首先研究通过Python爬虫对Google Map等地图瓦片进行获取,基于B/S架构实现地图瓦片的浏览与服务器端的拼接,最后实现拼接服务的负载均衡以提高服务器性能。

1 瓦片地图获取与存储

传统的瓦片生产由矢量地图或影像来切割生成,预先对地图数据渲染、切片,然后存放在服务器端,客户端访问时直接访问这些瓦片数据,以避免服务器端地图实时渲染给服务器造成的压力[2]。在全球范围内,无论是地图数据采集还是编绘都是巨大的工作量,通过网络爬虫来获取现有互联网地图瓦片以便直接利用。局域网内应用互联网地图瓦片的技术路线如图1。

图1 局域网内应用互联网地图瓦片的技术路线

1.1 网络地图获取

地图瓦片数据一般采用金字塔结构对不同分辨率(比例尺)的数据进行组织,由于数据坐标系统和地图用途的不同,采用的投影和瓦片切割算法也可能不同[2]。目前,主流的网络地图多采用WGS 1984Web Mercator投影(地球近似为圆球体),经度的投影范围取(-180,180),纬度投影范围取(-85.051 129,85.051 129)。金字塔的不同级别对应于不同分辨率的地图,地图瓦片的大小通常采用256×256或512×512像素,并采用PNG格式。特定级别的地图范围(通常是全球)可以确定每块瓦片的地理跨度和实际分辨率,进而计算出该瓦片在地图图层中的相对位置,即行列号。确定地图等级z,行列号x、y便对应于网络地图中的一块瓦片[6]。

能够通过网络爬虫来获取网络地图瓦片,是因为这些网络地图服务提供了获得每一块瓦片的接口,通常每一块瓦片均由独立的URL地址唯一确定。可以通过Request请求获取指定位置和级别的地图瓦片。以Google Map影像为例,用户request请求以下URL可以分别获得图2中4张瓦片。其中的主要参数x、y、z分别表示瓦片的行号、列号和级别。

1)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=1&y=0&z=1;

2)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=0&y=0&z=1;

3)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=1&y=1&z=1;

4)http://mt0.google.cn/maps/vt?lyrs=s%40699&hl=zh-CN&gl=CN&&x=0&y=1&z=1;

图2 Google影像数据

其他地图瓦片可以通过URL来获取,并根据其行列号和级别反解出其角点坐标。主要对Google Map的影像层(含注记层)、地图层以及OpenStreetMap的标准图层进行获取,这些图层的投影方式、投影范围、瓦片切割算法相同,可以在地图显示时很好地集成和切换。实际工作中通过Python爬虫程序获取Google Map影像、地图及OpenStreetMap3种地图0~10级全球范围内的瓦片数据。

1.2 瓦片地图的存储

地图瓦片是固定尺寸的图片,通常为PNG格式,随着地图级别的增加,地图瓦片的数据量呈指数级上升,如在第10级全球瓦片的数量达到410,如何实现地图瓦片的高效存取非常重要。若将这些海量的地图瓦片以文件的形式存储在硬盘中,则不仅造成磁盘存储碎片化严重、数据冗余,而且I/O性能差、不便于备份和恢复。通常的做法是将瓦片存储在数据库中,而且是非关系型数据库(NoSQL)中,因为传统关系型数据库对文件、二进制等数据的读写性能依然受限[3,7]。

MongoDB[3,7]是一个开源、基于分布式文件存储的NoSQL数据库。它使用一种类似JSON的BSON格式进行数据存储,因格式松散而支持复杂数据格式,尤其是内置GridFS功能,特别适应于大量小文件存储。在数据备份和恢复方面,可以使用mongodump和mongorestore工具轻易实现数据迁移。此外,MongoDB还支持Python、Java、C++、PHP等多种语言,而且操作简单便捷。基于这些特点,选用MongoDB来存储获取的地图瓦片,以实现对地图瓦片的高效存储和访问。采用Python的MongoDB操作工具pymongo实现对数据库中瓦片的读写。存储的信息除了图片文件,还包含行列号、文件格式、图层类别、下载时间等其他信息。

2 地图访问与地图拼接

2.1 地图访问的实现

地图访问的实现主要包括服务器端地图服务发布和Web端地图服务调用及交互两部分,如图3所示。

图3 地图访问与拼接的实现

服务器端主要实现地图服务器的功能,完成对数据库中瓦片的读取,并暴露服务接口。目前有许多商业GIS软件(如ArcGIS Server)和开源GIS(如GeoServer)可以用来发布瓦片地图服务。这些软件虽提供了丰富的GIS服务功能,但部署和操作复杂。本研究仅涉及地图服务和拼接服务,因此运用Python的Tornado框架来搭建自己轻量级的GIS服务器。

Tornado是 FriendFeed的Web服务器及其常用工具的开源版本,采用epoll非阻塞I/O,响应快速,每秒可处理数千并发连接,特别适用于实时的Web服务。基于该框架利用Python实现RESTful风格的地图瓦片服务。每块瓦片对应唯一一个URL,结构为http://localhost:3000/tile?z={z}&x={x}&y={y}&layer=g oogle_sat,其中x、y、z分别对应于瓦片的行号、列号和级别,layer为几种不同的瓦片图层,如Google影像、OpenStreetMap标准图层等。这样,浏览器端便可以通过URL获取每一块瓦片。

Web端(客户端)主要实现地图的浏览、漫游、缩放、定位等功能。要实现这些功能,一般要借助于WebGIS工具。目前,地图服务厂商和GIS厂商都有自己的WebGIS产 品, 如 GoogleMap JavaScript API、ArcGIS API for JavaScript等。除此之外,出现了越来越多的JavaScript开源WebGIS客户端,如 Leaflet、Openlayers、MapEasy、OpenScales等。由于开源GIS产品具有免费、开放、可扩展性和可定制性强,以及开发周期短、成本低等特点,基于开源GIS软件的应用项目越来越多[9,10]。

Leaflet 是一个为建设移动设备友好的互动地图而开发的开源JavaScript 库。代码量虽小,但具有开发人员开发在线地图的大部分功能。而且支持插件扩展,有一个友好、易于使用的API文档和一个简单的、可读的源代码。利用leaflet实现了浏览器端对瓦片地图的浏览、漫游、缩放、定位等功能,并利用leaflet工具实现对要素层的编辑(框选要拼接的地图范围)。

2.2 地图瓦片拼接的实现

地图拼接在服务器端完成,客户端和服务器配合完成。通过在浏览器端输入坐标范围、图层、图幅大小等参数,在服务器端实现瓦片的拼接,返回给浏览器端。瓦片拼接的一般过程如图4。

图4 拼接的实现过程

在客户端(浏览器):首先利用leaflet的draw工具在地图上绘制矩形范围框,为避免用户选择的地图范围过大,将用户选择的拼接范围分割成多个图幅进行拼接,因而用户还需要输入拼接后的图幅大小。为避免瓦片的裁剪,图幅大小采用瓦片大小的整数倍,如2 560×2 560、5 120×5 120像素等;接着选择要拼接的图层等级,并根据范围对级别进行限定,以避免拼接任务过于庞大;最后,选择需要拼接的图层,以满足不同地图瓦片的拼接需求。

在服务器端:根据从客户端接收过来的图幅范围、等级、图幅大小、图层等参数开始拼接任务,为了让客户端实时获取服务器端瓦片的拼接进度,在服务器端给每一个任务生成一个唯一的ID,然后将拼接的进度存储在Session中,这样浏览器就可以实时获取拼接进度,并在完成拼接后下载。

地图瓦片拼接服务使用Python来编写,主要用到两个工具:Imaging Library (PIL)和Geospatial Data Abstraction Library(GDAL)。PIL是 Python下的图像处理模块,支持多种格式,并提供强大的图形与图像处理功能。利用PIL将多块瓦片PNG图像拼接到一起。GDAL是一个在X/MIT许可协议下的开源栅格空间数据转换库。用它将EPSG描述的坐标系转换为WKT坐标系。瓦片拼接的成果主要包括3类文件:拼接好的图片PNG文件,记录图幅左上角点坐标及图片分辨率等参数的PNW文件,以及采用WKT描述的坐标系PRJ文件。后两者文件共同构成了PNG文件的空间参考。地图瓦片拼接将选定范围的瓦片拼接成一个或多个图幅,地图拼接的算法如下:

1)根据输入的拼接范围和级别计算要拼接的起始行列号、终止行列号以及瓦片分辨率;

2)根据起始行列号和终止行列号以及输入的图幅大小,计算出每一块图幅的起止行列号以及起始坐标;

3)根据每块图幅的起止行列号,将落在该范围的瓦片从数据库中取出拼在一起,完成每一个图幅的拼接,并根据起始坐标生成WKT描述的坐标系PRJ文件,将起始坐标及分辨率等参数记录到PRJ参数文件中;

4)将拼接的每一个图幅的PNG、PNW和PRJ文件压缩为一个压缩包。

3 服务器负载均衡

为适应用户对地图和瓦片拼接的大量并发访问,对服务器进行优化。利用Nginx反向代理实现对地图服务和瓦片拼接服务的负载均衡。Nginx是一个高性能的HTTP和反向代理服务器,作为负载均衡服务器时,支持作为HTTP代理服务器对外进行服务。当用户访问网站时,负载均衡服务器(Nginx)将应用服务请求转发至5台应用服务器,以保证某一台应用服务器负载过高,或是当某台应用服务器宕机时,系统能够继续运行。负载均衡部署如图5。

图5 服务器负载均衡

当对地图拼接服务实现负载均衡时,由于拼接任务是在某一台应用服务器上完成的,因此需要将所有任务的进度存储在一个Memcached的session服务器上,这样便可以获得每个拼接任务的进度。当拼接任务完成后,若拼接文件不在本机,同样需将下载请求转发至实际任务进行的应用服务器。

4 实验验证

实验下载了全球范围内Google Map影像、地图及OpenStreetMap三类瓦片的0~10级数据,并将数据存储在mongodb中,数据大小约为26 GB。系统部署在VMware的centos虚拟机中,部署的结构如图5。系统主要包括地图浏览和瓦片拼接下载功能,截图如图6。

图6 瓦片拼接效果图

地图浏览:地图浏览允许用户实现Google地图、Google影像、OpenStreetMap 3类瓦片地图的浏览、漫游、缩放和图层切换。地图浏览界面包括了右下角的图层切换按钮和右上角的地图拼接下载工具条,图层切换按钮允许用户切换浏览不同的图层,地图下载工具条主要完成地图拼接等功能,如图6a。

瓦片拼接下载:地图拼接下载主要通过地图拼接下载工具条完成,通过输入拼接范围、拼接图层、拼接图层的级别以及拼接图幅尺寸,向服务器提交拼接请求(如图6b),在拼接过程中界面将显示拼接进度,完成拼接后浏览器会弹出文件下载提示。图6c是下载拼接好的文件,图6d是将下载的文件在Global Mapper中打开的效果。

5 结 语

通过爬虫获取Google Map等互联网地图瓦片并存储在数据库,利用Python搭建轻量级地图服务器并利用leaflet实现地图的浏览功能。在此基础上,利用PIL和GDAL等工具实现瓦片地图的拼接服务,实现服务的负载均衡。实际应用效果较好,为局域网下利用互联网瓦片数据提供了一套有效的解决方案。下一步工作将实现瓦片缓存以便进一步提高系统性能,并研究局域网条件下瓦片地图服务的具体应用,如将瓦片地图服务引入生产作业网以直接作为数据参考、在瓦片拼接基础上利用瓦片完成地图的在线制作等。

[1]苏旭明, 谭建成. WebGIS中瓦片地图关键技术研究[J].北京测绘, 2012(2):9-12

[2]罗智勇,黎小东.基于数据库存储方案的高性能瓦片地图服务研究[J].地理与地理信息科学,2013,29(3): 52-55

[3]陈超, 王亮, 闫浩文,等. 一种基于NoSQL的地图瓦片数据存储技术[J].测绘科学, 2013, 38(1):142-143

[4]张广春, 仲伟政. 基于ArcGIS Engine组件实现瓦片地图的应用[J].测绘通报, 2015(3):115-116

[5]韦胜. ArcEngine环境下实现瓦片地图的访问与拼接[J].武汉大学学报(信息科学版), 2012, 37(6):737-740

[6]OpenStreetMap Wiki. Slippy Map Tilenames [EB/OL]. http://wiki.openstreetmap.org/w/index.php?title=Slippy_map_tilenam es&oldid=1342885.2016-09-08 / 2016-11-15

[7]邱新忠. 基于MongoDB GridFS的地图瓦片数据存储研究[J].地理空间信息, 2016(2):50-52

[8]邱儒琼, 郑丽娜, 李兵. 基于MongoDB的电子地图瓦片数据存储和服务研究[J].地理空间信息, 2014(6):155-157

[9]李光师. 基于开源平台构建WebGIS应用系统[J].测绘科学,2011, 36(6):259-261

[10]胡达天, 胡庆武. 基于开源系统的跨平台地图客户端开发[J].测绘科学, 2015, 40(7):142-145

P208

B

1672-4623(2017)12-0018-04

10.3969/j.issn.1672-4623.2017.12.006

2016-11-18。

地理信息工程国家重点实验室开放研究基金资助项目(SKLGIE2015-Z—2-1)。

周海,硕士研究生,主要从事地理编码、空间数据挖掘、GIS应用开发等工作。

猜你喜欢
图幅瓦片服务器端
Linux环境下基于Socket的数据传输软件设计
一种基于主题时空价值的服务器端瓦片缓存算法
惯性
浅析异步通信层的架构在ASP.NET 程序中的应用
基于Qt的安全即时通讯软件服务器端设计
基于EXCEL的地形图图幅号转换查询方法
基于ArcMap的图幅接合表快速生成方法研究
地形图图幅编号规则及实现
基于NoSQL数据库的瓦片地图服务
基于Bing Maps的地形图图幅编号的网络可视化查询