举例来说¶
- 作者
温可维尔萨洛维奇
- 接触
在VIKOO.CL
- 最后更新
2005-12-12
目录
注解
从7.4.0版本开始,PHP 7可以通过MapServer的 SWIG API . 我们鼓励MapServer用户使用SWIG API通过MapScript连接到PHP 7。本文档仅涵盖对遗留MapScript的支持;有关php7mapscript的最新示例,请参见 MS4W wiki 因为用户已经在那里贡献了PHP 7 mapscript脚本。
介绍¶
本文件旨在逐步解释 PHP映射脚本API 每一个都有实际的例子。它被假定为 MAP 和mapserver,并熟悉 PHP (scripting) 和 HTML (markup) 语言。此文档最初是为MapServer v4.0创建的,但示例仍然适用于较新的版本。
我们开始吧…。
你好,好心的读者。我是图特,谢谢你下载我。对不起,我只是一本技术手册,所以我不能回答任何问题。维修人员,一个英俊,非常好和懒惰的家伙,根据我从屏幕的另一边看到的,也许可以回答你的问题。我现在在这里告诉您关于mapscript在其php化身中的情况。在我目前的年龄,我对初学者比高级用户更有用,尽管我希望有一天我会足够老,能够对高级mapscript程序员有用。
希望我活得够久…叹息。
但我的个人问题已经够多了,让我自己开始吧。我的职责是让您熟悉mapscript,尤其是php mapscript。当我结束时,您应该了解mapscript是什么,并且能够编写应用程序来显示和导航,即通过Web浏览器缩放和平移形状文件。
以下是您在陪同我完成余下的旅程之前必须肯定回答的问题(我为我的维护者缺乏文学品味而道歉)。
你有没有在某个地方跑步…¶
一个能够将PHP作为CGI运行的Web服务器(Apache会这样做)?
PHP语言配置为CGI,4.1.2版或更高版本?我建议从4.3开始。
php mapscript,4.0版还是更高版本? php mapscript安装
你能。。。¶
编码php或愿意 learn how to 是吗?
写作和理解 HTML 文件?(请注意,javascript是一个加号)
MapScript概述¶
好吧,现在我终于到了我喜欢的地方。本概述旨在清除初学者在第一次面对mapscript时遇到的一些常见误解,并对mapscript的内部结构进行概述。现在,请看下面的图表(我再次为维护人员缺乏图形设计的品味而道歉)。

一切都始于网络上的一切。浏览器通过HTTP请求特定的URL。请求到达Web服务器,服务器依次传递文件或执行程序,然后将其输出返回浏览器。是的,我知道你知道,但是我被告知要尽可能完整,我会尽力的。
在mapscript的情况下,服务器执行一个特定的脚本,其中包含标准语言功能,也就是说,在没有mapscript的情况下,在该语言中具有的相同功能,加上对几乎所有mapserver c api的访问,mapserver api支持的完整性级别随您选择的语言而有所不同,但我认为它我的职责是告诉你几乎所有可用的mapscript风格都是可用的。这个API现在通过mapscript模块在脚本语言中公开,它允许您对空间数据执行许多类似于地理信息系统的操作,包括对形状文件的读写访问、数据的重投影以及许多其他操作。有关API的更多信息,请单击上面的链接。对于其他口味,您可以查看自己的文档,您会发现没有太大的区别。
运行mapscript应用程序不需要mapserver的cgi版本,就像运行cgi不需要特定的mapscript模块一样。CGI版本有许多现成的特性,mapscript只是一个API,所以对于mapscript,您必须从头开始,或者使用一些可用的示例。把CGI想象成一个直接用C语言编写的mapscript应用程序,可以直接访问mapserver c api。有时候开箱即用的功能有一些限制,这些限制可以被mapscript超越,但不能嵌入到CGI中。换句话说,CGI是不可脚本化的,但是您可以用mapscript来编程所有的CGI以及更多的CGI。这似乎是一个奇怪的事情要澄清,但是一个常见的误解,只要检查一下 list archives 如果你不愿意相信我。
与MAPServer本身一样,MAPScript只能使用 Mapfile 进行配置,但与CGI不同,它还包括动态创建地图或修改现有地图的可能性,以及将此信息与其他非地理信息系统数据源(如用户输入、非空间和空间数据)混合(这是MAPScript具有灵活性的关键)。数据库、文本文件等,您可以使用语言提供的每个模块。这种方法的威力是巨大的,最具限制性的是你的想象力。一如既往,灵活性伴随着价格、性能。通常使用脚本语言而不是C语言要慢一些,但现在这不应该是一个大问题。您仍然可以直接在C语言中编程(虽然您可能希望检查 mapserver-dev list )如果你愿意的话。
mapscript可以处理的输入和输出格式与构建mapserver/mapscript时配置的格式完全相同。但要记住的最重要的一点是,基本上,您将地理数据和相关的用户输入(例如单击地图图像)输入到mapscript,从而获得一个或多个文件,通常是标准图像文件,如png或jpeg。因此,您可以在任何服务器端脚本化Web应用程序、DHTML、Java小程序、CSS、HTML模板、会话中应用您所看到的任何东西。
我们的第一个申请¶
在第一个示例中,我将告诉您如何使用 Mapfile 在网页上显示形状文件。
Mapfile¶
这是 Mapfile :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | NAME "Europe in purple"
SIZE 400 400
STATUS ON
SYMBOLSET "/var/www/html/maps/symbols/symbols.sym"
EXTENT -5696501 1923039 5696501 11022882
UNITS METERS
SHAPEPATH "/var/www/html/maps/data"
WEB
IMAGEPATH "/var/www/html/maps/tmp/"
IMAGEURL "/tmp/"
END
LAYER
NAME "Europe"
TYPE POLYGON
STATUS ON
DATA "europe"
CLASS
STYLE
COLOR 110 50 100
OUTLINECOLOR 200 200 200
SYMBOL 0
END
END
END
END
|
这里我展示了一个单层的地图,其中europe.shp、europe.shx和europe.dbf文件必须位于名为data的子目录中。符号位于符号子目录中。所有这些位置都是相对于 Mapfile 所在的位置的,但我想这比对不起更安全。Web部分用于定义保存图像的位置和可用的URL。
用mapscript显示地图¶
要显示地图,将使用以下mapscript对象和方法:
MAPOBJ对象
ImageObj对象
MAPOBJ方法:
构造器方法:mapobj ms_new mapobj(string map_file_name[,string new_map_path])
绘制方法:imageobj draw()。
ImageObj方法:
saveWebImage方法:string saveWebImage()。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?php
dl('php_mapscript.so');
$map_path="/var/www/html/ms/map_files/";
$map = ms_newMapObj($map_path."europe.map");
$image=$map->draw();
$image_url=$image->saveWebImage();
?>
<HTML>
<HEAD>
<TITLE>Example 1: Displaying a map</TITLE>
</HEAD>
<BODY>
<IMG SRC=<?php echo $image_url; ?> >
</BODY>
</HTML>
|
我将通过本文档其余部分呈现的代码将遵循以下规则:
每个非空行都有编号
此代码将呈现与shapefile europe对应的图像,并将其显示在HTML页上。
代码解释¶
在第2行中,它加载了mapscript扩展名(如果您的php.ini文件配置为自动加载,则可能不需要它)。
第3行声明一个保存 Mapfile 绝对路径的变量。
第4行使用构造函数创建mapobj对象的实例。如您所见,构造函数接收 Mapfile 的位置作为其唯一必需的参数, Mapfile 接收到europe.map名称。
然后调用映射对象的draw方法来渲染由 Mapfile (第5行)定义的图像。结果(imageobj)保存在$image变量中。
第6行调用savewebimage方法来生成图像文件,它返回一个字符串,该字符串表示mapfile中定义的URL(在本例中为/tmp/filename.png)。
其余的行是纯HTML,第13行除外,它定义图像的源URL将是存储在$image_url中的值。
您应该在系统上测试应用程序,以检查它是否真正工作,并在继续进行更复杂的示例之前解决特定配置中可能出现的问题。
缩放与平移¶
现在我将告诉您如何向代码添加缩放和平移功能。
下面是新方法和调用的对象的列表。
新对象:
彭波托基
雷克托布杰
调用的新方法和成员:
映射对象的zoompoint方法:void zoompoint(int nzoomfactor、pointobj opixelpos、int nimagewidth、int nimageheight、rectobj ogeorefext)。
map对象的setextent方法:$map->setextent(double minx,double miny,double maxx,double maxy);。
地图对象的范围、宽度和高度成员。
rectobj和pointobj的构造函数:$point=ms_newpointobj();$rect=ms_newrectobj();
点对象的setxy方法:$point->setxy(double x_coord,double y_coord);
矩形对象的setextent方法:$rect->setextent(double minx,double miny,double maxx,double maxy);
.map文件与上一个示例中显示的文件保持相同。
php/mapscript代码¶
在这里我介绍了新的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | <?php
dl('php_mapscript.so');
// Default values and configuration
$val_zsize=3;
$check_pan="CHECKED";
$map_path="/var/www/html/ms/map_files/";
$map_file="europe.map";
$map = ms_newMapObj($map_path.$map_file);
if ( isset($_POST["mapa_x"]) && isset($_POST["mapa_y"])
&& !isset($_POST["full"]) ) {
$extent_to_set = explode(" ",$_POST["extent"]);
$map->setextent($extent_to_set[0],$extent_to_set[1],
$extent_to_set[2],$extent_to_set[3]);
$my_point = ms_newpointObj();
$my_point->setXY($_POST["mapa_x"],$_POST["mapa_y"]);
$my_extent = ms_newrectObj();
$my_extent->setextent($extent_to_set[0],$extent_to_set[1],
$extent_to_set[2],$extent_to_set[3]);
$zoom_factor = $_POST["zoom"]*$_POST["zsize"];
if ($zoom_factor == 0) {
$zoom_factor = 1;
$check_pan = "CHECKED";
$check_zout = "";
$check_zin = "";
} else if ($zoom_factor < 0) {
$check_pan = "";
$check_zout = "CHECKED";
$check_zin = "";
} else {
$check_pan = "";
$check_zout = "";
$check_zin = "CHECKED";
}
$val_zsize = abs($zoom_factor);
$map->zoompoint($zoom_factor,$my_point,$map->width,$map->height,
$my_extent);
}
$image=$map->draw();
$image_url=$image->saveWebImage();
$extent_to_html = $map->extent->minx." ".$map->extent->miny." "
.$map->extent->maxx." ".$map->extent->maxy;
?>
<HTML>
<HEAD>
<TITLE>Map 2</TITLE>
</HEAD>
<BODY>
<CENTER>
<FORM METHOD=POST ACTION=<?php echo $HTTP_SERVER_VARS['PHP_SELF']?>>
<TABLE>
<TR>
<TD>
<INPUT TYPE=IMAGE NAME="mapa" SRC="<?php echo $image_url?>">
</TD>
</TR>
<TR>
<TD>
Pan
</TD>
<TD>
<INPUT TYPE=RADIO NAME="zoom" VALUE=0 <?php echo $check_pan?>>
</TD>
</TR>
<TR>
<TD>
Zoom In
</TD>
<TD>
<INPUT TYPE=RADIO NAME="zoom" VALUE=1 <?php echo $check_zin?>>
</TD>
</TR>
<TR>
<TD>
Zoom Out
</TD>
<TD>
<INPUT TYPE=RADIO NAME="zoom" VALUE=-1 <?php echo $check_zout?>>
</TD>
</TR>
<TR>
<TD>
Zoom Size
</TD>
<TD>
<INPUT TYPE=TEXT NAME="zsize" VALUE="<?php echo $val_zsize?>"
SIZE=2>
</TD>
</TR>
<TR>
<TD>
Full Extent
</TD>
<TD>
<INPUT TYPE=SUBMIT NAME="full" VALUE="Go"
SIZE=2>
</TD>
</TABLE>
<INPUT TYPE=HIDDEN NAME="extent" VALUE="<?php echo $extent_to_html?>">
</FORM>
</CENTER>
</BODY>
</HMTL>
|
此代码将缩小、放大、平移和完全还原上一示例中显示的图像。
看起来比实际情况复杂得多,很多行是HTML代码,剩下的大部分PHP代码只是处理表单等。
你应该先试试看它是怎么工作的。通过复制和粘贴代码,在您自己的服务器中进行尝试。
现在是时候让你玩一下了,看看你浏览器中的源代码,看看它是如何变化的。
完成?,现在让我们从HTML部分开始解释。
代码解释-HTML¶
第49行声明一个表单,第53行声明mapscript生成的图像是该表单的一部分,因此当您单击它时,单击的X和Y坐标(以像素为单位)将与其他数据一起发送,以供PHP代码处理。
如果您熟悉HTML和PHP,那么除了第98行之外,其余的HTML代码应该很容易理解,这将在适当的时候得到解释。
代码解释-php¶
现在看看PHP代码,它几乎是示例1中使用的相同代码,加上第9行到第37行。这些线是干什么的?
第9行检查表单中的相关变量是否已设置。mapa_x'和'mapa_y'表示单击图像的x和y坐标,“full”表示单击“full extent”按钮。
第一次显示页面时,if语句之间的代码没有执行,但其余的代码执行。第40行和第41行将“$extent”设置为“html”变量,并将 Mapfile 中定义的范围值用空格分隔;该值将放入第98行的html变量“extent”。
现在看第11行和第12行。我们在if语句中,这意味着表单至少已经提交了一次。我们获取存储在代码前一次执行中的范围(“extent”html变量),并将映射的范围设置为最后一个范围。这允许缩放或平移上一个范围,而不是 Mapfile 中设置的范围。
从最后一段中,您可以推断出所有默认值都设置在 Mapfile 中,并且必须以某种方式存储通过mapscript更改并希望保留在代码中的任何内容。在这种情况下,它是通过表单中的隐藏变量完成的。对于更高级的应用程序,可以使用会话变量或数据库。
现在,您应该能够看到“完全扩展”按钮的工作原理。如果您检查第10行,它会说如果您没有按下按钮,跳过if语句中的代码,那么范围将重置为 Mapfile 的值。您还应该看到它不一定是完整的范围(如果 Mapfile 中的范围不是完整的范围)。
第14行和第15行声明一个新的点对象,并用用户单击的值初始化它。您不应该忘记这些值是以像素为单位的,而不是以地理坐标为单位的。
第16行到第18行创建一个新的矩形对象,并使用上一个图像的范围对其进行设置,就像在第12行中一样。事实上,这也会起作用:$my_extent=$map->extent;。
要进行所有的缩放和平移,第35行调用了zoompoint函数,但首先必须准备好它接收到的参数。您可以确定用户单击的点,以及图像的范围(分别是my-point和$my-extent),但现在您必须确定缩放系数。这就是19到33行所做的。如果您想知道为什么单选按钮的值为0、-1和1,用于平移、放大和缩小,那么现在您将知道原因了。
缩放系数为1表示缩放点操作为平移,负值表示缩小,正值表示放大。因此,通过将接收到的单选按钮值(HTML变量“zoom”)乘以用户输入的缩放大小,就可以计算出缩放系数。如果该值为0,则表示用户选择了平移操作,因此“$zoom_factor”设置为1,否则乘法的结果是需要接收的缩放因子zoompoint。其他行用于保留用户下次单击的按钮。第34行试图保留用户输入的缩放大小值(它不会一直这样做,何时以及为什么该行失败?这是你要知道的)。
最后,第34行使用获得的缩放因子调用zoom point方法,即根据像素坐标构建的点(我坚持这个问题,因为zoom point几乎是接收像素坐标的唯一方法,对于其他方法,您必须自己将像素转换为地理参考坐标),i的高度和宽度法师,和范围。
调用zoompoint后,图像的范围将根据所执行的操作(或者,更好地说,缩放系数)进行相应的更改。然后绘制图像并保存当前范围(缩放后),以便在下一次迭代中使用。
结论¶
好吧,我该去给电池充电了。所以我会用最后的能量来分享最后的话。我在这里介绍的例子非常基本,但是你现在应该能够设计出改进它们的方法,并使之适合你的需要。请记住,您可以从通常可以通过PHP读取的任何源代码预处理、存储、读取、写入数据,以及MapServer可以处理的所有GIS数据源。您甚至可以使用PHP处理一些地理信息系统数据,前提是需要(SQL源就是一个很好的例子)。您还可以使用混合方法,其中一些脚本准备数据,然后通过到MapServer的CGI接口显示这些数据,或者基于GPS的输入动态创建数据,等等。这种可能性太多,无法完全枚举。正如我已经说过的,你的想象力是极限。本文档的下一个版本将包括包含多个层、具有不同数据源(不只是形状文件)和创建动态层和类的示例。如果你有更好的主意,或者想先在这里看看其他的东西,请给我的维修人员写张便条。
同时,如果您需要更大的示例,您可以参考原始的“GMAP演示”(您可以下载源代码 here ) MapTools site (对于较旧的maplab,是基于phpmapscript构建的变色龙应用程序)。再见,谢谢你读到这里。