* 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', false);
/**
* Enable cache
*/
define('ENABLE_CACHE', true);
if (function_exists("dl")) {
if (! function_exists('ms_GetVersion')) {
dl('php_mapscript.' . PHP_SHLIB_SUFFIX);
}
if (! extension_loaded('php_mbstring')) {
dl('php_mbstring.' . PHP_SHLIB_SUFFIX);
}
}
if (! function_exists('ms_GetVersion')) {
echo "Nao foi possivel carregar php_mapscript";
}
/**
* 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;
var $postgis_mapa;
/**
* 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)) {
$this->send_header();
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;
}
if ($this->_networklink == false) {
// desliga todos os layers
for ($i = 0; $i < $this->map_object->numlayers; $i ++) {
$l = $this->map_object->getLayer($i);
$l->set("status", MS_OFF);
}
// ajusta a legenda
$nomesl = explode(',', $this->typename);
foreach ($nomesl as $nomel) {
$layer = $this->map_object->getlayerbyname($nomel);
if ($layer) {
$layer->set("status", MS_DEFAULT);
if ($layer->numclasses > 0) {
$classe = $layer->getclass(0);
if (($classe->name == "") || ($classe->name == " ")) {
$classe->set("name", $layer->getmetadata("tema"));
}
// corrige o titulo da legenda
$nclass = $layer->numclasses;
for ($j = 0; $j < $nclass; $j ++) {
$classe = $layer->getclass($j);
if ($classe->title === "") {
$classe->title = $classe->name;
}
}
}
}
}
}
$imageObj = $this->map_object->drawlegend();
$url = $imageObj->saveWebImage();
$protocolo = explode("/", $_SERVER['SERVER_PROTOCOL']);
$url = strtolower($protocolo[0] . "://" . $_SERVER['HTTP_HOST']) . $url;
$legenda = "
";
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);
$st->addChild('scale', 1);
} else {
$st->addChild('scale', 1);
}
$icon = & $st->addChild('Icon');
$icon->addChild('href', htmlentities($style_data['icon']));
}
$ls = & $new_style->addChild('LabelStyle');
$ls->addChild('scale', $style_data['label_size'] / 32);
// 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['color']->red != - 1) {
$st->addChild('color', sprintf('FF%02X%02X%02X', $style_data['color']->blue, $style_data['color']->green, $style_data['color']->red));
$st->addChild('fill', 1);
} 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 = & $this->simplexml_addChild($folder, 'Icon');
// $icon->addChild('href', $link . 'layers=' . $layer->name);
$this->simplexml_addChild($icon, 'href', $link . 'layers=' . $layer->name);
// $icon->addChild('viewRefreshMode', 'onStop');
$this->simplexml_addChild($icon, 'viewRefreshMode', 'onStop');
// $llbox =& $folder->addChild('LatLonBox');
$llbox = & $this->simplexml_addChild($folder, 'LatLonBox');
$ext = $this->map_object->extent;
$ext->project($this->in_proj, $this->out_proj);
// $llbox->north = $ext->maxy;
$this->simplexml_addChild($llbox, 'north', $ext->maxy);
// $llbox->south = $ext->miny;
$this->simplexml_addChild($llbox, 'south', $ext->miny);
// $llbox->east = $ext->maxx;
$this->simplexml_addChild($llbox, 'east', $ext->maxx);
// $llbox->west = $ext->minx;
$this->simplexml_addChild($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, $classindex)
{
$classe = $layer->getclass($classindex);
$estilo = $classe->getstyle(0);
$url = "";
$imageObj = $classe->createLegendIcon(30, 30);
if ($imageObj) {
$url = $imageObj->saveWebImage();
$protocolo = explode("/", $_SERVER['SERVER_PROTOCOL']);
$url = strtolower($protocolo[0] . "://" . $_SERVER['HTTP_HOST']) . $url;
$nome = $imageObj->imagepath . basename($url);
$img = imagecreatefrompng($nome);
$index = imagecolorexact($img, 255, 255, 255);
imagecolortransparent($img, $index);
imagepng($img, $nome);
}
return $url; // $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->getMetadata('TEMA');
}
if (! $description) {
$description = $layer->name;
}
$description = mb_convert_encoding($description, "UTF-8", mb_detect_encoding($description, "UTF-8,ISO-8859-1"));
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 {
$protocolo = explode("/", $_SERVER['SERVER_PROTOCOL']);
$servidor = strtolower($protocolo[0]) . "://" . $_SERVER['HTTP_HOST'];
$temp = $this->map;
if (file_exists(dirname(__FILE__) . "/../../../ms_configura.php")) {
include (dirname(__FILE__) . "/../../../ms_configura.php");
} else {
include (dirname(__FILE__) . "/../../ms_configura.php");
}
$this->postgis_mapa = $postgis_mapa;
if (! file_exists($this->map)) {
$maptemp = ms_newMapObj($locaplic . "/temas/" . $this->map . ".map");
// if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN'))
// {$this->map = $locaplic."/aplicmap/geral1windows.map";}
// else
// {$this->map = $locaplic."/aplicmap/geral1.map";}
$versao = $this->versao();
$versao = $versao["principal"];
if (! isset($base) || $base == "") {
if (strtoupper(substr(PHP_OS, 0, 3) == 'WIN')) {
$base = $locaplic . "/aplicmap/geral1windowsv" . $versao . ".map";
} else {
if ($base == "" && file_exists('/var/www/i3geo/aplicmap/geral1debianv' . $versao . '.map')) {
$base = "/var/www/i3geo/aplicmap/geral1debianv" . $versao . ".map";
}
if ($base == "" && file_exists('/var/www/html/i3geo/aplicmap/geral1fedorav' . $versao . '.map')) {
$base = "/var/www/html/i3geo/aplicmap/geral1fedorav" . $versao . ".map";
}
if ($base == "" && file_exists('/opt/www/html/i3geo/aplicmap/geral1fedorav' . $versao . '.map')) {
$base = "/opt/www/html/i3geo/aplicmap/geral1v" . $versao . ".map";
}
if ($base == "") {
$base = $locaplic . "/aplicmap/geral1v" . $versao . ".map";
}
}
}
$this->map = $base;
$this->map_object = ms_newMapObj($this->map);
if (! $this->_zipped) {
$this->map_object->setmetadata('wms_onlineresource', $servidor . ":80/i3geo/ogc.php?tema=" . $temp . "&width=1500&height=1500&TRANSPARENT=true&FORMAT=image/png&");
$this->map_object->setmetadata("ows_enable_request", "*");
}
$n = $this->map_object->numlayers;
for ($i = 0; $i < $n; $i ++) {
$l = $this->map_object->getlayer($i);
$l->set("status", MS_DELETE);
$l->set("name", "");
}
for ($i = 0; $i < ($maptemp->numlayers); $i ++) {
$l = $maptemp->getlayer($i);
$l->set("status", MS_DEFAULT);
if (! $this->_zipped) {
$l->set("type", MS_LAYER_RASTER);
$l->setmetadata('wms_onlineresource', "../../ogc.php?tema=" . $temp . "&width=1500&height=1500&TRANSPARENT=true&FORMAT=image/png&");
$l->setmetadata("ows_enable_request", "*");
}
ms_newLayerObj($this->map_object, $l);
}
} else {
$this->map_object = ms_newMapObj($this->map);
// $w = $this->map_object->web;
// $w->set("template","none.htm");
if (! $this->_zipped) {
// $this->map_object->setmetadata('wms_onlineresource',$servidor.":80".$locmapserv."?map=".$temp."&width=1500&height=1500&");
$this->map_object->setmetadata('wms_onlineresource', "../../ogc.php?tema=" . $temp . "&width=1500&height=1500&TRANSPARENT=true&FORMAT=image/png&");
$this->map_object->setmetadata("ows_enable_request", "*");
}
$n = $this->map_object->numlayers;
for ($i = 0; $i < $n; $i ++) {
$l = $this->map_object->getlayer($i);
$l->set("status", MS_DEFAULT);
if (! $this->_zipped)
$l->set("type", MS_LAYER_RASTER);
// $l->setmetadata('wms_onlineresource',"../../ogc.php?tema=".$temp."&width=500&height=500&");
// ms_newLayerObj($this->map_object, $l);
}
}
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-Disposition: attachment; filename=kml.km' . ($this->_zipped ? 'z' : 'l')); header('Content-type: application/vnd.google-earth.km' . ($this->_zipped ? 'z' : 'l') . '+XML'); } /** * Calculate cache file name */ function get_cache_file_name() { // obtem o arquivo do metadata do layer se existir $layer = @$this->map_object->getlayerbyname($this->typename); if (! $layer) { $layer = $this->map_object->getlayer(0); } $k = $layer->getmetadata("arquivokmz"); if ($k != "") { return $k; } if (file_exists(dirname(__FILE__) . "/../../../ms_configura.php")) { include (dirname(__FILE__) . "/../../../ms_configura.php"); } else { include (dirname(__FILE__) . "/../../ms_configura.php"); } return $dir_tmp . '/' . 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) { // error_log( 'creating cache ' . $this->get_cache_file_name() ); file_put_contents($this->get_cache_file_name(), $data); } print $data; exit(); } // phpversion <= 5.1.2 function simplexml_addChild($parent, $name, $value = '') { $new_child = new SimpleXMLElement("<$name>$value$name>"); $node1 = dom_import_simplexml($parent); $dom_sxe = dom_import_simplexml($new_child); $node2 = $node1->ownerDocument->importNode($dom_sxe, true); $node1->appendChild($node2); return simplexml_import_dom($node2); } function versao() { $v = "5.0.0"; $vs = explode(" ", ms_GetVersion()); $cvs = count($vs); for ($i = 0; $i < $cvs; ++ $i) { if (trim(strtolower($vs[$i])) == "version") { $v = $vs[$i + 1]; } } $versao["completa"] = $v; $v = explode(".", $v); $versao["principal"] = $v[0]; $versao["inteiro"] = ms_GetVersionInt(); return $versao; } } ?>