source: subversion/sites/other/trapi/fetchz.pl @ 12298

Revision 12298, 8.1 KB checked in by blarson, 5 years ago (diff)

Tiled Read-only API

Serves osm data optimized for tiles@home.

Line 
1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
6use constant VERSION=0;
7use ptdb;
8
9ptdbinit("<");
10
11my ($ptn, $n, $tn, $lat, $lon, $off, $key, $val, $w, $tw, $tr);
12my (%pw, %pn, %pr, %tiles);
13
14my ($bbs, $bbw, $bbn, $bbe);
15
16print "Content-Type: text/xml; charset=utf8\n\n";
17
18$_ = $ARGV[0];
19if (/map\?bbox\=(-?\d+(?:\.\d*)?)\,(-?\d+(?:\.\d*)?)\,(-?\d+(?:\.\d*)?)\,(-?\d+(?:\.\d*)?)$/) {
20# print "WSEN: $1, $2, $3, $4\n";
21    my ($west,$south) = getTileNumber($2,$1,14);
22    my ($east,$north) = getTileNumber($4,$3,14);
23# print "WSEN: $west, $south, $east, $north\n";
24    my ($x, $y);
25    for($y=$north; $y <= $south; $y++) {
26        for($x=$west; $x <= $east; $x++) {
27            $tiles{etoptn($x,$y)} = 1;
28        }
29    }
30    ($bbs, $bbw, undef, undef) = Project($west, $south, 14);
31    (undef, undef, $bbn, $bbe) = Project($east, $north, 14);
32} elsif (/node\/(\d+)$/) {
33    my $node = $1;
34    $ptn = nodeptn($node);
35    $pn{$ptn} = {$node => 1};
36} elsif (/way\/(\d+)$/) {
37    my $way = $1;
38    $ptn = wayptn($way);
39    $pw{$ptn} = {$way => 1};
40} elsif (/relation\/(\d+)$/) {
41    my $rel = $1;
42    $ptn = relationptn($rel);
43    $pr{$ptn} = {$rel => 1};
44} else {
45    die "Unknown request $_";
46}
47
48print "<?xml version='1.0' encoding='UTF-8'?>\n";
49print "<osm version=\"0.5\" generator=\"Trapi 0.0\">\n";
50if ($bbs) {
51  print "<bound box=\"$bbs,$bbw,$bbn,$bbe\" origin=\"http://www.openstreetmap.org/api/0.5\"/>\n";
52}
53
54foreach $ptn (keys %tiles) {
55    my $nd = openptn($ptn, "<", "data");
56    my $wf = openptn($ptn, "<", "ways");
57    my $rf = openptn($ptn, "<", "relations");
58
59# first we go through the ways, looking for ones stored remotely or with nodes
60# not in the tile
61    seek $wf, 0, 0;
62    while (read $wf, $w, 8) {
63      ($tw, $off) = unpack "NN", $w;
64      next unless($tw);
65      if ($off == 0) {
66        # way stored remotly
67        $w = wayptn($tw);
68# print "Remote way $tw\n";
69        unless (exists $tiles{$w}) {
70            unless (defined $pw{$w}) {
71                $pw{$w} = {};
72            }
73            ${$pw{$w}}{$tw} = 1;
74        }
75      } else {
76        seek $nd, $off, 0;
77        while(read $nd, $n, 4) {
78          ($tn) = unpack "N", $n;
79          last unless ($tn);
80          $n = nodeptn($tn);
81          unless (exists $tiles{$n}) {
82            # node stored remotly
83            unless (defined $pn{$n}) {
84              $pn{$n} = {};
85            }
86            ${$pn{$n}}{$tn} = 1;
87          }
88        }
89      }
90    }
91    seek $rf, 0, 0;
92    while (read $rf, $w, 8) {
93      ($tr, $off) = unpack "NN", $w;
94      next unless($tr);
95      if ($off == 0) {
96        my $r = relationptn($tr);
97        unless (exists $tiles{$r}) {
98          unless (defined $pr{$r}) {
99            $pr{$r} = {};
100          }
101          ${$pr{$r}}{$tr} = 1;
102        }
103      }
104    }
105}
106
107# now we go through the remote ways, looking for nodes and ways not in the tile
108  foreach my $tp (keys %pw) {
109    my $pwf = openptn($tp, "<", "ways");
110    my $pd = openptn($tp, "<", "data");
111    seek $pwf, 0, 0;
112    while (read $pwf, $w, 8) {
113      ($tw, $off) = unpack "NN", $w;
114      next unless($tw);
115      if (exists ${$pw{$tp}}{$tw}) {
116        seek $pd, $off, 0;
117        while(read $pd, $n, 4) {
118          ($tn) = unpack "N", $n;
119          last unless ($tn);
120          $n = nodeptn($tn);
121          unless (exists $tiles{$n}) {
122          # node stored remotly
123            unless (defined $pn{$n}) {
124              $pn{$n} = {};
125            }
126            ${$pn{$n}}{$tn} = 1;
127          }
128        }
129      }
130    }
131  }
132   
133# print nodes in the tile
134foreach $ptn (keys %tiles) {
135    my $nf = openptn($ptn, "<", "nodes");
136    my $nd = openptn($ptn, "<", "data");
137
138    my ($z, $x, $y) = fromptn($ptn);
139    print "<-- nodes from z$z $x $y >\n";
140    seek $nf, 0, 0;
141    while (read $nf, $n, 16) {
142        ($tn, $lat, $lon, $off) = unpack "NN!N!N", $n;
143        next unless($tn);
144        $lat /= 10000000;
145        $lon /= 10000000;
146        print "<node id=\"$tn\" lat=\"$lat\" lon=\"$lon\" ";
147        if ($off == 0) {
148            print "/>\n";
149        } else {
150            print ">\n";
151            seek $nd, $off, 0;
152            while ($key = gets $nd) {
153                $val = gets $nd;
154                print "  <tag k=\"$key\" v=\"$val\"/>\n";
155            }
156            print "</node>\n";
157        }
158    }
159}
160
161# print the nodes used by ways
162
163    foreach my $tp (keys %pn) {
164      my ($tz, $tx, $ty) = fromptn($tp);
165      print "<-- some nodes from z$tz $tx $ty >\n";
166      my $pnf = openptn($tp, "<", "nodes");
167      my $pd = openptn($tp, "<", "data");
168      seek $pnf, 0, 0;
169      while(read $pnf, $n, 16) {
170        ($tn, $lat, $lon, $off) = unpack "NN!N!N", $n;
171        next unless($tn);
172        if (exists ${$pn{$tp}}{$tn}) {
173          $lat /= 10000000;
174          $lon /= 10000000;
175          print "<node id=\"$tn\" lat=\"$lat\" lon=\"$lon\" ";
176          if ($off == 0) {
177            print "/>\n";
178          } else {
179            print ">\n";
180            seek $pd, $off, 0;
181            while ($key = gets $pd) {
182              $val = gets $pd;
183              print "  <tag k=\"$key\" v=\"$val\"/>\n";
184            }
185            print "</node>\n";
186          }
187        }
188      }
189    }
190
191# print ways
192foreach $ptn (keys %tiles) {
193    my $nd = openptn($ptn, "<", "data");
194    my $wf = openptn($ptn, "<", "ways");
195
196    my ($z, $x, $y) = fromptn($ptn);
197    print "<-- ways from z$z $x $y >\n";
198    seek $wf, 0, 0;
199    while(read $wf, $w, 8) {
200      ($tw, $off) = unpack "NN", $w;
201      next unless ($tw);
202      next unless ($off);
203      print "<way id=\"$tw\">\n";
204      seek $nd, $off, 0;
205      while (read $nd, $w, 4) {
206        ($tn) = unpack "N", $w;
207        last if($tn == 0);
208        print "  <nd ref=\"$tn\"/>\n";
209      }
210      while ($key = gets $nd) {
211        $val = gets $nd;
212        print "  <tag k=\"$key\" v=\"$val\"/>\n";
213      }
214      print "</way>\n";
215    }
216  }
217
218    foreach my $tp (keys %pw) {
219      my ($tz, $tx, $ty) = fromptn($tp);
220      print "<-- some ways from z$tz $tx $ty >\n";
221      my $pwf = openptn($tp, "<", "ways");
222      my $pd = openptn($tp, "<", "data");
223      seek $pwf, 0, 0;
224      while (read $pwf, $w, 8) {
225        ($tw, $off) = unpack "NN", $w;
226        next unless($tw);
227        if ($off && exists ${$pw{$tp}}{$tw}) {
228          print "<way id=\"$tw\">\n";
229          seek $pd, $off, 0;
230          while(read $pd, $n, 4) {
231            ($tn) = unpack "N", $n;
232            last unless ($tn);
233            print "  <nd ref=\"$tn\"/>\n";
234          }
235          while ($key = gets $pd) {
236            $val = gets $pd;
237            print "  <tag k=\"$key\" v=\"$val\"/>\n";
238          }
239          print "</way>\n";
240        }
241      }
242    }
243
244# print relations
245
246foreach $ptn (keys %tiles) {
247  my $nd = openptn($ptn, "<", "data");
248  my $rf = openptn($ptn, "<", "relations");
249 
250  my ($z, $x, $y) = fromptn($ptn);
251  print "<-- relations from z$z $x $y>\n";
252  seek $rf, 0, 0;
253  while (read $rf, $w, 8) {
254    ($tr, $off) = unpack "NN", $w;
255    next unless ($tr);
256    next unless ($off);
257    print "<relation id=\"$tr\">\n";
258    seek $nd, $off, 0;
259    while (read $nd, $w, 4) {
260      ($tn) = unpack "N", $w;
261      last unless ($tn);
262      my $role = gets($nd);
263      print "  <member type=\"node\" ref=\"$tn\" role=\"$role\"/>\n";
264    }
265    while (read $nd, $w, 4) {
266      ($tw) = unpack "N", $w;
267      last unless ($tw);
268      my $role = gets($nd);
269      print "  <member type=\"way\" ref=\"$tw\" role=\"$role\"/>\n";
270    }
271    while (read $nd, $w, 4) {
272      ($tw) = unpack "N", $w;
273      last unless ($tw);
274      my $role = gets($nd);
275      print "  <member type=\"relation\" ref=\"$tw\" role=\"$role\"/>\n";
276    }
277      while ($key = gets $nd) {
278        $val = gets $nd;
279        print "  <tag k=\"$key\" v=\"$val\"/>\n";
280      }
281    print "</relation>\n";
282  }
283}
284
285foreach my $tp (keys %pr) {
286  my ($tz, $tx, $ty) = fromptn($tp);
287  print "<-- some relations from z$tz $tx $ty >\n";
288  my $prf = openptn($tp, "<", "relations");
289  my $pd = openptn($tp, "<", "data");
290  seek $prf, 0, 0;
291  while (read $prf, $w, 8) {
292    ($tr, $off) = unpack "NN", $w;
293    next unless($tr);
294    if ($off && exists ${$pr{$tp}}{$tr}) {
295      print "<relation id=\"$tr\">\n";
296      seek $pd, $off, 0;
297      while (read $pd, $w, 4) {
298        ($tn) = unpack "N", $w;
299        last unless ($tn);
300        my $role = gets($pd);
301        print "  <member type=\"node\" ref=\"$tn\" role=\"$role\"/>\n";
302      }
303      while (read $pd, $w, 4) {
304        ($tw) = unpack "N", $w;
305        last unless ($tw);
306        my $role = gets($pd);
307        print "  <member type=\"way\" ref=\"$tw\" role=\"$role\"/>\n";
308      }
309      while (read $pd, $w, 4) {
310        ($tw) = unpack "N", $w;
311        last unless ($tw);
312        my $role = gets($pd);
313        print "  <member type=\"relation\" ref=\"$tw\" role=\"$role\"/>\n";
314      }
315      while ($key = gets $pd) {
316        $val = gets $pd;
317        print "  <tag k=\"$key\" v=\"$val\"/>\n";
318      }
319      print "</relation>\n";
320    }
321  }
322}
323
324print "</osm>\n";
Note: See TracBrowser for help on using the repository browser.