#!/usr/bin/perl use Data::Dumper; use Math::Trig; use bytes; #$dir="../"; sub parse_def { my ($file,$prefix,$prefix2)=@_; my $count=0; my $type; my (%map); open(FILE,"$dir/$file"); while () { if (/^$prefix\((.*)\)/) { $map{$1}=$count++; } if (/^$prefix2\(([^,]*),([^,]*)\)/) { $count=$1; $type=$2; $count = oct($count) if $count =~ /^0/; $map{$type}=$count++; } } #print Dumper(\%map); close(FILE); return \%map; } #$item_def=parse_def("item_def.h","ITEM","ITEM2"); #$attr_def=parse_def("attr_def.h","ATTR","ATTR2"); sub deg { my ($deg, $dir)=@_; my ($in,$degi); $in=$deg; $degi=int($deg); $deg-=$degi; $deg*=60; if($degi<0){ $degi=-$degi; $deg=-$deg; if($dir=~/E/){ $dir='W'; } else { $dir='S'; } } return sprintf("%d%09.6f %s", $degi, $deg, $dir); } sub coord { my ($coord)=(@_); return deg($coord->{'lat'}, "N") . " " . deg($coord->{'lon'}, "E"); } sub coord_bin { my ($coord,$bbox)=@_; my $x=$coord->{'lon'}*6371000.0*pi/180; printf("%s\n",deg($coord->{'lon'})); my $y=log(tan(pi/4+$coord->{'lat'}*pi/360))*6371000.0; if (defined($bbox)) { if (!defined($bbox->{'xl'}) || $x < $bbox->{'xl'}) { $bbox->{'xl'}=$x; } if (!defined($bbox->{'xh'}) || $x > $bbox->{'xh'}) { $bbox->{'xh'}=$x; } if (!defined($bbox->{'yl'}) || $y < $bbox->{'yl'}) { $bbox->{'yl'}=$y; } if (!defined($bbox->{'yh'}) || $y > $bbox->{'yh'}) { $bbox->{'yh'}=$y; } } return pack("ll",$x,$y); } sub contains_bbox { my ($xl,$yl,$xh,$yh,$bbox)=@_; # print STDERR "\n"; # print STDERR "$xl,$bbox->{xl},$bbox->{xh},$xh\n"; # print STDERR "$yl,$bbox->{yl},$bbox->{yh},$yh\n"; if ($bbox->{'xh'} < $xl || $bbox->{'xh'} > $xh) { # print STDERR "xh\n"; return 0; } if ($bbox->{'xl'} > $xh || $bbox->{'xl'} < $xl) { # print STDERR "xl\n"; return 0; } if ($bbox->{'yh'} < $yl || $bbox->{'yh'} > $yh) { # print STDERR "yh\n"; return 0; } if ($bbox->{'yl'} > $yh || $bbox->{'yl'} < $yl) { # print STDERR "yl\n"; return 0; } # print STDERR "within\n"; return 1; } sub find_tile { my ($bbox)=@_; my ($x0,$y0,$x1,$y1,$x2,$y2,$i); my $tiles; $x0=-20000000; $y0=-20000000; $x2=+20000000; $y2=+20000000; for ($i=0 ; $i < 14 ; $i++) { # print STDERR "loop tiles=$tiles\n"; $x1=($x0+$x2)/2; $y1=($y0+$y2)/2; if ( contains_bbox($x0,$y0,$x1,$y1,$bbox)) { $tiles.="d"; $x2=$x1; $y2=$y1; } elsif (contains_bbox($x1,$y0,$x2,$y1,$bbox)) { $tiles.="c"; $x0=$x1; $y2=$y1; } elsif (contains_bbox($x0,$y1,$x1,$y2,$bbox)) { $tiles.="b"; $x2=$x1; $y0=$y1; } elsif (contains_bbox($x1,$y1,$x2,$y2,$bbox)) { $tiles.="a"; $x0=$x1; $y0=$y1; } else { return $tiles; #print STDERR "Tile error\n"; #exit(0); } } return $tiles; } $types={ 'amenity'=>{ }, 'building'=>{ }, 'highway'=>{ 'cycleway' => 'street_nopass', 'footway' => 'street_nopass', 'steps' => 'street_nopass', 'cyclepath' => 'street_nopass', 'track' => 'street_nopass', 'service' => 'street_nopass', 'pedestrian' => 'street_nopass', 'residential' => 'street_1_city', 'unclassified' => 'street_1_city', 'tertiary' => 'street_2_city', 'secondary' => 'street_3_city', 'primary' => 'street_4_city', 'trunk' => 'street_4_city', 'trunk_link' => 'ramp', 'motorway' => 'highway_city', 'motorway_link' => 'ramp', }, 'landuse'=>{ 'allotments' => 'wood', 'cemetery' => 'cemetery_poly', }, 'leisure'=>{ 'park' => 'park_poly', }, 'natural'=>{ 'wood' => 'wood', 'water' => 'water_poly', }, 'place'=>{ 'suburb' => 'town_poly', }, 'railway'=>{ 'rail' => 'rail', 'subway' => 'rail', 'tram' => 'rail', }, 'waterway'=>{ 'canal' => 'water_line', 'river' => 'water_line', 'weir' => 'water_line', 'stream' => 'water_line', 'drain' => 'water_line', }, }; while (<>) { $line = $_; chomp($line); if ($line =~ /<(\/[^? ]+)>/) { $tag=$1; } elsif ($line =~ /<([^? ]+)(.*)/) { $tag=$1; $line = $2; %attr=(); while ($line =~ / ([^'"=]+)=['"]([^'"]*)['"](.*)/) { $attr{$1}=$2; $line=$3; } } else { if ($line =~ /<\?xml/) { next; } print STDERR "Unknown $line\n"; next; } #print "tag=$tag\n"; if ($tag eq 'node') { $id=$attr{'id'}; $node{$id}->{'lat'}=$attr{'lat'}; $node{$id}->{'lon'}=$attr{'lon'}; $node{$id}->{'ref'}=0; %tag=(); } elsif ($tag eq '/node') { } elsif ($tag eq 'tag') { if ($attr{'k'} ne 'created_by' && $attr{'k'} ne 'converted_by') { $tag{$attr{'k'}}=$attr{'v'}; } } elsif ($tag eq 'way') { %tag=(); @coords=(); $in_way=1; $way_id=$attr{'id'}; } elsif ($tag eq 'nd') { if ($in_way) { $ref=$attr{'ref'}; $node{$ref}->{'ref'}++; push(@coords,$node{$ref}); } } elsif ($tag eq 'relation') { } elsif ($tag eq 'member') { } elsif ($tag eq '/node') { if (%tag) { #print STDERR Dumper(\%tag); } } elsif ($tag eq '/way') { my @wcoord=@coords; my %wtag=%tag; $way{$way_id}->{'coord'}=\@wcoord; $way{$way_id}->{'tag'}=\%wtag; } elsif ($tag eq '/relation') { } elsif ($tag ne 'osm' && $tag ne '/osm' && $tag ne 'bound') { print STDERR "Unknown $tag\n"; } } sub attr_bin { my ($attr,$val)=@_; my ($adata); if ($attr eq 'label' || $attr eq 'debug') { $adata=$val; while (length($adata)%4) { $adata.="\0"; } } elsif ($attr eq 'limit') { $adata=pack("l", $val); } else { print STDERR "Unknown attr $attr\n"; } # print STDERR "attr=$attr val=$val len=" . length($adata) . "\n"; return pack("lL",1+length($adata)/4,$attr_def->{$attr}) . $adata; } sub write_item_bin { my ($item,$label,$limit,$debug,$coords)=@_; my ($cdata,$adata); my (%bbox); my $tile; foreach $coord (@$coords) { $cdata.=coord_bin($coord,\%bbox); } if (defined($label)) { $adata.=attr_bin('label',$label); } if (defined($limit) && $limit != 0) { $adata.=attr_bin('limit',$limit); } if (defined($debug)) { $adata.=attr_bin('debug',$debug); } $clen=length($cdata)/4; $alen=length($adata)/4; #print STDERR Dumper(\%bbox); $tile=find_tile(\%bbox); #exit(0); open(TILE,">>tiles/$tile"); print TILE pack("lLl", 2+$clen+$alen, $item_def->{$item}, $clen); print TILE $cdata; print TILE $adata; close(TILE); } sub write_item { my ($item,$label,$limit,$debug,$coords)=@_; $oline="type=$type"; if (defined($label)) { $oline.=" label=\"$label\""; } if (defined($limit) && $limit != 0) { $oline.=' limit=$limit'; } if (defined($debug)) { $oline.=" debug=\"$debug\""; } print "$oline\n"; foreach $coord (@$coords) { print coord($coord) . "\n"; } } while (($way_id, $way) = each %way) { #print STDERR "Way: $way_id\n"; #print STDERR Dumper($way); $type=''; while (($key, $value) = each %$types) { $tagval=$way->{'tag'}->{$key}; if ($tagval ne '') { $newtype=$types->{$key}->{$tagval}; if ($newtype eq '') { $types->{$key}->{$tagval}='street_unkn'; print STDERR "way $way_id Unknown $key $tagval\n"; $newtype='street_unkn'; } if ($type ne '') { print STDERR "way $way_id conflict:\n"; print STDERR Dumper(\%tag); } $type=$newtype; } } if ($type eq '') { print STDERR "way $way_id unknown type:\n"; print STDERR Dumper($way->{'tag'}); $type='street_unkn'; } $limit=0; $oneway=$way->{'tag'}->{'name'}; if ($oneway eq 'true' || $oneway eq 'yes') { $limit=1; } $debug="way_id=$way_id"; while (($key,$value)=each(%{$way->{'tag'}})) { $debug .= " $key='$value'"; } #print STDERR $way->{'coord'} . "\n"; $count=$#{$way->{'coord'}}; write_item($type, $way->{'tag'}->{'name'},$limit,$debug,$way->{'coord'}); # write_item_bin($type, $way->{'tag'}->{'name'},$limit,$debug,$way->{'coord'}); # for ($i=0 ; $i <= $count ; $i++) { # print coord($way->{'coord'}[$i]) . "\n"; # } } #print STDERR Dumper($types); #while (($key,$value)=each(%reference)) { # if ($value != 1) { # print STDERR "$key $value\n"; # } #}