Skip to content

Instantly share code, notes, and snippets.

@mojodna
Created February 21, 2011 18:19
Show Gist options
  • Save mojodna/837466 to your computer and use it in GitHub Desktop.
Save mojodna/837466 to your computer and use it in GitHub Desktop.
Extract OSM POIs and dump them as gardump/garload
#!/usr/bin/env perl
use warnings;
use strict;
use Data::Dumper;
use XML::XPath;
use XML::XPath::XMLParser;
my @exp = (
'//node/tag[@k="amenity"]/..',
'//node/tag[@k="atm"]/..',
'//node/tag[@k="historic"]/..',
'//node/tag[@k="place"]/..',
'//node/tag[@k="shop"]/..',
'//node/tag[@k="tourism"]/..',
);
my %sym = (
'aeroway:aerodrome' => 16384,
'amenity:airport' => 16384,
'amenity:arts_centre' => 161,
'amenity:bank' => 6,
'amenity:bar' => 13,
'amenity:bureau_de_change' => 6,
'amenity:bus_station' => 175,
'amenity:cafe' => 11,
'amenity:ferry_terminal' => 0,
'amenity:fuel' => 8,
'amenity:hospital' => 156,
'amenity:marketplace' => 172,
'amenity:parking' => 158,
'amenity:place_of_worship' => 8236,
'amenity:police' => 8226,
'amenity:police station (mahonda)' => 8226,
'amenity:post_office' => 8214,
'amenity:restaurant' => 11,
'amenity:school' => 1,
'amenity:taxi' => 170,
'amenity:telephone' => 155,
'amenity:toilets' => 152,
'amenity:university' => 1,
'atm:yes' => 6,
'bridge:yes' => 8233,
'building:yes' => 8234,
'historic:monument' => 8235,
'historic:ruins' => 8235,
'internet_access:terminal' => 8227,
'leisure:pitch' => 169,
'leisure:sport' => 169,
'leisure:sports_centre' => 169,
'man_made:lighthouse' => 16391,
'man_made:tower' => 16391,
'parking:surface' => 158,
'place:city' => 8200,
'place:island' => 8244,
'place:suburb' => 18,
'place:town' => 8199,
'place:village' => 8198,
'shop:books' => 172,
'shop:greengrocer' => 172,
'shop:supermarket' => 172,
'shop:travel_agency' => 157,
'shop:video' => 8210,
'sport:scuba_diving' => 21,
'sport:soccer' => 169,
'sport:swimming' => 163,
'tourism:artwork' => 161,
'tourism:attraction' => 161,
'tourism:clock tower' => 161,
'tourism:guest_house' => 173,
'tourism:hotel' => 173,
'tourism:information' => 157,
'tourism:museum' => 161,
'tourism:viewpoint' => 161,
'tourism:zoo' => 161,
);
sub tags {
my $n = shift;
my %t;
foreach my $c ($n->getChildNodes())
{
next unless $c->getNodeType() eq XML::XPath::Node::ELEMENT_NODE;
next unless $c->getName() eq 'tag';
my $k = $c->getAttribute('k');
my $v = $c->getAttribute('v');
if (defined($t{$k})) {
$t{$k} = [ $t{$k} ] unless ref($t{$k}) eq 'ARRAY';
push @{$t{$k}}, $v;
} else {
$t{$k} = $v;
}
}
%t;
}
sub findsym {
my %tag = @_;
my @res;
my @order = qw/aeroway tourism amenity shop atm historic/;
push @order, keys %tag;
foreach my $t (@order)
{
next unless $tag{$t};
my $vs = $tag{$t};
$vs = [ $vs ] unless ref($vs) eq 'ARRAY';
foreach my $v (@$vs) {
my $k = "$t:$v";
push @res, $sym{$k} if ($sym{$k});
}
}
foreach my $n (173, 11, 6, 13, 172) {
return $n if grep {$n == $_} @res;
}
push @res, 18;
return shift @res;
}
sub node2gpx {
my $n = shift;
my $lat = $n->getAttribute('lat');
my $lon = $n->getAttribute('lon');
my %tag = tags($n);
print "<wpt lat=\"$lat\" lon=\"$lon\">";
# name (shorten desc)
# cmt (convert to upper?)
print "<cmt>$tag{name}</cmt>" if $tag{name};
# description (not used by GPS)
print "<desc>$tag{name}</desc>" if $tag{name};
# symbol name/number (use amenity/atm/historic/place/shop/tourism)
print "<sym>", findsym(%tag), "</sym>";
# <type> Type name (category / classificaiton) of waypoint
print "</wpt>\n";
#print join(",", "lat: $lat, lon: $lon", %tag), "\n";
}
sub shorten {
my $s = shift;
$s =~ s/[-+=.,;:'"`~!@#\$\%^&*()]//g;
$s =~ s/[\s_]+/_/g;
$s =~ tr/a-z/A-Z/;
return $s;
}
sub node2dump {
my $n = shift;
my $lat = $n->getAttribute('lat');
my $lon = $n->getAttribute('lon');
my %tag = tags($n);
# description (not used by GPS)
my $desc = join(", ", map { my $a=$_; map { "$a:$_" } ( ref($tag{$_}) eq 'ARRAY' ? @{$tag{$_}} : $tag{$_} ) } sort keys %tag);
print "# $desc\n";
print " $lat $lon";
# symbol name/number (use amenity/atm/historic/place/shop/tourism)
print " S:", findsym(%tag);
# name (shorten desc)
print " I:", shorten($tag{name}) if $tag{name};
# cmt (convert to upper?)
print "\n";
#print join(",", "lat: $lat, lon: $lon", %tag), "\n";
}
my %d;
foreach my $fn (@ARGV) {
print STDERR "==> $fn\n";
my $xp = XML::XPath->new(filename => $fn);
foreach my $e (@exp) {
my $nodes = $xp->find($e);
#print STDERR "===> $e\n";
#print Dumper($nodes), "\n";
map { $d{$_->getAttribute('id')} = $_ } $nodes->get_nodelist;
}
}
my $n = scalar keys %d;
print "[waypoints, $n records]\n";
map { node2dump($_) } values %d;
print "[end transfer, $n/$n records]\n";
#print <<EOF;
#<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
#<gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1" creator="osm2gpx.pl"
# xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
# xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
#EOF
#map { node2gpx($_) } values %d;
#print "</gpx>\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment