Portable Basemap Server:多数据源多客户端的底图服务器

[poll id=”1″]
2014.3.8更新v3.1
~在线切片转换为MBTiles时,增加RecreateEmptyCache模式。当你想继续上次未完成的任务或打算合并多个级别/范围的切片时,RecreateEmptyCache模式会非常适合;
~在CustomOnlineMaps.xml中自定义数据源时,增加Multi-Layer模式,比如可将标注和影像两个数据源融合为一个服务。具体用法请参考自带示例;
~修复已知Bug;
2013.5.10更新v3.0
~添加以Windows服务方式运行功能;
~发布的缓存服务增加对OGC WMTS规范的支持。详见这里;
~数据源增加对OGC WMS服务的支持。详见这里;
~数据源增加对高德本地缓存文件的支持。详见这里;
~预览界面中可显示切片来源(动态生成/文件缓存/内存缓存,以不同底色区分);
~添加日志功能;
~修复已知bug;
2012.12.10更新v2.0.7
~为影像数据源增加本地缓存(.cache文件)功能。详见这里
~在线地图转换/下载到MBTiles格式时,增加按Shapefile文件范围下载功能。详见这里
~为转换后的MBTiles文件增加了”压缩”选项,某些情况下可大幅减小MBTiles文件体积。详见这里
2012.11.14更新v2.0.6:
~Portable Basemap Server已在CodePlex上开源,LGPL协议;
~添加ArcGIS Cache/在线地图数据源到MBTiles格式(.mbtiles)的转换/下载工具。详见这里
~为在线地图数据源添加本地缓存功能。详见这里
~改进ArcGIS Tile Package(.tpk)格式文件的读取速度;
~修复已知bug;
2012.4.24更新v2.0.5:
~为数据源类型为ArcGISDynamicMapService的PBS服务增加附加参数设置,比如layers,layerDefs等,达到控制图层可见性,按属性过滤图层内容等目的。详见这里
~REST Admin API为ArcGISDynamicMapService数据源增加changeParams操作,以动态修改附加参数。详见这里。详见这里
~数据源增加对ArcGISTiledMapService的支持;
~增加自定义在线地图功能。可通过修改CustomOnlineMaps.xml文件内容,自行增删在线地图数据源(数据源须采用Google Maps/Bing Maps/ArcGIS Online地图的缓存策略);
~增加自动保存/载入上次配置的功能;
~为系统托盘图标增加右键菜单;
~修复已知bug;
2012.1.9更新v2.0.4:
~REST Admin API增加enable/disable/clearByService三个操作,分别用于开启/关闭内存缓存功能,清除指定服务的内存缓存数据。详见这里
~界面改进:增加中文语言界面;支持最小化到系统托盘;地图预览加入显示切片网格功能;
~修复一些已知Bug;
2011.11.21更新v2.0.3:
~增加REST Admin API。任何程序可通过发送HTTP(POST)请求,对PBS的服务进行管理。新增操作:添加服务(addService),删除服务(deleteService)。详见这里
~底图风格化选项增加泛黄(tint)与浮雕(embossed)两种效果。详见这里
2011.11.08更新v2.0.2:
~数据源增加对ArcGIS Tile Package格式的支持。Tile Package是ArcGIS 10.1推出的便于分发,可将地图服务缓存文件(compact或exploded)打包成单一文件的文件格式。详见这里
~增加对单一服务的清除内存缓存功能;
2011.11.04更新v2.0.1:

~增加对单个服务是否启用内存缓存的控制;
~增加输出动态生成切片数量和内存缓存切片数量的信息;
~界面微调;
~修复bug:32位系统上无法启用内存缓存功能;
~修复bug:移动PBS文件夹后,启用内存缓存功能时可能报错;
~修复bug:对服务启用反色(Invert)视觉效果后,PBS内存占用过大;
~修复bug:在没有网络连接的情况下,双击预览没有初始范围的数据源时(第三方离线缓存或影像数据源),程序报错;

2011.10.31更新v2.0:

