Commit 035d3cd4c2b6f64e01797b100d598958231023bd
1 parent
0bd5f4eb
Exists in
master
and in
7 other branches
Adicionada a biblioteca kmlmapserver em pacotes
Showing
9 changed files
with
1741 additions
and
0 deletions
Show diff stats
... | ... | @@ -0,0 +1,165 @@ |
1 | + GNU LESSER GENERAL PUBLIC LICENSE | |
2 | + Version 3, 29 June 2007 | |
3 | + | |
4 | + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> | |
5 | + Everyone is permitted to copy and distribute verbatim copies | |
6 | + of this license document, but changing it is not allowed. | |
7 | + | |
8 | + | |
9 | + This version of the GNU Lesser General Public License incorporates | |
10 | +the terms and conditions of version 3 of the GNU General Public | |
11 | +License, supplemented by the additional permissions listed below. | |
12 | + | |
13 | + 0. Additional Definitions. | |
14 | + | |
15 | + As used herein, "this License" refers to version 3 of the GNU Lesser | |
16 | +General Public License, and the "GNU GPL" refers to version 3 of the GNU | |
17 | +General Public License. | |
18 | + | |
19 | + "The Library" refers to a covered work governed by this License, | |
20 | +other than an Application or a Combined Work as defined below. | |
21 | + | |
22 | + An "Application" is any work that makes use of an interface provided | |
23 | +by the Library, but which is not otherwise based on the Library. | |
24 | +Defining a subclass of a class defined by the Library is deemed a mode | |
25 | +of using an interface provided by the Library. | |
26 | + | |
27 | + A "Combined Work" is a work produced by combining or linking an | |
28 | +Application with the Library. The particular version of the Library | |
29 | +with which the Combined Work was made is also called the "Linked | |
30 | +Version". | |
31 | + | |
32 | + The "Minimal Corresponding Source" for a Combined Work means the | |
33 | +Corresponding Source for the Combined Work, excluding any source code | |
34 | +for portions of the Combined Work that, considered in isolation, are | |
35 | +based on the Application, and not on the Linked Version. | |
36 | + | |
37 | + The "Corresponding Application Code" for a Combined Work means the | |
38 | +object code and/or source code for the Application, including any data | |
39 | +and utility programs needed for reproducing the Combined Work from the | |
40 | +Application, but excluding the System Libraries of the Combined Work. | |
41 | + | |
42 | + 1. Exception to Section 3 of the GNU GPL. | |
43 | + | |
44 | + You may convey a covered work under sections 3 and 4 of this License | |
45 | +without being bound by section 3 of the GNU GPL. | |
46 | + | |
47 | + 2. Conveying Modified Versions. | |
48 | + | |
49 | + If you modify a copy of the Library, and, in your modifications, a | |
50 | +facility refers to a function or data to be supplied by an Application | |
51 | +that uses the facility (other than as an argument passed when the | |
52 | +facility is invoked), then you may convey a copy of the modified | |
53 | +version: | |
54 | + | |
55 | + a) under this License, provided that you make a good faith effort to | |
56 | + ensure that, in the event an Application does not supply the | |
57 | + function or data, the facility still operates, and performs | |
58 | + whatever part of its purpose remains meaningful, or | |
59 | + | |
60 | + b) under the GNU GPL, with none of the additional permissions of | |
61 | + this License applicable to that copy. | |
62 | + | |
63 | + 3. Object Code Incorporating Material from Library Header Files. | |
64 | + | |
65 | + The object code form of an Application may incorporate material from | |
66 | +a header file that is part of the Library. You may convey such object | |
67 | +code under terms of your choice, provided that, if the incorporated | |
68 | +material is not limited to numerical parameters, data structure | |
69 | +layouts and accessors, or small macros, inline functions and templates | |
70 | +(ten or fewer lines in length), you do both of the following: | |
71 | + | |
72 | + a) Give prominent notice with each copy of the object code that the | |
73 | + Library is used in it and that the Library and its use are | |
74 | + covered by this License. | |
75 | + | |
76 | + b) Accompany the object code with a copy of the GNU GPL and this license | |
77 | + document. | |
78 | + | |
79 | + 4. Combined Works. | |
80 | + | |
81 | + You may convey a Combined Work under terms of your choice that, | |
82 | +taken together, effectively do not restrict modification of the | |
83 | +portions of the Library contained in the Combined Work and reverse | |
84 | +engineering for debugging such modifications, if you also do each of | |
85 | +the following: | |
86 | + | |
87 | + a) Give prominent notice with each copy of the Combined Work that | |
88 | + the Library is used in it and that the Library and its use are | |
89 | + covered by this License. | |
90 | + | |
91 | + b) Accompany the Combined Work with a copy of the GNU GPL and this license | |
92 | + document. | |
93 | + | |
94 | + c) For a Combined Work that displays copyright notices during | |
95 | + execution, include the copyright notice for the Library among | |
96 | + these notices, as well as a reference directing the user to the | |
97 | + copies of the GNU GPL and this license document. | |
98 | + | |
99 | + d) Do one of the following: | |
100 | + | |
101 | + 0) Convey the Minimal Corresponding Source under the terms of this | |
102 | + License, and the Corresponding Application Code in a form | |
103 | + suitable for, and under terms that permit, the user to | |
104 | + recombine or relink the Application with a modified version of | |
105 | + the Linked Version to produce a modified Combined Work, in the | |
106 | + manner specified by section 6 of the GNU GPL for conveying | |
107 | + Corresponding Source. | |
108 | + | |
109 | + 1) Use a suitable shared library mechanism for linking with the | |
110 | + Library. A suitable mechanism is one that (a) uses at run time | |
111 | + a copy of the Library already present on the user's computer | |
112 | + system, and (b) will operate properly with a modified version | |
113 | + of the Library that is interface-compatible with the Linked | |
114 | + Version. | |
115 | + | |
116 | + e) Provide Installation Information, but only if you would otherwise | |
117 | + be required to provide such information under section 6 of the | |
118 | + GNU GPL, and only to the extent that such information is | |
119 | + necessary to install and execute a modified version of the | |
120 | + Combined Work produced by recombining or relinking the | |
121 | + Application with a modified version of the Linked Version. (If | |
122 | + you use option 4d0, the Installation Information must accompany | |
123 | + the Minimal Corresponding Source and Corresponding Application | |
124 | + Code. If you use option 4d1, you must provide the Installation | |
125 | + Information in the manner specified by section 6 of the GNU GPL | |
126 | + for conveying Corresponding Source.) | |
127 | + | |
128 | + 5. Combined Libraries. | |
129 | + | |
130 | + You may place library facilities that are a work based on the | |
131 | +Library side by side in a single library together with other library | |
132 | +facilities that are not Applications and are not covered by this | |
133 | +License, and convey such a combined library under terms of your | |
134 | +choice, if you do both of the following: | |
135 | + | |
136 | + a) Accompany the combined library with a copy of the same work based | |
137 | + on the Library, uncombined with any other library facilities, | |
138 | + conveyed under the terms of this License. | |
139 | + | |
140 | + b) Give prominent notice with the combined library that part of it | |
141 | + is a work based on the Library, and explaining where to find the | |
142 | + accompanying uncombined form of the same work. | |
143 | + | |
144 | + 6. Revised Versions of the GNU Lesser General Public License. | |
145 | + | |
146 | + The Free Software Foundation may publish revised and/or new versions | |
147 | +of the GNU Lesser General Public License from time to time. Such new | |
148 | +versions will be similar in spirit to the present version, but may | |
149 | +differ in detail to address new problems or concerns. | |
150 | + | |
151 | + Each version is given a distinguishing version number. If the | |
152 | +Library as you received it specifies that a certain numbered version | |
153 | +of the GNU Lesser General Public License "or any later version" | |
154 | +applies to it, you have the option of following the terms and | |
155 | +conditions either of that published version or of any later version | |
156 | +published by the Free Software Foundation. If the Library as you | |
157 | +received it does not specify a version number of the GNU Lesser | |
158 | +General Public License, you may choose any version of the GNU Lesser | |
159 | +General Public License ever published by the Free Software Foundation. | |
160 | + | |
161 | + If the Library as you received it specifies that a proxy can decide | |
162 | +whether future versions of the GNU Lesser General Public License shall | |
163 | +apply, that proxy's public statement of acceptance of any version is | |
164 | +permanent authorization for you to choose that version for the | |
165 | +Library. | ... | ... |
... | ... | @@ -0,0 +1,92 @@ |
1 | +KML mapserver wrapper | |
2 | +------------------------------------- | |
3 | + | |
4 | +* What is this thing? | |
5 | + this is a wrapper around UNM Mapserver, to serve KML data in a WFS-like manner | |
6 | + | |
7 | +* Requirements | |
8 | + PHP5 with simplexml | |
9 | + | |
10 | +* Configuration | |
11 | + Configuration is done through CGI-style calls and through some optional metadata in the mapfile | |
12 | + | |
13 | + METADATA: | |
14 | + RESULT_FIELDS # from which field take the name for the feature | |
15 | + # defaults to the first field | |
16 | + | |
17 | + DESCRIPTION_TEMPLATE # if present, this is used for placemark features | |
18 | + # tooltip. Parameters surrounded by "%" char are substituted | |
19 | + # with real values from the corresponding field for the feature | |
20 | + | |
21 | + DESCRIPTION # All those metadata are searched (in this order) to get a layer | |
22 | + OWS_TITLE # description | |
23 | + WFS_TITLE | |
24 | + WMS_TITLE | |
25 | + | |
26 | + KML_CACHE # number of second the cache will lasts | |
27 | + # if empty or not exists, the cache will be disabled for that layer | |
28 | + | |
29 | + KML_SKIP # if equals to "true", kml output is disabled for this layer, | |
30 | + # default is false | |
31 | + | |
32 | + KML_ADD_POINT # If not empty, add a point with balloon to start and end | |
33 | + # line geometries. Value is the icon url. | |
34 | + | |
35 | + | |
36 | + CGI-PARAMETERS: | |
37 | + * - request = string - optional - request type (OGC WFS like) | |
38 | + * - map = string - required - path to mapfile | |
39 | + * - typename = string - optional - (can be a csv list) - layer name(s), if empty, all layers are returned | |
40 | + * - filter = string - optional - filter encoding (single layer requests only) | |
41 | + * - bbox = string - optional - standard bbox specification (Not yet implemented) | |
42 | + * - encoding = string - optional - default to ISO-8859-1 | |
43 | + | |
44 | +* Filters | |
45 | + Only PropertyIsEqualTo and PropertyIsLike are supported ATM. | |
46 | + | |
47 | +* Encoding | |
48 | + kml is UTF-8, mapfile and attributes could have other encodings, you can set encoding via request parameter, otherwise ISO-8859-1 is used as default. | |
49 | + | |
50 | +* Raster support | |
51 | + Raster layer are supported as standard WMS network links, it is necessary to add EPSG:4326 to WMS_SRS metadata on all mapfile layers. | |
52 | + Mapfile must be correctly configured as WMS server (i.e. all required metadata must be set). | |
53 | + | |
54 | +* KMZ compressed output | |
55 | + | |
56 | +* Styles and classes | |
57 | + There is limited support for classes and style: | |
58 | + * only one style for each class is parsed, if you have multiple styles in one class, the values of the last one are used | |
59 | + * only color, outlinecolor, backgroundcolor, symbol, size and width are parsed | |
60 | + | |
61 | +* Cache | |
62 | + A simple caching for single layer requests is available. | |
63 | + If you want to use the cache, set KML_CACHE layer metadata to the number of seconds the cache should last. | |
64 | + A web server writeable "cache" directory must exists at the same level of the main script | |
65 | + | |
66 | +* Know issues | |
67 | + * Filled polygons fail to wrap on the mountains (this seems a GE bug), a define('TREAT_POLY_AS_LINE', true) control this behaviour | |
68 | + | |
69 | +EXAMPLE CALLS | |
70 | +------------------------------------ | |
71 | +Single layer: | |
72 | +http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map&typename=sfumo,vngeo_ospitalita | |
73 | + | |
74 | +Two layers (one raster and one vector): | |
75 | +http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map&typename=vngeo_ospitalita | |
76 | + | |
77 | +All layers as network links: | |
78 | +http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map | |
79 | + | |
80 | +Single layer with filter: | |
81 | +http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map&typename=comuni&filter=<Filter><PropertyIsLike><PropertyName>toponimo</PropertyName><Literal>Riederalp</Literal></PropertyIsLike></Filter> | |
82 | + | |
83 | + | |
84 | +ICON SERVER | |
85 | +------------------------------------- | |
86 | +Returns a PNG icon for a give poin layer/class combination | |
87 | +Example calls: | |
88 | +http://localhost/kmlserver/symbolservice.php?map=/map/mapfile-ogc.map&typename=vngeo_ospitalita&class=Alberghi | |
89 | + | |
90 | +If you want transparent icons, set PNG output format to RGBA and IMAGECOLOR to the transparent color | |
91 | + | |
92 | + | ... | ... |
... | ... | @@ -0,0 +1,102 @@ |
1 | +<?php | |
2 | +/** | |
3 | +* Mapserver wrapper to KML/KMZ data | |
4 | +* | |
5 | +* Returns KML or KMZ representation of common OGC requests | |
6 | +* | |
7 | +* <pre> | |
8 | +* accepted parameters (case insensitive): | |
9 | +* - request = string - request type (OGC WFS like), can be kml (default), kmz, icon | |
10 | +* - map = string - path to mapfile | |
11 | +* - typename = string - (can be a csv list) - layer name(s) | |
12 | +* - filter = string - filter encoding | |
13 | +* - bbox = string - (csv) - bounding box csv | |
14 | +* | |
15 | +* | |
16 | +* </pre> | |
17 | +* | |
18 | +* @author Alessandro Pasotti | |
19 | +* @copyright 2007 ItOpen.it - All rights reserved | |
20 | +* @package KMLMAPSERVER | |
21 | + | |
22 | +This file is part of KMLMAPSERVER. | |
23 | + | |
24 | + KMLMAPSERVER is free software; you can redistribute it and/or modify | |
25 | + it under the terms of the GNU Lesser General Public License as published by | |
26 | + the Free Software Foundation; either version 3 of the License, or | |
27 | + (at your option) any later version. | |
28 | + | |
29 | + KMLMAPSERVER is distributed in the hope that it will be useful, | |
30 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
31 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
32 | + GNU Lesser General Public License for more details. | |
33 | + | |
34 | + You should have received a copy of the GNU Lesser General Public License | |
35 | + along with KMLMAPSERVER; if not, write to the Free Software | |
36 | + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
37 | + | |
38 | +*/ | |
39 | + | |
40 | + | |
41 | +if (!extension_loaded('MapScript')) | |
42 | +{ | |
43 | + dl( 'php_mapscript.' . PHP_SHLIB_SUFFIX ); | |
44 | +} | |
45 | + | |
46 | + | |
47 | +/** | |
48 | +* Main server class, wraps real kml or icon servers | |
49 | +*/ | |
50 | + | |
51 | +class KmlServer { | |
52 | + | |
53 | + /** server instance */ | |
54 | + var $service; | |
55 | + | |
56 | + /** request */ | |
57 | + var $request; | |
58 | + | |
59 | + /** debug flag */ | |
60 | + var $_debug = false; | |
61 | + | |
62 | + /** | |
63 | + * Initialize | |
64 | + * | |
65 | + */ | |
66 | + function KmlServer(){ | |
67 | + $this->get_request(); | |
68 | + if($this->service == 'icon'){ | |
69 | + include 'symbolserver.class.php'; | |
70 | + $this->service = new SymbolServer(); | |
71 | + $this->service->run(); | |
72 | + } else { | |
73 | + include 'layerserver.class.php'; | |
74 | + $this->service = new LayerServer(); | |
75 | + $this->service->run(); | |
76 | + } | |
77 | + } | |
78 | + | |
79 | + /** | |
80 | + * Get all request parameters | |
81 | + */ | |
82 | + function get_request(){ | |
83 | + $this->service = $this->load_parm('service'); | |
84 | + if(!$this->service){ | |
85 | + $this->service= 'kml'; | |
86 | + } | |
87 | + } | |
88 | + | |
89 | + /** | |
90 | + * Get a request parameter | |
91 | + * @param string $name | |
92 | + * @return string the parameter value or empty string if null | |
93 | + */ | |
94 | + function load_parm($name){ | |
95 | + if(!isset($_REQUEST[$name])) return ''; | |
96 | + $value = $_REQUEST[$name]; | |
97 | + if(get_magic_quotes_gpc() != 1) $value = addslashes($value); | |
98 | + //$value = escapeshellcmd($value); | |
99 | + return $value; | |
100 | + } | |
101 | +} | |
102 | +?> | |
0 | 103 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,908 @@ |
1 | +<?php | |
2 | +/** | |
3 | +* Mapserver wrapper to KML/KMZ data | |
4 | +* | |
5 | +* Returns KML or KMZ representation of common OGC requests | |
6 | +* | |
7 | +* <pre> | |
8 | +* accepted parameters (case insensitive): | |
9 | +* - request = string - request type (OGC WFS like), can be kml (default), kmz, icon | |
10 | +* - map = string - path to mapfile | |
11 | +* - typename = string - (can be a csv list) - layer name(s) | |
12 | +* - filter = string - filter encoding | |
13 | +* - bbox = string - (csv) - bounding box csv | |
14 | +* - encoding = string - data and mapfile encoding, defaults to ISO-8859-1 | |
15 | +* | |
16 | +* | |
17 | +* </pre> | |
18 | +* | |
19 | +* @author Alessandro Pasotti | |
20 | +* @copyright 2007 ItOpen.it - All rights reserved | |
21 | +* @package KMLMAPSERVER | |
22 | + | |
23 | +This file is part of KMLMAPSERVER. | |
24 | + | |
25 | + KMLMAPSERVER is free software; you can redistribute it and/or modify | |
26 | + it under the terms of the GNU Lesser General Public License as published by | |
27 | + the Free Software Foundation; either version 3 of the License, or | |
28 | + (at your option) any later version. | |
29 | + | |
30 | + KMLMAPSERVER is distributed in the hope that it will be useful, | |
31 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
32 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
33 | + GNU Lesser General Public License for more details. | |
34 | + | |
35 | + You should have received a copy of the GNU Lesser General Public License | |
36 | + along with KMLMAPSERVER; if not, write to the Free Software | |
37 | + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
38 | + | |
39 | +*/ | |
40 | + | |
41 | + | |
42 | +/** Fix a GE bug for filled polygons */ | |
43 | +define('TREAT_POLY_AS_LINE', true); | |
44 | + | |
45 | +/** Enable cache */ | |
46 | +define('ENABLE_CACHE', true); | |
47 | + | |
48 | +if (!extension_loaded('MapScript')) | |
49 | +{ | |
50 | + dl( 'php_mapscript.' . PHP_SHLIB_SUFFIX ); | |
51 | +} | |
52 | + | |
53 | + | |
54 | +/** | |
55 | +* Main server class | |
56 | +*/ | |
57 | + | |
58 | +class LayerServer { | |
59 | + | |
60 | + /** map file path */ | |
61 | + var $map; | |
62 | + | |
63 | + /** request */ | |
64 | + var $request; | |
65 | + | |
66 | + /** map instance */ | |
67 | + var $map_object; | |
68 | + | |
69 | + /** layer name(s) passed on the request */ | |
70 | + var $typename; | |
71 | + | |
72 | + /** array of requested layer objects (hash with layer name as key) */ | |
73 | + var $layers; | |
74 | + | |
75 | + /** filters */ | |
76 | + var $filter; | |
77 | + | |
78 | + /** bounding box */ | |
79 | + var $bbox; | |
80 | + | |
81 | + /** error messages */ | |
82 | + var $errors; | |
83 | + | |
84 | + /** send zipped data */ | |
85 | + var $_zipped = false; | |
86 | + | |
87 | + /** internal XML buffer */ | |
88 | + var $_xml; | |
89 | + | |
90 | + /** input projection */ | |
91 | + var $in_proj; | |
92 | + | |
93 | + /** output projection */ | |
94 | + var $out_proj; | |
95 | + | |
96 | + /** debug flag */ | |
97 | + var $_debug = false; | |
98 | + | |
99 | + /** end point */ | |
100 | + var $endpoint; | |
101 | + | |
102 | + /** custom style counter */ | |
103 | + var $style_counter = 0; | |
104 | + | |
105 | + /** | |
106 | + * Mapfile and data encoding encoding | |
107 | + * XMl output must be UTF-8, attributes and METADATA based strings | |
108 | + * must be converted to UTF-8, encoding defaults to ISO-8859-1, if | |
109 | + * your encoding is different, you can set it through CGI style parameters | |
110 | + */ | |
111 | + var $encoding; | |
112 | + | |
113 | + /** | |
114 | + * send networklink | |
115 | + * wether folder should contain networklinks instead of real geometries | |
116 | + * it is automatically set when all layers are requested | |
117 | + */ | |
118 | + var $_networklink; | |
119 | + | |
120 | + | |
121 | + /** | |
122 | + * Initialize | |
123 | + * | |
124 | + */ | |
125 | + function LayerServer(){ | |
126 | + $this->errors = array(); | |
127 | + // Load request parameters | |
128 | + $this->get_request(); | |
129 | + | |
130 | + $this->style_counter = 0; | |
131 | + | |
132 | + // Load map | |
133 | + if(!$this->has_error()) { | |
134 | + $this->load_map(); | |
135 | + } | |
136 | + | |
137 | + } | |
138 | + | |
139 | + /** | |
140 | + * Run the server and sends data | |
141 | + * @return string or void | |
142 | + */ | |
143 | + function run(){ | |
144 | + // Check cache | |
145 | + if(ENABLE_CACHE){ | |
146 | + $cache_file = $this->get_cache_file_name(); | |
147 | + if(file_exists($cache_file)){ | |
148 | + // Check if is not expired | |
149 | + $layer = $this->map_object->getLayerByName($this->typename); | |
150 | + if(filectime($cache_file) + $layer->getMetadata('KML_CACHE') < (time())) { | |
151 | + error_log('removing cache ' . $cache_file); | |
152 | + //error_log('ctime : ' . filectime($cache_file) . ' , ' . time() . ' lm ' . $layer->getMetadata('KML_CACHE')); | |
153 | + @unlink($cache_file); | |
154 | + } else { | |
155 | + $this->send_header(); | |
156 | + error_log('sending cache ' . $cache_file); | |
157 | + readfile($cache_file); | |
158 | + exit; | |
159 | + } | |
160 | + } | |
161 | + } | |
162 | + | |
163 | + // If not layer are requested, send all as networklinks | |
164 | + if(!$this->typename){ | |
165 | + $this->_networklink = true; | |
166 | + $this->typename = $this->get_layer_list(); | |
167 | + } else { | |
168 | + $this->_networklink = false; | |
169 | + } | |
170 | + | |
171 | + $this->_xml = new SimpleXMLElement('<kml xmlns="http://earth.google.com/kml/2.0"><Document ></Document></kml>'); | |
172 | + // Prepare projection | |
173 | + $this->in_proj = ms_newProjectionObj($this->map_object->getProjection()); | |
174 | + // Set projection to GOOGLE earth's projection | |
175 | + $this->out_proj = ms_newProjectionObj("init=epsg:4326"); | |
176 | + // Set endpoint | |
177 | + //die($_SERVER['REQUEST_URI']); | |
178 | + $this->endpoint = ($_SERVER['HTTPS'] ? 'https' : 'http') . '://'.$_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] ? ':'.$_SERVER['SERVER_PORT'] : '') . $_SERVER['PHP_SELF']; | |
179 | + | |
180 | + | |
181 | + // Process request | |
182 | + if(!$this->has_error()) { | |
183 | + $this->process_request(); | |
184 | + } | |
185 | + if($this->has_error()){ | |
186 | + $this->add_errors(); | |
187 | + } | |
188 | + return $this->send_stream($this->get_kml()); | |
189 | + } | |
190 | + | |
191 | + /** | |
192 | + * Set debug flag | |
193 | + * @param boolean $value | |
194 | + */ | |
195 | + function set_debug($value){ | |
196 | + $this->_debug = $value; | |
197 | + } | |
198 | + | |
199 | + /** | |
200 | + * Get all request parameters | |
201 | + */ | |
202 | + function get_request(){ | |
203 | + $this->map = $this->load_parm('map'); | |
204 | + $this->bbox = $this->load_parm('bbox'); | |
205 | + $this->filter = $this->load_parm('filter'); | |
206 | + $this->typename = $this->load_parm('typename'); | |
207 | + $this->encoding = $this->load_parm('encoding', 'ISO-8859-1'); | |
208 | + $this->request = $this->load_parm('request', 'kml'); | |
209 | + | |
210 | + if($this->request == 'kmz') { | |
211 | + $this->_zipped = true; | |
212 | + } | |
213 | + | |
214 | + if(!$this->map){ | |
215 | + $this->set_error('No mapfile specified'); | |
216 | + } | |
217 | + } | |
218 | + | |
219 | + /** | |
220 | + * Apply filter | |
221 | + * @return array | |
222 | + */ | |
223 | + function apply_filter(&$layer, &$filter){ | |
224 | + if($layer->connectiontype == MS_POSTGIS){ | |
225 | + if($filter->PropertyIsEqualTo){ | |
226 | + $searchstring = '"'.$filter->PropertyIsEqualTo->PropertyName . ' = ' . '\''.addslashes($filter->PropertyIsEqualTo->Literal).'\''.'"'; | |
227 | + $searchfield = $filter->PropertyIsEqualTo->PropertyName; | |
228 | + } elseif($filter->PropertyIsLike){ | |
229 | + $searchfield = $filter->PropertyIsLike->PropertyName; | |
230 | + $searchstring ='"'.$filter->PropertyIsLike->PropertyName . ' LIKE \'%' . addslashes($filter->PropertyIsLike->Literal) . '%\''.'"'; | |
231 | + } | |
232 | + } elseif($layer->connectiontype == MS_SHAPEFILE || $layer->connectiontype == MS_OGR){ | |
233 | + if($filter->PropertyIsEqualTo){ | |
234 | + $searchstring = $filter->PropertyIsEqualTo->Literal; | |
235 | + $searchfield = $filter->PropertyIsEqualTo->PropertyName; | |
236 | + } elseif($filter->PropertyIsLike){ | |
237 | + $searchstring = $filter->PropertyIsLike->Literal; | |
238 | + $searchfield = $filter->PropertyIsLike->PropertyName; | |
239 | + } | |
240 | + } | |
241 | + return array($searchfield, $searchstring); | |
242 | + } | |
243 | + | |
244 | + /** | |
245 | + * Process request | |
246 | + */ | |
247 | + function process_request(){ | |
248 | + // Get layer(s) | |
249 | + $layers = split(',', $this->typename); | |
250 | + if($this->_networklink){ | |
251 | + foreach($layers as $layer){ | |
252 | + $this->add_networklink($layer); | |
253 | + } | |
254 | + } else { | |
255 | + foreach($layers as $layer){ | |
256 | + $this->process_layer_request($layer); | |
257 | + } | |
258 | + } | |
259 | + } | |
260 | + | |
261 | + /** | |
262 | + * Add a networklink | |
263 | + */ | |
264 | + function add_networklink(&$layer_name){ | |
265 | + $nl =& $this->_xml->Document->addChild('NetworkLink'); | |
266 | + | |
267 | + $layer = @$this->map_object->getLayerByName($layer_name); | |
268 | + $nl->addChild('name', $this->get_layer_description($layer)); | |
269 | + $nl->addChild('visibility', 0); | |
270 | + $link =& $nl->addChild('Link'); | |
271 | + $link->addChild('href', $this->endpoint . '?map=' . $this->map . '&typename=' . urlencode($layer_name) . '&request=' . ($this->_zipped ? 'kmz' : 'kml')); | |
272 | + } | |
273 | + | |
274 | + | |
275 | + /** | |
276 | + * Process a single layer | |
277 | + * @return boolean false on error | |
278 | + */ | |
279 | + function process_layer_request(&$layer_name){ | |
280 | + | |
281 | + $layer = @$this->map_object->getLayerByName($layer_name); | |
282 | + | |
283 | + if(!$layer){ | |
284 | + $this->set_error('Layer not found ' . $layer_name, $layer_name); | |
285 | + return false; | |
286 | + } | |
287 | + | |
288 | + // Add to layer list | |
289 | + $this->layers[$layer_name] =& $layer; | |
290 | + | |
291 | + // Get custom template if any | |
292 | + $description_template = $layer->getMetadata('DESCRIPTION_TEMPLATE'); | |
293 | + | |
294 | + // Set on | |
295 | + $layer->set( 'status', MS_ON ); | |
296 | + | |
297 | + // Set kml title from layer description (default to layer name) | |
298 | + $layer_desc = $this->get_layer_description($layer); | |
299 | + | |
300 | + // Now switch raster layers | |
301 | + //var_dump($layer->type == MS_LAYER_RASTER); | |
302 | + if($layer->type == MS_LAYER_RASTER){ | |
303 | + // Check if wms_onlineresource metadata is set | |
304 | + $wms_link = $this->map_object->getMetadata('wms_onlineresource'); | |
305 | + if(!$wms_link){ | |
306 | + $wms_link = $this->map_object->getMetadata('ows_onlineresource'); | |
307 | + } | |
308 | + if(!$wms_link){ | |
309 | + $this->set_error('No WMS server available for ' . $layer_name, $layer_name); | |
310 | + return false; | |
311 | + } | |
312 | + // Add parameters to OGC server call | |
313 | + // Fix & | |
314 | + $wms_link = preg_replace('/&/', '&', $wms_link); | |
315 | + $wms_link .= 'VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG:4326&STYLES=&BGCOLOR=0xFFFFFF&FORMAT=image/png&TRANSPARENT=TRUE&'; | |
316 | + // Link ok, create folder | |
317 | + $folder =& $this->_xml->Document->addChild('GroundOverlay'); | |
318 | + $folder->addChild('description', $this->get_layer_description($layer)); | |
319 | + $folder->addChild('name', $layer_desc); | |
320 | + $this->add_wms_link($folder, $layer, $wms_link); | |
321 | + } else { | |
322 | + | |
323 | + // Apply filter | |
324 | + if($this->filter){ | |
325 | + // Try loading as XML | |
326 | + try { | |
327 | + $filter = @new SimpleXMLElement($this->filter); | |
328 | + list($searchfield, $searchstring) = $this->apply_filter($layer, $filter); | |
329 | + if(! ($searchfield && $searchstring)){ | |
330 | + $this->set_error('Error parsing filter', $layer_name); | |
331 | + return false; | |
332 | + } | |
333 | + } catch (Exception $e) { | |
334 | + $this->set_error('Wrong XML filter', $layer_name); | |
335 | + $this->filter = null; | |
336 | + return false; | |
337 | + } | |
338 | + } | |
339 | + | |
340 | + // Get results | |
341 | + if(MS_SUCCESS == $layer->open()){ | |
342 | + // Search which column to use to identify the feature | |
343 | + $namecol = $layer->getMetadata('RESULT_FIELDS'); | |
344 | + if(!$namecol){ | |
345 | + $cols = array_values($layer->getItems()); | |
346 | + $namecol = $cols[0]; | |
347 | + } | |
348 | + // Add classes | |
349 | + $folder =& $this->_xml->Document->addChild('Folder'); | |
350 | + $class_list = $this->parse_classes($layer, $folder, $namecol, $title_field, $description_template); | |
351 | + | |
352 | + //die(print_r($class_list, true)); | |
353 | + $folder->addChild('description', $this->get_layer_description($layer)); | |
354 | + $folder->addChild('name', $layer_desc); | |
355 | + | |
356 | + //print("$searchfield && $searchstring"); | |
357 | + if($searchfield && $searchstring){ | |
358 | + if(@$layer->queryByAttributes($searchfield, $searchstring, MS_MULTIPLE) == MS_SUCCESS){ | |
359 | + $layer->open(); | |
360 | + //var_dump($layer->getItems()); die(); | |
361 | + for ($j=0; $j < $layer->getNumResults(); $j++) | |
362 | + { | |
363 | + // get next shape row | |
364 | + $result = $layer->getResult($j); | |
365 | + $shape = $layer->getShape($result->tileindex, $result->shapeindex); | |
366 | + $this->process_shape($layer, $shape, $class_list, $folder, $namecol); | |
367 | + // end for loop | |
368 | + } | |
369 | + } else { | |
370 | + $this->set_error('Query returned no data', $layer_name); | |
371 | + return false; | |
372 | + } | |
373 | + } else { // Get all shapes | |
374 | + $status = $layer->whichShapes($this->map_object->extent); | |
375 | + while ($shape = $layer->nextShape()) { | |
376 | + $this->process_shape($layer, $shape, $class_list, $folder,$namecol ); | |
377 | + } | |
378 | + } | |
379 | + $layer->close(); | |
380 | + } else { | |
381 | + $this->set_error('Layer cannot be opened', $layer_name); | |
382 | + return false; | |
383 | + } | |
384 | + } | |
385 | + return true; | |
386 | + } | |
387 | + | |
388 | + /** | |
389 | + * Process the shape | |
390 | + */ | |
391 | + function process_shape(&$layer, &$shape, &$class_list, &$folder, &$namecol){ | |
392 | + $shape->project($this->in_proj, $this->out_proj); | |
393 | + // Assign style | |
394 | + if($layer->classitem){ | |
395 | + $style_id = $this->get_shape_class($layer->classitem, $shape->values, $class_list); | |
396 | + } | |
397 | + if(!$style_id){ | |
398 | + // Get first class | |
399 | + $class_keys = array_keys($class_list); | |
400 | + $style_id = $class_keys[0]; | |
401 | + } | |
402 | + // Add the feature | |
403 | + if(array_key_exists('folder', $class_list[$style_id])) { | |
404 | + $feature_folder =& $class_list[$style_id]['folder']; | |
405 | + } else { | |
406 | + //die('missing folder for ' . $style_id); | |
407 | + $feature_folder =& $folder; | |
408 | + } | |
409 | + if(!is_object($feature_folder)){ | |
410 | + $folder_name = $feature_folder; | |
411 | + $feature_folder =& $folder ->addChild('Folder'); | |
412 | + $feature_folder->addChild('name', $folder_name); | |
413 | + } | |
414 | + // Add style class | |
415 | + $style_url =& $this->add_style($layer, $feature_folder, $style_id, $class_list[$style_id], $namecol, $shape->values); | |
416 | + | |
417 | + $wkt = $shape->toWkt(); | |
418 | + $placemark =& $this->add_feature($feature_folder, $wkt, $shape->values[$namecol], $shape->values, $description_template, $class_list[$style_id]); | |
419 | + | |
420 | + $placemark->addChild('styleUrl', '#'. $style_url); | |
421 | + | |
422 | + } | |
423 | + | |
424 | + /** | |
425 | + * Add the feature to the result set | |
426 | + * @return reference to placemark object | |
427 | + */ | |
428 | + function &add_feature(&$folder, &$wkt, $featurename, $attributes, $description_template, $style_data){ | |
429 | + $pm = $folder->addChild('Placemark'); | |
430 | + //if($featurename == 'VERCELLI') {var_dump($wkt); die();} | |
431 | + $pm->addChild('name', iconv($this->encoding, 'utf-8', $featurename)); | |
432 | + $pm->addChild('description', $this->get_feature_description($featurename, $attributes, $description_template)); | |
433 | + // Now parse the wkt | |
434 | + if(strpos($wkt, 'MULTILINESTRING') !== false){ | |
435 | + $this->add_multilinestring($wkt, $pm, $featurename, $style_data['icon']); | |
436 | + } elseif(strpos($wkt, 'LINESTRING') !== false){ | |
437 | + $this->add_linestring($wkt, $pm, $featurename, $style_data['icon']); | |
438 | + } elseif(strpos($wkt, 'POINT') !== false){ | |
439 | + $this->add_point($wkt, $pm, $featurename); | |
440 | + } elseif(strpos($wkt, 'MULTIPOLYGON') !== false){ | |
441 | + if(TREAT_POLY_AS_LINE){ | |
442 | + $ml = $pm->addChild('MultiGeometry'); | |
443 | + foreach(split('\), \(', $wkt) as $line){ | |
444 | + $this->add_multilinestring($line, $ml, $featurename ); | |
445 | + } | |
446 | + } else { | |
447 | + $this->add_multipolygon($wkt, $pm, $featurename); | |
448 | + } | |
449 | + } elseif(strpos($wkt, 'POLYGON') !== false){ | |
450 | + if(TREAT_POLY_AS_LINE){ | |
451 | + $this->add_multilinestring($wkt, $pm, $featurename); | |
452 | + } else { | |
453 | + $this->add_polygon($wkt, $pm, $featurename); | |
454 | + } | |
455 | + } else { | |
456 | + // Error? | |
457 | + } | |
458 | + return $pm; | |
459 | + } | |
460 | + | |
461 | + /** | |
462 | + * Add a linestring | |
463 | + */ | |
464 | + function add_linestring(&$wkt, &$element, $featurename, $add_points){ | |
465 | + preg_match('/(\d+[^\(\)]*\d)/', $wkt, $data); | |
466 | + $data = str_replace(', ', '#', $data[1]); | |
467 | + $data = str_replace(' ', ',', $data); | |
468 | + $data = str_replace('#', ' ', $data); | |
469 | + if($add_points){ | |
470 | + preg_match('/^(\d+\.\d+,\d+\.\d+).*(\d+\.\d+,\d+\.\d+)$/', $data, $points); | |
471 | + if(count($points) == 3){ | |
472 | + $mg = $element->addChild('MultiGeometry'); | |
473 | + $ls = $mg->addChild('LineString'); | |
474 | + $pt1 = $mg->addChild('Point'); | |
475 | + $pt1->addChild('coordinates', $points[1]); | |
476 | + $pt2 = $mg->addChild('Point'); | |
477 | + $pt2->addChild('coordinates', $points[2]); | |
478 | + } else { | |
479 | + die('errore'); | |
480 | + $ls = $element->addChild('LineString'); | |
481 | + } | |
482 | + //print_r($points);die(); | |
483 | + } else { | |
484 | + $ls = $element->addChild('LineString'); | |
485 | + } | |
486 | + $ls->addChild('coordinates', $data); | |
487 | + } | |
488 | + | |
489 | + /** | |
490 | + * Add a multilinestring | |
491 | + */ | |
492 | + function add_multilinestring(&$wkt, &$element, $featurename, $add_points){ | |
493 | + $ml = $element->addChild('MultiGeometry'); | |
494 | + foreach(split('\), \(', $wkt) as $line){ | |
495 | + $this->add_linestring($line, $ml, $featurename, $add_points ); | |
496 | + } | |
497 | + } | |
498 | + | |
499 | + /** | |
500 | + * Add a point | |
501 | + */ | |
502 | + function add_point(&$wkt, &$element, $featurename){ | |
503 | + $pt = $element->addChild('Point'); | |
504 | + preg_match('/(\d\.?\d+\s\d+\.?\d+)/', $wkt, $data); | |
505 | + $data = str_replace(' ', ',', $data[1]); | |
506 | + $pt->addChild('coordinates', $data); | |
507 | + } | |
508 | + | |
509 | + | |
510 | + /** | |
511 | + * Add a polygon | |
512 | + */ | |
513 | + function add_polygon(&$wkt, &$element, $featurename){ | |
514 | + $ml = $element->addChild('Polygon'); | |
515 | + foreach(split('\), \(', $wkt) as $line){ | |
516 | + preg_match('/(\d+[^\(\)]*\d)/', $wkt, $data); | |
517 | + $data = str_replace(', ', '#', $data[1]); | |
518 | + $data = str_replace(' ', ',', $data); | |
519 | + // Add 1 meter height | |
520 | + $data = str_replace('#', ',1 ', $data) . ',1'; | |
521 | + $ml->addChild('tessellate', 1); | |
522 | + //$element->addChild('altitudeMode', 'relativeToGround'); | |
523 | + $element->addChild('altitudeMode', 'clampToGround'); | |
524 | + $ob = $ml->addChild('outerBoundaryIs'); | |
525 | + $ls = $ob->addChild('LinearRing'); | |
526 | + $ls->addChild('coordinates', $data); | |
527 | + } | |
528 | + } | |
529 | + | |
530 | + | |
531 | + /** | |
532 | + * Add a multipolygon | |
533 | + * FIXME: untested, should take holes into account | |
534 | + */ | |
535 | + function add_multipolygon(&$wkt, &$element, $featurename){ | |
536 | + $ml = $element->addChild('MultiGeometry'); | |
537 | + foreach(split('\), \(', $wkt) as $line){ | |
538 | + $this->add_polygon($line, $ml, $featurename ); | |
539 | + } | |
540 | + } | |
541 | + | |
542 | + | |
543 | + /** | |
544 | + * Get the feature description | |
545 | + */ | |
546 | + function get_feature_description($featurename, $attributes, $description_template){ | |
547 | + // Compute hyperlink | |
548 | + if($description_template){ | |
549 | + $description = $description_template; | |
550 | + foreach($attributes as $k => $val){ | |
551 | + $description = str_replace("%$k%", iconv($this->encoding, 'utf-8', $val), $description); | |
552 | + } | |
553 | + } else { | |
554 | + $description = iconv($this->encoding, 'utf-8', $featurename); | |
555 | + } | |
556 | + return htmlentities($description); | |
557 | + } | |
558 | + | |
559 | + | |
560 | + /** | |
561 | + * Parse classes | |
562 | + * @return array hash of 'style_id' => style_data) | |
563 | + */ | |
564 | + function parse_classes(&$layer, &$folder, &$namecol, &$title_field, &$description_template ){ | |
565 | + $style_ar = array(); | |
566 | + $numclasses = $layer->numclasses; | |
567 | + for($i = 0; $i < $numclasses; $i++){ | |
568 | + $class = $layer->getClass($i); | |
569 | + $label = $class->label; | |
570 | + if($label){ | |
571 | + $style['label_color'] = $label->color; | |
572 | + $style['label_size'] = $label->size; | |
573 | + } | |
574 | + // Get styles | |
575 | + for($j = 0; $j < $class->numstyles; $j++){ | |
576 | + $_style = $class->getStyle($j); | |
577 | + $style['color'] = $_style->color; | |
578 | + $style['outlinecolor'] = $_style->outlinecolor; | |
579 | + $style['width'] = $_style->size; // Lines | |
580 | + $style['backgroundcolor'] = $_style->backgroundcolor; | |
581 | + $style['icon'] = $this->get_icon_url($layer, $class->name); | |
582 | + $style['icon_width'] = $_style->size; // Points | |
583 | + | |
584 | + } | |
585 | + $style['expression'] = $class->getExpression(); | |
586 | + // Set description_template if any | |
587 | + $style['description_template'] = $description_template; | |
588 | + // Get icon for lines if any | |
589 | + if($icon = $layer->getMetadata('KML_ADD_POINT')){ | |
590 | + $style['icon'] = $icon; | |
591 | + $style['icon_width'] = 32; | |
592 | + } | |
593 | + // Create style element | |
594 | + $style_id = preg_replace('/[^A-z0-9]/', '_', $layer->name . $class->name); | |
595 | + //$this->add_style($layer, $folder, $style_id, $style, $namecol, $title_field ); | |
596 | + // create folder if more than one class | |
597 | + if($numclasses > 1){ | |
598 | + $style['folder'] =& $class->name; | |
599 | + //$folder->addChild('Folder'); | |
600 | + //$style['folder']->addChild('name', $class->name); | |
601 | + } | |
602 | + $style_ar[$style_id] = $style; | |
603 | + } | |
604 | + return $style_ar; | |
605 | + } | |
606 | + | |
607 | + /** | |
608 | + * Return a CSV list of all layer names in the mapfile | |
609 | + * FIXME: filter out ANNOTATIONS and other "strange" layers | |
610 | + */ | |
611 | + function get_layer_list(){ | |
612 | + $layer_list = array(); | |
613 | + for($i = 0; $i < $this->map_object->numlayers; $i++){ | |
614 | + $layer =& $this->map_object->getLayer($i); | |
615 | + $kml_skip = $layer->getMetadata('KML_SKIP'); | |
616 | + if(strtolower($kml_skip) !== 'true'){ | |
617 | + $layer_list[] = $layer->name; | |
618 | + } | |
619 | + } | |
620 | + return join(',', $layer_list); | |
621 | + } | |
622 | + | |
623 | + | |
624 | + /** | |
625 | + * Return the class for the shape, default to last class if not match | |
626 | + */ | |
627 | + function get_shape_class(&$classitem, &$values, &$class_list){ | |
628 | + //var_dump($class_list); die(); | |
629 | + foreach($class_list as $style_id => $style_data){ | |
630 | + if($style_data['expression'] && preg_match($style_data['expression'], $values[$classitem])){ | |
631 | + //print "get_shape_class($classitem) ".$values[$classitem]." matches<br>"; | |
632 | + return $style_id; | |
633 | + } | |
634 | + } | |
635 | + //print "get_shape_class($classitem) ".$values[$classitem]." no matches<br>"; | |
636 | + return $style_id; | |
637 | + } | |
638 | + | |
639 | + /** | |
640 | + * Add the style | |
641 | + * @return the style URL | |
642 | + */ | |
643 | + function add_style(&$layer, &$folder, $style_id, &$style_data){ | |
644 | + // Calculare style URL | |
645 | + /* | |
646 | + if($style_data['description_template']){ | |
647 | + $this->style_counter++; | |
648 | + $style_id .= '_'.$this->style_counter; | |
649 | + $balloon_data = $this->get_feature_description($attributes[$namecol], $attributes, $style_data['description_template']); | |
650 | + } | |
651 | + */ | |
652 | + // Check if the style already exists | |
653 | + $expr = '//*[@id=\''.$style_id.'\']'; | |
654 | + if($folder->xpath($expr)) { | |
655 | + return $style_id; | |
656 | + } | |
657 | + $new_style =& $folder->addChild('Style'); | |
658 | + $new_style['id'] = $style_id; | |
659 | + // Switch layer type | |
660 | + switch($layer->type){ | |
661 | + case MS_LAYER_POINT: | |
662 | + $this->add_style_point($new_style, $style_data); | |
663 | + break; | |
664 | + case MS_LAYER_POLYGON: | |
665 | + $this->add_style_polygon($new_style, $style_data); | |
666 | + break; | |
667 | + case MS_LAYER_LINE: | |
668 | + $this->add_style_line($new_style, $style_data); | |
669 | + // Add KML_ADD_POINT icon | |
670 | + if($style_data['icon']){ | |
671 | + $this->add_style_point($new_style, $style_data); | |
672 | + } | |
673 | + break; | |
674 | + } | |
675 | + return $style_id; | |
676 | + } | |
677 | + | |
678 | + /** | |
679 | + * Add style for lines | |
680 | + */ | |
681 | + function add_style_line(&$new_style, &$style_data){ | |
682 | + if($style_data['outlinecolor']->red != -1){ | |
683 | + $st =& $new_style->addChild('LineStyle'); | |
684 | + $st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['outlinecolor']->blue, $style_data['outlinecolor']->green, $style_data['outlinecolor']->red)); | |
685 | + if($width) { | |
686 | + $st->addChild('width', $width); | |
687 | + } | |
688 | + } elseif($style_data['color']->red != -1){ | |
689 | + $st =& $new_style->addChild('LineStyle'); | |
690 | + $st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['color']->blue, $style_data['color']->green, $style_data['color']->red)); | |
691 | + if($width) { | |
692 | + $st->addChild('width', $width); | |
693 | + } | |
694 | + } | |
695 | + } | |
696 | + | |
697 | + /** | |
698 | + * Add style for points | |
699 | + */ | |
700 | + function add_style_point(&$new_style, &$style_data){ | |
701 | + if($style_data['icon']){ | |
702 | + $st =& $new_style->addChild('IconStyle'); | |
703 | + if($style_data['width'] && $style_data['icon_width'] != 32){ | |
704 | + $st->addChild('scale', $style_data['icon_width'] / 32); | |
705 | + } | |
706 | + $icon =& $st->addChild('Icon'); | |
707 | + $icon->addChild('href', htmlentities($style_data['icon'])); | |
708 | + } | |
709 | + /*/ Add the balloon style if description_template is set | |
710 | + if($style_data['description_template']){ | |
711 | + $this->add_balloon_style($new_style, $balloon_data); | |
712 | + } | |
713 | + */ | |
714 | + // Label size and color | |
715 | + if($style_data['label_size'] || $style_data['label_color']){ | |
716 | + $ls =& $new_style->addChild('LabelStyle'); | |
717 | + if($style_data['label_size'] != -1 && $style_data['label_size'] != 32){ | |
718 | + $ls->addChild('scale', $style_data['label_size'] / 32); | |
719 | + } | |
720 | + if($style_data['label_color']->red != -1){ | |
721 | + $ls->addChild('color', sprintf('FF%02X%02X%02X', $style_data['label_color']->blue, $style_data['label_color']->green, $style_data['label_color']->red)); | |
722 | + } | |
723 | + } | |
724 | + } | |
725 | + | |
726 | + /** | |
727 | + * Add style for polygons | |
728 | + */ | |
729 | + function add_style_polygon(&$new_style, &$style_data){ | |
730 | + // Get also outline styles | |
731 | + $this->add_style_line($new_style, $style_data); | |
732 | + $st =& $new_style->addChild('PolyStyle'); | |
733 | + //die(print_r($backgroundcolor, true)); | |
734 | + if($style_data['backgroundcolor']->red != -1){ | |
735 | + $st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['backgroundcolor']->blue, $style_data['backgroundcolor']->green, $style_data['backgroundcolor']->red)); | |
736 | + $st->addChild('fill', 0); | |
737 | + } else { | |
738 | + $st->addChild('fill', 0); | |
739 | + } | |
740 | + $st->addChild('outline', 1); | |
741 | + } | |
742 | + | |
743 | + /** | |
744 | + * Add a WMS raster link | |
745 | + */ | |
746 | + function add_wms_link(&$folder, &$layer, &$link){ | |
747 | + // Build up the KML response document. | |
748 | + $icon =& $folder->addChild('Icon'); | |
749 | + $icon->addChild('href', $link . 'layers=' . $layer->name); | |
750 | + //$icon->addChild('viewBoundScale', 1.5); | |
751 | + $icon->addChild('viewRefreshMode', 'onStop'); | |
752 | + $llbox =& $folder->addChild('LatLonBox'); | |
753 | + $ext = $this->map_object->extent; | |
754 | + $ext->project($this->in_proj, $this->out_proj); | |
755 | + $llbox->north = $ext->maxy; | |
756 | + $llbox->south = $ext->miny; | |
757 | + $llbox->east = $ext->maxx; | |
758 | + $llbox->west = $ext->minx; | |
759 | + // Reset original projection | |
760 | + $ext->project($this->out_proj, $this->in_proj); | |
761 | + } | |
762 | + | |
763 | + /** | |
764 | + * Get the url for a point icon | |
765 | + */ | |
766 | + function get_icon_url($layer, $classname){ | |
767 | + return $this->endpoint . '?service=icon&map=' . $this->map . '&typename=' . urlencode($layer->name) . '&classname=' . urlencode($classname); | |
768 | + } | |
769 | + | |
770 | + /** | |
771 | + * Get the layer description | |
772 | + */ | |
773 | + function get_layer_description(&$layer){ | |
774 | + $description = $layer->getMetadata('DESCRIPTION'); | |
775 | + if(!$description){ | |
776 | + $description = $layer->getMetadata('OWS_TITLE'); | |
777 | + } | |
778 | + if(!$description){ | |
779 | + $description = $layer->getMetadata('WFS_TITLE'); | |
780 | + } | |
781 | + if(!$description){ | |
782 | + $description = $layer->getMetadata('WMS_TITLE'); | |
783 | + } | |
784 | + if(!$description){ | |
785 | + $description = $layer->name; | |
786 | + } | |
787 | + return $description; | |
788 | + } | |
789 | + | |
790 | + | |
791 | + | |
792 | + /** | |
793 | + * Add style for balloon | |
794 | + * @param string style XML id | |
795 | + * @param string column name for title | |
796 | + */ | |
797 | + function add_balloon_style(&$style, $balloon_data){ | |
798 | + $balloon =& $style->addChild('BalloonStyle'); | |
799 | + $balloon->addChild('text', htmlentities($balloon_data)); | |
800 | + } | |
801 | + | |
802 | + | |
803 | + /** | |
804 | + * Get a request parameter | |
805 | + * @param string $name | |
806 | + * @param string $default parameter optional | |
807 | + * @return string the parameter value or empty string if null | |
808 | + */ | |
809 | + function load_parm($name, $default = ''){ | |
810 | + if(!isset($_REQUEST[$name])) return $default; | |
811 | + $value = $_REQUEST[$name]; | |
812 | + if(get_magic_quotes_gpc() != 1) $value = addslashes($value); | |
813 | + //$value = escapeshellcmd($value); | |
814 | + return $value; | |
815 | + } | |
816 | + | |
817 | + /** | |
818 | + * Set error message | |
819 | + * @param string $message | |
820 | + * @param string $layer name | |
821 | + */ | |
822 | + function set_error($message, $layer = 'Error'){ | |
823 | + $this->errors[$layer][] = $message; | |
824 | + } | |
825 | + | |
826 | + | |
827 | + /** | |
828 | + * Load the map and create the map instance | |
829 | + */ | |
830 | + function load_map(){ | |
831 | + if(!file_exists($this->map) && is_readable($this->map)){ | |
832 | + $this->set_error('Cannot read mapfile '. $this->map); | |
833 | + } else { | |
834 | + $this->map_object = ms_newMapObj($this->map); | |
835 | + if(!$this->map_object){ | |
836 | + $this->set_error('Cannot load mapfile '. $this->map); | |
837 | + } | |
838 | + } | |
839 | + } | |
840 | + | |
841 | + /** | |
842 | + * Test if has errors | |
843 | + * @return boolean | |
844 | + */ | |
845 | + function has_error(){ | |
846 | + return count($this->errors) > 0; | |
847 | + } | |
848 | + | |
849 | + /** | |
850 | + * Add error messages to folders TAGS | |
851 | + */ | |
852 | + function add_errors(){ | |
853 | + foreach($this->errors as $layer => $errors){ | |
854 | + $folder =& $this->_xml->Document->addChild('Folder'); | |
855 | + $folder->addChild('name', $layer); | |
856 | + $folder->addChild('description', '<p>' . join("</p>\n<p>", $errors) . "</p>"); | |
857 | + } | |
858 | + return $errorxml; | |
859 | + } | |
860 | + | |
861 | + /** | |
862 | + * Fetch XML and format it | |
863 | + */ | |
864 | + function get_kml(){ | |
865 | + $doc = new DOMDocument('1.0'); | |
866 | + $doc->formatOutput = true; | |
867 | + $domnode = dom_import_simplexml($this->_xml); | |
868 | + $domnode = $doc->importNode($domnode, true); | |
869 | + $domnode = $doc->appendChild($domnode); | |
870 | + return $doc->saveXML(); | |
871 | + } | |
872 | + | |
873 | + /** | |
874 | + * Send header | |
875 | + */ | |
876 | + function send_header(){ | |
877 | + header('Content-type: application/vnd.google-earth.km'.($this->_zipped ? 'z' : 'l').'+XML'); | |
878 | + } | |
879 | + | |
880 | + /** | |
881 | + * Calculate cache file name | |
882 | + */ | |
883 | + function get_cache_file_name(){ | |
884 | + return 'cache/'. md5($_SERVER['QUERY_STRING']) . ($this->_zipped ? '.kmz' : '.kml'); | |
885 | + } | |
886 | + | |
887 | + /** | |
888 | + * Send stream | |
889 | + */ | |
890 | + function send_stream($data){ | |
891 | + $this->send_header(); | |
892 | + // Compress data | |
893 | + if($this->_zipped){ | |
894 | + include("zip.class.php"); | |
895 | + $ziper = new zipfile(); | |
896 | + $ziper->addFile($data, 'doc.kml'); | |
897 | + $data = $ziper->file(); | |
898 | + } | |
899 | + // Create cache if needed | |
900 | + if(ENABLE_CACHE && count($this->layers) == 1 && $this->layers[$this->typename]->getMetadata('KML_CACHE')) { | |
901 | + error_log( 'creating cache ' . $this->get_cache_file_name() ); | |
902 | + file_put_contents($this->get_cache_file_name(), $data); | |
903 | + } | |
904 | + print $data; | |
905 | + exit(); | |
906 | + } | |
907 | +} | |
908 | +?> | |
0 | 909 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,210 @@ |
1 | +<?php | |
2 | +/** | |
3 | +* Mapserver wrapper to symbol icons | |
4 | +* | |
5 | +* Returns an image for the symbol | |
6 | +* | |
7 | +* <pre> | |
8 | +* accepted parameters (case insensitive): | |
9 | +* - map = string - path to mapfile | |
10 | +* - typename = string - layer name | |
11 | +* - classname = string - class name | |
12 | +* </pre> | |
13 | +* | |
14 | +* @author Alessandro Pasotti | |
15 | +* @copyright 2007 ItOpen.it - All rights reserved | |
16 | +* @package KMLSERVER | |
17 | + | |
18 | +This file is part of KMLMAPSERVER. | |
19 | + | |
20 | + KMLMAPSERVER is free software; you can redistribute it and/or modify | |
21 | + it under the terms of the GNU Lesser General Public License as published by | |
22 | + the Free Software Foundation; either version 3 of the License, or | |
23 | + (at your option) any later version. | |
24 | + | |
25 | + KMLMAPSERVER is distributed in the hope that it will be useful, | |
26 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | + GNU Lesser General Public License for more details. | |
29 | + | |
30 | + You should have received a copy of the GNU Lesser General Public License | |
31 | + along with KMLMAPSERVER; if not, write to the Free Software | |
32 | + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
33 | + | |
34 | +*/ | |
35 | + | |
36 | +class SymbolServer { | |
37 | + | |
38 | + /** map file path */ | |
39 | + var $map; | |
40 | + | |
41 | + /** map instance */ | |
42 | + var $map_object; | |
43 | + | |
44 | + /** layer name */ | |
45 | + var $typename; | |
46 | + | |
47 | + /** class */ | |
48 | + var $classname; | |
49 | + | |
50 | + /** class index */ | |
51 | + var $classindex; | |
52 | + | |
53 | + /** icon_layer */ | |
54 | + var $icon_layer; | |
55 | + | |
56 | + /** icon point object */ | |
57 | + var $iconpoint; | |
58 | + | |
59 | + | |
60 | + function SymbolServer(){ | |
61 | + $this->errors = array(); | |
62 | + // Load request parameters | |
63 | + $this->get_request(); | |
64 | + // Load map | |
65 | + if(!$this->has_error()) { | |
66 | + $this->load_map(); | |
67 | + } | |
68 | + } | |
69 | + | |
70 | + /** | |
71 | + * Run the server and sends data | |
72 | + * @return string or void | |
73 | + */ | |
74 | + function run(){ | |
75 | + // Process request | |
76 | + if(!$this->has_error()) { | |
77 | + $this->process_request(); | |
78 | + } | |
79 | + if($this->has_error()){ | |
80 | + $this->send_errors(); | |
81 | + } else { | |
82 | + $this->send_icon(); | |
83 | + } | |
84 | + } | |
85 | + | |
86 | + | |
87 | + /** | |
88 | + * Process request | |
89 | + */ | |
90 | + function process_request(){ | |
91 | + $layer = @$this->map_object->getLayerByName($this->typename); | |
92 | + if(!$layer){ | |
93 | + $this->set_error('Layer not found ' . $layer_name, $layer_name); | |
94 | + return false; | |
95 | + } | |
96 | + // Get class | |
97 | + $class = null; | |
98 | + for($i = 0; $i < $layer->numclasses; $i++){ | |
99 | + $_class = @$layer->getClass($i); | |
100 | + if($this->classname == $_class->name){ | |
101 | + $class =& $_class; | |
102 | + $this->classindex = $i; | |
103 | + break; | |
104 | + } | |
105 | + } | |
106 | + if(!$class){ | |
107 | + $this->set_error('Class name not found ' . $layer_name, $this->classname); | |
108 | + return false; | |
109 | + } | |
110 | + // Get symbol size | |
111 | + for($i = 0; $i < $class->numstyles; $i++){ | |
112 | + $_style = @$class->getStyle($i); | |
113 | + if($_style->symbolname){ | |
114 | + // 64 pixel is standard Google Earth pushpin | |
115 | + //$_style->set('size', 64); | |
116 | + $symbolsize = $_style->size; | |
117 | + break; | |
118 | + } | |
119 | + } | |
120 | + // Provide a default here | |
121 | + if(!$symbolsize) { | |
122 | + $symbolsize = 10; | |
123 | + } | |
124 | + $ext = $this->map_object->extent; | |
125 | + $centerx = ($ext->maxx - $ext->minx)/2; | |
126 | + $centery = ($ext->maxy - $ext->miny)/2; | |
127 | + | |
128 | + // Create a new layer | |
129 | + $this->icon_layer = ms_newLayerObj($this->map_object, $layer); | |
130 | + $this->map_object->setSize($symbolsize, $symbolsize); | |
131 | + $this->map_object->setExtent($centerx - $symbolsize, $centery - $symbolsize, $centerx + $symbolsize, $centery + $symbolsize); | |
132 | + $this->icon_layer->set( 'status', MS_ON ); | |
133 | + $this->iconpoint = ms_newPointObj(); | |
134 | + $this->iconpoint->setXY($centerx, $centery); | |
135 | + } | |
136 | + | |
137 | + /** | |
138 | + * Test if has errors | |
139 | + * @return boolean | |
140 | + */ | |
141 | + function has_error(){ | |
142 | + return count($this->errors) > 0; | |
143 | + } | |
144 | + | |
145 | + /** | |
146 | + * Get all request parameters | |
147 | + */ | |
148 | + function get_request(){ | |
149 | + $this->map = $this->load_parm('map'); | |
150 | + $this->typename = $this->load_parm('typename'); | |
151 | + $this->classname= $this->load_parm('classname'); | |
152 | + if(!$this->map){ | |
153 | + $this->set_error('No mapfile specified'); | |
154 | + } | |
155 | + if(!$this->typename){ | |
156 | + $this->set_error('No typename (layer) specified'); | |
157 | + } | |
158 | + } | |
159 | + | |
160 | + /** | |
161 | + * Get a request parameter | |
162 | + * @param string $name | |
163 | + * @return string the parameter value or empty string if null | |
164 | + */ | |
165 | + function load_parm($name){ | |
166 | + if(!isset($_REQUEST[$name])) return ''; | |
167 | + $value = $_REQUEST[$name]; | |
168 | + if(get_magic_quotes_gpc() != 1) $value = addslashes($value); | |
169 | + //$value = escapeshellcmd($value); | |
170 | + return $value; | |
171 | + } | |
172 | + | |
173 | + /** | |
174 | + * Set error message | |
175 | + * @param string $message | |
176 | + * @param string $layer name | |
177 | + */ | |
178 | + function set_error($message, $layer = 'Error'){ | |
179 | + $this->errors[$layer][] = $message; | |
180 | + } | |
181 | + | |
182 | + /** | |
183 | + * Load the map and create the map instance | |
184 | + */ | |
185 | + function load_map(){ | |
186 | + if(!file_exists($this->map) && is_readable($this->map)){ | |
187 | + $this->set_error('Cannot read mapfile '. $this->map); | |
188 | + } else { | |
189 | + $this->map_object = ms_newMapObj($this->map); | |
190 | + if(!$this->map_object){ | |
191 | + $this->set_error('Cannot load mapfile '. $this->map); | |
192 | + } | |
193 | + } | |
194 | + } | |
195 | + | |
196 | + function send_errors(){ | |
197 | + print_r($this->errors); | |
198 | + } | |
199 | + | |
200 | + function send_icon(){ | |
201 | + header('Content-type:image/png'); | |
202 | + // Set transparency (needs imageformat RBGA in the mapfile too) | |
203 | + $this->map_object->set('transparent', 'on'); | |
204 | + $img = $this->map_object->draw(); | |
205 | + $this->iconpoint->draw($this->map_object, $this->icon_layer, $img, $this->classindex, ''); | |
206 | + $img->saveImage(''); | |
207 | + } | |
208 | + | |
209 | +} | |
210 | +?> | |
0 | 211 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,230 @@ |
1 | +<?php | |
2 | +/** | |
3 | +* Zip file creation class. | |
4 | +* Makes zip files. | |
5 | +* | |
6 | +* Last Modification and Extension By : | |
7 | +* | |
8 | +* Hasin Hayder | |
9 | +* HomePage : www.hasinme.info | |
10 | +* Email : countdraculla@gmail.com | |
11 | +* IDE : PHP Designer 2005 | |
12 | +* | |
13 | +* | |
14 | +* Originally Based on : | |
15 | +* | |
16 | +* http://www.zend.com/codex.php?id=535&single=1 | |
17 | +* By Eric Mueller <eric@themepark.com> | |
18 | +* | |
19 | +* http://www.zend.com/codex.php?id=470&single=1 | |
20 | +* by Denis125 <webmaster@atlant.ru> | |
21 | +* | |
22 | +* a patch from Peter Listiak <mlady@users.sourceforge.net> for last modified | |
23 | +* date and time of the compressed file | |
24 | +* | |
25 | +* Official ZIP file format: http://www.pkware.com/appnote.txt | |
26 | +* | |
27 | +* @access public | |
28 | +*/ | |
29 | +class zipfile | |
30 | +{ | |
31 | + /** | |
32 | + * Array to store compressed data | |
33 | + * | |
34 | + * @var array $datasec | |
35 | + */ | |
36 | + var $datasec = array(); | |
37 | + | |
38 | + /** | |
39 | + * Central directory | |
40 | + * | |
41 | + * @var array $ctrl_dir | |
42 | + */ | |
43 | + var $ctrl_dir = array(); | |
44 | + | |
45 | + /** | |
46 | + * End of central directory record | |
47 | + * | |
48 | + * @var string $eof_ctrl_dir | |
49 | + */ | |
50 | + var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; | |
51 | + | |
52 | + /** | |
53 | + * Last offset position | |
54 | + * | |
55 | + * @var integer $old_offset | |
56 | + */ | |
57 | + var $old_offset = 0; | |
58 | + | |
59 | + | |
60 | + /** | |
61 | + * Converts an Unix timestamp to a four byte DOS date and time format (date | |
62 | + * in high two bytes, time in low two bytes allowing magnitude comparison). | |
63 | + * | |
64 | + * @param integer the current Unix timestamp | |
65 | + * | |
66 | + * @return integer the current date in a four byte DOS format | |
67 | + * | |
68 | + * @access private | |
69 | + */ | |
70 | + function unix2DosTime($unixtime = 0) { | |
71 | + $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime); | |
72 | + | |
73 | + if ($timearray['year'] < 1980) { | |
74 | + $timearray['year'] = 1980; | |
75 | + $timearray['mon'] = 1; | |
76 | + $timearray['mday'] = 1; | |
77 | + $timearray['hours'] = 0; | |
78 | + $timearray['minutes'] = 0; | |
79 | + $timearray['seconds'] = 0; | |
80 | + } // end if | |
81 | + | |
82 | + return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | | |
83 | + ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); | |
84 | + } // end of the 'unix2DosTime()' method | |
85 | + | |
86 | + | |
87 | + /** | |
88 | + * Adds "file" to archive | |
89 | + * | |
90 | + * @param string file contents | |
91 | + * @param string name of the file in the archive (may contains the path) | |
92 | + * @param integer the current timestamp | |
93 | + * | |
94 | + * @access public | |
95 | + */ | |
96 | + function addFile($data, $name, $time = 0) | |
97 | + { | |
98 | + $name = str_replace('\\', '/', $name); | |
99 | + | |
100 | + $dtime = dechex($this->unix2DosTime($time)); | |
101 | + $hexdtime = '\x' . $dtime[6] . $dtime[7] | |
102 | + . '\x' . $dtime[4] . $dtime[5] | |
103 | + . '\x' . $dtime[2] . $dtime[3] | |
104 | + . '\x' . $dtime[0] . $dtime[1]; | |
105 | + eval('$hexdtime = "' . $hexdtime . '";'); | |
106 | + | |
107 | + $fr = "\x50\x4b\x03\x04"; | |
108 | + $fr .= "\x14\x00"; // ver needed to extract | |
109 | + $fr .= "\x00\x00"; // gen purpose bit flag | |
110 | + $fr .= "\x08\x00"; // compression method | |
111 | + $fr .= $hexdtime; // last mod time and date | |
112 | + | |
113 | + // "local file header" segment | |
114 | + $unc_len = strlen($data); | |
115 | + $crc = crc32($data); | |
116 | + $zdata = gzcompress($data); | |
117 | + $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug | |
118 | + $c_len = strlen($zdata); | |
119 | + $fr .= pack('V', $crc); // crc32 | |
120 | + $fr .= pack('V', $c_len); // compressed filesize | |
121 | + $fr .= pack('V', $unc_len); // uncompressed filesize | |
122 | + $fr .= pack('v', strlen($name)); // length of filename | |
123 | + $fr .= pack('v', 0); // extra field length | |
124 | + $fr .= $name; | |
125 | + | |
126 | + // "file data" segment | |
127 | + $fr .= $zdata; | |
128 | + | |
129 | + // "data descriptor" segment (optional but necessary if archive is not | |
130 | + // served as file) | |
131 | + $fr .= pack('V', $crc); // crc32 | |
132 | + $fr .= pack('V', $c_len); // compressed filesize | |
133 | + $fr .= pack('V', $unc_len); // uncompressed filesize | |
134 | + | |
135 | + // add this entry to array | |
136 | + $this -> datasec[] = $fr; | |
137 | + | |
138 | + // now add to central directory record | |
139 | + $cdrec = "\x50\x4b\x01\x02"; | |
140 | + $cdrec .= "\x00\x00"; // version made by | |
141 | + $cdrec .= "\x14\x00"; // version needed to extract | |
142 | + $cdrec .= "\x00\x00"; // gen purpose bit flag | |
143 | + $cdrec .= "\x08\x00"; // compression method | |
144 | + $cdrec .= $hexdtime; // last mod time & date | |
145 | + $cdrec .= pack('V', $crc); // crc32 | |
146 | + $cdrec .= pack('V', $c_len); // compressed filesize | |
147 | + $cdrec .= pack('V', $unc_len); // uncompressed filesize | |
148 | + $cdrec .= pack('v', strlen($name) ); // length of filename | |
149 | + $cdrec .= pack('v', 0 ); // extra field length | |
150 | + $cdrec .= pack('v', 0 ); // file comment length | |
151 | + $cdrec .= pack('v', 0 ); // disk number start | |
152 | + $cdrec .= pack('v', 0 ); // internal file attributes | |
153 | + $cdrec .= pack('V', 32 ); // external file attributes - 'archive' bit set | |
154 | + | |
155 | + $cdrec .= pack('V', $this -> old_offset ); // relative offset of local header | |
156 | + $this -> old_offset += strlen($fr); | |
157 | + | |
158 | + $cdrec .= $name; | |
159 | + | |
160 | + // optional extra field, file comment goes here | |
161 | + // save to central directory | |
162 | + $this -> ctrl_dir[] = $cdrec; | |
163 | + } // end of the 'addFile()' method | |
164 | + | |
165 | + | |
166 | + /** | |
167 | + * Dumps out file | |
168 | + * | |
169 | + * @return string the zipped file | |
170 | + * | |
171 | + * @access public | |
172 | + */ | |
173 | + function file() | |
174 | + { | |
175 | + $data = implode('', $this -> datasec); | |
176 | + $ctrldir = implode('', $this -> ctrl_dir); | |
177 | + | |
178 | + return | |
179 | + $data . | |
180 | + $ctrldir . | |
181 | + $this -> eof_ctrl_dir . | |
182 | + pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk" | |
183 | + pack('v', sizeof($this -> ctrl_dir)) . // total # of entries overall | |
184 | + pack('V', strlen($ctrldir)) . // size of central dir | |
185 | + pack('V', strlen($data)) . // offset to start of central dir | |
186 | + "\x00\x00"; // .zip file comment length | |
187 | + } // end of the 'file()' method | |
188 | + | |
189 | + | |
190 | + /** | |
191 | + * A Wrapper of original addFile Function | |
192 | + * | |
193 | + * Created By Hasin Hayder at 29th Jan, 1:29 AM | |
194 | + * | |
195 | + * @param array An Array of files with relative/absolute path to be added in Zip File | |
196 | + * | |
197 | + * @access public | |
198 | + */ | |
199 | + function addFiles($files /*Only Pass Array*/) | |
200 | + { | |
201 | + foreach($files as $file) | |
202 | + { | |
203 | + if (is_file($file)) //directory check | |
204 | + { | |
205 | + $data = implode("",file($file)); | |
206 | + $this->addFile($data,$file); | |
207 | + } | |
208 | + } | |
209 | + } | |
210 | + | |
211 | + /** | |
212 | + * A Wrapper of original file Function | |
213 | + * | |
214 | + * Created By Hasin Hayder at 29th Jan, 1:29 AM | |
215 | + * | |
216 | + * @param string Output file name | |
217 | + * | |
218 | + * @access public | |
219 | + */ | |
220 | + function output($file) | |
221 | + { | |
222 | + $fp=fopen($file,"w"); | |
223 | + fwrite($fp,$this->file()); | |
224 | + fclose($fp); | |
225 | + } | |
226 | + | |
227 | + | |
228 | + | |
229 | +} // end of the 'zipfile' class | |
230 | +?> | |
0 | 231 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,30 @@ |
1 | +<?php | |
2 | +/** | |
3 | +* KML server | |
4 | +* | |
5 | +* @author Alessandro Pasotti | |
6 | +* @copyright 2007 ItOpen.it - All rights reserved | |
7 | +* @package KMLSERVER | |
8 | + | |
9 | +This file is part of KMLMAPSERVER. | |
10 | + | |
11 | + KMLMAPSERVER is free software; you can redistribute it and/or modify | |
12 | + it under the terms of the GNU Lesser General Public License as published by | |
13 | + the Free Software Foundation; either version 3 of the License, or | |
14 | + (at your option) any later version. | |
15 | + | |
16 | + KMLMAPSERVER is distributed in the hope that it will be useful, | |
17 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | + GNU Lesser General Public License for more details. | |
20 | + | |
21 | + You should have received a copy of the GNU Lesser General Public License | |
22 | + along with KMLMAPSERVER; if not, write to the Free Software | |
23 | + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
24 | + | |
25 | +*/ | |
26 | + | |
27 | +set_time_limit(0); | |
28 | +include 'classes/kmlserver.class.php'; | |
29 | +$server = new KmlServer(); | |
30 | +?> | |
0 | 31 | \ No newline at end of file | ... | ... |