Location: PHPKode > projects > jjfmapper > jjfmapper/lib/geoformat_gpx.php
<?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);
        }
    }
}

?>
Return current item: jjfmapper