<?php #-*-Mode: php; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/*
jjfMapper, a cartography program for PHP 4.
Copyright (C) 2004 John J Foerch
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
include_once(JJFM_LIBDIR.'/built_in_icons.php');
include_once(JJFM_LIBDIR.'/geoformat.php');
include_once(JJFM_LIBDIR.'/xml_detail_parser.php');
class geoformat_gpx extends geoformat {
var $xml;
var $gpxfile;
var $dot = false;
var $wptdot = false;
var $rtedot = false;
var $trkdot = false;
var $dotcolor = false;
var $wptdotcolor = false;
var $rtedotcolor = false;
var $trkdotcolor = false;
var $color = false;
var $rtecolor = false;
var $trkcolor = false;
var $weight = false;
var $rteweight = false;
var $trkweight = false;
var $style = JJFM_DASHED_LINE;
var $rtestyle = false;
var $trkstyle = false;
function parse_instructions (&$ops, &$symbols) {
$ret = array();
if (isset($ops['FILE']))
{
$ret['file'] = expand_symbols ($ops['FILE'], $symbols);
}
if (isset($ops['DOT'])) $ret['dot'] = $ops['DOT'];
if (isset($ops['WPTDOT'])) $ret['wptdot'] = $ops['WPTDOT'];
if (isset($ops['RTEDOT'])) $ret['rtedot'] = $ops['RTEDOT'];
if (isset($ops['TRKDOT'])) $ret['trkdot'] = $ops['TRKDOT'];
if (isset ($ops['DOTCOLOR'])) $ret['dotcolor'] = $ops['DOTCOLOR'];
if (isset ($ops['WPTDOTCOLOR']))
$ret['wptdotcolor'] = $ops['WPTDOTCOLOR'];
if (isset ($ops['RTEDOTCOLOR']))
$ret['rtedotcolor'] = $ops['RTEDOTCOLOR'];
if (isset ($ops['TRKDOTCOLOR']))
$ret['trkdotcolor'] = $ops['TRKDOTCOLOR'];
//attribute TRAILCOLOR is provided as an alias for COLOR
if (isset($ops['TRAILCOLOR'])) $ret['color'] = $ops['TRAILCOLOR'];
if (isset($ops['COLOR'])) $ret['color'] = $ops['COLOR'];
if (isset($ops['RTECOLOR'])) $ret['rtecolor'] = $ops['RTECOLOR'];
if (isset($ops['TRKCOLOR'])) $ret['trkcolor'] = $ops['TRKCOLOR'];
//attribute TRAILWEIGHT is provided as an alias for WEIGHT
if (isset($ops['TRAILWEIGHT'])) $ret['weight'] = $ops['TRAILWEIGHT'];
if (isset($ops['WEIGHT'])) $ret['weight'] = $ops['WEIGHT'];
if (isset($ops['RTEWEIGHT'])) $ret['rteweight'] = $ops['RTEWEIGHT'];
if (isset($ops['TRKWEIGHT'])) $ret['trkweight'] = $ops['TRKWEIGHT'];
if (isset($ops['STYLE'])) $ret['style'] = strtoupper($ops['STYLE']);
if (isset($ops['RTESTYLE']))
$ret['rtestyle'] = strtoupper ($ops['RTESTYLE']);
if (isset($ops['TRKSTYLE']))
$ret['trkstyle'] = strtoupper ($ops['TRKSTYLE']);
return $ret;
}
function geoformat_gpx (&$args) {
$gpx_content = '';
//file takes precedence over inline content
if (isset($args['file'])) $this->gpxfile = $args['file'];
elseif (isset ($args['inline'])) $gpx_content = $args['inline'];
if ($this->gpxfile == '' & $gpx_content == '')
{
$this->ok=false;
$this->error = 'no gpx filename or content passed.';
return;
}
//begin dot type logic
if (isset($args['dot']))
{
$this->dot = $args['dot'];
$this->wptdot = & $this->dot;
$this->rtedot = & $this->dot;
$this->trkdot = & $this->dot;
}
if (isset ($args['wptdot'])) $this->wptdot = & $args['wptdot'];
if (isset ($args['rtedot'])) $this->rtedot = & $args['rtedot'];
if (isset ($args['trkdot'])) $this->trkdot = & $args['trkdot'];
//end dot type logic
//begin dot color logic
if (isset ($args['dotcolor']))
{
$this->dotcolor = $args['dotcolor'];
$this->wptdotcolor = & $this->dotcolor;
$this->rtedotcolor = & $this->dotcolor;
$this->trkdotcolor = & $this->dotcolor;
}
if (isset ($args['wptdotcolor']))
{
$this->wptdotcolor = & $args['wptdotcolor'];
if ($this->wptdot === false) $this->wptdot = 'dot';
}
if (isset ($args['rtedotcolor']))
{
$this->rtedotcolor = & $args['rtedotcolor'];
if ($this->rtedot === false) $this->rtedot = 'dot';
}
if (isset ($args['trkdotcolor']))
{
$this->trkdotcolor = & $args['trkdotcolor'];
if ($this->trkdot === false) $this->trkdot = 'dot';
}
//end dot color logic
//begin [trail] color logic
if (isset ($args['color'])) $this->color = $args['color'];
else $this->color = 'black';
$this->rtecolor = & $this->color;
$this->trkcolor = & $this->color;
if (isset ($args['rtecolor'])) $this->rtecolor = & $args['rtecolor'];
if (isset ($args['trkcolor'])) $this->trkcolor = & $args['trkcolor'];
//end [trail] color logic
//begin [trail] weight logic
if (isset ($args['weight'])) $this->weight = $args['weight'];
else $this->weight = 1;
$this->rteweight = & $this->weight;
$this->trkweight = & $this->weight;
if (isset ($args['rteweight'])) $this->rteweight =& $args['rteweight'];
if (isset ($args['trkweight'])) $this->trkweight =& $args['trkweight'];
//end [trail] weight logic
//begin style logic
if (isset ($args['style']) && $args['style'] == 'SOLID')
$this->style = JJFM_SOLID_LINE;
$this->rtestyle = $this->style;
$this->trkstyle = $this->style;
if (isset ($args['rtestyle']) && $args['trkstyle'] == 'SOLID')
$this->rtestyle = JJFM_SOLID_LINE;
if (isset ($args['trkstyle']) && $args['trkstyle'] == 'SOLID')
$this->trkstyle = JJFM_SOLID_LINE;
//end style logic
if ($this->gpxfile != '')
{
if (!file_exists ($this->gpxfile))
{
$this->ok=false;
$this->error = 'could not find specified gpx file.';
return;
}
$f = fopen($this->gpxfile,'rb');
$gpx_content = fread($f,filesize($this->gpxfile));
fclose($f);
}
//now construct the xml data structure
$op = array ('support' => 'WPT,TRKPT,RTEPT,RTE,TRK,BOUNDS,GPX,TRKSEG');
$this->xml = new xml_detail_parser ($gpx_content, $op);
}
function draw(&$projection) {
$this->trail_data ($projection, 'TRK');
$this->trail_data ($projection, 'RTE');
$this->waypoints ($projection);
}
//trail_data.. pass string 'TRK' or 'RTE'
/*this function does not support the TRKSEG tag within a TRK tag. Yet I
do not see at present that TRKSEG itself provides any useful information
in the context of this mapper.
*/
function trail_data (&$projection, $type) {
$ptype = $type .'PT';
if (! isset ($this->xml->index[$type])) return;
if (! isset ($this->xml->index[$ptype])) return;
$trails_idx = array();
foreach ($this->xml->index[$type] as $trail_o) {
if ($this->xml->struct[$trail_o]['type'] != 'open') continue;
$trail_c = $this->xml->struct[$trail_o]['close'];
$trails_idx[] = array ($trail_o, $trail_c);
}
$q = array(0,0);
$p = -1;
$trails = array ();
foreach ($this->xml->index[$ptype] as $pt_o) {
if ($pt_o > $q[1])
{
$q = & $trails_idx[++$p];
$s = array_push ($trails, array());
$r = & $trails[$s - 1];
}
if (isset ($this->xml->struct[$pt_o]['attributes']['LON']) &&
isset ($this->xml->struct[$pt_o]['attributes']['LAT']))
{
$r[] = $this->xml->struct[$pt_o]['attributes']['LON'];
$r[] = $this->xml->struct[$pt_o]['attributes']['LAT'];
}
}
//at this point we should have an array of arrays, $trails,
//which are ready to plot
if ($type == 'TRK')
{
$dot = & $this->trkdot;
$dotcolor = & $this->trkdotcolor;
$color = & $this->trkcolor;
$weight = & $this->trkweight;
$style = $this->trkstyle;
} elseif ($type == 'RTE') {
$dot = & $this->rtedot;
$dotcolor = & $this->rtedotcolor;
$color = & $this->rtecolor;
$weight = & $this->rteweight;
$style = $this->rtestyle;
} else {
$dot = false;
$dotcolor = false;
$color = false;
$weight = false;
$style = $this->style;
}
foreach ($trails as $t_k => $t_v) {
$geometry = array (
'track' => array (
'weight' => $weight,
'color' => $color,
'style' => $style,
'data' => $t_v
),
);
if ($dot !== false)
{
$geometry['point'] = array (
'dot' => $dot,
'data' => $t_v
);
if ($dotcolor !== false)
$geometry['point']['dotcolor'] = $dotcolor;
}
$projection->draw ($geometry);
}
}
function waypoints (&$projection) {
if (! isset($this->xml->index['WPT'])) return;
$geometry = array (
'point' => array (
'dot' => $this->wptdot,
'dotcolor' => $this->wptdotcolor,
'data' => array ()
)
);
$pts = & $geometry['point']['data'];
foreach ($this->xml->index['WPT'] as $wptidx) {
if (isset($this->xml->struct[$wptidx]['attributes']['LON']) &&
isset($this->xml->struct[$wptidx]['attributes']['LAT']))
{
$pts[] = $this->xml->struct[$wptidx]['attributes']['LON'];
$pts[] = $this->xml->struct[$wptidx]['attributes']['LAT'];
}
}
$projection->draw ($geometry);
}
function bounds () {
if(isset($this->xml->index['BOUNDS']) &&
count ($this->xml->index['BOUNDS'] == 1))
{
//return single bounding box
//latmin, latmax, lonmin, lonmax
$r = $this->xml->index['BOUNDS'][0];
return array($this->xml->struct[$r]['attributes']['MINLAT'],
$this->xml->struct[$r]['attributes']['MAXLAT'],
$this->xml->struct[$r]['attributes']['MINLON'],
$this->xml->struct[$r]['attributes']['MAXLON']);
} else {
//iterate through all waypoints, routepoints and trackpoints
$minlat = $maxlat = $minlon = $maxlon = false;
$tags = array ('WPT','RTEPT','TRKPT');
foreach ($tags as $tag) {
if (! isset ($this->xml->index[$tag])) continue;
foreach ($this->xml->index[$tag] as $t) {
if (! isset($this->xml->struct[$t]['attributes']))
continue;
$m = & $this->xml->struct[$t]['attributes'];
if (! (isset ($m['LON']) && isset ($m['LAT']))) continue;
if ($minlon === false || $m['LON'] < $minlon)
$minlon = $m['LON'];
if ($minlat === false || $m['LAT'] < $minlat)
$minlat = $m['LAT'];
if ($maxlon === false || $m['LON'] > $maxlon)
$maxlon = $m['LON'];
if ($maxlat === false || $m['LAT'] > $maxlat)
$maxlat = $m['LAT'];
}
}
return array ($minlat, $maxlat, $minlon, $maxlon);
}
}
}
?>