C++语言的开源WebGIS解决方案:PostGIS+Mapserver+OpenLayers

最近在做毕业设计,准备开发一种栅格数据的空间索引,也顺便实现一下从本科毕业开始的宏愿,于是进行了调研,选择了这套解决方案,即利用PostGIS做后台,Mapserver做服务,OpenLayers做交互实现WebGIS的开发。

测试1:利用QGIS+Mapserver+OpenLayers实现栅格数据的可视化

参考文章:CSDN博文

1、利用QGIS添加Raster文件,并生成Mapserver的map文件;

这里需要熟练使用QGIS的Plugins,而高版本的QGIS对PostGIS,Mapserver的支持并不好,因此推荐采用1.8.0版的QGIS进行操作。

此外,QGIS并不原生支持PostGIS的Raster数据,因此这也是强烈推荐低版本QGIS的原因。

S1、下载,安装,打开QGIS1.8.0【点击打开链接】,添加Raster图层

S2、添加插件MapServer Export

S3、将栅格图层导出为map文件。

2、利用Mapserver发布map文件,并测试;

不建议自己编译Mapserver,采用官方发布的ms4w在线下载就好了。配置过程中顺风顺水,问题不大。

截至到此,参照参考博文中1-6步即可实现。

S1、下载并安装ms4w点击打开链接

S2、配置map文件。

安装ms4w,将map文件配置到ms4w目录下:ms4w/Apache/htdocs,之后重新ms4w服务,即在cmd中启动apache-restart。

根据cmd中的ERROR提示,修改.map文件中的部分相对路径。例如找不到文件云云。

注意,如需要执行apache-install,请用管理员权限启动命令行。

S3、本地测试map文件。

输入 http://127.0.0.1/cgi-bin/mapserv.exe?MAP=D:/ms4w/ms4w/Apache/htdocs/marsmap.map&LAYERS=ALL&MODE=MAP,对map文件进行测试。

本人的map文件测试结果如下【火星全球影像】

3、利用Mapserver发布WCS服务并测试;

详情参考:MapServer官方帮助

S1、修改.map文件以发布WCS服务,语法和要求见MapServer官方帮助CSDN博文

S2、利用命令测试WCS服务,MapServer官方帮助

这里列举3种请求代码。

GetCapability测试

http://127.0.0.1/cgi-bin/mapserv.exe?MAP=D:/ms4w/ms4w/Apache/htdocs/marsmap.map&SERVICE=WCS&&VERSION=1.0.0&REQUEST=GetCapabilities
DescribeCoverage测试

http://127.0.0.1/cgi-bin/mapserv.exe?MAP=D:/ms4w/ms4w/Apache/htdocs/marsmap.map&SERVICE=WCS&&&VERSION=1.0.0&REQUEST=DescribeCoverage&COVERAGE=RASTER_GLOBAL

GetCoverage测试

http://127.0.0.1/cgi-bin/mapserv.exe?MAP=D:/ms4w/ms4w/Apache/htdocs/marsmap.map&&SERVICE=WCS&VERSION=1.0.0&REQUEST=GetCoverage&coverage=RASTER_GLOBAL&CRS=EPSG:4326&BBOX=-180,-90,180,90&WIDTH=600&HEIGHT=300&FORMAT=image/png
测试返回一张xml表或图片,正确测试结果可参考MapServer官方帮助中的Example。

当测试结果出错时,可以打开map文件的DEBUG格式输出错误日志进行Debug。


参考官方文档发布WCS问题重重,由于map文件由QGIS生成,需要多次修改,在这里列出碰到的部分问题。

  • msSaveImage(): Unable to access file. Failed to create output file (/tmp/wcs_sample14803471043908.png).

修改WEB选项中的PATH,将相对路径变为绝对路径。

  • 利用&SERVICE=WCS&&VERSION=1.0.0&REQUEST=GetCapabilities,返回值中无ContentMetadat.

点击打开链接得出灵感,对map文件进行Debug调试,发现问题出在Projection上,经过修改以后可以查询到ContentMetadata。

4、在OpenLayers中添加Layers。

S1、下载OpenLayers并调用,OL3下载

ol3是个JS,因此直接在同名文件夹下建立文本文件,改名为index.html。

S2、WCS代码中添加如下内容【根据不同需要修改,参考 OL工程部分中文简介 OL3官方API

