| 1 |
<?php
|
| 2 |
// $Id: gmap_gpx.inc,v 1.1.2.2 2007/08/28 21:06:30 bdragon Exp $
|
| 3 |
|
| 4 |
/*
|
| 5 |
* Created on 11.04.2007
|
| 6 |
* parse gpx files so we can show tracks on the map
|
| 7 |
*/
|
| 8 |
|
| 9 |
function gmap_gpx_parse_file($gpxfile) {
|
| 10 |
|
| 11 |
if (!file_exists($gpxfile)) return false;
|
| 12 |
|
| 13 |
$fp = @fopen($gpxfile, "r");
|
| 14 |
if (!$fp) return false;
|
| 15 |
|
| 16 |
$data = fgets($fp, 8192);
|
| 17 |
while (!feof($fp)) {
|
| 18 |
$data .= fgets($fp, 8192);
|
| 19 |
}
|
| 20 |
fclose($fp);
|
| 21 |
|
| 22 |
return gmap_gpx_parse($data);
|
| 23 |
}
|
| 24 |
|
| 25 |
function gmap_gpx_parse(&$data) {
|
| 26 |
global $gmap_gpx;
|
| 27 |
|
| 28 |
$parser = drupal_xml_parser_create($data);
|
| 29 |
|
| 30 |
xml_set_element_handler($parser, '_gmap_gpx_start_element', '_gmap_gpx_stop_element');
|
| 31 |
xml_set_character_data_handler($parser, '_gmap_gpx_char_data');
|
| 32 |
|
| 33 |
$gmap_gpx = array(
|
| 34 |
'char_data' => NULL,
|
| 35 |
'stack' => array(),
|
| 36 |
);
|
| 37 |
xml_parse($parser, $data, true); //$buf, feof($fp));
|
| 38 |
|
| 39 |
xml_parser_free($parser);
|
| 40 |
|
| 41 |
//_gmap_gpx_write_csv_file();
|
| 42 |
unset($gmap_gpx['stack']);
|
| 43 |
}
|
| 44 |
|
| 45 |
function gmap_gpx_cleanup() {
|
| 46 |
global $gmap_gpx;
|
| 47 |
$gmap_gpx = null;
|
| 48 |
}
|
| 49 |
|
| 50 |
function gmap_gpx_data2map(&$map) {
|
| 51 |
global $gmap_gpx;
|
| 52 |
|
| 53 |
$c = is_array($gmap_gpx['wpt']) ? count($gmap_gpx['wpt']) : 0;
|
| 54 |
for ($i = 0; $i <= $c; $i++) {
|
| 55 |
$wp =& $gmap_gpx['wpt'][$i];
|
| 56 |
$m = array('latitude' => $wp['lat'], 'longitude' => $wp['lon']);
|
| 57 |
if ($wp['name']) $m['opts']['title'] = $wp['name'];
|
| 58 |
$map['markers'][] = $m;
|
| 59 |
// TODO: select icon from $wp['sym'] and $wp['type']
|
| 60 |
}
|
| 61 |
|
| 62 |
// 0..n routes with 0..x points each
|
| 63 |
if (isset($gmap_gpx['rte']) && is_array($gmap_gpx['rte'])) {
|
| 64 |
$c = count($gmap_gpx['rte']); // number of routes
|
| 65 |
for ($i = 0; $i < $c; $i++) {
|
| 66 |
_gmap_gpx_add_wp_poly($map, $gmap_gpx['rte'][$i]['points']);
|
| 67 |
}
|
| 68 |
}
|
| 69 |
|
| 70 |
// 0..n tracks with 1..m segments
|
| 71 |
if (isset($gmap_gpx['trk']) && is_array($gmap_gpx['trk'])) {
|
| 72 |
$c = count($gmap_gpx['trk']); // number of tracks
|
| 73 |
for ($i = 0; $i < $c; $i++) {
|
| 74 |
$segs =& $gmap_gpx['trk'][$i]['segs'];
|
| 75 |
$c2 = count($segs); // number of segments in track
|
| 76 |
for ($j = 0; $j < $c2; $j++) {
|
| 77 |
_gmap_gpx_add_wp_poly($map, $segs[$j]['points']);
|
| 78 |
}
|
| 79 |
}
|
| 80 |
}
|
| 81 |
|
| 82 |
// TODO: make sure we don't screw up around 180 degrees
|
| 83 |
if ($gmap_gpx['bounds']) {
|
| 84 |
$lat = ($gmap_gpx['bounds']['minlat'] + $gmap_gpx['bounds']['maxlat']) / 2;
|
| 85 |
$lon = ($gmap_gpx['bounds']['minlon'] + $gmap_gpx['bounds']['maxlon']) / 2;
|
| 86 |
$map['latlong'] = $lat .','. $lon;
|
| 87 |
}
|
| 88 |
}
|
| 89 |
|
| 90 |
function _gmap_gpx_add_wp_poly(&$map, &$wpa) {
|
| 91 |
$c = count($wpa);
|
| 92 |
$s = array('type' => 'polygon', 'points' => array());
|
| 93 |
for ($i = 0; $i < $c; $i++) {
|
| 94 |
$wp = $wpa[$i];
|
| 95 |
$s['points'][] = array('latitude' => $wp['lat'], 'longitude' => $wp['lon']);
|
| 96 |
}
|
| 97 |
//$s['style'] = array('#0000ff', 3, 1);
|
| 98 |
$map['shapes'][] = $s;
|
| 99 |
}
|
| 100 |
|
| 101 |
function _gmap_gpx_start_element(&$parser, $name, $attrs) {
|
| 102 |
global $gmap_gpx;
|
| 103 |
static $wpa = array('GPX WPT' => 1, 'GPX RTE RTEPT' => 1,
|
| 104 |
'GPX TRK TRKSEG TRKPT' => 1);
|
| 105 |
$path = join(' ', $gmap_gpx['stack']) .' '. $name;
|
| 106 |
|
| 107 |
//if (($path == 'GPX WPT') || ($path == 'GPX RTE RTEPT') || ($path == 'GPX TRK TRKSEG TRKPT')) {
|
| 108 |
if (isset ($wpa[$path])) {
|
| 109 |
$gmap_gpx['waypoint'] = array(
|
| 110 |
'lat' => $attrs['LAT'],
|
| 111 |
'lon' => $attrs['LON'],
|
| 112 |
//'lat_pretty' => _gmap_gpx_latlon_pretty($attrs['LAT'], 'N', 'S'),
|
| 113 |
//'lon_pretty' => _gmap_gpx_latlon_pretty($attrs['LON'], 'E', 'W', true),
|
| 114 |
);
|
| 115 |
$gmap_gpx['point_type'] = strtolower($name); // 'wpt' || 'rtept' || 'trkpt'
|
| 116 |
}
|
| 117 |
elseif (isset($gmap_gpx['waypoint']) && ($name == 'EXTENSIONS')) {
|
| 118 |
$gmap_gpx['in_extension'] = true;
|
| 119 |
}
|
| 120 |
elseif ($name == 'BOUNDS') {
|
| 121 |
foreach ($attrs as $key => $val) {
|
| 122 |
$gmap_gpx['bounds'][strtolower($key)] = $val;
|
| 123 |
}
|
| 124 |
}
|
| 125 |
|
| 126 |
$gmap_gpx['char_data'] = '';
|
| 127 |
$gmap_gpx['stack'][] = $name;
|
| 128 |
}
|
| 129 |
|
| 130 |
function _gmap_gpx_stop_element(&$parser, $name) {
|
| 131 |
global $gmap_gpx;
|
| 132 |
static $info_tags = array('NAME' => 1 , 'DESC' => 1, 'CMT' => 1,
|
| 133 |
'URL' => 1, 'URLNAME' => 1, 'TIME' => 1);
|
| 134 |
static $wpa = array('GPX WPT' => 1, 'GPX RTE RTEPT' => 1,
|
| 135 |
'GPX TRK TRKSEG TRKPT' => 1);
|
| 136 |
|
| 137 |
$path = join(' ', $gmap_gpx['stack']);
|
| 138 |
array_pop($gmap_gpx['stack']); // remove $name from stack
|
| 139 |
|
| 140 |
$point_type = $gmap_gpx['point_type'];
|
| 141 |
if (isset($wpa[$path])) { // closing tag of one point
|
| 142 |
$gmap_gpx[$point_type]['points'][] = $gmap_gpx['waypoint'];
|
| 143 |
unset($gmap_gpx['waypoint']);
|
| 144 |
unset($gmap_gpx['point_type']);
|
| 145 |
}
|
| 146 |
elseif (isset($gmap_gpx['waypoint'])) { // more info for a point
|
| 147 |
if ($gmap_gpx['in_extension']) {
|
| 148 |
if ($name == 'EXTENSIONS') unset($gmap_gpx['in_extension']);
|
| 149 |
return;
|
| 150 |
}
|
| 151 |
if ($name == 'TIME') {
|
| 152 |
$gmap_gpx['waypoint']['time'] = strtotime($gmap_gpx['char_data']);
|
| 153 |
}
|
| 154 |
else {
|
| 155 |
$gmap_gpx['waypoint'][strtolower($name)] = $gmap_gpx['char_data'];
|
| 156 |
}
|
| 157 |
}
|
| 158 |
elseif ($path == 'GPX RTE') { // end of a route
|
| 159 |
$gmap_gpx['rte'][] = $gmap_gpx['rtept'];
|
| 160 |
unset($gmap_gpx['rtept']);
|
| 161 |
}
|
| 162 |
elseif ($path == 'GPX TRK TRKSEG') { // end of a track segment
|
| 163 |
$gmap_gpx['cur_trk']['segs'][] = $gmap_gpx['trkpt'];
|
| 164 |
unset($gmap_gpx['trkpt']);
|
| 165 |
}
|
| 166 |
elseif ($path == 'GPX TRK') { // end of a track
|
| 167 |
$gmap_gpx['trk'][] = $gmap_gpx['cur_trk'];
|
| 168 |
unset($gmap_gpx['cur_trk']);
|
| 169 |
}
|
| 170 |
elseif (isset($info_tags[$name])) { // more info for track, route or whole file
|
| 171 |
$nl = strtolower($name);
|
| 172 |
$v = ($name == 'time') ? strtotime($gmap_gpx['char_data']) : $gmap_gpx['char_data'];
|
| 173 |
switch ($gmap_gpx['stack'][1]) {
|
| 174 |
case 'RTE':
|
| 175 |
$gmap_gpx['rtept']['info'][$nl] = $v;
|
| 176 |
break;
|
| 177 |
case 'TRK':
|
| 178 |
$gmap_gpx['cur_trk']['info'][$nl] = $v;
|
| 179 |
break;
|
| 180 |
default:
|
| 181 |
$gmap_gpx['info'][$nl] = $v;
|
| 182 |
}
|
| 183 |
}
|
| 184 |
|
| 185 |
unset($gmap_gpx['char_data']);
|
| 186 |
}
|
| 187 |
|
| 188 |
function _gmap_gpx_char_data(&$parser, $data) {
|
| 189 |
global $gmap_gpx;
|
| 190 |
$gmap_gpx['char_data'] .= $data;
|
| 191 |
}
|
| 192 |
|
| 193 |
function _gmap_gpx_latlon_pretty($deg, $pos, $neg, $three = false) {
|
| 194 |
if ($deg > 0) {
|
| 195 |
$str = $pos;
|
| 196 |
}
|
| 197 |
else {
|
| 198 |
$str = $neg;
|
| 199 |
$deg = - $deg;
|
| 200 |
}
|
| 201 |
|
| 202 |
$d = $deg;
|
| 203 |
settype($d, 'integer');
|
| 204 |
$deg -= $d;
|
| 205 |
if ($three && $d < 100)
|
| 206 |
$str .= '0';
|
| 207 |
if ($d < 10)
|
| 208 |
$str .= '0';
|
| 209 |
$str .= $d .'°';
|
| 210 |
|
| 211 |
$deg *= 60;
|
| 212 |
$deg *= 1000;
|
| 213 |
settype($deg, 'integer');
|
| 214 |
$deg /= 1000;
|
| 215 |
$str .= $deg ."'";
|
| 216 |
|
| 217 |
return $str;
|
| 218 |
}
|