source: subversion/applications/rendering/gpx_slippy_map/gpx.php @ 30322

Last change on this file since 30322 was 7921, checked in by ojw, 11 years ago

note the change of file format

File size: 4.5 KB
Line 
1<?php
2#----------------------------------------------------------------
3# Load a GPX tracklog from openstreetmap.org/traces and
4# store it in a binary file
5#
6#------------------------------------------------------
7# File format:
8#
9# +---------+--------+------+--------------------------+
10# | size    | type   | name | description              |
11# +---------+--------+------+--------------------------+
12# | 4 bytes | int    | n    | number of trackpoints    |
13# | 8 bytes | double | xmin | bounding box (W)         |
14# | 8 bytes | double | xmax | bounding box (E)         |
15# | 8 bytes | double | ymin | bounding box (S)         |
16# | 8 bytes | double | ymax | bounding box (N)         |
17# +---------+--------+------+--------------------------+
18#   then n pairs of:
19# +---------+--------+------+--------------------------+
20# | 4 bytes | int    | x    | coded position           |
21# | 4 bytes | int    | y    | coded position           |
22# +---------+--------+------+--------------------------+
23#
24# xmin,xmax,ymin,ymax,x,and y are stored as positions
25# relative to the coverage of the slippy map system
26#
27# x positions from 0 = 180 degrees west to 1 = 180 degrees west
28# y positions from 0 = 85.0511 north to 1 = 85.0511 south
29#
30# note that these are in the mercator projection, i.e.
31# dLat/dy is not constant
32#
33# encoding of x and y:
34# the positions described above are divided by 2^31 for
35# storage as an integer,
36# i.e.:
37#  x: 0 = fully west, to 2^31-1 = fully east
38#  y: 0 = fully north, to 2^31-1 = fully south
39#
40# integers are big-endian
41# double-precision floats are platform-dependant
42#------------------------------------------------------
43# Copyright 2008, Oliver White
44#
45# This program is free software: you can redistribute it and/or modify
46# it under the terms of the GNU General Public License as published by
47# the Free Software Foundation, either version 3 of the License, or
48# (at your option) any later version.
49#
50# This program is distributed in the hope that it will be useful,
51# but WITHOUT ANY WARRANTY; without even the implied warranty of
52# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
53# GNU General Public License for more details.
54#
55# You should have received a copy of the GNU General Public License
56# along with this program.  If not, see <http://www.gnu.org/licenses/>.
57#------------------------------------------------------
58include_once("projection.php");
59
60function getGpx($ID)
61{
62  $URL = sprintf("http://www.openstreetmap.org/trace/%d/data", $ID);
63  $Filename = sprintf("cache/gpx_%d", $ID);
64 
65  if(file_exists($Filename))
66    return($Filename);
67 
68  $fpOut = fopen($Filename, "wb");
69  if(!$fpOut)
70    return("");
71   
72  $fpIn = fopen($URL, "r");
73  if(!$fpIn)
74    {
75    fclose($fpOut);
76    return("");
77    }
78 
79  # extents of data
80  $A = 1;
81  $B = 0;
82  $C = 1;
83  $D = 0;
84  $Count = 0;
85 
86  # Reserve space for header
87  fwrite($fpOut, pack("N", 0), 4);
88  fwrite($fpOut, pack("d4", 0,0,0,0), 32);
89 
90  $Resolution = 1 / pow(2.0, 31);
91 
92  while(!feof($fpIn))
93  {
94    $Line = fgets($fpIn, 400);
95    if(preg_match('{<trkpt lat="(.*?)" lon="(.*?)">}', $Line, $Matches))
96    {
97      list($x,$y) = latlon2relativeXY($Matches[1]+0, $Matches[2]+0);
98     
99      fwrite($fpOut, pack("NN", $x / $Resolution, $y / $Resolution), 8);
100     
101      if($x < $A) $A = $x;
102      if($x > $B) $B = $x;
103      if($y < $C) $C = $y;
104      if($y > $D) $D = $y;
105      $Count++;
106    }
107  }
108 
109  # Write the file header
110  fseek($fpOut, 0, SEEK_SET);
111  fwrite($fpOut, pack("N", $Count), 4);
112  fwrite($fpOut, pack("d4", $A,$B,$C,$D), 32);
113 
114  fclose($fpIn);
115  fclose($fpOut);
116  return($Filename);
117}
118
119function getMeta($Filename, $LeaveOpen = 0)
120{
121  # Default data
122  $Data = array(
123    'exists'=>0, 
124    'size'=>filesize($Filename),
125    'filename'=>$Filename);
126 
127  # Does it contain enough data for the header?
128  $Data['valid'] = ($Data['size'] >= 4 + 32);
129 
130  # Try to open file
131  $fp = fopen($Filename, "rb");
132  if($fp)
133    {
134    $Data['exists'] = 1;
135    if($Data['valid'])
136      {
137      list(
138        $Spare, 
139        $Data['points']) = unpack("N", fread($fp, 4));
140      list(
141        $Spare,
142        $Data['xmin'], 
143        $Data['xmax'], 
144        $Data['ymin'], 
145        $Data['ymax']) = unpack("d4", fread($fp, 32));
146      }
147
148    # Now that we have the file open, option to return the filehandle
149    # if the calling function wants to continue reading data
150    if($LeaveOpen && $Data['valid'])
151      {
152      $Data['fp'] = $fp;
153      }
154    else
155      {
156      fclose($fp);
157      }
158    }
159  return($Data);
160}
161
162if($_GET['test_gpx_reader'])
163{
164  header("Content-type:text/plain");
165  $a = getGpx(112168);
166  print_r(getMeta($a));
167}
168
169?>
Note: See TracBrowser for help on using the repository browser.