<!DOCTYPE html>
<html>
  <head>
    <title>My Mars MapServer</title>
    <link rel=”stylesheet” href=”https://openlayers.org/en/v3.19.1/css/ol.css” type=”text/css”>
    <!– The line below is only needed for old environments like Internet Explorer and Android 4.x –>
    <script src=”https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL”></script>
    <script src=”https://openlayers.org/en/v3.19.1/build/ol.js”></script>
  </head>
  <body>
    <div id=”map” class=”map”></div>
    <script>

    var tileSource=new ol.source.TileWMS({
url:’http://127.0.0.1/cgi-bin/mapserv.exe?’,
params:{
‘map’:’D:/ms4w/ms4w/Apache/htdocs/marsmap.map’,
‘SERVICE’:’wcs’,
‘VERSION’:’1.0.0′,
‘REQUEST’:’GetCoverage’,
‘coverage’:’RASTER_GLOBAL’,
‘BBOX’:[‘-180′,’-90′,’180′,’90’],
‘CRS’:’epsg:4326′,
‘FORMAT’:’image/png’
},
serverType:’mapserver’
});

var layers =[
new ol.layer.Tile({
title:’mapserver-geotiff’,
extent: [-180,-90,180,90],
source:tileSource
    })];

var map = new ol.Map({
layers:layers,
target: ‘map’,
view: new ol.View({
center:[0,0], 
projection:’EPSG:4326′,
zoom: 3 })
      });
    </script>
  </body>
</html>

代码分块讲解:OL3用以显示地图并进行交互的对象为Map,而在Map中包含数个Layers,Layers中主要对象又包含多种,为了达到调用WCS服务的目的,我们创建Tile对象,Tile对象从TileWMS数据源中通过’GetCoverage’请求调用瓦片,从而达到在OL3中加载WCS瓦片的目的。

其基本html结构显而易见,JS部分代码分块讲解如下:

1、TileWMS

var tileSource=new ol.source.TileWMS({
url:’http://127.0.0.1/cgi-bin/mapserv.exe?’,
params:{
‘map’:’D:/ms4w/ms4w/Apache/htdocs/marsmap.map’,
‘SERVICE’:’wcs’,
‘VERSION’:’1.0.0′,
‘REQUEST’:’GetCoverage’,
‘coverage’:’RASTER_GLOBAL’,
‘BBOX’:[‘-180′,’-90′,’180′,’90’],
‘CRS’:’epsg:4326′,
‘FORMAT’:’image/png’
},
serverType:’mapserver’
});
利用ol.source.TileWMS发送getcoverage请求以调用瓦片,其余参数为mapserver调用WCS必备参数,主要包含wcs服务版本,服务器类型,坐标系,范围等。可以参考OL3官方API

2、创建一个包含Tile的Layers。

var layers =[
new ol.layer.Tile({
title:’mapserver-geotiff’,
extent: [-180,-90,180,90],
source:tileSource
    })];

创建一个Layers,Layers中包含一个Layer,此Layer中引用了上面ol.Source.TileWMS,并制订了名称和范围。

3、创建一个包含view的map。

var map = new ol.Map({
layers:layers,
target: ‘map’,
view: new ol.View({
center:[0,0], 
projection:’EPSG:4326′,
zoom: 3 })
      });

创建一个Map,Map中包含一个View并引用了上文的layers,指定了对象map,View中还定义了坐标系和范围。

最终结果如图所示,笔者通过ol和Mapserver加载火星全球栅格数据,测试成功。

改进1:在MapServer中添加栅格数据缓存服务

经过测试1中的步骤,我们初步实现了栅格数据的加载,但我们发现,对于一次访问,数据的加载可以说是慢之又慢,硬盘却在喀喀喀的转,查看了map文件中设置的tmp文件夹,发现文件夹空空如也。因此推测,MapServer中的WCS数据并没有缓存。

为了做到让自己的WebGIS像度娘地图一样如丝袜版流畅顺滑,准备在MapServer中添加栅格数据缓存服务。

通过MapServer使用笔记我们发现,还真有这种东西。看了介绍,楼楼决定使用TileCache进行缓存的尝试【因为另一个是基于Java的,看到第一步需要在Tomcat中解压我就跪了】。

Apache和IIS都是服务器的一种服务,利用Apache调用TileCache需要在Apache中增加modpython插件,并调用TileCache。因为modpython并没有针对Apache2.4.0的release包,进行编译代价过大,因此采用IIS服务发布TileCache。

S1、配置TileCache配置可以参考点击打开链接,楼主系统是Win10,IIS服务组件没有安装,因此还百度了一下如何开启IIS

配置过IIS以后,进行测试:

http://localhost/tilecache-2.11/tilecache.py?LAYERS=RASTER_GLOBAL&SERVICE=WMS&VERSION=1.0.0&REQUEST=GetCoverage&SRS=EPSG:4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256

发现问题:

  • An
    error occurred: No section: ‘cache’

采用点击打开链接,在.py文件中的选取内用[]扩选,问题解决。

  • An error occurred: coercing to Unicode: need string or buffer, list found

利用PyCharm对tilecache.py进行调试,发现依旧是由于文件名错误导致。

S2、配置好TileCache后,利用Openlayers调用Tilecache源,进行栅格数据缓存。

转载自:https://mtr-1.oss-cn-beijing.aliyuncs.com/qyblog/2019/04/53369076.jpg

You may also like...

退出移动版