~增加内存缓存功能。可将已生成过的切片数据自动缓存在机器内存中,之后可从内存中直接返回该切片,而不是动态生成。启用内存缓存功能后,可显著提高PBS性能,尤其对于动态缓存地图服务功能(影像数据或动态地图服务作为数据源),在几乎不占用cpu资源的情况下,支持的并发数可提高数十倍。该功能利用Memcached完成,它是一个免费的高性能分布式缓存系统(http://memcached.org/)。详细介绍
2011.10.25更新v1.0.6:

~增加底图风格化选项。目前除了原本的底图之外,为所有服务提供两个视觉风格选项:灰度图(Gray)和反色图(Invert),用于特殊目的。比如使用灰度图可突出显示业务内容,详见这里详细介绍
2011.10.12更新v1.0.5:

~增加ArcGIS Server Endpoint(http://localhost/arcgis/rest/services?f=json)信息,以便需要此信息的程序来使用PBS发布的服务。比如可在Silverlight Viewer中,直接加载PBS转发的天地图服务;
2011.8.8更新v1.0.4:
~增加配置文件功能:可将已发布的服务保存为配置文件,下回启动程序时可载入配置文件以启动相应服务;
~增加选择本地IP地址功能:方便生成供其他机器使用的正确服务地址;
~修复bug:在有些机器上双击服务进行预览时,程序会崩溃。原因是预览窗口中的服务属性使用了xaml binding,但出现了没有捕捉到的异常(有vs2010开发环境的机器不会抛出此异常)。感谢ningjun198624的反馈
~修复bug:在没有vs2010开发环境的机器上发布RasterDataset数据源报错。原因是程序中使用的gdal由vs2010编译,需要用到几个额外的动态链接库。新版本中已将所需的文件随压缩包分发。
2011.7.31更新v1.0.3:
~影像数据源增加对.sid格式的支持:MrSID是LizardTech公司持有的高压缩比影像存储格式,根据GDAL的解释,最初被FBI用于指纹存储。了解遥感的mm同事告诉我,MrSID格式压缩率通常比ecw格式要高,并且使用更广泛;
~数据源增加对ArcGIS影像服务的支持:在10.1版本之前,ArcGIS Server发布的Image Service是不能够做切片的。通过PBS,可将ArcGIS Server的影像服务转换成动态缓存地图服务,既提高了显示速度和效果,又省去了切图时间和硬盘空间;
~添加平均出图时间统计:服务信息中增加“Seconds Per Tile”统计信息,即该服务平均成功输出一张切片所用的时间。
2011.7.24更新v1.0.2:
~影像数据源增加对.ecw格式的支持:ecw是ERDAS公司持有的高压缩比影像存储格式,压缩率可达1:2~1:100。比如1m大小的ecw文件可包含3波段3000*3000(行/列)大小的影像数据;
~影像数据源增加对.vrt格式的支持:类似于ArcGIS中的Raster Catalog。比如你有不同空间范围内的若干小的影像文件,可通过构建后缀名为vrt的xml文件,直接将它们通过动态镶嵌,发布为一个完整的动态缓存地图服务;
~修复bug:ArcGISDynamicMapService数据源输入错误服务地址时程序会崩溃;
~代码重构。
2011.7.17更新v1.0.1:
~数据源加入对影像数据的支持:对于大数据量的影像文件,无需切图,即可提供动态缓存地图服务。数据源选择RasterDataset,可发布文件形式的影像数据。利用GDAL读取栅格图像,支持格式见这里;不支持动态投影(TilingScheme文件中的空间参考必须与影像数据的空间参考一致);
~修复bug:未发布服务时点击“Copy to Clipboard”按钮出错;
~修复bug:预览窗口中左上角的缩放级别信息在有的坐标系下不准确。
————————————————-更新分割线————————————————-
  使用现在流行的Web地图API的第一件事情,就是往地图控件中添加一个底图(Basemap)图层,做为我们整个GIS应用的可视化基础。而这个底图图层通常有两个特点,一是经过了缓存,即服务器端提供已经预先缓存好或动态提供固定大小(比如256*256)地图切片,加快客户端的访问速度;二是该图层由一个REST风格的网络服务暴露出来。对于它的访问,客户端一般会发起若干个包含有三个关键参数的请求,比如http://hostaddress/servicename/LEVEL/ROW/COLUMN,将请求的结果(若干切片)拼接成我们所看到的地图。
  目前来讲,要使用这些底图服务的前提是,我们必须使用特定的客户端才能加载特定的底图服务,比如利用Google Maps API加载Google的底图;如果要加载自己地理数据,还需要有专门的GIS软件,比如ArcGIS Server来发布Map Service。
  为了解决这一问题,使得开发人员能够更加方便地加载各种底图服务,从而将更多的精力投入到做出更有用的系统中去,我做了这个称作Portable Basemap Server(简称PBS)的小程序供大家免费使用。它的目的是通过一个可以拷贝到U盘里的,免安装的WPF程序,来加载各种数据源作为底图图层,直接为更多的客户端API提供一致风格的REST底图服务,从而使开发人员免去为每个应用程序自定义图层的麻烦。

Untitled-1

关于PBS的功能

使用起来很简单,大致分四个步骤。1、选择数据源类型,2、设置数据源路径,3、设置将要发布的服务端口号和服务名,4、启动服务。程序界面如下:
image

一、选择数据源类型:

image

  • MobileAtlasCreator:MAC是一个开源的Java程序,可将在线地图切片保存到本地,比如Sqlite数据库中,供移动设备离线使用。介绍看这里。很多朋友都喜欢使用Google地图作为底图,以前的方法是,用第三方程序(MAC还是比较厚道的,不加水印没有任何功能限制)去下载切片,保存到本地,然后按照ArcGIS缓存的组织规则重新组织这些切片,再将其发布成缓存地图服务。最后一步比较麻烦。利用PBS,就可以直接读取MAC保存的Sqlite数据库,将其中的切片直接发布成可供多种客户端API使用的底图服务;
  • MBTiles:类似于MAC,但它有更严格的规范,比如在特定位置存储全图范围(MAC没有),具体规范查看这里。MBTiles切片存储遵循的是TMS规范,虽然这中规范已被WMTS逐步取代,但PBS依然支持这种数据源,可直接读取该数据源作为多种客户端的底图服务。可在这里下载一个海地的地形图进行试验;
  • ArcGISCache:这个不用多说了,ArcGIS Server生成的地图缓存,指定包含Conf.xml和Conf.cdi文件的文件夹作为数据源即可,PBS会自动读取Tiling Scheme;Exploded和Compact两种存储格式均可识别。如果是ArcGIS 10之前的切片,需要自己手动创建Conf.cdi文件(仿照现有的文件即可,里面存储的是全图范围);
  • ArcGISTilePackage:Tile Package是ArcGIS 10.1推出的便于分发,可将地图服务缓存文件(compact或exploded)打包成单一文件的文件格式,文件后缀名为.tpk。以前为了分发地图数据,需要将样式配置信息(针对所有图层的地图文档.mxd,针对单个图层的图层样式.lyer)和实际地理数据(.mdb/.gdb/.shp等)一起拷贝。自9.3.1的开始,为了便于地图数据的分发,ArcGIS推出了Layer Package格式(.lpk),它包括了图层样式(.lyr)以及引用到的实际地理数据。这样其他用户拿到一个文件,就可完全还原数据本身和显示样式。ArcGIS10开始推出Map Package(.mpk)格式,10.1开始推出Tile Package(.tpk),Locator Package(.apk)和Geoprocessing Package(.gpk)格式;
  • RasterImage:1.0.1版本开始支持。文件形式的影像数据。在项目过程中,可能需要加入高分辨率的影像文件做为底图服务,但对这些影像文件切图、保存需要耗费极大的时间、空间。利用PBS可将影像文件直接发布为动态缓存地图服务,无需切图即可达到缓存地图服务的效果。对栅格数据的读取是利用GDAL完成的,支持的影像格式见这里。发布的影像数据必须具有正确的空间参考信息(不支持动态投影);需要选择ArcGIS Server生成的TilingScheme(Conf.xml和Conf.cdi文件)以确定缓存服务的级别;
    1.0.2版本开始支持.ecw和.vrt影像格式。
    ecw是ERDAS公司持有的高压缩比影像格式,压缩率可达1:2~1:100。比如1m大小的ecw文件可包含3波段3000*3000(行/列)大小的影像数据;
    .vrt格式类似于ArcGIS中的Raster Catalog,具有对多张影像动态镶嵌的功能。比如你有很多空间连续的小的影像文件,它们加起来可能有上百G。通过构建后缀名为vrt的xml文件,直接将它们通过动态镶嵌,发布为一个完整的动态缓存地图服务。vrt文件可利用gdalbuildvrt.exe工具来自动创建,发布时PBS中数据源直接选择.vrt文件即可。vrt格式介绍一文,供参考。
    1.0.3版本开始支持.sid影像格式。
    MrSID是LizardTech公司持有的高压缩比影像存储格式,根据GDAL的解释,最初被FBI用于指纹存储。我对遥感知识知之甚少,做遥感的mm同事告诉我,MrSID格式压缩率通常比ecw格式要高,并且使用更广泛;
    v2.0.7版本开始,为影像数据源提供本地缓存功能,任何客户端浏览过的切片,都会存储在指定目录的本地缓存文件中;本地缓存文件存在的情况下,会首先从该文件中输出切片,而不是动态输出。对于多并发情况下的影像数据源,可大幅减少cpu的使用率(与内存缓存配合可达成二级缓存的效果)。此功能可通过配置文件中的AllowFileCacheOfRasterImage参数设置,默认为True。
    image
  • ArcGISDynamicMapService:此数据源是指利用ArcGIS Server发布的,没有创建过缓存的动态地图服务。动态地图服务如何作为缓存地图服务的数据源呢?这就是所谓的动态缓存服务,没有预先创建过缓存,但能够提供缓存服务效果,并且支持动态投影的服务,也可查看超图的在线帮助。通过PBS,也能够提供动态缓存服务了,并且不需要在客户端再去自定义图层,因为PBS已经为你做好,直接使用即可。还可以输入多个动态服务地址,通过多个服务实例来达到加速动态缓存地图服务的目的,原理说明可查看这篇文章。输入服务地址后,还需要选择Tiling Scheme。可以选择Google/Bing/ArcGISOnline采用的Tiling Scheme,也可指定ArcGIS Server创建的Tiling Scheme(Conf.xml和Conf.cdi文件),如果数据源的坐标系与指定的Tiling Scheme坐标系不一致,可以自动进行动态投影;2.0.5版本开始,在创建服务后,可为此数据源设置附加参数,比如layers,layerDefs等,达到控制图层可见性,按属性过滤图层内容等目的,具体语法请参考ArcGIS Server REST API
    image[4]
  • ArcGISImageService:ArcGIS Server发布的影像服务(ImageService)。10.1版本之前的ArcGIS,不支持ImageService的切图。类似于上面的动态地图服务数据源,PBS可将动态的ImageService转成动态缓存地图服务,既大大改善了ImageService的显示效果和速度,又省去了切图所需的时间和硬盘空间。支持输入多个影像服务地址,通过多个服务实例来达到加速动态缓存地图服务的目的。选择此数据源,默认填入Esri发布的全球Landsat数据影像服务地址,可通过观察原动态影像服务,对比PBS转换后的动态缓存地图服务的效果;
  • 各种在线地图:这个也不用多说了。目前支持OpenStreetMap,Google Maps街道图,Google Maps影像图,Bing Maps街道图,Bing Maps影像图,天地图(文字注记和地图是两个服务,可叠加)这几种在线地图作为数据源,天地图Tiling Scheme是WGS 1984坐标系的,其他几种均是WGS 1984 Web Mercator坐标系的。需要说明一点,如果你打算使用PBS为公网用户提供服务,选用在线数据源时可能会有延迟,因为PBS首先会下载切片到本机(内存中),然后公网用户在下载这些结果,局域网应用可忽略此问题(2.0版本开始提供内存缓存功能,可解决此问题);如果确实慢,可考虑使用MAC数据源(Bing Maps服务最好输入一个合法的API KEY,以用达到最快的下载速度)。v2.0.6版本开始,为在线地图数据源提供本地缓存功能,任何客户端浏览过或在格式转换过程中下载过的切片,都会存储在指定目录的本地缓存文件中;本地缓存文件存在的情况下,会首先从该文件中输出切片,而不是重新下载。此功能可通过配置文件中的AllowLocalCacheOfOnlineMaps参数设置,默认为True。还要郑重声明一点,这些数据源只能做试验使用,不能直接用于商业目的,没有技术手段限制,但大家要自觉。如需商用,还请联系最终服务提供商


二、设置数据源:

为选择的数据源类型设置相应的数据源位置即可。MAC和MBTile直接选去本地的Sqlite文件;ArcGISCache选择包含有Conf.xml和Conf.cdi的文件夹;ArcGISDynamicMapService直接输入一个或多个REST服务的地址;所有在线地图不需要设置数据源位置,PBS已为你做好。

三、设置端口号和服务名

PBS是通过.NET Framework的WCF框架完成的。在启动服务之前需要选择将服务发布到本机的哪个端口上。一个端口上可以发布多个服务,也可将服务发布在多个端口上。但同一端口上不能有同名的服务。
  DisableClientCache:默认情况下,PBS输出的图片可以被缓存在客户端,下次访问时会直接使用客户端的缓存而不需要重新绘制切片。勾选此选项后,PBS输出的图片响应会指明不允许客户端进行缓存,从而方便客户端每次都请求道最新的数据。
  Display”NoData”Tile:勾选此项后,在Tiling Scheme范围内,如果某些范围或某些比例尺没有创建缓存,则会显示一个NoData的图片;如果打算用此服务与其它服务叠加(保持此服务背景透明),请不要勾选。

四、启动服务

设置好上面参数后,点击“Start New Service”,即可启动该服务。启动好的服务会出现在下方的服务列表中:
image

五、服务管理

程序下方的服务列表内会列出所有正在运行的底图服务,会显示服务名,所在端口号,数据源类型,服务启动后输出的切片数量,平均成功输出一张切片所需时间,以及最后一次被请求的客户端ip地址做为服务情况的大致预览。可在服务列表中双击某个服务,会弹出一个对话框,调用ArcGIS API for WPF查看该服务,并显示该服务的详细信息。如果该服务缺少全图范围参数,比如MAC数据源,则会新弹出的WPF对话框会额外添加一个ArcGIS Online底图,以便方便浏览到该服务的范围。

image

如果加载某个切片失败,比如下载在线数据源时网络连接出现问题,会显示失败的图片:

image
  若要删除某个服务,请在服务列表中选中,然后点击“DeleteService”即可。
  此外,还可将已发布的全部服务保存成配置文件(v1.0.4版本以上),下回程序启动时可载入配置文件以启动相应的服务。配置文件保存在程序根目录下的Config.db文件中(sqlite文件格式)。

image

2.0.3版本开始,PBS增加REST Admin API。任何程序可通过发送HTTP(POST)请求,对PBS的服务进行管理。PBS的REST Admin API使用HTTP基本认证,即HTTP请求头(request header)中必须含有“Authorization”项,该项内容为Base64编码字符串,格式为“用户名:密码”。请求认证信息中的用户(包含正确的密码),必须为PBS运行机器上Administrators组中的成员,所发送的请求才会被正确处理,否则将返回包含详细错误描述的响应信息。
  为了保证PBS能够正确响应请求的操作,请求中的端口必须提前打开。2.0.3版本开始,PBS默认使用7080端口,该端口会在PBS启动时自动开启。可修改配置文件中的DefaultPort值来更改PBS使用的默认端口号。
  每项管理操作都需要相应的参数,参数提交格式为标准JSON对象,对象中每一个键值对即为一个参数(键应为string类型,值应为string/int/bool/null类型)。参数应存放于HTTP请求体(request body)内。
  ~添加服务(addService):v2.0.3,该操作的地址为“http://serverip:port/PBS/rest/admin/addService”,参数列表如下:

  • name:(必须)需要添加的服务名称;
  • port:(必须)需要添加的服务端口号;
  • dataSourceType:(必须)需要添加的服务数据源类型,例如“ArcGISTilePackage”。可选值:MobileAtlasCreator|MBTile|ArcGISCache|ArcGISTilePackage|RasterImage|
    ArcGISDynamicMapService|ArcGISImageService|OpenStreetMap|BingMapsRoad|
    BingMapsImagery|GoogleMapsRoad|GoogleMapsImagery|TianDiTuAnnotation|
    TianDiTuMap。区分大小写;
  • dataSourcePath:(必须)需要添加的服务数据源路径。文件数据源类型可用本地路径或UNC路径,比如“D:\arcgisserver\arcgiscache\CharlotteRaster.tpk”或“\192.168.0.100\arcgisserver\arcgiscache\CharlotteRaster.tpk”;ArcGIS动态地图服务或影像服务填服务地址;其余在线服务不需要此参数,填“”即可。注:RasterImage数据源路径中不能有中文字符;
  • allowMemoryCache:(可选)需要添加的服务是否允许支持内存缓存,默认为true。可选值:true|false;
  • disableClientCache:(可选)需要添加的服务是否禁止客户端缓存,默认为false。可选值:true|false;
  • displayNodataTile:(可选)需要添加的服务是否显示“Nodata”的切片,默认为false。如需要和其它服务叠加,此项需为false。可选值:true|false;
  • visualStyle:(可选)需要添加的服务的视觉效果,默认为None。可选值:None|Gray|Invert|Tint|Embossed。区分大小写;
  • tilingSchemePath:(可选)需要添加的服务使用的tiling scheme(缓存策略)文件路径。默认为null;

比如,在fiddler中发送如下请求:
image[7]

或用C#发送如下请求:

   1: byte[] postData = Encoding.UTF8.GetBytes(@"{""port"":7080, ""disableClientCache"":false, ""dataSourcePath"":""D:\arcgisserver\arcgiscache\CharlotteRaster.tpk"",""dataSourceType"":""ArcGISTilePackage"", ""tilingSchemePath"":null, ""allowMemoryCache"":true, ""visualStyle"":""None"", ""name"":""ServiceName1"", ""displayNodataTile"":false}");

   2:             HttpWebRequest myReq = WebRequest.Create("http://localhost:7080/PBS/rest/admin/addService") as HttpWebRequest;

   3:             myReq.Method = "POST";

   4:             string username = "Administrator";

   5:             string password = "123456";

   6:             string usernamePassword = username + ":" + password;

   7:             //注意格式 “用户名:密码”,之后Base64编码

   8:             myReq.Headers.Add("Authorization", Convert.ToBase64String(Encoding.UTF8.GetBytes(usernamePassword)));

   9:             myReq.ContentLength = postData.Length;

  10:             using (System.IO.Stream requestStream = myReq.GetRequestStream())

  11:             {

  12:                 requestStream.Write(postData, 0, postData.Length);

  13:             }            

  14:             WebResponse wr = myReq.GetResponse();

  15:             System.IO.Stream receiveStream = wr.GetResponseStream();

  16:             System.IO.StreamReader reader = new System.IO.StreamReader(receiveStream, Encoding.UTF8);

  17:             string content = reader.ReadToEnd();

  18:             receiveStream.Close();

  19:             reader.Close();

响应内容:JSON字符串,格式:{“success””: [ture|false],”message”: [detail message]}。如果操作成功,detail message将返回PBS服务信息的JSON字符串,如果失败,将返回详细错误原因。
  ~删除服务(deleteService):v2.0.3,该操作地址为“http://serverip:port/PBS/rest/admin/deleteService”,参数列表如下:

  • name:(必须)需要删除的服务名称;
  • port:(必须)需要删除的服务所在端口号;

响应内容:JSON字符串,格式:{“success””: [ture|false],”message”: [detail message]}。
  ~开启内存缓存(enable):v2.0.4,该操作地址为“http://serverip:port/PBS/rest/admin/memCache/enable”,参数列表如下:

  • memSize:(可选)内存缓存功能占用的内存大小,默认为64(M)。

如果内存缓存功能已经开启,返回结果依然为true,但会有额外提示。
  响应内容:JSON字符串,格式:{“success””: [ture|false],”message”: [detail message]}。
  ~关闭内存缓存(disable):v2.0.4,该操作地址为“http://serverip:port/PBS/rest/admin/memCache/disable”,此操作不需要参数(请求体为空即可,如有则忽略)。如果内存缓存功能已经关闭,返回结果依然为true,但会有额外提示。
  响应内容:JSON字符串,格式:{“success””: [ture|false],”message”: [detail message]}。
  ~清除某个服务的内存缓存(clearByService):v2.0.4,该操作地址为“http://serverip:port/PBS/rest/admin/memCache/clearByService”,参数列表如下:

  • name:(必须)需要清除内存缓存的服务名称;
  • port:(必须)需要清除内存缓存服务所在端口号;

响应内容:JSON字符串,格式:{“success””: [ture|false],”message”: [detail message]}。
  ~改变ArcGISDynamicMapService数据源的附加参数(changeParams):v2.0.5,该操作地址为“http://serverip:port/PBS/rest/admin/ArcGISDynamicMapService/changeParams”,参数列表如下:

  响应内容:JSON字符串,格式:{“success””: [ture|false],”message”: [detail message]}。
  后续版本将增加更多操作…

六、服务使用

启动好的服务都会暴露出来两个REST服务地址(v3.0版本开始支持WMTS规范),
imageArcGIS REST URL可供所有ArcGIS客户端API,包括Javascript/Flex/Silverlight/iOS/Windows Phone/Android,以及即将推出的ArcGIS Runtime直接使用;由于OpenLayer中可通过ArcGIS93REST图层直接加载ArcGIS的服务,因此PBS服务也可直接被OpenLayers客户端使用;而OGC WMTS URL则供所有支持WMTS规范的客户端使用。
  比如在ArcGIS API for Javascript中,我们在地图中添加一个底图图层,Url地址指向PBS发布的某个服务:
image

这样就能直接通过PBS为我们提供的,类似于原生ArcGIS缓存地图服务的Url地址,访问到第三方的底图数据了。开发人员从此免去了在客户端自定义图层,去加载第三方切片的麻烦。比如通过PBS提供的服务,分别在ArcGIS API for Javascript/Flex/Silverlight中调用Google Maps地图。

image

image

image

  v3.0版本开始,通过PBS发布的所有服务兼容OGC的WMTS规范(目前为1.0.0版本),支持KVP和RESTful两种编码方式。下图为不同客户端(ArcMap,OpenLayers,ArcGIS API for Silverlight,SuperMap iClient for Silverlight)加载由PBS发布的MapBox数据源的底图。
wmts
  除此之外,从1.0.6版本开始,PBS增加了风格化的选项,可以在不需要重新切图的情况下(动态地图服务则无需切图),直接改变所有底图服务的视觉呈现效果。目前提供视觉风格选项:灰度图(Gray)和反色图(Invert),用于特殊目的。比如使用灰度图可突出显示业务内容,详见这里
  2.0.3版本新增泛黄(tint)与浮雕(embossed)两种效果。
VisualSytle

 

七、格式转换

v2.0.6版本开始,PBS提供部分数据源格式之间的转换功能。

  • ArcGIS Cache转换到MBTiles格式:可将ArcGIS的缓存文件(紧凑/松散)转换成单个MBTiles格式文件,方便数据迁移。
    arcgistombtiles
  • Online Maps转换/下载到MBTiles格式:可将在线地图下载成单个MBTiles格式文件,方便你的方便。整个过程耗时取决于你的网速和在线地图数据源服务器的速度。v2.0.7版本开始,提供按Shapefile文件下载切片功能,对于不规则区域,可大幅减少切片下载数量。类似ArcGIS Server中的Map caching based on feature boundaries,此功能仅对大比例尺有效;请提前对Shapefile文件做要素合并,节点抽希等处理。按Shapefile文件范围下载时,下载进度,结果文件预计大小等信息无效。
    onlinemapstombtiles 捕获

  v2.0.7版本开始,为转换后的MBTiles文件增加了”压缩”选项,如果转换结果中,尤其在大比例尺下,包含大量沙漠,海洋等区域,可大幅减小MBTiles结果文件的体积。具体原理请参考MBTiles规范。例如,存储国内某城市0-17级切片的.mbtiles文件,不勾选”压缩”选项时文件大小220MB,经过”压缩”后的文件大小为150MB。”压缩”过程耗时取决于文件内容的多少,另外请确保磁盘剩余空间大于压缩前文件体积。
  上述转换会根据切片数量不同自动增加工作线程数:数据源为ArcGIS Cache时,每个线程处理128×128个切片;数据源为在线地图时,每个线程处理16×16个切片。

 

关于PBS的性能

PBS利用WCF REST框架开发,支持多用户,多并发请求,性能仅受机器硬件限制。初步用Apache JMeter做了测试,在我的笔记本上,通过PBS的REST服务,请求Sqlite数据库中一张22kb的图片,500个并发请求的响应时间在10ms以下:
image

在磁盘性能更好的服务器上测试,1000个并发请求的相应时间可以在10ms以下。
  而实际使用中,单个底图服务达到上千个并发请求的情况还是比较少见的,所以PBS可以满足大多数需求。
  从2.0版本开始,PBS增加了内存缓存功能。可将已生成过的切片数据自动缓存在机器内存中,之后可从内存中直接返回该切片,而不是动态生成。
image_thumb[3]
  2.0.1版本增加对单个服务是否启用内存缓存的控制,并增加输出动态生成切片数量和内存缓存切片数量的信息。
image_thumb[3]
  2.0.2版本增加对单一服务清除内存缓存的功能。
  只需在Memory Cache菜单下,勾选Enable选项,即可启用内存缓存功能。该特性可显著提高PBS性能,尤其对于动态缓存地图服务功能(影像数据或动态地图服务作为数据源),在几乎不占用cpu资源的情况下,支持的并发数可提高数十倍。该功能利用Memcached完成,它是一个免费的高性能分布式缓存系统(http://memcached.org/)。
  默认情况下,Memory Cache会使用64M机器内存来缓存切片数据,达到64M后,会自动替换掉最早的缓存数据。使用机器内存的大小可通过PortableBasemapServer.exe.config配置文件进行配置,只需修改其中MemcachedSize节点的数值即可。
  比如对于影像数据作为数据源的动态缓存地图服务功能,在服务器机器上,可配置更多的物理内存(比如4G)供PBS使用。这样一来,只需在第一个客户端访问时生成一次切片数据,后续的请求就可直接从内存中获得切片。以内存方式替代cpu的工作和硬盘的存储空间,使得PBS投入实际生产运行成为可能。
  经测试(笔记本环境),对于PBS转发的在线地图服务(Google Maps)中的一张切片,没有使用内存缓存功能时,100个并发请求响应时间平均为10秒左右(和我的网速慢也有很大关系),因为每次请求都需要在线下载该切片;使用了内存缓存功能后,对于同样的一个切片,100个并发请求响应时间平均为2毫秒(该切片已在内存中的情况,下同),500个并发平均响应时间为6毫秒,1000个并发平均响应时间为200毫秒左右。在内存更好的服务器上测试,可获得更理想的结果

总结

对于ArcGIS用户来说,通过PBS,可直接加载第三方的离线数据源(MAC/MBTile),而不需要按照ArcGIS的切图规则重新组织切片;可将动态地图服务转换成动态缓存地图服务,无需自己在客户端API中自定义图层;可使用多种数据源;
  对于OpenLayers用户,可使用更多的,内容更丰富的底图数据;
  Portable Basemap Server可装入U盘带走,在任何具有.NET Framework 4.0环境的机器上直接运行,无需安装。一个U盘即可提供多种底图,方便开发者使用;
  后续计划加入更多数据源,比如本地影像数据(已加入),以及为更多客户端提供支持。

下载地址

2012.11.14:Portable Basemap Server已在CodePlex上开源,LGPL协议。
http://www.arcgis.com/home/item.html?id=48bf53da123e442ab8ac9aed52747552
如果大家对于软件有任何意见或建议,欢迎在此篇博客中留言回复。

119 thoughts on “Portable Basemap Server:多数据源多客户端的底图服务器”

    1. 菩提老王 Post Author

      呵呵,这个主要是为开发人员准备的,所以一般机器上都应该有.net framework 4.0了。

    1. 菩提老王 Post Author

      数据源里提到的mac可以试一下,它能够把在线地图下载到本地,保存到sqlite数据库中。写程序再读出来保存成jpg格式应该不是太困难。

  1. alexshi9000

    这个东西能开放源代码吗?有个想法,PBS将解决逐步解决多数据源问题,能不能增加基于角色的权限控制功能,比如说用户是普通用户,那么他将只能看到部分地图服务,如果是受限的普通用户,那么只能对地图服务进行查询操作,不知道我有没有说清楚^_^

    1. diligentpig

      暂时没考虑。因为后续还要加入一些功能,做完之后大家需要的话可以开放。用户权限控制还是在应用程序级别做比较好,在后台或者对开发人员做限制不知是否有需要?

      1. alexshi9000

        这个想法的初衷是能提供一套管理地图服务的平台,可以支持多数据源,支持服务授权,目前北京**数码已经有这样的产品了。

  2. Zeng

    要是能有Android版的PBS运行在android移动设备上,就能够方便开发离线版的移动GIS,以应对网络不好的情况。

    1. diligentpig

      PBS是当做在线服务提供者的角色来使用的,不适合运行在移动端。你的需求可以通过直接在手机上加载离线数据源来完成,请参考:https://blog.newnaw.com/?p=736

  3. Pingback: 在ArcGIS Web API应用程序中使用灰度地图 - 菩提老王的葡萄架

    1. diligentpig

      这个可以有。打算在将来的某个版本,加入下载任意范围切片到本地文件(arcgis server缓存文件和mac/mbtile的sqlite文件格式)的功能。
      不过在线地图牵扯到版权问题,可能不能直接下载,需要找到一种变通可行的办法。

  4. mingkof

    希望支持各种切片存储的互相转换功能!
    这个功能还是有用的啊,就拿ArcGIS 自己的瓦片来说吧,“松散和紧凑”,如果转换就必须要通过ArcCatalog连接到Server上面再进行转换,太麻烦了。

  5. qfnhm

    我用你文章中提到的“海地的地形图”进行试验;为什么在PBS中可以预览到地图,用Arcgis+javascript就不能显示地图;求解,Arcgis+javascript代码和LZ给的图片中的一样;GIS新手求解~~~

    1. diligentpig

      你好,我这边试验是完全正常的。javascript api代码中首先需要连接互联网下载一段js脚本文件,如果机器无法访问互联网的话肯定是有问题的,而pbs预览用到的wpf api则不需要。

      1. qfnhm

        原来是我的浏览器设置代理导致无法显示地图;再请教个问题,MAC下载下来的Sqlite影像地图数据在PBS中无法预览,是怎么回事?

  6. qfnhm

    上个问题解决了,是我在联网的时候设置了浏览器的代理;还有个问题,我用MAC下载的影像图为什么在PBC中无法预览,怎么解决???

    1. diligentpig

      tile package格式实际上是个zip包,里面的主要内容是已经熟悉的compact格式的缓存切片。这样的话就可以读取了。具体可参考此文:http://www.gisall.com/html/35/160435-6285.html
      不过在客户端去加载tpk,要求每个客户端都有一份数据,一般不会这么做。

  7. mayimb

    你好,这工具真不错!
    但我现在遇到一个问题,我用MAC下了google和microsoft的街道图,发布了底图服务,
    然后在arcgis发布了动态的道路服务,这个动态道路和底图存在一点偏移,是我设置有问题呢
    还是啥原因呢?,谢谢,能否帮我分析分析

    1. diligentpig

      你好,pbs发布mac数据的底图服务正常?咱们看到网上的电子地图,矢量图都是经过偏移的,这是法律规定。如果你动态服务的道路数据没有经过偏移,那叠加起来肯定就有偏差了,一般在1-200米左右。mac下载的影像图是没有偏移的,可以再试验一下。

  8. eggh

    你好,能否增加sogoumap,baidumap等四维图新的底图哦?目前发现支持的基本上都是MapABC的底图。,还有就是用MAC下载图片,有些太大,只能下载成多个db库,莫非只有自己去合并这些库为一个吗?sqlite一个文件的容量到底有好大哦?

    1. diligentpig

      理论上,sqlite数据库的体积最大限制是140TB(140*1024GB)。不知你用MAC下载了多大范围的切片?另外是否是由于FAT32格式的4GB限制了文件体积?
      如果可以,请列出你希望加入的底图链接,我会尝试加入。下个版本已经确定会加入高德地图和nokia地图。

      1. eggh

        我下载的切片3440640,17级,也就是整个大重庆17级的的切片,结果MAC禁止一次下载这样大。莫非只有减小尺寸,下载为多个sqlite文件,然后对文件进行合并?
        能否支持map.sogou.com, 和map.baidu.com的地图呢?

        1. eggh

          补充一下,我是用的MacOS的操作系统,我是用的苹果电脑64位的操作系统Mac OS X 10.7.3版本的。

        2. 菩提老王 Post Author

          mac下载的rmaps离线文件应该没有限制,通常一个城市下载到17级左右大小可能在几百m,不会有问题的。http://bbs.hiapk.com/bbs/viewthread.php?tid=147574

  9. 林南

    老王您好!请教一个问题,PBS最新版本2.0.4在服务预览中加入了网格显示,网格原点在左上角。但MBTiles规定的原点应该在左下角吧?所以在预览MBTiles发布的服务时,PBS网格显示的行列号,和MBTiles实际存储切片的行列号是不一致的?还是ArcGIS的这个控件在访问MBTiles的时候,转换了行列号?能否解答我的疑问?纠结了很久,灰常灰常感谢~~

    1. diligentpig

      你好,你说的这个问题确实存在,目前版本显示MBTile的行列号是错误的。目前的行列号是按照ArcGIS/Google Maps/Bing Maps的缓存规则从左上角计算行列号的,没有针对MBTile做单独处理。下个版本中会更正这个问题,感谢提醒。

  10. Pingback: Portable Basemap Server发布2.0.5版本 - 菩提老王的葡萄架

  11. Pingback: Portable Basemap Server发布2.0.6版本 | 菩提老王的葡萄架

  12. alexshi9000

    老王,问你个flex调用天地图服务的问题:
    程序开发的时候,调用底图,放大,原先的瓦片待新的瓦片加载之后消失。但是程序发布后,放大,旧的瓦片没有等新的瓦片加载完成就消失了,导致地图浏览出现空白,这个问题是怎么回事?

    1. 菩提老王 Post Author

      建议在程序发布的环境里,调用其他在线服务看看。排查是程序的问题还是天地图数据源的问题

  13. Pingback: Portable Basemap Server发布2.0.7版本 | 菩提老王的葡萄架

  14. Saga

    請問一下:這邊直接生成的 google map 或是 bing map 都是簡體中文的,有沒有辦法轉成英文或是繁體中文的地圖?

    1. diligentpig

      方法参考这个帖子:http://productforums.google.com/d/msg/maps-zh-cn/MPgigPVdsWQ/MdlfzIj3aZwJ
      将customonlinemaps.xml中google地图链接里的hl=zh-CN修改成相应的语言字母即可。我试了en和zh-TW,可以满足你的需求。

  15. horseluke

    看到这神器简直泪流满面啊,妈妈再也不用担心我的地图数据缓存不了啊… :mrgreen:

    一点建议:
    可以指定是否启动自带的memcache、以及启动的端口。我的电脑上由于已经有memcache,产生了冲突,导致内存缓存失败……

  16. horseluke

    我用openlayer的 wms.js 调用 此类 wmsts 服务。 始终不出图。 您能否将你的这段代码共享下? 麻烦了

    1. diligentpig

      上面ol例子网址里,wmts.js的全部代码:
      var projection = ol.projection.get(‘EPSG:102100’);
      var projectionExtent = projection.getExtent();
      var size = ol.extent.getWidth(projectionExtent) / 256;
      var resolutions = new Array(19);
      var matrixIds = new Array(19);
      for (var z = 0; z < 19; ++z) {
      // generate resolutions and matrixIds arrays for this WMTS
      resolutions[z] = size / Math.pow(2, z);
      matrixIds[z] = z;//matrixIds[z] = 'EPSG:102100:' + z;
      }

      var map = new ol.Map({
      layers: [
      new ol.layer.TileLayer({
      source: new ol.source.OSM(),
      opacity: 1.0
      }),
      new ol.layer.TileLayer({
      opacity: 0.8,
      source: new ol.source.WMTS({
      url: 'http://192.168.100.109:7080/PBS/rest/services/MapBox/MapServer/WMTS&#039;,
      layer: 'MapBox',
      matrixSet: 'default028mm',
      format: 'image/jpg',
      projection: projection,
      tileGrid: new ol.tilegrid.WMTS({
      origin: ol.extent.getTopLeft(projectionExtent),
      resolutions: resolutions,
      matrixIds: matrixIds
      }),
      //style: '_null',
      extent: [-20037508.342789244,20037508.342789244,-20037508.342789244,20037508.342789244]
      })
      })
      ],
      renderer: ol.RendererHint.CANVAS,
      target: 'map',
      view: new ol.View2D({
      center: [0, 0],
      zoom: 1
      })
      });

  17. Saga

    請問一下轉出來的 MBTiles 可以合併嗎? 我是說同一個服務我分兩次不同地方轉成 MBTiles 但我想要合併成同一個檔案可以嗎?另外 MBTiles 支援的最大檔案容量是多少? 謝謝

    1. diligentpig

      PBS没有提供合并MBTiles的功能。
      如果需要下载不连续地理范围的切片,可利用shapefile指定下载范围即可(两个或多个相离的多边形);此外2.0.6版本开始提供了本地缓存文件(https://blog.newnaw.com/?p=890#OnlineMapsLocalCache),即默认下载过的切片会保存在本地缓存文件.cache中,下次下载同一范围切片可直接从缓存中输出而不是在线下载。如果你的.cache文件中已经有两个需要合并范围的切片,那利用shapefile指定两个多变形后重新下载,绝大多数的切片都会直接从缓存文件输出,而不需在线下载,相当于合并了,过程会很快完成。
      最后,也可用sql语句来合并mbtiles,具体需要对mbtiles规范比较熟悉。
      mbtiles格式是sqlite,根据官方页面提示https://www.sqlite.org/limits.html,理论上大小可达140TB左右,但也有人建议应控制在100GB以下,供参考。

  18. dakyuan

    选择以windows服务运行后,关掉UI,为什么PBS服务是’已停止’状态,而不是‘正在运行’? 为什么要删除服务才能重现UI呢?

    1. diligentpig

      只要windows服务显示为已停止状态,就可以启动ui了,不用删除服务。目前服务和ui不能同时运行,是想让启动ui时,保持pbs的便携性(绿色),而不依赖于windows服务;以服务方式运行是为了给想让pbs运行在服务器上的人使用的。
      如果有好的兼容或替代方式,后面会进行改进。

  19. Saga

    您好:請問下載tiles有什麼限制嗎?我下載bing map imagery到了約2.3G大小就出現了out of memory的問題,我的作業系統是windows 8 64bit,16G ram。需要作什麼設定嗎?

    1. diligentpig

      目前正在做测试,在mbtiles在4g大小左右时出现了别的问题,没有重现out of memory的异常。暂时建议开启文件缓存(allowfilecacheofonlinemaps=true),这样程序中断后可接着上一次进度下载。如发现bug后续会推出修正的版本,谢谢反馈!

        1. diligentpig

          感谢反馈,我这边也发现了同样的问题。由于其他原因,最近投入在pbs上的精力比较少,但会尽可能快的排查这个问题的原因。在此之前我会尽快推出一个新的workaround版本来,让用户能避过这个问题,持续生成更大的mbtiles文件。

          1. diligentpig

            新版本还得等加入些其他功能才能推出,不过现在已经加入了RecreateEmptyCache这个模式,可以增量更新MBTiles文件了,利用它也可以实现合并多个地理范围或者多个比例尺级别的功能。测试地址在这:
            https://www.dropbox.com/s/cuozmoqwblv7uto/output.7z
            这样在下载大范围的切片时可跳过已下载好的部分(如果文件太大,这个过程仍需要一定时间),只下载未完成的部分就行了。

          2. Saga

            現在有一個新的問題在抓某些地方的Cache時會出現「Online maps converting to MBTiles error! 索引超出範圍,必須非負數且小於集合的大小。參數名稱:index」,請問這部分我該怎麼解決呢?謝謝

          3. 菩提老王 Post Author

            原来在经度循环的时候有这个问题,新发的测试版已经把经度循环去掉了。不知道你说的这个问题通过什么步骤和什么具体位置能复现出来?我测试一下

  20. swd

    老王你这个东西真的很好。
    有没有考虑在以后的版本中加入百度地图,现在所有的地图中百度做了最好了感觉。

    1. 菩提老王 Post Author

      暂时没有这个计划。百度地图的切片有偏移和加密,不能通过自定义模板加载。如有需要,可以自己修改源代码增加这个类。

  21. jyxl

    好像arcgis调用pbs发布的wmts服务,
    在线地图只能显示jpg格式的图片,
    而mac下载的离线地图只能显示png格式的,
    不知是不是这样,希望下一版本在线、离线地图都能显示,谢谢!

  22. nautilus

    一个建议:创建服务后,如果要调整参数,如“视觉效果”等,则需要删除服务,再重新建立服务,这样太麻烦,不能修改设置后,显示“重启服务”按钮吗?

    一个问题:我用格式转换下载谷歌地图到MBTiles,范围是鼠标画的江苏到上海一块,8-17级,上面预估大小1879M,由于耗时较长,我每次都通宵不关电脑下载。前天开始下载,昨天早上一看出错崩溃掉了,文件大小2.08G。然后我重新下载,昨天下班前显示正在压缩,文件大小2.3G,结果现在看还是正在压缩。不知道是因为什么?

    1. 菩提老王 Post Author

      感谢建议,后续会考虑修改的。另外压缩功能适用于大比例尺级别下连续大片范围都是同样切片,比如沙漠海洋地区的,城市范围内不建议压缩,效果基本体现不出来。

  23. 小西门

    请教:天地图的服务不能实现代理,是因为天地图新版的地址变了吗?
    建议:将代理服务的地址写成可交互或可查看的,便于发现问题。

  24. 悟空

    在做ArcGIS 缓存转MBTILES时遇到如下错误:
    —————————
    Error
    —————————
    ArcGIS cache converting to MBTiles error!

    The WKID of ArcGIS Cache is not 3857 or 102100!
    —————————
    确定
    —————————

    1. 菩提老王 Post Author

      你好,mbtiles规范规定其存储切片只能是wgs 1984 web mercator坐标系的(wkid=3857 or 102100),所以PBS首先会做检查。否则转存的文件在其他实现mbtiles规范的软件里读不出来的。

    1. 菩提老王 Post Author

      这个真没有。牵扯到版权,本来online maps->mbtiles已经属于副产品了,不打算再提供更多更能,有需要可以自己修改源码实现。

        1. Joe-xXx

          从mbtiles的tile_col和tile_row算出来的地理范围,怎么和真实相差挺大的?

          坐标计算思路:mbtiles(col,row)->google_tiles(col,row)->根据原点算出Web墨卡托投影下的x,y->反算出经纬度(lon,lat)

      1. Joe-xXx

        经纬度大地坐标计算思路:mbtiles(col,row)->google_tiles(col,row)->根据原点算出Web墨卡托投影下的x,y->反算出经纬度(lon,lat)

        是否正确?

        1. 菩提老王 Post Author

          坐标计算思路:mbtiles(col,row)->google_tiles(col,row)->根据原点算出Web墨卡托投影下的x,y->反算出经纬度(lon,lat)

          这个思路是正确的。源代码里有个utility类,里面应该有上面几个过程的方法,你可以参考。

  25. dong

    googlemaps卫星图有偏移的,把原来的地址CustomOnlineMaps文件里的google卫星图地址改成https://khms{$s}.google.com/kh/v=144&x={$x}&y={$y}&z={$z}&s=就变成没有偏移的啦

  26. cc

    你好大师!我开始使用你的server开始做数据编辑工作,因为有一个好的离线地图,方便地图数字化,但是我想把某个地图服务的投影参数修改成为我自己设定的参数,我该怎么做?我查了mbtiles里面好像没有专门的字段储存这个投影数据,还是server本身可以接受xml的参数设定?特别说明,我只是想针对某一个服务修改投影参数,而不是全部的服务

    1. 菩提老王 Post Author

      在切片生成之前,你可以转换地图服务的空间参考参数,比如为要生成的切片指定conf.xml参数。切片生成之后是改不了的,除非重新做切片。

  27. Dongyu

    菩提老王的东西真好,不过最近好像用Google Road Map 的时候好像加载不了了,是不是目前google地图的服务不能调用了啊。

    1. Dongyu

      感谢菩提老王了,我发现问题在哪了。在国内访问google.com有困难,所以把所有的google.com改成google.cn就可以解决了。

  28. lx

    菩提老王你好!通过这个软件加载的地图貌似不太准,我发布了之后,在ArcMap里加载,然后测量距离,跟实际的怎么不一样?比如在北京地铁西直门站到复兴门站的距离,测得4.8公里,但是在管网的地图上是3.6公里。

  29. 老c

    老王你好,我在旁边是3.1里添加mobac的data
    G:Mobile Atlas Creator 1.9.16tilestoredb-Microsoft Earth0000000.jdb
    报错误 不是database文件,或文件加密了

  30. Sadegh

    Hi
    I have problem for mbtile that i downloaded from format convert.
    If you run service from online database like google imagary .in autocad map 2022 it accept wmts and show google with no error

    But if you have mbtile and make service of it the and use wmts url on autocad map 2022 it shows error:
    Faild to get bands data
    Invalid data

Leave a Reply to swd Cancel Reply

Your email address will not be published. Required fields are marked *