diff --git a/pacotes/kmlmapserver/LICENCE b/pacotes/kmlmapserver/LICENCE
new file mode 100644
index 0000000..853047c
--- /dev/null
+++ b/pacotes/kmlmapserver/LICENCE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/pacotes/kmlmapserver/README b/pacotes/kmlmapserver/README
new file mode 100644
index 0000000..f0b705a
--- /dev/null
+++ b/pacotes/kmlmapserver/README
@@ -0,0 +1,92 @@
+KML mapserver wrapper
+-------------------------------------
+
+* What is this thing?
+ this is a wrapper around UNM Mapserver, to serve KML data in a WFS-like manner
+
+* Requirements
+ PHP5 with simplexml
+
+* Configuration
+ Configuration is done through CGI-style calls and through some optional metadata in the mapfile
+
+ METADATA:
+ RESULT_FIELDS # from which field take the name for the feature
+ # defaults to the first field
+
+ DESCRIPTION_TEMPLATE # if present, this is used for placemark features
+ # tooltip. Parameters surrounded by "%" char are substituted
+ # with real values from the corresponding field for the feature
+
+ DESCRIPTION # All those metadata are searched (in this order) to get a layer
+ OWS_TITLE # description
+ WFS_TITLE
+ WMS_TITLE
+
+ KML_CACHE # number of second the cache will lasts
+ # if empty or not exists, the cache will be disabled for that layer
+
+ KML_SKIP # if equals to "true", kml output is disabled for this layer,
+ # default is false
+
+ KML_ADD_POINT # If not empty, add a point with balloon to start and end
+ # line geometries. Value is the icon url.
+
+
+ CGI-PARAMETERS:
+ * - request = string - optional - request type (OGC WFS like)
+ * - map = string - required - path to mapfile
+ * - typename = string - optional - (can be a csv list) - layer name(s), if empty, all layers are returned
+ * - filter = string - optional - filter encoding (single layer requests only)
+ * - bbox = string - optional - standard bbox specification (Not yet implemented)
+ * - encoding = string - optional - default to ISO-8859-1
+
+* Filters
+ Only PropertyIsEqualTo and PropertyIsLike are supported ATM.
+
+* Encoding
+ 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.
+
+* Raster support
+ Raster layer are supported as standard WMS network links, it is necessary to add EPSG:4326 to WMS_SRS metadata on all mapfile layers.
+ Mapfile must be correctly configured as WMS server (i.e. all required metadata must be set).
+
+* KMZ compressed output
+
+* Styles and classes
+ There is limited support for classes and style:
+ * only one style for each class is parsed, if you have multiple styles in one class, the values of the last one are used
+ * only color, outlinecolor, backgroundcolor, symbol, size and width are parsed
+
+* Cache
+ A simple caching for single layer requests is available.
+ If you want to use the cache, set KML_CACHE layer metadata to the number of seconds the cache should last.
+ A web server writeable "cache" directory must exists at the same level of the main script
+
+* Know issues
+ * Filled polygons fail to wrap on the mountains (this seems a GE bug), a define('TREAT_POLY_AS_LINE', true) control this behaviour
+
+EXAMPLE CALLS
+------------------------------------
+Single layer:
+http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map&typename=sfumo,vngeo_ospitalita
+
+Two layers (one raster and one vector):
+http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map&typename=vngeo_ospitalita
+
+All layers as network links:
+http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map
+
+Single layer with filter:
+http://localhost/kmlserver/service.php?map=/map/mapfile-ogc.map&typename=comuni&filter=toponimoRiederalp
+
+
+ICON SERVER
+-------------------------------------
+Returns a PNG icon for a give poin layer/class combination
+Example calls:
+http://localhost/kmlserver/symbolservice.php?map=/map/mapfile-ogc.map&typename=vngeo_ospitalita&class=Alberghi
+
+If you want transparent icons, set PNG output format to RGBA and IMAGECOLOR to the transparent color
+
+
diff --git a/pacotes/kmlmapserver/cache/index.html b/pacotes/kmlmapserver/cache/index.html
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/pacotes/kmlmapserver/cache/index.html
diff --git a/pacotes/kmlmapserver/classes/kmlserver.class.php b/pacotes/kmlmapserver/classes/kmlserver.class.php
new file mode 100644
index 0000000..0770e16
--- /dev/null
+++ b/pacotes/kmlmapserver/classes/kmlserver.class.php
@@ -0,0 +1,102 @@
+
+* accepted parameters (case insensitive):
+* - request = string - request type (OGC WFS like), can be kml (default), kmz, icon
+* - map = string - path to mapfile
+* - typename = string - (can be a csv list) - layer name(s)
+* - filter = string - filter encoding
+* - bbox = string - (csv) - bounding box csv
+*
+*
+*
+*
+* @author Alessandro Pasotti
+* @copyright 2007 ItOpen.it - All rights reserved
+* @package KMLMAPSERVER
+
+This file is part of KMLMAPSERVER.
+
+ KMLMAPSERVER is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ KMLMAPSERVER is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with KMLMAPSERVER; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+
+if (!extension_loaded('MapScript'))
+{
+ dl( 'php_mapscript.' . PHP_SHLIB_SUFFIX );
+}
+
+
+/**
+* Main server class, wraps real kml or icon servers
+*/
+
+class KmlServer {
+
+ /** server instance */
+ var $service;
+
+ /** request */
+ var $request;
+
+ /** debug flag */
+ var $_debug = false;
+
+ /**
+ * Initialize
+ *
+ */
+ function KmlServer(){
+ $this->get_request();
+ if($this->service == 'icon'){
+ include 'symbolserver.class.php';
+ $this->service = new SymbolServer();
+ $this->service->run();
+ } else {
+ include 'layerserver.class.php';
+ $this->service = new LayerServer();
+ $this->service->run();
+ }
+ }
+
+ /**
+ * Get all request parameters
+ */
+ function get_request(){
+ $this->service = $this->load_parm('service');
+ if(!$this->service){
+ $this->service= 'kml';
+ }
+ }
+
+ /**
+ * Get a request parameter
+ * @param string $name
+ * @return string the parameter value or empty string if null
+ */
+ function load_parm($name){
+ if(!isset($_REQUEST[$name])) return '';
+ $value = $_REQUEST[$name];
+ if(get_magic_quotes_gpc() != 1) $value = addslashes($value);
+ //$value = escapeshellcmd($value);
+ return $value;
+ }
+}
+?>
\ No newline at end of file
diff --git a/pacotes/kmlmapserver/classes/layerserver.class.php b/pacotes/kmlmapserver/classes/layerserver.class.php
new file mode 100644
index 0000000..1116b2b
--- /dev/null
+++ b/pacotes/kmlmapserver/classes/layerserver.class.php
@@ -0,0 +1,908 @@
+
+* accepted parameters (case insensitive):
+* - request = string - request type (OGC WFS like), can be kml (default), kmz, icon
+* - map = string - path to mapfile
+* - typename = string - (can be a csv list) - layer name(s)
+* - filter = string - filter encoding
+* - bbox = string - (csv) - bounding box csv
+* - encoding = string - data and mapfile encoding, defaults to ISO-8859-1
+*
+*
+*
+*
+* @author Alessandro Pasotti
+* @copyright 2007 ItOpen.it - All rights reserved
+* @package KMLMAPSERVER
+
+This file is part of KMLMAPSERVER.
+
+ KMLMAPSERVER is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ KMLMAPSERVER is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with KMLMAPSERVER; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+
+/** Fix a GE bug for filled polygons */
+define('TREAT_POLY_AS_LINE', true);
+
+/** Enable cache */
+define('ENABLE_CACHE', true);
+
+if (!extension_loaded('MapScript'))
+{
+ dl( 'php_mapscript.' . PHP_SHLIB_SUFFIX );
+}
+
+
+/**
+* Main server class
+*/
+
+class LayerServer {
+
+ /** map file path */
+ var $map;
+
+ /** request */
+ var $request;
+
+ /** map instance */
+ var $map_object;
+
+ /** layer name(s) passed on the request */
+ var $typename;
+
+ /** array of requested layer objects (hash with layer name as key) */
+ var $layers;
+
+ /** filters */
+ var $filter;
+
+ /** bounding box */
+ var $bbox;
+
+ /** error messages */
+ var $errors;
+
+ /** send zipped data */
+ var $_zipped = false;
+
+ /** internal XML buffer */
+ var $_xml;
+
+ /** input projection */
+ var $in_proj;
+
+ /** output projection */
+ var $out_proj;
+
+ /** debug flag */
+ var $_debug = false;
+
+ /** end point */
+ var $endpoint;
+
+ /** custom style counter */
+ var $style_counter = 0;
+
+ /**
+ * Mapfile and data encoding encoding
+ * XMl output must be UTF-8, attributes and METADATA based strings
+ * must be converted to UTF-8, encoding defaults to ISO-8859-1, if
+ * your encoding is different, you can set it through CGI style parameters
+ */
+ var $encoding;
+
+ /**
+ * send networklink
+ * wether folder should contain networklinks instead of real geometries
+ * it is automatically set when all layers are requested
+ */
+ var $_networklink;
+
+
+ /**
+ * Initialize
+ *
+ */
+ function LayerServer(){
+ $this->errors = array();
+ // Load request parameters
+ $this->get_request();
+
+ $this->style_counter = 0;
+
+ // Load map
+ if(!$this->has_error()) {
+ $this->load_map();
+ }
+
+ }
+
+ /**
+ * Run the server and sends data
+ * @return string or void
+ */
+ function run(){
+ // Check cache
+ if(ENABLE_CACHE){
+ $cache_file = $this->get_cache_file_name();
+ if(file_exists($cache_file)){
+ // Check if is not expired
+ $layer = $this->map_object->getLayerByName($this->typename);
+ if(filectime($cache_file) + $layer->getMetadata('KML_CACHE') < (time())) {
+ error_log('removing cache ' . $cache_file);
+ //error_log('ctime : ' . filectime($cache_file) . ' , ' . time() . ' lm ' . $layer->getMetadata('KML_CACHE'));
+ @unlink($cache_file);
+ } else {
+ $this->send_header();
+ error_log('sending cache ' . $cache_file);
+ readfile($cache_file);
+ exit;
+ }
+ }
+ }
+
+ // If not layer are requested, send all as networklinks
+ if(!$this->typename){
+ $this->_networklink = true;
+ $this->typename = $this->get_layer_list();
+ } else {
+ $this->_networklink = false;
+ }
+
+ $this->_xml = new SimpleXMLElement('');
+ // Prepare projection
+ $this->in_proj = ms_newProjectionObj($this->map_object->getProjection());
+ // Set projection to GOOGLE earth's projection
+ $this->out_proj = ms_newProjectionObj("init=epsg:4326");
+ // Set endpoint
+ //die($_SERVER['REQUEST_URI']);
+ $this->endpoint = ($_SERVER['HTTPS'] ? 'https' : 'http') . '://'.$_SERVER['SERVER_NAME'] . ($_SERVER['SERVER_PORT'] ? ':'.$_SERVER['SERVER_PORT'] : '') . $_SERVER['PHP_SELF'];
+
+
+ // Process request
+ if(!$this->has_error()) {
+ $this->process_request();
+ }
+ if($this->has_error()){
+ $this->add_errors();
+ }
+ return $this->send_stream($this->get_kml());
+ }
+
+ /**
+ * Set debug flag
+ * @param boolean $value
+ */
+ function set_debug($value){
+ $this->_debug = $value;
+ }
+
+ /**
+ * Get all request parameters
+ */
+ function get_request(){
+ $this->map = $this->load_parm('map');
+ $this->bbox = $this->load_parm('bbox');
+ $this->filter = $this->load_parm('filter');
+ $this->typename = $this->load_parm('typename');
+ $this->encoding = $this->load_parm('encoding', 'ISO-8859-1');
+ $this->request = $this->load_parm('request', 'kml');
+
+ if($this->request == 'kmz') {
+ $this->_zipped = true;
+ }
+
+ if(!$this->map){
+ $this->set_error('No mapfile specified');
+ }
+ }
+
+ /**
+ * Apply filter
+ * @return array
+ */
+ function apply_filter(&$layer, &$filter){
+ if($layer->connectiontype == MS_POSTGIS){
+ if($filter->PropertyIsEqualTo){
+ $searchstring = '"'.$filter->PropertyIsEqualTo->PropertyName . ' = ' . '\''.addslashes($filter->PropertyIsEqualTo->Literal).'\''.'"';
+ $searchfield = $filter->PropertyIsEqualTo->PropertyName;
+ } elseif($filter->PropertyIsLike){
+ $searchfield = $filter->PropertyIsLike->PropertyName;
+ $searchstring ='"'.$filter->PropertyIsLike->PropertyName . ' LIKE \'%' . addslashes($filter->PropertyIsLike->Literal) . '%\''.'"';
+ }
+ } elseif($layer->connectiontype == MS_SHAPEFILE || $layer->connectiontype == MS_OGR){
+ if($filter->PropertyIsEqualTo){
+ $searchstring = $filter->PropertyIsEqualTo->Literal;
+ $searchfield = $filter->PropertyIsEqualTo->PropertyName;
+ } elseif($filter->PropertyIsLike){
+ $searchstring = $filter->PropertyIsLike->Literal;
+ $searchfield = $filter->PropertyIsLike->PropertyName;
+ }
+ }
+ return array($searchfield, $searchstring);
+ }
+
+ /**
+ * Process request
+ */
+ function process_request(){
+ // Get layer(s)
+ $layers = split(',', $this->typename);
+ if($this->_networklink){
+ foreach($layers as $layer){
+ $this->add_networklink($layer);
+ }
+ } else {
+ foreach($layers as $layer){
+ $this->process_layer_request($layer);
+ }
+ }
+ }
+
+ /**
+ * Add a networklink
+ */
+ function add_networklink(&$layer_name){
+ $nl =& $this->_xml->Document->addChild('NetworkLink');
+
+ $layer = @$this->map_object->getLayerByName($layer_name);
+ $nl->addChild('name', $this->get_layer_description($layer));
+ $nl->addChild('visibility', 0);
+ $link =& $nl->addChild('Link');
+ $link->addChild('href', $this->endpoint . '?map=' . $this->map . '&typename=' . urlencode($layer_name) . '&request=' . ($this->_zipped ? 'kmz' : 'kml'));
+ }
+
+
+ /**
+ * Process a single layer
+ * @return boolean false on error
+ */
+ function process_layer_request(&$layer_name){
+
+ $layer = @$this->map_object->getLayerByName($layer_name);
+
+ if(!$layer){
+ $this->set_error('Layer not found ' . $layer_name, $layer_name);
+ return false;
+ }
+
+ // Add to layer list
+ $this->layers[$layer_name] =& $layer;
+
+ // Get custom template if any
+ $description_template = $layer->getMetadata('DESCRIPTION_TEMPLATE');
+
+ // Set on
+ $layer->set( 'status', MS_ON );
+
+ // Set kml title from layer description (default to layer name)
+ $layer_desc = $this->get_layer_description($layer);
+
+ // Now switch raster layers
+ //var_dump($layer->type == MS_LAYER_RASTER);
+ if($layer->type == MS_LAYER_RASTER){
+ // Check if wms_onlineresource metadata is set
+ $wms_link = $this->map_object->getMetadata('wms_onlineresource');
+ if(!$wms_link){
+ $wms_link = $this->map_object->getMetadata('ows_onlineresource');
+ }
+ if(!$wms_link){
+ $this->set_error('No WMS server available for ' . $layer_name, $layer_name);
+ return false;
+ }
+ // Add parameters to OGC server call
+ // Fix &
+ $wms_link = preg_replace('/&/', '&', $wms_link);
+ $wms_link .= 'VERSION=1.1.1&REQUEST=GetMap&SRS=EPSG:4326&STYLES=&BGCOLOR=0xFFFFFF&FORMAT=image/png&TRANSPARENT=TRUE&';
+ // Link ok, create folder
+ $folder =& $this->_xml->Document->addChild('GroundOverlay');
+ $folder->addChild('description', $this->get_layer_description($layer));
+ $folder->addChild('name', $layer_desc);
+ $this->add_wms_link($folder, $layer, $wms_link);
+ } else {
+
+ // Apply filter
+ if($this->filter){
+ // Try loading as XML
+ try {
+ $filter = @new SimpleXMLElement($this->filter);
+ list($searchfield, $searchstring) = $this->apply_filter($layer, $filter);
+ if(! ($searchfield && $searchstring)){
+ $this->set_error('Error parsing filter', $layer_name);
+ return false;
+ }
+ } catch (Exception $e) {
+ $this->set_error('Wrong XML filter', $layer_name);
+ $this->filter = null;
+ return false;
+ }
+ }
+
+ // Get results
+ if(MS_SUCCESS == $layer->open()){
+ // Search which column to use to identify the feature
+ $namecol = $layer->getMetadata('RESULT_FIELDS');
+ if(!$namecol){
+ $cols = array_values($layer->getItems());
+ $namecol = $cols[0];
+ }
+ // Add classes
+ $folder =& $this->_xml->Document->addChild('Folder');
+ $class_list = $this->parse_classes($layer, $folder, $namecol, $title_field, $description_template);
+
+ //die(print_r($class_list, true));
+ $folder->addChild('description', $this->get_layer_description($layer));
+ $folder->addChild('name', $layer_desc);
+
+ //print("$searchfield && $searchstring");
+ if($searchfield && $searchstring){
+ if(@$layer->queryByAttributes($searchfield, $searchstring, MS_MULTIPLE) == MS_SUCCESS){
+ $layer->open();
+ //var_dump($layer->getItems()); die();
+ for ($j=0; $j < $layer->getNumResults(); $j++)
+ {
+ // get next shape row
+ $result = $layer->getResult($j);
+ $shape = $layer->getShape($result->tileindex, $result->shapeindex);
+ $this->process_shape($layer, $shape, $class_list, $folder, $namecol);
+ // end for loop
+ }
+ } else {
+ $this->set_error('Query returned no data', $layer_name);
+ return false;
+ }
+ } else { // Get all shapes
+ $status = $layer->whichShapes($this->map_object->extent);
+ while ($shape = $layer->nextShape()) {
+ $this->process_shape($layer, $shape, $class_list, $folder,$namecol );
+ }
+ }
+ $layer->close();
+ } else {
+ $this->set_error('Layer cannot be opened', $layer_name);
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Process the shape
+ */
+ function process_shape(&$layer, &$shape, &$class_list, &$folder, &$namecol){
+ $shape->project($this->in_proj, $this->out_proj);
+ // Assign style
+ if($layer->classitem){
+ $style_id = $this->get_shape_class($layer->classitem, $shape->values, $class_list);
+ }
+ if(!$style_id){
+ // Get first class
+ $class_keys = array_keys($class_list);
+ $style_id = $class_keys[0];
+ }
+ // Add the feature
+ if(array_key_exists('folder', $class_list[$style_id])) {
+ $feature_folder =& $class_list[$style_id]['folder'];
+ } else {
+ //die('missing folder for ' . $style_id);
+ $feature_folder =& $folder;
+ }
+ if(!is_object($feature_folder)){
+ $folder_name = $feature_folder;
+ $feature_folder =& $folder ->addChild('Folder');
+ $feature_folder->addChild('name', $folder_name);
+ }
+ // Add style class
+ $style_url =& $this->add_style($layer, $feature_folder, $style_id, $class_list[$style_id], $namecol, $shape->values);
+
+ $wkt = $shape->toWkt();
+ $placemark =& $this->add_feature($feature_folder, $wkt, $shape->values[$namecol], $shape->values, $description_template, $class_list[$style_id]);
+
+ $placemark->addChild('styleUrl', '#'. $style_url);
+
+ }
+
+ /**
+ * Add the feature to the result set
+ * @return reference to placemark object
+ */
+ function &add_feature(&$folder, &$wkt, $featurename, $attributes, $description_template, $style_data){
+ $pm = $folder->addChild('Placemark');
+ //if($featurename == 'VERCELLI') {var_dump($wkt); die();}
+ $pm->addChild('name', iconv($this->encoding, 'utf-8', $featurename));
+ $pm->addChild('description', $this->get_feature_description($featurename, $attributes, $description_template));
+ // Now parse the wkt
+ if(strpos($wkt, 'MULTILINESTRING') !== false){
+ $this->add_multilinestring($wkt, $pm, $featurename, $style_data['icon']);
+ } elseif(strpos($wkt, 'LINESTRING') !== false){
+ $this->add_linestring($wkt, $pm, $featurename, $style_data['icon']);
+ } elseif(strpos($wkt, 'POINT') !== false){
+ $this->add_point($wkt, $pm, $featurename);
+ } elseif(strpos($wkt, 'MULTIPOLYGON') !== false){
+ if(TREAT_POLY_AS_LINE){
+ $ml = $pm->addChild('MultiGeometry');
+ foreach(split('\), \(', $wkt) as $line){
+ $this->add_multilinestring($line, $ml, $featurename );
+ }
+ } else {
+ $this->add_multipolygon($wkt, $pm, $featurename);
+ }
+ } elseif(strpos($wkt, 'POLYGON') !== false){
+ if(TREAT_POLY_AS_LINE){
+ $this->add_multilinestring($wkt, $pm, $featurename);
+ } else {
+ $this->add_polygon($wkt, $pm, $featurename);
+ }
+ } else {
+ // Error?
+ }
+ return $pm;
+ }
+
+ /**
+ * Add a linestring
+ */
+ function add_linestring(&$wkt, &$element, $featurename, $add_points){
+ preg_match('/(\d+[^\(\)]*\d)/', $wkt, $data);
+ $data = str_replace(', ', '#', $data[1]);
+ $data = str_replace(' ', ',', $data);
+ $data = str_replace('#', ' ', $data);
+ if($add_points){
+ preg_match('/^(\d+\.\d+,\d+\.\d+).*(\d+\.\d+,\d+\.\d+)$/', $data, $points);
+ if(count($points) == 3){
+ $mg = $element->addChild('MultiGeometry');
+ $ls = $mg->addChild('LineString');
+ $pt1 = $mg->addChild('Point');
+ $pt1->addChild('coordinates', $points[1]);
+ $pt2 = $mg->addChild('Point');
+ $pt2->addChild('coordinates', $points[2]);
+ } else {
+ die('errore');
+ $ls = $element->addChild('LineString');
+ }
+ //print_r($points);die();
+ } else {
+ $ls = $element->addChild('LineString');
+ }
+ $ls->addChild('coordinates', $data);
+ }
+
+ /**
+ * Add a multilinestring
+ */
+ function add_multilinestring(&$wkt, &$element, $featurename, $add_points){
+ $ml = $element->addChild('MultiGeometry');
+ foreach(split('\), \(', $wkt) as $line){
+ $this->add_linestring($line, $ml, $featurename, $add_points );
+ }
+ }
+
+ /**
+ * Add a point
+ */
+ function add_point(&$wkt, &$element, $featurename){
+ $pt = $element->addChild('Point');
+ preg_match('/(\d\.?\d+\s\d+\.?\d+)/', $wkt, $data);
+ $data = str_replace(' ', ',', $data[1]);
+ $pt->addChild('coordinates', $data);
+ }
+
+
+ /**
+ * Add a polygon
+ */
+ function add_polygon(&$wkt, &$element, $featurename){
+ $ml = $element->addChild('Polygon');
+ foreach(split('\), \(', $wkt) as $line){
+ preg_match('/(\d+[^\(\)]*\d)/', $wkt, $data);
+ $data = str_replace(', ', '#', $data[1]);
+ $data = str_replace(' ', ',', $data);
+ // Add 1 meter height
+ $data = str_replace('#', ',1 ', $data) . ',1';
+ $ml->addChild('tessellate', 1);
+ //$element->addChild('altitudeMode', 'relativeToGround');
+ $element->addChild('altitudeMode', 'clampToGround');
+ $ob = $ml->addChild('outerBoundaryIs');
+ $ls = $ob->addChild('LinearRing');
+ $ls->addChild('coordinates', $data);
+ }
+ }
+
+
+ /**
+ * Add a multipolygon
+ * FIXME: untested, should take holes into account
+ */
+ function add_multipolygon(&$wkt, &$element, $featurename){
+ $ml = $element->addChild('MultiGeometry');
+ foreach(split('\), \(', $wkt) as $line){
+ $this->add_polygon($line, $ml, $featurename );
+ }
+ }
+
+
+ /**
+ * Get the feature description
+ */
+ function get_feature_description($featurename, $attributes, $description_template){
+ // Compute hyperlink
+ if($description_template){
+ $description = $description_template;
+ foreach($attributes as $k => $val){
+ $description = str_replace("%$k%", iconv($this->encoding, 'utf-8', $val), $description);
+ }
+ } else {
+ $description = iconv($this->encoding, 'utf-8', $featurename);
+ }
+ return htmlentities($description);
+ }
+
+
+ /**
+ * Parse classes
+ * @return array hash of 'style_id' => style_data)
+ */
+ function parse_classes(&$layer, &$folder, &$namecol, &$title_field, &$description_template ){
+ $style_ar = array();
+ $numclasses = $layer->numclasses;
+ for($i = 0; $i < $numclasses; $i++){
+ $class = $layer->getClass($i);
+ $label = $class->label;
+ if($label){
+ $style['label_color'] = $label->color;
+ $style['label_size'] = $label->size;
+ }
+ // Get styles
+ for($j = 0; $j < $class->numstyles; $j++){
+ $_style = $class->getStyle($j);
+ $style['color'] = $_style->color;
+ $style['outlinecolor'] = $_style->outlinecolor;
+ $style['width'] = $_style->size; // Lines
+ $style['backgroundcolor'] = $_style->backgroundcolor;
+ $style['icon'] = $this->get_icon_url($layer, $class->name);
+ $style['icon_width'] = $_style->size; // Points
+
+ }
+ $style['expression'] = $class->getExpression();
+ // Set description_template if any
+ $style['description_template'] = $description_template;
+ // Get icon for lines if any
+ if($icon = $layer->getMetadata('KML_ADD_POINT')){
+ $style['icon'] = $icon;
+ $style['icon_width'] = 32;
+ }
+ // Create style element
+ $style_id = preg_replace('/[^A-z0-9]/', '_', $layer->name . $class->name);
+ //$this->add_style($layer, $folder, $style_id, $style, $namecol, $title_field );
+ // create folder if more than one class
+ if($numclasses > 1){
+ $style['folder'] =& $class->name;
+ //$folder->addChild('Folder');
+ //$style['folder']->addChild('name', $class->name);
+ }
+ $style_ar[$style_id] = $style;
+ }
+ return $style_ar;
+ }
+
+ /**
+ * Return a CSV list of all layer names in the mapfile
+ * FIXME: filter out ANNOTATIONS and other "strange" layers
+ */
+ function get_layer_list(){
+ $layer_list = array();
+ for($i = 0; $i < $this->map_object->numlayers; $i++){
+ $layer =& $this->map_object->getLayer($i);
+ $kml_skip = $layer->getMetadata('KML_SKIP');
+ if(strtolower($kml_skip) !== 'true'){
+ $layer_list[] = $layer->name;
+ }
+ }
+ return join(',', $layer_list);
+ }
+
+
+ /**
+ * Return the class for the shape, default to last class if not match
+ */
+ function get_shape_class(&$classitem, &$values, &$class_list){
+ //var_dump($class_list); die();
+ foreach($class_list as $style_id => $style_data){
+ if($style_data['expression'] && preg_match($style_data['expression'], $values[$classitem])){
+ //print "get_shape_class($classitem) ".$values[$classitem]." matches
";
+ return $style_id;
+ }
+ }
+ //print "get_shape_class($classitem) ".$values[$classitem]." no matches
";
+ return $style_id;
+ }
+
+ /**
+ * Add the style
+ * @return the style URL
+ */
+ function add_style(&$layer, &$folder, $style_id, &$style_data){
+ // Calculare style URL
+ /*
+ if($style_data['description_template']){
+ $this->style_counter++;
+ $style_id .= '_'.$this->style_counter;
+ $balloon_data = $this->get_feature_description($attributes[$namecol], $attributes, $style_data['description_template']);
+ }
+ */
+ // Check if the style already exists
+ $expr = '//*[@id=\''.$style_id.'\']';
+ if($folder->xpath($expr)) {
+ return $style_id;
+ }
+ $new_style =& $folder->addChild('Style');
+ $new_style['id'] = $style_id;
+ // Switch layer type
+ switch($layer->type){
+ case MS_LAYER_POINT:
+ $this->add_style_point($new_style, $style_data);
+ break;
+ case MS_LAYER_POLYGON:
+ $this->add_style_polygon($new_style, $style_data);
+ break;
+ case MS_LAYER_LINE:
+ $this->add_style_line($new_style, $style_data);
+ // Add KML_ADD_POINT icon
+ if($style_data['icon']){
+ $this->add_style_point($new_style, $style_data);
+ }
+ break;
+ }
+ return $style_id;
+ }
+
+ /**
+ * Add style for lines
+ */
+ function add_style_line(&$new_style, &$style_data){
+ if($style_data['outlinecolor']->red != -1){
+ $st =& $new_style->addChild('LineStyle');
+ $st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['outlinecolor']->blue, $style_data['outlinecolor']->green, $style_data['outlinecolor']->red));
+ if($width) {
+ $st->addChild('width', $width);
+ }
+ } elseif($style_data['color']->red != -1){
+ $st =& $new_style->addChild('LineStyle');
+ $st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['color']->blue, $style_data['color']->green, $style_data['color']->red));
+ if($width) {
+ $st->addChild('width', $width);
+ }
+ }
+ }
+
+ /**
+ * Add style for points
+ */
+ function add_style_point(&$new_style, &$style_data){
+ if($style_data['icon']){
+ $st =& $new_style->addChild('IconStyle');
+ if($style_data['width'] && $style_data['icon_width'] != 32){
+ $st->addChild('scale', $style_data['icon_width'] / 32);
+ }
+ $icon =& $st->addChild('Icon');
+ $icon->addChild('href', htmlentities($style_data['icon']));
+ }
+ /*/ Add the balloon style if description_template is set
+ if($style_data['description_template']){
+ $this->add_balloon_style($new_style, $balloon_data);
+ }
+ */
+ // Label size and color
+ if($style_data['label_size'] || $style_data['label_color']){
+ $ls =& $new_style->addChild('LabelStyle');
+ if($style_data['label_size'] != -1 && $style_data['label_size'] != 32){
+ $ls->addChild('scale', $style_data['label_size'] / 32);
+ }
+ if($style_data['label_color']->red != -1){
+ $ls->addChild('color', sprintf('FF%02X%02X%02X', $style_data['label_color']->blue, $style_data['label_color']->green, $style_data['label_color']->red));
+ }
+ }
+ }
+
+ /**
+ * Add style for polygons
+ */
+ function add_style_polygon(&$new_style, &$style_data){
+ // Get also outline styles
+ $this->add_style_line($new_style, $style_data);
+ $st =& $new_style->addChild('PolyStyle');
+ //die(print_r($backgroundcolor, true));
+ if($style_data['backgroundcolor']->red != -1){
+ $st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['backgroundcolor']->blue, $style_data['backgroundcolor']->green, $style_data['backgroundcolor']->red));
+ $st->addChild('fill', 0);
+ } else {
+ $st->addChild('fill', 0);
+ }
+ $st->addChild('outline', 1);
+ }
+
+ /**
+ * Add a WMS raster link
+ */
+ function add_wms_link(&$folder, &$layer, &$link){
+ // Build up the KML response document.
+ $icon =& $folder->addChild('Icon');
+ $icon->addChild('href', $link . 'layers=' . $layer->name);
+ //$icon->addChild('viewBoundScale', 1.5);
+ $icon->addChild('viewRefreshMode', 'onStop');
+ $llbox =& $folder->addChild('LatLonBox');
+ $ext = $this->map_object->extent;
+ $ext->project($this->in_proj, $this->out_proj);
+ $llbox->north = $ext->maxy;
+ $llbox->south = $ext->miny;
+ $llbox->east = $ext->maxx;
+ $llbox->west = $ext->minx;
+ // Reset original projection
+ $ext->project($this->out_proj, $this->in_proj);
+ }
+
+ /**
+ * Get the url for a point icon
+ */
+ function get_icon_url($layer, $classname){
+ return $this->endpoint . '?service=icon&map=' . $this->map . '&typename=' . urlencode($layer->name) . '&classname=' . urlencode($classname);
+ }
+
+ /**
+ * Get the layer description
+ */
+ function get_layer_description(&$layer){
+ $description = $layer->getMetadata('DESCRIPTION');
+ if(!$description){
+ $description = $layer->getMetadata('OWS_TITLE');
+ }
+ if(!$description){
+ $description = $layer->getMetadata('WFS_TITLE');
+ }
+ if(!$description){
+ $description = $layer->getMetadata('WMS_TITLE');
+ }
+ if(!$description){
+ $description = $layer->name;
+ }
+ return $description;
+ }
+
+
+
+ /**
+ * Add style for balloon
+ * @param string style XML id
+ * @param string column name for title
+ */
+ function add_balloon_style(&$style, $balloon_data){
+ $balloon =& $style->addChild('BalloonStyle');
+ $balloon->addChild('text', htmlentities($balloon_data));
+ }
+
+
+ /**
+ * Get a request parameter
+ * @param string $name
+ * @param string $default parameter optional
+ * @return string the parameter value or empty string if null
+ */
+ function load_parm($name, $default = ''){
+ if(!isset($_REQUEST[$name])) return $default;
+ $value = $_REQUEST[$name];
+ if(get_magic_quotes_gpc() != 1) $value = addslashes($value);
+ //$value = escapeshellcmd($value);
+ return $value;
+ }
+
+ /**
+ * Set error message
+ * @param string $message
+ * @param string $layer name
+ */
+ function set_error($message, $layer = 'Error'){
+ $this->errors[$layer][] = $message;
+ }
+
+
+ /**
+ * Load the map and create the map instance
+ */
+ function load_map(){
+ if(!file_exists($this->map) && is_readable($this->map)){
+ $this->set_error('Cannot read mapfile '. $this->map);
+ } else {
+ $this->map_object = ms_newMapObj($this->map);
+ if(!$this->map_object){
+ $this->set_error('Cannot load mapfile '. $this->map);
+ }
+ }
+ }
+
+ /**
+ * Test if has errors
+ * @return boolean
+ */
+ function has_error(){
+ return count($this->errors) > 0;
+ }
+
+ /**
+ * Add error messages to folders TAGS
+ */
+ function add_errors(){
+ foreach($this->errors as $layer => $errors){
+ $folder =& $this->_xml->Document->addChild('Folder');
+ $folder->addChild('name', $layer);
+ $folder->addChild('description', '
' . join("
\n", $errors) . "
");
+ }
+ return $errorxml;
+ }
+
+ /**
+ * Fetch XML and format it
+ */
+ function get_kml(){
+ $doc = new DOMDocument('1.0');
+ $doc->formatOutput = true;
+ $domnode = dom_import_simplexml($this->_xml);
+ $domnode = $doc->importNode($domnode, true);
+ $domnode = $doc->appendChild($domnode);
+ return $doc->saveXML();
+ }
+
+ /**
+ * Send header
+ */
+ function send_header(){
+ header('Content-type: application/vnd.google-earth.km'.($this->_zipped ? 'z' : 'l').'+XML');
+ }
+
+ /**
+ * Calculate cache file name
+ */
+ function get_cache_file_name(){
+ return 'cache/'. md5($_SERVER['QUERY_STRING']) . ($this->_zipped ? '.kmz' : '.kml');
+ }
+
+ /**
+ * Send stream
+ */
+ function send_stream($data){
+ $this->send_header();
+ // Compress data
+ if($this->_zipped){
+ include("zip.class.php");
+ $ziper = new zipfile();
+ $ziper->addFile($data, 'doc.kml');
+ $data = $ziper->file();
+ }
+ // Create cache if needed
+ if(ENABLE_CACHE && count($this->layers) == 1 && $this->layers[$this->typename]->getMetadata('KML_CACHE')) {
+ error_log( 'creating cache ' . $this->get_cache_file_name() );
+ file_put_contents($this->get_cache_file_name(), $data);
+ }
+ print $data;
+ exit();
+ }
+}
+?>
\ No newline at end of file
diff --git a/pacotes/kmlmapserver/classes/symbolserver.class.php b/pacotes/kmlmapserver/classes/symbolserver.class.php
new file mode 100644
index 0000000..e2f3cca
--- /dev/null
+++ b/pacotes/kmlmapserver/classes/symbolserver.class.php
@@ -0,0 +1,210 @@
+
+* accepted parameters (case insensitive):
+* - map = string - path to mapfile
+* - typename = string - layer name
+* - classname = string - class name
+*
+*
+* @author Alessandro Pasotti
+* @copyright 2007 ItOpen.it - All rights reserved
+* @package KMLSERVER
+
+This file is part of KMLMAPSERVER.
+
+ KMLMAPSERVER is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ KMLMAPSERVER is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with KMLMAPSERVER; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+*/
+
+class SymbolServer {
+
+ /** map file path */
+ var $map;
+
+ /** map instance */
+ var $map_object;
+
+ /** layer name */
+ var $typename;
+
+ /** class */
+ var $classname;
+
+ /** class index */
+ var $classindex;
+
+ /** icon_layer */
+ var $icon_layer;
+
+ /** icon point object */
+ var $iconpoint;
+
+
+ function SymbolServer(){
+ $this->errors = array();
+ // Load request parameters
+ $this->get_request();
+ // Load map
+ if(!$this->has_error()) {
+ $this->load_map();
+ }
+ }
+
+ /**
+ * Run the server and sends data
+ * @return string or void
+ */
+ function run(){
+ // Process request
+ if(!$this->has_error()) {
+ $this->process_request();
+ }
+ if($this->has_error()){
+ $this->send_errors();
+ } else {
+ $this->send_icon();
+ }
+ }
+
+
+ /**
+ * Process request
+ */
+ function process_request(){
+ $layer = @$this->map_object->getLayerByName($this->typename);
+ if(!$layer){
+ $this->set_error('Layer not found ' . $layer_name, $layer_name);
+ return false;
+ }
+ // Get class
+ $class = null;
+ for($i = 0; $i < $layer->numclasses; $i++){
+ $_class = @$layer->getClass($i);
+ if($this->classname == $_class->name){
+ $class =& $_class;
+ $this->classindex = $i;
+ break;
+ }
+ }
+ if(!$class){
+ $this->set_error('Class name not found ' . $layer_name, $this->classname);
+ return false;
+ }
+ // Get symbol size
+ for($i = 0; $i < $class->numstyles; $i++){
+ $_style = @$class->getStyle($i);
+ if($_style->symbolname){
+ // 64 pixel is standard Google Earth pushpin
+ //$_style->set('size', 64);
+ $symbolsize = $_style->size;
+ break;
+ }
+ }
+ // Provide a default here
+ if(!$symbolsize) {
+ $symbolsize = 10;
+ }
+ $ext = $this->map_object->extent;
+ $centerx = ($ext->maxx - $ext->minx)/2;
+ $centery = ($ext->maxy - $ext->miny)/2;
+
+ // Create a new layer
+ $this->icon_layer = ms_newLayerObj($this->map_object, $layer);
+ $this->map_object->setSize($symbolsize, $symbolsize);
+ $this->map_object->setExtent($centerx - $symbolsize, $centery - $symbolsize, $centerx + $symbolsize, $centery + $symbolsize);
+ $this->icon_layer->set( 'status', MS_ON );
+ $this->iconpoint = ms_newPointObj();
+ $this->iconpoint->setXY($centerx, $centery);
+ }
+
+ /**
+ * Test if has errors
+ * @return boolean
+ */
+ function has_error(){
+ return count($this->errors) > 0;
+ }
+
+ /**
+ * Get all request parameters
+ */
+ function get_request(){
+ $this->map = $this->load_parm('map');
+ $this->typename = $this->load_parm('typename');
+ $this->classname= $this->load_parm('classname');
+ if(!$this->map){
+ $this->set_error('No mapfile specified');
+ }
+ if(!$this->typename){
+ $this->set_error('No typename (layer) specified');
+ }
+ }
+
+ /**
+ * Get a request parameter
+ * @param string $name
+ * @return string the parameter value or empty string if null
+ */
+ function load_parm($name){
+ if(!isset($_REQUEST[$name])) return '';
+ $value = $_REQUEST[$name];
+ if(get_magic_quotes_gpc() != 1) $value = addslashes($value);
+ //$value = escapeshellcmd($value);
+ return $value;
+ }
+
+ /**
+ * Set error message
+ * @param string $message
+ * @param string $layer name
+ */
+ function set_error($message, $layer = 'Error'){
+ $this->errors[$layer][] = $message;
+ }
+
+ /**
+ * Load the map and create the map instance
+ */
+ function load_map(){
+ if(!file_exists($this->map) && is_readable($this->map)){
+ $this->set_error('Cannot read mapfile '. $this->map);
+ } else {
+ $this->map_object = ms_newMapObj($this->map);
+ if(!$this->map_object){
+ $this->set_error('Cannot load mapfile '. $this->map);
+ }
+ }
+ }
+
+ function send_errors(){
+ print_r($this->errors);
+ }
+
+ function send_icon(){
+ header('Content-type:image/png');
+ // Set transparency (needs imageformat RBGA in the mapfile too)
+ $this->map_object->set('transparent', 'on');
+ $img = $this->map_object->draw();
+ $this->iconpoint->draw($this->map_object, $this->icon_layer, $img, $this->classindex, '');
+ $img->saveImage('');
+ }
+
+}
+?>
\ No newline at end of file
diff --git a/pacotes/kmlmapserver/classes/zip.class.php b/pacotes/kmlmapserver/classes/zip.class.php
new file mode 100644
index 0000000..84f21cf
--- /dev/null
+++ b/pacotes/kmlmapserver/classes/zip.class.php
@@ -0,0 +1,230 @@
+
+*
+* http://www.zend.com/codex.php?id=470&single=1
+* by Denis125
+*
+* a patch from Peter Listiak for last modified
+* date and time of the compressed file
+*
+* Official ZIP file format: http://www.pkware.com/appnote.txt
+*
+* @access public
+*/
+class zipfile
+{
+ /**
+ * Array to store compressed data
+ *
+ * @var array $datasec
+ */
+ var $datasec = array();
+
+ /**
+ * Central directory
+ *
+ * @var array $ctrl_dir
+ */
+ var $ctrl_dir = array();
+
+ /**
+ * End of central directory record
+ *
+ * @var string $eof_ctrl_dir
+ */
+ var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";
+
+ /**
+ * Last offset position
+ *
+ * @var integer $old_offset
+ */
+ var $old_offset = 0;
+
+
+ /**
+ * Converts an Unix timestamp to a four byte DOS date and time format (date
+ * in high two bytes, time in low two bytes allowing magnitude comparison).
+ *
+ * @param integer the current Unix timestamp
+ *
+ * @return integer the current date in a four byte DOS format
+ *
+ * @access private
+ */
+ function unix2DosTime($unixtime = 0) {
+ $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
+
+ if ($timearray['year'] < 1980) {
+ $timearray['year'] = 1980;
+ $timearray['mon'] = 1;
+ $timearray['mday'] = 1;
+ $timearray['hours'] = 0;
+ $timearray['minutes'] = 0;
+ $timearray['seconds'] = 0;
+ } // end if
+
+ return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
+ ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
+ } // end of the 'unix2DosTime()' method
+
+
+ /**
+ * Adds "file" to archive
+ *
+ * @param string file contents
+ * @param string name of the file in the archive (may contains the path)
+ * @param integer the current timestamp
+ *
+ * @access public
+ */
+ function addFile($data, $name, $time = 0)
+ {
+ $name = str_replace('\\', '/', $name);
+
+ $dtime = dechex($this->unix2DosTime($time));
+ $hexdtime = '\x' . $dtime[6] . $dtime[7]
+ . '\x' . $dtime[4] . $dtime[5]
+ . '\x' . $dtime[2] . $dtime[3]
+ . '\x' . $dtime[0] . $dtime[1];
+ eval('$hexdtime = "' . $hexdtime . '";');
+
+ $fr = "\x50\x4b\x03\x04";
+ $fr .= "\x14\x00"; // ver needed to extract
+ $fr .= "\x00\x00"; // gen purpose bit flag
+ $fr .= "\x08\x00"; // compression method
+ $fr .= $hexdtime; // last mod time and date
+
+ // "local file header" segment
+ $unc_len = strlen($data);
+ $crc = crc32($data);
+ $zdata = gzcompress($data);
+ $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
+ $c_len = strlen($zdata);
+ $fr .= pack('V', $crc); // crc32
+ $fr .= pack('V', $c_len); // compressed filesize
+ $fr .= pack('V', $unc_len); // uncompressed filesize
+ $fr .= pack('v', strlen($name)); // length of filename
+ $fr .= pack('v', 0); // extra field length
+ $fr .= $name;
+
+ // "file data" segment
+ $fr .= $zdata;
+
+ // "data descriptor" segment (optional but necessary if archive is not
+ // served as file)
+ $fr .= pack('V', $crc); // crc32
+ $fr .= pack('V', $c_len); // compressed filesize
+ $fr .= pack('V', $unc_len); // uncompressed filesize
+
+ // add this entry to array
+ $this -> datasec[] = $fr;
+
+ // now add to central directory record
+ $cdrec = "\x50\x4b\x01\x02";
+ $cdrec .= "\x00\x00"; // version made by
+ $cdrec .= "\x14\x00"; // version needed to extract
+ $cdrec .= "\x00\x00"; // gen purpose bit flag
+ $cdrec .= "\x08\x00"; // compression method
+ $cdrec .= $hexdtime; // last mod time & date
+ $cdrec .= pack('V', $crc); // crc32
+ $cdrec .= pack('V', $c_len); // compressed filesize
+ $cdrec .= pack('V', $unc_len); // uncompressed filesize
+ $cdrec .= pack('v', strlen($name) ); // length of filename
+ $cdrec .= pack('v', 0 ); // extra field length
+ $cdrec .= pack('v', 0 ); // file comment length
+ $cdrec .= pack('v', 0 ); // disk number start
+ $cdrec .= pack('v', 0 ); // internal file attributes
+ $cdrec .= pack('V', 32 ); // external file attributes - 'archive' bit set
+
+ $cdrec .= pack('V', $this -> old_offset ); // relative offset of local header
+ $this -> old_offset += strlen($fr);
+
+ $cdrec .= $name;
+
+ // optional extra field, file comment goes here
+ // save to central directory
+ $this -> ctrl_dir[] = $cdrec;
+ } // end of the 'addFile()' method
+
+
+ /**
+ * Dumps out file
+ *
+ * @return string the zipped file
+ *
+ * @access public
+ */
+ function file()
+ {
+ $data = implode('', $this -> datasec);
+ $ctrldir = implode('', $this -> ctrl_dir);
+
+ return
+ $data .
+ $ctrldir .
+ $this -> eof_ctrl_dir .
+ pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk"
+ pack('v', sizeof($this -> ctrl_dir)) . // total # of entries overall
+ pack('V', strlen($ctrldir)) . // size of central dir
+ pack('V', strlen($data)) . // offset to start of central dir
+ "\x00\x00"; // .zip file comment length
+ } // end of the 'file()' method
+
+
+ /**
+ * A Wrapper of original addFile Function
+ *
+ * Created By Hasin Hayder at 29th Jan, 1:29 AM
+ *
+ * @param array An Array of files with relative/absolute path to be added in Zip File
+ *
+ * @access public
+ */
+ function addFiles($files /*Only Pass Array*/)
+ {
+ foreach($files as $file)
+ {
+ if (is_file($file)) //directory check
+ {
+ $data = implode("",file($file));
+ $this->addFile($data,$file);
+ }
+ }
+ }
+
+ /**
+ * A Wrapper of original file Function
+ *
+ * Created By Hasin Hayder at 29th Jan, 1:29 AM
+ *
+ * @param string Output file name
+ *
+ * @access public
+ */
+ function output($file)
+ {
+ $fp=fopen($file,"w");
+ fwrite($fp,$this->file());
+ fclose($fp);
+ }
+
+
+
+} // end of the 'zipfile' class
+?>
\ No newline at end of file
diff --git a/pacotes/kmlmapserver/doc/index.html b/pacotes/kmlmapserver/doc/index.html
new file mode 100644
index 0000000..adf20a8
--- /dev/null
+++ b/pacotes/kmlmapserver/doc/index.html
@@ -0,0 +1,4 @@
+See online docs here:
+
+http://www.itopen.it/soluzioni/webmapping/kml-map-server/
+
\ No newline at end of file
diff --git a/pacotes/kmlmapserver/kmlservice.php b/pacotes/kmlmapserver/kmlservice.php
new file mode 100644
index 0000000..adef6d5
--- /dev/null
+++ b/pacotes/kmlmapserver/kmlservice.php
@@ -0,0 +1,30 @@
+
\ No newline at end of file
--
libgit2 0.21.2