MapServer的使用流程

MapServer作为WebGIS解决方案。它是面向对象的,基本配置文件MapFile和MapScript模块的API组织都是基于对象的。MapServer通过支持OGC协会的若干标准,支持分布和互操作。不论是使用MapServer CGI模块或服务端脚本语言+MapScript,都可以实现服务端与客户浏览器的动态交互。配置MapFile文件的语法简单、易学;如果你有使用过桌面GIS软件(如ArcMap)做过专题地图的经验,更是如此。与商业软件相比,MapServer是开源的,你可以免费使用,还可以根据需要修改源代码。需要指出的是MapServer作为开源项目,在不断的发展中。本文介绍的内容是以Mapserver的4.4.2版本为基础的。

配置好MapFile文件后,就可以使用MapServer CGI模块或MapScript模块开发WebGIS程序。它们的区别:

1.利用MapServer CGI模块需要做的工作:准备MapFile需要的资源,配置MapFile,设计用户交互界面(即html文件,可以使用脚本语言,如JavaScript增强交互性)。无法进行服务器端设计,因为MapServer CGI本身就是定制好的服务器端程序。当然可以通过修改源代码来使Map Server CGI具有需要的特性。

2.利用MapScript模块就需要其他服务器端解决方案(指脚本语言),如PHP(以CGI模块安装在Web Server上)。MapScript模块作为PHP的扩展模块,放在PHP安装路径的extensions目录下。MapScript模块保留MapFile文件的层次对象结构,向PHP提供对象结构的API。那么,程序员在服务器端就可以使用PHP通过调用MapScript的API灵活的选择,修改MapFile文件;而不像MapServer CGI模块那样死板。同时结合PHP对众多数据库——非空间数据库,如Oracle,Sybase,MySQL等的支持,在WebGIS中整合空间数据和非空间数据变的容易。

MapScript支持的语言:PHP,Perl,Python,Java,Tcl,C#等。

Mapfile基本要求

正如你所看到的,Mapfile 的语法是相对简单的。一般来说,MapServer的关键字和值不区分大小写。然而在这本书中,关键字是始终是大写和值是小写。这种做法是为清楚起见,并且不是必需的。然而你应该注意这种情况下,可能是重要的,当你与空间数据集交互。例如,底层数据库中的属性名称可能是大小写敏感的,因此表达式包含属性的引用也将是区分大小写。

