* 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;
/**
* 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;
}
$imageObj = $this->map_object->drawlegend();
$url = $imageObj->saveWebImage();
$protocolo = explode("/",$_SERVER['SERVER_PROTOCOL']);
$url = strtolower($protocolo[0]."://".$_SERVER['HTTP_HOST']).$url;
$legenda = " " . PHP_EOL
. " Legenda" . PHP_EOL
. " " . PHP_EOL
. " ".$url."" . PHP_EOL
. " " . PHP_EOL
. " " . PHP_EOL
. " " . PHP_EOL
. " " . PHP_EOL
. " " . PHP_EOL;
$this->_xml = new SimpleXMLElement(''.$legenda.'');
// 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']);
$protocolo = explode("/",$_SERVER['SERVER_PROTOCOL']);
$protocolo = strtolower($protocolo[0]);
$this->endpoint = $protocolo . '://'.$_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 = explode(',', $this->typename);
if($this->_networklink){
foreach($layers as $layer){
$this->add_networklink($layer);
}
} else {
foreach($layers as $layer){
//echo "Oi";exit;
$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);
if(!$layer)
{$layer = $this->map_object->getlayer(0);}
$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){
error_reporting(0);
$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];}
}
$v = explode(".",$v);
$versao = $v[0];
$layer = @$this->map_object->getLayerByName($layer_name);
if(!$layer)
{$layer = $this->map_object->getlayer(0);}
if(!$layer){
$this->set_error('Nenhum layer com esse nome foi encontrado no mapfile ' . $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_DEFAULT );
// 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:4618&STYLES=&FORMAT=image/jpeg&TRANSPARENT=TRUE&';
// Link ok, create folder
//$folder =& $this->_xml->Document->addChild('GroundOverlay');
$folder =& $this->simplexml_addChild($this->_xml->Document,'GroundOverlay');
//simplexml_addChild($parent, $name, $value='')
//$folder->addChild('description', $this->get_layer_description($layer));
$this->simplexml_addChild($folder,'name',$layer_desc);
//$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("itens");
if($namecol == ""){
$cols = array_values($layer->getItems());
$namecol = $cols[0];
}
else
{$namecol = explode(",",$namecol);$namecol = $namecol[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(!isset($searchfield)){$searchfield = false;}
if(!isset($searchstring)){$searchstring = false;}
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
if($versao == 6)
{$shape = $layer->getShape($layer->getResult($j));}
else{
$result = $layer->getResult($j);
$shape = $layer->getFeature($result->shapeindex,$result->tileindex);
}
$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
$layer->set("template","none.htm");
$layer->queryByrect($this->map_object->extent);
$layer->open();
$n = $layer->getNumResults();
for ($j=0; $j < $n; $j++)
{
// get next shape row
if($versao == 6)
{
$result = $layer->getResult($j);
$shape = $layer->getShape($result);
}
else{
$result = $layer->getResult($j);
$shape = $layer->getFeature($result->shapeindex,$result->tileindex);
}
$shape->classindex = $result->classindex;
$this->process_shape($layer, $shape, $class_list, $folder, $namecol);
}
if($n == 0) {
$this->set_error('QueryByRect returned no data', $layer_name);
return false;
}
}
$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){
$permite = $layer->getmetadata("permitekmz");
if($permite == "nao"){return;}
$itens = $layer->getmetadata("itens");
$itensdesc = $layer->getmetadata("itensdesc");
$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(!isset($style_id)){
// Get first class
$class_keys = array_keys($class_list);
$indice = $shape->classindex;
$classe = $layer->getclass($indice);
$nome= $classe->name;
$style_id = preg_replace('/[^A-z0-9]/', '_', $layer->name . $nome);
}
// 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();
$description_template = $layer->getMetadata('DESCRIPTION_TEMPLATE');//false;
if($description_template == "")
{$description_template = false;}
$placemark =& $this->add_feature($feature_folder, $wkt, $shape->values[$namecol], $shape->values, $description_template, $class_list[$style_id],$itens,$itensdesc);
$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,$itens,$itensdesc){
$pm = $folder->addChild('Placemark');
$fname = mb_convert_encoding($featurename,"UTF-8",mb_detect_encoding($featurename,'UTF-8, UTF-7, ASCII, ISO-8859-1'));
$pm->addChild('name',$fname);
$pm->addChild('description', $this->get_feature_description($fname, $attributes, $description_template,$itens,$itensdesc));
// 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);
//var_dump($data);exit;
$data = str_replace(' ', ',', $data[1]);
*/
$data = str_replace("(","",$wkt);
$data = str_replace(")","",$data);
$data = str_replace("POINT","",$data);
$data = str_replace(" ",",",trim($data));
//echo $data;exit;
$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,$itens,$itensdesc){
// Compute hyperlink
//var_dump($attributes);exit;
//if($description_template != ""){return $description_template;}
$n = "";
if($description_template != "")
{
foreach($attributes as $k => $val)
{$description_template = str_replace("%".$k."%",$attributes[$k],$description_template);}
$n = $description_template;
}
else
{
if($itens == "")
{
foreach($attributes as $k => $val){
$n .= $k." - ".$attributes[$k]."\n";
}
}
else
{
$itens = explode(",",$itens);
$itensdesc = explode(",",$itensdesc);
for($i=0;$i 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;
if($layer->type == MS_LAYER_POINT)
$style['icon'] = $this->get_icon_url($layer, $class->name,$i);
$style['icon_width'] = $_style->size; // Points
}
$style['expression'] = $class->getExpressionString();
// 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);
$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("../../ms_configura.php");
}
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&");
$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=500&height=500&");
$l->setmetadata("ows_enable_request","*");
}
ms_newLayerObj($this->map_object, $l);
}
}
else{
$this->map_object = ms_newMapObj($this->map);
if(!$this->_zipped){
$this->map_object->setmetadata('wms_onlineresource',$servidor.":80".$locmapserv."?map=".$temp."&width=1500&height=1500&");
$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;
}
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];
return $versao;
}
}
?>