Fixcoastlines.pl
From OpenStreetMap Wiki
#!/usr/bin/perl
use XML::Parser;
# Rename to local OSM filename
$osmfile = "brighton.osm";
sub parseElem {
my $e = shift;
my $attr = shift;
shift;
$$e = shift;
for (my $i = 0; $i < scalar(@_); $i += 2) {
$$attr{ $_[ $i ] } = $_[ $i+1 ];
}
}
sub stringElem {
my $e = shift;
my $attr = shift;
$elem = "<" . $$e;
foreach my $a (keys(%$attr)) {
$elem .= " " . $a . "=\"" . $$attr{$a} . "\"";
}
$elem .= ">";
return $elem;
}
sub handle_start {
my $e, %attr;
parseElem(\$e,\%attr,@_);
if ($way) {
# We are processing a Way
# Check for almien_coastlines
if ($e eq "tag" && $attr{'k'} eq "created_by" && $attr{'v'} eq "almien_coastlines") {
$almien = 1;
}
# Store tags and other contents (we write almien tags only once)
if ($e eq "tag") {
$waytags .= stringElem(\$e,\%attr);
} else {
$waycontents .= stringElem(\$e,\%attr);
}
} elsif ($e eq "way") {
# Start processing a Way, store start tag
$way = stringElem(\$e,\%attr);
} else {
# Just output
print stringElem(\$e,\%attr);
}
undef %attr;
}
sub handle_char {
my ($p,$data) = @_;
if ($way) {
$waycontents .= $data;
} else {
print $data;
}
}
sub handle_close {
shift;
my $e = shift;
if ($way) {
if ($e eq "way") {
# If way is closing, store if almien, otherwise output
if ($almien) {
$almiencontents .= $waycontents;
} else {
print $way . $waycontents . $waytags ."</way>";
}
#clear storage
undef $way;
undef $waycontents;
undef $waytags;
undef $almien;
} elsif ($e eq "tag") {
$waytags .= "</" . $e . ">\n";
} else {
$waycontents .= "</" . $e . ">";
}
} elsif ($e eq "osm") {
# Document is finished, output almien
print '<way id="999999999" timestamp="2006-10-09 10:00:00">' . "\n";
print $almiencontents;
print '<tag k="create_by" v="almien_coastlines"/>' . "\n";
print '<tag k="source" v="PGS"/>' . "\n";
print '<tag k="natural" v="coastline"/>' . "\n";
print '</way>';
print "</osm>";
} else {
print "</" . $e . ">";
}
}
$xp = new XML::Parser(Handlers => {Start => \&handle_start,
Char => \&handle_char,
End => \&handle_close});
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
eval {
$xp->parsefile($osmfile);
};