注意MapServer的4.4.1版出现不区分大小写shape文件的属性名称,尽管该语句与“MAPFILE参考 MapServer的4.4”的文件(http://mapserver.gis.umn.edu/doc44/mapfile-reference.html)相反。假设他们是大小写敏感的,是很好的做法。当然,属性值仍然是区分大小写。

包含嵌入的空格的字符串必须加引号。单引号或双引号都可以接受的,但他们必须成对使用,你不能举一个字符串,使用两种不同的引号字符。

MapServer地图文件格式分析

MapServer通过地图文件(mapfile)来配置要发布的地图。mapfile是MapServer的核心,它将各种地图要素组织成具有层次关系的对象系统。mapfile定义了构成地图的各要素以及它们之间的关系,并告诉MapServer从哪里装载数据并如何表现这些数据。在mapfile文件中,图层(Layer)是数据和样式的综合体,而其中的数据是空间数据和属性数据的联合。而样式是通过Class和Style对象来实现的。

地图文件使用 # 作为行注释符。地图文件都是以关键字MAP作为地图对象的开始,以关键字END作为地图对象定义的结束标志,整个地图文件就代表一个地图对象。在MAP和END关键之间是以关键字/值对的方式描述地图对象的属性。

Map对象有许多属性,例如地图图片格式(IMAGETYPE)、地图大小(SIZE)、地图数据的路径(SHAPEPATH)、地图的范围(EXTENT)以及地图使用的符号集(SYMBOLSET)和字体集(FONTSET)等。

每个地图文件至少要有一个图层对象。用户可以定义任意多个图层,但MapServer有一个默认的最多图层的限制,即100个图层,可以通过修改map.h文件来修改这个参数。

MapServer不仅支持矢量图层,同时也支持栅格形式的影像图层,如GeoTIFF、JPEG、PNG和GIF等。更值得关注的是,MapServer还支持WMS图层,即从其他WMS服务器获取地图图片来构成地图对象的一个图层。

每个图层也有一些常用的属性如图层名称(NAME)、数据集(DATA)、类型(TYPE)以及是否显示(STATUS)等。

每个图层有一个或多个Class对象,用来实现对图层中要素进行分类表现。通常图层对象中还有一个关键字CLASSITEM(属性),用来指定一个属性字段,以便可以根据该字段的值将图层分成若干个类别(Class)或主题(Theme)。如果在图层对象中指定了关键字CLASSITEM,则每Class对象中就需要一个关键字EXPRESSION来指示该类别代表的属性值。Class对象通常有一个Name属性。

每个Class对象都用一个或多个Style对象来定义该类要素的显示样式,如符号类型(SYMBOL)、填充的颜色(COLOR或OUTLINECOLOR)和符号的大小(SIZE)等。

Mapfile的结构

Mapfile 由层次结构的对象组成。在层次结构的顶部是地图对象(即 Mapfile的本身)。地图对象既包含简单的和结构化的项目。简单的项目由关键字值对组成,结构性项目包含其他项目,每一个都可以是简单的或结构性的。你已经看到了这两种类型的mapfile的结构的例子,例如,在第2章中讨论的first.map,包含以下几行:

NAME "First"
EXTENT -125.00 20.00 -65.00 50.00

这些行中的每一个都包含了一些简单的mapfile的对象。您还会注意到,这些关键字指定一个值,使地图作为一个整体才有意义。例如,关键字名称首先设置地图的名称。此关键字在地图的层次上使用来指定的字符串,用于标识所有在mapfile的生成输出文件MapServer的过程中生产的地图。注意,但是,关键字可以使用相同的名字在其他层面,它的功能取决于它的在哪里使用。同样地,在关键字的范围设置了整个地图的范围,所以它也必须被定义在地图层次级别。如NAME,它也可用于在较低的水平。

请注意,如果你是新MapServer和使用者,使用相同的关键字(如姓名,模板或颜色)在mapfile中的不同级别中可能会造成混淆。当你熟悉了mapfile的的概念,这将不存在问题,事实上,你会很感激,开发商选择在不同的层面对相似的概念定义相同的关键字。

first.map包含以下几行

WEB
   TEMPLATE '/var/www/htdocs/first.html'
   IMAGEPATH '/var/www/htdocs/tmp'
   IMAGEURL '/tmp/'
END

这是一个结构化的对象的一个例子。Web对象决定了MapServer将使用哪个HTML模板,以及模板的位置。Web对象一般用于确定MapServer怎么响应Web请求,并且可以包含比这里显示的更多的关键字。由于Web对象定义用来显示整个地图的事情,它指定地图是有道理的。不过,同样的关键字模板可用于在较低的水平,它的功能是非常不同的。有许多MapServer的对象可以定义地图,但现在我就为大家介绍一个层对象。

利用MapServer CGI模块开发WebGIS

CGI是一组定义了Web服务器与在同一台机器上的其他软件相互通信的规则。遵循CGI通信规则的其他软件叫CGI程序或CGI脚本。Web服务器可利用CGI程序实现动态交互功能(Server-side)。通常CGI程序是运行在服务器端的小程序,被Web服务器调用,处理从Web服务器获得的数据(如对表单数据处理,查询数据库等),将处理结果返回给Web服务器:

Web服务器——CGI程序——其他软件(如数据库)。

CGI程序可以使用任何语言编写,只要遵循CGI通信规则。编译语言:C、C++等;脚本语言:Perl, Python, Bourne shell,Java等[7]。

MapServer CGI模块是用C语言编写的CGI程序,非常小。MapServer CGI模块的核心mapserv.exe不过36KB。

当浏览器通过URL告知Web Server调用MapServer CGI模块时,Web Server就为CGI模块创建一个进程;CGI模块运行并加载URL指定的MapFile文件,读取MapFile文件中的TEMPLATE文件(HTML文件),并将TEMPLATE文件中CGI变量的替换变量(template substitutions)替换成具体的值;处理完TEMPLATE文件后,CGI模块将TEMPLATE文件处理结果(HTML文件)返回给Web Server,Web Server在将HTML文件输出到用户浏览器上。这时TEMPLATE文件(HTML文件)就作为用户的交互界面。

使用MapServer CGI程序设计WebGIS的基本步骤:

1.配置MapFile 一般在Web Object的TEMPLATE属性中指明使用的用户交互界面。用户也可以通过URL指明使用的用户交互界面。

2.设计初始化界面 考虑到访问CGI程序(mapserv.exe)URL很长,而且对于普通用户并不知道访问CGI程序(mapserv.exe)的URL格式;所以在初始交互界面中嵌入指向CGI程序(mapserv.exe)的链接(URL)。

3.设计用户交互及交互界面 这里需要引出MapServer CGI模块的关键概念:CGI 变量和Templates。MapServer CGI 变量可以看作是CGI模块mapserv.exe的接口。在URL或HTML的表单中调用CGI变量就可以完成大多数动态交互,如图层选择,放大缩小等。

Templates是HTML文件或URL。 在Templates中含有CGI变量和它的替换变量,这里替换变量(template substitutions)与CGI变量相一一对应。设计用户交互及交互界面,即在URL或HTML文件中使用CGI变量和替换变量。那么,既然替换变量(template substitutions)与CGI变量相一一对应,又为何要引入替换变量(template substitutions)的概念了?确实在概念上有点多取一举。不过,使用替换变量可以用来指示CGI变量值为空的情况。

在附录2中将提供利用MapServer CGI模块开发WebGIS的例子。

利用MapScript模块开发WebGIS

使用CGI模块编程就是利用CGI变量和它的替换变量,而CGI模块是编译好的程序(mapserv.exe);使用CGI模块难以实现较为复杂的动态交互。利用其他服务端脚本语言和MapScript可以更容易实现复杂的WebGIS功能。

这里将以流行的服务器端脚本语言PHP为例介绍MapScript模块的使用方法。PHP以CGI程序安装在Web Server中,把MapScript模块放置在PHP安装路径的extensions下,配置php.int文件支持使用MapScript模块,就完成PHP/Mapscript安装。在 *.php 文件或 *.phtml 文件中使用函数:dl(“MapScript模块名称”)就可以加载MapScript模块了。由MapScript模块提供的API是基于对象的,它将MapFile中对象组织成对象接口。在 *.php 文件或 *.phtml 文件中可以调用对象的属性和方法。

在附录3中将提供由作者使用PHP/MapScript编写的程序源代码。

MapServer数据处理流程

客户端将参数及要求的cgi程序传送给MapServer。MapServer接收到客户端传送的参数后,根据参数中指定的mapfile路径读取mapfile文件。根据mapfile中指定的data路径读取相关数据。将读入的数据进行文字资料转图工作。该项工作是呼叫FreeType Font Engine配合GD Graphics Library进行的。图形制作完成后,保存至客户端参数中指定的目录。MapServer 根据mapfile中定义的信息,读取指定的模板(template file),进行html及画面显示的配置与相关资料,图形(如:比例尺寸,样本图,参考文字)的制做及嵌入工作,将动态生成的空间资讯图嵌入模板以生成能够供客户端使用的文件。完成后返回客户端。

MapFile文件

Mapfile的一些工具,包括VIM 的高亮工具,Sublime 高亮工具。

MapFile文件将各种地图要素组织成具有层次关系的对象系统。数据来源,使用的数据格式, 用户交互和对OGC协议的支持也在MapFile中定义。

  • MapObject
  • Querymap
  • Symbol
  • Projection
  • WebObject
  • Reference Map
  • Outputformat
  • Scalebar
  • Lengend
  • Layer Object
  • Label Object
  • Label Object
  • Feature
  • Projection
  • Class Object
  • Join Object
  • Label Object
  • Style Object
  • Grid Object

MapFile中的对象及其层次关系;注意为绘图方便有些对象省略Object

MapFile中的对象及其层次关系;注意为绘图方便有些对象省略Object

MapFile的语法很简单。 MapFile的关键字包括对象名(图2中的所有对象)、对象属性(keyword), 对象结束标记“END”。对象名和对象结束标记“END”大小写不敏感;属性名大小写敏感,配置ESRI的shapfile文件要使用大写,PostGIS的却总是小写。在MapFile文件中,符号 对单行注释。MapFile文件以 .map 为扩展名,可以使用各种文字编辑器编写。以下是MapFile的一个例子:

配置一个完整的MapFile文件需要:GIS数据源,字体文件,符号文件。GIS数据源可以分布在不同的计算机上;字体文件用来定义输出地图中使用的字体类型。地图中使用的点,线,面符号可以在MapFile文件Symbol对象中定义;不过为了实现符号的重用——无须在不同的MapFile文件中定义相同的符号,通常在MapFile外部定义独立的符号文件。

MapFile文件中大部分对象或与地图要素相对应, 或是GIS中应用较普遍的概念;如Lengend,Scalebar,Layer等。 这些对象的作用是较为明显,易懂的。在附录1中将对MapFile文件中的对象和属性的意义做详尽的解释。在这里解释四个特别对象的意义: Web Object,Outputformat Object,Query Object,Reference Map Object。

  • Web Object定义如何处理web接口。如:属性IMAGEPATH定义存储临时文件和图像的路径,TEMPLATE定义使用的交互界面文件[5]。
  • Outputformate Object定义输出图像的格式。MapServer将GIS数据格式文件(如shapefile)转换成MIME (Multipurpose Internet Mail Extensions)协议支持的图像格式,如gif,png,jpeg等[5]。
  • QueryMap Object定义了查询结果的生成机制。如:属性STYLE(不是对象)设置选中的特征如何显示[5]。
  • Reference Map Object定义参照地图如何创立。MapServer支持三种参照地图类型。参照地图最普遍的用法是做为map的观察窗口。

可以利用参照地图对查询结果进行观察。当点查询发生时,会在输出Reference Map中产生一个点符号,以指示被查询的位置。区域查询就在Reference Map中产生一个方框,以指示查询区域。特征查询就在Reference Map显示查询的特征。总之,Reference Map可以视为查询的观察窗口[5]

在规划好WebGIS网站之后,配置MapFile文件步骤:

  1. 准备MapFile文件需要的资源,包括GIS数据,字体文件,符号文件。
  2. 按照WebGIS网站的需求,遵循MapFile的语法,使用文本编辑软件或MapLab等专门的MapFile编写软件编写MapFile。
  3. 使用调试软件(如MapLab)测试、查看MapFile配置是否正确、合适。