随着越来越多智慧城市项目的落地实施,基于 GIS 的应用程序展现出越来越广泛的应用场景,例如大多数行业都需要对真实世界中的现有资源进行可视化的实时监控、分析、操作从而提高效率,使得利益最大化;再比如基于位置的服务也越来越在公众中普及,如此等等。正因为有着如此广泛的应用场景,如何经济、快速的搭建一个开发环境,并依托此环境构建各式各样的 GIS 应用就成了一个值得关注的话题。
本文中,作者总结了在实际项目中如何快速利用开源软件构建 GIS 开发环境的实践方法和技巧,以及在搭建和使用 GIS 开发环境中所遇到的问题的解决办法,并通过一个示例将这些经验分享给需要开发 GIS 应用程序的开发人员。
通过本文,读者可以了解到 GIS 应用程序的体系结构,并能根据自身项目的特点确定所需的开源 GIS 软件,且能够快速搭建一套 GIS 开发环境来构建 GIS 应用程序。
一个基本的 GIS 体系结构可以按层次在逻辑上进行抽象,如下图所示,主要包括以下四个部分:
上图所列举的体系结构是一个标准的三层结构,包括了用户交互层、中间层(包括 Web 服务器和 GIS 服务器)以及数据层。
在软件世界里,开源无所不在。开源 GIS 软件目前已经形成了一个比较齐全的产品线,打开 FreeGIS[2] 的网站,我们可以找到各具特色的 GIS 软件,从中可以找到很好的商用 GIS 软件的替代品。
针对不同的层次,通过比较常用开源 GIS 软件的用途和优势,并且结合自身的需求,选择如下的 GIS 开源软件。
提到 GIS 的渲染引擎,很多开发人员首先想到的可能是 OpenLayer 这款著名的使用 JavaScript 的开源 GIS 前端,但是,从技术上来说,基于 Flex 的前台地图框架也有着很大的应用空间,所以我们选择的是一款基于 ActionScript3 和 Flex 的开源 GIS 前端产品 OpenScales。它是一个优秀的前台地图框架,提供了相对完善的功能,主要包括:
MapServer 是利用 C 语言开发的开源 WebGIS 项目,它是一套基于胖服务器端 / 瘦客户端模式的实时地图发布系统,客户端发送数据请求时,服务器端实时的处理空间数据,并将生成的数据发送给客户端。MapServer 有如下几个关键的特性 [4]:
PostGIS 在对象关系型数据库 PostgreSQL 上增加了存储管理空间数据的能力,是最著名的开源 GIS 数据库。
从 MapServer 产品页面下载最新版本。尽管官方文档对 Unix 和 Window 平台下的源代码安装步骤给出了详细的说明,但是笔者通过实践可以发现,在 Win32 平台下,从源代码编译安装 MapServer 是一个复杂的任务,所以推荐使用 MapServer 给出的已编译安装包 MS4W,从而能快速搭建开发环境。
将下载的 MS4W 解压到硬盘指定的目录,然后在命令提示符窗口切换到 MS4W 所在的目录,运行 apache-install,如果结果如下图所示则表示安装成功,或者使用浏览器访问 http://127.0.0.1/cgi-bin/mapserv.exe,验证 MapServer 返回的提示信息。
使用 MapServer 发布地图数据,关键就是要编写一个后缀名为 map 的 Mapfile 配置文件。在官方文档中,介绍了手工编写该配置文件的方法,关于手工编写的格式和注意事项会在后面的实例中有所介绍;同样读者还可以通过其他图形化配置界面工具或者是开源桌面软件来生成 Mapfile 文件。
安装 PostGIS 空间数据库的前提条件是有关系型的 PostgreSQL 数据库,而且值得注意的是 PostgreSQL8.3 以上的版本才支持 PostGIS 空间数据库。
这样,首先从 PostgreSQL 产品页面下载最新 Windows 版本的安装文件,接下来按照安装进度依次选择安装目录、数据目录、密码和端口,等待 PostgreSQL 安装完成之后,会出现如下界面:
点击完成按钮之后选择所需要的 PostGIS 版本以及下载地址后进行安装:
PostGIS 空间数据库安装完成后,可以做如下的验证:
如果能得到如上述的结果,说明 PostGIS 安装成功,并且顺利导入 Shape 格式的矢量数据。
利用上述搭建的开发环境,接下来将展示如何使用 OpenScales,并且在 MapServer 和 PostGIS 的帮助下快速构建一个 GIS 应用程序。在这个应用程序中,将展示如下几个关键内容点,包括:
准备三种数据源
为了能演示支持三种不同形式的数据,需要准备三个数据源,分别是:
编写 Mapfile 文件
准备好数据之后,接下来要利用 MapServer 搭建的 GIS 引擎来获得上述的数据,完成这一步最最为关键的就是编写 Mapfile 文件了。在这里,为了方便介绍细节,我们采用手工编写 Mapfile 文件的方式。以下是一个示例的 Mapfile 文件。
MAP Object 是 Mapfile 的根对象,它包含了一系列的属性,结合下面的示例文件,介绍 MAP Object 的结构和部分常用属性。
1 MAP 2 NAME "china" 3 SIZE 400 300 4 IMAGECOLOR 255 255 255 5 IMAGETYPE JPEG 6 SHAPEPATH "data" 7 EXTENT 73.447 3.408 135.086 53.558 8 9 PROJECTION 10 "init=epsg:4326" 11 END 12 13 WEB 14 TEMPLATE "/ms4w/apps/testshapefile/index.html" 15 IMAGEPATH "/ms4w/tmp/ms_tmp/" 16 IMAGEURL "/ms_tmp/" 17 END 18 19 LAYER 20 ……
代码 1 中出现的一般参数及含义如下:
同时,MAP Object 允许一些嵌套的对象:PROJECTION, QUERYMAP, REFERENCE, SCALEBAR, SYMBOL, WEB. LAYER, LEGEND。接下来将介绍在示例文件中用到的三个嵌套对象,其他对象的详细用法可以参考 MapServer 的官方文档:
下面是一段 LAYER Object 的示例代码,分别介绍了如何展示从空间数据库,Shape 文件(矢量数据)和 GIF 文件(光栅数据)导入的地理数据。
1 LAYER 2 NAME "chinalayer" 3 STATUS ON 4 TYPE line 5 CONNECTIONTYPE postgis 6 CONNECTION "host=** port=* dbname=postgis user=postgres password=passw0rd" 7 DATA "the_geom from bou2_4l" 8 9 CLASS 10 STYLE 11 COLOR 255 0 0 12 END 13 14 LABEL 15 COLOR 255 0 0 16 SIZE SMALL 17 END 18 END 19 END 20 21 LAYER 22 NAME "chinalayer2" 23 STATUS default 24 TYPE line 25 DATA "BOUNT_line" 26 27 CLASS 28 STYLE 29 COLOR 0 0 0 30 END 31 32 LABEL 33 COLOR 0 0 0 34 SIZE SMALL 35 END 36 END 37 END 38 39 LAYER 40 NAME "chinalayer3" 41 DATA "test_gif.gif" 42 STATUS ON 43 TYPE RASTER 44 #PROCESSING "SCALE=-10,10" 45 PROCESSING "SCALE_BUCKETS=2" 46 47 CLASS 48 STYLE 49 COLOR 0 0 0 50 END 51 52 LABEL 53 COLOR 0 0 0 54 SIZE TINY 55 END 56 END 57 END
从代码 2 中可以发现,从第 1 行到第 19 行配置的是从空间数据库中获取数据,从第 21 行到第 37 行配置的是从 Shape 文件获取数据,从第 39 行到 57 行是从 GIF 文件获取数据,其中部分属性介绍如下:
这里值得注意的是,如果读者选择了 KML 格式的矢量数据,需要通过 orginfo 命令行查看该文件的 Layer 名字,如下图中的 hz2 就是该 KML 文件的 Layer 名字。
从 KML 文件加载数据的 Mapfile 配置文件片段如下:
1 LAYER 2 NAME "chinalayer2" 3 STATUS DEFAULT 4 TYPE POINT 5 CONNECTIONTYPE OGR 6 CONNECTION "kml/fountains-hotel.kml" 7 DATA "fountains-hotel" 8 9 CLASS 10 ……
构建应用程序
准备好 GIS 服务器和所需的空间数据后,下面将展示如何构建基于 GIS 的 Flex 示例程序,该示例程序将用于展示不同数据源的空间数据,并提供基本的用户交互能力。接下来将逐步介绍构建 Flex 示例程序的过程。
首先,在 Flex Builder 中创建 Flex 工程,导入开源 GIS 渲染引擎 OpenScales 包,项目结构如下图所示:
其中,需要导入引用 4 个 swc 文件;在 src 目录下,最重要的是 osclient.mxml 文件,接下来会重点讲解,另外 ImageMarker.as 文件定义了在地图上显示用的图标类型,icons 文件加下放的是各式不同的图片
在 osclient.mxml 文件中主要完成了两件事情:第一,展示从不同数据源来的空间数据;第二,定义页面布局及一系列交互功能。
<os:Map id="fxmap" width="100%" height="100%" zoom="3" centerLonLat="105.02831248205241,35.17319551790936" cornerRadius="7"> <os:WMS id="file_data" url="http://localhost/cgi-bin/mapserv.exe?map=/ms4w/apps/testshapefile/first.map" layers="chinalayer2" isBaseLayer="true" transparent="true" projection="EPSG:4326"/> <os:WMS id="shape_file" url="http://localhost/cgi-bin/mapserv.exe?map=/ms4w/apps/testshapefile/first.map" layers="chinalayer" isBaseLayer="true" transparent="true" projection="EPSG:4326" /> <os:MousePosition x="10" y="{height-20}" displayProjection="EPSG:900913"/> <os:Spinner id="spinner" x="{this.width / 2}" y="{this.height / 2}"/> <os:LayerSwitcher/> <os:DragHandler/> <os:ClickHandler/> <os:WheelHandler/> <os:SelectFeaturesHandler active="true" enableClickSelection="false" enableBoxSelection="false" enableOverSelection="true" /> </os:Map>
上述这段代码所描述的就是如何获取空间数据,这里有两点需要强调一下:第一,每一个
同样,我们可以做如下配置,从而能够使用 OpenStreetMap 数据:
<os:Mapnik name="mapnik" isBaseLayer="true"proxy="http://openscales.org/proxy.php?url="/>
<os:ControlPanel x="10" y="10" width="140" title="Navigation"> <os:PanComponent map="{_map}"/> <mx:HBox width="100%" paddingLeft="5" paddingRight="5"> <os:ZoomComponent map="{_map}"/> <mx:Spacer width="100%"/> <os:ZoomBoxComponent map="{_map}" width="32" height="32"/> </mx:HBox> </os:ControlPanel> <os:ControlPanel title="Drawing Tools" x="150" y="10"> <os:FeatureDrawingComponent map="{_map}" /> </os:ControlPanel>
上述这段代码定义了两个组件,一个用于显示包含缩放比例尺的导航,另外一个用于显示包含一些 OpenScales 自定义的画图工具,在接下来的 GIS 应用展示中会看到这两个组件。
构建应用程序所需要的完整代码可以在下载资源中找到。
至此,通过介绍 GIS 体系结构以及相应的常用开源软件,并且通过实例应用程序具体介绍了如何搭建和使用 GIS 开发环境并构建应用程序,相信读者能够充分认识到这一套开源开发环境具有很强的易用性、相对完善的功能性、支持个性化应用场景的可扩展性,并且能够按照本文中介绍的步骤和方法,快速构建基于 GIS 的应用程序。