summaryrefslogtreecommitdiff
path: root/scripts/osm/perl_lib
diff options
context:
space:
mode:
authorChristian Perrier <bubulle@debian.org>2012-10-07 13:27:36 +0100
committerChristian Perrier <bubulle@debian.org>2012-10-07 13:27:36 +0100
commit99f5c8bf63a674faf8c507aea7425b935814548a (patch)
treeb3202c295c4bb71ec09e3748d49b43a9fec6b4cd /scripts/osm/perl_lib
gpsdrive (2.10~pre4-6.dfsg-5.2) unstable; urgency=low
* Non-maintainer upload [ Allison Randal ] * Disable optional mapnik libraries, gpsdrive is incompatible with APIs of mapnik version 2.0.0. * debian/patches/107-fix-disable-mapnik.dpatch: Fix known bug with gpsdrive-2.10pre4 when disabling Mapnik library. # imported from the archive
Diffstat (limited to 'scripts/osm/perl_lib')
-rw-r--r--scripts/osm/perl_lib/Geo/Filter/Area.pm179
-rw-r--r--scripts/osm/perl_lib/Geo/GPX/File.pm317
-rw-r--r--scripts/osm/perl_lib/Geo/Geometry.pm213
-rwxr-xr-xscripts/osm/perl_lib/Geo/Gpsdrive/DBFuncs.pm742
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/DB_Defaults.pm185
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/DB_tracks.pmbin0 -> 7513 bytes
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/Defaults_Cities.pm513
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/Gps.pm236
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/GpsDrive.pm255
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/JiGLE.pm154
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/Kismet.pm156
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/NGA.pm822
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/OSM.pm621
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB.pm239
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB2.pm243
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/PocketGpsPoi.pm130
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/Utils.pm260
-rwxr-xr-xscripts/osm/perl_lib/Geo/Gpsdrive/WDB.pm204
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/Way_Txt.pm188
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/census.pm86
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/getstreet.pm276
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/gettraffic.pm90
-rw-r--r--scripts/osm/perl_lib/Geo/Gpsdrive/mapsource.pm99
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/APIClientV4.pm226
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/APIClientV5.pm221
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/EntitiesV3.pm296
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/EntitiesV5.pm375
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/MapFeatures.pm194
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV3.pm323
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV5.pm314
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/OsmReaderV3.pm246
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/OsmReaderV5.pm249
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/OsmXML.pm161
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/Planet.pm318
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/SegmentList.pm338
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/Tracks2OSM.pm234
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/Upload.pm145
-rw-r--r--scripts/osm/perl_lib/Geo/OSM/Write.pm179
-rw-r--r--scripts/osm/perl_lib/Geo/Tracks/GpsBabel.pm82
-rw-r--r--scripts/osm/perl_lib/Geo/Tracks/Kismet.pm125
-rw-r--r--scripts/osm/perl_lib/Geo/Tracks/NMEA.pm373
-rw-r--r--scripts/osm/perl_lib/Geo/Tracks/TRK.pm143
-rw-r--r--scripts/osm/perl_lib/Geo/Tracks/Tools.pm395
-rw-r--r--scripts/osm/perl_lib/Makefile.am38
-rw-r--r--scripts/osm/perl_lib/Makefile.in581
-rw-r--r--scripts/osm/perl_lib/Utils/Debug.pm169
-rw-r--r--scripts/osm/perl_lib/Utils/File.pm171
-rw-r--r--scripts/osm/perl_lib/Utils/LWP/Utils.pm134
-rw-r--r--scripts/osm/perl_lib/Utils/Math.pm65
49 files changed, 12303 insertions, 0 deletions
diff --git a/scripts/osm/perl_lib/Geo/Filter/Area.pm b/scripts/osm/perl_lib/Geo/Filter/Area.pm
new file mode 100644
index 0000000..e99970c
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Filter/Area.pm
@@ -0,0 +1,179 @@
+##################################################################
+package Geo::Filter::Area;
+##################################################################
+
+use strict;
+use warnings;
+use Carp;
+
+use Data::Dumper;
+
+# ------------------------------------------------------------------
+my $AREA_DEFINITIONS = {
+ # min | max
+ # [ lat , lon, lat, lon ]
+ uk => [ [ 49.7, -7.6, 58.8, 3.2 ], # Great Britain (GB)
+ [ 49.9, -5.8, 54.0, 0.8 ], # NI
+ ],
+ ni => [ [ 49.9, -5.8, 54.0, 0.8 ] ], # NI
+ gb => [ [ 49.7, -7.6, 58.8, 3.2 ] ], # Great Britain (GB)
+
+ iom => [ [ 49.0, -11.0, 64.0, 3.0 ] ],
+ france => [ [ 42.3, -1.7, 51.1, 8.2 ] ],
+ germany => [ [ 47.0, 5.0, 55.1, 16.0 ] ],
+ bavaria => [ [ 47.0, 10.0, 50.1, 16.0 ] ],
+ turkey => [ [ 35.8, 26.0, 42.5, 45.0 ] ],
+ hamburg => [ [ 53.40133,9.623, 53.7676,10.36 ] ],
+ switzerland => [ [ 45.5, 6.0 , 47.5 , 10.3 ] ],
+ spain => [ [ 35.5, -9.0, 44.0, 4.0 ] ],
+ iceland => [ [ 62.2, -24.4, 66.8, -12.2 ] ],
+ italy => [ [ 46.5, 6.75, 46.6, 14.0 ],
+ [ 40.0, 8.0, 45.5, 12.47 ],
+ [ 35.0, 10.0, 42.0, 18.0 ],
+ ],
+ australia => [ [ -44.0, 110.0, -10.0, 154.0 ] ],
+ newzealand => [ [ -50.0, 160.0, -30.0, 180.0 ] ],
+ norway => [ [ 56.0, 2.0, 78.0, 16.0 ] ],
+ africa => [ [ -35.0, -20.0, 38.0, 55.0 ] ],
+ # Those eat up all memory on normal machines
+ europe => [ [ 35.0, -12.0, 75.0, 35.0 ],
+ [ 62.2, -24.4, 66.8, -12.2 ], # Iceland
+ ],
+ southafrica => [ [ -34.9, 16.4, -22.1, 33 ] ],
+ world_east => [ [ -90.0, -30.0, 90.0, 180.0 ] ],
+ world_west => [ [ -90.0,-180.0, 90.0, -30.0 ] ],
+ world => [ [ -90.0,-180.0, 90.0, 180.0 ] ],
+};
+
+# ------------------------------------
+my $stripe_lon = -180;
+my $stripe_step = 45;
+my $stripe_overlap = 0.2;
+while ( $stripe_lon < 180 ){
+ my $stripe_lon1=$stripe_lon+$stripe_step+$stripe_overlap;
+ $AREA_DEFINITIONS->{"stripe_${stripe_lon}_${stripe_lon1}"} =
+ [ [ -90,$stripe_lon,
+ 90, $stripe_lon1] ];
+ $stripe_lon=$stripe_lon+$stripe_step;
+}
+
+# ------------------------------------
+sub new($;@){
+ my $class = shift;
+ if( scalar(@_) % 2 ) {
+ Carp::confess("uneven amount of options\n");
+ };
+ my %options = @_;
+
+ my $self={};
+ my $area;
+ if ( defined $options{lat_min} &&
+ defined $options{lon_min} &&
+ defined $options{lat_max} &&
+ defined $options{lon_max}
+ ) {
+ $self->{area_filters}= [
+ [$options{lat_min},$options{lon_min},
+ $options{lat_max},$options{lon_max}]
+ ];
+ $self->{area_name} = "[$options{lat_min},$options{lon_min}".
+ " .. ".
+ "$options{lat_max},$options{lon_max}]";
+
+ } elsif ( defined $options{area} ) {
+ $area = delete $options{area};
+ if ( ! defined ( $AREA_DEFINITIONS->{$area} ) ) {
+ die "unknown area $area.\n".
+ "Allowed Areas:\n\t".
+ join("\n\t",$class->allowed_areas())."\n";
+ }
+ $self->{area_name} = $area;
+ $self->{area_filters} = $AREA_DEFINITIONS->{$area};
+ }
+
+ if( scalar(@_) % 2 ) {
+ Carp::confess("uneven amount of options for area->new()\n");
+ };
+ bless ($self,$class);
+ return $self;
+}
+
+sub list_areas($) {
+ my $class = shift;
+ return join("\n",$class->allowed_areas());
+}
+
+sub allowed_areas($) {
+ my $class = shift;
+ return sort keys %{$AREA_DEFINITIONS};
+}
+
+sub name($) {
+ my $self = shift;
+ return $self->{area_name};
+}
+
+# ------------------------------------------------------------------
+
+sub inside($$){
+ my $self = shift;
+ my $obj = shift;
+
+ my $area_filters=$self->{area_filters};
+ #print "in_area(".Dumper(\$obj).")";;
+ #print Dumper(\$area_filters);
+ for my $a ( @{$area_filters} ) {
+ if (
+ $obj->{lat} >= $a->[0] &&
+ $obj->{lon} >= $a->[1] &&
+ $obj->{lat} <= $a->[2] &&
+ $obj->{lon} <= $a->[3] ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+# ------------------------------------------------------------------
+
+my $test_area = Geo::Filter::Area->new(area=>"uk");
+if ( $test_area->inside({lat=>10,lon=>10})) {
+ Carp::confess("Area filters are not working\n");
+};
+
+1;
+
+
+__END__
+
+=head1 NAME
+
+Area.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/GPX/File.pm b/scripts/osm/perl_lib/Geo/GPX/File.pm
new file mode 100644
index 0000000..4ac1861
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/GPX/File.pm
@@ -0,0 +1,317 @@
+##################################################################
+package Geo::GPX::File;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( read_gpx_file write_gpx_file );
+
+
+use strict;
+use warnings;
+use Carp;
+
+use Date::Parse;
+use Data::Dumper;
+use Date::Parse;
+use Date::Manip;
+use POSIX qw(strftime);
+
+use Geo::Geometry;
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+
+# -----------------------------------------------------------------------------
+# Read GPS Data from GPX - File
+sub read_gpx_file($;$) {
+ my $filename = shift;
+ my $real_filename = shift || $filename;
+
+ my $start_time=time();
+ my $fh;
+
+ my $new_tracks={
+ filename => $real_filename,
+ tracks => [],
+ wpt => []
+ };
+
+ $fh = data_open($filename);
+ if ( ! ref($filename) =~ m/IO::File/ ) {
+ print STDERR "Parsing file: $filename\n" if $DEBUG;
+ }
+ return $new_tracks unless $fh;
+
+ my $p = XML::Parser->new( Style => 'Objects' ,
+ );
+
+ my $content = [{Kids => []}];
+ eval {
+ $content = $p->parse($fh);
+ };
+ if ( $@ ) {
+ warn "$@Error while parsing\n $filename\n";
+ #print "Parsing Content:".Dumper(\$content) if $DEBUG>99;
+ #return $content->[0]->{Kids};
+ }
+ if ( $content && (scalar(@{$content})>1) ) {
+ die "More than one top level Section was read in $filename\n";
+ }
+ if (not $p) {
+ print STDERR "WARNING: Could not parse osm data\n";
+ return $new_tracks;
+ }
+ if ( $VERBOSE >1 ) {
+ printf STDERR "Read and parsed $filename";
+ print_time($start_time);
+ }
+
+ #print Dumper(keys %{$content});
+ #print Dumper(\$content);
+ $content = $content->[0];
+ $content = $content->{Kids};
+
+
+# print "Parsing Content:".Dumper(\$content) if $DEBUG>99;
+
+ # Extract Waypoints
+ for my $elem ( @{$content} ) {
+ next unless ref($elem) eq "Geo::GPX::File::wpt";
+ my $wpt_elem = $elem->{Kids};
+ my $new_wpt={};
+ $new_wpt->{lat} = $elem->{lat};
+ $new_wpt->{lon} = $elem->{lon};
+ for my $elem ( @{$wpt_elem} ) {
+ my $found=0;
+ for my $type ( qw ( name ele
+ cmt desc
+ sym pdop vdop
+ course fix hdop sat speed time )) {
+ if ( ref($elem) eq "Geo::GPX::File::$type" ){
+ $new_wpt->{$type} = $elem->{Kids}->[0]->{Text};
+ $found++;
+ }
+ }
+ if ( $found ){
+ } elsif (ref($elem) eq 'Geo::GPX::File::Characters') {
+ } else {
+ printf STDERR "unknown tag in Waypoint:".Dumper(\$elem);
+ }
+ }
+ #printf STDERR Dumper(\$new_wpt);
+ push(@{$new_tracks->{wpt}},$new_wpt);
+ }
+
+ # Extract Tracks
+ for my $elem ( @{$content} ) {
+ next unless ref($elem) eq "Geo::GPX::File::trk";
+ # GPX::trkseg
+ $elem = $elem->{Kids};
+ #printf STDERR "Tracks: ".ref($elem)." ".Dumper(\$elem);
+ my $new_track=[];
+ for my $trk_elem ( @{$elem} ) {
+ next unless ref($trk_elem) eq "Geo::GPX::File::trkseg";
+ $trk_elem = $trk_elem->{Kids};
+ #printf STDERR "Track: ".ref($elem)." ".Dumper(\$trk_elem);
+ for my $trk_pt ( @{$trk_elem} ) {
+ next unless ref($trk_pt) eq "Geo::GPX::File::trkpt";
+ #printf STDERR "Track Point:".Dumper(\$trk_pt);
+ for my $trk_pt_kid ( @{$trk_pt->{Kids}} ) {
+ next if ref($trk_pt_kid) eq "Geo::GPX::File::Characters";
+ #printf STDERR "Track Point Kid:".Dumper(\$trk_pt_kid);
+ my $ref = ref($trk_pt_kid);
+ my ( $type ) = ($ref =~ m/Geo::GPX::File::(.*)/ );
+ $trk_pt->{$type} = $trk_pt_kid->{Kids}->[0]->{Text};
+ }
+ my $trk_time = $trk_pt->{time};
+ if ( defined $trk_time ) {
+ #printf STDERR "trk_time $trk_time\n";
+ my $time = str2time( $trk_time);
+ my $ltime = localtime($time);
+ my ($year,$month) = split(/-/,$trk_time);
+ if ( $year < 1970 ) {
+ warn "Ignoring Dataset because of Strange Date $trk_time ($ltime) in GPX File\n";
+ next;
+ };
+ if ( $DEBUG >= 11 ) {
+ printf STDERR "time: $ltime ".$trk_pt->{time}."\n\n";
+ }
+ $trk_pt->{time_string} = $trk_pt->{time};
+ $trk_pt->{time} = $time;
+ }
+
+ delete $trk_pt->{Kids};
+ #printf STDERR "Final Track Point:".Dumper(\$trk_pt);
+ push(@{$new_track},$trk_pt);
+ }
+ }
+ push(@{$new_tracks->{tracks}},$new_track);
+ }
+
+ #printf STDERR Dumper(\$new_tracks);
+ return $new_tracks;
+}
+
+#------------------------------------------------------------------
+sub write_gpx_file($$) { # Write an gpx File
+ my $tracks = shift;
+ my $filename = shift;
+
+ my $start_time=time();
+
+ # TODO: This has to get a good interface
+ my $write_gpx_wpt=$main::write_gpx_wpt;
+ my $fake_gpx_date=$main::fake_gpx_date;
+
+ die "fake_gpx_date not defined \n"
+ unless defined $fake_gpx_date;
+
+ printf STDERR ("Writing GPS File $filename\n") if $VERBOSE >1 || $DEBUG >1;
+
+ my $fh;
+ if ( $filename eq '-' ) {
+ $fh = IO::File->new(">&STDOUT");
+ } else {
+ $fh = IO::File->new(">$filename");
+ }
+ print $fh "<?xml version=\"1.0\"?>\n";
+ print $fh "<gpx \n";
+ print $fh " version=\"1.0\"\n";
+ print $fh " creator=\"osmfilter Converter\"\n";
+ print $fh " xmlns=\"http://www.ostertag.name\"\n";
+ print $fh " >\n";
+ # <bounds minlat="47.855922617" minlon ="8.440864999" maxlat="48.424462667" maxlon="12.829756737" />
+ # <time>2006-07-11T08:01:39Z</time>
+
+ my $point_count=0;
+
+ # write tracks
+ my $fake_time=0;
+ my $track_id=0;
+ for my $track ( @{$tracks->{tracks}} ) {
+ $track_id++;
+ print $fh "\n";
+ print $fh "<trk>\n";
+ print $fh " <name>$filename $track_id</name>\n";
+ print $fh " <number>$track_id</number>\n";
+ print $fh " <trkseg>\n";
+
+ for my $elem ( @{$track} ) {
+ $point_count++;
+ my $lat = $elem->{lat};
+ my $lon = $elem->{lon};
+ if ( abs($lat) >90 || abs($lon) >180 ) {
+ warn "write_gpx_track: Element ($lat/$lon) out of bound\n";
+ next;
+ };
+ print $fh " <trkpt lat=\"$lat\" lon=\"$lon\">\n";
+ if( defined $elem->{ele} ) {
+ print $fh " <ele>$elem->{ele}</ele>\n";
+ };
+ # --- time
+ if ( defined ( $elem->{time} ) ) {
+ #print Dumper(\$elem);
+
+ ##################
+ my ($time_sec,$time_usec)=( $elem->{time} =~ m/(\d+)(\.\d*)?/);
+ if ( defined($time_usec) ) {
+ $time_usec =~ s/^\.//;
+ }
+ if ( $time_sec && $time_sec < 3600*30 ) {
+ #print "---------------- time_sec: $time_sec\n";
+ }
+ if ( $fake_gpx_date ) {
+ $fake_time += rand(10);
+ $time_sec = $fake_time;
+ }
+ my $time = strftime("%FT%H:%M:%SZ", localtime($time_sec));
+ #UnixDate("epoch ".$time_sec,"%m/%d/%Y %H:%M:%S");
+ $time =~ s/Z/.${time_usec}Z/ if $time_usec && ! $fake_gpx_date;
+ if ( $DEBUG >20) {
+ printf STDERR "elem-time: $elem->{time} UnixDate: $time\n";
+ }
+ print $fh " <time>".$time."</time>\n";
+ }
+ # --- other attributes
+ for my $type ( qw ( name ele
+ cmt course
+ fix pdop hdop vdop sat
+ speed )) {
+ next if $fake_gpx_date && ($type eq "time");
+ my $value = $elem->{$type};
+ if( defined $value ) {
+ print $fh " <$type>$value</$type>\n";
+ }
+ };
+ print $fh " </trkpt>\n";
+ }
+ print $fh " </trkseg>\n";
+ print $fh "</trk>\n\n";
+
+ }
+
+ # write Waypoints
+ if ( $write_gpx_wpt ) {
+ print $fh "\n";
+ for my $wpt ( @{$tracks->{wpt}} ) {
+ my $lat = $wpt->{lat};
+ my $lon = $wpt->{lon};
+ print $fh " <wpt lat=\"$lat\" lon=\"$lon\">\n";
+ #print $fh " <name>$wpt->{name}</name>\n";
+ for my $type ( qw ( name ele
+ cmt desc
+ sym
+ course fix hdop sat speed time )) {
+ my $value = $wpt->{$type};
+ next if $fake_gpx_date && ($type eq "time");
+ if( defined $value ) {
+ print $fh " <$type>$value</$type>\n";
+ }
+ };
+ print $fh " </wpt>\n";
+ }
+ }
+
+ print $fh "</gpx>\n";
+ $fh->close();
+
+ my $comment = "wrote to GPX File";
+ printf STDERR "%-35s: %5d Points in %d Tracks $comment",$filename,$point_count,$track_id;
+ print_time($start_time);
+}
+
+1;
+
+=head1 NAME
+
+Geo::GPX::File
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Geometry.pm b/scripts/osm/perl_lib/Geo/Geometry.pm
new file mode 100644
index 0000000..67ec9d3
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Geometry.pm
@@ -0,0 +1,213 @@
+##################################################################
+package Geo::Geometry;
+##################################################################
+
+use strict;
+use warnings;
+
+
+use Exporter;
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@ISA = qw( Exporter );
+@EXPORT = qw( distance_point_point_Km distance_degree_point_point angle_north
+ angle_north_relative distance_line_point_Km distance_line_point
+ adjust_bounding_box
+ );
+
+use Math::Trig;
+
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+
+# ------------------------------------------------------------------
+# Distance in Km between 2 geo points with lat/lon
+# Wild estimation of Earth radius 40.000Km
+# At the poles we are completely off, since we assume the
+# lat/lon both have 40000Km radius, which is completely wrong
+# if you are not at the aequator
+sub distance_point_point_Km($$) {
+ my $p1 = shift;
+ my $p2 = shift;
+ no warnings 'deprecated';
+
+ return 999999999
+ unless defined($p1) && defined($p2);
+
+ my $lat1 = $p1->{'lat'};
+ my $lon1 = $p1->{'lon'};
+ my $lat2 = $p2->{'lat'};
+ my $lon2 = $p2->{'lon'};
+
+ return 999999999
+ unless defined($lat1) && defined($lon1);
+ return 999999999
+ unless defined($lat2) && defined($lon2);
+
+
+ # Distance
+ my $delta_lat=$lat1-$lat2;
+ my $delta_lon=$lon1-$lon2;
+ return sqrt($delta_lat*$delta_lat+$delta_lon*$delta_lon)*40000/360;
+
+}
+
+# ------------------------------------------------------------------
+# Distance between 2 geo points with lat/lon,
+# result: (delta_lat,delta_lon) in degrees
+sub distance_degree_point_point($$) {
+ my $p1 = shift;
+ my $p2 = shift;
+
+ return (999999999,999999999)
+ unless defined($p1) && defined($p2);
+
+ my $lat1 = $p1->{lat};
+ my $lon1 = $p1->{lon};
+ my $lat2 = $p2->{lat};
+ my $lon2 = $p2->{lon};
+
+ # Distance
+ my $delta_lat=$lat1-$lat2;
+ my $delta_lon=$lon1-$lon2;
+ return $delta_lat,$delta_lon;
+
+}
+
+# ------------------------------------------------------------------
+# Angle from North
+# East is +0 .. 180
+# West is -0 .. - 180
+sub angle_north($$){
+ my $p1 = shift;
+ my $p2 = shift;
+
+ my $lat1 = $p1->{lat};
+ my $lon1 = $p1->{lon};
+ my $lat2 = $p2->{lat};
+ my $lon2 = $p2->{lon};
+
+ # Distance
+ my $delta_lat=$lat1-$lat2;
+ my $delta_lon=$lon1-$lon2;
+
+ # Angle
+ my $angle = - rad2deg(atan2($delta_lat,$delta_lon));
+ return $angle;
+}
+
+# ------------------------------------------------------------------
+# Angle from North relative
+# so if you exchange the two points of the segment the angle keeps the same
+# result is between +0 .. 180
+sub angle_north_relative($$){
+ my $p1 = shift;
+ my $p2 = shift;
+ my $angle = angle_north($p1,$p2);
+ $angle += 180 if $angle < 0;
+ $angle -= 180 if $angle >180;
+ return $angle;
+}
+
+# ------------------------------------------------------------------
+# Minimal Distance between line and point in degrees
+sub distance_line_point_Km($$$$$$) {
+ return distance_line_point(@_)*40000/360;
+}
+# ------------------------------------------------------------------
+# Minimal Distance between line and point in degrees
+sub distance_line_point($$$$$$) {
+ my $x1 = shift;
+ my $y1 = shift;
+ my $x2 = shift;
+ my $y2 = shift;
+
+ my $xp = shift;
+ my $yp = shift;
+
+
+ printf STDERR "distance_line_point(%f,%f, %f,%f, %f,%f)\n", $x1, $y1, $x2, $y2, $xp, $yp
+ if ( $DEBUG >10 ) ;
+
+ my $dx1p = $x1 - $xp;
+ my $dx21 = $x2 - $x1;
+ my $dy1p = $y1 - $yp;
+ my $dy21 = $y2 - $y1;
+ my $frac = $dx21 * $dx21 + $dy21 * $dy21;
+
+ if ( $frac == 0 ) {
+ return(sqrt(($x1-$xp)*($x1-$xp) + ($y1-$yp)*($y1-$yp)));
+ }
+
+ my $lambda = -($dx1p * $dx21 + $dy1p * $dy21) / $frac;
+ printf STDERR "distance_line_point(): lambda_1: %f\n",$lambda
+ if ( $DEBUG > 10 );
+
+ $lambda = min(max($lambda,0.0),1.0);
+
+ printf STDERR "distance_line_point(): lambda: %f\n",$lambda
+ if ( $DEBUG > 10 ) ;
+
+ my $xsep = $dx1p + $lambda * $dx21;
+ my $ysep = $dy1p + $lambda * $dy21;
+ return sqrt($xsep * $xsep + $ysep * $ysep);
+}
+
+sub adjust_bounding_box($$$){
+ my $bbox = shift;
+ my $lat = shift;
+ my $lon = shift;
+
+ for my $type ( qw(lat_min lat_max lon_min lon_max lat lon )) {
+ next if defined ($bbox->{$type});
+ if ( $type =~m/min/ ) {
+ $bbox->{$type} = 1000;
+ } else {
+ $bbox->{$type} = -1000;
+ }
+ }
+ # remember lat/lon Min/Max
+ $bbox->{lat_min}= min($bbox->{lat_min},$lat);
+ $bbox->{lat_max}= max($bbox->{lat_max},$lat);
+ $bbox->{lon_min}= min($bbox->{lon_min},$lon);
+ $bbox->{lon_max}= max($bbox->{lon_max},$lon);
+ $bbox->{lat_delta}= $bbox->{lat_max}-$bbox->{lat_min};
+ $bbox->{lon_delta}= $bbox->{lon_max}-$bbox->{lon_min};
+ $bbox->{lat}= ($bbox->{lat_min}+$bbox->{lat_max})/2;
+ $bbox->{lon}= ($bbox->{lon_min}+$bbox->{lon_max})/2;
+}
+
+
+1;
+
+=head1 NAME
+
+Geo::Geometry
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/DBFuncs.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/DBFuncs.pm
new file mode 100755
index 0000000..3c2432d
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/DBFuncs.pm
@@ -0,0 +1,742 @@
+# Database Functions for poi.pl
+
+package Geo::Gpsdrive::DBFuncs;
+
+use strict;
+use warnings;
+
+use POSIX qw(strftime);
+use Time::Local;
+use DBI;
+use Geo::Gpsdrive::Utils;
+use Data::Dumper;
+use IO::File;
+
+$|= 1; # Autoflush
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+
+ # set the version for version checking
+ $VERSION = 1.00;
+ # if using RCS/CVS, this may be preferred
+ #$VERSION = sprintf "%d.%03d", q$Revision: 1303 $ =~ /(\d+)/g;
+
+ @ISA = qw(Exporter);
+ @EXPORT = qw( &poi_type_names &poi_type_list &poi_type_name2id &poi_type_id2name
+ &db_disconnect &db_read_mysql_sys_pwd
+ &add_poi &add_poi_multi
+ &poi_list
+ &column_names
+ &source_name2id
+ &insert_hash
+ &delete_all_from_source
+ &enable_keys &disable_keys);
+ %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ],
+ # your exported package globals go here,
+ # as well as any optionally exported functions
+ @EXPORT_OK = qw();
+
+}
+our @EXPORT_OK;
+
+
+END { }
+
+
+# -----------------------------------------------------------------------------
+# switch off updating of index
+sub disable_keys($){
+ my $table = shift;
+ print "disable_keys($table)\n" if $verbose;
+ db_exec("ALTER TABLE $table DISABLE KEYS;");
+}
+
+# -----------------------------------------------------------------------------
+# switch on updating of index
+sub enable_keys($){
+ my $table = shift;
+ print "enable_keys($table)\n" if $verbose;
+ db_exec("ALTER TABLE $table ENABLE KEYS;");
+}
+
+# -----------------------------------------------------------------------------
+# retrieve Column Names for desired table
+my %COLUMN_NAMES;
+sub column_names($){
+ my $table = shift;
+ my @col;
+
+ # look for cached result
+ if ( defined($COLUMN_NAMES{$table} ) ){
+ return @{$COLUMN_NAMES{$table}};
+ }
+
+ my $dbh = db_connect();
+ my $query = "SHOW COLUMNS FROM $main::GPSDRIVE_DB_NAME.$table;";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ while ( my $array_ref = $sth->fetchrow_arrayref() ) {
+ push ( @col ,$array_ref->[0] );
+ }
+ $COLUMN_NAMES{$table}=\@col;
+ return @col;
+}
+
+
+# -----------------------------------------------------------------------------
+# get all indix info for $table
+# RETURNS:
+# $result->{$name}->{...}
+# where $name is name of index
+sub show_index($) {
+ my $table = shift;
+
+ my $query = "SHOW INDEX FROM $table;";
+ my $dbh = db_connect();
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ my $result ={};
+ foreach my $row ( @{ $sth->fetchall_arrayref({}) } ) {
+ my $name =$row->{'Key_name'};
+ my $seq_index = $row->{'Seq_in_index'};
+ if ( $seq_index ) {
+ $result->{$name}->{Columns}->[$seq_index-1] = $row->{'Column_name'};
+ for my $k ( keys %{$row} ) {
+ if ( ! exists($result->{$name} ) ||
+ ! exists($result->{$name}->{$k}) ) {
+ $result->{$name}->{$k} = $row->{$k};
+ } elsif ( !defined($result->{$name}->{$k}) && !defined($row->{$k}) ) {
+ # Avoid undef warnings
+ } elsif ( $result->{$name}->{$k} ne $row->{$k} ) {
+ $result->{$name}->{$k} .= ",$row->{$k}";
+ }
+ }
+ } else {
+ $result->{$name} = $row;
+ }
+ }
+
+ return $result;
+}
+
+# -----------------------------------------------------------------------------
+# insert hash into database
+my $last_insert_table_name='';
+my @fields;
+my $insert_hash_sth;
+sub insert_hash($$;$) {
+ my $table = shift;
+ my $field_values = shift;
+
+ # read multiple hashreference and override Hash Values
+ # of field_values
+ while ( my $h = shift ) {
+# print "Adding ".Dumper($h);
+ map { $field_values->{$_} = $h->{$_} } sort keys %{$h};
+ }
+
+ $field_values->{"$table.last_update"} ||= time();
+
+ # get Table info and create sql query if
+ # the table differs from the last insert Statement
+ if ( $last_insert_table_name ne $table ) {
+ # get column names of table
+ @fields = map { "$table.$_" } column_names($table);
+
+ my $sql = sprintf ( "insert into %s (%s) values (%s)",
+ $table,
+ join(',', @fields),
+ join(",", ("?") x scalar(@fields))
+ );
+
+ my $dbh = db_connect();
+ #print "insert_hash($table, ".Dumper(\$field_values).")\n";
+ #print "$sql\n";
+ #print "insert_hash($table, ".join(",",map { $_ || '' } @values).")\n";
+ $insert_hash_sth = $dbh->prepare_cached($sql);
+ $last_insert_table_name = $table;
+ }
+
+ # get the values into the right order
+ my @values = @{$field_values}{@fields};
+
+ my $res = $insert_hash_sth->execute(@values);
+ if ( ! $res ) {
+ warn "Error while inserting Hash ".Dumper($field_values)." into table '$table'\n";
+ $insert_hash_sth->errstr;
+ }
+
+ return $res;
+}
+
+#############################################################################
+# Try to find and read the system user password and username
+sub db_read_mysql_sys_pwd(){
+ return unless $main::db_user eq "";
+ return unless $main::db_password eq "";
+ return unless -r "/etc/mysql/debian.cnf";
+ open(my $fh , "</etc/mysql/debian.cnf");
+ die "Cannot open /etc/mysql/debian.cnf:$!\n" unless $fh;
+ while (defined (my $line = <$fh> )
+ && (!$main::db_user || !$main::db_password)
+ ) {
+ $main::db_user = $1 if $line =~ m/user\s*=\s*(.*)/;
+ $main::db_password = $1 if $line =~ m/password\s*=\s*(.*)/;
+ }
+ #print "user: $main::db_user\n";
+ #print "PWD: $main::db_password\n";
+}
+
+#############################################################################
+# All necessary information for connecting the DB
+# these are: host, user and passwort; the db is always $main::GPSDRIVE_DB_NAME
+my $dbh;
+sub db_connect() {
+ my $db = $main::GPSDRIVE_DB_NAME;
+ my $opt_user = $main::db_user;
+ my $opt_password = $main::db_password;
+ my $host = $main::db_host;
+ #$host = 'mysql_socket=/home/tweety/.gpsdrive/mysql/mysqld.sock';
+
+ # First connect to Database
+ unless ( $dbh ) {
+ $dbh = DBI->connect(
+ "DBI:mysql:$db:$host",
+ $opt_user,$opt_password)
+ || die "Can't connect: $DBI::errstr\n";
+ }
+
+ return $dbh;
+}
+
+sub db_disconnect(){
+ $dbh->disconnect()
+ if $dbh;
+}
+
+# -----------------------------------------------------------------------------
+# Delete all entries matching source with name
+sub delete_all_from_source($){
+ my $source_name = shift;
+ if ( $main::no_delete ){
+ print "Keeping old entries for '$source_name'\n" if $verbose;
+ return;
+ }
+
+ print "Delete all from '$source_name'\n" if $verbose;
+ debug("delete_all_from_source($source_name)");
+ return unless $source_name;
+ my $source_id = source_name2id( $source_name);
+ debug("Delete all from '$source_id'\n");
+ return unless $source_id >0;
+
+ my $query = "DELETE FROM poi WHERE poi.source_id = '$source_id'";
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+ $sth->finish;
+
+ print "Deleted all from '$source_name'\n" if $verbose>3;
+}
+
+# -----------------------------------------------------------------------------
+# convert source name to source_id and cache it locally
+my $source_id_cache;
+sub source_name2id($){
+ my $source_name = shift;
+ my $source_id;
+ if ( defined $source_id_cache->{$source_name} ) {
+ $source_id = $source_id_cache->{$source_name};
+ } else {
+ my $dbh = db_connect();
+ my $query = "SELECT source_id FROM source WHERE source.name = '$source_name' LIMIT 1";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ my $array_ref = $sth->fetchrow_arrayref();
+ if ( $array_ref ) {
+ $source_id = $array_ref->[0];
+ $source_id_cache->{$source_name} = $source_id;
+ } else {
+ # Nicht gefunden --> Neuen Eintrag anlegen
+ $source_id=0;
+ }
+ $sth->finish;
+ }
+
+ debug("Source: $source_name -> $source_id");
+
+ return $source_id;
+}
+
+# -----------------------------------------------------------------------------
+# convert poi_type.name to poi_type_id and cache it locally
+# TODO: if we get a Hash; create the source entry if not already existent
+my $poi_type_id_cache;
+my $poi_type_id_2_name_cache;
+sub poi_type_name2id($){
+ my $type_name = shift ||'';
+ my $poi_type_id;
+
+ return 0 unless $type_name;
+
+ if ( defined $poi_type_id_cache->{$type_name} ) {
+ $poi_type_id = $poi_type_id_cache->{$type_name};
+ } else {
+ my $dbh = db_connect();
+ my $query = "SELECT poi_type_id FROM poi_type WHERE poi_type.name = '$type_name' LIMIT 1";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ my $array_ref = $sth->fetchrow_arrayref();
+ if ( $array_ref ) {
+ $poi_type_id = $array_ref->[0];
+ $poi_type_id_cache->{$type_name} = $poi_type_id;
+ $poi_type_id_2_name_cache->{$poi_type_id} = $type_name;
+ } else {
+ # Nicht gefunden
+ $poi_type_id=0;
+ }
+ $sth->finish;
+ }
+
+ debug("Type: $type_name -> $poi_type_id")
+ if $verbose;
+
+ return \$poi_type_id;
+}
+
+
+# ------------------------------------------------------------------
+# get assignment poi_type.name -> poi_type_id
+sub get_poi_types()
+{
+ my %poi_types;
+ my $db_query = 'SELECT poi_type_id,name FROM poi_type;';
+ my $dbh = Geo::Gpsdrive::DBFuncs::db_connect();
+ my $sth=$dbh->prepare($db_query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ while (my @row = $sth->fetchrow_array)
+ {
+ $poi_types{$row[1]} = $row[0];
+ }
+ $sth->finish;
+ return \%poi_types;
+}
+
+
+# ------------------------------------------------------------------
+sub poi_type_id2name($){
+ my $poi_type_id=shift;
+
+ my $poi_type_name='';
+ return '' unless $poi_type_id;
+
+ if ( defined $poi_type_id_2_name_cache->{$poi_type_id} ) {
+ $poi_type_name = $poi_type_id_2_name_cache->{$poi_type_id};
+ } else {
+ my $dbh = db_connect();
+ my $query = "SELECT poi_type.name FROM poi_type WHERE poi_type.pi_type_id = '$poi_type_id' LIMIT 1";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ my $array_ref = $sth->fetchrow_arrayref();
+ if ( $array_ref ) {
+ $poi_type_name = $array_ref->[0];
+ $poi_type_id_cache->{$poi_type_name} = $poi_type_id;
+ $poi_type_id_2_name_cache->{$poi_type_id} = $poi_type_name;
+ } else {
+ # Nicht gefunden
+ $poi_type_name='';
+ }
+ $sth->finish;
+ }
+
+ debug("Type: $poi_type_id --> $poi_type_name");
+
+ return $poi_type_name;
+}
+
+# -----------------------------------------------------------------------------
+# get a list of all type names
+sub poi_type_names(){
+ my @poi_type_names;
+
+ my $dbh = db_connect();
+
+ my $query = "SELECT name FROM poi_type";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ while (my $row = $sth->fetchrow_arrayref) {
+ push(@poi_type_names,$row->[0]);
+ }
+ $sth->finish;
+
+ return @poi_type_names;
+}
+
+# -----------------------------------------------------------------------------
+# retrieve a complete list of known types
+# This returns a list with a hash for each type with all relevant data
+sub poi_type_list(){
+ my @poi_type_list;
+
+ my $dbh = db_connect();
+
+ my @columns = column_names("poi_type");
+ my $query = "SELECT ".join(',', @columns)." FROM poi_type";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ while (my $row = $sth->fetchrow_arrayref) {
+ my $poi_type = {};
+ for my $i ( 0.. $#columns) {
+ $poi_type->{$columns[$i]} = $row->[$i];
+ }
+ push(@poi_type_list,$poi_type);
+ }
+ $sth->finish;
+
+ return @poi_type_list;
+}
+
+
+
+
+
+# -----------------------------------------------------------------------------
+# retrieve first n entries from poi Table
+# default is 100 Entries
+sub poi_list(;$){
+ my $limit = shift || 100;
+ my @poi_list;
+
+ my $dbh = db_connect();
+
+ my @columns = column_names("poi");
+ my $query = "SELECT ".join(',', @columns)." FROM poi LIMIT $limit";
+
+ my $sth=$dbh->prepare($query) or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ while (my $row = $sth->fetchrow_arrayref) {
+ my $poi = {};
+ for my $i ( 0.. $#columns) {
+ $poi->{$columns[$i]} = $row->[$i];
+ }
+ push(@poi_list,$poi);
+ }
+ $sth->finish;
+
+ return @poi_list;
+}
+
+#############################################################################
+# Add all Waypoints from Hash into th MySQL POI Database
+#############################################################################
+sub add_poi_multi($){
+ my $waypoints = shift;
+ print "Adding Waypoints to Database\n";
+
+ for my $wp_name ( sort keys %{$waypoints} ) {
+ my $values = $waypoints->{$wp_name};
+
+ unless ( defined($values->{'poi.lat'}) &&
+ defined($values->{'poi.lon'}) ) {
+ print "Error undefined lat/lon: ".Dumper(\$values);
+ }
+
+ correct_lat_lon($values);
+
+ # TODO: Check if this is obsolete
+ for my $t (qw(Wlan Action Sqlnr Proximity) ) {
+ unless ( defined ( $values->{$t})) {
+ $values->{$t} = 0;
+ }
+ }
+
+ $values->{Proximity} =~ s/\s*m$//;
+ add_poi($values);
+ }
+}
+
+#############################################################################
+# Add a single poi into DB
+sub add_poi($){
+ my $poi = shift;
+ my $point = {};
+ my @columns = column_names("poi");
+ map { $point->{"poi.$_"} = ( $poi->{"poi.$_"} || $poi->{$_} || $poi->{lc($_)}) } @columns;
+
+ # ---------------------- SOURCE
+ #print Dumper(\$point);
+ if ( $point->{"source.name"} && ! $point->{'poi.source_id'}) {
+ my $source_id = source_name2id($point->{"source.name"});
+ # print "Source: $point->{'source.name'} -> $source_id\n";
+
+ $point->{'source.source_id'} = $source_id;
+ $point->{'poi.source_id'} = $source_id;
+ }
+
+ # ---------------------- POI_Type
+ my $type_name = $poi->{'poi_type.name'};
+ if ( $type_name && ! $point->{'poi.poi_type_id'}) {
+ my $poi_type_id = type_name2id($type_name);
+ unless ( $poi_type_id ) {
+ my $type_hash= {
+ 'poi_type.name' => $type_name
+ };
+ insert_hash("poi_type",$type_hash);
+ $poi_type_id = type_name2id($point->{"type.name"});
+ }
+ $point->{'poi.poi_type_id'} = $poi_type_id;
+ }
+
+ # ---------------------- TYPE
+ $point->{'poi.poi_type_id'} ||= 0;
+
+ # ---------------------- POI
+ $point->{'poi.last_modified'} ||= time();
+ insert_hash("poi",$point);
+
+}
+
+#############################################################################
+# Add a single wlan into DB
+sub add_wlan($){
+ my $point = shift;
+ my @columns = column_names("wlan");
+# print "Add_WLAN wlan: ".Dumper(\$point);
+
+ # ---------------------- SOURCE
+ if ( $point->{"source.name"} && ! $point->{'wlan.source_id'}) {
+ my $source_id = source_name2id($point->{"source.name"});
+ # print "Source: $point->{'source.name'} -> $source_id\n";
+
+ $point->{'source.source_id'} = $source_id;
+ $point->{'wlan.source_id'} = $source_id;
+ }
+
+ # ---------------------- WLAN
+ $point->{'wlan.last_modified'} ||= time();
+ insert_hash("wlan",$point);
+
+}
+
+# -----------------------------------------------------------------------------
+sub db_exec($){
+ my $statement = shift;
+ debug("db_exec($statement)");
+
+ my $dbh = db_connect();
+ my $sth = $dbh->prepare($statement);
+ unless ( $sth->execute() ) {
+ warn "Error in query '$statement'\n";
+ $sth->errstr;
+ return 0;
+ }
+ return 1;
+}
+
+# -----------------------------------------------------------------------------
+# create known indices for given table
+# if they dont exist already
+sub add_if_not_exist_index($$;$){
+ my $table = shift;
+ my $name = shift;
+ my $keys = shift || $name || '';
+
+ my $indices = show_index($table);
+ debug( "If not exist; adding Index $table.$name: '$keys'");
+ if ( $keys && $keys =~ m/\,/ ) { # Multi Key
+ my $ist ='';
+ if ( exists $indices->{$name}->{Columns} &&
+ @{$indices->{$name}->{Columns}} ) {
+ $ist = join('`,`',@{$indices->{$name}->{Columns}});
+ if ( $ist eq $keys ) { # exists and correct
+ return;
+ } else {
+ print "Dropping Index: $table.$name\n";
+ db_exec("ALTER TABLE `$table` DROP INDEX `$name`;");
+ }
+ }
+ } elsif ( defined $indices->{$name}->{'Column_name'} &&
+ $indices->{$name}->{'Column_name'} eq $keys ) {
+ return;
+ } elsif ( defined $indices->{$name}->{'Column_name'} ) {
+ print "Droping Index: $table.$name\n";
+ db_exec("ALTER TABLE `$table` DROP INDEX `$name`;");
+ }
+
+ debug( "Adding Index: $table.$name: `$keys`");
+ db_exec("ALTER TABLE `$table` ADD INDEX `$name` ( `$keys` );");
+}
+
+# -----------------------------------------------------------------------------
+# create known indices for given table
+sub add_index($){
+ my $table = shift;
+
+ if ( $table eq "poi" ){
+ for my $key ( qw( last_modified name lat lon ) ){
+ add_if_not_exist_index($table,$key);
+ }
+ add_if_not_exist_index( $table,'combi1','lat`,`lon`,`poi_type_id');
+ } elsif ( $table eq "wlan" ){
+ for my $key ( qw( last_modified macaddr lat lon ) ){
+ add_if_not_exist_index($table,$key);
+ }
+ add_if_not_exist_index( $table,'combi1','lat`,`lon`,`poi_type_id');
+ } elsif ( $table eq "waypoints" ){
+ for my $key ( qw( macaddr type name typenr ) ){
+ add_if_not_exist_index($table,$key);
+ }
+ } elsif ( $table eq "source" ){
+ for my $key ( qw( name ) ){
+ add_if_not_exist_index($table,$key);
+ }
+ } elsif ( $table eq "poi_type" ){
+ for my $key ( qw( name ) ){
+ add_if_not_exist_index($table,$key);
+ }
+ }
+
+ # TODO: add more index
+}
+
+# -----------------------------------------------------------------------------
+sub create_db(){
+ my $create_statement;
+ my $dbh;
+ my $sth;
+
+ $create_statement="CREATE DATABASE IF NOT EXISTS $main::GPSDRIVE_DB_NAME "
+ ." CHARACTER SET utf8;";
+ my $drh = DBI->install_driver("mysql");
+ my $rc = $drh->func('createdb', $main::GPSDRIVE_DB_NAME, $main::db_host,
+ $main::db_user,$main::db_password, 'admin');
+ die "Cannot create Database: $@" if $@;
+
+ $dbh = db_connect();
+ $sth = $dbh->prepare($create_statement);
+ $sth->execute()
+ or die $sth->errstr;
+
+ # ------- POI
+ db_exec('CREATE TABLE IF NOT EXISTS `poi_type` (
+ `poi_type_id` int(11) NOT NULL auto_increment,
+ `name` varchar(160) NOT NULL default \'\',
+ `scale_min` int(12) NOT NULL default \'1\',
+ `scale_max` int(12) NOT NULL default \'25000\',
+ `title` varchar(160) NULL default \'\',
+ `title_en` varchar(160) NULL default \'\',
+ `description` varchar(160) NULL default \'\',
+ `description_en` varchar(160) NULL default \'\',
+ PRIMARY KEY (`poi_type_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+ add_index('poi_type');
+
+ db_exec('CREATE TABLE IF NOT EXISTS `poi` (
+ `poi_id` int(11) NOT NULL auto_increment,
+ `name` varchar(80) NOT NULL default \'not specified\',
+ `poi_type_id` int(11) NOT NULL default \'1\',
+ `lat` double NOT NULL default \'0\',
+ `lon` double NOT NULL default \'0\',
+ `alt` double default \'0\',
+ `proximity` float default \'10\',
+ `comment` varchar(255) default NULL,
+ `last_modified` datetime NOT NULL default \'0000-00-00\',
+ `source_id` int(11) NOT NULL default \'1\',
+ `private` char(1) default NULL,
+ PRIMARY KEY (`poi_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+ add_index('poi');
+
+ db_exec('CREATE TABLE IF NOT EXISTS `poi_extra` (
+ `poi_id` int(11) NOT NULL default \'0\',
+ `field_name` varchar(160) NOT NULL default \'0\',
+ `entry` varchar(8192) default NULL,
+ INDEX (`poi_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+ add_index('poi_extra');
+
+ db_exec('CREATE TABLE IF NOT EXISTS `poi_extra_fields` (
+ `poi_type_id` int(11) NOT NULL default \'0\',
+ `field_name` varchar(160) NOT NULL default \'0\',
+ `description_en` varchar(160) NULL default \'\',
+ PRIMARY KEY (`poi_type_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+ add_index('poi_extra_fields');
+
+ # ------- WLAN
+ db_exec('CREATE TABLE IF NOT EXISTS `wlan` (
+ `wlan_id` int(11) NOT NULL auto_increment,
+ `lat` double NOT NULL default \'0\',
+ `lon` double NOT NULL default \'0\',
+ `alt` double default \'0\',
+ `comment` varchar(255) default NULL,
+ `macaddr` varchar(30) NOT NULL,
+ `essid` varchar(255) NOT NULL,
+ `nettype` int(11) NOT NULL default \'0\',
+ `wep` int(11) NOT NULL default \'0\',
+ `cloaked` int(11) NOT NULL default \'0\',
+ `last_modified` date NOT NULL default \'0000-00-00\',
+ PRIMARY KEY (`wlan_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+
+
+ # ------- Source
+ db_exec('CREATE TABLE IF NOT EXISTS `source` (
+ `source_id` int(11) NOT NULL auto_increment,
+ `name` varchar(80) NOT NULL default \'\',
+ `comment` varchar(160) NOT NULL default \'\',
+ `last_update` date NOT NULL default \'0000-00-00\',
+ `url` varchar(160) NOT NULL default \'\',
+ `licence` varchar(160) NOT NULL default \'\',
+ PRIMARY KEY (`source_id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+ add_index('source');
+
+ # -------- traffic: For Traffic Information
+ db_exec('CREATE TABLE IF NOT EXISTS traffic (
+ `id` int(11) NOT NULL auto_increment ,
+ `status` int(11) default NULL ,
+ `street` varchar(40) default NULL ,
+ `descshort` varchar(100) default NULL ,
+ `desclong` text NOT NULL ,
+ `future` int(11) NOT NULL default \'0\',
+ `time` time default \'00:00:00\',
+ `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
+ PRIMARY KEY (`id`)
+ ) ENGINE=MyISAM DEFAULT CHARSET=utf8;') or die;
+ add_index('traffic');
+
+
+ # -----------------------------------------------------------------------------
+ # Set Privileges
+ # TODO: Split priviledges
+ db_exec("grant select,insert,update,delete,lock tables on $main::GPSDRIVE_DB_NAME.* to gast\@localhost identified by \'gast\'");
+ db_exec('flush privileges;');
+
+ print "!!! WARNING: Created a user gast with password gast\n";
+ print "!!! WARNING: this might be a security issue if you have your mysql \n";
+ print "!!! WARNING: database accessible from outside of your computer\n";
+ print "\n";
+
+ print "Creation completed\n";
+
+}
+# -----------------------------------------------------------------------------
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/DB_Defaults.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/DB_Defaults.pm
new file mode 100644
index 0000000..306b164
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/DB_Defaults.pm
@@ -0,0 +1,185 @@
+# Database Defaults for poi/streets Table for poi.pl
+
+package Geo::Gpsdrive::DB_Defaults;
+
+use strict;
+use warnings;
+
+use POSIX qw(strftime);
+use Time::Local;
+use DBI;
+use Geo::Gpsdrive::Utils;
+use Data::Dumper;
+use IO::File;
+use Geo::Gpsdrive::DBFuncs;
+use XML::Twig;
+
+$|= 1; # Autoflush
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+
+ # set the version for version checking
+ $VERSION = 1.00;
+ # if using RCS/CVS, this may be preferred
+ #$VERSION = sprintf "%d.%03d", q$Revision: 1254 $ =~ /(\d+)/g;
+
+ @ISA = qw(Exporter);
+ @EXPORT = qw( );
+ %EXPORT_TAGS = ( );
+ @EXPORT_OK = qw();
+
+}
+
+
+# -----------------------------------------------------------------------------
+# Fill poi_type database
+sub fill_default_poi_types {
+ our $lang = $main::lang || 'de';
+ my $i=1;
+ my $used_icons ={};
+ my $poi_type_id=20;
+
+ # for debug purpose
+ Geo::Gpsdrive::DBFuncs::db_exec("TRUNCATE TABLE `poi_type`;");
+
+ my $unused_icon ={};
+ my $existing_icon ={};
+
+ my $icon_file='../data/map-icons/icons.xml';
+ $icon_file = '../share/map-icons/icons.xml' unless -s $icon_file;
+ $icon_file = '/usr/local/share/map-icons/icons.xml' unless -s $icon_file;
+ $icon_file = '/usr/share/map-icons/icons.xml' unless -s $icon_file;
+ $icon_file = '/opt/gpsdrive/icons.xml' unless -s $icon_file;
+ die "no Icon File found" unless -s $icon_file;
+
+ our $title = ''; our $title_en = '';
+ our $description = ''; our $description_en = '';
+
+ # parse icon file
+ #
+ my $twig= new XML::Twig
+ (
+ TwigHandlers => { rule => \&sub_poi,
+ title => \&sub_title,
+ description => \&sub_desc }
+ );
+ $twig->parsefile( "$icon_file");
+ my $rules= $twig->root;
+
+ $twig->purge;
+
+ sub sub_poi
+ {
+ my ($twig, $poi_elm) = @_;
+ if ($poi_elm->first_child('condition')->att('k') eq 'poi')
+ {
+ my $poi_type_id =
+ $poi_elm->first_child('geoinfo')->first_child('poi_type_id')->text;
+ my $name = $poi_elm->first_child('geoinfo')->first_child('name')->text;
+ my $scale_min = $poi_elm->first_child('scale_min')->text;
+ my $scale_max = $poi_elm->first_child('scale_max')->text;
+ $title = $title_en unless ($title);
+ $description = $description_en unless ($description);
+
+ Geo::Gpsdrive::DBFuncs::db_exec(
+ "DELETE FROM `poi_type` WHERE poi_type_id = $poi_type_id ;");
+ Geo::Gpsdrive::DBFuncs::db_exec(
+ "INSERT INTO `poi_type` ".
+ "(poi_type_id, name, scale_min, scale_max, title, title_en, ".
+ "description, description_en) ".
+ "VALUES ($poi_type_id,'$name','$scale_min','$scale_max','$title',".
+ "'$title_en','$description','$description_en');")
+ or die;
+ }
+ $title = ''; $title_en = '';
+ $description = ''; $description_en = '';
+ }
+
+ sub sub_title
+ {
+ my ($twig, $title_elm) = @_;
+ if ($title_elm->att('lang') eq 'en')
+ { $title_en = $title_elm->text; }
+ elsif ($title_elm->att('lang') eq $lang)
+ { $title = $title_elm->text; }
+ }
+
+ sub sub_desc
+ {
+ my ($twig, $desc_elm) = @_;
+ if ($desc_elm->att('lang') eq 'en')
+ { $description_en = $desc_elm->text; }
+ elsif ($desc_elm->att('lang') eq $lang)
+ { $description = $desc_elm->text; }
+ }
+}
+
+# -----------------------------------------------------------------------------
+sub fill_default_sources() { # Just some Default Sources
+
+ my $default_licence =
+ $main::default_licence || 'Creative Commons Attribution-ShareAlike 2.0';
+
+ my @sources = (
+ { source_id => '1',
+ name => 'unknown',
+ comment => 'Unknown source or source not defined',
+ last_update => '2007-01-03',
+ url => 'http://www.gpsdrive.cc/',
+ licence => 'unknown'
+ },
+ { source_id => '2',
+ name => 'way.txt',
+ comment => 'Data imported from way.txt',
+ last_update => '2007-01-03',
+ url => 'http://www.gpsdrive.cc/',
+ licence => 'unknown'
+ },
+ { source_id => '3',
+ name => 'user',
+ comment => 'Data entered by the GPSDrive-User',
+ last_update => '2007-01-23',
+ url => 'http://www.gpsdrive.cc/',
+ licence => $default_licence
+ },
+ { source_id => '4',
+ name => 'OpenStreetMap.org',
+ comment => 'General Data imported from the OpenStreetMap Project',
+ last_update => '2007-01-03',
+ url => 'http://www.openstreetmap.org/',
+ licence => 'Creative Commons Attribution-ShareAlike 2.0'
+ },
+ { source_id => '5',
+ name => 'groundspeak',
+ comment => 'Geocache data from Groundspeak',
+ last_update => '2007-01-30',
+ url => 'http://www.groundspeak.com/',
+ licence => 'unknown'
+ },
+ );
+
+ foreach (@sources) {
+ Geo::Gpsdrive::DBFuncs::db_exec(
+ "DELETE FROM `source` WHERE source_id = $$_{'source_id'};");
+ Geo::Gpsdrive::DBFuncs::db_exec(
+ "INSERT INTO `source` ".
+ "(source_id, name, comment, last_update, url, licence) ".
+ "VALUES ($$_{'source_id'},'$$_{'name'}','$$_{'comment'}',".
+ "'$$_{'last_update'}','$$_{'url'}','$$_{'licence'}');") or die;
+ }
+
+}
+
+# -----------------------------------------------------------------------------
+
+sub fill_defaults(){
+ print "Create Defaults ...\n";
+ fill_default_poi_types();
+ fill_default_sources();
+ print "Create Defaults completed\n";
+}
+
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/DB_tracks.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/DB_tracks.pm
new file mode 100644
index 0000000..04e540f
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/DB_tracks.pm
Binary files differ
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/Defaults_Cities.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/Defaults_Cities.pm
new file mode 100644
index 0000000..edc8a5f
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/Defaults_Cities.pm
@@ -0,0 +1,513 @@
+{ name => 'Mechtat A���ne el Msad', lat => 36.5033333, lon => 6.0758333 },
+{ name => 'Halte A���n Lehma', lat => 36.1166667, lon => 6.4833333 },
+{ name => 'Halte d\' A���n-Lehms', lat => 36.1166667, lon => 6.4833333 },
+{ name => 'Berteau \'A���n Lehma', lat => 36.1166667, lon => 6.4833333 },
+{ name => 'Berteaux-\'A���n Lehma', lat => 36.1166667, lon => 6.4833333 },
+{ name => 'Bordjel El Hassane', lat => 36.6027778, lon => 7.6916667 },
+{ name => 'Borj Scander', lat => 36.8347222, lon => 7.7013889 },
+{ name => 'Bouchegout', lat => 36.4722222, lon => 7.7333333 },
+{ name => 'Dar Lahleme', lat => 36.8347222, lon => 7.575 },
+{ name => 'Djenane El Bey', lat => 36.8305556, lon => 7.1180556 },
+{ name => 'Henchir Mokhtar Abdullah el Medjid', lat => 36.6388889, lon => 7.7083333 },
+{ name => 'Mechetet Bell\'chari', lat => 36.6083333, lon => 7.5805556 },
+{ name => 'Mechta \'A���n el Msad', lat => 36.5033333, lon => 6.0758333 },
+{ name => 'Mechta Beni Hameza', lat => 36.6694444, lon => 7.4347222 },
+{ name => 'Mechta Fedj el Ouathia', lat => 36.2583333, lon => 7.9861111 },
+{ name => 'Mechta Fetmiat', lat => 36.7680556, lon => 7.3166667 },
+{ name => 'Mechta Guebel \`A���n', lat => 36.0013889, lon => 7.7819444 },
+{ name => 'Mechta Guebel\`A���n', lat => 36.0027778, lon => 7.7805556 },
+{ name => 'Mechta Jorf El Ahmar', lat => 36.4513889, lon => 7.5805556 },
+{ name => 'Mechta Messous', lat => 36.4847222, lon => 7.2472222 },
+{ name => 'Mechta Ouled Bou Dene', lat => 36.0294444, lon => 6.5097222 },
+{ name => 'Mechta Ouled Bou Denn', lat => 36.0294444, lon => 6.5097222 },
+{ name => 'Mechtat Ahmed Bel Ajmi', lat => 36.3347222, lon => 7.5083333 },
+{ name => 'Mechtat Bou Rougaa', lat => 36.6194444, lon => 7.875 },
+{ name => 'Mechtat es Stah', lat => 36.0916667, lon => 7.7847222 },
+{ name => 'Mechtat Ouled Bou Denn', lat => 36.0294444, lon => 6.5097222 },
+{ name => 'Mechtet Ain Maflouf', lat => 36.525, lon => 7.5347222 },
+{ name => 'Mzara Sidi Goulea', lat => 36.6638889, lon => 7.5583333 },
+{ name => 'Elbasan', lat => 41.1125, lon => 20.0822222 },
+{ name => 'Elbasani', lat => 41.1125, lon => 20.0822222 },
+{ name => 'Elbassan', lat => 41.1125, lon => 20.0822222 },
+{ name => 'Bosna-Sarai', lat => 43.85, lon => 18.3833333 },
+{ name => 'Sarajevo', lat => 43.85, lon => 18.3833333 },
+{ name => 'Vrh Bosna', lat => 43.85, lon => 18.3833333 },
+{ name => 'Chuquisaca', lat => -19.0430556, lon => -65.2591667 },
+{ name => 'Ciudad Potosi', lat => -19.5836111, lon => -65.7530556 },
+{ name => 'Ciudad Sucre', lat => -19.0430556, lon => -65.2591667 },
+{ name => 'Potos���', lat => -19.5836111, lon => -65.7530556 },
+{ name => 'Sucre', lat => -19.0430556, lon => -65.2591667 },
+{ name => 'Bazargic', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Bourgas', lat => 42.5, lon => 27.4666667 },
+{ name => 'Burgas', lat => 42.5, lon => 27.4666667 },
+{ name => 'Burgaz', lat => 42.5, lon => 27.4666667 },
+{ name => 'Burghaz', lat => 42.5, lon => 27.4666667 },
+{ name => 'Choum���n', lat => 43.2766667, lon => 26.9291667 },
+{ name => 'Dobri��', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Dobrich', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Dobritch', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Dobritsch', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Eski Zagra', lat => 42.4327778, lon => 25.6419444 },
+{ name => 'Eumolpias', lat => 42.15, lon => 24.75 },
+{ name => 'Filiba', lat => 42.15, lon => 24.75 },
+{ name => 'Filipopol', lat => 42.15, lon => 24.75 },
+{ name => 'Filippopol', lat => 42.15, lon => 24.75 },
+{ name => 'Flavia', lat => 42.15, lon => 24.75 },
+{ name => 'Had���i-Oghlu-Pazard���ik', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Islimje', lat => 42.6858333, lon => 26.3291667 },
+{ name => 'Julia', lat => 42.15, lon => 24.75 },
+{ name => 'Khadzhioglu Bazardzhik', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Khadzhioglu Pazardzhik', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Kolarovgrad', lat => 43.2766667, lon => 26.9291667 },
+{ name => 'Odessos', lat => 43.2166667, lon => 27.9166667 },
+{ name => 'Odessus', lat => 43.2166667, lon => 27.9166667 },
+{ name => 'Philippopel', lat => 42.15, lon => 24.75 },
+{ name => 'Philippopoli', lat => 42.15, lon => 24.75 },
+{ name => 'Philippopolis', lat => 42.15, lon => 24.75 },
+{ name => 'Pinople', lat => 42.15, lon => 24.75 },
+{ name => 'Pleven', lat => 43.4166667, lon => 24.6166667 },
+{ name => 'Plevna', lat => 43.4166667, lon => 24.6166667 },
+{ name => 'Plewen', lat => 43.4166667, lon => 24.6166667 },
+{ name => 'Plodin', lat => 42.15, lon => 24.75 },
+{ name => 'Ploudin', lat => 42.15, lon => 24.75 },
+{ name => 'Plovdin', lat => 42.15, lon => 24.75 },
+{ name => 'Plovdiv', lat => 42.15, lon => 24.75 },
+{ name => 'Plyeven', lat => 43.4166667, lon => 24.6166667 },
+{ name => 'Poulpoudeva', lat => 42.15, lon => 24.75 },
+{ name => 'Rouss���', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Roustchouk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Ruschuk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Ruschuq', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Rusciuk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Rusclink', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Ru�����uk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Ruse', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Rushchuk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Rushtuk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Russe', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Rustschuk', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Saray-Makhle', lat => 43.8563889, lon => 25.9708333 },
+{ name => 'Schumen', lat => 43.2766667, lon => 26.9291667 },
+{ name => 'Serdica', lat => 42.6833333, lon => 23.3166667 },
+{ name => 'Shumen', lat => 43.2766667, lon => 26.9291667 },
+{ name => 'Shumla', lat => 43.2766667, lon => 26.9291667 },
+{ name => 'Sinople', lat => 42.15, lon => 24.75 },
+{ name => 'Sliven', lat => 42.6858333, lon => 26.3291667 },
+{ name => 'Slivno', lat => 42.6858333, lon => 26.3291667 },
+{ name => 'Sliwen', lat => 42.6858333, lon => 26.3291667 },
+{ name => 'Sofia', lat => 42.6833333, lon => 23.3166667 },
+{ name => 'Sofija', lat => 42.6833333, lon => 23.3166667 },
+{ name => 'Sofiya', lat => 42.6833333, lon => 23.3166667 },
+{ name => 'Sredets', lat => 42.6833333, lon => 23.3166667 },
+{ name => 'Stalin', lat => 43.2166667, lon => 27.9166667 },
+{ name => 'Stara Sagora', lat => 42.4327778, lon => 25.6419444 },
+{ name => 'Stara Zagora', lat => 42.4327778, lon => 25.6419444 },
+{ name => '���umen', lat => 43.2766667, lon => 26.9291667 },
+{ name => '���umla', lat => 43.2766667, lon => 26.9291667 },
+{ name => 'Tolbuhin', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Tolbukhin', lat => 43.5666667, lon => 27.8333333 },
+{ name => 'Trimontium', lat => 42.15, lon => 24.75 },
+{ name => 'Ulpia', lat => 42.15, lon => 24.75 },
+{ name => 'Ulpia-Serdica', lat => 42.6833333, lon => 23.3166667 },
+{ name => 'Varna', lat => 43.2166667, lon => 27.9166667 },
+{ name => 'Vinipoppolis', lat => 42.15, lon => 24.75 },
+{ name => 'Warna', lat => 43.2166667, lon => 27.9166667 },
+{ name => 'Bubanza', lat => -3.0833333, lon => 29.3944444 },
+{ name => 'Buheranyi', lat => -3.095, lon => 30.3072222 },
+{ name => 'Bujumbura', lat => -3.3761111, lon => 29.36 },
+{ name => 'Bururi', lat => -3.9511111, lon => 29.6166667 },
+{ name => 'Cankuzo', lat => -3.2194444, lon => 30.5527778 },
+{ name => 'Cibitoke', lat => -2.8861111, lon => 29.1236111 },
+{ name => 'Ciyubake', lat => -3.4277778, lon => 29.9677778 },
+{ name => 'Dutwaro', lat => -3.3205556, lon => 29.8611111 },
+{ name => 'Gacaca', lat => -3.2869444, lon => 29.9322222 },
+{ name => 'Gasyangiri', lat => -3.3458333, lon => 30.42 },
+{ name => 'Gitega', lat => -3.425, lon => 29.9333333 },
+{ name => 'Karuzi', lat => -3.1013889, lon => 30.1647222 },
+{ name => 'Kayanza', lat => -2.9222222, lon => 29.6222222 },
+{ name => 'Kibenga', lat => -3.7991667, lon => 29.3858333 },
+{ name => 'Kirambi', lat => -3.4352778, lon => 30.1155556 },
+{ name => 'Kirundo', lat => -2.5847222, lon => 30.0972222 },
+{ name => 'Kiryama', lat => -2.6588889, lon => 30.0502778 },
+{ name => 'Kitega', lat => -3.425, lon => 29.9333333 },
+{ name => 'Makamba', lat => -4.1347222, lon => 29.805 },
+{ name => 'Muramvya', lat => -3.2680556, lon => 29.6166667 },
+{ name => 'Mururinzi', lat => -3.1361111, lon => 30.4508333 },
+{ name => 'Muyinga', lat => -2.8494444, lon => 30.3361111 },
+{ name => 'Ngozi', lat => -2.9083333, lon => 29.8277778 },
+{ name => 'Nyaguhaga', lat => -3.5266667, lon => 30.1477778 },
+{ name => 'Nyamuhanga', lat => -3.8283333, lon => 29.5947222 },
+{ name => 'Rusunwe', lat => -3.0511111, lon => 29.9180556 },
+{ name => 'Rutana', lat => -3.9191667, lon => 29.9936111 },
+{ name => 'Ruvumu', lat => -3.4144444, lon => 30.1094444 },
+{ name => 'Ruyigi', lat => -3.4763889, lon => 30.2486111 },
+{ name => 'Rwimbogo', lat => -3.2808333, lon => 30.4641667 },
+{ name => 'Beijing', lat => 39.9288889, lon => 116.3883333 },
+{ name => 'Beijing Shi', lat => 39.9288889, lon => 116.3883333 },
+{ name => 'Kombo Lot���', lat => 3.4830556, lon => 9.7280556 },
+{ name => 'Bangui', lat => 4.3666667, lon => 18.5833333 },
+{ name => 'Aalborg', lat => 57.05, lon => 9.9333333 },
+{ name => 'Aarhus', lat => 56.15, lon => 10.2166667 },
+{ name => '��lborg', lat => 57.05, lon => 9.9333333 },
+{ name => '��rhus', lat => 56.15, lon => 10.2166667 },
+{ name => 'Copenhagen', lat => 55.6666667, lon => 12.5833333 },
+{ name => 'Kjobenhavn', lat => 55.6666667, lon => 12.5833333 },
+{ name => 'K���benhavn', lat => 55.6666667, lon => 12.5833333 },
+{ name => 'Odense', lat => 55.4, lon => 10.3833333 },
+{ name => 'Qaryat \`Al��� Bin Ab��� �����lib', lat => 26.7005556, lon => 31.4236111 },
+{ name => 'Baile ��tha Cliath', lat => 53.3330556, lon => -6.2488889 },
+{ name => 'Corcaigh', lat => 51.8986111, lon => -8.4958333 },
+{ name => 'Cork', lat => 51.8986111, lon => -8.4958333 },
+{ name => 'Dublin', lat => 53.3330556, lon => -6.2488889 },
+{ name => 'D���n Laoghaire', lat => 53.2925, lon => -6.1286111 },
+{ name => 'Dunleary', lat => 53.2925, lon => -6.1286111 },
+{ name => 'Kingstown', lat => 53.2925, lon => -6.1286111 },
+{ name => 'Derpt', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'Dorpat', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'Kallinn', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Kolyvan', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'R����veli', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Reval', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Revel\'', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Talinas', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Tallin', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Tallina', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Tallinn', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Tallinna', lat => 59.4338889, lon => 24.7280556 },
+{ name => 'Tartto', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'Tartu', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'T��rbata', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'Yurev', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'Yur\'yev', lat => 58.3661111, lon => 26.7361111 },
+{ name => 'Pilsen', lat => 49.75, lon => 13.3666667 },
+{ name => 'Plze��', lat => 49.75, lon => 13.3666667 },
+{ name => '��bo', lat => 60.45, lon => 22.2833333 },
+{ name => 'Esbo', lat => 60.2166667, lon => 24.6666667 },
+{ name => 'Espoo', lat => 60.2166667, lon => 24.6666667 },
+{ name => 'Helsingfors', lat => 60.1755556, lon => 24.9341667 },
+{ name => 'Helsinki', lat => 60.1755556, lon => 24.9341667 },
+{ name => 'Khel\'sinki', lat => 60.1755556, lon => 24.9341667 },
+{ name => 'Oulu', lat => 65.0166667, lon => 25.4666667 },
+{ name => 'Tammerfors', lat => 61.5, lon => 23.75 },
+{ name => 'Tampere', lat => 61.5, lon => 23.75 },
+{ name => 'Turku', lat => 60.45, lon => 22.2833333 },
+{ name => 'Ule���borg', lat => 65.0166667, lon => 25.4666667 },
+{ name => 'Uleoborg', lat => 65.0166667, lon => 25.4666667 },
+{ name => 'Vanda', lat => 60.3, lon => 24.85 },
+{ name => 'Vantaa', lat => 60.3, lon => 24.85 },
+{ name => 'Yelsinki', lat => 60.1755556, lon => 24.9341667 },
+{ name => 'Paris', lat => 48.8666667, lon => 2.3333333 },
+{ name => 'Godthaab', lat => 64.1833333, lon => -51.75 },
+{ name => 'Godth���b', lat => 64.1833333, lon => -51.75 },
+{ name => 'Nuk', lat => 64.1833333, lon => -51.75 },
+{ name => 'Nuuk', lat => 64.1833333, lon => -51.75 },
+{ name => 'Augusta Ubiorum', lat => 50.9333333, lon => 6.95 },
+{ name => 'Berlin', lat => 52.5166667, lon => 13.4 },
+{ name => 'Bremen', lat => 53.0833333, lon => 8.8 },
+{ name => 'C���ln', lat => 50.9333333, lon => 6.95 },
+{ name => 'Cologne', lat => 50.9333333, lon => 6.95 },
+{ name => 'Colonia Agrippina', lat => 50.9333333, lon => 6.95 },
+{ name => 'Colonia Agrippinensis', lat => 50.9333333, lon => 6.95 },
+{ name => 'Dortmund', lat => 51.5166667, lon => 7.45 },
+{ name => 'Duisburg', lat => 51.4333333, lon => 6.75 },
+{ name => 'Duisburg and Hamborn', lat => 51.4333333, lon => 6.75 },
+{ name => 'Duisburg-Hamborn', lat => 51.4333333, lon => 6.75 },
+{ name => 'D���sseldorf', lat => 51.2166667, lon => 6.7666667 },
+{ name => 'Essen', lat => 51.45, lon => 7.0166667 },
+{ name => 'Frankford-on-Main', lat => 50.1166667, lon => 8.6833333 },
+{ name => 'Frankfort', lat => 50.1166667, lon => 8.6833333 },
+{ name => 'Frankfort on the Main', lat => 50.1166667, lon => 8.6833333 },
+{ name => 'Frankfurt', lat => 50.1166667, lon => 8.6833333 },
+{ name => 'Frankfurt', lat => 50.1166667, lon => 8.6833333 },
+{ name => 'Hamburg', lat => 53.55, lon => 10.0 },
+{ name => 'Hannover', lat => 52.3666667, lon => 9.7166667 },
+{ name => 'Hanover', lat => 52.3666667, lon => 9.7166667 },
+{ name => 'Koeln', lat => 50.9333333, lon => 6.95 },
+{ name => 'K���ln', lat => 50.9333333, lon => 6.95 },
+{ name => 'Monaco', lat => 48.15, lon => 11.5833333 },
+{ name => 'Muenchen', lat => 48.15, lon => 11.5833333 },
+{ name => 'M���nchen', lat => 48.15, lon => 11.5833333 },
+{ name => 'Munich', lat => 48.15, lon => 11.5833333 },
+{ name => 'Stuttgart', lat => 48.7666667, lon => 9.1833333 },
+{ name => 'L���risa', lat => 39.6372222, lon => 22.4202778 },
+{ name => 'L���rissa', lat => 39.6372222, lon => 22.4202778 },
+{ name => 'Le Pir���e', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'P���tra', lat => 38.2444444, lon => 21.7344444 },
+{ name => 'Patrae', lat => 38.2444444, lon => 21.7344444 },
+{ name => 'P���trai', lat => 38.2444444, lon => 21.7344444 },
+{ name => 'Patras', lat => 38.2444444, lon => 21.7344444 },
+{ name => 'Patrasse', lat => 38.2444444, lon => 21.7344444 },
+{ name => 'Peiraeus', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Peirai���', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Peirai���fs', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Peiraieus', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Peiraievs', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Piraeus', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Pirai���vs', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Pir���efs', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Pireo', lat => 37.9613889, lon => 23.6388889 },
+{ name => 'Salonica', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Salonika', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Salon���ki', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Salonique', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Selanik', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Solun', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Thessalon���k��', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Thessalon���ki', lat => 40.6402778, lon => 22.9438889 },
+{ name => 'Agram', lat => 45.8, lon => 16.0 },
+{ name => 'Andautonia', lat => 45.8, lon => 16.0 },
+{ name => 'Fiume', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Fkumen', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Flumen Sancti Viti', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'R��ka', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Rieka', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Rijeka', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Sankt Veit am Flaum', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Sankt Veit am Pflaum', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Vitipolis', lat => 45.3430556, lon => 14.4091667 },
+{ name => 'Zabrag', lat => 45.8, lon => 16.0 },
+{ name => 'Zabreg', lat => 45.8, lon => 16.0 },
+{ name => 'Zagabria', lat => 45.8, lon => 16.0 },
+{ name => 'Z���gr���b', lat => 45.8, lon => 16.0 },
+{ name => 'Zagrabia', lat => 45.8, lon => 16.0 },
+{ name => 'Zagreb', lat => 45.8, lon => 16.0 },
+{ name => 'Djumpandang', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Macassar', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Makasar', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Makassar', lat => 2.45, lon => 99.7833333 },
+{ name => 'Makassar', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Makasser', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Udjungpadang', lat => 2.45, lon => 99.7833333 },
+{ name => 'Udjung Pandang', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Ujungpadang', lat => 2.45, lon => 99.7833333 },
+{ name => 'Ujungpandang', lat => -5.1463889, lon => 119.4386111 },
+{ name => 'Asumumbay', lat => 18.975, lon => 72.8258333 },
+{ name => 'Bombay', lat => 18.975, lon => 72.8258333 },
+{ name => 'Mumbai', lat => 18.975, lon => 72.8258333 },
+{ name => 'Numbai', lat => 18.975, lon => 72.8258333 },
+{ name => 'Ghar��b���-e K���chek', lat => 30.2075, lon => 49.685 },
+{ name => 'Ghar��b���-e yakom', lat => 30.2075, lon => 49.685 },
+{ name => 'Ghar��bi K���chik', lat => 30.2075, lon => 49.685 },
+{ name => 'Ghar��b���-ye K���chek', lat => 30.2075, lon => 49.685 },
+{ name => 'Ghar��b���-ye \`Oly��', lat => 30.2075, lon => 49.685 },
+{ name => '���oseyn��b��d', lat => 34.8558333, lon => 50.8583333 },
+{ name => 'Na\`���m��b��d', lat => 34.45, lon => 50.8683333 },
+{ name => 'Kavagbouma', lat => 7.8533333, lon => -6.1066667 },
+{ name => 'Kavagouma', lat => 7.8533333, lon => -6.1066667 },
+{ name => 'Edo', lat => 35.685, lon => 139.7513889 },
+{ name => 'Tokio', lat => 35.685, lon => 139.7513889 },
+{ name => 'Tokyo', lat => 35.685, lon => 139.7513889 },
+{ name => 'T��ky��', lat => 35.685, lon => 139.7513889 },
+{ name => 'Heij��', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Heij��-fu', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Heizy��', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Heizy�� Hu', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Hpyeng-yang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'P-hj���ng-jang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Phyeng-yang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Phyong-yang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Pienyang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Pingyang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Pyengyang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'P\'y��ngyang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Pyongyang', lat => 39.0194444, lon => 125.7547222 },
+{ name => 'Choei-yuen', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Hang-yang-tcheng', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Hans��ng', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'H��n-yang', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'H��-seng', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Kan-y��-j��', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Keijo', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Keizy��e', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Kiung', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Ky��ngs��ng', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Seoul', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Seul', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'S��ul', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Suigen', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Sye-ul', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Syou-ouen', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'Wang-ching', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'W��-j��', lat => 37.5663889, lon => 126.9997222 },
+{ name => 'R���ga', lat => 56.95, lon => 24.1 },
+{ name => 'Rija', lat => 56.95, lon => 24.1 },
+{ name => 'Caunas', lat => 54.9, lon => 23.9 },
+{ name => 'Kauen', lat => 54.9, lon => 23.9 },
+{ name => 'Kaunas', lat => 54.9, lon => 23.9 },
+{ name => 'Kauno', lat => 54.9, lon => 23.9 },
+{ name => 'Kovno', lat => 54.9, lon => 23.9 },
+{ name => 'Kowno', lat => 54.9, lon => 23.9 },
+{ name => 'Palemonas', lat => 54.9, lon => 23.9 },
+{ name => 'Panevezhi', lat => 55.7333333, lon => 24.35 },
+{ name => 'Panevezhis', lat => 55.7333333, lon => 24.35 },
+{ name => 'Panev����io', lat => 55.7333333, lon => 24.35 },
+{ name => 'Panev����ys', lat => 55.7333333, lon => 24.35 },
+{ name => 'Poniewesch', lat => 55.7333333, lon => 24.35 },
+{ name => 'Poniewiesh', lat => 55.7333333, lon => 24.35 },
+{ name => 'Poniewie���', lat => 55.7333333, lon => 24.35 },
+{ name => 'Schaulen', lat => 55.9333333, lon => 23.3166667 },
+{ name => 'Shaulyay', lat => 55.9333333, lon => 23.3166667 },
+{ name => 'Shavli', lat => 55.9333333, lon => 23.3166667 },
+{ name => 'Shyaulyay', lat => 55.9333333, lon => 23.3166667 },
+{ name => '���iauliai', lat => 55.9333333, lon => 23.3166667 },
+{ name => '���iauli���', lat => 55.9333333, lon => 23.3166667 },
+{ name => 'Sokniai', lat => 55.9333333, lon => 23.3166667 },
+{ name => 'Szawle', lat => 55.9333333, lon => 23.3166667 },
+{ name => 'Vilna', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'Vilnia', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'Vilnius', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'Vil\'no', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'Vil\'nyus', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'Wilna', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'Wilno', lat => 54.6833333, lon => 25.3166667 },
+{ name => 'B��l���i', lat => 47.7616667, lon => 27.9288889 },
+{ name => 'Baltsy', lat => 47.7616667, lon => 27.9288889 },
+{ name => 'Beltsi', lat => 47.7616667, lon => 27.9288889 },
+{ name => 'Bel\'tsy', lat => 47.7616667, lon => 27.9288889 },
+{ name => 'Bendary', lat => 46.8305556, lon => 29.4711111 },
+{ name => 'Bender', lat => 46.8305556, lon => 29.4711111 },
+{ name => 'Bendery', lat => 46.8305556, lon => 29.4711111 },
+{ name => 'Byelcy', lat => 47.7616667, lon => 27.9288889 },
+{ name => 'Chi��in��u', lat => 47.0055556, lon => 28.8575 },
+{ name => 'Kischinew', lat => 47.0055556, lon => 28.8575 },
+{ name => 'Kiscinev', lat => 47.0055556, lon => 28.8575 },
+{ name => 'Kishinef', lat => 47.0055556, lon => 28.8575 },
+{ name => 'Kishin���v', lat => 47.0055556, lon => 28.8575 },
+{ name => 'Kishiniv', lat => 47.0055556, lon => 28.8575 },
+{ name => 'Tighina', lat => 46.8305556, lon => 29.4711111 },
+{ name => 'Tigina', lat => 46.8305556, lon => 29.4711111 },
+{ name => 'Tiraspol', lat => 46.8402778, lon => 29.6433333 },
+{ name => 'Tiraspol\'', lat => 46.8402778, lon => 29.6433333 },
+{ name => 'Al Qunay���irah', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Kenitra', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Khenifra', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Lyautey', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Mina Hassan Tani', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Port Laoti', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Port-Lyautey', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Rabat', lat => 34.0252778, lon => -6.8361111 },
+{ name => 'Sal���', lat => 34.0394444, lon => -6.8027778 },
+{ name => 'Sali', lat => 34.0394444, lon => -6.8027778 },
+{ name => 'Sallee', lat => 34.0394444, lon => -6.8027778 },
+{ name => 'Sla', lat => 34.0394444, lon => -6.8027778 },
+{ name => 'Ville de Kenitra', lat => 34.2608333, lon => -6.5794444 },
+{ name => 'Maale', lat => 4.1666667, lon => 73.5 },
+{ name => 'Male', lat => 4.1666667, lon => 73.5 },
+{ name => 'Bergen', lat => 60.3911111, lon => 5.3247222 },
+{ name => 'Christiania', lat => 59.9166667, lon => 10.75 },
+{ name => 'Kristiania', lat => 59.9166667, lon => 10.75 },
+{ name => 'Nidaros', lat => 63.4166667, lon => 10.4166667 },
+{ name => 'Oslo', lat => 59.9166667, lon => 10.75 },
+{ name => 'Trondheim', lat => 63.4166667, lon => 10.4166667 },
+{ name => 'Trondhjem', lat => 63.4166667, lon => 10.4166667 },
+{ name => 'Basti Khokhar', lat => 28.4125, lon => 70.1027778 },
+{ name => 'Seri Guria', lat => 34.4361111, lon => 73.0194444 },
+{ name => 'La Palma', lat => 8.4027778, lon => -78.1452778 },
+{ name => 'Felicitas Julia', lat => 38.7166667, lon => -9.1333333 },
+{ name => 'Lisboa', lat => 38.7166667, lon => -9.1333333 },
+{ name => 'Lisbon', lat => 38.7166667, lon => -9.1333333 },
+{ name => 'Lissabon', lat => 38.7166667, lon => -9.1333333 },
+{ name => 'Olisipo', lat => 38.7166667, lon => -9.1333333 },
+{ name => 'Al\'met\'yevo', lat => 54.8833333, lon => 52.3333333 },
+{ name => 'Al\'met\'yevsk', lat => 54.8833333, lon => 52.3333333 },
+{ name => 'Archangel', lat => 64.5666667, lon => 40.5333333 },
+{ name => 'Archangelsk', lat => 64.5666667, lon => 40.5333333 },
+{ name => 'Arkhangel\'sk', lat => 64.5666667, lon => 40.5333333 },
+{ name => 'Brezhnev', lat => 55.7561111, lon => 52.4288889 },
+{ name => 'Kasan', lat => 55.75, lon => 49.1333333 },
+{ name => 'Kazan\'', lat => 55.75, lon => 49.1333333 },
+{ name => 'Molotovsk', lat => 64.5666667, lon => 39.8333333 },
+{ name => 'Molotowsk', lat => 64.5666667, lon => 39.8333333 },
+{ name => 'Naberezhnyye Chelny', lat => 55.7561111, lon => 52.4288889 },
+{ name => 'Nizhnekamsk', lat => 55.6383333, lon => 51.8169444 },
+{ name => 'Nizhnekamskiy', lat => 55.6383333, lon => 51.8169444 },
+{ name => 'Novo-Kholmogory', lat => 64.5666667, lon => 40.5333333 },
+{ name => 'Novyye Kholmogory', lat => 64.5666667, lon => 40.5333333 },
+{ name => 'Severodvinsk', lat => 64.5666667, lon => 39.8333333 },
+{ name => 'Sudostroy', lat => 64.5666667, lon => 39.8333333 },
+{ name => 'Dakar', lat => 14.6708333, lon => -17.4380556 },
+{ name => 'Goeteborg', lat => 57.7166667, lon => 11.9666667 },
+{ name => 'G���teborg', lat => 57.7166667, lon => 11.9666667 },
+{ name => 'Goteburg', lat => 57.7166667, lon => 11.9666667 },
+{ name => 'Gothenburg', lat => 57.7166667, lon => 11.9666667 },
+{ name => 'Gottenborg', lat => 57.7166667, lon => 11.9666667 },
+{ name => 'Malm���', lat => 55.6, lon => 13.0 },
+{ name => 'Stockholm', lat => 59.3333333, lon => 18.05 },
+{ name => 'Tukholma', lat => 59.3333333, lon => 18.05 },
+{ name => 'Uppsala', lat => 59.85, lon => 17.6333333 },
+{ name => 'V���ster���s', lat => 59.6166667, lon => 16.55 },
+{ name => 'B���le', lat => 47.5666667, lon => 7.6 },
+{ name => 'Basel', lat => 47.5666667, lon => 7.6 },
+{ name => 'Basilea', lat => 47.5666667, lon => 7.6 },
+{ name => 'Basle', lat => 47.5666667, lon => 7.6 },
+{ name => 'Bern', lat => 46.9166667, lon => 7.4666667 },
+{ name => 'Berna', lat => 46.9166667, lon => 7.4666667 },
+{ name => 'Berne', lat => 46.9166667, lon => 7.4666667 },
+{ name => 'Geneva', lat => 46.2, lon => 6.1666667 },
+{ name => 'Gen���ve', lat => 46.2, lon => 6.1666667 },
+{ name => 'Genf', lat => 46.2, lon => 6.1666667 },
+{ name => 'Ginevra', lat => 46.2, lon => 6.1666667 },
+{ name => 'Lausanne', lat => 46.5333333, lon => 6.6666667 },
+{ name => 'Z���rich', lat => 47.3666667, lon => 8.55 },
+{ name => 'Astacus', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Boursa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Brossa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Broussa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Brousse', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Brusa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Brussa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Bursa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Chalcedon', lat => 40.9855556, lon => 29.0294444 },
+{ name => 'Cocaeli', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Conia', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Gebze', lat => 40.7977778, lon => 29.4305556 },
+{ name => 'Guebze', lat => 40.7977778, lon => 29.4305556 },
+{ name => 'Iconium', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Ikoniow', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Ismid', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Ismit', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Isnimid', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Izmid', lat => 40.7669444, lon => 29.9169444 },
+{ name => '���zmit', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Kadi Kioi', lat => 40.9855556, lon => 29.0294444 },
+{ name => 'Kadik���i', lat => 40.9855556, lon => 29.0294444 },
+{ name => 'Kad���k���y', lat => 40.9855556, lon => 29.0294444 },
+{ name => 'Kartal', lat => 40.9033333, lon => 29.1725 },
+{ name => 'Kocaeli', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Kodja-Eli', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Koja-Ili', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Konia', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Konieh', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Konya', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Kuniyah', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Nicomedia', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Nikomedeia', lat => 40.7669444, lon => 29.9169444 },
+{ name => 'Pendik', lat => 40.8775, lon => 29.2513889 },
+{ name => 'Prousa', lat => 40.1916667, lon => 29.0611111 },
+{ name => 'Qonia', lat => 37.8655556, lon => 32.4825 },
+{ name => 'Seyhan', lat => 37.0, lon => 35.3044444 },
+{ name => 'Ouagadouga', lat => 12.3702778, lon => -1.5247222 },
+{ name => 'Ouagadougou', lat => 12.3702778, lon => -1.5247222 },
+{ name => 'Wagadugu', lat => 12.3702778, lon => -1.5247222 },
+{ name => 'Donja Badanja', lat => 44.5, lon => 19.4758333 },
+{ name => 'Ili��i', lat => 44.0477778, lon => 19.7783333 },
+{ name => 'Joki��i', lat => 44.0491667, lon => 19.7847222 },
+{ name => 'Maria-Theresianopel', lat => 46.1, lon => 19.6666667 },
+{ name => 'Maria-Theresiopel', lat => 46.1, lon => 19.6666667 },
+{ name => 'Maria-Theresiopolis', lat => 46.1, lon => 19.6666667 },
+{ name => 'Nich', lat => 43.3247222, lon => 21.9033333 },
+{ name => 'Ni���', lat => 43.3247222, lon => 21.9033333 },
+{ name => 'Nisch', lat => 43.3247222, lon => 21.9033333 },
+{ name => 'Nish', lat => 43.3247222, lon => 21.9033333 },
+{ name => 'Nissa', lat => 43.3247222, lon => 21.9033333 },
+{ name => 'Podgorica', lat => 42.4411111, lon => 19.2636111 },
+{ name => 'Prishtin���', lat => 42.6666667, lon => 21.1666667 },
+{ name => 'Pri���tina', lat => 42.6666667, lon => 21.1666667 },
+{ name => 'Sawaditz', lat => 46.1, lon => 19.6666667 },
+{ name => 'Slatina', lat => 44.6491667, lon => 19.6469444 },
+{ name => 'Subotica', lat => 46.1, lon => 19.6666667 },
+{ name => 'Szabadka', lat => 46.1, lon => 19.6666667 },
+{ name => 'Szent-M���ria', lat => 46.1, lon => 19.6666667 },
+{ name => 'Theresiopel', lat => 46.1, lon => 19.6666667 },
+{ name => 'Titograd', lat => 42.4411111, lon => 19.2636111 },
+{ name => 'Zubotica', lat => 46.1, lon => 19.6666667 },
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/Gps.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/Gps.pm
new file mode 100644
index 0000000..ebddc43
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/Gps.pm
@@ -0,0 +1,236 @@
+# Some Gps related Functions
+#
+# $Log$
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.6 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.5 2005/05/24 08:35:25 tweety
+# move track splitting to its own function +sub track_add($)
+# a little bit more error handling
+# earth_distance somtimes had complex inumbers as result
+# implemented streets_check_if_moved_reset which is called when you toggle the draw streets button
+# this way i can re-read all currently displayed streets from the DB
+# fix minor array iindex counting bugs
+# add some content to the comment column
+#
+# Revision 1.4 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.3 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+use strict;
+use warnings;
+
+package Geo::Gpsdrive::Gps;
+
+use IO::File;
+use File::Basename;
+use Data::Dumper;
+use Math::Trig;
+#use Date::Manip qw(ParseDate DateCalc UnixDate);
+
+require Exporter;
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+
+@ISA = qw( Exporter );
+
+@EXPORT = qw( earth_distance miles2km hash2str is_in_country is_europe is_germany is_bayern is_muenchen);
+
+my $M_PI = 3.14159;
+
+my $last_point={};
+my $last_points=[];
+
+#############################################################################
+sub pow($$){
+ my $x = shift;
+ my $y = shift;
+ return ($x ** $y);
+}
+#############################################################################
+sub xx_rad2deg($){
+ my $x = shift;
+ return $x * $M_PI/180.0;
+}
+
+#############################################################################
+# Liegen die Punkte im Groben innerhalb Europas/Deutschland?
+sub is_in_country($$){
+ my $point=shift;
+ my $country=shift;
+ if ($country =~ m/europ/ ) {
+ return is_europe($point);
+ } elsif ($country =~ m/bayern/ ) {
+ return is_bayern($point);
+ } elsif ($country =~ m/muenchen/ ) {
+ return 0 if $point->{lat} < 45;
+ return 0 if $point->{lat} >49;
+ return 0 if $point->{lon} <9.5;
+ return 0 if $point->{lon} >12;
+ } else {
+ return is_germany($point);
+ }
+ return 1;
+}
+
+#############################################################################
+# Liegen die Punkte im Groben innerhalb Europas?
+sub is_europe($){
+ my $point = shift;
+ return 0 if $point->{lat} < 5;
+ return 0 if $point->{lat} > 60;
+ return 0 if $point->{lon} < -10;
+ return 0 if $point->{lon} > 20;
+# return 0 if $point->{lat} < 10;
+# return 0 if $point->{lat} > 56;
+# return 0 if $point->{lon} < 0;
+# return 0 if $point->{lon} > 16;
+ return 1;
+}
+
+#############################################################################
+# Liegen die Punkte im Groben innerhalb Deutschlands?
+sub is_germany($){
+ my $point = shift;
+ return 0 if $point->{lat} <47;
+ return 0 if $point->{lat} >55;
+ return 0 if $point->{lon} <5;
+ return 0 if $point->{lon} >15;
+ return 1;
+}
+
+#############################################################################
+# Liegen die Punkte im Groben innerhalb Bayern?
+sub is_bayern($){
+ my $point = shift;
+ return 0 if $point->{lat} <47;
+ return 0 if $point->{lat} >51;
+ return 0 if $point->{lon} <5;
+ return 0 if $point->{lon} >15;
+ return 1;
+}
+
+
+#############################################################################
+
+sub earth_distance($$$$){
+ my $lat1 = shift || 0;
+ my $lon1 = shift || 0;
+ my $lat2 = shift || 0;
+ my $lon2 = shift || 0;
+
+ # /*
+ # my $calcedR1 = calcR(lat1);
+ # my $calcedR2 = calcR(lat2);
+
+ # my $sinradi1 = sin(rad2deg(90-lat1));
+ # my $sinradi2 = sin(rad2deg(90-lat2));
+
+ # my $x1 = calcedR1 * cos(rad2deg(lon1)) * sinradi1;
+ # my $x2 = calcedR2 * cos(rad2deg(lon2)) * sinradi2;
+ # my $y1 = calcedR1 * sin(rad2deg(lon1)) * sinradi1;
+ # my $y2 = calcedR2 * sin(rad2deg(lon2)) * sinradi2;
+ # my $z1 = calcedR1 * cos(rad2deg(90-lat1));
+ # my $z2 = calcedR2 * cos(rad2deg(90-lat2));
+
+ # my $calcedR = calcR((double)(lat1+lat2)) / 2;
+ # my $a = acos((x1*x2 + y1*y2 + z1*z2)/square(calcedR));
+ # */
+
+ my $x1 = calcR( $lat1 ) * cos(rad2deg( $lon1 )) * sin(rad2deg( 90-$lat1 ));
+ my $x2 = calcR( $lat2 ) * cos(rad2deg( $lon2 )) * sin(rad2deg( 90-$lat2 ));
+ my $y1 = calcR( $lat1 ) * sin(rad2deg( $lon1 )) * sin(rad2deg( 90-$lat1 ));
+ my $y2 = calcR( $lat2 ) * sin(rad2deg( $lon2 )) * sin(rad2deg( 90-$lat2 ));
+ my $z1 = calcR( $lat1 ) * cos(rad2deg( 90 - $lat1 ));
+ my $z2 = calcR( $lat2 ) * cos(rad2deg( 90 - $lat2 ));
+ my $r = calcR( ($lat1+$lat2)/2);
+
+# print "earth_distance($lat1,$lon1,$lat2,$lon2)\n";
+
+ my $a = acos( ($x1*$x2 + $y1*$y2 + $z1*$z2) / pow($r,2) );
+ if ( UNIVERSAL::isa($a,'Math::Complex')) {
+ $a = $a->Re();
+ }
+
+ my $erg = calcR( ($lat1+$lat2) / 2) * $a;
+ $erg = $erg / 3340;
+
+ if ( $erg =~ m/i$/) {
+ print "==================================================================\n";
+ print "WARNING: Complex Result\n";
+ print "earth_distance($lat1,$lon1,$lat2,$lon2) = ($erg)".Dumper($erg);
+ };
+ return $erg;
+}
+
+# Lifted from gpsdrive 1.7
+# CalcR gets the radius of the earth at a particular latitude
+# calcxy finds the x and y positions on a 1280x1024 image of a certian scale
+# centered on a given lat/lon.
+
+# This pulls the "real radius" of a lat, instead of a global guesstimate
+sub calcR($){
+ my $lat = shift;
+
+ my $a = 6378.137;
+ my ( $r, $sc, $x, $y, $z);
+ my $e2 = 0.081082 * 0.081082;
+ # the radius of curvature of an ellipsoidal Earth in the plane of the
+ # meridian is given by
+
+ #R' = a * (1 - e^2) / (1 - e^2 * (sin(lat))^2)^(3/2)
+
+ #where a is the equatorial radius,
+ # b is the polar radius, and
+ # e is the eccentricity of the ellipsoid = sqrt(1 - b^2/a^2)
+
+ # a = 6378 km (3963 mi) Equatorial radius (surface to center distance)
+ # b = 6356.752 km (3950 mi) Polar radius (surface to center distance)
+ # e = 0.081082 Eccentricity
+ # */
+
+ $lat = $lat * $M_PI / 180.0;
+ $sc = sin($lat);
+ $x = $a * (1.0 - $e2);
+ $z = 1.0 - $e2 * $sc * $sc;
+ $y = pow($z, 1.5);
+ $r = $x / $y;
+
+ $r = $r * 1000.0;
+ return $r;
+}
+
+my $map_width = 1280;
+my $map_height = 1024;
+my $draw_x_offset=0;
+my $draw_y_offset=0;
+
+
+sub miles2km($){
+ my $m = shift;
+ return $m * 1.609344;
+}
+
+sub hash2str($){
+ my $h = shift;
+ my $erg = '';
+
+ foreach my $k ( sort keys %$h){
+ next if $k eq 'line';
+ $erg .= ", " if $erg;
+ $erg .= "$k=$h->{$k}";
+ }
+ $erg .= " line: $h->{line} ";
+ return $erg;
+}
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/GpsDrive.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/GpsDrive.pm
new file mode 100644
index 0000000..b799eb1
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/GpsDrive.pm
@@ -0,0 +1,255 @@
+# Einlesen der GpsDrive Track Daten und schreiben in die geoinfo Datenbank von
+# gpsdrive
+#
+# $Log$
+# Revision 1.2 2005/10/11 08:28:35 tweety
+# gpsdrive:
+# - add Tracks(MySql) displaying
+# - reindent files modified
+# - Fix setting of Color for Grid
+# - poi Text is different in size depending on Number of POIs shown on
+# screen
+#
+# geoinfo:
+# - get Proxy settings from Environment
+# - create tracks Table in Database and fill it
+# this separates Street Data from Track Data
+# - make geoinfo.pl download also Opengeodb Version 2
+# - add some poi-types
+# - Split off Filling DB with example Data
+# - extract some more Funtionality to Procedures
+# - Add some Example POI for Kirchheim(Munich) Area
+# - Adjust some Output for what is done at the moment
+# - Add more delayed index generations 'disable/enable key'
+# - If LANG=*de_DE* then only impert europe with --all option
+# - WDB will import more than one country if you wish
+# - add more things to be done with the --all option
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.8 2005/08/14 09:47:17 tweety
+# seperate tracks into it own table in geoinfo database
+# move Info's from TODO abaout geoinfo DB to Man Page
+# rename poi.pl to geoinfo.pl
+#
+# Revision 1.7 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.6 2005/07/07 06:45:23 tweety
+# Autor: Blake Swadling <blake@swadling.com>
+# Autor: John Hay <jhay@icomtek.csir.co.za>
+# Honor Makefile src
+# honor +- in import track
+# update TODO
+#
+# Revision 1.5 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.4 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::GpsDrive;
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Basename;
+use File::Path;
+use Date::Manip;
+use Time::Local;
+
+#use Data::Dumper;
+
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Geo::Gpsdrive::Gps;
+
+use Geo::Gpsdrive::DB_tracks;
+
+my $multi_insert=1; # Insert with a multicommand all segments of a sub-track at once
+ # 0=insert each segment of track as it is processed
+$|=1;
+
+##########################################################################
+
+sub import_GpsDrive_track_file($$){
+ my $full_filename = shift;
+ my $source_id = shift;
+
+ print "Reading Track File $full_filename\n";
+
+ my $fh = IO::File->new("<$full_filename");
+
+ my ($lat1,$lon1,$alt1,$time1) = (0,0,0,0);
+ my ($lat2,$lon2,$alt2,$time2) = (0,0,0,0);
+
+ my $track_nr=0;
+ my $segments_in_track=0;
+ my $segments=[];
+ while ( my $line = $fh->getline() ) {
+ my $valid=0;
+ my $tracks_type_id = 2;
+
+ chomp $line;
+# print "line: $line\n";
+ #48.175667 11.754383 561 Tue May 18 18:28:04 2004
+
+ ( $lat1,$lon1,$alt1,$time1 ) = ( $lat2,$lon2,$alt2,$time2 );
+
+ ( $lat2,$lon2,$alt2,$time2 ) = (0,0,0,0);
+
+ if ($line =~ m/^\s*(-?\d{1,3}\.\d+)\s+(-?\d{1,3}\.\d+)\s+(-?[\d\.]+)\s+(\S+\s+\S+\s+\d+\s+[\d\:]+\s+\d+)/ ) {
+ $lat2 = $1;
+ $lon2 = $2;
+ $alt2 = $3;
+ my $date = ParseDate($4);
+ # Wed Dec 10 09:38:24 2003
+ $time2 = UnixDate($date,"%s");
+ $valid=1;
+ } elsif ( $line =~ m/^\s*$/) {
+ } elsif ( $line =~ m/^\s*nan\s*nan\s*/) {
+ } elsif ( $line =~ m/^\s*1001.000000 1001.000000\s*/) {
+ } else {
+ print "Unparsed Line '$line'";
+ }
+
+ next unless $valid;
+
+
+ my $dist = Geo::Gpsdrive::Gps::earth_distance($lat1,$lon1,$lat2,$lon2);;
+ my $time_delta = $time2 - $time1;
+ my $speed = $valid&&$time_delta ? $dist / $time_delta * 3.600 : -1;
+ #printf "Dist: %.4f/%.2f => %.2f\n",$dist,$time_delta,$speed;
+ $tracks_type_id = 1 if ( $speed >0 );
+ $tracks_type_id = 2 if ( $speed >30 );
+ $tracks_type_id = 3 if ( $speed >60 );
+ $tracks_type_id = 4 if ( $speed >100 );
+
+ if ( $alt2 == 1001 ) { # Otherwise I assume it was POS Mode
+ debug("Altitude = 1001");
+ $valid=0;
+ }
+
+ if ( $time_delta >300 ) {
+ debug( "Time diff = $time_delta");
+ $valid = 0;
+ }
+
+ if ( $speed >400 ) {
+ debug("Speed = $speed");
+ debug("But ignoring, because time accuracy =1 sec ==> speed not accurate");
+ $valid = 0;
+ }
+
+ if ( $dist > 1000 ) {
+ debug(sprintf("earth_distance($lat1,$lon1,$lat2,$lon2) => %.2f\n",$dist));
+ $valid = 0;
+ }
+
+ if ( $lat2 > 500 ||
+ $lon2 > 500
+ ) {
+ print "lat/lon >500\n";
+ $valid = 0;
+ }
+
+ if ( $valid ) {
+ if ( ! $multi_insert ) {
+ Geo::Gpsdrive::DBFuncs::track_add(
+ { lat1 => $lat1, lon1 => $lon1, alt1 => $alt1,
+ lat2 => $lat2, lon2 => $lon2, alt2 => $alt2,
+ level_min => 0, level_max => 99,
+ tracks_type_id => $tracks_type_id,
+ name => "$dist $full_filename",
+ source_id => $source_id
+ }
+ );
+ } else {
+ push(@{$segments},[$lat2,$lon2,$alt2,$time2]);
+ }
+ $segments_in_track++;
+ } else {
+ if ( $segments_in_track ) {
+ $track_nr ++;
+ print "Tracks: $track_nr ($segments_in_track Segments)\n"
+ if $debug;
+ if ( $multi_insert ) {
+ # Check for pos mode
+ my $pos_mode=1;
+ for my $segment ( @{$segments} ) {
+ if ( $segment->[2] != 0 ) {
+ $pos_mode=0; # I assume it was not POS Mode
+ last;
+ }
+ }
+
+ if ( $pos_mode ) {
+ print "pos mode\n";
+ } else {
+ tracks_add(
+ { segments => $segments,
+ level_min => 0, level_max => 99,
+ tracks_type_id => $tracks_type_id,
+ name => "$dist $full_filename",
+ source_id => $source_id
+ }
+ );
+ };
+ $segments=[];
+ }
+ }
+ $segments_in_track=0;
+ }
+ }
+}
+
+
+
+
+# *****************************************************************************
+sub import_Data(){
+
+ my $gpsdrive_dir = "$main::CONFIG_DIR/";
+ my $source = "Gpsdrive Tracks";
+
+ print "\n";
+ print "Reading and importing Gpsdrive Tracks\n";
+
+ delete_all_from_source($source);
+
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => "",
+ 'source.name' => $source ,
+ 'source.comment' => 'My own Tracks' ,
+ 'source.licence' => "It's up to myself"
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+
+
+ disable_keys('tracks');
+
+ debug("$gpsdrive_dir/{tracks}/*.sav");
+ foreach my $full_filename ( glob("$gpsdrive_dir/*.sav"),
+ glob("$gpsdrive_dir/tracks/*.sav") ) {
+ import_GpsDrive_track_file($full_filename,$source_id);
+ }
+
+ enable_keys('tracks');
+ print "Finished reading and importing Gpsdrive Tracks\n";
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/JiGLE.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/JiGLE.pm
new file mode 100644
index 0000000..6cc7814
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/JiGLE.pm
@@ -0,0 +1,154 @@
+#############################################################################
+# Einlesen der von jiggle gecacheten Daten und
+# schreiben in die WLAN Datenbank
+#
+# $Log$
+# Revision 1.2 2006/10/02 23:28:07 tweety
+# add own wlan database. This is kind of a template to eliminate the problems with the SSIDs with strange charset.
+# make all Tables UTF8
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/WLAN --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.5 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/WLAN
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.4 2005/05/10 05:28:49 tweety
+# type in disable_keys
+#
+# Revision 1.3 2005/04/10 00:15:58 tweety
+# changed primary language for wlan-type generation to english
+# added translation for WLAN-types
+# added some icons classifications to wlan-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::JiGLE;
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Basename;
+use File::Path;
+use Data::Dumper;
+
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Geo::Gpsdrive::Gps;
+
+use Date::Manip;
+use Time::Local;
+
+$|=1;
+
+
+my $LINES_COUNT_FILE =0;
+my $LINES_COUNT_UNPARSED =0;
+
+our $wlan_id;
+
+sub import_Jigle_file($$){
+ my $full_filename = shift;
+ my $source_id = shift;
+
+ print "Reading $full_filename \n";
+
+ my $fh = IO::File->new("<$full_filename");
+ my $filename = basename($full_filename);
+
+ my $wlan_id=99999999;
+
+ $LINES_COUNT_FILE =0;
+ while ( my $line = $fh->getline() ) {
+ $LINES_COUNT_FILE ++;
+
+ next if $line =~ m/trilat~trilong~ssid~netid~discoverer/;
+
+# print "line: $line\n";
+ if ( $line =~ m/^\s*$/) {
+ } elsif ( $line =~ m/^trilat/ ) {
+ } else {
+# print "$line\n";
+ # trilat~trilong~ssid~netid~discoverer~channel~type~freenet~firsttime~wep~comment~qos~lastupdt~paynet~userfound
+ # 48.035843~10.747351~ ~00:01:E3:00:DD:71~ ~0~????~N~2004-02-20 03:27:45~N~ ~0~20040404125535~N~Y
+ # 48.029793~10.51143~ ~00:02:2D:39:9A:79~ ~0~????~N~2004-02-20 03:21:39~N~ ~0~20040404125620~N~Y
+
+ # trilat ~trilong ~ssid~netid ~discoverer~channel~type~freenet~firsttime ~wep~comment~qos~lastupdt ~paynet~userfound
+ # 48.43025~10.281776~ ~00:02:2d:9c:77:66~ ~8192 ~BBS ~N ~2004-03-07 10:32:13~Y ~ ~0 ~20040511173722~N ~N
+ # 0 1 2 3 4 5 6 7 8 9 0 1 2 3
+ my @line = split(/\~/,$line);
+
+ $wlan_id++;
+ my $point;
+ $point->{'wlan.lat'} = $line[0];
+ $point->{'wlan.lon'} = $line[1];
+ $point->{'wlan.ssid'} = $line[2];
+ $point->{'wlan.bssid'} = $line[3];
+ $point->{'wlan.name'} = $point->{'wlan.ssid'}."\t".$point->{'wlan.bssid'};
+ $point->{'wlan.essid'} = $point->{'wlan.ssid'};
+ $point->{'wlan.wlan_id'} = $wlan_id;
+ $point->{'wlan.discoverer'} = $line[4];
+ $point->{'wlan.channel'} = $line[5];
+ $point->{'wlan.type'} = $line[6];
+ $point->{'wlan.nettype'} = ($line[7] eq "Y") ? 1 : 0;
+ $point->{'wlan.cloaked'} = "0";
+ $point->{'wlan.freenet'} = $line[7];
+ $point->{'wlan.last_modified'} = $line[8];
+ $point->{'wlan.wep'} = $line[7];
+ $point->{'wlan.comment'} = $point->{'wlan.bssid'};
+ $point->{'wlan.macaddr'} = $point->{'wlan.bssid'};
+ $point->{'wlan.date2'} = $line[12];
+ $point->{'wlan.proximity'} = 100;
+
+ # Kismet: bssid time-sec time-usec lat lon alt spd heading fix signal quality noise
+
+ $point->{source_id} = $source_id;
+ correct_lat_lon($point);
+ Geo::Gpsdrive::DBFuncs::add_wlan($point);
+
+ }
+
+ }
+
+}
+
+# *****************************************************************************
+sub import_Data($){
+ my $dir = shift;
+ my $jigle_dir = $dir || "~/JiGLE/WiGLEnet/data";
+ my $source = "JiGLE WLAN";
+
+
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => "",
+ 'source.name' => $source ,
+ 'source.comment' => 'JiGLE Wlan' ,
+ 'source.licence' => "JiGLE"
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+ for my $type ( qw ( closed public open pay wep wlan ) ) {
+ $wlan_id->{$type} = poi_type_name2id("w-lan.$type");
+ };
+
+ Geo::Gpsdrive::DBFuncs::disable_keys('wlan');
+
+ delete_all_from_source($source);
+
+ debug("$jigle_dir/*.autocache");
+ foreach my $full_filename ( glob("$jigle_dir/*.autocache") ) {
+ import_Jigle_file($full_filename,$source_id)
+ if ( -s $full_filename > 110 );
+ }
+ Geo::Gpsdrive::DBFuncs::enable_keys('wlan');
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/Kismet.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/Kismet.pm
new file mode 100644
index 0000000..2eacbcf
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/Kismet.pm
@@ -0,0 +1,156 @@
+# Einlesen der Kismet Daten und schreiben in die geoinfo Datenbank von
+# gpsdrive
+#
+# $Log$
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.6 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.5 2005/05/24 08:35:25 tweety
+# move track splitting to its own function +sub track_add($)
+# a little bit more error handling
+# earth_distance somtimes had complex inumbers as result
+# implemented streets_check_if_moved_reset which is called when you toggle the draw streets button
+# this way i can re-read all currently displayed streets from the DB
+# fix minor array iindex counting bugs
+# add some content to the comment column
+#
+# Revision 1.4 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.3 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::Kismet;
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Basename;
+use File::Path;
+use Data::Dumper;
+
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Geo::Gpsdrive::Gps;
+
+use Date::Manip;
+use Time::Local;
+
+$|=1;
+
+##########################################################################
+sub bad_location($$){
+ my $lat = shift;
+ my $lon = shift;
+ return 1
+ if $lat>48.17552 && $lon >11.75440
+ && $lat<48.17579 && $lon <11.75494;
+ return 0;
+}
+
+##########################################################################
+
+sub import_Kismet_track_file($$){
+ my $full_filename = shift;
+ my $source = shift;
+
+ print "Reading $full_filename \n";
+
+ my $fh = IO::File->new("<$full_filename");
+
+
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => "",
+ 'source.name' => $source ,
+ 'source.comment' => 'My own Tracks' ,
+ 'source.licence' => "It's up to myself"
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+ my $track = {
+ scale_min => 0,
+ scale_max => 10000000,
+ name => sprintf("Track %s",basename($full_filename)),
+ source_id => $source_id,
+ segments => [],
+ } ;
+
+ my $line_count=0;
+
+ while ( my $line = $fh->getline() ) {
+ $line_count++;
+ chomp $line;
+ # <gps-point bssid="GP:SD:TR:AC:KL:OG" time-sec="1081010927" time-usec="47374"
+ # lat="48.175289" lon="11.747722" alt="1672.439941" spd="33.257549"
+ # heading="267.482422" fix="3" signal="18" quality="0" noise="7"/>
+
+ next unless ( $line =~ s/^\s*<.*gps-point\s+bssid="GP:SD:TR:AC:KL:OG"\s*// );
+ unless ( $line =~ s/\/>\s*$// ) {
+ print "incomplete Line: $line\n";
+ next;
+ }
+ #print "$line\n";
+
+ my %elem;
+ ( $elem{lat},$elem{lon},$elem{alt} ) = (1001,1001,-1001);
+
+ %elem = split(/[\s=]+/,$line);
+ for my $k ( keys %elem ) {
+ $elem{$k} =~ s/^"(.*)"$/$1/;
+ }
+
+ $elem{time} = $elem{'time-sec'}+( $elem{'time-usec'}/1000000);
+
+ push (@{$track->{segments}}, {
+ lat => $elem{lat},
+ lon => $elem{lon},
+ alt => $elem{alt},
+ time => $elem{time},
+ speed => miles2km($elem{spd}),
+ heading => $elem{heading}
+ });
+
+ }
+ my $segment_count = @{$track->{segments}};
+ Geo::Gpsdrive::DBFuncs::track_add( $track );
+ print "read $line_count lines with $segment_count segments from $full_filename\n";
+}
+
+
+
+
+# *****************************************************************************
+sub import_Data($){
+ my $dir = shift;
+ my $kismet_file_pattern = $dir || "$main::CONFIG_DIR}/kismet";
+ my $source = "Kismet Tracks";
+ delete_all_from_source($source);
+
+ $kismet_file_pattern = "$kismet_file_pattern/*.gps" if -d $kismet_file_pattern;
+ $kismet_file_pattern = "$kismet_file_pattern*.gps" unless $kismet_file_pattern =~ m/\.gps$/;
+
+ my @files = glob($kismet_file_pattern);
+ printf "Importing (%d) files from $kismet_file_pattern/*.gps\n",scalar @files;
+ Geo::Gpsdrive::DBFuncs::disable_keys('streets');
+ foreach my $full_filename ( @files ) {
+ import_Kismet_track_file($full_filename,$source);
+ }
+ Geo::Gpsdrive::DBFuncs::enable_keys('streets');
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/NGA.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/NGA.pm
new file mode 100644
index 0000000..7d392eb
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/NGA.pm
@@ -0,0 +1,822 @@
+# Import Data from http://earth-info.nga.mil/
+#
+# $Log$
+# Revision 1.4 2006/08/08 08:18:51 tweety
+# nsert points too
+#
+# Revision 1.3 2006/03/10 08:37:09 tweety
+# - Replace Street/Track find algorithmus in Query Funktion
+# against real Distance Algorithm (distance_line_point).
+# - Query only reports Track/poi/Streets if currently displaying
+# on map is selected for these
+# - replace old top/map Selection by a MapServer based selection
+# - Draw White map if no Mapserver is selected
+# - Remove some useless Street Data from Examples
+# - Take the real colors defined in Database to draw Streets
+# - Add a frame to the Streets to make them look nicer
+# - Added Highlight Option for Tracks/Streets to see which streets are
+# displayed for a Query output
+# - displaymap_top und displaymap_map removed and replaced by a
+# Mapserver centric approach.
+# - Treaked a little bit with Font Sizes
+# - Added a very simple clipping to the lat of the draw_grid
+# Either the draw_drid or the projection routines still have a slight
+# problem if acting on negative values
+# - draw_grid with XOR: This way you can see it much better.
+# - move the default map dir to ~/.gpsdrive/maps
+# - new enum map_projections to be able to easily add more projections
+# later
+# - remove history from gpsmisc.c
+# - try to reduce compiler warnings
+# - search maps also in ./data/maps/ for debugging purpose
+# - cleanup and expand unit_test.c a little bit
+# - add some more rules to the Makefiles so more files get into the
+# tar.gz
+# - DB_Examples.pm test also for ../data and data directory to
+# read files from
+# - geoinfo.pl: limit visibility of Simple POI data to a zoom level of 1-20000
+# - geoinfo.pl NGA.pm: Output Bounding Box for read Data
+# - gpsfetchmap.pl:
+# - adapt zoom levels for landsat maps
+# - correct eniro File Download. Not working yet, but gets closer
+# - add/correct some of the Help Text
+# - Update makefiles with a more recent automake Version
+# - update po files
+#
+# Revision 1.2 2005/10/11 08:28:35 tweety
+# gpsdrive:
+# - add Tracks(MySql) displaying
+# - reindent files modified
+# - Fix setting of Color for Grid
+# - poi Text is different in size depending on Number of POIs shown on
+# screen
+#
+# geoinfo:
+# - get Proxy settings from Environment
+# - create tracks Table in Database and fill it
+# this separates Street Data from Track Data
+# - make geoinfo.pl download also Opengeodb Version 2
+# - add some poi-types
+# - Split off Filling DB with example Data
+# - extract some more Funtionality to Procedures
+# - Add some Example POI for Kirchheim(Munich) Area
+# - Adjust some Output for what is done at the moment
+# - Add more delayed index generations 'disable/enable key'
+# - If LANG=*de_DE* then only impert europe with --all option
+# - WDB will import more than one country if you wish
+# - add more things to be done with the --all option
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.10 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.9 2005/05/14 21:21:23 tweety
+# Update Index createion
+# Update default Streets
+# Eliminate some undefined Value
+#
+# Revision 1.8 2005/05/01 13:49:36 tweety
+# Added more Icons
+# Moved filling with defaults to DB_Defaults.pm
+# Added some more default POI Types
+# Added icons.html to see which icons are used
+# Added more Comments
+# Reformating Makefiles
+# Added new options for importing from way*.txt and adding defaults
+# Added more source_id and type_id
+#
+# Revision 1.7 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.6 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::NGA;
+
+sub min($$){
+ my $a=shift;
+ my $b=shift;
+ return $a<$b?$a:$b;
+}
+sub max($$){
+ my $a=shift;
+ my $b=shift;
+ return $a>$b?$a:$b;
+}
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Path;
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Data::Dumper;
+
+
+our $write_defaults_poi_list;
+
+#############################################################################
+our @countries = qw(aa ac ae af ag aj al am an ao ar as at au av
+ ba bb bc bd be bf bg bh bk bl bm bn bo bp br bs bt bu bv bx by
+ ca cb cd ce cf cg ch ci cj ck cm cn co cr cs ct cu cv cw cy
+ da dj do dr ec eg ei ek en er es et eu ez
+ fg fi fj fk fm fo fp fr fs
+ ga gb gg gh gi gj gk gl gm go gp gr gt gv gy gz
+ ha hk hm ho hr hu
+ ic id im in io ip ir is it iv iz
+ ja je jm jn jo ju ke kg kn kr ks kt ku kz
+ la le lg lh li lo ls lt lu ly
+ ma mb mc md mf mg mh mi mk ml mn mo mp mr mt mu mv mx my mz
+ nc ne nf ng nh ni nl nm no np nr ns nt nu nz
+ os
+ pa pc pe pf pg pk pl pm po pp ps pu
+ qa re rm ro
+ rp rs rw
+ sa sb sc se sf sg sh si sl sm sn so sp st su sv sw sx sy sz
+ td te th ti tk tl tn to tp ts tt tu tv tw tx tz
+ uf ug uk up uv uy uz
+ vc ve vi vm vt
+ wa we wf wi ws wz
+ yi ym
+ za zi);
+
+our $name2country = {
+ 'afghanistan' => 'af',
+ 'albania' => 'al',
+ 'algeria' => 'ag',
+ 'andorra' => 'an',
+ 'angola' => 'ao',
+ 'anguilla' => 'av',
+ 'antigua and barbuda' => 'ac',
+ 'argentina' => 'ar',
+ 'armenia' => 'am',
+ 'aruba' => 'aa',
+ 'ashmore and cartier islands' => 'at',
+ 'australia' => 'as',
+ 'austria' => 'au',
+ 'azerbaijan' => 'aj',
+ 'bahamas, the' => 'bf',
+ 'bahrain' => 'ba',
+ 'bangladesh' => 'bg',
+ 'barbados' => 'bb',
+ 'bassas da india' => 'bs',
+ 'belarus' => 'bo',
+ 'belgium' => 'be',
+ 'belize' => 'bh',
+ 'benin' => 'bn',
+ 'bermuda' => 'bd',
+ 'bhutan' => 'bt',
+ 'bolivia' => 'bl',
+ 'bosnia and herzegovina' => 'bk',
+ 'botswana' => 'bc',
+ 'bouvet island' => 'bv',
+ 'brazil' => 'br',
+ 'british indian ocean territory' => 'io',
+ 'british virgin islands' => 'vi',
+ 'brunei' => 'bx',
+ 'bulgaria' => 'bu',
+ 'burkina faso' => 'uv',
+ 'burma' => 'bm',
+ 'burundi' => 'by',
+ 'cambodia' => 'cb',
+ 'cameroon' => 'cm',
+ 'canada' => 'ca',
+ 'cape verde' => 'cv',
+ 'cayman islands' => 'cj',
+ 'central african republic' => 'ct',
+ 'chad' => 'cd',
+ 'chile' => 'ci',
+ 'china' => 'ch',
+ 'christmas island' => 'kt',
+ 'clipperton island' => 'ip',
+ 'cocos (keeling) islands' => 'ck',
+ 'colombia' => 'co',
+ 'comoros' => 'cn',
+ 'congo' => 'cf',
+ 'congo, democratic republic of the' => 'cg',
+ 'cook islands' => 'cw',
+ 'coral sea islands' => 'cr',
+ 'costa rica' => 'cs',
+ 'croatia' => 'hr',
+ 'cuba' => 'cu',
+ 'cyprus' => 'cy',
+ 'czech republic' => 'ez',
+ 'cote d\'ivoire' => 'iv',
+ 'denmark' => 'da',
+ 'djibouti' => 'dj',
+ 'dominica' => 'do',
+ 'dominican republic' => 'dr',
+ 'east timor' => 'tt',
+ 'ecuador' => 'ec',
+ 'egypt' => 'eg',
+ 'el salvador' => 'es',
+ 'equatorial guinea' => 'ek',
+ 'eritrea' => 'er',
+ 'estonia' => 'en',
+ 'ethiopia' => 'et',
+ 'europa island' => 'eu',
+ 'falkland islands (islas malvinas)' => 'fk',
+ 'faroe islands' => 'fo',
+ 'fiji' => 'fj',
+ 'finland' => 'fi',
+ 'france' => 'fr',
+ 'french guiana' => 'fg',
+ 'french polynesia' => 'fp',
+ 'french southern and antarctic lands' => 'fs',
+ 'gabon' => 'gb',
+ 'gambia, the' => 'ga',
+ 'gaza strip' => 'gz',
+ 'georgia' => 'gg',
+ 'germany' => 'gm',
+ 'ghana' => 'gh',
+ 'gibraltar' => 'gi',
+ 'glorioso islands' => 'go',
+ 'greece' => 'gr',
+ 'greenland' => 'gl',
+ 'grenada' => 'gj',
+ 'guadeloupe' => 'gp',
+ 'guatemala' => 'gt',
+ 'guernsey' => 'gk',
+ 'guinea' => 'gv',
+ 'guinea-bissau' => 'pu',
+ 'guyana' => 'gy',
+ 'haiti' => 'ha',
+ 'heard island and mcdonald islands' => 'hm',
+ 'honduras' => 'ho',
+ 'hong kong' => 'hk',
+ 'hungary' => 'hu',
+ 'iceland' => 'ic',
+ 'india' => 'in',
+ 'indonesia' => 'id',
+ 'iran' => 'ir',
+ 'iraq' => 'iz',
+ 'ireland' => 'ei',
+ 'isle of man' => 'im',
+ 'israel' => 'is',
+ 'italy' => 'it',
+ 'jamaica' => 'jm',
+ 'jan mayen' => 'jn',
+ 'japan' => 'ja',
+ 'jersey' => 'je',
+ 'jordan' => 'jo',
+ 'juan de nova island' => 'ju',
+ 'kazakhstan' => 'kz',
+ 'kenya' => 'ke',
+ 'kiribati' => 'kr',
+ 'kuwait' => 'ku',
+ 'kyrgyzstan' => 'kg',
+ 'laos' => 'la',
+ 'latvia' => 'lg',
+ 'lebanon' => 'le',
+ 'lesotho' => 'lt',
+ 'liberia' => 'li',
+ 'libya' => 'ly',
+ 'liechtenstein' => 'ls',
+ 'lithuania' => 'lh',
+ 'luxembourg' => 'lu',
+ 'macau' => 'mc',
+ 'macedonia, the former yugoslav republic of' => 'mk',
+ 'madagascar' => 'ma',
+ 'malawi' => 'mi',
+ 'malaysia' => 'my',
+ 'maldives' => 'mv',
+ 'mali' => 'ml',
+ 'malta' => 'mt',
+ 'marshall islands' => 'rm',
+ 'martinique' => 'mb',
+ 'mauritania' => 'mr',
+ 'mauritius' => 'mp',
+ 'mayotte' => 'mf',
+ 'mexico' => 'mx',
+ 'micronesia, federated states of' => 'fm',
+ 'moldova' => 'md',
+ 'monaco' => 'mn',
+ 'mongolia' => 'mg',
+ 'montserrat' => 'mh',
+ 'morocco' => 'mo',
+ 'mozambique' => 'mz',
+ 'namibia' => 'wa',
+ 'nauru' => 'nr',
+ 'nepal' => 'np',
+ 'netherlands antilles' => 'nt',
+ 'netherlands' => 'nl',
+ 'new caledonia' => 'nc',
+ 'new zealand' => 'nz',
+ 'nicaragua' => 'nu',
+ 'niger' => 'ng',
+ 'nigeria' => 'ni',
+ 'niue' => 'ne',
+ 'no man\'s land' => 'nm',
+ 'norfolk island' => 'nf',
+ 'north korea' => 'kn',
+ 'norway' => 'no',
+ 'oceans' => 'os',
+ 'oman' => 'mu',
+ 'pakistan' => 'pk',
+ 'palau' => 'ps',
+ 'panama' => 'pm',
+ 'papua new guinea' => 'pp',
+ 'paracel islands' => 'pf',
+ 'paraguay' => 'pa',
+ 'peru' => 'pe',
+ 'philippines' => 'rp',
+ 'pitcairn islands' => 'pc',
+ 'poland' => 'pl',
+ 'portugal' => 'po',
+ 'qatar' => 'qa',
+ 'reunion' => 're',
+ 'romania' => 'ro',
+ 'russia' => 'rs',
+ 'rwanda' => 'rw',
+ 'saint helena' => 'sh',
+ 'saint kitts and nevis' => 'sc',
+ 'saint lucia' => 'st',
+ 'saint pierre and miquelon' => 'sb',
+ 'saint vincent and the grenadines' => 'vc',
+ 'samoa' => 'ws',
+ 'san marino' => 'sm',
+ 'sao tome and principe' => 'tp',
+ 'saudi arabia' => 'sa',
+ 'senegal' => 'sg',
+ 'serbia and montenegro' => 'yi',
+ 'seychelles' => 'se',
+ 'sierra leone' => 'sl',
+ 'singapore' => 'sn',
+ 'slovakia' => 'lo',
+ 'slovenia' => 'si',
+ 'solomon islands' => 'bp',
+ 'somalia' => 'so',
+ 'south africa' => 'sf',
+ 'south georgia and the south sandwich islands' => 'sx',
+ 'south korea' => 'ks',
+ 'spain' => 'sp',
+ 'spratly islands' => 'pg',
+ 'sri lanka' => 'ce',
+ 'sudan' => 'su',
+ 'suriname' => 'ns',
+ 'svalbard' => 'sv',
+ 'swaziland' => 'wz',
+ 'sweden' => 'sw',
+ 'switzerland' => 'sz',
+ 'syria' => 'sy',
+ 'taiwan' => 'tw',
+ 'tajikistan' => 'ti',
+ 'tanzania' => 'tz',
+ 'thailand' => 'th',
+ 'togo' => 'to',
+ 'tokelau' => 'tl',
+ 'tonga' => 'tn',
+ 'trinidad and tobago' => 'td',
+ 'tromelin island' => 'te',
+ 'tunisia' => 'ts',
+ 'turkey' => 'tu',
+ 'turkmenistan' => 'tx',
+ 'turks and caicos islands' => 'tk',
+ 'tuvalu' => 'tv',
+ 'uganda' => 'ug',
+ 'ukraine' => 'up',
+ 'undersea features' => 'uf',
+ 'united arab emirates' => 'ae',
+ 'united kingdom' => 'uk',
+ 'uruguay' => 'uy',
+ 'uzbekistan' => 'uz',
+ 'vanuatu' => 'nh',
+ 'vatican city' => 'vt',
+ 'venezuela' => 've',
+ 'vietnam' => 'vm',
+ 'wallis and futuna' => 'wf',
+ 'west bank' => 'we',
+ 'western sahara' => 'wi',
+ 'yemen' => 'ym',
+ 'zambia ' => 'za',
+ 'zimbabwe' => 'zi',
+};
+
+my $country2name={};
+for my $name ( keys %{$name2country} ) {
+ $country2name->{$name2country->{$name}}=$name;
+}
+
+
+
+#############################################################################
+# Args:
+# $filename : Filename to read
+# returns:
+# $waypoints : Hash of read Waypoints
+#############################################################################
+sub add_earthinfo_nga_mil_to_db($$){
+ my $full_filename = shift;
+ my $source = shift;
+
+ my ($country) = ($full_filename =~ m,/([^/]+).txt,);
+
+ print "Reading earthinfo_nga_mil ($full_filename) [$country2name->{$country}] and writing to db\n";
+
+ my $lat_min= 1000;
+ my $lat_max=-1000;
+ my $lon_min= 1000;
+ my $lon_max=-1000;
+
+ my $fh = IO::File->new("<$full_filename");
+ $fh or die ("add_earthinfo_nga_mil_to_db: Cannot open $full_filename:$!\n");
+
+ Geo::Gpsdrive::DBFuncs::delete_all_from_source($source);
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => "http://earth-info.nga.mil/gns/html/",
+ 'source.name' => $source ,
+ 'source.comment' => '' ,
+ 'source.licence' => "Licensing GNS Data".
+ "There are no licensing requirements or restrictions ".
+ "in place for the use of ".
+ "the GNS data.\n".
+ "\n".
+ "Toponymic information is based on the Geographic Names Data Base, ".
+ "containing official standard names approved by the ".
+ "United States Board on Geographic Names and maintained ".
+ "by the National Geospatial-Intelligence Agency. ".
+ "More information is available at the Products and Services ".
+ "link at www.nga.mil. The National Geospatial-Intelligence ".
+ "Agency name, initials, and seal are protected by ".
+ "10 United States Code Section xxx445."
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+
+ my @columns;
+ @columns = qw( rc ufi uni
+ poi.lat poi.lon
+ dms_lat dms_long
+ utm jog fc
+ dsg pc cc1
+ adm1 adm2
+ dim
+ cc2 nt lc
+ short_form
+ generic
+ sort_name full_name full_name_nd
+ mod_date
+ );
+ my $lines_count_file =0;
+ my $line = $fh->getline(); # Header entfernen
+ my $count_entries = {}; # Count the entries for special types
+ while ( $line = $fh->getline() ) {
+ $lines_count_file ++;
+ print "$lines_count_file\r" if $verbose && ! ($lines_count_file % 100);
+ $line =~ s/[\t\r\n\s]*$//g;
+# print "line: '$line'\n";
+ if ( $line =~ m/^$/ ) {
+ } elsif ( $line =~ m/^\#/ ) {
+ } else {
+ die "Spalten nicht definiert" unless @columns;
+# print "-----------------------------------------------------------------\n";
+# print "WP: $line\n";
+ my @values = split(/\t/,$line);
+# print Dumper(\@values);
+ my $values;
+ for my $i ( 0 .. scalar @columns -1 ) {
+# next unless $columns[$i] =~ m/\./;
+ $values->{$columns[$i]} = ($values[$i]||'');
+# print $columns[$i].": \t".($values[$i]||'-')."\n" if $debug;
+ }
+
+
+ $values->{'poi.source_id'}=$source_id;
+ #$values->{'source.name'} = $source;
+# print Dumper(\$values);
+
+ # A specific part of the name that could substitute for the full name.
+ $values->{'poi.name'}=$values->{'short_form'}||$values->{'full_name'};
+
+ print "Name longer than 80 chars: $values->{'poi.name'} \n"
+ if length($values->{'poi.name'}) > 80 ;
+
+ $values->{'poi.comment'}=$values->{'generic'};
+ # GENERIC
+ # The descriptive part of the full name (does not apply to populated
+ # place names).
+
+
+ # SORT_NAME
+ # A form of the full name which allows for easy sorting of the name
+ # into alpha-numeric sequence. It is comprised of the specific name,
+ # generic name, and any articles or prepositions.
+ # This field is all upper case with spaces, diacritics, and hyphens
+ # removed and numbers are substituted with lower case alphabetic characters.
+
+ # FULL_NAME
+ # The full name is a complete name which identifies the named feature.
+ # It is comprised of the specific name, generic name, and any articles
+ # or prepositions (refer to REGIONS.PDF for character mapping).
+ if ( $values->{'full_name'} eq $values->{'poi.name'} ) {
+ $values->{'poi.comment'}='';
+ } else {
+ $values->{'poi.comment'}=$values->{'full_name'};
+ }
+
+ # FULL_NAME_ND
+ # Same as the full name but the diacritics and special characters are
+ # substituted with Roman characters (refer to REGIONS.PDF for character
+ # mapping). ND = No Diacritics / Stripped Diacritics.
+
+
+ $values->{'poi.last_modified'}=$values->{'mod_date'};
+
+ {
+ my $pc = $values->{'pc'};
+ # Populated Place Classification.
+ # A graduated numerical scale denoting the relative importance
+ # of a populated place.
+ # The scale ranges from 1, relatively high, to 5, relatively low.
+ # The scale could also include NULL (no value) as a value for
+ # populated places with unknown or undetermined classification.
+ my $scale_min = 0;
+ my $scale_max = 99;
+ if ( defined($pc) && $pc ne '' ) {
+ #print "pc : $pc \n";
+ if ( $pc == 1 ) { $scale_min = 1; $scale_max = 100000000; }
+ elsif ( $pc == 2 ) { $scale_min = 1; $scale_max = 10000000; }
+ elsif ( $pc == 3 ) { $scale_min = 1; $scale_max = 1000000; }
+ elsif ( $pc == 4 ) { $scale_min = 1; $scale_max = 100000; }
+ elsif ( $pc == 5 ) { $scale_min = 1; $scale_max = 10000; }
+ } else {
+ $scale_min = 1; $scale_max = 10000;
+ };
+ $values->{'poi.scale_min'} = $scale_min;
+ $values->{'poi.scale_max'} = $scale_max;
+ }
+
+
+
+ { # NT Name Type:
+ # C = Conventional;
+ # D = Not verified;
+ # N = Native;
+ # V = Variant or alternate.
+ my $nt = $values->{'nt'};
+ }
+
+ { # decide which symbol
+ my $fc = $values->{'fc'};
+ my $symbol = "City";
+ #FC
+ #Feature Classification:
+ if ( $fc eq "A" ) { $symbol = "Administrative region" }
+ elsif ( $fc eq "P" ) { $symbol = "Populated place" }
+ elsif ( $fc eq "V" ) { $symbol = "Vegetation" }
+ elsif ( $fc eq "L" ) { $symbol = "Locality or area" }
+ elsif ( $fc eq "U" ) { $symbol = "Undersea" }
+ elsif ( $fc eq "R" ) { $symbol = "Streets, highways, roads, or railroad" }
+ elsif ( $fc eq "T" ) { $symbol = "Hypsographic" }
+ elsif ( $fc eq "H" ) { $symbol = "Hydrographic" }
+ elsif ( $fc eq "S" ) { $symbol = "Spot feature." }
+ else { $symbol = "Unknown" }
+ $values->{'type.name'} = $symbol;
+ }
+
+ { # DIM Dimension.
+ # Usually used to display elevation or population data.
+ # +-10 Digits
+ my $proximity = $values->{'dim'} ;
+ $proximity ||= 1 if $values->{'fc'} eq 'R'; # Roads
+ $proximity ||= 800 if $values->{'fc'} eq 'P'; # Populated Place
+ $proximity ||= ' 100m';
+ $values->{'poi.proximity'} = $proximity;
+ }
+
+ # RC Region Code.
+ # A code that determines the character mapping used in the Full_Name
+ # field (refer to REGIONS.PDF for character mapping):
+ # 1 = Western Europe/Americas;
+ # 2 = Eastern Europe;
+ # 3 = Africa/Middle East;
+ # 4 = Central Asia;
+ # 5 = Asia/Pacific;
+ # 6 = Vietnam.
+
+ # UFI
+ # Unique Feature Identifier. A number which uniquely identifies the feature.
+ # number +- 10 Digits
+
+ # UNI
+ # Unique Name Identifier. A number which uniquely identifies a name.
+ # number +- 10 Digits
+
+
+ # LAT Latitude of the feature in +- decimal degrees (WGS84): +- 2.7 Digits
+ # LONG Longitude of the feature in +- decimal degrees (WGS84): +- 3.7 Digits
+ # DMS_LAT Latitude of the feature in +- degrees, minutes, and seconds (WGS84): +- 6 Digits
+ # DMS_LONG Longitude of the feature in +- degrees, minutes, and seconds (WGS84): +- 7 Digits
+ # UTM Universal Transverse Mercator coordinate grid reference. 4 Characters
+ # JOG Joint Operations Graphic reference. 7 Characters
+
+
+ # DSG Feature Designation Code.
+ # A two to five-character code used to identify the type of feature a name is applied to.
+
+ # PC Populated Place Classification.
+ # A graduated numerical scale denoting the relative importance of a populated place.
+ # The scale ranges from 1, relatively high, to 5, relatively low. The scale could also
+ # include NULL (no value) as a value for populated places with unknown or undetermined classification.
+
+ # CC1 Primary Country Code.
+ # A two alphabetic character code uniquely identifying a
+ # geopolitical entity (countries, dependencies,
+ # and areas of special sovereignty).
+
+ # ADM1 First-order administrative division.
+ # A two alphanumeric character code uniquely identifying a
+ # primary administrative division of a country,
+ # such as a state in the United States.
+
+ # ADM2 Second-order administrative division.
+ # The name of a subdivision of a first-order administrative division,
+ # such as a county in the United States.
+ # 200 Characters
+
+
+ # CC2 Secondary Country Code.
+ # A two alphabetic character code uniquely identifying the
+ # country code of a particular name if different than that of the feature.
+
+ # LC Language Code.
+ # A two alphabetic character code uniquely identifying a
+ # language of a country if multiple official languages are used.
+ # 2 Characters
+
+ # SHORT_FORM
+ # A specific part of the name that could substitute for the full name.
+ # 128 Characters
+
+ # GENERIC
+ # The descriptive part of the full name (does not apply to populated place names).
+ # 128 Characters
+
+ # SORT_NAME
+ # A form of the full name which allows for easy sorting of the name
+ # into alpha-numeric sequence. It is comprised of the specific name,
+ # generic name, and any articles or prepositions. This field is all
+ # upper case with spaces, diacritics, and hyphens removed and numbers
+ # are substituted with lower case alphabetic characters.
+ # 200 Characters
+
+ # FULL_NAME
+ # The full name is a complete name which identifies the named feature.
+ # It is comprised of the specific name, generic name, and any articles
+ # or prepositions (refer to REGIONS.PDF for character mapping).
+ # 200 Characters
+
+ # FULL_NAME_ND
+ # Same as the full name but the diacritics and special characters are
+ # substituted with Roman characters (refer to REGIONS.PDF for character mapping).
+ # ND = No Diacritics / Stripped Diacritics.
+ # 200 Characters
+
+ # MOD_DATE
+ # The date a new feature was added or any part of an existing feature was modified (YYYY-MM-DD).
+
+
+ my $lat = $values->{'poi.lat'};
+ my $lon = $values->{'poi.lon'};
+ #print substr($line,10,30)."\n" if ( $lon < 10 );
+ $lat_min= min($lat_min,$lat);
+ $lat_max= max($lat_max,$lat);
+ $lon_min= min($lon_min,$lon);
+ $lon_max= max($lon_max,$lon);
+
+# printf "lat,lon %.2f,%.2f (%.2f,%.2f) - (%.2f,%.2f)\n",$lat,$lon,$lat_min,$lon_min,$lat_max,$lon_max if $verbose;
+
+ if ($main::do_collect_init_data ) { # Collect Major Cities
+ for my $type ( qw(pc) ) {
+ $count_entries->{$type}->{$values->{$type}}++;
+ }
+
+ #$count_entries->{dim}->{x} if defined($values->{dim}) && ( $values->{dim} > 0);
+
+ if ( $values->{pc} eq "1" && $write_defaults_poi_list ) {
+ my $name = $values->{'poi.name'};
+ $name =~ s/'/\\'/g; # '
+ $name =~ s/`/\\`/g; # `
+ print $write_defaults_poi_list ' ';
+ print $write_defaults_poi_list "{ name => '$name',";
+ print $write_defaults_poi_list ' lat => '.$values->{'poi.lat'}.",";
+ print $write_defaults_poi_list ' lon => '.$values->{'poi.lon'}." },\n";
+ print "Name:".$values->{'poi.name'}."\n";
+ print "DIM:".$values->{dim}."\n" if $values->{dim};
+# print "ADM1:".$values->{adm1}."\n";
+# print "ADM2:".$values->{adm2}."\n";
+# print "FC:".$values->{fc}."\n";
+# print join("",map{"\t$_ \t=> ".$values->{$_}."\n" } keys %$values);
+ add_poi($values);
+ }
+ }
+
+# DEBUG
+ add_poi($values);
+ }
+ }
+ print "$lines_count_file read\n" if $verbose;
+ print "lat($lat_min , $lat_max) lon($lon_min , $lon_max)\n" if $verbose;
+ if ( $debug && $verbose ) {
+ for my $type ( keys %{$count_entries} ) {
+ for my $sub_type ( keys %{$count_entries->{$type}} ) {
+ print " $type=$sub_type: ".$count_entries->{$type}->{$sub_type}."\n";
+ }
+ }
+ }
+}
+
+# *****************************************************************************
+sub import_Data($){
+ my $what = shift;
+
+ my $earthinfo_dir="$main::CONFIG_DIR/MIRROR/earthinfo";
+
+ print "\nDownload an import NGA Data\n";
+
+ # If the File exist it will be filled with the Major cities
+ # So just touch it and it will be filled
+ if ($main::do_collect_init_data ) { # Collect Major Cities
+ if ( -d "../data/" ) {
+ $write_defaults_poi_list = IO::File->new(">../data/Default_poi.txt");
+ } else {
+ print "Warning: ../data not a directory; writing no default poi list\n";
+ };
+ }
+
+ unless ( -d $earthinfo_dir ) {
+ print "Creating Directory $earthinfo_dir\n";
+ mkpath $earthinfo_dir
+ or die "Cannot create Directory $earthinfo_dir:$!\n";
+ }
+
+ my @do_countries;
+ my $country;
+ if ($what eq "??" ) {
+ print "Available counties:\n\n ";
+ print join("\n ",map { "$_ ($name2country->{$_})" } sort keys %{$name2country} );
+ print "\n";
+ print "\n";
+ print "See http://earth-info.nga.mil/gns/html/cntry_files.html for more Information\n";
+ print "\n";
+ } elsif ( $what =~ m/^\D/ ) {
+ for $country ( split(",",$what) ) {
+ if ( $name2country->{$country} ) {
+ push ( @do_countries , $name2country->{$country} );
+ } else {
+ if ( grep { $_ eq $country } @countries ) {
+ push ( @do_countries , $country );
+ } else {
+ print "Country $country not valid\n";
+ print "List of valid countries:\n";
+ print join(",",@countries);
+ print "\n";
+ print "Use:\n";
+ print "poi.pl -earthinfo_nga_mil=??\n";
+ print "For detailed list\n;"
+
+ }
+ }
+ }
+ } else {
+ @do_countries = @countries;
+ }
+
+ for $country ( @do_countries ) {
+ # download
+ # http://earth-info.nga.mil/gns/html/cntyfile/gm.zip # Germany
+ my $url="http://earth-info.nga.mil/gns/html/cntyfile/$country.zip";
+ print "Mirror $url\n";
+ my $mirror = mirror_file($url ,"$earthinfo_dir/geonames_$country.zip");
+
+ # print "Mirror: $mirror\n";
+ if ( (!-s "$earthinfo_dir/$country.txt") ||
+ file_newer("$earthinfo_dir/geonames_$country.zip",
+ "$earthinfo_dir/$country.txt") ) {
+ print "Unpacking geonames_$country.zip\n";
+ `(cd $earthinfo_dir/; unzip -o geonames_$country.zip)`;
+ } else {
+ print "unpack: $country.txt up to date\n" unless $verbose;
+ }
+
+ add_earthinfo_nga_mil_to_db("$earthinfo_dir/$country.txt","earth-info.nga.mil $country");
+ }
+
+ print "Download an import NGA Data FINISHED\n";
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/OSM.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/OSM.pm
new file mode 100644
index 0000000..1a47b68
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/OSM.pm
@@ -0,0 +1,621 @@
+# Import Data from http://openstreetmap.org/
+
+use strict;
+use warnings;
+
+use Storable ();
+
+package Geo::Gpsdrive::OSM;
+use strict;
+use warnings;
+
+use IO::File;
+use File::Path;
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Geo::OSM::Planet;
+use Data::Dumper;
+use XML::Parser;
+use XML::Simple;
+use Geo::Filter::Area;
+use Geo::OSM::Planet;
+use Utils::Debug;
+use Utils::File;
+use Utils::LWP::Utils;
+use Utils::Math;
+
+our $OSM_polite = 10; # Wait n times as long as the request lasted
+our $AREA_FILTER;
+our $PARSING_START_TIME=0;
+our $PARSING_DISPLAY_TIME=0;
+our $ICON_RULES;
+our $ELEMSTYLES;
+our $ELEMSTYLES_RULES;
+
+my $SOURCE_OSM = "OpenStreetMap.org";
+my $SOURCE_ID_OSM=0;
+
+our (%MainAttr,%Tags);
+# Stored data
+our %Stats;
+my $all_unknown_tags={};
+
+# Estimated Number of elements to show progress while reading in percent
+for my $type ( qw( tag node segment way )) {
+ $Stats{"${type}s estim"} = estimated_max_count($type);
+}
+$Stats{"tags"} = 0;
+$Stats{"nodes"} = 0;
+$Stats{"segments"} = 0;
+$Stats{"ways"} = 0;
+
+my $IGNORE_TAG={
+ '' => 1,
+ 'access' => 1,
+ 'angle' => 1,
+ 'maxweight' => 1,
+ 'bicycle' => 1,
+ 'bike' => 1,
+ 'bridge' => 1,
+ 'bridge' => 1,
+ 'car' => 1,
+ 'city' => 1,
+ 'converted_by' => 1,
+ 'course' => 1,
+ 'created_by' => 1,
+ 'creator' => 1,
+ 'difficulty' => 1,
+ 'direction' => 1,
+ 'editor' => 1,
+ 'ele' => 1,
+ 'elevated' => 1,
+ 'elevation' => 1,
+ 'fix' => 1,
+ 'foot' => 1,
+ 'from' => 1,
+ 'hdop' => 1,
+ 'horse' => 1,
+ 'id' => 1,
+ 'int_ref' => 1,
+ 'is_in' => 1,
+ 'junction' => 1,
+ 'lanes' => 1,
+ 'lat' => 1,
+ 'layer' => 1,
+ 'level' => 1,
+ 'ski' => 1,
+ 'country' => 1,
+ 'lane' => 1,
+ 'loc_ref' => 1,
+ 'lon' => 1,
+ 'mapping_status' => 1,
+ 'max_speed' => 1,
+ 'maxspeed' => 1,
+ 'min_speed' => 1,
+ 'motorbike' => 1,
+ 'motorcar' => 1,
+ 'motorcycle' => 1,
+ 'name' => 1,
+ 'nat_ref' => 1,
+ 'FACC_CODE' => 1,
+ 'note' => 1,
+ 'one_way' => 1,
+ 'oneway' => 1,
+ 'osm_obj_type' => 1,
+ 'pdop' => 1,
+ 'postal_code' => 1,
+ 'rail' => 1,
+ 'ref' => 1,
+ 'sat' => 1,
+ 'source' => 1,
+ 'speed' => 1,
+ 'speedlimit' => 1,
+ 'time' => 1,
+ 'timestamp' => 1,
+ 'to' => 1,
+ 'tracktype' => 1,
+ 'tunnel' => 1,
+ 'upload_tag' => 1,
+ 'vdop' => 1,
+ 'width' => 1,
+ 'surface' => 1,
+};
+# --------------------------------------------
+sub display_status($){
+ my $mode = shift;
+ return unless $VERBOSE || $DEBUG ;
+ return unless time()-$PARSING_DISPLAY_TIME >2;
+
+ $PARSING_DISPLAY_TIME= time();
+ print STDERR "\r";
+ #print STDERR "$mode(".$AREA_FILTER->name()."): ";
+ print STDERR " ". $Stats{"elem read"}. "elem " if $DEBUG>2;
+
+ print STDERR time_estimate($PARSING_START_TIME,
+ $Stats{"elem read"},
+ estimated_max_count("elem"));
+
+ print STDERR mem_usage();
+ print STDERR "\r";
+
+}
+
+#----------------------------------------------
+# Statistics output
+sub output_statistic($){
+ my $filename = shift;
+ print STDERR "Statistics output $filename\n" if $DEBUG;
+ if(! open(STATS,">$filename")) {
+ warn "output_osm: Cannot write to $filename\n";
+ return;
+ }
+ binmode(STATS,":utf8");
+
+ printf STATS "\n\nStats:\n";
+ for my $k ( keys(%Stats) ){
+ printf STATS "* %5d %s\n", $Stats{$k}, ($k||'');
+ }
+
+}
+
+#----------------------------------------------
+sub print_obj($){
+ my $obj = shift;
+ my $tags_string="";
+ for my $k ( sort keys %{$obj} ){
+ next if $k =~ m/^(timestamp|id|osm_obj_type|created_by|name)$/;
+ $tags_string .= "$k = $obj->{$k}, ";
+ }
+ warn " $obj->{id} $obj->{osm_obj_type}\t$tags_string\n"
+ if $tags_string;
+};
+
+
+#----------------------------------------------
+# Function is called whenever an XML tag is started
+sub DoStart()
+{
+ my ($expat, $name, %attr) = @_;
+
+ if($name eq "node"){
+ undef %Tags;
+ %MainAttr = %attr;
+ }
+ if($name eq "tag"){
+ # TODO: protect against id,from,to,lat,long,etc. being used as tags
+ $Tags{$attr{"k"}} = $attr{"v"};
+ $Stats{"tags"}++;
+ }
+}
+
+# Function is called whenever an XML tag is ended
+#----------------------------------------------
+sub DoEnd(){
+ my ($expat, $element) = @_;
+ my $id = $MainAttr{"id"};
+ $Stats{"${element}s read"}++;
+ $Stats{"tags read"}++;
+ if ( defined( $Stats{"${element}s read"} )
+ &&( $Stats{"${element}s read"}== 1 ) ){
+ $Stats{"memory at 1st $element rss"} = sprintf("%.0f",mem_usage('rss'));
+ $Stats{"memory at 1st $element vsz"} = sprintf("%.0f",mem_usage('vsz'));
+ if ( $DEBUG >1 || $VERBOSE >1) {
+ print STDERR "\n";
+ }
+ }
+
+ if($element eq "node"){
+ my $node={ osm_obj_type => 'node' };
+ $node->{"lat"} = $MainAttr{"lat"};
+ $node->{"lon"} = $MainAttr{"lon"};
+
+ if ( $AREA_FILTER->inside($node) ) {
+ foreach(keys(%Tags)){
+ $node->{$_} = $Tags{$_};
+ }
+ write_named_point($node);
+ $Stats{"nodes"}++;
+ }
+ }
+
+ if ( ( $VERBOSE || $DEBUG ) &&
+# ! ( $Stats{"tags read"} % 10000 ) &&
+ ( time()-$PARSING_DISPLAY_TIME >0.9)
+
+ ) {
+ $PARSING_DISPLAY_TIME= time();
+ print STDERR "\r";
+ print STDERR "Read(".$AREA_FILTER->name()."): ";
+ for my $k ( qw(tags nodes segments ways ) ) {
+ next if $k =~ m/( estim| read| rss| vsz)$/;
+ if ( $DEBUG>6 || $VERBOSE>6) {
+ print STDERR $k;
+ } else {
+ print STDERR substr($k,0,1);
+ }
+ print STDERR ":".$Stats{$k};
+ printf STDERR "=%.0f%%",(100*$Stats{"$k"}/$Stats{"$k read"})
+ if $Stats{"$k read"};
+ printf STDERR "(%d",($Stats{"$k read"}||0);
+ if ( $Stats{"$k read"} && defined($Stats{"$k estim"}) ) {
+ printf STDERR "=%.0f%%",(100*($Stats{"$k read"}||0)/$Stats{"$k estim"});
+ }
+ print STDERR ") ";
+ }
+
+ my $rss = sprintf("%.0f",mem_usage('rss'));
+ $Stats{"max rss"} = max($Stats{"max rss"},$rss) if $rss;
+ printf STDERR "max-rss %d" ,($Stats{"max rss"}) if $Stats{"max rss"} >$rss*1.3;
+ my $vsz = sprintf("%.0f",mem_usage('vsz'));
+ $Stats{"max vsz"} = max($Stats{"max vsz"},$vsz) if $vsz;
+ printf STDERR "max-vsz %d" ,($Stats{"max vsz"}) if $Stats{"max vsz"} >$vsz*1.3;
+
+ print STDERR mem_usage();
+ print STDERR time_estimate($PARSING_START_TIME,$Stats{"tags read"},$Stats{"tags estim"});
+ print STDERR "\r";
+ if ($DEBUG > 5 ) {
+ print STDERR "\n";
+ for my $k ( sort keys %{$all_unknown_tags}){
+ my $v = $all_unknown_tags->{$k};
+ next unless $v>1;
+ print "\t$v*\t$k\n";
+ }
+ }
+
+ }
+}
+
+# Function is called whenever text is encountered in the XML file
+#----------------------------------------------
+sub DoChar(){
+ my ($expat, $string) = @_;
+}
+
+
+sub write_named_point($) {
+ my $node = shift;
+ return unless defined $node;
+ my $poi_type_id=0;
+ my $unknown_keys='';
+ for my $k ( keys %{$node}) {
+ next if $k =~ m/^(highway)$/;
+ next if $k =~ m/^(osmarender:|source_ref:)/;
+ next if defined($IGNORE_TAG->{$k});
+ next if defined($IGNORE_TAG->{lc($k)});
+
+ # for streets/segments we need to have a look at
+ # bridge=yes
+ # oneway=true
+ # ref=A21
+ # layer=1
+ my $v = $node->{$k};
+ #print "check $k=$v\n";
+ $poi_type_id = poi_type_id($k,$v);
+ if ( $poi_type_id ) {
+ my $values;
+ $values->{'poi.source_id'} = $SOURCE_ID_OSM;
+ $values->{'poi.name'} = $node->{name}||$node->{ref}||'Unknown OSM POI';
+ $values->{'poi.lat'} = $node->{lat};
+ $values->{'poi.lon'} = $node->{lon};
+ $values->{'poi.poi_type_id'} = $poi_type_id;
+# $values->{'poi.comment'} = $comment;
+ Geo::Gpsdrive::DBFuncs::add_poi($values);
+ }
+ }
+ if ( $unknown_keys && !$poi_type_id ) {
+ print STDERR "Unknown Keys: $unknown_keys\n" if $DEBUG>5;
+ }
+}
+
+###########################################
+
+# ------------------------------------------------------------------
+# load the complete MapFeatures Structure into memory
+sub load_elemstyles($){
+ my $filename = shift;
+ return unless $filename && -s $filename;
+ print("Loading Elemstyles $filename\n") if $VERBOSE || $DEBUG;
+ print "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+ print STDERR "Parsing file: $filename\n" if $DEBUG;
+
+ my $fh = data_open($filename);
+ die "Could not open $filename\n" unless $fh;
+ my $rules = XMLin($fh);
+ die "Could not parse $filename\n" unless $rules;
+
+ my $max_street_id=100;
+ for my $rule ( @{$rules->{'rule'}} ) {
+ #print Dumper(\$rule);
+ unless ( defined($rule->{streets_type_id} ) ){
+ $rule->{streets_type_id} = $max_street_id++;
+ }
+ my $k = $rule->{condition}->{k};
+ my $v = $rule->{condition}->{v};
+ if ( defined( $rule->{icon} ) ) {
+ $ELEMSTYLES->{$k}->{$v} = $rule;
+ }
+ if ( defined( $rule->{line} ) ) {
+ $ELEMSTYLES->{$k}->{$v} = $rule;
+ push(@{$ELEMSTYLES_RULES}, $rule);
+ }
+ if ( defined( $rule->{area} ) ) {
+ $ELEMSTYLES->{$k}->{$v} = $rule;
+ }
+ }
+ print "read up to id:$max_street_id\n";
+}
+
+
+# ------------------------------------------------------------------
+# get the poi_type_id from icon_rules without pulluting the hash-structure
+sub poi_type_id($$){
+ my $k = lc(shift); # for now lowercase, so we catch more
+ my $v = lc(shift); # for now lowercase, so we catch more
+ return 0 unless defined $ICON_RULES->{$k};
+ return 0 unless defined $ICON_RULES->{$k}->{$v};
+ return $ICON_RULES->{$k}->{$v};
+}
+
+# ------------------------------------------------------------------
+# load the complete icons.xml into memory
+# in the end we have a hash structure where you get the poi_type_id
+# by simply asking for
+# $ICON_RULES->{$k}->{$v};
+sub load_icons($){
+ my $filename = shift;
+ return unless $filename && -s $filename;
+
+ print("Loading Icons $filename\n") if $VERBOSE || $DEBUG;
+ print "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+ print STDERR "Parsing file: $filename\n" if $DEBUG;
+
+ my $fh = data_open($filename);
+ if (not $fh) {
+ die "Could not open $filename\n";
+ return;
+ }
+ my $rules = XMLin($fh);
+ if (not $rules) {
+ die "Could not parse $filename\n";
+ return;
+ }
+
+ $ICON_RULES={};
+
+ sub add_rule($$){
+ my $rule = shift;
+ my $condition = shift;
+ my $k = $condition->{'k'};
+ my $v = $condition->{'v'};
+ $ICON_RULES->{$k}->{$v}=$rule->{'geoinfo'}->{'poi_type_id'};
+ }
+ for my $rule ( @{$rules->{'rule'}} ) {
+ my $condition = $rule->{'condition'};
+ if ( ref($condition) eq "HASH" ) {
+ add_rule($rule,$condition);
+ } else {
+ for my $cond (@{$condition} ) {
+ add_rule($rule,$cond);
+ }
+ }
+ }
+ #warn Dumper(\$rules);
+ #warn Dumper(\$ICON_RULES);
+}
+
+
+# -----------------------------------------------------------------------------
+sub read_osm_file($$) { # Insert Streets from osm File
+ my $file_name = shift;
+ my $area_name = shift;
+
+ my $start_time=time();
+
+ $AREA_FILTER = Geo::Filter::Area->new( area => $area_name );
+
+ print("\rReading $file_name for $area_name\n") if $VERBOSE || $debug;
+ print "$file_name: ".(-s $file_name)." Bytes\n" if $debug;
+
+ print STDERR "Parsing file: $file_name\n" if $debug;
+ $PARSING_START_TIME=time();
+
+ my $p = new XML::Parser( Handlers => {
+ Start => \&DoStart,
+ End => \&DoEnd,
+ Char => \&DoChar});
+
+ my $fh = data_open($file_name);
+ my $content;
+ eval {
+ $content = $p->parse($fh);
+ };
+
+ if ($DEBUG >2 ) {
+ print STDERR "Unknown Tags in Area($area_name)of File($file_name):\n";
+ for my $k ( sort keys %{$all_unknown_tags}){
+ my $v = $all_unknown_tags->{$k};
+ next unless $v>1;
+ print "\t$v*\t$k\n";
+ }
+ }
+
+ if ($@) {
+ die "ERROR: Could not parse osm data $file_name\n".
+ "$@\n";
+ }
+ if (not $p) {
+ die "ERROR: Could not parse osm data $file_name\n";
+ }
+ if ( $VERBOSE) {
+ printf "Read and parsed $file_name in %.0f sec\n",time()-$start_time;
+ }
+ return;
+}
+
+# -----------------------------------------------------------------------------
+sub read_osm_dir($$) { # read all OSM Files in Directory
+ my $osm_dir = shift;
+ my $area_name = shift;
+
+ my $osm_auth = " --http-user=$ENV{OSMUSER} --http-passwd=$ENV{OSMPASSWD} ";
+ my $osm_base_url="http://www.openstreetmap.org/api/0.3/map?bbox=";
+ # http://www.openstreetmap.org/api/0.3/map?bbox=11.0,48.0,12.0,49.0
+
+ for my $abs_filename (
+ #glob("$osm_dir/planet.osm"),
+ glob("$osm_dir/Streets*.osm"),
+ glob("$osm_dir/Streets*.xml"),
+ glob("$osm_dir/Streets*.gz"),
+ glob("$osm_dir/Streets*.bz2"),
+ ) {
+ $abs_filename .= ".gz" if -s "$abs_filename.gz" && ! -s $abs_filename;
+ my $size = (-s $abs_filename)||0;
+ if ( $size == 538 ) { # Probably Internal Error Message
+ `cat $abs_filename`;
+ next;
+ }
+ next unless $size >76; # Empty File (Only Header, no nodes)
+ print "$abs_filename: $size Bytes\n";
+ read_osm_file($abs_filename,$area_name);
+ }
+}
+
+
+# ------------------------------------------------------------------
+my $class2type = {
+ "barn" => "area.building.barn",
+ "bridge" => "area.bridge",
+ "campsite" => "accommodation.camping",
+ "car park" => "vehicle.parking",
+ "caution" => "misc.caution",
+ "church" => "religion.church",
+ "city" => "places.settlement.city",
+ "country park" => "recreation.park",
+ "farm" => "area.area.farm",
+ "hamlet" => "places.settlement.hamlet",
+ "hill" => "area.area.hill",
+ "historic-name" => "sightseeing",
+ "industrial area" => "area.area.industial-area",
+ "large town" => "places.settlement.city",
+ "lift" => "transport.station.lift",
+ "locality" => "unknown",
+ "parking" => "vehicle.parking",
+ "point of interest" => "unknown",
+ "pub" => "food.pub",
+ "railway crossing" => "area.railway-crossing",
+ "railway station" => "transport.railway",
+ "restaurant" => "food.restaurant",
+ "school" => "education.school",
+ "small town" => "places.settlement.town",
+ "suburb" => "places.settlement.town",
+ "tea shop" => "shopping.groceries.tea",
+ "town" => "places.settlement.town",
+ "trafficlight" => "vehicle.trafficlight",
+ "tunnel" => "area.tunnel",
+ "viewpoint" => "sightseeing.viewpoint",
+ "village" => "places.settlement.village",
+ "Village" => "places.settlement.village",
+ "waypoint" => "waypoint",
+};
+
+
+# ******************************************************************
+sub delete_existing_osm_entries(){
+
+ unless ( $main::no_delete ) {
+ print "Delete old OSM Data\n";
+ Geo::Gpsdrive::DBFuncs::delete_all_from_source($SOURCE_OSM);
+ print "Deleted old OSM Data\n" if $VERBOSE || $debug;
+ }
+
+}
+
+# ******************************************************************
+sub get_source_id{
+
+ $SOURCE_ID_OSM = Geo::Gpsdrive::DBFuncs::source_name2id($SOURCE_OSM);
+
+ unless ( $SOURCE_ID_OSM ) {
+ my $source_hash = {
+ 'source.url' => "http://openstreetmap.org/",
+ 'source.name' => $SOURCE_ID_OSM ,
+ 'source.comment' => '' ,
+ 'source.licence' => ""
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $SOURCE_ID_OSM = Geo::Gpsdrive::DBFuncs::source_name2id($SOURCE_OSM);
+ }
+ die "Cannot get Source ID for $SOURCE_OSM\n"
+ unless $SOURCE_ID_OSM;
+ return $SOURCE_ID_OSM;
+}
+
+
+# *****************************************************************************
+
+sub import_Data($@){
+ my $areas_todo = shift;
+ my @filenames = @_;
+
+ #$areas_todo ||= 'germany';
+ $areas_todo ||= 'world';
+ $areas_todo=lc($areas_todo);
+
+ print "\nImport OSM Data($areas_todo)\n";
+
+ my $mirror_dir="$main::MIRROR_DIR/osm";
+
+ -d $mirror_dir or mkpath $mirror_dir
+ or die "Cannot create Directory $mirror_dir:$!\n";
+
+ my $icons_filename;
+ for my $fn ( "$ENV{HOME}/.josm/icons.xml",
+ "../data/map-icons/icons.xml",
+ "data/map-icons/icons.xml",
+ "/usr/local/map-icons/icons.xml",
+ "/usr/local/share/map-icons/icons.xml",
+ ) {
+ unless ( $icons_filename && -s $icons_filename ){
+ print STDERR "Checking icons-file: $fn\n"
+ if $VERBOSE || $DEBUG;
+ $icons_filename = $fn;
+ }
+ }
+ die "!!!!!!!!ERROR: icons File '$icons_filename' not found\n"
+ unless $icons_filename && -s $icons_filename;
+
+ load_icons( $icons_filename );
+
+ my $elemstyles_filename = "$ENV{HOME}/.josm/plugins/mappaint/elemstyles.xml";
+ $elemstyles_filename ="$ENV{HOME}/svn.openstreetmap.org/applications/editors/josm/plugins/mappaint/styles/standard/elemstyles.xml" unless -s $elemstyles_filename;
+ $elemstyles_filename ="../../editors/josm/plugins/mappaint/styles/standard/elemstyles.xml" unless -s $elemstyles_filename;
+ $elemstyles_filename ="../../etc/elemstyles.xml" unless -s $elemstyles_filename;
+ load_elemstyles($elemstyles_filename);
+
+ disable_keys('poi');
+ $SOURCE_ID_OSM = get_source_id();
+
+ delete_existing_osm_entries();
+
+ for my $filename ( @filenames ) {
+ print "Import OSM Data '$filename'\n";
+
+ if ( -s $filename ) {
+ read_osm_file( $filename,$areas_todo);
+ } elsif ( $filename eq '' ) {
+ print "Download planet-xxxxxx.osm\n";
+ $filename = mirror_planet();
+ print "Mirror $filename complete\n";
+ read_osm_file($filename,$areas_todo);
+ } else {
+ die "OSM::import_Data: Cannot find File '$filename'\n";
+ print "Read OSM Data\n";
+ };
+ }
+
+ enable_keys('poi');
+
+ print "\nDownload and import of OSM Data FINISHED\n";
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB.pm
new file mode 100644
index 0000000..5ac4c00
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB.pm
@@ -0,0 +1,239 @@
+# Import Data from Open GEO DB to geoinfo.poi
+#
+# $Log$
+# Revision 1.5 2006/04/20 22:41:05 tweety
+# make database name variable
+# import osm POI too
+# add colog_bg, width, width_bg to db layout
+#
+# Revision 1.4 2006/02/13 18:56:23 tweety
+# Update to new Version of Database
+#
+# Revision 1.3 2005/10/20 20:53:38 tweety
+# change min scale to 1
+#
+# Revision 1.2 2005/10/11 08:28:35 tweety
+# gpsdrive:
+# - add Tracks(MySql) displaying
+# - reindent files modified
+# - Fix setting of Color for Grid
+# - poi Text is different in size depending on Number of POIs shown on
+# screen
+#
+# geoinfo:
+# - get Proxy settings from Environment
+# - create tracks Table in Database and fill it
+# this separates Street Data from Track Data
+# - make geoinfo.pl download also Opengeodb Version 2
+# - add some poi-types
+# - Split off Filling DB with example Data
+# - extract some more Funtionality to Procedures
+# - Add some Example POI for Kirchheim(Munich) Area
+# - Adjust some Output for what is done at the moment
+# - Add more delayed index generations 'disable/enable key'
+# - If LANG=*de_DE* then only impert europe with --all option
+# - WDB will import more than one country if you wish
+# - add more things to be done with the --all option
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.12 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.11 2005/05/10 05:28:49 tweety
+# type in disable_keys
+#
+# Revision 1.10 2005/05/01 13:49:36 tweety
+# Added more Icons
+# Moved filling with defaults to DB_Defaults.pm
+# Added some more default POI Types
+# Added icons.html to see which icons are used
+# Added more Comments
+# Reformating Makefiles
+# Added new options for importing from way*.txt and adding defaults
+# Added more source_id and type_id
+#
+# Revision 1.9 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.8 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::OpenGeoDB;
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Path;
+
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Geo::Gpsdrive::Gps;
+
+#############################################################################
+# Args:
+# $filename : Filename to read
+#############################################################################
+sub read_open_geo_db($){
+ my $full_filename = shift;
+
+ print "Reading open geo db: $full_filename\n";
+ my $fh = IO::File->new("<$full_filename");
+ $fh or die ("read_open_geo_db: Cannot open $full_filename:$!\n");
+
+ my $source = "open geo db";
+ delete_all_from_source($source);
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => $full_filename,
+ 'source.name' => $source ,
+ 'source.comment' => '' ,
+ 'source.licence' => ""
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+ my @columns;
+ @columns = qw( primarykey
+ address.state address.bundesland address.regierungsbezirk
+ address.landkreis address.verwaltungszusammenschluss
+ address.ort address.ortsteil address.gemeindeteil
+ poi.lat poi.lon
+ poi.autokennzeichen
+ address.plz);
+ my $lines_count_file =0;
+ debug( " ". join("\t",@columns));
+ while ( my $line = $fh->getline() ) {
+ $lines_count_file ++;
+ $line =~ s/[\t\r\n\s]*$//g;;
+# print "line: '$line'\n";
+ if ( $line =~ m/^$/ ) {
+ } elsif ( $line =~ m/^\#/ ) {
+ } else {
+ die "Spalten nicht definiert" unless @columns;
+
+# print "WP: $line\n";
+ my @values = split(/\s*\;\s*/,$line);
+ #print Dumper(\@values);
+ my $values;
+ for my $i ( 0 .. scalar @columns -1 ) {
+ $values->{$columns[$i]} = $values[$i];
+ $values->{'poi.comment'} .= "$values[$i]\n" if $i>2;
+ }
+
+ ############################################
+ # Set Default Proximity
+ $values->{'poi.proximity'} ||= "1000 m";
+
+ $values->{'poi.symbol'} ||= "City";
+
+
+ my $first_in_a_row=1;
+ for my $plz ( split(',',$values->{'address.plz'})) {
+ # print Dumper($values);
+ my $wp_name = '';
+ $wp_name .= "$values->{'address.state'} ";
+# $wp_name .= $plz;
+ # $wp_name .= "_$values->{'poi.primarykey'}";
+ # $wp_name .= "_$values->{'address.regierungsbezirk'}";
+ # $wp_name .= "_$values->{'address.landkreis'}";
+ # $wp_name .= "_$values->{'address.verwaltungszusammenschluss'}";
+ $wp_name .= " $values->{'address.ort'}\n";
+ $wp_name .= " $values->{'address.ortsteil'}";
+ $wp_name .= " $values->{'address.gemeindeteil'}";
+# $wp_name .= " ($values->{'address.bundesland'})";
+ $values->{'poi.name'}=$wp_name;
+ if ( $plz =~ m/000$/ ) {
+ print "$values->{'address.state'}-$plz $values->{'address.ort'}\n";
+ $values->{'poi.scale_max'} = 1000000000;
+ $values->{'poi.proximity'} = "10000m";
+ } elsif ( $values->{'address.ortsteil'} eq "-" &&
+ $values->{'address.gemeindeteil'} eq "-" &&
+ $values->{'address.regierungsbezirk'} eq "-" &&
+ $values->{'address.verwaltungszusammenschluss'} eq "-" &&
+ $first_in_a_row
+ ) {
+ debug( "$values->{'address.state'}-$plz :". join("\t",@values));
+ $values->{'poi.scale_max'} = 100000000;
+ $values->{'poi.proximity'} = "5000m";
+ $first_in_a_row=0;
+ } elsif ( $plz =~ m/00$/ ) {
+ $values->{'poi.scale_max'} = 5000000;
+ $values->{'poi.proximity'} = "5000m";
+ } elsif ( $plz =~ m/0$/ ) {
+ $values->{'poi.scale_max'} = 1000000;
+ $values->{'poi.proximity'} = "1000m";
+ } else {
+ $values->{'poi.scale_max'} = 100000;
+ $values->{'poi.proximity'} = "300m";
+ }
+ $values->{'poi.scale_min'} = 1;
+
+ $values->{'poi.name'}.=$values->{'poi.scale_max'};
+ unless ( defined($values->{'poi.lat'}) ) {
+ print "Undefined lat".Dumper(\$values);
+ }
+ unless ( defined($values->{'poi.lon'}) ) {
+ print "Undefined lon".Dumper(\$values);
+ }
+
+ $values->{'poi.source_id'}=$source_id;
+
+ correct_lat_lon($values);
+ Geo::Gpsdrive::DBFuncs::add_poi($values);
+ #print "Values:".Dumper(\$values);
+ }
+ }
+ }
+}
+
+########################################################################################
+# Get and Unpack opengeodb
+# http://www.opengeodb.de/download/
+########################################################################################
+sub import_Data() {
+ my $mirror_dir="$main::MIRROR_DIR/opengeodb";
+ my $unpack_dir="$main::UNPACK_DIR/opengeodb";
+
+ print "\nDownload an import OpenGeoDB Data\n";
+
+ -d $mirror_dir or mkpath $mirror_dir
+ or die "Cannot create Directory $mirror_dir:$!\n";
+
+ -d $unpack_dir or mkpath $unpack_dir
+ or die "Cannot create Directory $unpack_dir:$!\n";
+
+ # download
+ my $file_name ="opengeodb-0.2.4d-UTF8-text-orte.zip";
+ my $url = "http://dl.sourceforge.net/sourceforge/opengeodb/$file_name";
+ print "Mirror $url\n";
+ my $mirror = mirror_file($url,"$mirror_dir/$file_name");
+ print "Mirror: $mirror\n";
+
+ # Unpack it
+ `(cd $unpack_dir/; unzip -o $mirror_dir/$file_name)`;
+
+ disable_keys('poi');
+
+ for my $file_name ( glob("$unpack_dir/opengeodb*.txt") ) {
+ my $out_file_name = "$main::CONFIG_DIR/way_opengeodb.txt";
+ read_open_geo_db($file_name);
+ }
+
+ enable_keys('poi');
+
+ print "Download an import OpenGeoDB Data FINISHED\n";
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB2.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB2.pm
new file mode 100644
index 0000000..9a573ae
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/OpenGeoDB2.pm
@@ -0,0 +1,243 @@
+# Import Data from Open GEO DB to geoinfo.poi
+#
+# $Log$
+# Revision 1.2 2006/02/13 23:29:45 tweety
+# get actual Version of OpenGeodb
+#
+# Revision 1.1 2005/10/11 08:28:35 tweety
+# gpsdrive:
+# - add Tracks(MySql) displaying
+# - reindent files modified
+# - Fix setting of Color for Grid
+# - poi Text is different in size depending on Number of POIs shown on
+# screen
+#
+# geoinfo:
+# - get Proxy settings from Environment
+# - create tracks Table in Database and fill it
+# this separates Street Data from Track Data
+# - make geoinfo.pl download also Opengeodb Version 2
+# - add some poi-types
+# - Split off Filling DB with example Data
+# - extract some more Funtionality to Procedures
+# - Add some Example POI for Kirchheim(Munich) Area
+# - Adjust some Output for what is done at the moment
+# - Add more delayed index generations 'disable/enable key'
+# - If LANG=*de_DE* then only impert europe with --all option
+# - WDB will import more than one country if you wish
+# - add more things to be done with the --all option
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.12 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.11 2005/05/10 05:28:49 tweety
+# type in disable_keys
+#
+# Revision 1.10 2005/05/01 13:49:36 tweety
+# Added more Icons
+# Moved filling with defaults to DB_Defaults.pm
+# Added some more default POI Types
+# Added icons.html to see which icons are used
+# Added more Comments
+# Reformating Makefiles
+# Added new options for importing from way*.txt and adding defaults
+# Added more source_id and type_id
+#
+# Revision 1.9 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.8 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::OpenGeoDB2;
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Path;
+
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+use Geo::Gpsdrive::Gps;
+
+#############################################################################
+# Args:
+# $filename : Filename to read
+#############################################################################
+sub read_open_geo_db2($){
+ my $full_filename = shift;
+
+ print "Reading open geo db: $full_filename\n";
+ my $fh = IO::File->new("<$full_filename");
+ $fh or die ("read_open_geo_db: Cannot open $full_filename:$!\n");
+
+ my $source = "open geo db";
+ delete_all_from_source($source);
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => "http://ovh.dl.sourceforge.net/".
+ "sourceforge/geoclassphp/opengeodb-0.1.3-txt.tar.gz",
+ 'source.name' => $source ,
+ 'source.comment' => '' ,
+ 'source.licence' => ""
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+ my @columns;
+ @columns = qw( primarykey
+ address.state address.bundesland address.regierungsbezirk
+ address.landkreis address.verwaltungszusammenschluss
+ address.ort address.ortsteil address.gemeindeteil
+ poi.lat poi.lon
+ poi.autokennzeichen
+ address.plz);
+ my $lines_count_file =0;
+ debug( " ". join("\t",@columns));
+ while ( my $line = $fh->getline() ) {
+ $lines_count_file ++;
+ $line =~ s/[\t\r\n\s]*$//g;;
+# print "line: '$line'\n";
+ if ( $line =~ m/^$/ ) {
+ } elsif ( $line =~ m/^\#/ ) {
+ } else {
+ die "Spalten nicht definiert" unless @columns;
+
+# print "WP: $line\n";
+ my @values = split(/\s*\;\s*/,$line);
+ #print Dumper(\@values);
+ my $values;
+ for my $i ( 0 .. scalar @columns -1 ) {
+ $values->{$columns[$i]} = $values[$i];
+ $values->{'poi.comment'} .= "$values[$i]\n" if $i>2;
+ }
+
+ ############################################
+ # Set Default Proximity
+ $values->{'poi.proximity'} ||= "1000 m";
+
+ $values->{'poi.symbol'} ||= "City";
+
+
+ my $first_in_a_row=1;
+ for my $plz ( split(',',$values->{'address.plz'})) {
+ # print Dumper($values);
+ my $wp_name = '';
+ $wp_name .= "$values->{'address.state'}-";
+ $wp_name .= $plz;
+ # $wp_name .= "_$values->{'poi.primarykey'}";
+ # $wp_name .= "_$values->{'address.regierungsbezirk'}";
+ # $wp_name .= "_$values->{'address.landkreis'}";
+ # $wp_name .= "_$values->{'address.verwaltungszusammenschluss'}";
+ $wp_name .= " $values->{'address.ort'}\n";
+ $wp_name .= " $values->{'address.bundesland'}";
+ $wp_name .= " $values->{'address.ortsteil'}";
+ $wp_name .= " $values->{'address.gemeindeteil'}";
+ $values->{'poi.name'}=$wp_name;
+ if ( $plz =~ m/000$/ ) {
+ print "$values->{'address.state'}-$plz $values->{'address.ort'}\n";
+ $values->{'poi.scale_max'} = 1000000000;
+ $values->{'poi.proximity'} = "10000m";
+ } elsif ( $values->{'address.ortsteil'} eq "-" &&
+ $values->{'address.gemeindeteil'} eq "-" &&
+ $values->{'address.regierungsbezirk'} eq "-" &&
+ $values->{'address.verwaltungszusammenschluss'} eq "-" &&
+ $first_in_a_row
+ ) {
+ debug( "$values->{'address.state'}-$plz :". join("\t",@values));
+ $values->{'poi.scale_max'} = 100000000;
+ $values->{'poi.proximity'} = "5000m";
+ $first_in_a_row=0;
+ } elsif ( $plz =~ m/00$/ ) {
+ $values->{'poi.scale_max'} = 5000000;
+ $values->{'poi.proximity'} = "5000m";
+ } elsif ( $plz =~ m/0$/ ) {
+ $values->{'poi.scale_max'} = 1000000;
+ $values->{'poi.proximity'} = "1000m";
+ } else {
+ $values->{'poi.scale_max'} = 100000;
+ $values->{'poi.proximity'} = "300m";
+ }
+ $values->{'poi.scale_min'} = 0;
+
+ $values->{'poi.name'}.=$values->{'poi.scale_max'};
+ unless ( defined($values->{'poi.lat'}) ) {
+ print "Undefined lat".Dumper(\$values);
+ }
+ unless ( defined($values->{'poi.lon'}) ) {
+ print "Undefined lon".Dumper(\$values);
+ }
+
+ $values->{'poi.source_id'}=$source_id;
+
+ correct_lat_lon($values);
+ Geo::Gpsdrive::DBFuncs::add_poi($values);
+ #print "Values:".Dumper(\$values);
+ }
+ }
+ }
+}
+
+########################################################################################
+# Get and Unpack opengeodb
+# http://www.opengeodb.de/download/
+########################################################################################
+sub import_Data() {
+ my $mirror_dir="$main::MIRROR_DIR/opengeodb";
+ my $unpack_dir="$main::UNPACK_DIR/opengeodb";
+
+ print "\nDownload an import OpenGeoDB2 Data\n";
+
+ -d $mirror_dir or mkpath $mirror_dir
+ or die "Cannot create Directory $mirror_dir:$!\n";
+
+ -d $unpack_dir or mkpath $unpack_dir
+ or die "Cannot create Directory $unpack_dir:$!\n";
+
+ # download
+ my $file_name = "opengeodb-0.2.4c-UTF8-mysql.zip";
+ my $url = "http://dl.sourceforge.net/sourceforge/opengeodb/$file_name";
+ print "Mirror $url\n";
+ my $mirror = mirror_file($url,"$mirror_dir/$file_name");
+ print "Mirror: $mirror\n";
+
+ # Unpack it
+ print "Unpack\n";
+ `(cd $unpack_dir/; unzip -o $mirror_dir/$file_name)`;
+
+ print "Drop DB\n";
+ `echo "drop database opengeodb;"|mysql -u$main::db_user -p$main::db_password`;
+ print "Create DB\n";
+ `echo 'CREATE DATABASE \`opengeodb\` ;'|mysql -u$main::db_user -p$main::db_password`;
+ print "Insert into DB\n";
+ `mysql -u$main::db_user -p$main::db_password opengeodb <$unpack_dir/opengeodb-0.2.4a-UTF8-mysql.sql`;
+
+if (0){
+ disable_keys('poi');
+
+ for my $file_name ( glob("$unpack_dir/opengeodb*.txt") ) {
+ my $out_file_name = "$main::CONFIG_DIR/way_opengeodb.txt";
+ read_open_geo_db2($file_name);
+ }
+
+ enable_keys('poi');
+ print "Download an import OpenGeoDB Data FINISHED\n";
+}
+ print "Download OpenGeoDB2 Data FINISHED\n";
+
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/PocketGpsPoi.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/PocketGpsPoi.pm
new file mode 100644
index 0000000..d33b827
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/PocketGpsPoi.pm
@@ -0,0 +1,130 @@
+# Import Speedtrap Data into geoinfo.poi
+#
+# $Log$
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.4 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.3 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.2 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::PocketGpsPoi;
+
+use strict;
+use warnings;
+
+use IO::File;
+use LWP::Debug qw(- -conns -trace);
+use LWP::UserAgent;
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+
+#############################################################################
+# Args:
+# $filename : Filename to read
+# RETURNS:
+# $waypoints : Hash of read Waypoints
+#############################################################################
+sub read_speedstrap_wp($$){
+ my $full_filename = shift;
+ my $type = shift; # Type of Speedtrap / Photo
+
+ print "Reading: $full_filename\n";
+
+ my $fh = IO::File->new("<$full_filename");
+ $fh or die ("read_speedtrap_wp: Cannot open $full_filename:$!\n");
+
+ my $waypoints;
+ my $lines_count_file =0;
+ while ( my $line = $fh->getline() ) {
+ $lines_count_file ++;
+ $line =~ s/[\t\r\n\s]*$//g;;
+ # print "line: '$line'\n";
+ if ($line =~ m/^Longitude,Latitude,Name/ ) {
+ } elsif ( $line =~ m/^$/ ) {
+ } elsif ( $line =~ m/^\-?\d+/ ) {
+ my @values = split(/\,/,$line);
+ #print Dumper(\@values);
+ my $values;
+ $values->{lat} = $values[0];
+ $values->{lon} = $values[1];
+ $values->{Name} = $values[2];
+ $values->{Name} =~ s/^\"//;
+ $values->{Name} =~ s/\"$//;
+
+ ############################################
+ # Set Default Proximity for speedtraps to 500m
+ $values->{'Proximity'} ||= "500 m";
+
+ $values->{Symbol} = "SPEEDTRAP-$type";
+
+ ############################################
+ correct_lat_lon($values);
+
+ #print Dumper($values) if defined $values->{'Proximity'};
+ my $wp_name = $values->{'Name'};
+ $waypoints->{$wp_name} = $values;
+ } else {
+ print "Unknown Line: '$line'\n";
+ }
+
+ }
+ return $waypoints;
+}
+
+########################################################################################
+# Get and Unpack POCKETGPS_DIR
+# http://www.pocketgpspoi.com
+########################################################################################
+sub import_Data(){
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+ print "Pocketgps Not working yet.\n";
+ print "Skipping \n";
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+}
+if ( 0 ) {
+ my $POCKETGPS_DIR = "$main::CONFIG_DIR/MIRROR/POCKETGPS";
+
+ unless ( -d $POCKETGPS_DIR ) {
+ print "Creating Directory $POCKETGPS_DIR\n";
+ mkpath $POCKETGPS_DIR
+ or die "Cannot create Directory $POCKETGPS_DIR:$!\n";
+ }
+
+ # download
+ my $mirror = mirror_file("http://www.pocketgpspoi.com/downloads/pocketgps_uk_sc.zip",
+ "$POCKETGPS_DIR/pocketgps_uk_sc.zip");
+
+ print "Mirror: $mirror\n";
+
+ if ( $mirror ) {
+ # Unpack it
+ `(cd $POCKETGPS_DIR/; unzip -o pocketgps_uk_sc.zip)`;
+
+ for my $file_name ( glob("$POCKETGPS_DIR/pocketgps_*.csv") ) {
+ my ( $type ) = ($file_name =~ m/pocketgps_(.*)\.csv/);
+ my $out_file_name = "/home/gpsdrive/way_pocketgps_$type.txt";
+ my $waypoints = read_speedstrap_wp($file_name,$type);
+ write_gpsdrive_waypoints($waypoints,$out_file_name);
+ write_mapsource_waypoints($waypoints,"way_pocketgps_$type.txt");
+ }
+ }
+}
+
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/Utils.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/Utils.pm
new file mode 100644
index 0000000..3b695ac
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/Utils.pm
@@ -0,0 +1,260 @@
+# Some small ungrouped Utility functions
+#
+# $Log$
+# Revision 1.3 2006/10/02 23:28:07 tweety
+# add own wlan database. This is kind of a template to eliminate the problems with the SSIDs with strange charset.
+# make all Tables UTF8
+#
+# Revision 1.2 2005/10/11 08:28:35 tweety
+# gpsdrive:
+# - add Tracks(MySql) displaying
+# - reindent files modified
+# - Fix setting of Color for Grid
+# - poi Text is different in size depending on Number of POIs shown on
+# screen
+#
+# geoinfo:
+# - get Proxy settings from Environment
+# - create tracks Table in Database and fill it
+# this separates Street Data from Track Data
+# - make geoinfo.pl download also Opengeodb Version 2
+# - add some poi-types
+# - Split off Filling DB with example Data
+# - extract some more Funtionality to Procedures
+# - Add some Example POI for Kirchheim(Munich) Area
+# - Adjust some Output for what is done at the moment
+# - Add more delayed index generations 'disable/enable key'
+# - If LANG=*de_DE* then only impert europe with --all option
+# - WDB will import more than one country if you wish
+# - add more things to be done with the --all option
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.4 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.3 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::Utils;
+
+use strict;
+use warnings;
+
+use IO::File;
+use LWP::Debug qw(- -conns -trace);
+use LWP::UserAgent;
+
+$|= 1; # Autoflush
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+
+ # set the version for version checking
+ $VERSION = 1.00;
+ # if using RCS/CVS, this may be preferred
+ # $VERSION = sprintf "%d.%03d", q$Revision: 1190 $ =~ /(\d+)/g;
+
+ @ISA = qw(Exporter);
+ @EXPORT = qw( &debug $debug $debug_range
+ &stacktrace &mirror_file &file_newer
+ &correct_lat_lon
+ $PROXY $no_mirror $verbose);
+ %EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ],
+ # your exported package globals go here,
+ # as well as any optionally exported functions
+ @EXPORT_OK = qw();
+
+}
+our @EXPORT_OK;
+
+
+our $debug;
+our $debug_range =''; # Ein Ausdruck ala !Funktion,Funktion
+our $PROXY='';
+our $no_mirror = 0;
+our $verbose=0;
+
+#############################################################################
+# Debug
+#############################################################################
+sub debug($){
+ my $msg = shift;
+ return unless $debug || $debug_range;
+
+ my $function = (caller(1))[3];
+
+ if ( $debug_range ) {
+ my @debug_ranges = split(/(\,|\s+)\s*/,$debug_range); # Stings separated by ',' or blank
+ print STDERR "range: $debug_range\n";
+ my $do_debug = 0;
+ # Check positive
+ foreach my $check ( @debug_ranges) {
+ my $i=0;
+ my ($p,$f,$l,$s) = (1,0,0,0);
+ while ( $p ){
+ ($p,$f,$l,$s) = caller($i++);
+ last unless $p;
+ #print STDERR "DEBUG: $i ($p,$f,$l,$s)\n";
+ if ( $check =~ s/^\!// ){
+ return
+ if $s =~ m{$check};
+ } else { # Negativ !...
+ if ($s =~ m{$check}) {
+ $do_debug = 1;
+ } else {
+ $do_debug = 2
+ unless $do_debug;
+ }
+ }
+ #print STDERR "check: $check,$s,$do_debug\n";
+
+ }
+ }
+ return unless $do_debug == 1;
+ #stacktrace("Debug");
+ }
+ print STDERR "$function: " if $verbose;
+ print STDERR "$msg\n";
+}
+
+#############################################################################
+# Stacktrace
+#############################################################################
+sub stacktrace {
+ my $msg = shift || "unnamed";
+ my $i = shift || 0;
+
+ print STDERR "STACKTRACE: $msg";
+ my $n = 20;
+ while ( $n-- >= 0 ) {
+ my ($p,$f,$l,$s) = caller($i++);
+ last unless $p;
+ printf STDERR "STACK($i): File=%-20s Package=%-15s, Line=%-3d called Sub=%-20s\n",$f,$p,$l,$s;
+ }
+}
+
+
+#############################################################################
+# get File with lwp-mirror
+#############################################################################
+sub mirror_file($$){
+ my $url = shift;
+ my $local_filename = shift;
+
+ my $mirror=1;
+
+ return 1 if $no_mirror;
+
+ # LPW::UserAgent initialisieren
+ my $ua = LWP::UserAgent->new;
+
+ # Set Proxy from Environment
+ if (!$PROXY) {
+ $PROXY ||= $ENV{'PROXY'};
+ $PROXY ||= $ENV{'http_proxy'};
+ print "Set Proxy to $PROXY\n" if $PROXY;
+ }
+ if ( $PROXY ){
+ $PROXY = "http://$PROXY" unless $PROXY =~ m,^.?.tp://,;
+ $PROXY = "$PROXY/" unless $PROXY =~ m,/$,;
+ $ua->proxy(['http','ftp'],$PROXY);
+ }
+
+ #$ua->level("+trace") if $debug;
+
+ debug("mirror_file($url --> $local_filename)");
+ print "mirror_file($url) " if $verbose;
+ print "\n" if $debug;
+ my $response = $ua->mirror($url,$local_filename);
+# debug(sprintf("success = %d <%s>",$response->is_success,$response->status_line));
+
+ if ( ! $response->is_success ) {
+ if ( $response->status_line =~ /^304/ ) {
+ print "\tNOT MOD" if $debug ;
+ $mirror=2;
+ } else {
+ print "\tCOULD NOT GET ";
+ print "$url\n" unless $debug;
+ print sprintf("ERROR: %s\n",$response->message)
+ if $debug;
+ $mirror=0;
+ }
+ } else {
+ print "\tOK" if $debug;
+ }
+ print "\n" if $debug;
+ return $mirror;
+}
+
+#############################################################################
+# check modifikation times
+# true if file1 newer than file2
+#############################################################################
+sub file_newer($$){
+ my $file1 = shift;
+ my $file2 = shift;
+
+ my $t_1 = (stat($file1))[9];
+ my $t_2 = (stat($file2))[9];
+ return 0 unless $t_2;
+ debug("file 1 ($file1):".localtime($t_1));
+ debug("file 2 ($file2):".localtime($t_2));
+ return ($t_1 < $t_1 );
+}
+
+
+#############################################################################
+# correct/convert lat/lon to apropriate Format
+sub correct_lat_lon($){
+ my $point = shift;
+
+ #print "correct_lat_lon(".Dumper($point);
+
+ for my $type ( qw(poi.lat poi.lon wlan.lat wlan.lon) ) {
+ next unless defined $point->{$type};
+ # N123 12.34
+ if ( $point->{$type} =~ m/^\s*([NSWE]\d{1,3})\s+(\d+\.\d+)\s*$/ ) {
+ my $val1 = $1;
+ my $val2 = $2;
+ $val1 =~ s/[EN]//;
+ $val1 =~ s/[SW]/-/;
+ $point->{$type} = sprintf("%0.9f",$val1+$val2/60);
+ }
+ # N123.34
+ if ( $point->{$type} =~ m/^\s*([NSEW]\d{1,3}\.\d+)\s*$/ ) {
+ my $val = $1;
+ $val =~ s/[NE]//;
+ $val =~ s/[SW]/-/;
+ $point->{$type} = sprintf("%0.9f",$val);
+ }
+ }
+
+ unless ( defined($point->{Position}) && $point->{Position} ){
+ my $lat = $point->{'poi.lat'};
+ my $lon = $point->{'poi.lon'};
+ if ( $lat && $lon ) {
+ if ( $lat =~ s/^-// ) {
+ $lat ="S$lat";
+ } else {
+ $lat ="N$lat";
+ }
+ if ( $lon =~ s/^-// ) {
+ $lon ="W$lon";
+ } else {
+ $lon ="E$lon";
+ }
+
+ $point->{Position} = "$lat $lon";
+ }
+ }
+}
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/WDB.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/WDB.pm
new file mode 100755
index 0000000..6599ea8
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/WDB.pm
@@ -0,0 +1,204 @@
+# Einlesen der WDB Daten und schreiben in die geodb Datenbank von
+# gpsdrive
+#
+
+package Geo::Gpsdrive::WDB;
+
+use strict;
+use warnings;
+
+use IO::File;
+use File::Basename;
+use File::Path;
+use Data::Dumper;
+
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+
+$|=1;
+
+my $LINES_COUNT_FILE =0;
+my $LINES_COUNT_UNPARSED =0;
+
+##################################################################
+# Alle Punkte rausschreiben
+# Args:
+# $fo : Filedescriptor to write t
+# @{$points_in_segment} : List of points
+sub write_points($$){
+ my $fo = shift;
+ my $points_in_segment = shift;
+ if ( @{$points_in_segment} ) {
+ for my $point ( @{$points_in_segment} , $points_in_segment->[0] ) {
+ #$fo->point($point);
+ #$fo{$rank}->point($point) if $rank;
+ print $fo "$point->{lat} $point->{lon}\n";
+ }
+ print $fo "1001.0 1001.0\n";
+ }
+}
+
+##########################################################################
+
+sub import_wdb($){
+ my $full_filename = shift;
+
+ print "Reading $full_filename \n";
+ my $base_filename = basename($full_filename);
+ my ( $area ) = ($base_filename =~ m/^([^-]+)/ );
+ my $fh = IO::File->new("<$full_filename");
+ my $segment = 0;
+ my $rank = 0;
+ my $points = 0;
+ my ($lat1,$lon1) = (0,0);
+ my ($lat2,$lon2) = (0,0);
+
+ my ( $sub_source ) = ( $base_filename =~ m/(.*).txt/ );
+ my ( $country,$type_string) = ( $base_filename =~ m/(.*)-(.*).txt/);
+
+ my $source = "WDB $sub_source";
+ Geo::Gpsdrive::DBFuncs::delete_all_from_source($source);
+ my $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+
+ unless ( $source_id ) {
+ my $source_hash = {
+ 'source.url' => "http://www.evl.uic.edu/pape/data/WDB/WDB-text.tar.gz",
+ 'source.name' => $source ,
+ 'source.comment' => '' ,
+ 'source.licence' => ""
+ };
+ Geo::Gpsdrive::DBFuncs::insert_hash("source", $source_hash);
+ $source_id = Geo::Gpsdrive::DBFuncs::source_name2id($source);
+ }
+
+
+
+ my $area_limit=0;
+ if ( $main::lat_min ||
+ $main::lat_max ||
+ $main::lon_min ||
+ $main::lon_max ) {
+ $area_limit=1;
+ }
+
+
+
+
+ my $streets_type_id=0;
+ my @segments;
+ my $line_number = 0;
+ my $sum_points = 0;
+ while ( my $line = $fh->getline() ) {
+ chomp $line;
+ #print "line: $line\n";
+ $line_number++;
+ if ( $line =~ m/^\s*$/) {
+ } elsif ( $line =~ m/^segment\s+(\d+)\s+rank\s+(\d+)\s+points\s+(\d+)/ ) {
+ if ( @segments ) {
+ street_segments_add(
+ { streets_type_id => $streets_type_id,
+ source_id => $source_id,
+ segments => \@segments
+ }
+ );
+ };
+ # Segment: segment 27 rank 1 points 1131
+ ($segment,$rank,$points) = ( $1,$2,$3) ;
+ @segments=();
+ $sum_points += $points;
+ print "Segment: $segment, rank: $rank points: $points \r";
+ print "\n" if $verbose>1;
+ ( $lat1,$lon1 ) = ( $lat2 , $lon2 ) = (0,0);
+
+ # ---------------------- Type
+ my $type_name = "WDB $area $type_string rank $rank";
+ $streets_type_id = streets_type_name2id($type_name);
+ die "Missing Street Type $type_name\n" unless $streets_type_id;
+ } elsif ( $line =~ m/^\s*([\d\.\-]+)\s+([\d\.\-]+)\s*$/ ) {
+ ( $lat1,$lon1 ) = ( $lat2 , $lon2 );
+ ( $lat2,$lon2 ) = ($1,$2);
+ # 31.646111 25.148056
+ if ( $area_limit &&
+ ( $lat2 < $main::lat_min || $lat2 > $main::lat_max ||
+ $lon2 < $main::lon_min || $lon2 > $main::lon_max
+ )
+ ){
+ #print "Skipping $lat2,$lon2\n";
+ next;
+ }
+
+
+ push(@segments,{
+ lat=> $lat2, lon=>$lon2,
+ name => "$rank : $segment : $points"
+ });
+ } else {
+ warn "WDB import: Unrecognized Line $line_number:'$line'\n";
+ }
+ }
+ street_segments_add( {
+ streets_type_id => $streets_type_id,
+ source_id => $source_id,
+ segments => \@segments
+ } );
+
+ print "Read $line_number lines and inserted $sum_points Points\n"
+ if $verbose;
+}
+
+
+
+
+# *****************************************************************************
+sub import_Data($){
+ my $what = shift || "europe,africa,asia,namer,samer";
+
+ my $mirror_dir="$main::MIRROR_DIR/wdb";
+ my $unpack_dir="$main::UNPACK_DIR/wdb";
+
+ print "\nDownload and import CIA World DataBank II for $what\n";
+
+ -d $mirror_dir or mkpath $mirror_dir
+ or die "Cannot create Directory $mirror_dir:$!\n";
+
+ -d $unpack_dir or mkpath $unpack_dir
+ or die "Cannot create Directory $unpack_dir:$!\n";
+
+ my $url = "http://www.evl.uic.edu/pape/data/WDB/WDB-text.tar.gz";
+ my $tar_file = "$mirror_dir/WDB-text.tar.gz";
+ print "Mirror $url\n";
+ my $mirror = mirror_file($url,$tar_file);
+
+ my $dst_file="$unpack_dir/WDB/europe-bdy.txt";
+ if ( (!-s $dst_file) ||
+ file_newer($tar_file,$unpack_dir ) ) {
+ print "Unpacking $tar_file\n";
+ `(cd $unpack_dir/; tar -xvzf $tar_file)`;
+ } else {
+ print "unpack: $dst_file up to date\n" unless $verbose;
+ }
+
+
+ # extract to desired data from the files
+ if ( $what =~ m/^\d/ ) {
+ $what ="europe,africa,asia,namer,samer";
+ }
+
+ disable_keys('streets');
+
+ for my $country ( split(",",$what) ) {
+ if ( $country !~ m/europe|africa|asia|namer|samer/ ) {
+ die ("$country for WDB not supported\n");
+ }
+ debug("$unpack_dir/WDB/*.txt");
+ foreach my $full_filename ( glob("$unpack_dir/WDB/$country*.txt") ) {
+ # print "Mirror: $mirror\n";
+ import_wdb($full_filename);
+ };
+ };
+ enable_keys('streets');
+
+ print "Download an import WDB Data FINISHED\n";
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/Way_Txt.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/Way_Txt.pm
new file mode 100644
index 0000000..b5e0c23
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/Way_Txt.pm
@@ -0,0 +1,188 @@
+# Database Defaults for poi/streets Table for poi.pl
+#
+# $Log$
+# Revision 1.2 2005/10/11 08:28:35 tweety
+# gpsdrive:
+# - add Tracks(MySql) displaying
+# - reindent files modified
+# - Fix setting of Color for Grid
+# - poi Text is different in size depending on Number of POIs shown on
+# screen
+#
+# geoinfo:
+# - get Proxy settings from Environment
+# - create tracks Table in Database and fill it
+# this separates Street Data from Track Data
+# - make geoinfo.pl download also Opengeodb Version 2
+# - add some poi-types
+# - Split off Filling DB with example Data
+# - extract some more Funtionality to Procedures
+# - Add some Example POI for Kirchheim(Munich) Area
+# - Adjust some Output for what is done at the moment
+# - Add more delayed index generations 'disable/enable key'
+# - If LANG=*de_DE* then only impert europe with --all option
+# - WDB will import more than one country if you wish
+# - add more things to be done with the --all option
+#
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.3 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.2 2005/05/14 21:21:23 tweety
+# Update Index createion
+# Update default Streets
+# Eliminate some undefined Value
+#
+# Revision 1.1 2005/05/09 19:35:12 tweety
+# Split Default Values into seperate File
+# Add new Icon
+#
+
+package Geo::Gpsdrive::Way_Txt;
+
+use strict;
+use warnings;
+
+use POSIX qw(strftime);
+use Time::Local;
+use DBI;
+use Geo::Gpsdrive::Utils;
+use Data::Dumper;
+use IO::File;
+use Geo::Gpsdrive::DBFuncs;
+
+$|= 1; # Autoflush
+
+BEGIN {
+ use Exporter ();
+ our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);
+
+ # set the version for version checking
+ $VERSION = 1.00;
+ # if using RCS/CVS, this may be preferred
+ # $VERSION = sprintf "%d.%03d", q$Revision: 1190 $ =~ /(\d+)/g;
+
+ @ISA = qw(Exporter);
+ @EXPORT = qw( );
+ %EXPORT_TAGS = ( );
+ @EXPORT_OK = qw();
+
+}
+#our @EXPORT_OK;
+
+
+# *****************************************************************************
+sub import_Data(){
+
+ print "\nimport Way.txt File(s)\n";
+ Geo::Gpsdrive::DBFuncs::disable_keys('streets');
+
+
+ # Import Points from way*.txt into DB
+
+ my $type2poi_type = {
+ AIRPORT => "transport.public.airport" ,
+ BURGERKING => "food.restaurant.fastfood.burger king" ,
+ CAFE => "food.cafe" ,
+ GASSTATION => "transport.car.gas station" ,
+ GEOCACHE => "recreation.geocache" ,
+ GOLF => "recreation.sports.golf place" ,
+ HOTEL => "accommodation" ,
+ MCDONALDS => "food.restaurant.fastfood.mc donalds" ,
+ MONU => "recreation.landmark" ,
+ NIGHTCLUB => "recreation.night club" ,
+ SHOP => "shopping" ,
+ SPEEDTRAP => "transport.traffic.speedtrap" ,
+ WLAN => "w-lan.open" ,
+ 'WLAN-WEP' => "w-lan.wep" ,
+ 'Automatic_key' => "unknown" ,
+ 'Reiten' => 'recreation.sports.horse.riding',
+ 'FRITZ' => 'custom.friends.home',
+ };
+
+ for my $k ( keys %{$type2poi_type} ) {
+ if ( ! poi_type_name2id($type2poi_type->{$k}) ) {
+ print "Undefined Type for WP-translation $k => $type2poi_type->{$k}\n";
+ } else {
+ #print " Type $k => $type2poi_type->{$k} => ".poi_type_name2id($type2poi_type->{$k})."\n";
+ }
+ }
+
+ for my $file_name ( glob('~/.gpsdrive/way*.txt') ) {
+ my ($file_type ) = ( $file_name =~ m/way[-_]?(.*)\.txt$/);
+ my $default_poi_type = 'unknown';
+ $default_poi_type = $file_type if poi_type_name2id($file_type);
+ $default_poi_type = $type2poi_type->{$file_type} if poi_type_name2id($type2poi_type->{$file_type});
+ print "Default Type: $default_poi_type\n" if $default_poi_type ne "unknown";
+ next if $file_name =~ m,/way-SQLRESULT.txt$,;
+ print "Reading $file_name\n";
+
+ my $source_id = source_name2id("import way.txt");
+
+ my $fh = IO::File->new($file_name);
+ my $count =0;
+ while ( my $line = $fh->getline() ) {
+ # Columns: (wayp + i)->name, slat, slong, typ, wlan, action, sqlnr, proximity
+ my @columns = ('')x10;
+ @columns = split(/\t/,$line);
+ unless ( $columns[0] && $columns[1] && $columns[2]){
+ @columns = split(/\s+/,$line);
+ };
+ next unless $columns[0] && $columns[1] && $columns[2];
+ $columns[0] =~ s/'/\\'/g;
+ my $type = "unknown";
+ $type = $columns[3];
+ $type ||= $default_poi_type;
+ $type = $default_poi_type if $type eq"-";
+ my $wep = 0;
+ $wep ='1' if $type eq "WLAN-WEP";
+ $type = "WLAN" if $columns[0] =~ m/\d\d\:\d\d\:\d\d\:\d\d\:\d\d\:\d\d/;
+
+ my $poi_type_id = poi_type_name2id($type2poi_type->{"$type"});
+ $poi_type_id ||= poi_type_name2id("$type");
+ $poi_type_id || printf "Unknown Waypoint Type '$type' in $line\n";
+ $poi_type_id ||= poi_type_name2id("import way.txt");
+
+ for my $t ( qw(waypoints poi)) {
+ my $wp = { "waypoints.wep" => 0 ,
+ "waypoints.nettype" => '',
+ "waypoints.type" => 'import_way.txt',
+ "poi.poi_type_id" => $poi_type_id,
+ "poi.source_id" => $source_id,
+ "poi.scale_min" => 1,
+ "poi.scale_max" => 100000,
+ "poi.last_modified" => localtime(time()),
+ "$t.name" => $columns[0],
+ "$t.lat" => $columns[1],
+ "$t.lon" => $columns[2],
+ "$t.proximity" => $columns[7],
+ "$t.type" => $type,
+ "$t.wep" => $wep,
+ };
+
+ Geo::Gpsdrive::DBFuncs::db_exec("DELETE FROM $t ".
+ "WHERE $t.name = '$columns[0]' ".
+ "AND $t.lat = '$columns[1]' ".
+ "AND $t.lon = '$columns[2]' ");
+
+ Geo::Gpsdrive::DBFuncs::insert_hash($t, $wp );
+ }
+ $count++;
+ }
+ $fh->close();
+ print "Inserted $count Entries from $file_name\n";
+ }
+
+ Geo::Gpsdrive::DBFuncs::enable_keys('streets');
+ print "import Way.txt File(s) FINISHED\n";
+}
+
+
+
+
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/census.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/census.pm
new file mode 100644
index 0000000..e5aa2f9
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/census.pm
@@ -0,0 +1,86 @@
+# Read Data from US Census Bureau and import into geoinfo DB
+#
+# $Log$
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.3 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.2 2005/04/10 00:15:58 tweety
+# changed primary language for poi-type generation to english
+# added translation for POI-types
+# added some icons classifications to poi-types
+# added LOG: Entry for CVS to some *.pm Files
+#
+
+package Geo::Gpsdrive::census;
+
+use strict;
+use warnings;
+
+use IO::File;
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+
+########################################################################################
+# Get and Unpack Census Data
+# http://www.census.gov/geo/cob/bdy/
+########################################################################################
+sub import_Data() {
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+ print "Census Download Not working yet.\n";
+ print "Skipping \n";
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+ print "=============================================================================\n";
+}
+if ( 0 ) {
+ my $CENSUS_DIR = "$main::CONFIG_DIR/MIRROR/CENSUS";
+
+ unless ( -d $CENSUS_DIR ) {
+ print "Creating Directory $CENSUS_DIR\n";
+ mkpath $CENSUS_DIR
+ or die "Cannot create Directory $CENSUS_DIR:$!\n";
+ }
+
+ `wget --mirror --directory-prefix= --no-host-directories --include-directories=geo/cob/bdy --force-directories --level=2 http://www.census.gov/geo/cob/bdy/ --accept=zip,html -nv -D$CENSUS_DIR`;
+
+ # download
+ for my $state ( qw( aia/ an/ bg/ cc/ cd/ co/
+ cs/ dv/ econ/ ir/ ma/ mcd/
+ na/ ne/ ou/ pl/ pu/ rg/
+ sb/ se/ sl/ sn/ ss/ st/
+ su/ tb/ tr/ ts/ tt/ tz/
+ ua/ vt/ zt/
+ 90_data/
+ scripts/
+ )) {
+# for my $type ( qw( 00ascii/ 00e00/ 00shp/ ) ) {
+ my $mirror = mirror_file("http://www.census.gov/geo/cob/bdy/".
+ "$state/${state}00ascii/${state}99_d00ascii.zip",
+ "$CENSUS_DIR/${state}99_d00ascii.zip");
+
+ print "Mirror: $mirror\n";
+ if ( $mirror ) {
+ # Unpack it
+ `(cd $CENSUS_DIR/; unzip -o xy.zip)`;
+
+ for my $file_name ( glob("$CENSUS_DIR/pocketgps_*.csv") ) {
+ my ( $type ) = ($file_name =~ m/pocketgps_(.*)\.csv/);
+ my $out_file_name = "/home/gpsdrive/way_pocketgps_$type.txt";
+ my $waypoints = read_speedstrap_wp($file_name,$type);
+ write_gpsdrive_waypoints($waypoints,$out_file_name);
+ write_mapsource_waypoints($waypoints,"way_pocketgps_$type.txt");
+ }
+ }
+ }
+}
+
+
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/getstreet.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/getstreet.pm
new file mode 100644
index 0000000..1f248a9
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/getstreet.pm
@@ -0,0 +1,276 @@
+package Geo::Gpsdrive::getstreet;
+#noch nicht alle variablen angepasst
+use LWP::UserAgent;
+use WWW::Mechanize;
+use Text::Query;
+use Getopt::Long; #maybe not needed any more
+use Pod::Usage;
+use DBI;
+use strict;
+#use Thread;
+use threads;
+ my %hash;
+ my @header;
+ my @lines;
+ my @rows;
+ my $x; #counter
+ my $use_street;
+ my $use_city;
+ our $street = $main::street; #not needed
+ our $use_zip = $main::plz;
+ our $ort = $main::ort; #not needed
+ our $mysql =$main::sql;
+ our $file = $main::file;
+ our $country;
+ our $version;
+ our $area; # dont work at the moment not changed since moved form .pl to .pm
+ our $scale; # dont work
+ our $name;
+ our @street;
+ our $type="STREET";
+ our $comment="";
+ our $help;
+ our $VER="getstreet (c) SHB\nInitial Version (Mar,2005) by SHB\n";
+sub streets(){
+# 'nname=s' => \$name,
+# 'n=s' => \$name,
+# 'country=s' => \$country,
+# 'c=s' => \$country,
+# 'f=s' => \$file,
+# 'file=s' => \$file,
+# 'scale=s' => \$scale,
+# 'a=s' => \$area,
+# 'type=s' => \$type,
+# 't=s' => \$type,
+# 'comment=s' => \$comment,
+
+ if($help){
+ print "\n\nHelp\n\n";
+
+ print "Usage:\n";
+ print "Usage getstreet.pl\n";
+ print "-p, --plz\t zipcode\n";
+ print "-o, --ort\t country\n";
+ print "-s, --street \t\t\"name of street\"\n";
+ print "-f, --file\t\t name of a file instat a streetname";
+ print "\n\n";
+ print "optional parameters:\n";
+ print "-a Umkreis --scale scale\n";
+ print "-t, --type\ttype \n";
+ print "--sql insert query in the mysql database\n";
+ print "optional sql parameters:\n";
+ print "\t --comment \t insert a comment into the database";
+ print "\n\n";
+ print "-h, --help \tshow this display and exit the programm\n";
+ print "-v, --version show the version\n ";
+ print "At the moment only germany is supportet\n\n";
+ print "note these script is beta\n\n";
+ }
+ if($country eq "help"){
+ #needed for other country than germany, not working at the moment
+ print "List of countrys:\n\n";
+ print "Australien : 22\n";
+ print "Belgien : 1\n";
+ print "Brasilien : 23\n";
+ print "Dänemark : 3\n";
+ print "Deutschland : 5\n";
+ print "Finnland (Helsinki) : 16\n";
+ print "Frankreich : 4\n";
+ print "Griechenland (Athen) : 24\n";
+ print "Großbritannien : 11\n";
+ print "Italien : 6\n";
+ print "Kanada : 2\n";
+ print "Luxemburg : 7\n";
+ print "Niederlande : 8\n";
+ print "Norwegen : 17\n";
+ print "Österreich : 0\n";
+ print "Portugal : 18\n";
+ print "Schweden : 19\n";
+ print "Schweiz : 10\n";
+ print "Spanien : 9\n";
+ print "Vereinigte Staaten : 12\n";
+ print "\n\n";
+ }
+if($main::street && $main::ort){
+ $use_street = $main::street;
+ $use_city = $main::ort;
+ $use_zip = $main::plz;
+ if($main::thread){
+ print "using threads\n";
+ my $thread = threads->new( \&getstreet );
+ $thread->join;
+ }else{
+ &getstreet;
+ }
+}
+ if($main::file){
+ open(FILE, "< file");
+ while( <FILE>){
+ $_ =~ s/\n//g; #maybe delete if errors in the array, but i dont think so
+ push(@street,$_);
+ }
+ close(FILE);
+ my $sum_str =@street;
+ if($street[0] =~ /^<.*>$/){
+ $street[0] =~ s/\<//g; # remove this <
+ $street[0] =~ s/\>//g; #remove this >
+ #$street[0] =~ s/\n//g; #not need if $_ =~ s/\n//g; work
+ @header = split(/;/,$street[0]);
+ my $a=0;
+ my $sum_header = @header;
+ for(@header){
+ my $y=0;
+ $x = 1;
+ while($y<$sum_str){
+ @lines = split(/;/,$street[$x]);
+ ## print "$lines[$a]";##
+ # if( $street[$x] !~ /^#/){
+ $rows[$y] = $lines[$a];
+ # }
+ $x++;
+ $y++;
+ }
+ $a++;
+ # print "Hash $_ Erstellt\n"; #can remove, only for showing which hashs are createt###
+ $hash{$_} = [@rows];
+
+ }
+ if(!$hash{street}){
+ print STDERR "a <street> section is needed in the \$file \n"; #\$file must be changed in $main::file
+ exit 2;
+ }
+ if(!$hash{city}){
+ print STDERR "a <city> section is needet in the \$file \n";
+ exit 3;
+ }
+ if(!$hash{zip}){
+ print STDERR "<zip> don't exitsts, this doesent matter, but maybe you will need it\n";
+ }
+# print "@header\n"; #not needed remove, only for testing
+ #print "test hash print: $hash{city}[1]\n";
+ }
+ else
+ {
+ print " file has wrong format\n"; #\$file musst be changed in main::file #give an example for the file
+ exit 4;
+ }
+
+ $x=0;
+ my @Threads;
+ my $hash_length=@{$hash{street}};
+# print $hash_length;
+ my $time =0;
+ for(0..$hash_length){
+ $use_street=$hash{street}[$x];
+ $use_city=$hash{city}[$x];
+ $use_zip=$hash{zip}[$x];
+ if($use_city eq ""){
+ $use_city = $hash{city}[$x-1];
+ $hash{city}[$x]=$hash{city}[$x-1];
+ }
+ if($use_zip eq ""){
+ $use_zip = $hash{zip}[$x-1];
+ $hash{zip}[$x]=$hash{zip}[$x-1];
+ }
+
+ if($main::thread){
+# print "using threads\n";
+ push(@Threads,threads->new(\&getstreet));
+ $time++;
+ if($time>=9){
+ sleep 30;
+ $time=0;
+ }
+ }else{
+ &getstreet;
+ }
+ $x++;
+ }
+ if($main::thread){
+ foreach(@Threads)
+ {
+ $_->join();
+ # $_->detach();
+ }
+ }
+ }
+ return 1;
+}
+sub getstreet {
+ print "$use_street|$use_city|$use_zip\n"; #needed for testing ;)
+ my $url="http://mappoint.msn.de";
+ my $val = "MapForm:POIText";
+ my $v_ort = $use_city;
+ my $v_plz = $use_zip;
+ my $v_str = $use_street ; # erinerung
+ $v_str =~ s/ü/u/g;
+ $v_str =~ s/ö/o/g;
+ $v_str =~ s/ä/a/g;
+ $v_str =~ s/Ü/U/g;
+ $v_str =~ s/Ö/O/g;
+ $v_str =~ s/Ä/Ä/g;
+ $v_str =~ s/ß/ss/g;
+ my $ort = "FndControl:CityText";
+ my $plz = "FndControl:ZipText";
+ my $str = "FndControl:StreetText";
+ my $cou = "FndControl:ARegionSelect";
+ my $form = "FindForm";
+ my $mech= WWW::Mechanize->new();
+ $mech->agent_alias( 'Windows IE 6' );
+ $mech->get($url);
+ $mech->form_name($form);
+ ##
+ $mech->field($ort,$v_ort);
+ $mech->field($plz,$v_plz);
+ $mech->field($str,$v_str);
+ $mech->submit();
+ if($mech->form_name('MCForm')){
+ $mech->form_name('MCForm');
+ my $out= $mech->value($val);
+ my @split=split(/\|/,$out);
+ my @cord=split("%2c",$split[1]);
+ my @addr=split("%2c",$split[3]);
+ my $str=$addr[0];
+ my @ort_plz=split(/\+/,$addr[1]);
+ $ort=$ort_plz[2]; #unused
+ $plz=$ort_plz[1]; #unused
+ $str =~ s/%c3%9f/ss/g;
+ $str =~ s/%c3%bc/ue/g;
+ $str =~ s/\+/\_/g;
+ if($str eq ""){
+ print "$str\n";
+ print "$out\n";
+ print "Strasse nicht gefunden\n";
+ }else{
+ print STDERR "$out\n";
+ if($name ne ""){
+ $str=$name;
+ }
+ my $ausgabe= "$str\t$cord[0]\t$cord[1]\t$main::type\n";
+ my $datei = "$ENV{'HOME'}/.gpsdrive/way.txt";
+ if($main::sql){
+ $comment = $split[3];
+ print "comment: $comment\n";
+ my $dbh = DBI->connect( "dbi:mysql:$main::GPSDRIVE_DB_NAME", $main::db_user, $main::db_password )
+ || die "Kann keine Verbindung zum MySQL-Server aufbauen: $DBI::errstr\n";
+ my $query ="insert into waypoints(name,lat,lon,type,comment) values('$str','$cord[0]','$cord[1]','$type','$comment')";
+ $dbh->prepare($query)->execute;
+ }else{
+ open(FILE,">>$datei")||die "Error: File not found\n";
+ }
+ print FILE $ausgabe;
+ close(FILE);
+ if($area && $scale){
+ system("gpsfetchmap.pl -w $str -a $area --scale $scale");
+ }
+ }
+ }elsif($mech->form_name('FindForm')){
+ #this will happen, if you get a multiple choice answer
+ #print $mech->value('FndControl:AmbiguousSelect');
+ # print "\n";
+ print "Multiplie choice \nstill in development\n";
+
+ }
+ }
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/gettraffic.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/gettraffic.pm
new file mode 100644
index 0000000..548cd3c
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/gettraffic.pm
@@ -0,0 +1,90 @@
+# Database Defaults for poi/streets Table for poi.pl
+#
+# $Log$
+# Revision 1.2 2006/04/20 22:41:05 tweety
+# make database name variable
+# import osm POI too
+# add colog_bg, width, width_bg to db layout
+#
+# Revision 1.1 2006/02/01 18:08:01 tweety
+# 2 new features by Stefan Wolf
+#
+
+package Geo::Gpsdrive::gettraffic;
+
+use strict;
+use warnings;
+
+use DBI;
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+
+use WWW::Mechanize;
+
+sub gettraffic(){
+ my $url ="http://gpsdrive.blue-stripes.de/verkehr.php";
+ my $mech= WWW::Mechanize->new();
+ $mech->agent_alias( 'Windows IE 6' );
+ $mech->get($url);
+ my $source =$mech->content(); #open website $url which create the verkehr.bz2
+ $url ="http://gpsdrive.blue-stripes.de/verkehr.bz2";
+ $mech->get($url);
+ $source = $mech->content(); #download verker.bz2
+ my $datei = "$ENV{'HOME'}/.gpsdrive/traffic.bz2"; #this shoud be better with Compress::Bzip2
+ open(FILE,">$datei")
+ || die "Error: File not found\n";
+ print FILE $source;
+ close(FILE);
+
+ # Entpacken und einlesen
+ system("bzip2 -f -d $datei");
+ $datei = "$ENV{'HOME'}/.gpsdrive/traffic";
+ open(FILE,"<$datei")
+ || die "Error: File not found";
+ my @file = <FILE>;
+ close(FILE);
+
+ system("rm -f $datei");
+ my $x =0;
+ my @data;
+ my $dbh = DBI->connect( "dbi:mysql:$main::GPSDRIVE_DB_NAME", $main::db_user, $main::db_password )
+ || die "Kann keine Verbindung zum MySQL-Server aufbauen: $DBI::errstr\n";
+
+ #clear table
+ my $query = "delete from traffic";
+ $dbh->prepare($query)->execute;
+
+ for my $line ( @file ){
+ chomp($line);
+ @data = split(";",$line);
+ debug("insert $line");
+ $query = "insert into traffic(status,street,descshort,desclong,future,time)".
+ "values('$data[0]','$data[1]','$data[2]','$data[3]','$data[4]','$data[5]')";
+ $dbh->prepare($query)->execute;
+ }
+ return 1;
+}
+sub showtraffic(){
+ #nur Autobahnen und Bundesstraßen raussuchen
+ my $query = "select status,street,descshort,desclong from traffic where street like 'A%' or street like 'B%'";
+
+ my $dbh = DBI->connect( "dbi:mysql:$main::GPSDRIVE_DB_NAME", $main::db_user, $main::db_password )
+ || die "Kann keine Verbindung zum MySQL-Server aufbauen: $DBI::errstr\n";
+ my $sth = $dbh->prepare( $query );
+ $sth->execute();
+ my( $status, $street, $descshort, $desclong );
+ $sth->bind_columns( undef, \$status, \$street, \$descshort, \$desclong );
+
+ while( $sth->fetch() ) {
+ if (!$status ){$status = "Unknown"}
+ elsif ($status == 1){$status = "Stau"}
+ elsif ($status == 2){$status = "Bauarbeiten"}
+ elsif ($status == 3){$status = "Gesperrt"}
+ elsif ($status == 4){$status = "Achtung"}
+ elsif ($status == 5){$status = "Aufgehoben"}
+ elsif ($status == 6){$status = "Unbekannt"};
+ printf "%-5s %-12s %s\n\t\t\t%s\n"
+ ,$street,$status,$descshort,$desclong;
+ }
+}
+1;
diff --git a/scripts/osm/perl_lib/Geo/Gpsdrive/mapsource.pm b/scripts/osm/perl_lib/Geo/Gpsdrive/mapsource.pm
new file mode 100644
index 0000000..7b973c5
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Gpsdrive/mapsource.pm
@@ -0,0 +1,99 @@
+# Read waypoints from Mapsource Data exported as txt
+# and import into geoinfo.poi
+#
+# $Log$
+# Revision 1.1 2005/08/15 13:54:22 tweety
+# move scripts/POI --> scripts/Geo/Gpsdrive to reflect final Structure and make debugging easier
+#
+# Revision 1.4 2005/08/09 01:08:30 tweety
+# Twist and bend in the Makefiles to install the DataDirectory more apropriate
+# move the perl Functions to Geo::Gpsdrive in /usr/share/perl5/Geo/Gpsdrive/POI
+# adapt icons.txt loading according to these directories
+#
+# Revision 1.3 2005/04/13 19:58:30 tweety
+# renew indentation to 4 spaces + tabstop=8
+#
+# Revision 1.2 2005/04/10 20:47:49 tweety
+# added src/speech_out.h
+# update configure and po Files
+#
+
+package Geo::Gpsdrive::mapsource;
+
+use strict;
+use warnings;
+
+use IO::File;
+use Geo::Gpsdrive::DBFuncs;
+use Geo::Gpsdrive::Utils;
+
+#############################################################################
+# Args:
+# $filename : Filename to read
+# RETURNS:
+# $waypoints : Has of read Waypoints
+#############################################################################
+sub read_mapsource_waypoints($){
+ my $full_filename = shift;
+
+ my $waypoints={};
+
+ print "Reading: $full_filename\n";
+
+ my $fh = IO::File->new("<$full_filename");
+ $fh or die ("read_mapsource_waypoints: Cannot open $full_filename:$!\n");
+ my @columns;
+
+ my $lines_count_file =0;
+ while ( my $line = $fh->getline() ) {
+ $lines_count_file ++;
+ $line =~ s/[\t\r\n\s]*$//g;;
+ # print "line: '$line'\n";
+ if ($line =~ m/^Grid\s+Breite\/L.nge / ) {
+ } elsif ( $line =~ m/^$/ ) {
+ } elsif ( $line =~ m/^Datum\s+WGS 84/ ) {
+ } elsif ( $line =~ m/^Header/ ) {
+ @columns = split(/\s+/,$line);
+ #print Dumper(\@columns);
+ } elsif ( $line =~ m/^Waypoint\s+/ ) {
+ die "Spalten nicht definiert" unless @columns;
+
+# print "WP: $line\n";
+ my @values = split(/\t/,$line);
+ #print Dumper(\@values);
+ my $values;
+ for my $i ( 0 .. scalar @columns -1 ) {
+ $values->{$columns[$i]} = $values[$i];
+ }
+
+ ############################################
+ ############################################
+ # Set Default Proximity to 800m
+ $values->{'Proximity'} ||= "800 m";
+
+
+ $values->{Symbol} ||= "";
+
+ ( $values->{lat},$values->{lon}) = split(/\s+/,$values->{'Position'});
+
+ ############################################
+ correct_lat_lon($values);
+
+ #print Dumper($values) if defined $values->{'Proximity'};
+ my $wp_name = $values->{'Name'};
+ $waypoints->{$wp_name} = $values;
+ } else {
+ print "Unknown Line: '$line'\n";
+ }
+
+ }
+ return $waypoints;
+}
+
+sub Geo::Gpsdrive::mapsource::import_DB
+{
+ my $waypoints = read_mapsource_waypoints($do_mapsource_points);
+ db_add_waypoints($waypoints);
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/OSM/APIClientV4.pm b/scripts/osm/perl_lib/Geo/OSM/APIClientV4.pm
new file mode 100644
index 0000000..41a92a7
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/APIClientV4.pm
@@ -0,0 +1,226 @@
+##################################################################
+## APIClientV4.pm - General Perl client for the API ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Currently only supports uploading. Note the package actually ##
+## creates a package named Geo::OSM::APIClient so upgrades to ##
+## later versions will be easier. ##
+## Licence: LGPL ##
+##################################################################
+
+use LWP::UserAgent;
+use strict;
+
+package Geo::OSM::APIClient;
+use Geo::OSM::OsmReaderV3;
+use MIME::Base64;
+use HTTP::Request;
+use Carp;
+use Encode;
+use POSIX qw(sigprocmask);
+
+sub new
+{
+ my( $class, %attr ) = @_;
+
+ my $obj = bless {}, $class;
+
+ my $url = $attr{api};
+ if( not defined $url )
+ {
+ croak "Did not specify aip url";
+ }
+
+ $url =~ s,/$,,; # Strip trailing slash
+ $obj->{url} = $url;
+ $obj->{client} = new LWP::UserAgent(agent => 'Geo::OSM::APIClientV4');
+
+ if( defined $attr{username} and defined $attr{password} )
+ {
+ if( $obj->{url} =~ m,http://([\w.]+)/, )
+ {
+ $obj->{client}->credentials( "$1:80", "Web Password", $attr{username}, $attr{password} );
+ }
+ my $encoded = MIME::Base64::encode_base64("$attr{username}:$attr{password}","");
+ $obj->{client}->default_header( "Authorization", "Basic $encoded" );
+ }
+
+ $obj->{reader} = init Geo::OSM::OsmReader( sub { _process($obj,@_) } );
+ return $obj;
+}
+
+# This is the callback from the parser. If checks if the buffer is defined.
+# If the buffer is an array, append the new object. If the buffer is a proc,
+# call it.
+sub _process
+{
+ my($obj,$ent) = @_;
+ if( not defined $obj->{buffer} )
+ { die "Internal error: Received object with buffer" }
+ if( ref $obj->{buffer} eq "ARRAY" )
+ { push @{$obj->{buffer}}, $ent; return }
+ if( ref $obj->{buffer} eq "CODE" )
+ { $obj->{buffer}->($ent); return }
+ die "Internal error: don't know what to do with buffer $obj->{buffer}";
+}
+
+# Utility function to handle the temporary blocking of signals in a way that
+# works with exception handling.
+sub _with_blocked_sigs(&)
+{
+ my $ss = new POSIX::SigSet( &POSIX::SIGINT );
+ my $func = shift;
+ my $os = new POSIX::SigSet;
+ sigprocmask( &POSIX::SIG_BLOCK, $ss, $os );
+ my $ret = eval { &$func };
+ sigprocmask( &POSIX::SIG_SETMASK, $os );
+ die $@ if $@;
+ return $ret;
+}
+
+sub _request
+{
+ my $self = shift;
+ my $req = shift;
+ return _with_blocked_sigs { $self->{client}->request($req) };
+}
+
+sub last_error_code
+{
+ return shift->{last_error}->code;
+}
+
+sub last_error_message
+{
+ return shift->{last_error}->message;
+}
+
+sub create
+{
+ my( $self, $ent ) = @_;
+ my $oldid = $ent->id;
+ $ent->set_id(0);
+ my $content = encode("utf-8", $ent->full_xml);
+ $ent->set_id($oldid);
+ my $req = new HTTP::Request PUT => $self->{url}."/".$ent->type()."/create";
+ $req->content($content);
+
+# print $req->as_string;
+
+ my $res = $self->_request($req);
+
+# print $res->as_string;
+
+ if( $res->code == 200 )
+ {
+ return $res->content
+ }
+
+ $self->{last_error} = $res;
+ return undef;
+}
+
+sub modify
+{
+ my( $self, $ent ) = @_;
+ my $content = encode("utf-8", $ent->full_xml);
+ my $req = new HTTP::Request PUT => $self->{url}."/".$ent->type()."/".$ent->id();
+ $req->content($content);
+
+# print $req->as_string;
+
+ my $res = $self->_request($req);
+
+ return $ent->id() if $res->code == 200;
+ $self->{last_error} = $res;
+ return undef;
+}
+
+sub delete
+{
+ my( $self, $ent ) = @_;
+ my $content = encode("utf-8", $ent->full_xml);
+ my $req = new HTTP::Request DELETE => $self->{url}."/".$ent->type()."/".$ent->id();
+# $req->content($content);
+
+# print $req->as_string;
+
+ my $res = $self->_request($req);
+
+ return $ent->id() if $res->code == 200;
+ $self->{last_error} = $res;
+ return undef;
+}
+
+sub get($$)
+{
+ my $self = shift;
+ my $type = shift;
+ my $id = shift;
+
+ my $req = new HTTP::Request GET => $self->{url}."/$type/$id";
+
+ my $res = $self->_request($req);
+
+ if( $res->code != 200 )
+ {
+ $self->{last_error} = $res;
+ return undef;
+ }
+
+ my @res;
+ $self->{buffer} = \@res;
+ $self->{reader}->parse($res->content);
+ undef $self->{buffer};
+ if( scalar(@res) != 1 )
+ {
+ die "Unexpected response for get_$type [".$res->content()."]\n";
+ }
+
+ return $res[0];
+}
+
+sub get_node($)
+{
+ my $self = shift;
+ return $self->get("node",shift);
+}
+
+sub get_way($)
+{
+ my $self = shift;
+ return $self->get("way",shift);
+}
+
+sub get_segment($)
+{
+ my $self = shift;
+ return $self->get("segment",shift);
+}
+
+
+sub map($$$$)
+{
+ my $self = shift;
+ my @bbox = @_;
+
+ my $req = new HTTP::Request GET => $self->{url}."/map?bbox=$bbox[0],$bbox[1],$bbox[2],$bbox[3]";
+
+ my $res = $self->_request($req);
+
+ if( $res->code != 200 )
+ {
+ $self->{last_error} = $res;
+ return undef;
+ }
+
+ my @res;
+ $self->{buffer} = \@res;
+ $self->{reader}->parse($res->content);
+ undef $self->{buffer};
+
+ return \@res;
+}
+
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/OSM/APIClientV5.pm b/scripts/osm/perl_lib/Geo/OSM/APIClientV5.pm
new file mode 100644
index 0000000..db941b8
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/APIClientV5.pm
@@ -0,0 +1,221 @@
+##################################################################
+## APIClientV5.pm - General Perl client for the API ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Currently only supports uploading. Note the package actually ##
+## creates a package named Geo::OSM::APIClient so upgrades to ##
+## later versions will be easier. ##
+## Licence: LGPL ##
+##################################################################
+
+use LWP::UserAgent;
+use strict;
+
+package Geo::OSM::APIClient;
+use Geo::OSM::OsmReaderV5;
+use MIME::Base64;
+use HTTP::Request;
+use Carp;
+use Encode;
+use POSIX qw(sigprocmask);
+
+sub new
+{
+ my( $class, %attr ) = @_;
+
+ my $obj = bless {}, $class;
+
+ my $url = $attr{api};
+ if( not defined $url )
+ {
+ croak "Did not specify api url";
+ }
+
+ $url =~ s,/$,,; # Strip trailing slash
+ $obj->{url} = $url;
+ $obj->{client} = new LWP::UserAgent(agent => 'Geo::OSM::APIClientV5');
+
+ if( defined $attr{username} and defined $attr{password} )
+ {
+ my $encoded = MIME::Base64::encode_base64("$attr{username}:$attr{password}","");
+ $obj->{client}->default_header( "Authorization", "Basic $encoded" );
+ }
+
+ $obj->{reader} = init Geo::OSM::OsmReader( sub { _process($obj,@_) } );
+ return $obj;
+}
+
+# This is the callback from the parser. If checks if the buffer is defined.
+# If the buffer is an array, append the new object. If the buffer is a proc,
+# call it.
+sub _process
+{
+ my($obj,$ent) = @_;
+ if( not defined $obj->{buffer} )
+ { die "Internal error: Received object with buffer" }
+ if( ref $obj->{buffer} eq "ARRAY" )
+ { push @{$obj->{buffer}}, $ent; return }
+ if( ref $obj->{buffer} eq "CODE" )
+ { $obj->{buffer}->($ent); return }
+ die "Internal error: don't know what to do with buffer $obj->{buffer}";
+}
+
+# Utility function to handle the temporary blocking of signals in a way that
+# works with exception handling.
+sub _with_blocked_sigs(&)
+{
+ my $ss = new POSIX::SigSet( &POSIX::SIGINT );
+ my $func = shift;
+ my $os = new POSIX::SigSet;
+ sigprocmask( &POSIX::SIG_BLOCK, $ss, $os );
+ my $ret = eval { &$func };
+ sigprocmask( &POSIX::SIG_SETMASK, $os );
+ die $@ if $@;
+ return $ret;
+}
+
+sub _request
+{
+ my $self = shift;
+ my $req = shift;
+ return _with_blocked_sigs { $self->{client}->request($req) };
+}
+
+sub last_error_code
+{
+ return shift->{last_error}->code;
+}
+
+sub last_error_message
+{
+ return shift->{last_error}->message;
+}
+
+sub create($)
+{
+ my( $self, $ent ) = @_;
+ my $oldid = $ent->id;
+ $ent->set_id(0);
+ my $content = encode("utf-8", $ent->full_xml);
+ $ent->set_id($oldid);
+ my $req = new HTTP::Request PUT => $self->{url}."/".$ent->type()."/create";
+ $req->content($content);
+
+# print $req->as_string;
+
+ my $res = $self->_request($req);
+
+# print $res->as_string;
+
+ if( $res->code == 200 )
+ {
+ return $res->content
+ }
+
+ $self->{last_error} = $res;
+ return undef;
+}
+
+sub modify($)
+{
+ my( $self, $ent ) = @_;
+ my $content = encode("utf-8", $ent->full_xml);
+ my $req = new HTTP::Request PUT => $self->{url}."/".$ent->type()."/".$ent->id();
+ $req->content($content);
+
+# print $req->as_string;
+
+ my $res = $self->_request($req);
+
+ return $ent->id() if $res->code == 200;
+ $self->{last_error} = $res;
+ return undef;
+}
+
+sub delete($)
+{
+ my( $self, $ent ) = @_;
+ my $content = encode("utf-8", $ent->full_xml);
+ my $req = new HTTP::Request DELETE => $self->{url}."/".$ent->type()."/".$ent->id();
+# $req->content($content);
+
+# print $req->as_string;
+
+ my $res = $self->_request($req);
+
+ return $ent->id() if $res->code == 200;
+ $self->{last_error} = $res;
+ return undef;
+}
+
+sub get($$)
+{
+ my $self = shift;
+ my $type = shift;
+ my $id = shift;
+
+ my $req = new HTTP::Request GET => $self->{url}."/$type/$id";
+
+ my $res = $self->_request($req);
+
+ if( $res->code != 200 )
+ {
+ $self->{last_error} = $res;
+ return undef;
+ }
+
+ my @res;
+ $self->{buffer} = \@res;
+ $self->{reader}->parse($res->content);
+ undef $self->{buffer};
+ if( scalar(@res) != 1 )
+ {
+ die "Unexpected response for get_$type [".$res->content()."]\n";
+ }
+
+ return $res[0];
+}
+
+sub get_node($)
+{
+ my $self = shift;
+ return $self->get("node",shift);
+}
+
+sub get_way($)
+{
+ my $self = shift;
+ return $self->get("way",shift);
+}
+
+sub get_relation($)
+{
+ my $self = shift;
+ return $self->get("relation",shift);
+}
+
+
+sub map($$$$)
+{
+ my $self = shift;
+ my @bbox = @_;
+
+ my $req = new HTTP::Request GET => $self->{url}."/map?bbox=$bbox[0],$bbox[1],$bbox[2],$bbox[3]";
+
+ my $res = $self->_request($req);
+
+ if( $res->code != 200 )
+ {
+ $self->{last_error} = $res;
+ return undef;
+ }
+
+ my @res;
+ $self->{buffer} = \@res;
+ $self->{reader}->parse($res->content);
+ undef $self->{buffer};
+
+ return \@res;
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/OSM/EntitiesV3.pm b/scripts/osm/perl_lib/Geo/OSM/EntitiesV3.pm
new file mode 100644
index 0000000..2708463
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/EntitiesV3.pm
@@ -0,0 +1,296 @@
+##################################################################
+## EntitiesV3.pm - Wraps entities used by OSM ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Package that wraps the entities used by OSM into Perl ##
+## object, so they can be easily manipulated by various ##
+## packages. ##
+## ##
+## Licence: LGPL ##
+##################################################################
+
+use XML::Writer;
+use strict;
+
+############################################################################
+## Top level Entity type, parent of all types, includes stuff relating to ##
+## tags and IDs which are shared by all entity types ##
+############################################################################
+package Geo::OSM::Entity;
+use POSIX qw(strftime);
+
+use Carp;
+
+sub _new
+{
+ bless {}, shift;
+}
+
+sub _get_writer
+{
+ my($self,$res) = @_;
+ return new XML::Writer(OUTPUT => $res, NEWLINES => 0, ENCODING => 'utf-8');
+}
+
+sub add_tag
+{
+ my($self, $k,$v) = @_;
+ push @{$self->{tags}}, $k, $v;
+}
+
+sub add_tags
+{
+ my($self, @tags) = @_;
+ if( scalar(@tags)&1 )
+ { croak "add_tags requires an even number of arguments" }
+ push @{$self->{tags}}, @tags;
+}
+
+sub set_tags
+{
+ my($self,$tags) = @_;
+ if( ref($tags) eq "HASH" )
+ { $self->{tags} = [%$tags] }
+ elsif( ref($tags) eq "ARRAY" )
+ { $self->{tags} = [@$tags] }
+ else
+ { croak "set_tags must be HASH or ARRAY" }
+}
+
+sub tags
+{
+ my $self = shift;
+ return [@{$self->{tags}}]; # Return copy
+}
+
+sub tag_xml
+{
+ my ($self,$writer) = @_;
+ my @a = @{$self->{tags}};
+
+ my $str = "";
+
+ while( my($k,$v) = splice @a, 0, 2 )
+ {
+ $writer->emptyTag( "tag", 'k' => $k, 'v' => $v );
+ }
+}
+
+our $_ID = -1;
+
+sub set_id
+{
+ my($self,$id) = @_;
+
+ if( not defined $id )
+ { $id = $_ID-- }
+ $self->{id} = $id;
+}
+
+sub id
+{
+ my $self = shift;
+ return $self->{id};
+}
+
+sub set_timestamp
+{
+ my($self,$time) = @_;
+ if( defined $time )
+ { $self->{timestamp} = $time }
+ else
+ { $self->{timestamp} = strftime "%Y-%m-%dT%H:%M:%S+00:00", gmtime(time) }
+}
+
+sub timestamp
+{
+ my $self = shift;
+ return $self->{timestamp};
+}
+
+sub full_xml
+{
+ my $self = shift;
+ return qq(<?xml version="1.0"?>\n<osm version="0.4">\n).$self->xml()."</osm>\n";
+}
+
+package Geo::OSM::Way;
+our @ISA = qw(Geo::OSM::Entity);
+
+sub new
+{
+ my($class, $attr, $tags, $segs) = @_;
+
+ my $obj = bless $class->SUPER::_new(), $class;
+
+ $obj->set_tags($tags);
+ $obj->set_segs($segs);
+ $obj->set_id($attr->{id} );
+ $obj->set_timestamp( $attr->{timestamp} );
+
+ return $obj;
+}
+
+sub type { return "way" }
+
+sub set_segs
+{
+ my($self,$segs) = @_;
+ $self->{segs} = $segs;
+}
+
+sub segs
+{
+ my $self = shift;
+ return [@{$self->{segs}}]; # Return a copy
+}
+
+sub xml
+{
+ my $self = shift;
+ my $str = "";
+ my $writer = $self->_get_writer(\$str);
+
+ $writer->startTag( "way", id => $self->id, timestamp => $self->timestamp );
+ $self->tag_xml( $writer );
+ for my $seg (@{$self->segs})
+ {
+ $writer->emptyTag( "seg", id => $seg );
+ }
+ $writer->endTag( "way" );
+ $writer->end;
+ return $str;
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my $incomplete = 0;
+ my ($new_id) = $mapper->map('way',$self->id); # Determine mapped ID
+ # It is ok for the new_id to be incomplete; it may be a create request
+
+ my @new_segs = map { [ $mapper->map('segment',$_) ] } @{$self->segs};
+ map { $incomplete |= $_->[1] } @new_segs;
+ # incomplete tracks if any of the segs are incomplete
+
+ my $new_ent = new Geo::OSM::Way( {id=>$new_id, timestamp=>$self->timestamp}, $self->tags, [map {$_->[0]} @new_segs] );
+ return($new_ent,$incomplete);
+}
+
+package Geo::OSM::Segment;
+our @ISA = qw(Geo::OSM::Entity);
+
+sub new
+{
+ my($class, $attr, $tags) = @_;
+
+ my $obj = bless $class->SUPER::_new(), $class;
+
+ $obj->set_tags($tags);
+ $obj->set_id($attr->{id} );
+ $obj->set_timestamp( $attr->{timestamp} );
+ $obj->{from} = $attr->{from};
+ $obj->{to} = $attr->{to};
+
+ return $obj;
+}
+
+sub type { return "segment" }
+
+sub set_fromto
+{
+ my($self,$from,$to) = @_;
+ $self->{from} = $from;
+ $self->{to} = $to;
+}
+
+sub from
+{
+ shift->{from};
+}
+sub to
+{
+ shift->{to};
+}
+
+sub xml
+{
+ my $self = shift;
+ my $str = "";
+ my $writer = $self->_get_writer(\$str);
+
+ $writer->startTag( "segment", id => $self->id, from => $self->from, to => $self->to, timestamp => $self->timestamp );
+ $self->tag_xml( $writer );
+ $writer->endTag( "segment" );
+ $writer->end;
+ return $str;
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my ($new_id) = $mapper->map('segment',$self->id);
+ my ($new_from,$i1) = $mapper->map('node',$self->from);
+ my ($new_to,$i2) = $mapper->map('node',$self->to);
+ my $new_ent = new Geo::OSM::Segment( {id=>$new_id, timestamp=>$self->timestamp, from=>$new_from, to=>$new_to}, $self->tags );
+ return($new_ent,$i1|$i2);
+}
+
+package Geo::OSM::Node;
+our @ISA = qw(Geo::OSM::Entity);
+
+sub new
+{
+ my($class, $attr, $tags) = @_;
+
+ my $obj = bless $class->SUPER::_new(), $class;
+
+ $obj->set_tags($tags);
+ $obj->set_id($attr->{id} );
+ $obj->set_timestamp( $attr->{timestamp} );
+ $obj->{lon} = $attr->{lon};
+ $obj->{lat} = $attr->{lat};
+
+ return $obj;
+}
+
+sub type { return "node" }
+
+sub set_latlon
+{
+ my($self,$lat,$lon) = @_;
+ $self->{lat} = $lat;
+ $self->{lon} = $lon;
+}
+
+sub lat
+{
+ shift->{lat};
+}
+sub lon
+{
+ shift->{lon};
+}
+
+sub xml
+{
+ my $self = shift;
+ my $str = "";
+ my $writer = $self->_get_writer(\$str);
+
+ $writer->startTag( "node", id => $self->id, lat => $self->lat, lon => $self->lon, timestamp => $self->timestamp );
+ $self->tag_xml( $writer );
+ $writer->endTag( "node" );
+ $writer->end;
+ return $str;
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my ($new_id) = $mapper->map('node',$self->id);
+ my $new_ent = new Geo::OSM::Node( {id=>$new_id, timestamp=>$self->timestamp, lat=>$self->lat, lon=>$self->lon}, $self->tags );
+ return($new_ent,0);
+}
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/OSM/EntitiesV5.pm b/scripts/osm/perl_lib/Geo/OSM/EntitiesV5.pm
new file mode 100644
index 0000000..625ff6b
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/EntitiesV5.pm
@@ -0,0 +1,375 @@
+##################################################################
+## EntitiesV3.pm - Wraps entities used by OSM ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Package that wraps the entities used by OSM into Perl ##
+## object, so they can be easily manipulated by various ##
+## packages. ##
+## ##
+## Licence: LGPL ##
+##################################################################
+
+use XML::Writer;
+use strict;
+
+############################################################################
+## Top level Entity type, parent of all types, includes stuff relating to ##
+## tags and IDs which are shared by all entity types ##
+############################################################################
+package Geo::OSM::Entity;
+use POSIX qw(strftime);
+
+use Carp;
+
+sub _new
+{
+ bless {}, shift;
+}
+
+sub _get_writer
+{
+ my($self,$res) = @_;
+ return new XML::Writer(OUTPUT => $res, NEWLINES => 0, ENCODING => 'utf-8');
+}
+
+sub add_tag
+{
+ my($self, $k,$v) = @_;
+ push @{$self->{tags}}, $k, $v;
+}
+
+sub add_tags
+{
+ my($self, @tags) = @_;
+ if( scalar(@tags)&1 )
+ { croak "add_tags requires an even number of arguments" }
+ push @{$self->{tags}}, @tags;
+}
+
+sub set_tags
+{
+ my($self,$tags) = @_;
+ if( ref($tags) eq "HASH" )
+ { $self->{tags} = [%$tags] }
+ elsif( ref($tags) eq "ARRAY" )
+ { $self->{tags} = [@$tags] }
+ else
+ { croak "set_tags must be HASH or ARRAY" }
+}
+
+sub tags
+{
+ my $self = shift;
+ return [@{$self->{tags}}]; # Return copy
+}
+
+sub tag_xml
+{
+ my ($self,$writer) = @_;
+ my @a = @{$self->{tags}};
+
+ my $str = "";
+
+ while( my($k,$v) = splice @a, 0, 2 )
+ {
+ $writer->emptyTag( "tag", 'k' => $k, 'v' => $v );
+ }
+}
+
+our $_ID = -1;
+
+sub set_id
+{
+ my($self,$id) = @_;
+
+ if( not defined $id )
+ { $id = $_ID-- }
+ $self->{id} = $id;
+}
+
+sub id
+{
+ my $self = shift;
+ return $self->{id};
+}
+
+sub set_timestamp
+{
+ my($self,$time) = @_;
+ if( defined $time )
+ { $self->{timestamp} = $time }
+ else
+ { $self->{timestamp} = strftime "%Y-%m-%dT%H:%M:%S+00:00", gmtime(time) }
+}
+
+sub timestamp
+{
+ my $self = shift;
+ return $self->{timestamp};
+}
+
+sub full_xml
+{
+ my $self = shift;
+ return qq(<?xml version="1.0"?>\n<osm version="0.5">\n).$self->xml()."</osm>\n";
+}
+
+package Geo::OSM::Way;
+our @ISA = qw(Geo::OSM::Entity);
+use Carp;
+
+sub new
+{
+ my($class, $attr, $tags, $nodes) = @_;
+
+ my $obj = bless $class->SUPER::_new(), $class;
+
+ $obj->set_tags($tags);
+ $obj->set_nodes($nodes);
+ $obj->set_id($attr->{id} );
+ $obj->set_timestamp( $attr->{timestamp} );
+
+ return $obj;
+}
+
+sub type { return "way" }
+
+sub set_nodes
+{
+ my($self,$nodes) = @_;
+ if( not defined $nodes )
+ { $nodes = [] }
+ if( ref($nodes) ne "ARRAY" )
+ { $nodes = [$nodes] }
+ if( scalar( grep { (ref($_) ne "")?$_->type ne "node":$_ !~ /^-?\d+/ } @$nodes ) )
+ { croak "Expected array of nodes" }
+ $self->{nodes} = [map { ref($_)?$_->id:$_ } @$nodes];
+}
+
+sub nodes
+{
+ my $self = shift;
+ return [@{$self->{nodes}}]; # Return a copy
+}
+
+sub xml
+{
+ my $self = shift;
+ my $str = "";
+ my $writer = $self->_get_writer(\$str);
+
+ $writer->startTag( "way", id => $self->id, timestamp => $self->timestamp );
+ $self->tag_xml( $writer );
+ for my $node (@{$self->nodes})
+ {
+ $writer->emptyTag( "nd", ref => $node );
+ }
+ $writer->endTag( "way" );
+ $writer->end;
+ return $str;
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my $incomplete = 0;
+ my ($new_id) = $mapper->map('way',$self->id); # Determine mapped ID
+ # It is ok for the new_id to be incomplete; it may be a create request
+
+ my @new_nodes = map { [ $mapper->map('node',$_) ] } @{$self->nodes};
+ map { $incomplete |= $_->[1] } @new_nodes;
+ # incomplete tracks if any of the segs are incomplete
+
+ my $new_ent = new Geo::OSM::Way( {id=>$new_id, timestamp=>$self->timestamp}, $self->tags, [map {$_->[0]} @new_nodes] );
+ return($new_ent,$incomplete);
+}
+
+package Geo::OSM::Relation::Member;
+use Carp;
+# Relation reference can be specified in several ways:
+# { type => $type, ref => $id [ , role => $str ] }
+# { ref => $obj [ , role => $str ] }
+# [ $type, $id [,$role] ]
+# [ $obj, [,$role] ]
+sub new
+{
+ my $class = shift;
+ my $arg = shift;
+ return $arg if ref($arg) eq $class; # Return if already object
+ if( ref($arg) eq "ARRAY" )
+ {
+ if( ref $arg->[0] )
+ { $arg = { ref => $arg->[0], role => $arg->[1] } }
+ else
+ { $arg = { type => $arg->[0], ref => $arg->[1], role => $arg->[2] } }
+ }
+ if( ref($arg) eq "HASH" )
+ {
+ if( ref $arg->{ref} )
+ { $arg = [ $arg->{ref}->type, $arg->{ref}->id, $arg->{role} ] }
+ else
+ { $arg = [ $arg->{type}, $arg->{ref}, $arg->{role} ] }
+ }
+ else
+ { croak "Relation reference must be array or hash" }
+ croak "Bad type of member '$arg->[0]'"
+ unless $arg->[0] =~ /^(way|node|relation)$/;
+ croak "Bad member id '$arg->[1]'"
+ unless $arg->[1] =~ /^-?\d+$/;
+ $arg->[2] ||= "";
+
+ return bless $arg, $class;
+}
+
+sub member_type { shift->[0] }
+sub ref { shift->[1] }
+sub role { shift->[2] }
+
+sub type { return "relation:member" }
+
+sub _xml
+{
+ my $self = shift;
+ my $writer = shift;
+
+ $writer->emptyTag( "member", type => $self->member_type, ref => $self->ref, role => $self->role );
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my ($new_ref,$incomplete) = $mapper->map($self->member_type,$self->ref);
+ my $new_member = new Geo::OSM::Relation::Member( { type => $self->member_type, ref => $new_ref, role => $self->role } );
+ return($new_member,$incomplete);
+}
+
+package Geo::OSM::Relation;
+our @ISA = qw(Geo::OSM::Entity);
+
+sub new
+{
+ my($class, $attr, $tags, $members) = @_;
+
+ my $obj = bless $class->SUPER::_new(), $class;
+
+ $obj->set_tags($tags);
+ $obj->set_members($members);
+ $obj->set_id($attr->{id} );
+ $obj->set_timestamp( $attr->{timestamp} );
+
+ return $obj;
+}
+
+sub set_members
+{
+ my($self,$members) = @_;
+ if( not defined $members )
+ { $members = [] }
+ if( ref($members) ne "ARRAY" )
+ { $members = [$members] }
+ $self->{members} = [map { new Geo::OSM::Relation::Member($_) } @$members];
+}
+
+sub members
+{
+ my $self = shift;
+ return [@{$self->{members}}];
+}
+
+sub type { return "relation" }
+
+sub xml
+{
+ my $self = shift;
+ my $str = "";
+ my $writer = $self->_get_writer(\$str);
+
+ $writer->startTag( "relation", id => $self->id, timestamp => $self->timestamp );
+ $self->tag_xml( $writer );
+ # Write members
+ foreach my $member (@{$self->{members}})
+ { $member->_xml( $writer ) }
+ $writer->endTag( "relation" );
+ $writer->end;
+ return $str;
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my $incomplete = 0;
+
+ my ($new_id) = $mapper->map('relation',$self->id);
+ my @new_members = map { [ $_->map($mapper) ] } @{$self->members};
+ map { $incomplete |= $_->[1] } @new_members;
+ # incomplete tracks if any of the members are incomplete
+ my $new_ent = new Geo::OSM::Relation( {id=>$new_id, timestamp=>$self->timestamp}, $self->tags, [map {$_->[0]} @new_members] );
+ return($new_ent,$incomplete);
+}
+
+package Geo::OSM::Node;
+use Carp;
+our @ISA = qw(Geo::OSM::Entity);
+
+sub new
+{
+ my($class, $attr, $tags) = @_;
+
+ my $obj = bless $class->SUPER::_new(), $class;
+
+ $obj->set_tags($tags);
+ $obj->set_id($attr->{id} );
+ $obj->set_timestamp( $attr->{timestamp} );
+ if( $attr->{lon} !~ /^[-+]?\d+(\.\d+)?([eE][+-]?\d+)?$/ or
+ $attr->{lat} !~ /^[-+]?\d+(\.\d+)?([eE][+-]?\d+)?$/ )
+ {
+ croak "Invalid lat,lon values ($attr->{lat},$attr->{lon})\n";
+ }
+ $obj->{lon} = $attr->{lon};
+ $obj->{lat} = $attr->{lat};
+
+ return $obj;
+}
+
+sub type { return "node" }
+
+sub set_latlon
+{
+ my($self,$lat,$lon) = @_;
+ $self->{lat} = $lat;
+ $self->{lon} = $lon;
+}
+
+sub lat
+{
+ shift->{lat};
+}
+sub lon
+{
+ shift->{lon};
+}
+
+sub xml
+{
+ my $self = shift;
+ my $str = "";
+ my $writer = $self->_get_writer(\$str);
+
+ $writer->startTag( "node", id => $self->id, lat => $self->lat, lon => $self->lon, timestamp => $self->timestamp );
+ $self->tag_xml( $writer );
+ $writer->endTag( "node" );
+ $writer->end;
+ return $str;
+}
+
+sub map
+{
+ my($self,$mapper) = @_;
+ my ($new_id) = $mapper->map('node',$self->id);
+ my $new_ent = new Geo::OSM::Node( {id=>$new_id, timestamp=>$self->timestamp, lat=>$self->lat, lon=>$self->lon}, $self->tags );
+ return($new_ent,0);
+}
+
+
+
+1;
diff --git a/scripts/osm/perl_lib/Geo/OSM/MapFeatures.pm b/scripts/osm/perl_lib/Geo/OSM/MapFeatures.pm
new file mode 100644
index 0000000..c4ae62f
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/MapFeatures.pm
@@ -0,0 +1,194 @@
+##################################################################
+package Geo::OSM::MapFeatures;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( );
+
+use strict;
+use warnings;
+
+use HTTP::Request;
+use File::Basename;
+use File::Copy;
+use File::Path;
+use Getopt::Long;
+use HTTP::Request;
+use Storable ();
+use Data::Dumper;
+
+use Utils::File;
+use Utils::Debug;
+use Utils::LWP::Utils;
+use XML::Parser;
+use XML::Simple;
+
+my $self;
+
+# ------------------------------------------------------------------
+sub style($){
+ my $self = shift;
+
+}
+
+# ------------------------------------------------------------------
+# load the complete MapFeatures Structure into memory
+sub load($;$){
+ my ($class, $filename) = @_;
+ #$filename ||= '../../freemap/freemap.xml';
+ $filename ||= './map-features.xml';
+ print("Loading Map Features from $filename\n") if $VERBOSE || $DEBUG;
+ print "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+ print STDERR "Parsing file: $filename\n" if $DEBUG;
+
+ my $fh = data_open($filename);
+ if (not $fh) {
+ print STDERR "WARNING: Could not open osm data from $filename\n";
+ return;
+ }
+ my $self = XMLin($fh);
+
+ if (not $self) {
+ print STDERR "WARNING: Could not parse osm data from $filename\n";
+ return;
+ }
+
+ #delete $self->{defs}->{symbol};
+ #warn Dumper(\$self->{defs});
+ #warn Dumper(\$self->{data});
+ #warn Dumper(\$self->{rule});
+ #warn Dumper(keys %{$self});
+ #warn Dumper(%{$self});
+
+ bless($self,$class);
+ return $self;
+}
+
+# ------------------------------------------------------------------
+# Load icons into memory nad create a PDF Version out of it
+sub load_icons($$){
+ my $self = shift;
+ my $PDF = shift;
+ die "No PDF Document defined\n" unless $PDF;
+
+ print STDERR "load_icons():\n" if $DEBUG;
+# print STDERR Dumper(\$self);
+
+ for my $rule ( @{$self->{rule}} ) {
+ my $img = $rule->{style}->{image};
+ next unless defined $img;
+ $img =~s/^images\///;
+ my $img_filename;
+ for my $path ( qw( ../../freemap/images
+ ../../map-icons/square.small
+ ../../map-icons/square.big
+ ../../map-icons/classic.big
+ ../../map-icons/classic.small
+ ../../map-icons/nick
+ ../../map-icons/classic/other
+ ) ) {
+ $img_filename = "$path/$img";
+ if ( -s $img_filename ) {
+ my $png = $PDF->image_png($img_filename);
+ $rule->{png}=$png;
+ #print STDERR "image: $img_filename\n";
+ last;
+ }
+ }
+
+ if ( ! $rule->{png} ) {
+ warn "missing $img\n";
+ }
+ #print STDERR "rule: ".Dumper(\$rule);
+# print STDERR "condition: ".Dumper(\$rule->{condition});
+ my $condition = $rule->{condition};
+# print STDERR "image: $img_filename\t";
+ print STDERR " #condition: $condition->{k}=$condition->{v}\t";
+ printf STDERR "scale: %d-%d",
+ ($rule->{style}->{scale_max}||0),
+ ($rule->{style}->{scale_min}||0);
+ print STDERR "get_icon() image: $img\n";
+
+ }
+}
+
+# ------------------------------------------------------------------
+sub get_icons($$$){
+ my $self = shift;
+ my $rule_line= shift;
+ my $scale = shift;
+ return undef if $rule_line =~ m/^[\s\,]*$/;
+# return undef if $rule_line eq ",";
+
+ my ($dummy1,$dummy2,$attr) = split(",",$rule_line,3);
+ my %attr;
+ foreach my $kv ( split(",",$attr)){
+ my ($k,$v)=split("=",$kv);
+ $attr{$k}=$v;
+ }
+
+
+ print STDERR "get_icon($attr)\n";
+
+ my $png =undef;
+ for my $rule ( @{$self->{rule}} ) {
+ my $img = $rule->{style}->{image};
+ next unless $img;
+
+ my $condition = $rule->{condition};
+# print STDERR "condition: $condition->{k}=$condition->{v}\n";
+ if ( defined ( $attr{scale_max}) &&
+ $scale > $attr{scale_max}) {
+ next;
+ }
+
+ if ( defined( $attr{ $condition->{k}}) &&
+ $attr{ $condition->{k}} eq $condition->{v} ) {
+ print STDERR "condition: $condition->{k}=$condition->{v}\n";
+ print STDERR "get_icon() image: $img\t";
+ $png = $rule->{png};
+ }
+
+ return $png if $png;
+ }
+ return undef;
+}
+1;
+
+=head1 NAME
+
+Geo::OSM::MapFeature
+
+=head1 DESCRIPTION
+
+Load the MapFeatures.xml into memory
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (MapFeatures-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV3.pm b/scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV3.pm
new file mode 100644
index 0000000..65103a3
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV3.pm
@@ -0,0 +1,323 @@
+##################################################################
+## OsmChangeReader.pm - Library for reading OSM change files ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Package that reads both osmChange and JOSM file format change##
+## files. The user creates the parse with a callback and the ##
+## loader will call the callback for each detected change. Note ##
+## that for JOSM file entires that are not changes are ignored. ##
+## ##
+## Licence: LGPL ##
+##################################################################
+package Geo::OSM::OsmChangeReader;
+
+use strict;
+use warnings;
+
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+use XML::Parser;
+use Carp;
+
+use Geo::OSM::EntitiesV3;
+
+use constant STATE_INIT => 1;
+use constant STATE_EXPECT_COMMAND => 2;
+use constant STATE_EXPECT_ENTITY => 3;
+use constant STATE_EXPECT_BODY => 4;
+
+use constant FILETYPE_UNKNOWN => 0;
+use constant FILETYPE_OSMCHANGE => 1;
+use constant FILETYPE_OSM => 2;
+
+sub new
+{
+ my $obj = bless{}, shift;
+ my $proc = shift;
+ my $prog = shift;
+ if( ref $proc ne "CODE" )
+ { die "new Geo::OSM::OsmChangeReader requires a sub as argument\n" }
+ $obj->{oldproc} = $proc;
+ if( defined $prog )
+ { $obj->{progress} = $prog }
+ return $obj;
+}
+
+# With this initialiser, your process will get called with instantiated objects rather than useless details
+sub init
+{
+ my $obj = bless{}, shift;
+ my $proc = shift;
+ my $prog = shift;
+ if( ref $proc ne "CODE" )
+ { die "init Geo::OSM::OsmChangeReader requires a sub as argument\n" }
+ $obj->{newproc} = $proc;
+ if( defined $prog )
+ { $obj->{progress} = $prog }
+ return $obj;
+}
+
+sub _process
+{
+ my($self, $command, $entity, $attr, $tags, $segs) = @_;
+
+ if( defined $self->{oldproc} )
+ {
+ return $self->{oldproc}->($command, $entity, $attr, $tags, $segs);
+ }
+
+ my $ent;
+ if( $entity eq "node" )
+ {
+ $ent = new Geo::OSM::Node( $attr, $tags );
+ }
+ if( $entity eq "segment" )
+ {
+ $ent = new Geo::OSM::Segment( $attr, $tags );
+ }
+ if( $entity eq "way" )
+ {
+ $ent = new Geo::OSM::Way( $attr, $tags, $segs );
+ }
+ croak "Unknown entity '$entity'" if not defined $ent;
+
+ return $self->{newproc}->($command, $ent );
+}
+
+sub load{
+ my ($self, $file_name) = @_;
+
+ $self->{filetype} = FILETYPE_UNKNOWN;
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ my $fh = data_open($file_name);
+ die "Cannot open OSM File $file_name\n" unless $fh;
+ $self->{input_length} = -s $fh;
+ $self->{count}=0;
+ eval {
+ $P->parse($fh);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed $file_name in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n $file_name\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+
+}
+
+sub parse($)
+{
+ my ($self, $string) = @_;
+
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ $self->{input_length} = length($string);
+ $self->{count}=0;
+ eval {
+ $P->parse($string);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed string in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n [$string]\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+}
+
+# Function is called whenever an XML tag is started
+sub DoStart
+{
+#print @_,"\n";
+ my ($self, $Expat, $Name, %Attr) = @_;
+
+ if( $self->{filetype} == FILETYPE_UNKNOWN )
+ {
+ if( $self->{state} == STATE_INIT )
+ {
+ if($Name eq "osmChange"){
+ $self->{state} = STATE_EXPECT_COMMAND;
+ $self->{filetype} = FILETYPE_OSMCHANGE;
+
+ if( $Attr{version} ne "0.3" and $Attr{version} ne "0.4" )
+ { die "OsmChangeReaderV3 can only read 0.3 and 0.4 files, found '$Attr{version}'\n" }
+ } elsif($Name eq "osm"){
+ $self->{state} = STATE_EXPECT_ENTITY;
+ $self->{filetype} = FILETYPE_OSM;
+
+ if( $Attr{version} ne "0.3" and $Attr{version} ne "0.4" )
+ { die "OsmChangeReaderV3 can only read 0.3 and 0.4 files, found '$Attr{version}'\n" }
+ } else {
+ die "Expected 'osmChange' tag, got '$Name'\n";
+ }
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_COMMAND )
+ {
+ if($Name eq 'create' or $Name eq 'modify' or $Name eq 'delete'){
+ $self->{command} = $Name;
+ $self->{state} = STATE_EXPECT_ENTITY;
+ } else {
+ die "Expected command\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ # Pick up the origin attribute from the bound tag
+ if( $Name eq "bound" )
+ {
+ if( exists $Attr{origin} )
+ {
+ $self->{origin} = $Attr{origin};
+ }
+ return;
+ }
+ if($Name eq "node" or $Name eq "segment" or $Name eq "way"){
+ $self->{entity} = $Name;
+ $self->{attr} = {%Attr};
+ $self->{tags} = [];
+ $self->{segs} = ($Name eq "way") ? [] : undef;
+ $self->{state} = STATE_EXPECT_BODY;
+ } else {
+ die "Expected entity\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if($Name eq "tag"){
+ push @{$self->{tags}}, $Attr{"k"}, $Attr{"v"};
+ }
+ if($Name eq "seg"){
+ push @{$self->{segs}}, $Attr{"id"};
+ }
+ }
+}
+
+# Function is called whenever an XML tag is ended
+sub DoEnd
+{
+ my ($self, $Expat, $Name) = @_;
+ if( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if( $Name eq $self->{entity} )
+ {
+ if( $self->{filetype} == FILETYPE_OSMCHANGE )
+ {
+ $self->_process( $self->{command}, $self->{entity}, $self->{attr}, $self->{tags}, $self->{segs} );
+ }
+ else # FILETYPE_OSM
+ {
+ # Only entities with a modify tag are interesting, or if they have a negative ID (that's create)
+ if( exists $self->{attr}->{action} )
+ {
+ $self->_process( $self->{attr}->{action}, $self->{entity}, $self->{attr}, $self->{tags}, $self->{segs} );
+ }
+ elsif( $self->{attr}{id} < 0 )
+ {
+ $self->_process( "create", $self->{entity}, $self->{attr}, $self->{tags}, $self->{segs} );
+ }
+ }
+ $self->{count}++;
+ if( $self->{progress} and ($self->{count}%11) == 1)
+ {
+ $self->{progress}->($self->{count}, $Expat->current_byte()/$self->{input_length} );
+ }
+ $self->{state} = STATE_EXPECT_ENTITY;
+ }
+ return;
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ return if $Name eq "bound";
+ if( $self->{filetype} == FILETYPE_OSMCHANGE )
+ {
+ if( $Name eq $self->{command} )
+ {
+ $self->{state} = STATE_EXPECT_COMMAND;
+ }else {die}
+ }
+ else # FILETYPE_OSM
+ {
+ if( $Name eq "osm" )
+ {
+ $self->{state} = STATE_INIT;
+ } else {die}
+ }
+ return;
+ }
+ elsif( $self->{state} == STATE_EXPECT_COMMAND )
+ {
+ if( $Name eq "osmChange" )
+ {
+ $self->{state} = STATE_INIT;
+ }else {die}
+ return;
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+OsmChangeReaderV3 - Module for reading OpenStreetMap V3 Change XML data files
+
+=head1 SYNOPSIS
+
+ my $OSM = new Geo::OSM::OsmChangeReader(\&process);
+ $OSM->load("Data/changes.osc");
+
+ sub process
+ {
+ my($OSM, $command, $entity, $attr, $tags, $segs) = @_;
+ print "Doing a $command on a $entity $attr->{id}\n";
+ while( my($k,$v) = splice @{$tags}, 0, 2 )
+ { print " $k: $v\n" }
+ if( defined $segs )
+ { print " Segs: ", join(", ",@$segs),"\n"; }
+ }
+
+=head1 AUTHOR
+
+Martijn van Oosterhout <kleptog@svana.org>
+based on OsmXML.pm written by:
+Oliver White (oliver.white@blibbleblobble.co.uk)
+
+=head1 COPYRIGHT
+
+Copyright 2007, Martijn van Oosterhout
+Copyright 2006, Oliver White
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV5.pm b/scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV5.pm
new file mode 100644
index 0000000..f886442
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/OsmChangeReaderV5.pm
@@ -0,0 +1,314 @@
+##################################################################
+## OsmChangeReader.pm - Library for reading OSM change files ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Package that reads both osmChange and JOSM file format change##
+## files. The user creates the parse with a callback and the ##
+## loader will call the callback for each detected change. Note ##
+## that for JOSM file entires that are not changes are ignored. ##
+## ##
+## Licence: LGPL ##
+##################################################################
+package Geo::OSM::OsmChangeReader;
+
+use strict;
+use warnings;
+
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+use XML::Parser;
+use Carp;
+
+use Geo::OSM::EntitiesV5;
+
+use constant STATE_INIT => 1;
+use constant STATE_EXPECT_COMMAND => 2;
+use constant STATE_EXPECT_ENTITY => 3;
+use constant STATE_EXPECT_BODY => 4;
+
+use constant FILETYPE_UNKNOWN => 0;
+use constant FILETYPE_OSMCHANGE => 1;
+use constant FILETYPE_OSM => 2;
+
+# With this initialiser, your process will get called with instantiated objects
+sub init
+{
+ my $obj = bless{}, shift;
+ my $proc = shift;
+ my $prog = shift;
+ if( ref $proc ne "CODE" )
+ { die "init Geo::OSM::OsmChangeReader requires a sub as argument\n" }
+ $obj->{newproc} = $proc;
+ if( defined $prog )
+ { $obj->{progress} = $prog }
+ return $obj;
+}
+
+sub _process
+{
+ my($self, $command, $entity, $attr, $tags, $members) = @_;
+
+ if( defined $self->{oldproc} )
+ {
+ return $self->{oldproc}->($command, $entity, $attr, $tags, $members);
+ }
+
+ my $ent;
+ if( $entity eq "node" )
+ {
+ $ent = new Geo::OSM::Node( $attr, $tags );
+ }
+ if( $entity eq "relation" )
+ {
+ $ent = new Geo::OSM::Relation( $attr, $tags, $members );
+ }
+ if( $entity eq "way" )
+ {
+ $ent = new Geo::OSM::Way( $attr, $tags, $members );
+ }
+ croak "Unknown entity '$entity'" if not defined $ent;
+
+ return $self->{newproc}->($command, $ent );
+}
+
+sub load{
+ my ($self, $file_name) = @_;
+
+ $self->{filetype} = FILETYPE_UNKNOWN;
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ my $fh = data_open($file_name);
+ die "Cannot open OSM File $file_name\n" unless $fh;
+ $self->{input_length} = -s $fh;
+ $self->{count}=0;
+ eval {
+ $P->parse($fh);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed $file_name in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n $file_name\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+
+}
+
+sub parse($)
+{
+ my ($self, $string) = @_;
+
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ $self->{input_length} = length($string);
+ $self->{count}=0;
+ eval {
+ $P->parse($string);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed string in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n [$string]\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+}
+
+# Function is called whenever an XML tag is started
+sub DoStart
+{
+#print @_,"\n";
+ my ($self, $Expat, $Name, %Attr) = @_;
+
+ if( $self->{filetype} == FILETYPE_UNKNOWN )
+ {
+ if( $self->{state} == STATE_INIT )
+ {
+ if($Name eq "osmChange"){
+ $self->{state} = STATE_EXPECT_COMMAND;
+ $self->{filetype} = FILETYPE_OSMCHANGE;
+
+ if( $Attr{version} ne "0.5" )
+ { die "OsmChangeReaderV3 can only read 0.5 files, found '$Attr{version}'\n" }
+ } elsif($Name eq "osm"){
+ $self->{state} = STATE_EXPECT_ENTITY;
+ $self->{filetype} = FILETYPE_OSM;
+
+ if( $Attr{version} ne "0.5" )
+ { die "OsmChangeReaderV3 can only read 0.5 files, found '$Attr{version}'\n" }
+ } else {
+ die "Expected 'osmChange' tag, got '$Name'\n";
+ }
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_COMMAND )
+ {
+ if($Name eq 'create' or $Name eq 'modify' or $Name eq 'delete'){
+ $self->{command} = $Name;
+ $self->{state} = STATE_EXPECT_ENTITY;
+ } else {
+ die "Expected command\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ # Pick up the origin attribute from the bound tag
+ if( $Name eq "bound" )
+ {
+ if( exists $Attr{origin} )
+ {
+ $self->{origin} = $Attr{origin};
+ }
+ return;
+ }
+ if($Name eq "node" or $Name eq "relation" or $Name eq "way"){
+ $self->{entity} = $Name;
+ $self->{attr} = {%Attr};
+ $self->{tags} = [];
+ $self->{members} = ($Name ne "node") ? [] : undef;
+ $self->{state} = STATE_EXPECT_BODY;
+ } else {
+ die "Expected entity\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if($Name eq "tag"){
+ push @{$self->{tags}}, $Attr{"k"}, $Attr{"v"};
+ }
+ if($Name eq "nd"){
+ push @{$self->{members}}, $Attr{"ref"};
+ }
+ if($Name eq "member"){
+ push @{$self->{members}}, new Geo::OSM::Relation::Member( \%Attr );
+ }
+ }
+}
+
+# Function is called whenever an XML tag is ended
+sub DoEnd
+{
+ my ($self, $Expat, $Name) = @_;
+ if( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if( $Name eq $self->{entity} )
+ {
+ if( $self->{filetype} == FILETYPE_OSMCHANGE )
+ {
+ $self->_process( $self->{command}, $self->{entity}, $self->{attr}, $self->{tags}, $self->{members} );
+ }
+ else # FILETYPE_OSM
+ {
+ # Only entities with a modify tag are interesting, or if they have a negative ID (that's create)
+ if( exists $self->{attr}->{action} )
+ {
+ $self->_process( $self->{attr}->{action}, $self->{entity}, $self->{attr}, $self->{tags}, $self->{members} );
+ }
+ elsif( $self->{attr}{id} < 0 )
+ {
+ $self->_process( "create", $self->{entity}, $self->{attr}, $self->{tags}, $self->{members} );
+ }
+ }
+ $self->{count}++;
+ if( $self->{progress} and ($self->{count}%11) == 1)
+ {
+ $self->{progress}->($self->{count}, $Expat->current_byte()/$self->{input_length} );
+ }
+ $self->{state} = STATE_EXPECT_ENTITY;
+ }
+ return;
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ return if $Name eq "bound";
+ if( $self->{filetype} == FILETYPE_OSMCHANGE )
+ {
+ if( $Name eq $self->{command} )
+ {
+ $self->{state} = STATE_EXPECT_COMMAND;
+ }else {die}
+ }
+ else # FILETYPE_OSM
+ {
+ if( $Name eq "osm" )
+ {
+ $self->{state} = STATE_INIT;
+ } else {die}
+ }
+ return;
+ }
+ elsif( $self->{state} == STATE_EXPECT_COMMAND )
+ {
+ if( $Name eq "osmChange" )
+ {
+ $self->{state} = STATE_INIT;
+ }else {die}
+ return;
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+OsmChangeReaderV5 - Module for reading OpenStreetMap V5 Change XML data files
+
+=head1 SYNOPSIS
+
+ my $OSM = new Geo::OSM::OsmChangeReader(\&process);
+ $OSM->load("Data/changes.osc");
+
+ sub process
+ {
+ my($OSM, $command, $entity) = @_;
+ print "Doing a $command on a $entity ".$entity->id."\n";
+ my $tags = $entity->tags;
+ while( my($k,$v) = splice @{$tags}, 0, 2 )
+ { print " $k: $v\n" }
+ if( $entity->type eq "way" )
+ { print " Nodes: ", join(", ",@{$entity->nodes}),"\n"; }
+ }
+
+=head1 AUTHOR
+
+Martijn van Oosterhout <kleptog@svana.org>
+based on OsmXML.pm written by:
+Oliver White (oliver.white@blibbleblobble.co.uk)
+
+=head1 COPYRIGHT
+
+Copyright 2007, Martijn van Oosterhout
+Copyright 2006, Oliver White
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/OsmReaderV3.pm b/scripts/osm/perl_lib/Geo/OSM/OsmReaderV3.pm
new file mode 100644
index 0000000..3fc219d
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/OsmReaderV3.pm
@@ -0,0 +1,246 @@
+##################################################################
+## OsmReader.pm - Library for reading OSM files ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Package that reads both OSM file format files. ##
+## The user creates the parse with a callback and the ##
+## loader will call the callback for each detected object. ##
+## Licence: LGPL ##
+##################################################################
+package Geo::OSM::OsmReader;
+
+use strict;
+use warnings;
+
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+use XML::Parser;
+use Carp;
+
+use Geo::OSM::EntitiesV3;
+
+use constant STATE_INIT => 1;
+use constant STATE_EXPECT_ENTITY => 3;
+use constant STATE_EXPECT_BODY => 4;
+
+# With this initialiser, your process will get called with instantiated objects
+sub init
+{
+ my $obj = bless{}, shift;
+ my $proc = shift;
+ my $prog = shift;
+ if( ref $proc ne "CODE" )
+ { die "init Geo::OSM::OsmReader requires a sub as argument\n" }
+ $obj->{newproc} = $proc;
+ if( defined $prog )
+ { $obj->{progress} = $prog }
+ return $obj;
+}
+
+sub _process
+{
+ my($self, $entity, $attr, $tags, $members) = @_;
+
+ my $ent;
+ if( $entity eq "node" )
+ {
+ $ent = new Geo::OSM::Node( $attr, $tags );
+ }
+ if( $entity eq "segment" )
+ {
+ $ent = new Geo::OSM::Segment( $attr, $tags );
+ }
+ if( $entity eq "way" )
+ {
+ $ent = new Geo::OSM::Way( $attr, $tags, $members );
+ }
+ croak "Unknown entity '$entity'" if not defined $ent;
+
+ return $self->{newproc}->( $ent );
+}
+
+sub load($)
+{
+ my ($self, $file_name) = @_;
+
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ my $fh = data_open($file_name);
+ die "Cannot open OSM File $file_name\n" unless $fh;
+ $self->{input_length} = -s $fh;
+ $self->{count}=0;
+ eval {
+ $P->parse($fh);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed $file_name in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n $file_name\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+}
+
+sub parse($)
+{
+ my ($self, $string) = @_;
+
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ $self->{input_length} = length($string);
+ $self->{count}=0;
+ eval {
+ $P->parse($string);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed string in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n [$string]\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+}
+
+# Function is called whenever an XML tag is started
+sub DoStart
+{
+#print @_,"\n";
+ my ($self, $Expat, $Name, %Attr) = @_;
+
+ if( $self->{state} == STATE_INIT )
+ {
+ if($Name eq "osm"){
+ $self->{state} = STATE_EXPECT_ENTITY;
+
+ if( $Attr{version} ne "0.3" and $Attr{version} ne "0.4")
+ { die "OsmReaderV5 can only read 0.3 or 0.4 files, found '$Attr{version}'\n" }
+ } else {
+ die "Expected 'osm' tag, got '$Name'\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ # Pick up the origin attribute from the bound tag
+ if( $Name eq "bound" )
+ {
+ if( exists $Attr{origin} )
+ {
+ $self->{origin} = $Attr{origin};
+ }
+ return;
+ }
+ if($Name eq "node" or $Name eq "segment" or $Name eq "way"){
+ $self->{entity} = $Name;
+ $self->{attr} = {%Attr};
+ $self->{tags} = [];
+ $self->{members} = ($Name ne "node") ? [] : undef;
+ $self->{state} = STATE_EXPECT_BODY;
+ } else {
+ die "Expected entity\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if($Name eq "tag"){
+ push @{$self->{tags}}, $Attr{"k"}, $Attr{"v"};
+ }
+ if($Name eq "seg"){
+ push @{$self->{members}}, $Attr{"id"};
+ }
+ }
+}
+
+# Function is called whenever an XML tag is ended
+sub DoEnd
+{
+ my ($self, $Expat, $Name) = @_;
+ if( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if( $Name eq $self->{entity} )
+ {
+ $self->_process( $self->{entity}, $self->{attr}, $self->{tags}, $self->{members} );
+ $self->{count}++;
+ if( $self->{progress} and ($self->{count}%11) == 1)
+ {
+ $self->{progress}->($self->{count}, $Expat->current_byte()/$self->{input_length} );
+ }
+ $self->{state} = STATE_EXPECT_ENTITY;
+ }
+ return;
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ return if $Name eq "bound";
+ if( $Name eq "osm" )
+ {
+ $self->{state} = STATE_INIT;
+ } else {die}
+ return;
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+OsmReaderV3 - Module for reading OpenStreetMap V3 XML data files
+
+=head1 SYNOPSIS
+
+ my $OSM = new Geo::OSM::OsmReader(\&process);
+ $OSM->load("Data/changes.osc");
+
+ sub process
+ {
+ my($OSM, $entity) = @_;
+ print "Read $entity ".$entity->id."\n";
+ my $tags = $entity->tags;
+ while( my($k,$v) = splice @{$tags}, 0, 2 )
+ { print " $k: $v\n" }
+ if( $entity->type eq "way" )
+ { print " Segs: ", join(", ",@{$entity->segs}),"\n"; }
+ }
+
+=head1 AUTHOR
+
+Martijn van Oosterhout <kleptog@svana.org>
+based on OsmXML.pm written by:
+Oliver White (oliver.white@blibbleblobble.co.uk)
+
+=head1 COPYRIGHT
+
+Copyright 2007, Martijn van Oosterhout
+Copyright 2006, Oliver White
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/OsmReaderV5.pm b/scripts/osm/perl_lib/Geo/OSM/OsmReaderV5.pm
new file mode 100644
index 0000000..37a477b
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/OsmReaderV5.pm
@@ -0,0 +1,249 @@
+##################################################################
+## OsmReader.pm - Library for reading OSM files ##
+## By Martijn van Oosterhout <kleptog@svana.org> ##
+## ##
+## Package that reads both OSM file format files. ##
+## The user creates the parse with a callback and the ##
+## loader will call the callback for each detected object. ##
+## Licence: LGPL ##
+##################################################################
+package Geo::OSM::OsmReader;
+
+use strict;
+use warnings;
+
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+use XML::Parser;
+use Carp;
+
+use Geo::OSM::EntitiesV5;
+
+use constant STATE_INIT => 1;
+use constant STATE_EXPECT_ENTITY => 3;
+use constant STATE_EXPECT_BODY => 4;
+
+# With this initialiser, your process will get called with instantiated objects
+sub init
+{
+ my $obj = bless{}, shift;
+ my $proc = shift;
+ my $prog = shift;
+ if( ref $proc ne "CODE" )
+ { die "init Geo::OSM::OsmReader requires a sub as argument\n" }
+ $obj->{newproc} = $proc;
+ if( defined $prog )
+ { $obj->{progress} = $prog }
+ return $obj;
+}
+
+sub _process
+{
+ my($self, $entity, $attr, $tags, $members) = @_;
+
+ my $ent;
+ if( $entity eq "node" )
+ {
+ $ent = new Geo::OSM::Node( $attr, $tags );
+ }
+ if( $entity eq "relation" )
+ {
+ $ent = new Geo::OSM::Relation( $attr, $tags, $members );
+ }
+ if( $entity eq "way" )
+ {
+ $ent = new Geo::OSM::Way( $attr, $tags, $members );
+ }
+ croak "Unknown entity '$entity'" if not defined $ent;
+
+ return $self->{newproc}->( $ent );
+}
+
+sub load($)
+{
+ my ($self, $file_name) = @_;
+
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ my $fh = data_open($file_name);
+ die "Cannot open OSM File $file_name\n" unless $fh;
+ $self->{input_length} = -s $fh;
+ $self->{count}=0;
+ eval {
+ $P->parse($fh);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed $file_name in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n $file_name\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+}
+
+sub parse($)
+{
+ my ($self, $string) = @_;
+
+ $self->{state} = STATE_INIT;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => sub{ DoStart( $self, @_ )}, End => sub { DoEnd( $self, @_ )}});
+ $self->{input_length} = length($string);
+ $self->{count}=0;
+ eval {
+ $P->parse($string);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed string in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n [$string]\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+}
+
+# Function is called whenever an XML tag is started
+sub DoStart
+{
+#print @_,"\n";
+ my ($self, $Expat, $Name, %Attr) = @_;
+
+ if( $self->{state} == STATE_INIT )
+ {
+ if($Name eq "osm"){
+ $self->{state} = STATE_EXPECT_ENTITY;
+
+ if( $Attr{version} ne "0.5" )
+ { die "OsmReaderV5 can only read 0.5 files, found '$Attr{version}'\n" }
+ } else {
+ die "Expected 'osm' tag, got '$Name'\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ # Pick up the origin attribute from the bound tag
+ if( $Name eq "bound" )
+ {
+ if( exists $Attr{origin} )
+ {
+ $self->{origin} = $Attr{origin};
+ }
+ return;
+ }
+ if($Name eq "node" or $Name eq "relation" or $Name eq "way"){
+ $self->{entity} = $Name;
+ $self->{attr} = {%Attr};
+ $self->{tags} = [];
+ $self->{members} = ($Name ne "node") ? [] : undef;
+ $self->{state} = STATE_EXPECT_BODY;
+ } else {
+ die "Expected entity\n";
+ }
+ }
+ elsif( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if($Name eq "tag"){
+ push @{$self->{tags}}, $Attr{"k"}, $Attr{"v"};
+ }
+ if($Name eq "nd"){
+ push @{$self->{members}}, $Attr{"ref"};
+ }
+ if($Name eq "member"){
+ push @{$self->{members}}, new Geo::OSM::Relation::Member( \%Attr );
+ }
+ }
+}
+
+# Function is called whenever an XML tag is ended
+sub DoEnd
+{
+ my ($self, $Expat, $Name) = @_;
+ if( $self->{state} == STATE_EXPECT_BODY )
+ {
+ if( $Name eq $self->{entity} )
+ {
+ $self->_process( $self->{entity}, $self->{attr}, $self->{tags}, $self->{members} );
+ $self->{count}++;
+ if( $self->{progress} and ($self->{count}%11) == 1)
+ {
+ $self->{progress}->($self->{count}, $Expat->current_byte()/$self->{input_length} );
+ }
+ $self->{state} = STATE_EXPECT_ENTITY;
+ }
+ return;
+ }
+ elsif( $self->{state} == STATE_EXPECT_ENTITY )
+ {
+ return if $Name eq "bound";
+ if( $Name eq "osm" )
+ {
+ $self->{state} = STATE_INIT;
+ } else {die}
+ return;
+ }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+OsmReaderV5 - Module for reading OpenStreetMap V5 XML data files
+
+=head1 SYNOPSIS
+
+ my $OSM = new Geo::OSM::OsmReader(\&process);
+ $OSM->load("Data/changes.osc");
+
+ sub process
+ {
+ my($OSM, $entity) = @_;
+ print "Read $entity ".$entity->id."\n";
+ my $tags = $entity->tags;
+ while( my($k,$v) = splice @{$tags}, 0, 2 )
+ { print " $k: $v\n" }
+ if( $entity->type eq "way" )
+ { print " Nodes: ", join(", ",@{$entity->nodes}),"\n"; }
+ }
+
+=head1 AUTHOR
+
+Martijn van Oosterhout <kleptog@svana.org>
+based on OsmXML.pm written by:
+Oliver White (oliver.white@blibbleblobble.co.uk)
+
+=head1 COPYRIGHT
+
+Copyright 2007, Martijn van Oosterhout
+Copyright 2006, Oliver White
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/OsmXML.pm b/scripts/osm/perl_lib/Geo/OSM/OsmXML.pm
new file mode 100644
index 0000000..60f458d
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/OsmXML.pm
@@ -0,0 +1,161 @@
+package Geo::OSM::OsmXML;
+
+use strict;
+use warnings;
+
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+use XML::Parser;
+
+sub new(){ bless{} }
+
+sub load(){
+ my ($self, $file_name) = @_;
+
+ my $start_time = time();
+ my $P = new XML::Parser(Handlers => {Start => \&DoStart, End => \&DoEnd, Char => \&DoChar});
+ my $fh = data_open($file_name);
+ die "Cannot open OSM File $file_name\n" unless $fh;
+ eval {
+ $P->parse($fh);
+ };
+ print "\n" if $DEBUG || $VERBOSE;
+ if ( $VERBOSE) {
+ printf "Read and parsed $file_name in %.0f sec\n",time()-$start_time;
+ }
+ if ( $@ ) {
+ warn "$@Error while parsing\n $file_name\n";
+ return;
+ }
+ if (not $P) {
+ warn "WARNING: Could not parse osm data\n";
+ return;
+ }
+
+}
+sub name(){return($OsmXML::lastName)};
+
+sub bounds(){
+ my ($S,$W,$N,$E) = (1e+6,1e+6,-1e+6,-1e+6); # S,W,N,E
+ foreach my $Node(values %OsmXML::Nodes){
+ $S = $Node->{"lat"} if($Node->{"lat"} < $S);
+ $N = $Node->{"lat"} if($Node->{"lat"} > $N);
+ $W = $Node->{"lon"} if($Node->{"lon"} < $W);
+ $E = $Node->{"lon"} if($Node->{"lon"} > $E);
+ }
+ return($S,$W,$N,$E);
+}
+
+# Function is called whenever an XML tag is started
+sub DoStart()
+{
+ my ($Expat, $Name, %Attr) = @_;
+
+ if($Name eq "node"){
+ undef %OsmXML::Tags;
+ %OsmXML::MainAttr = %Attr;
+ }
+ if($Name eq "segment"){
+ undef %OsmXML::Tags;
+ %OsmXML::MainAttr = %Attr;
+ }
+ if($Name eq "way"){
+ undef %OsmXML::Tags;
+ undef @OsmXML::WaySegments;
+ %OsmXML::MainAttr = %Attr;
+ }
+ if($Name eq "tag"){
+ $OsmXML::Tags{$Attr{"k"}} = $Attr{"v"};
+ }
+ if($Name eq "seg"){
+ push(@OsmXML::WaySegments, $Attr{"id"});
+ }
+}
+
+# Function is called whenever an XML tag is ended
+sub DoEnd(){
+ my ($Expat, $Element) = @_;
+ if($Element eq "node"){
+ my $ID = $OsmXML::MainAttr{"id"};
+ $OsmXML::Nodes{$ID}{"lat"} = $OsmXML::MainAttr{"lat"};
+ $OsmXML::Nodes{$ID}{"lon"} = $OsmXML::MainAttr{"lon"};
+ foreach(keys(%OsmXML::Tags)){
+ $OsmXML::Nodes{$ID}{$_} = $OsmXML::Tags{$_};
+ }
+ }
+ if($Element eq "segment"){
+ my $ID = $OsmXML::MainAttr{"id"};
+ $OsmXML::Segments{$ID}{"from"} = $OsmXML::MainAttr{"from"};
+ $OsmXML::Segments{$ID}{"to"} = $OsmXML::MainAttr{"to"};
+ foreach(keys(%OsmXML::Tags)){
+ $OsmXML::Segments{$ID}{$_} = $OsmXML::Tags{$_};
+ }
+ }
+ if($Element eq "way"){
+ my $ID = $OsmXML::MainAttr{"id"};
+ $OsmXML::Ways{$ID}{"segments"} = join(",",@OsmXML::WaySegments);
+ foreach(keys(%OsmXML::Tags)){
+ $OsmXML::Ways{$ID}{$_} = $OsmXML::Tags{$_};
+ }
+ }
+}
+
+# Function is called whenever text is encountered in the XML file
+sub DoChar(){
+ my ($Expat, $String) = @_;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+OsmXML - Module for reading OpenStreetMap XML data files
+
+=head1 SYNOPSIS
+
+ $OSM = new OsmXML();
+ $OSM->load("Data/nottingham.osm");
+
+ foreach $Way(%OsmXML::Ways){
+ @Segments = split(/,/, $Way->{"segments"});
+
+ foreach $SegmentID(@Segments){
+ $Segment = $OsmXML::Segments{$SegmentID};
+
+ $Node1 = $OsmXML::Nodes{$Segment->{"from"}};
+ $Node2 = $OsmXML::Nodes{$Segment->{"to"}};
+
+ printf "Node at %f,%f, named %s, is a %s",
+ $Node2->{"lat"},
+ $Node2->{"lon"},
+ $Node2->{"name"},
+ $Node2->{"highway"};
+ }
+ }
+
+=head1 AUTHOR
+
+Oliver White (oliver.white@blibbleblobble.co.uk)
+
+=head1 COPYRIGHT
+
+Copyright 2006, Oliver White
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/Planet.pm b/scripts/osm/perl_lib/Geo/OSM/Planet.pm
new file mode 100644
index 0000000..9530190
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/Planet.pm
@@ -0,0 +1,318 @@
+##################################################################
+package Geo::OSM::Planet;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( mirror_planet
+ osm_dir
+ planet_dir
+ UTF8sanitize
+ estimated_max_id
+ estimated_max_count
+ );
+
+use strict;
+use warnings;
+
+use HTTP::Request;
+use File::Basename;
+use File::Copy;
+use File::Path;
+use File::Slurp;
+use Getopt::Long;
+use HTTP::Request;
+use Storable ();
+use Data::Dumper;
+
+use Utils::File;
+use Utils::Debug;
+use Utils::LWP::Utils;
+
+
+# As of planet-061220
+my $estimations = {
+ 'way' => {
+ 'count' => 1986578,
+ 'max_id' => 6065507
+ },
+ 'elem' => {
+ 'count' => 206470511,
+ 'max_id' => 206470511
+ },
+ 'seg' => {
+ 'count' => 26718444,
+ 'max_id' => 44429733
+ },
+ 'segment' => {
+ 'count' => 28634826,
+ 'max_id' => 44356553
+ },
+ 'tag' => {
+ 'count' => 119070695,
+ 'max_id' => 1
+ },
+ 'node' => {
+ 'count' => 30059968,
+ 'max_id' => 49727934
+ },
+ 'line' => {
+ 'count' => 260506933,
+ 'max_id' => 206470511
+ }
+};
+
+# ------------------------------------------------------------------
+# This routine estimates the maximum id for way,elem,seg,...
+# The values are taken from older planet.osm Files
+# So they mostly are a little bit to low
+# ARGS:
+# $type: line|way|tag|...
+# RETURNS:
+# $result: number of estimated max_id
+sub estimated_max_id($){
+ my $type= shift;
+ unless ( defined ($estimations->{$type}->{max_id})) {
+ warn("\n estimated_max_id($type): unknown Tag-Type\n");
+ return 0;
+ };
+ return $estimations->{$type}->{max_id};
+}
+
+# ------------------------------------------------------------------
+# This routine estimates the maximim number of elements for way,elem,seg,...
+# The values are taken from older planet.osm Files
+# So they mostly are a little bit to low
+# ARGS:
+# $type: line|way|tag|...
+# RETURNS:
+# $result: number of estimated elements
+sub estimated_max_count($){
+ my $type= shift;
+ unless ( defined ($estimations->{$type}->{count})) {
+ warn("\n estimated_max_id($type): unknown Tag-Type\n");
+ return 0;
+ };
+ return $estimations->{$type}->{count};
+}
+
+# ------------------------------------------------------------------
+# returns the osm main directory for holding data
+sub osm_dir() {
+ # For later these are the defaults
+ # on where we can read/write
+ # ~/osm
+ # /var/data/osm
+ my $dir;
+
+ my $home = $ENV{HOME};
+ unless ( $home ) {
+ $home = `whoami`;
+ chomp $home;
+ $home = "/home/$home";
+ }
+
+ $dir = "$home/osm";
+ return $dir;
+}
+
+# ------------------------------------------------------------------
+# Returns (or sets) the directory where the planet.osm files will be found
+my $PLANET_DIR='';
+sub planet_dir(;$) {
+ my $new_dir=shift;
+
+ if ( $new_dir ) {
+ $PLANET_DIR = $new_dir;
+ } elsif( ! $PLANET_DIR) {
+ my $dir = osm_dir();
+ $PLANET_DIR = "$dir/planet";
+ }
+ return $PLANET_DIR;
+}
+
+
+# ------------------------------------------------------------------
+# mirror the newest planet.osm File to
+# ~/osm/planet/planet.osm.bz2
+# and the resulting
+# Filename is returned
+#
+# the file is -----NO LONGER--- Sanitized afterwards
+sub mirror_planet(){
+ my $planet_server="http://planet.openstreetmap.org";
+ my $url = "$planet_server";
+
+ my $mirror_dir=planet_dir();
+ mkdir_if_needed( $mirror_dir );
+
+ my $current_file;
+ if ( !$Utils::LWP::Utils::NO_MIRROR ) {
+ # Get Index.html of Planet.osm.org
+ my $apache_sort_hy_date="?C=M;O=D";
+ my $index_file="$mirror_dir/planet_index.html";
+ my $result = mirror_file("$url/$apache_sort_hy_date",$index_file);
+ if ( $result ) {
+ my $index_content = read_file( $index_file ) ;
+
+ # Get the current planet.osm File
+ my @all_files = ($index_content =~ m/(planet-\d\d\d\d\d\d.osm.bz2)/g);
+ ( $current_file ) = grep { $_ !~ m/planet-061008/ } @all_files;
+ if ( $current_file ) {
+ $url .= "/$current_file";
+ $current_file = "$mirror_dir/$current_file";
+ print STDERR "Mirror OSM Data from $url\n" if $VERBOSE || $DEBUG;
+ $result = mirror_file($url,$current_file);
+ #return undef unless $result;
+ }
+ }
+ }
+
+ my @files= sort { $b cmp $a}
+ grep { $_ !~ m/planet-061008/ }
+ glob("$mirror_dir/planet-*.osm.bz2");
+ if ( $DEBUG) {
+ print STDERR "Existing Files: \n\t".join("\n\t",@files)."\n";
+ }
+ $current_file = $files[0];
+
+ if ( $DEBUG) {
+ print STDERR "Choosen File: $current_file\n";
+ }
+
+ return undef unless $current_file;
+
+# $current_file = UTF8sanitize($current_file);
+# if ( $DEBUG >2 || $VERBOSE>3) {
+# print STDERR "Sanitized File: $current_file\n";
+# }
+
+ my ($unpacked_file) = ($current_file=~ m/(.*\.osm)/);
+ $current_file = $unpacked_file
+ unless file_needs_re_generation($current_file,$unpacked_file);
+
+ print STDERR "Mirror done, using '$current_file'\n" if $VERBOSE>1 || $DEBUG>1;
+ return $current_file;
+}
+
+# ------------------------------------------------------------------
+# creates a second file with a sanitized Version of planet.osm
+# the resulting file can be found at
+# ~/osm/planet/planet-07XXXX-a.osm.bz2
+# If a recent enought Version is found in ~/osm/planet/
+# nothing is done, but the filename of the file is returned
+# if the routine finds an uncompressed up to date Version
+# ~/osm/planet/planet-07XXXX-a.osm
+# this Filename is returned.
+sub UTF8sanitize($){
+ my $filename = shift;
+ if ( $DEBUG) {
+ print STDERR "UTF8sanitize($filename)\n";
+ }
+ my $start_time=time();
+
+ # the newer Files do not need to be sanitized
+ my ($file_date) = ($filename =~ m/planet-(\d+)/ );
+ return $filename
+ if ($file_date >= 061205) && ( $file_date < 061213);
+
+ my $filename_new= $filename;
+ $filename_new =~ s/\.osm/-a.osm/;
+ my $filename_new_check=newest_unpacked_filename($filename_new);
+
+ # check if planet-070101-a.osm[.bz2] is newer than planet-070101.osm.bz2
+ return $filename_new_check
+ unless file_needs_re_generation($filename,$filename_new_check);
+
+ # We have to create a new one
+ print STDERR "UTF8 Sanitize $filename ... \n";
+ # Uggly Hack, but for now it works
+ my $UTF8sanitizer=`which UTF8sanitizer`;
+ chomp $UTF8sanitizer;
+ unless ( -x $UTF8sanitizer ) {
+ $UTF8sanitizer=find_file_in_perl_path('../planet.osm/C/UTF8sanitizer');
+ }
+ die "Sanitizer not found\n" unless -x $UTF8sanitizer;
+ print STDERR "Sanitizer found at '$UTF8sanitizer'\n" if $DEBUG;
+
+ print STDERR " this may take some time ... \n";
+ my $cmd = "gzip -dc $filename | $UTF8sanitizer | bzip2 >$filename_new.part";
+ print "Command: $cmd" if $DEBUG || $VERBOSE;
+ my $result = `$cmd`;
+ print $result if $DEBUG || $VERBOSE;
+
+ print "Sanitized $filename " if $DEBUG || $VERBOSE;
+ print_time($start_time);
+
+ my $file_size = -s "$filename";
+ my $file_size_new = -s "$filename_new.part";
+ if ( $file_size_new < ($file_size*0.9) ) {
+ die "File Sanitize seems not successfull.\n".
+ "Original Size $file_size\n".
+ "Sanitized Size $file_size_new\n";
+ }
+ rename "$filename_new.part","$filename_new";
+ if ( ! -s $filename_new ) {
+ die "Cannot sanitize $filename\n";
+ }
+ print "now we have a sanitized $filename_new\n" if $DEBUG || $VERBOSE;
+ return $filename_new;
+}
+
+# ------------------------------------------------------------------
+# find a file in the current Perl Search path. For now this was the
+# easiest solution to find programms like UTF8Sanitize
+# ARGS: relative filename (relative to @INC-path
+# RETURNS: Absolute path to file
+sub find_file_in_perl_path($){
+ my $file = shift;
+
+ my $found_file = '';
+ for my $path ( @INC ) {
+ my $filename = "$path/$file";
+ print "find_file_in_perl_path: looking in '$filename'\n" if $DEBUG>2;
+ if ( -s $filename){
+ $found_file = $filename;
+ last;
+ };
+ }
+
+ print "find_file_in_perl_path($file): --> $found_file\n" if $DEBUG;
+ return $found_file;
+}
+
+# ------------------------------------------------------------------
+1;
+
+=head1 NAME
+
+Geo::OSM::Planet
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/SegmentList.pm b/scripts/osm/perl_lib/Geo/OSM/SegmentList.pm
new file mode 100644
index 0000000..21b1ce9
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/SegmentList.pm
@@ -0,0 +1,338 @@
+##################################################################
+package Geo::OSM::SegmentList;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( LoadOSM_segment_csv
+ reduce_segments_list
+ read_osm_file
+ load_segment_list
+ );
+
+use strict;
+use warnings;
+
+use Math::Trig;
+
+use Data::Dumper;
+use Geo::Geometry;
+use Geo::OSM::Planet;
+use Utils::Debug;
+use Utils::File;
+use Utils::Math;
+
+sub load_segment_list($){
+ my $do_filter_against_osm = shift;
+
+ my $osm_segments;
+ if ( -s $do_filter_against_osm ) {
+ if ( $do_filter_against_osm =~ m/\.csv/ ) {
+ $osm_segments = Geo::OSM::SegmentList::LoadOSM_segment_csv($do_filter_against_osm);
+ } elsif ( $do_filter_against_osm =~ m/\.osm/ ) {
+ $osm_segments = Geo::OSM::SegmentList::read_osm_file($do_filter_against_osm);
+ } else {
+ die "Unknown Datatype for $do_filter_against_osm\n";
+ }
+ #print Dumper(\$osm_segments ) if $DEBUG;
+ } elsif ( $do_filter_against_osm !~ m/^\d*$/ ) {
+ die "Unknown Datatype for $do_filter_against_osm\n";
+ } else {
+
+ # later we search in:
+ # ~/.osm/data/planet.osm.csv
+ # /var/data/osm/planet.osm.csv
+
+ my $home = $ENV{HOME}|| '~/';
+ my $path= planet_dir();
+ my $osm_filename = "${path}/csv/osm.csv";
+ $osm_filename =~ s,\~/,$home/,;
+ printf STDERR "check $osm_filename for loading\n" if $DEBUG;
+
+ die "Cannot open $osm_filename\n" unless -s $osm_filename;
+ $osm_segments = Geo::OSM::SegmentList::LoadOSM_segment_csv($osm_filename);
+ };
+ return $osm_segments
+}
+
+# ------------------------------------------------------------------
+# reduce osm Segments to only those inside the bounding box
+# This make comparison faster
+sub reduce_segments_list($$) {
+ my $all_osm_segments = shift;
+ my $bounds = shift;
+
+ my $start_time=time();
+
+ #printf STDERR "reduce_osm_segments(".Dumper(\$bounds).")\n" if $DEBUG;
+
+ my $osm_segments = [];
+ my $count=0;
+ my $all_count=0;
+ for my $segment ( @{$all_osm_segments} ) {
+ $all_count++;
+ next unless $segment->[0] >= $bounds->{lat_min};
+ next unless $segment->[0] <= $bounds->{lat_max};
+ next unless $segment->[1] >= $bounds->{lon_min};
+ next unless $segment->[1] <= $bounds->{lon_max};
+ next unless $segment->[2] >= $bounds->{lat_min};
+ next unless $segment->[2] <= $bounds->{lat_max};
+ next unless $segment->[3] >= $bounds->{lon_min};
+ next unless $segment->[3] <= $bounds->{lon_max};
+ $count++;
+ push(@{$osm_segments},$segment);
+ }
+ if ( $VERBOSE > 3 || $DEBUG > 3 ) {
+ printf STDERR " Reduced OSM Data to $count( $all_count) OSM-Segments ";
+ print_time($start_time);
+ }
+
+ return $osm_segments;
+}
+
+# -------------------------------------------------------
+# Load the csv Version of a segment list
+sub LoadOSM_segment_csv($)
+{
+ my $filename = shift;
+
+ printf STDERR "Reading OSM File: $filename\n"
+ if $DEBUG || $VERBOSE;
+ my $start_time=time();
+
+ my $segments;
+
+ if ( -s "$filename.storable" &&
+ ! file_needs_re_generation($filename,"$filename.storable")) {
+ # later we should compare if the file also is newer than the source
+ $filename .= ".storable";
+ $segments = Storable::retrieve($filename);
+ } else {
+ my $fh = data_open($filename);
+
+ die "Cannot open $filename in LoadOSM_segment_csv.\n".
+ "Please create it first to use the option --osm.\n".
+ "See --help for more info" unless $fh;
+
+ while ( my $line = $fh ->getline() ) {
+ my @segment;
+ my $dummy;
+ ($segment[0],$segment[1],$segment[2],$segment[3],$dummy) = split(/,/,$line,5);
+ $segment[4] = angle_north_relative(
+ { lat => $segment[0] , lon => $segment[1] },
+ { lat => $segment[2] , lon => $segment[3] });
+ $segment[5] = $dummy if $DEBUG;
+ push (@{$segments},\@segment);
+ }
+ $fh->close();
+ Storable::store($segments ,"$filename.storable");
+ }
+
+ if ( $VERBOSE >1 || $DEBUG) {
+ printf STDERR "Read and parsed $filename";
+ print_time($start_time);
+ }
+
+ return($segments);
+}
+
+
+# ----------------------
+sub Storable_save($$){
+ my $filename = shift;
+ my $segments = shift;
+ eval{
+ Storable::store($segments ,"$filename.storable");
+ };
+ if ( $@ ) {
+ #warn Dumper(\$segments);
+ die "Storable_save(): $@\n";
+ }
+ printf STDERR "Stored OSM File: $filename as storable\n"
+ if $DEBUG || $VERBOSE;
+}
+
+# ----------------------
+sub Storable_load($){
+ my $filename = shift;
+ $filename .= ".storable";
+ my $segments = Storable::retrieve($filename);
+ printf STDERR "Loaded OSM File: $filename as storable\n"
+ if $DEBUG || $VERBOSE;
+ return $segments;
+}
+
+##################################################################
+# read Segment list from osm File
+##################################################################
+
+our $read_osm_nodes;
+our $read_osm_segments;
+our $read_osm_obj;
+
+sub node_ {
+ $read_osm_obj = undef;
+}
+sub node {
+ my($p, $tag, %attrs) = @_;
+
+ my $id = delete $attrs{id};
+ $read_osm_obj = {};
+ $read_osm_obj->{id} = $id;
+
+ $read_osm_obj->{lat} = delete $attrs{lat};
+ $read_osm_obj->{lon} = delete $attrs{lon};
+
+ delete $attrs{timestamp};
+ delete $attrs{action};
+ delete $attrs{visible};
+ delete $attrs{user};
+
+ if ( keys %attrs ) {
+ warn "node $id has extra attrs: ".Dumper(\%attrs);
+ }
+
+ $read_osm_nodes->{$id} = $read_osm_obj;
+}
+
+# ----------------------
+sub segment_ {
+ $read_osm_obj = undef;
+}
+sub segment {
+ my($p, $tag, %attrs) = @_;
+
+ my $id = delete $attrs{id};
+ $read_osm_obj = {};
+ $read_osm_obj->{id} = $id;
+
+ $read_osm_obj->{from} = delete $attrs{from};
+ $read_osm_obj->{to} = delete $attrs{to};
+
+ delete $attrs{timestamp};
+ delete $attrs{action};
+ delete $attrs{visible};
+ delete $attrs{user};
+
+ if ( keys %attrs ) {
+ warn "segment $id has extra attrs: ".Dumper(\%attrs);
+ }
+
+ my @segment;
+ my $dummy;
+ my $node1 = $read_osm_nodes->{$read_osm_obj->{from}};
+ my $node2 = $read_osm_nodes->{$read_osm_obj->{to}};
+ ($segment[0],$segment[1],$segment[2],$segment[3]) =
+ ($node1->{lat},$node1->{lon},$node2->{lat},$node2->{lon});
+
+ $segment[4] = angle_north_relative(
+ { lat => $segment[0] , lon => $segment[1] },
+ { lat => $segment[2] , lon => $segment[3] });
+ #$segment[5] = $attrs{name} if $DEBUG;
+ push (@{$read_osm_segments},\@segment);
+}
+
+# ----------------------
+sub way_ {
+ $read_osm_obj = undef;
+}
+sub way {
+ my($p, $tag, %attrs) = @_;
+
+ my $id = delete $attrs{id};
+}
+
+# ----------------------
+sub tag {
+ my($p, $tag, %attrs) = @_;
+ #print "Tag - $tag: ".Dumper(\%attrs);
+ my $k = delete $attrs{k};
+ my $v = delete $attrs{v};
+
+ return if $k eq "created_by";
+
+ if ( keys %attrs ) {
+ print "Unknown Tag value for ".Dumper($read_osm_obj)."Tags:".Dumper(\%attrs);
+ }
+
+ my $id = $read_osm_obj->{id};
+ if ( defined( $read_osm_obj->{tag}->{$k} ) &&
+ $read_osm_obj->{tag}->{$k} ne $v
+ ) {
+ if ( $DEBUG >1 ) {
+ printf STDERR "Tag %8s already exists for obj tag '$read_osm_obj->{tag}->{$k}' ne '$v'\n",$k ;
+ }
+ }
+ $read_osm_obj->{tag}->{$k} = $v;
+ if ( $k eq "alt" ) {
+ $read_osm_obj->{alt} = $v;
+ }
+}
+
+# --------------------------------------------
+sub read_osm_file($) { # Insert Segments from osm File
+ my $filename = shift;
+
+ if ( file_needs_re_generation($filename,"$filename.storable")) {
+ print("Reading OSM Segment from File $filename\n") if $VERBOSE || $DEBUG;
+ print "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+
+ print STDERR "Parsing file: $filename\n" if $DEBUG;
+ my $p = XML::Parser->new( Style => 'Subs' ,
+ ErrorContext => 10,
+ );
+
+ my $fh = data_open($filename);
+ if (not $fh) {
+ print STDERR "WARNING: Could not open osm data from $filename\n";
+ return;
+ }
+ my $content = $p->parse($fh);
+ if (not $p) {
+ print STDERR "WARNING: Could not parse osm data from $filename\n";
+ return;
+ }
+ #warn Dumper(\$read_osm_segments);
+ Storable_save($filename,$read_osm_segments);
+ } else {
+ $read_osm_segments=Storable_load($filename);
+ }
+ return($read_osm_segments);
+}
+
+# -------------------------------------------------------
+
+1;
+
+=head1 NAME
+
+Geo::OSM::SegmentList
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/Tracks2OSM.pm b/scripts/osm/perl_lib/Geo/OSM/Tracks2OSM.pm
new file mode 100644
index 0000000..1c5337e
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/Tracks2OSM.pm
@@ -0,0 +1,234 @@
+##################################################################
+package Geo::OSM::Tracks2OSM;
+# Functions:
+# tracks2osm:
+# converts a tracks Hash to an OSM Datastructure
+#
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( tracks2osm );
+
+use strict;
+use warnings;
+
+use Data::Dumper;
+
+use Geo::Geometry;
+use Geo::Tracks::Tools;
+use Utils::Debug;
+use Utils::File;
+use Utils::Math;
+
+my $first_id = -10000;
+
+my $lat_lon2node={};
+my $next_osm_node_number = $first_id;
+my $osm_nodes_duplicate = {};
+# Check if a node at this position exists
+# if it exists we get the old id; otherwise we create a new one
+sub create_node($$) {
+ my $osm_nodes = shift;
+ my $elem = shift;
+
+ printf STDERR "create_node(): lat or lon undefined : $elem->{lat},$elem->{lon} ".Dumper(\$elem)."\n"
+ unless defined($elem->{lat}) && defined($elem->{lon}) ;
+
+ my $id=0;
+ my $lat_lon = sprintf("%f_%f",$elem->{lat},$elem->{lon});
+ if ( defined( $osm_nodes_duplicate->{$lat_lon} ) ) {
+ $id = $osm_nodes_duplicate->{$lat_lon};
+ printf STDERR "Node already exists as $id pos:$lat_lon\n"
+ if $DEBUG>2;
+ $osm_nodes->{$id}=$elem;
+ # TODO: We have to check that the tags of the old and new nodes don't differ
+ # or we have to merge them
+ } else {
+ $next_osm_node_number--;
+ $id = $next_osm_node_number;
+ $elem->{tag}->{converted_by} = "Track2osm" ;
+ $osm_nodes->{$id}=$elem;
+ $lat_lon2node->{$lat_lon}=$id;
+ $osm_nodes_duplicate->{$lat_lon}=$id;
+ };
+ if ( !$id ) {
+ print STDERR "create_node(): Null node($id,$lat_lon) created\n".
+ Dumper($elem)
+ if $DEBUG;
+ }
+ return $id;
+}
+
+my $next_osm_segment_number = $first_id;
+my $osm_segments_duplicate= {};
+sub create_segment($$){
+ my $elem = shift;
+ my $osm_segments = shift;
+
+ my $seg_id = 0;
+ my $from_to = $elem->{from}.",".$elem->{to};
+ if ( defined($osm_segments_duplicate->{$from_to}) ) {
+ $seg_id = $osm_segments_duplicate->{$from_to};
+ printf STDERR "Duplicate segment $next_osm_segment_number --> $seg_id\n";
+ } else {
+ $next_osm_segment_number--;
+ $seg_id=$next_osm_segment_number;
+ $elem->{tag}->{converted_by} = "Track2osm" ;
+ $osm_segments->{$seg_id} = {
+ from => $elem->{from},
+ to => $elem->{to},
+ tag => $elem->{tag},
+ };
+ };
+ return $seg_id;
+}
+
+my $next_osm_way_number = $first_id;
+# ------------------------------------------------------------------
+sub tracks2osm($){
+ my $tracks = shift;
+
+
+ my $osm_nodes = {};
+ my $osm_segments = {};
+ my $osm_ways = {};
+ my $reference = $tracks->{filename};
+
+ my $last_angle = 999999999;
+ my $angle;
+ my $way={};
+ my $angle_to_last;
+
+
+ my $count_valid_points_for_ways=0;
+
+ # TODO: We have to find a better solution for this
+ my $generate_ways=$main::generate_ways;
+
+ my $track_nr=0;
+
+ enrich_tracks($tracks);
+
+ for my $track ( @{$tracks->{tracks}} ) {
+ $track_nr++;
+
+ my $element_count=0;
+ my $last_elem = $track->[0];
+ $last_elem->{node_id}=create_node($osm_nodes,$last_elem);
+
+ for my $track_pos ( 1 .. $#{@{$track}} ) {
+ my $elem = $track->[$track_pos];
+
+ my $seg_id=0;
+ my $dist=$last_elem->{dist};
+
+ # -------------------------------------------- Create Nodes
+ my $from = $last_elem->{node_id};
+ my $to = $elem->{node_id} || create_node($osm_nodes,$elem);
+ $elem->{node_id} ||= $to;
+
+ # -------------------------------------------- Create Segments
+ if ( ! $from ) {
+ printf STDERR "From Part of Segment not existent $from -> $to\n"
+ if $DEBUG >2;
+ next;
+ }
+ if ( $from == $to ) {
+ printf STDERR "Null length Segment $from -> $to Track: $track_nr Pos:$track_pos\n"
+ if $DEBUG >2;
+ next;
+ }
+ my $tags = {"converted_by" => "Track2osm"};
+ if ( $DEBUG >10 ) {
+ $tags->{distance} = $dist;
+ $tags->{distance_meter} = $dist*1000;
+ $tags->{reference} = "$reference $track_pos, Track:$track_nr";
+ $tags->{from_to} = "$from $to";
+ };
+ if ( $DEBUG >12 ) {
+ for my $k ( keys %{$elem} ) {
+ next if $k =~ m/^sat_/;
+ $tags->{$k}=$elem->{$k};
+ }
+ }
+
+ $seg_id = create_segment(
+ {
+ from => $from,
+ to => $to,
+ tag => $tags,
+ },$osm_segments);
+
+
+ # -------------------------------------------- Create Ways
+ if ( $generate_ways ) {
+ $angle=$elem->{angle};
+ $last_angle = $last_elem->{angle};
+
+ if ( ! $seg_id # Wir haben ein neues Segment
+ || abs($last_angle) > 25 # over x Grad Lenkeinschlag
+ || $dist > 5 # more than x Km Distance
+ ) {
+ if ( defined($way->{seg})
+ && ( @{$way->{seg}} > 4)
+ ) {
+ $next_osm_way_number--;
+ if ( $DEBUG >10 ) {
+ $way->{reference} = $reference;
+ }
+ $osm_ways->{$next_osm_way_number} = $way;
+ }
+ $way={};
+ }
+
+ push(@{$way->{seg}},$seg_id);
+ $count_valid_points_for_ways++;
+
+ my $tags = {"converted_by" => "Track2osm"};
+ $way->{tag} = $tags;
+ }
+
+ $last_elem=$elem;
+ }
+ }
+ return { nodes => $osm_nodes,
+ segments => $osm_segments,
+ ways => $osm_ways,
+ };
+}
+
+
+
+=head1 NAME
+
+Geo::OSM::Track2OSM
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/OSM/Upload.pm b/scripts/osm/perl_lib/Geo/OSM/Upload.pm
new file mode 100644
index 0000000..da18e97
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/Upload.pm
@@ -0,0 +1,145 @@
+package osm;
+
+use strict;
+use warnings;
+
+
+use WWW::Curl::easy;
+
+sub new(){bless{}};
+
+sub setup(){
+ my $self = shift();
+ $self->{Username} = shift();
+ $self->{Password} = shift();
+ $self->{UserAgent} = shift();
+}
+
+sub tempfiles(){
+ my $self = shift();
+ $self->{file1} = shift();
+ $self->{file2} = shift();
+}
+
+sub uploadWay(){
+ my ($self, $Tags, @Segments) = @_;
+ $Tags .= sprintf("<tag k=\"created_by\" v=\"%s\"/>", $self->{UserAgent});
+
+ my $Segments = "";
+ foreach $Segment(@Segments){
+ $Segments .= "<seg id=\"$Segment\"/>";
+ }
+
+ my $Way = "<way id=\"0\">$Segments$Tags</way>";
+ my $OSM = "<osm version=\"0.3\">$Way</osm>";
+ my $data = "<?xml version=\"1.0\"?>\n$OSM";
+ my $path = "way/0";
+
+ my ($response, $http_code) = $self->upload($data, $path);
+ return($response);
+}
+
+sub uploadSegment(){
+ my ($self, $Node1,$Node2,$Tags) = @_;
+ $Tags .= sprintf("<tag k=\"created_by\" v=\"%s\"/>", $self->{UserAgent});
+
+ my $Segment = sprintf("<segment id=\"0\" from=\"%d\" to=\"%d\">$Tags</segment>", $Node1,$Node2);
+ my $OSM = "<osm version=\"0.3\">$Segment</osm>";
+ my $data = "<?xml version=\"1.0\"?>\n$OSM";
+ my $path = "segment/0";
+
+ my ($response, $http_code) = $self->upload($data, $path);
+
+
+ return($response);
+}
+
+sub uploadNode(){
+ my ($self, $Lat, $Long, $Tags) = @_;
+ $Tags .= sprintf("<tag k=\"created_by\" v=\"%s\"/>", $self->{UserAgent});
+
+ my $Node = sprintf("<node id=\"0\" lon=\"%f\" lat=\"%f\">$Tags</node>", $Long, $Lat);
+ my $OSM = "<osm version=\"0.3\">$Node</osm>";
+ my $data = "<?xml version=\"1.0\"?>\n$OSM";
+ my $path = "node/0";
+
+ my ($response, $http_code) = $self->upload($data, $path);
+
+ return($response);
+}
+
+sub upload(){
+ my($self, $data, $path) = @_;
+
+ my $curl = new WWW::Curl::easy;
+
+ my $login = sprintf("%s:%s", $self->{Username}, $self->{Password});
+
+ open(my $FileToSend, ">", $self->{file1});
+ print $FileToSend $data;
+ close $FileToSend;
+
+ my $url = "http://www.openstreetmap.org/api/0.3/$path";
+
+ open(my $TxFile, "<", $self->{file1});
+ open(my $RxFile, ">",$self->{file2});
+ $curl->setopt(CURLOPT_URL,$url);
+ $curl->setopt(CURLOPT_RETURNTRANSFER,-1);
+ $curl->setopt(CURLOPT_HEADER,0);
+ $curl->setopt(CURLOPT_USERPWD,$login);
+ $curl->setopt(CURLOPT_PUT,-1);
+ $curl->setopt(CURLOPT_INFILE,$TxFile);
+ $curl->setopt(CURLOPT_INFILESIZE, -s $self->{file1});
+ $curl->setopt(CURLOPT_FILE, $RxFile);
+
+ $curl->perform();
+ my $http_code = $curl->getinfo(CURLINFO_HTTP_CODE);
+ my $err = $curl->errbuf;
+ $curl->close();
+ close $TxFile;
+ close $RxFile;
+
+ open(my $ResponseFile, "<", $self->{file2});
+ my $response = int(<$ResponseFile>);
+ close $ResponseFile;
+
+ print "Code $http_code\n" if($http_code != 200);
+
+ return($response, $http_code);
+}
+
+1;
+
+
+=head1 NAME
+
+Geo::OSM::Upload
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
+
diff --git a/scripts/osm/perl_lib/Geo/OSM/Write.pm b/scripts/osm/perl_lib/Geo/OSM/Write.pm
new file mode 100644
index 0000000..c7b4bc3
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/OSM/Write.pm
@@ -0,0 +1,179 @@
+##################################################################
+package Geo::OSM::Write;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( write_osm_file );
+
+use strict;
+use warnings;
+
+use Math::Trig;
+use Data::Dumper;
+
+use Geo::Geometry;
+use Utils::Debug;
+use Utils::File;
+use Utils::Math;
+
+
+# ------------------------------------------------------------------
+sub tags2osm($){
+ my $obj = shift;
+
+ my $erg = "\n";
+ for my $k ( keys %{$obj->{tag}} ) {
+ my $v = $obj->{tag}{$k};
+ if ( ! defined $v ) {
+ warn "incomplete Object: ".Dumper($obj);
+ }
+ #next unless defined $v;
+
+ # character escaping as per http://www.w3.org/TR/REC-xml/
+ $v =~ s/&/&amp;/g;
+ $v =~ s/\'/&apos;/g;
+ $v =~ s/</&lt;/g;
+ $v =~ s/>/&gt;/g;
+ $v =~ s/\"/&quot;/g;
+
+ $erg .= " <tag k=\'$k\' v=\'$v\' />\n";
+ }
+ return $erg;
+}
+
+sub write_osm_file($$) { # Write an osm File
+ my $filename = shift;
+ my $osm = shift;
+
+ my $osm_nodes = $osm->{nodes};
+ my $osm_segments = $osm->{segments};
+ my $osm_ways = $osm->{ways};
+
+ $osm->{tool} ||= "OSM-Tool";
+ my $count_nodes = 0;
+ my $count_segments = 0;
+ my $count_ways = 0;
+
+ my $generate_ways=$main::generate_ways;
+
+ my $start_time=time();
+
+ printf STDERR ("Writing OSM File $filename\n") if $VERBOSE >1 || $DEBUG>1;
+
+ my $fh;
+ if ( $filename eq "-" ) {
+ $fh = IO::File->new('>&STDOUT');
+ $fh or die("cannot open STDOUT: $!");
+ } else {
+ $fh = IO::File->new(">$filename");
+ }
+ $fh->binmode(':utf8');
+
+ print $fh "<?xml version='1.0' encoding='UTF-8'?>\n";
+ print $fh "<osm version=\'0.4\' generator=\'".$osm->{tool}."\'>\n";
+
+ # --- Nodes
+ for my $node_id ( sort keys %{$osm_nodes} ) {
+ next unless $node_id;
+ my $node = $osm_nodes->{$node_id};
+ my $lat = $node->{lat};
+ my $lon = $node->{lon};
+ unless ( defined($lat) && defined($lon)){
+ printf STDERR "Node '$node_id' not complete\n";
+ next;
+ }
+ print $fh " <node id=\'$node_id\' ";
+ print $fh " timestamp=\'".$node->{timestamp}."\' "
+ if defined $node->{timestamp};
+ print $fh " lat=\'$lat\' ";
+ print $fh " lon=\'$lon\' ";
+ print $fh ">\t";
+ print $fh tags2osm($node);
+ print $fh " </node>\n";
+ $count_nodes++;
+ }
+
+ # --- Segments
+ for my $segment_id ( sort keys %{$osm_segments} ) {
+ next unless $segment_id;
+ my $segment = $osm_segments->{$segment_id};
+ my $node_from = $segment->{from};
+ my $node_to = $segment->{to};
+ print $fh " <segment id=\'$segment_id\' ";
+ print $fh " timestamp=\'".$segment->{timestamp}."\' "
+ if defined $segment->{timestamp};
+ print $fh " from=\'$node_from\' ";
+ print $fh " to=\'$node_to\' ";
+ print $fh ">";
+ print $fh tags2osm($segment);
+ print $fh " </segment>\n";
+ $count_segments++;
+ }
+
+ # --- Ways
+ for my $way_id ( sort keys %{$osm_ways} ) {
+ next unless $way_id;
+ my $way = $osm_ways->{$way_id};
+ print $fh " <way id=\'$way_id\'";
+ print $fh " timestamp=\'".$way->{timestamp}."\'"
+ if defined $way->{timestamp};
+ print $fh ">";
+ print $fh tags2osm($way);
+
+ for my $seg_id ( @{$way->{seg}} ) {
+ next unless $seg_id;
+ print $fh " <seg id=\'$seg_id\'";
+ print $fh " />\n";
+ }
+ print $fh " </way>\n";
+ $count_ways++;
+
+ }
+
+ print $fh "</osm>\n";
+ $fh->close();
+
+ if ( $VERBOSE || $DEBUG ) {
+ printf STDERR "%-35s: ",$filename;
+ printf STDERR " Wrote OSM File ".
+ "($count_nodes Nodes, $count_segments Segments, $count_ways Ways)";
+ print_time($start_time);
+ }
+
+}
+
+1;
+
+=head1 NAME
+
+Geo::OSM::Write
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Tracks/GpsBabel.pm b/scripts/osm/perl_lib/Geo/Tracks/GpsBabel.pm
new file mode 100644
index 0000000..a531694
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Tracks/GpsBabel.pm
@@ -0,0 +1,82 @@
+##################################################################
+package Geo::Tracks::GpsBabel;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( read_track_GpsBabel );
+
+use strict;
+use warnings;
+use IO::File;
+
+use Geo::Geometry;
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+use Geo::GPX::File;
+
+
+# -----------------------------------------------------------------------------
+# Read GPS Data with the help of gpsbabel converting a file to a GPX-File
+sub read_track_GpsBabel($$) {
+ my $filename = shift;
+ my $gpsbabel_type = shift;
+
+ my $data = {
+ filename => $filename,
+ tracks => [],
+ wpt => [],
+ };
+
+ printf STDERR ("Reading $filename\n") if $VERBOSE>1 || $DEBUG;
+ printf STDERR "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+
+ my $gpsbabel_call="gpsbabel -i $gpsbabel_type -f '$filename' -o gpx -F - ";
+ printf STDERR "calling gpsbabel:\n$gpsbabel_call\n " if $DEBUG>3;
+ my $fh = IO::File->new("$gpsbabel_call |");
+ if ( !$fh ) {
+ warn "Cannot Convert $filename as Type $gpsbabel_type\n";
+ return $data;
+ }
+ $data = read_gpx_file($fh);
+ $data->{filename} = $filename;
+ return $data;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+GpsBabel.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Tracks/Kismet.pm b/scripts/osm/perl_lib/Geo/Tracks/Kismet.pm
new file mode 100644
index 0000000..e62fc2e
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Tracks/Kismet.pm
@@ -0,0 +1,125 @@
+##################################################################
+package Geo::Tracks::Kismet;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( read_kismet_file );
+
+use strict;
+use warnings;
+
+use Math::Trig;
+use Date::Parse;
+use Data::Dumper;
+
+use Data::Dumper;
+use Geo::Geometry;
+use Utils::Debug;
+use Utils::File;
+use Utils::Math;
+
+# -----------------------------------------------------------------------------
+# Read GPS Data from Kismet File
+sub read_kismet_file($) {
+ my $filename = shift;
+
+ my $start_time=time();
+
+ my $data = {
+ filename => $filename,
+ tracks => [],
+ wpt => [],
+ };
+
+ printf STDERR ("Reading $filename\n") if $VERBOSE>1 || $DEBUG;
+ printf STDERR "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+
+ print STDERR "Parsing file: $filename\n" if $DEBUG;
+ my $p = XML::Parser->new( Style => 'Objects' ,
+ );
+
+ my $fh = data_open($filename);
+ return $data unless $fh;
+ my $content = [{Kids => []}];
+ eval {
+ $content = $p->parse($fh);
+ };
+ if ( $@ ) {
+ warn "$@Error while parsing\n $filename\n";
+ printf STDERR Dumper(\$content);
+ #return $content->[0]->{Kids};
+ }
+ if (not $p) {
+ print STDERR "WARNING: Could not parse osm data\n";
+ return $data;
+ }
+ if ( $DEBUG ) {
+ printf STDERR "Read and parsed $filename";
+ print_time($start_time);
+ }
+ my $track=[];
+ for my $elem ( @{$content->[0]->{Kids}} ) {
+ next unless ref($elem) eq "Geo::Tracks::Kismet::gps-point";
+ next unless $elem->{'bssid'} eq 'GP:SD:TR:AC:KL:OG';
+ delete $elem->{Kids};
+ if ( defined($elem->{"time-sec"}) && defined($elem->{"time-usec"}) ) {
+ $elem->{time} = $elem->{"time-sec"}+($elem->{"time-usec"}/1000000);
+ #printf STDERR "$elem->{time} = $elem->{'time-sec'} $elem->{'time-usec'}\n";
+ }
+ delete $elem->{'time-sec'};
+ delete $elem->{'time-usec'};
+ delete $elem->{'bssid'};
+ delete $elem->{'signal'};
+ delete $elem->{'quality'};
+ delete $elem->{'noise'};
+ $elem->{'speed'} = delete($elem->{'spd'}) * 1;
+ if ( $DEBUG > 10 ) {
+ printf STDERR "read element: ".Dumper(\$elem);
+ }
+ push(@{$track},$elem);
+ };
+
+# printf STDERR Dumper(\$track);
+
+ $data->{tracks}=[$track];
+ return $data;
+}
+
+1;
+
+
+__END__
+
+=head1 NAME
+
+Kismet.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Tracks/NMEA.pm b/scripts/osm/perl_lib/Geo/Tracks/NMEA.pm
new file mode 100644
index 0000000..7cbb665
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Tracks/NMEA.pm
@@ -0,0 +1,373 @@
+##################################################################
+package Geo::Tracks::NMEA;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( read_track_NMEA );
+
+use strict;
+use warnings;
+
+use Data::Dumper;
+use Date::Manip;
+use Date::Parse;
+use IO::File;
+use Math::Trig;
+
+use Geo::Geometry;
+use Utils::Debug;
+use Utils::File;
+use Utils::Math;
+
+# -----------------------------------------------------------------------------
+# Read GPS Data from NMEA - File
+sub read_track_NMEA($) {
+ my $filename = shift;
+
+ my $start_time=time();
+
+ my $new_tracks={
+ filename => $filename,
+ tracks => [],
+ wpt => []
+ };
+ printf STDERR ("Reading $filename\n") if $VERBOSE || $DEBUG;
+ printf STDERR "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+
+ my $fh = data_open($filename);
+ return $new_tracks unless $fh;
+ my $elem ={};
+ my $last_date='';
+ my $last_time=0;
+ my $new_track=[];
+ my ($sat,$pdop,$hdop,$vdop,$sat_count);
+ my $sat_time = 0;
+ my $dop_time = 0;
+ my $IS_grosser_reiseplaner=0;
+ while ( my $line = $fh->getline() ) {
+ my ($dummy,$type,$time,$status,$lat,$lat_v,$lon,$lon_v,$speed,$alt);
+ my ($date,$mag_variation,$checksumm,$quality,$alt_unit);
+ $alt=0;
+ chomp $line;
+
+ my $full_line = $line;
+
+ $IS_grosser_reiseplaner++ if $line =~ m/Logfile for travel center/;
+
+ # Grosser Reisseplaner Line:
+ # 16.08.06 15:47:23 GPGGA,134851.835,4807.8129,N,01136.6276,E,1,04,12.8,815.8,M,47.5,M,0.0,0000*42
+ if ($IS_grosser_reiseplaner){
+ if ( $line !~ s/^\d\d\.\d\d.\d\d \d\d:\d\d:\d\d GP/\$GP/ ) {
+ printf STDERR "ERROR in Grosser Reiseplaner: $full_line\n"
+ if $DEBUG>1;
+ next;
+ };
+ }
+
+
+ # Checksumm is at line-end: for example *EA
+ if ( $line =~ s/\*([\dABCDEF]{2})\s*$// ){
+ $checksumm=$1;
+ } else {
+ print "WARNING Checksumm is missing\n";
+ printf STDERR "Line: $full_line\n"
+ if $DEBUG>1;
+ next;
+ }
+
+ # Destinator Line: 160849.006,A,4606.6122,N,01819.4709,E,047.1,074.2,290705,003.1,E*6C^M
+ if ( $line =~ m/^\d+\.\d+,A,\d+\.\d+,[NS],\d+\.\d+,[EW],\d+\.\d+,\d+\.\d+,\d+,\d+\.\d+,(\S+)$/){
+ $type = "RMC";
+ } else {
+ ($type,$line) = split( /,/,$line,2);
+ }
+ $type =~ s/^\s*\$?//; # TomTom GO logger is missing the $ sign this is the reason for \$?
+ if ( $type !~ s/^GP// ){
+ print "WARNING Type is wrong: $type\n";
+ printf STDERR "Line: $line\n"
+ if $DEBUG>1;
+ next;
+ }
+ my $count_line=$line;
+ $count_line =~ s/[^,]//g;
+ my $elem_count = length($count_line);
+ printf STDERR "Type: $type, line: $line, checksumm:$checksumm, elem#: $elem_count\n"
+ if $DEBUG>4;
+
+ my $elem_soll ={
+ GGA => 13,
+ RMC => 10,
+ GSA => 16,
+ GSV => 18,
+ VTG => 7,
+ GLL => 5,
+ ZDA => 5,
+ };
+
+ if ( $type =~ m/RMC/ && ( $elem_count != 10 ) && ( $elem_count != 11 ) ){
+ print "!!!!!!! ERROR $elem_count is wrong Number of elements(should be $elem_soll->{$type}): $full_line\n";
+ next;
+ } elsif ( $type !~ m/GSV|GSA/ && $elem_count != $elem_soll->{$type} ){
+ print "!!!!!!! ERROR $elem_count is wrong Number of elements(should be $elem_soll->{$type}): $full_line\n";
+ next;
+ }
+
+
+ if ( $type eq "VTG" ) {
+ } elsif ( $type eq "GGA" ) {
+ # GGA - Global Positioning System Fix Data
+ # Time, Position and fix related data fora GPS receiver.
+ # 1 2 3 4 5 6 7 8 9 10 | 12 13 14 15
+ # | | | | | | | | | | | | | | |
+ # $--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>
+ # 1) Universal Time Coordinated (UTC)
+ # 2) Latitude
+ # 3) N or S (North or South)
+ # 4) Longitude
+ # 5) E or W (East or West)
+ # 6) GPS Quality Indicator, 0 - fix not available, 1 - GPS fix, 2 - Differential GPS fix
+ # 7) Number of satellites in view, 00 - 12
+ # 8) Horizontal Dilution of precision
+ # 9) Antenna Altitude above/below mean-sea-level (geoid)
+ # 10) Units of antenna altitude, meters
+ # 11) Geoidal separation, the difference between the WGS-84 earth
+ # ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid
+ # 12) Units of geoidal separation, meters
+ # 13) Age of differential GPS data, time in seconds since last SC104
+ # type 1 or 9 update, null field when DGPS is not used
+ # 14) Differential reference station ID, 0000-1023
+ # 15) Checksum
+ ($time,$lat,$lat_v,$lon,$lon_v,$quality,$dummy,$dummy,$alt,$alt_unit,
+ $dummy,$dummy,$dummy)
+ = split(/,/,$line);
+ printf STDERR "GGA: (time: $time, la: $lat,$lat_v, lo: $lon,$lon_v, Q: $quality, Alt: $alt,$alt_unit)\n"
+ if $DEBUG>4;
+ } elsif ( $type eq "RMC" ) {
+ # RMC - Recommended Minimum Navigation Information
+ # 1 2 3 4 5 6 7 8 9 10 11|
+ # | | | | | | | | | | | |
+ # $--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxx,x.x,a*hh<CR><LF>
+ # 1) UTC Time
+ # 2) Status, V = Navigation receiver warning
+ # 3) Latitude
+ # 4) N or S
+ # 5) Longitude
+ # 6) E or W
+ # 7) Speed over ground, knots
+ # 8) Track made good, degrees true
+ # 9) Date, ddmmyy
+ # 10) Magnetic Variation, degrees
+ # 11) E or W
+ # 12) Checksum
+ ($time,$status,$lat,$lat_v,$lon,$lon_v,$speed,$dummy,$date,$mag_variation)
+ = split(/,/,$line);
+ printf STDERR "RMC: (Time: $time,Status: $status, la: $lat,$lat_v, lo: $lon,$lon_v, Speed: $speed)\n"
+ if $DEBUG >4;
+ } elsif ( $type eq "GSA" ) {
+ # GSA - GPS DOP and active satellites
+ # 1 2 3 14 15 16 17 18
+ # | | | | | | | |
+ # $--GSA,a,a,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x.x,x.x,x.x*hh<CR><LF>
+ # Field Number:
+ # 1) Selection mode
+ # 2) Mode
+ # 3) ID of 1st satellite used for fix
+ # ...
+ # 14) ID of 12th satellite used for fix
+ # 15) PDOP in meters
+ # 16) HDOP in meters
+ # 17) VDOP in meters
+ # 18) checksum
+ ($dummy,$dummy,$dummy,$dummy,$dummy,$dummy,$dummy,$dummy,$dummy,$dummy,
+ $dummy,$dummy,$dummy,$dummy,$pdop,$hdop,$vdop)
+ = split(/,/,$line);
+ $hdop = undef unless $hdop =~ m/[\d\-\+]+/;
+ $vdop = undef unless $vdop =~ m/[\d\-\+]+/;
+ $pdop = undef unless $pdop =~ m/[\d\-\+]+/;
+ $dop_time=$last_time;
+ next;
+ } elsif ( $type eq "GSV" ) {
+ # GSV - Satellites in view
+ #
+ # 1 2 3 4 5 6 7 n
+ # | | | | | | | |
+ # $--GSV,x,x,x,x,x,x,x,...*hh<CR><LF>
+ # Field Number:
+ # 1) total number of messages
+ # 2) message number
+ # 3) satellites in view
+ # 4) satellite number
+ # 5) elevation in degrees
+ # 6) azimuth in degrees to true
+ # 7) SNR in dB
+ # more satellite infos like 4)-7)
+ # n) checksum
+ my ($msg_anz,$msg_no,$rest);
+ ($msg_anz,$msg_no,$sat_count,$rest) = split(/,/,$line,4);
+ $msg_anz = 20 if $msg_anz>20;
+ $sat={} if $msg_no == 1;
+ #printf STDERR "# of Messages: $msg_anz; rest: '$rest'\n";
+ while ( defined $rest && $rest =~ m/,/) {
+ #printf STDERR "# $count: $rest\n";
+ my ($sat_no,$sat_ele,$sat_azi,$sat_snr);
+ ($sat_no,$sat_ele,$sat_azi,$sat_snr,$rest) = split(/,/,$rest,5);
+ #printf STDERR "($sat_no,$sat_ele,$sat_azi,$sat_snr)\n";
+ last unless defined ($sat_no) && defined($sat_ele) && defined($sat_azi) && defined($sat_snr);
+ $sat->{$sat_no}->{ele} = $sat_ele;
+ $sat->{$sat_no}->{azi} = $sat_azi;
+ $sat->{$sat_no}->{snr} = $sat_snr;
+ }
+ $sat_time = $last_time;
+ #printf STDERR Dumper(\$sat);
+ next;
+ } else {
+ printf STDERR "Ignore Line $type: $full_line\n"
+ if $DEBUG>6;
+ next;
+ };
+
+ next unless defined( $lat) && ($lat ne "" )&& defined( $lon) && ($lon ne "");
+ next if ($lat eq "0000.0000" ) && ($lon eq "00000.0000");
+ if ( $lat =~ m/(\d\d)(\d\d.\d+)/) {
+ $lat = $1 + $2/60;
+ } else {
+ printf STDERR "Error in lat: '$lat'\nLine: $full_line\n";
+ next;
+ }
+ if ($lon =~ m/(\d+)(\d\d\.\d+)/){
+ $lon = $1 + $2/60;
+ } else {
+ printf STDERR "Error in lon: '$lon'\nLine: $full_line\n";
+ next;
+ }
+ $lat = -$lat if $lat_v eq "S";
+ $lon = -$lon if $lon_v eq "W";
+ printf STDERR "type $type (time:$time lat:$lat lon:$lon alt:$alt speed:$speed)\n"
+ if $DEBUG>5;
+ if ( ( abs($lat) < 0.001 ) &&
+ ( abs($lat) < 0.001 ) ) {
+ printf STDERR "too near to (0/0) : type $type (time:$time lat:$lat lon:$lon alt:$alt speed:$speed)\n";
+ next;
+ };
+
+ $time =~ s/^(..)(..)(..)/$1:$2:$3/;
+ if ( defined($date)) {
+ $date =~ s/^(..)(..)(..)/20$3-$2-$1/;
+ } else {
+ $date = $last_date;
+ }
+ $last_date=$date;
+ $time = str2time("$date ${time}");
+ $last_time = $time if $time;
+
+ if ( defined $elem->{time} &&
+ defined $elem->{lat} &&
+ defined $elem->{lon} &&
+ ($elem->{time} != ($time||0)) ) { # We have a new Timestamp
+ bless($elem,"NMEA::gps-point");
+ push(@{$new_track},$elem);
+ $elem ={};
+ }
+
+ $elem->{lat} = $lat;
+ $elem->{lon} = $lon;
+ $elem->{alt} = $alt if defined $alt;
+ $elem->{time} = $time if defined $time;
+ $time ||=0;
+
+ my $dop_time_diff = $time - $dop_time;
+ #printf STDERR "time diff: %f\n ", $dop_time_diff;
+ if ( $dop_time_diff < 10
+ && defined($hdop)
+ && defined($vdop)
+ && defined($pdop)
+ ) {
+ $elem->{pdop} = $pdop if $pdop;
+ $elem->{hdop} = $hdop if $hdop;
+ $elem->{vdop} = $vdop if $vdop;
+ if ( $hdop > 30 or
+ $vdop > 30 or
+ $pdop > 30 ) {
+ #printf STDERR Dumper(\$elem);
+ next;
+ }
+ }
+
+ if (0) { # Currently we don't need these values
+ # So we save on local memory consumption
+ my $sat_time_diff = $time - $sat_time;
+ #printf STDERR "time diff: %f\n ", $sat_time_diff;
+ if ( $sat_time_diff < 10 ) {
+ $elem->{sat} = $sat_count;
+ for my $sat_no ( keys %{$sat} ) {
+ $elem->{"sat_${sat_no}_ele"} = $sat->{$sat_no}->{ele};
+ $elem->{"sat_${sat_no}_azi"} = $sat->{$sat_no}->{azi};
+ $elem->{"sat_${sat_no}_snr"} = $sat->{$sat_no}->{snr};
+ }
+ }
+ }
+ # More interesting Info might be:
+ # <course>52.000000</course>
+ # <ele>0.000000</ele>
+ # <fix>2d</fix>
+ # <fix>3d</fix>
+ # <sat>4</sat>
+ # <speed>0.000000</speed>
+ # <time>2035-12-03T05:42:23Z</time>
+ # <trkpt lat="48.177040000" lon="11.759786667">
+ }
+
+ # Write last element
+ if ( defined $elem->{lat} &&
+ defined $elem->{lon} ) {
+ bless($elem,"NMEA::gps-point");
+ push(@{$new_track},$elem);
+ $elem ={};
+ };
+
+ push(@{$new_tracks->{tracks}},$new_track);
+ if ( $VERBOSE >1 ) {
+ printf STDERR "Read and parsed $filename";
+ print_time($start_time);
+ }
+
+ return $new_tracks;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+NMEA.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Tracks/TRK.pm b/scripts/osm/perl_lib/Geo/Tracks/TRK.pm
new file mode 100644
index 0000000..8577019
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Tracks/TRK.pm
@@ -0,0 +1,143 @@
+##################################################################
+package Geo::Tracks::TRK;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( read_track_TRK );
+
+use strict;
+use warnings;
+
+use Data::Dumper;
+use IO::File;
+use Utils::Debug;
+use Utils::File;
+use Utils::Math;
+use Date::Manip;
+use Date::Parse;
+use Time::Local;
+
+# -----------------------------------------------------------------------------
+# Read GPS Data from TRK - File
+sub read_track_TRK($) {
+ my $filename = shift;
+
+ my $start_time=time();
+
+ my $new_tracks={
+ filename => $filename,
+ tracks => [],
+ wpt => []
+ };
+ printf STDERR ("Reading $filename\n") if $VERBOSE || $DEBUG;
+ printf STDERR "$filename: ".(-s $filename)." Bytes\n" if $DEBUG;
+
+ my ($fn_mtime) = (stat($filename))[9] || 0;
+ #print "$filename mtime: ".localtime($fn_mtime)."\n";
+ my $date ="01-01-2007";
+
+ my $fh = data_open($filename);
+ return $new_tracks unless $fh;
+ my $new_track=[];
+
+ while ( my $line = $fh->getline() ) {
+ chomp $line;
+
+ print "$line\n" if $DEBUG>10;
+
+ my ($dummy1,$time,$lon,$lat,$heading,$speed,$test1,$test2,$test3) = split(/\s*,\s*/,$line);
+ my $alt=0;
+ $time =~ s/^(..)(..)(..)/$1:$2:$3/;
+
+ $time = str2time("$date ${time}");
+ if ( $DEBUG >3) {
+ printf STDERR "".localtime($time)."\t, la: $lat, lo: $lon,";
+ printf STDERR "\tHeading: %6.2f",$heading;
+ printf STDERR "\tSpeed: %8.4f",$speed;
+ printf STDERR "\tTest1($test1)";
+ printf STDERR "\tdop?($test2)";
+ printf STDERR "\tSat#?: $test3";
+ printf STDERR "\tdummy1: $dummy1\n";
+ };
+
+
+ if ( $heading>360) {
+ print STDERR "Here something is wrong the heading ($heading) ".
+ "is larger than 360 degrees\n";
+ print STDERR "Line: $line\n";
+ }
+ my ($msg_anz,$msg_no,$rest);
+
+ unless ( defined( $lat) && ($lat ne "" )&& defined( $lon) && ($lon ne "")) {
+ print "ERROR in Line: $line\n";
+ next;
+ };
+
+ my $elem ={};
+ $elem->{pdop} = $test2;
+ $elem->{lat} = $lat;
+ $elem->{lon} = $lon;
+ $elem->{alt} = $alt if defined $alt;
+ $elem->{time} = $time if defined $time;
+ $time ||=0;
+
+ if ( defined $elem->{time} &&
+ defined $elem->{lat} &&
+ defined $elem->{lon} ) {
+ bless($elem,"TRK::gps-point");
+ push(@{$new_track},$elem);
+ $elem ={};
+ } else {
+ if ( @$new_track ) {
+ push(@{$new_tracks->{tracks}},$new_track);
+ }
+ $new_track=[];
+ }
+ }
+
+ push(@{$new_tracks->{tracks}},$new_track);
+ if ( $VERBOSE >1 ) {
+ printf STDERR "Read and parsed $filename";
+ print_time($start_time);
+ }
+
+ return $new_tracks;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+TRK.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (TRK.pm.openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Geo/Tracks/Tools.pm b/scripts/osm/perl_lib/Geo/Tracks/Tools.pm
new file mode 100644
index 0000000..5008f71
--- /dev/null
+++ b/scripts/osm/perl_lib/Geo/Tracks/Tools.pm
@@ -0,0 +1,395 @@
+##################################################################
+package Geo::Tracks::Tools;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( copy_track_structure copy_track_wpt
+ tracks_only_good_point tracks_only_good_point_split
+ count_good_point
+ set_number_bad_points
+ enrich_tracks
+ track_point_speed
+ track_part_angle
+ track_part_distance
+ print_count_data
+ count_data
+ add_tracks
+);
+
+
+use strict;
+use warnings;
+use Carp;
+
+use Geo::Geometry;
+use Utils::File;
+use Utils::Math;
+use Utils::Debug;
+
+# Copy the track structure
+sub copy_track_structure($$){
+ my $tracks = shift;
+ my $new_tracks = shift;
+
+ Carp::confess "Must get Hashref to copy structure to\n"
+ unless ref($new_tracks) eq "HASH";
+
+ $new_tracks->{filename} = $tracks->{filename};
+ $new_tracks->{tracks} ||= [];
+ $new_tracks->{wpt} ||= [];
+}
+
+# Copy the track waypoints
+sub copy_track_wpt($$){
+ my $tracks = shift;
+ my $new_tracks = shift;
+
+ Carp::confess "Must get Hashref to copy structure to\n"
+ unless ref($new_tracks) eq "HASH";
+
+ # Keep WPT
+ for my $elem ( @{$tracks->{wpt}} ) {
+ next unless $elem;
+ push(@{$new_tracks->{wpt}},$elem);
+ }
+
+ return $new_tracks;
+}
+
+
+##################################################################
+# Copy only those trackpoints with the good_point Flag set
+# The Track Elements have Tags:
+# $elem->{good_point} : Ignore this point
+# $elem->{split_track} : Split track before this point
+# RETURN: Tracks Structure
+sub tracks_only_good_point($){
+ my $tracks = shift;
+
+ my $new_tracks={};
+ copy_track_structure($tracks,$new_tracks);
+ copy_track_wpt($tracks,$new_tracks);
+
+
+ Carp::Confess("Tracks to copy to musst be of Type Hash")
+ unless ref($new_tracks) eq "HASH";
+
+ for my $track ( @{$tracks->{tracks}} ) {
+ next if !$track;
+ my $new_track=[];
+
+ # Copy only those with good_point set to 1
+ for my $track_pos ( 0 .. $#{@{$track}} ) {
+ my $elem=$track->[$track_pos];
+
+ if ( $elem->{split_track} ) {
+ my $num_elem=scalar(@{$new_track});
+ if ( $num_elem >1 ) {
+ push(@{$new_tracks->{tracks}},$new_track);
+ }
+ $new_track=[];
+ }
+ next unless $elem->{good_point};
+ push(@{$new_track},$elem);
+ }
+ if ( scalar(@{$new_track} ) > 1 ) {
+ push(@{$new_tracks->{tracks}},$new_track);
+ }
+ }
+ return $new_tracks;
+}
+
+
+
+
+##################################################################
+# Set number of points in track to bad
+sub set_number_bad_points($$$){
+ my $track = shift; # reference to track
+ my $start_pos = shift; # position to start setting the tag
+ my $count = shift;
+
+ return unless $count;
+
+ my $max_pos = $#{@{$track}};
+ for my $i ( 0 .. $count-1 ){
+ last if $start_pos+$i > $max_pos;
+ $track->[$start_pos+$i]->{good_point}= 0;
+ }
+}
+
+##################################################################
+# Returns number of points with the tag ->{good_point} set
+sub count_good_point($){
+ my $tracks = shift; # A reference to a list of Tracks
+
+ my $count =0;
+ for my $track ( @{$tracks->{tracks}} ) {
+ next if !$track;
+ for ( my $track_pos=0; $track_pos <= $#{@{$track}};$track_pos++ ) {
+ $count++ if $track->[$track_pos]->{good_point};
+ }
+ }
+ return $count;
+};
+
+
+# ------------------------------------------------------------------
+# Enrich Track Data by adding:;
+# dist: Distance to next point in meters
+# angle_n: Angle to next point compared to north
+# angle_n_r: Angle to next point compared to north ignoring direction
+# angle: Angle between previous segment and following segment
+# compare_dist: is pdop or any other usefull distance in
+# meter we can later use for distance comparison
+sub enrich_single_track($){
+ my $track = shift;
+ my $last_track_point = $#{@{$track}};
+ my $compare_dist=30;
+ for my $track_pos ( 0 .. $last_track_point) {
+ my $elem0=$track->[$track_pos-1];
+ my $elem1=$track->[$track_pos];
+ my $elem2=$track->[$track_pos+1];
+
+ if ( ref($elem1) eq "ARRAY" ) {
+ print Dumper(\$track);
+ Carp::confess("enrich_single_track(): track_pos $track_pos has ARRAY instead of Hash");
+ }
+
+ $elem1->{good_point}= 1;
+
+ my $pdop = $elem1->{pdop};
+ if ( defined ( $pdop ) && ($pdop >0) ) {
+ $compare_dist= $pdop;
+ }
+ $compare_dist=10 if $compare_dist <10;
+ $elem1->{compare_dist} = $compare_dist;
+
+ if ( $track_pos < $last_track_point ) {
+ $elem1->{angle_n} = angle_north($elem1,$elem2);
+ $elem1->{angle_n_r} = angle_north_relative($elem1,$elem2);
+ } else {
+ $elem1->{angle_n} = -999999;
+ $elem1->{angle_n_r} = -999999;
+ }
+ if ( ($track_pos > 0) &&
+ ( $track_pos < $last_track_point ) ) {
+ $elem1->{angle} =
+ angle_north($elem0,$elem1) -
+ angle_north($elem1,$elem2);
+ } else {
+ $elem1->{angle} =0;
+ }
+ if ( ($track_pos > 0) &&
+ ( $track_pos < $last_track_point ) ) {
+ $elem2->{angle_to_last} =$elem1->{angle};
+ }
+ # Distance between line of segment($segment) to trackpoint $elem1
+ $elem1->{dist} = 1000*distance_point_point_Km($elem1,$elem2);
+
+ if ( defined($elem1->{time}) && defined($elem2->{time}) ) {
+ $elem1->{time_diff} = $elem1->{time} - $elem2->{time};
+ }
+ }
+}
+
+# ------------------------------------------------------------------
+# Enrich Tracks Data by doing enrich_singleTrack an all tracks
+sub enrich_tracks($){
+ my $tracks = shift;
+ for my $track ( @{$tracks->{tracks}} ) {
+ enrich_single_track($track);
+ }
+}
+
+
+# ------------------------------------------------------------------
+# Calculate Average Speed of track segment
+sub track_point_speed($$){
+ my $track = shift;
+ my $track_pos = shift;
+
+ my $elem = $track->[$track_pos];
+ return $elem->{speed} if defined $elem->{speed};
+
+ my $pos_start = $track_pos-10;
+ $pos_start = 0 if $pos_start<0;
+
+ my $pos_end = $pos_start+20;
+ my $max_pos = $#{@{$track}};
+ $pos_end = $max_pos if $pos_end> $max_pos;
+
+ return track_part_speed($track,$pos_start,$pos_end);
+}
+
+# ------------------------------------------------------------------
+# Calculate Average Speed of track segment
+sub track_part_speed($$$){
+ my $track = shift;
+ my $pos_start = shift;
+ my $pos_end = shift;
+ my $avg_speed = 0;
+
+ return 0 unless defined $track;
+
+ my $max_pos = $#{@{$track}};
+ $pos_start = 0 if $pos_start<0;
+ $pos_end = $max_pos if $pos_end> $max_pos;
+
+ my $dist = track_part_distance($track,$pos_start,$pos_end)/1000;
+ my $elem_s = $track->[$pos_start];
+ my $elem_e = $track->[$pos_end];
+
+ my $speed=0;
+ if ( defined($elem_s->{time}) && defined($elem_e->{time}) ) {
+ my $time_diff = $elem_s->{time} - $elem_e->{time};
+ if ( $time_diff ) {
+ my $speed = $dist/$time_diff*3600;
+ };
+ };
+ $avg_speed = $speed;
+
+ my $sum_speed=0;
+ for my $track_pos ( $pos_start .. $pos_end ) {
+ my $elem = $track->[$track_pos];
+
+ return $speed # Abort if any sub-speeds are not defined
+ unless defined $elem->{speed};
+
+ $sum_speed += $elem->{speed};
+ }
+ $avg_speed = $sum_speed/($pos_end-$pos_start+1);
+
+ return $avg_speed;
+}
+
+# ------------------------------------------------------------------
+# Summarize all angles between start and endpoint of a single track
+sub track_part_angle($$$){
+ my $track = shift;
+ my $pos_start = shift;
+ my $pos_end = shift;
+ my $sum_angle=0;
+
+ for my $track_pos ( $pos_start .. $pos_end ) {
+ $sum_angle += $track->[$track_pos]->{angle};
+ }
+ return $sum_angle;
+}
+
+# ------------------------------------------------------------------
+# Summarize distance between start and endpoint of a single track
+sub track_part_distance($$$){
+ my $track = shift;
+ my $pos_start = shift;
+ my $pos_end = shift;
+ my $sum_angle=0;
+
+ for my $track_pos ( $pos_start .. $pos_end ) {
+ $sum_angle += $track->[$track_pos]->{dist};
+ }
+ return $sum_angle;
+}
+
+# ------------------------------------------------------------------
+# count tracks and points
+sub count_data($){
+ my $tracks = shift; # reference to tracks list
+
+ my $start_time=time();
+
+ my $count_tracks=0;
+ my $count_points=0;
+
+ for my $track ( @{$tracks->{tracks}} ) {
+ next if !$track;
+ for my $elem ( @{$track} ) {
+ $count_points++;
+ }
+ $count_tracks++;
+ }
+
+ my $used_time = time()-$start_time;
+ if ( $DEBUG>5 || $VERBOSE>5 || ($used_time >5 )) {
+ printf STDERR "Counted ( $count_tracks Tracks,$count_points Points)";
+ print_time($start_time);
+ }
+
+ return ( $count_tracks,$count_points);
+}
+
+# ------------------------------------------------------------------
+# Print Number of points/tracks with a comment
+# and print them with a comment and the filename stored in the track
+sub print_count_data($$){
+ my $tracks = shift; # reference to tracks list
+ my $comment = shift;
+
+ my $filename = $tracks->{filename};
+
+ my ($track_count,$point_count) = GPS::count_data($tracks);
+ if ( $VERBOSE || $DEBUG) {
+ printf STDERR "%-35s: %5d Points in %d Tracks $comment",$filename,$point_count,$track_count;
+ }
+}
+
+
+# ------------------------------------------------------------------
+# add a list of tracks to another list of Tracks
+sub add_tracks($$){
+ my $dst_tracks = shift; # reference to tracks list
+ my $src_tracks = shift; # reference to tracks list
+
+ $dst_tracks ||= { filename => '',
+ tracks => [],
+ wpt => [],
+ };
+ $dst_tracks->{filename} .=",$src_tracks->{filename}";
+ for my $elem ( @{$src_tracks->{wpt}} ) {
+ next unless $elem;
+ push(@{$dst_tracks->{wpt}},$elem);
+ }
+ for my $elem ( @{$src_tracks->{tracks}} ) {
+ next unless $elem;
+ push(@{$dst_tracks->{tracks}},$elem);
+ }
+}
+
+1;
+
+
+__END__
+
+=head1 NAME
+
+Geo::Tracks::Tools
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Makefile.am b/scripts/osm/perl_lib/Makefile.am
new file mode 100644
index 0000000..d475c20
--- /dev/null
+++ b/scripts/osm/perl_lib/Makefile.am
@@ -0,0 +1,38 @@
+# Makefile.am for scripts/perl_lib
+
+gpsdrivedir = $(datadir)/gpsdrive
+
+Geodir = $(PERL_PACKAGE_DIR)/Geo
+Geo_DATA = Geo/*.pm
+
+Geo_Gpsdrivedir = $(PERL_PACKAGE_DIR)/Geo/Gpsdrive
+Geo_Gpsdrive_DATA = Geo/Gpsdrive/*.pm
+
+Geo_Tracksdir = $(PERL_PACKAGE_DIR)/Geo/Tracks
+Geo_Tracks_DATA = Geo/Tracks/*.pm
+
+Geo_OSMdir = $(PERL_PACKAGE_DIR)/Geo/OSM
+Geo_OSM_DATA = Geo/OSM/*.pm
+
+Geo_GPXdir = $(PERL_PACKAGE_DIR)/Geo/GPX
+Geo_GPX_DATA = Geo/GPX/*.pm
+
+Geo_Filterdir = $(PERL_PACKAGE_DIR)/Geo/Filter
+Geo_Filter_DATA = Geo/Filter/*.pm
+
+Utilsdir = $(PERL_PACKAGE_DIR)/Utils
+Utils_DATA = Utils/*.pm
+
+Utils_LWPdir = $(PERL_PACKAGE_DIR)/Utils/LWP
+Utils_LWP_DATA = Utils/LWP/*.pm
+
+
+EXTRA_DIST = \
+ $(Geo_DATA) \
+ $(Geo_Filter_DATA) \
+ $(Geo_GPX_DATA)\
+ $(Geo_Gpsdrive_DATA) \
+ $(Geo_OSM_DATA) \
+ $(Geo_Tracks_DATA) \
+ $(Utils_DATA) \
+ $(Utils_LWP_DATA)
diff --git a/scripts/osm/perl_lib/Makefile.in b/scripts/osm/perl_lib/Makefile.in
new file mode 100644
index 0000000..767a41d
--- /dev/null
+++ b/scripts/osm/perl_lib/Makefile.in
@@ -0,0 +1,581 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+# Makefile.am for scripts/perl_lib
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ../../..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = scripts/osm/perl_lib
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/ac_check_perl_modules.m4 \
+ $(top_srcdir)/m4/ac_check_socketlen_t.m4 \
+ $(top_srcdir)/m4/aq_check_gdal.m4 $(top_srcdir)/m4/gettext.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/lib-ld.m4 \
+ $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+SOURCES =
+DIST_SOURCES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(Geodir)" "$(DESTDIR)$(Geo_Filterdir)" \
+ "$(DESTDIR)$(Geo_GPXdir)" "$(DESTDIR)$(Geo_Gpsdrivedir)" \
+ "$(DESTDIR)$(Geo_OSMdir)" "$(DESTDIR)$(Geo_Tracksdir)" \
+ "$(DESTDIR)$(Utilsdir)" "$(DESTDIR)$(Utils_LWPdir)"
+GeoDATA_INSTALL = $(INSTALL_DATA)
+Geo_FilterDATA_INSTALL = $(INSTALL_DATA)
+Geo_GPXDATA_INSTALL = $(INSTALL_DATA)
+Geo_GpsdriveDATA_INSTALL = $(INSTALL_DATA)
+Geo_OSMDATA_INSTALL = $(INSTALL_DATA)
+Geo_TracksDATA_INSTALL = $(INSTALL_DATA)
+UtilsDATA_INSTALL = $(INSTALL_DATA)
+Utils_LWPDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(Geo_DATA) $(Geo_Filter_DATA) $(Geo_GPX_DATA) \
+ $(Geo_Gpsdrive_DATA) $(Geo_OSM_DATA) $(Geo_Tracks_DATA) \
+ $(Utils_DATA) $(Utils_LWP_DATA)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkgdatadir = @pkgdatadir@
+ACLOCAL = @ACLOCAL@
+AMAPNIK = @AMAPNIK@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBUS_CFLAGS = @DBUS_CFLAGS@
+DBUS_GLIB_LIBS = @DBUS_GLIB_LIBS@
+DBUS_LIBS = @DBUS_LIBS@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DISABLEGARMIN_FALSE = @DISABLEGARMIN_FALSE@
+DISABLEGARMIN_TRUE = @DISABLEGARMIN_TRUE@
+DISABLEPLUGINS_FALSE = @DISABLEPLUGINS_FALSE@
+DISABLEPLUGINS_TRUE = @DISABLEPLUGINS_TRUE@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FRIENDSSERVERVERSION = @FRIENDSSERVERVERSION@
+GDAL_CFLAGS = @GDAL_CFLAGS@
+GDAL_CONFIG = @GDAL_CONFIG@
+GDAL_LDADD = @GDAL_LDADD@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GLIB_CFLAGS = @GLIB_CFLAGS@
+GLIB_GENMARSHAL = @GLIB_GENMARSHAL@
+GLIB_LIBS = @GLIB_LIBS@
+GLIB_MKENUMS = @GLIB_MKENUMS@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GOBJECT_QUERY = @GOBJECT_QUERY@
+GREP = @GREP@
+GTK_CFLAGS = @GTK_CFLAGS@
+GTK_LIBS = @GTK_LIBS@
+HAVE_DBUS_FALSE = @HAVE_DBUS_FALSE@
+HAVE_DBUS_TRUE = @HAVE_DBUS_TRUE@
+HAVE_GDAL_FALSE = @HAVE_GDAL_FALSE@
+HAVE_GDAL_TRUE = @HAVE_GDAL_TRUE@
+HAVE_GTK_FALSE = @HAVE_GTK_FALSE@
+HAVE_GTK_TRUE = @HAVE_GTK_TRUE@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LIBADD_DL = @LIBADD_DL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+NOGARMIN = @NOGARMIN@
+NOPLUGINS = @NOPLUGINS@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PCRE_CONFIG = @PCRE_CONFIG@
+PERL = @PERL@
+PERL_PACKAGE_DIR = @PERL_PACKAGE_DIR@
+PKGCONFIG_CFLAGS = @PKGCONFIG_CFLAGS@
+PKGCONFIG_LIBS = @PKGCONFIG_LIBS@
+PKG_CONFIG = @PKG_CONFIG@
+POSUB = @POSUB@
+POW_LIB = @POW_LIB@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_MAPNIK_FALSE = @WITH_MAPNIK_FALSE@
+WITH_MAPNIK_TRUE = @WITH_MAPNIK_TRUE@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XML_CFLAGS = @XML_CFLAGS@
+XML_LIBS = @XML_LIBS@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+gpsdrivedir = $(datadir)/gpsdrive
+Geodir = $(PERL_PACKAGE_DIR)/Geo
+Geo_DATA = Geo/*.pm
+Geo_Gpsdrivedir = $(PERL_PACKAGE_DIR)/Geo/Gpsdrive
+Geo_Gpsdrive_DATA = Geo/Gpsdrive/*.pm
+Geo_Tracksdir = $(PERL_PACKAGE_DIR)/Geo/Tracks
+Geo_Tracks_DATA = Geo/Tracks/*.pm
+Geo_OSMdir = $(PERL_PACKAGE_DIR)/Geo/OSM
+Geo_OSM_DATA = Geo/OSM/*.pm
+Geo_GPXdir = $(PERL_PACKAGE_DIR)/Geo/GPX
+Geo_GPX_DATA = Geo/GPX/*.pm
+Geo_Filterdir = $(PERL_PACKAGE_DIR)/Geo/Filter
+Geo_Filter_DATA = Geo/Filter/*.pm
+Utilsdir = $(PERL_PACKAGE_DIR)/Utils
+Utils_DATA = Utils/*.pm
+Utils_LWPdir = $(PERL_PACKAGE_DIR)/Utils/LWP
+Utils_LWP_DATA = Utils/LWP/*.pm
+EXTRA_DIST = \
+ $(Geo_DATA) \
+ $(Geo_Filter_DATA) \
+ $(Geo_GPX_DATA)\
+ $(Geo_Gpsdrive_DATA) \
+ $(Geo_OSM_DATA) \
+ $(Geo_Tracks_DATA) \
+ $(Utils_DATA) \
+ $(Utils_LWP_DATA)
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu scripts/osm/perl_lib/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu scripts/osm/perl_lib/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool
+uninstall-info-am:
+install-GeoDATA: $(Geo_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Geodir)" || $(mkdir_p) "$(DESTDIR)$(Geodir)"
+ @list='$(Geo_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(GeoDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Geodir)/$$f'"; \
+ $(GeoDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Geodir)/$$f"; \
+ done
+
+uninstall-GeoDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Geo_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Geodir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Geodir)/$$f"; \
+ done
+install-Geo_FilterDATA: $(Geo_Filter_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Geo_Filterdir)" || $(mkdir_p) "$(DESTDIR)$(Geo_Filterdir)"
+ @list='$(Geo_Filter_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(Geo_FilterDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Geo_Filterdir)/$$f'"; \
+ $(Geo_FilterDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Geo_Filterdir)/$$f"; \
+ done
+
+uninstall-Geo_FilterDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Geo_Filter_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Geo_Filterdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Geo_Filterdir)/$$f"; \
+ done
+install-Geo_GPXDATA: $(Geo_GPX_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Geo_GPXdir)" || $(mkdir_p) "$(DESTDIR)$(Geo_GPXdir)"
+ @list='$(Geo_GPX_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(Geo_GPXDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Geo_GPXdir)/$$f'"; \
+ $(Geo_GPXDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Geo_GPXdir)/$$f"; \
+ done
+
+uninstall-Geo_GPXDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Geo_GPX_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Geo_GPXdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Geo_GPXdir)/$$f"; \
+ done
+install-Geo_GpsdriveDATA: $(Geo_Gpsdrive_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Geo_Gpsdrivedir)" || $(mkdir_p) "$(DESTDIR)$(Geo_Gpsdrivedir)"
+ @list='$(Geo_Gpsdrive_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(Geo_GpsdriveDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Geo_Gpsdrivedir)/$$f'"; \
+ $(Geo_GpsdriveDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Geo_Gpsdrivedir)/$$f"; \
+ done
+
+uninstall-Geo_GpsdriveDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Geo_Gpsdrive_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Geo_Gpsdrivedir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Geo_Gpsdrivedir)/$$f"; \
+ done
+install-Geo_OSMDATA: $(Geo_OSM_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Geo_OSMdir)" || $(mkdir_p) "$(DESTDIR)$(Geo_OSMdir)"
+ @list='$(Geo_OSM_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(Geo_OSMDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Geo_OSMdir)/$$f'"; \
+ $(Geo_OSMDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Geo_OSMdir)/$$f"; \
+ done
+
+uninstall-Geo_OSMDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Geo_OSM_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Geo_OSMdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Geo_OSMdir)/$$f"; \
+ done
+install-Geo_TracksDATA: $(Geo_Tracks_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Geo_Tracksdir)" || $(mkdir_p) "$(DESTDIR)$(Geo_Tracksdir)"
+ @list='$(Geo_Tracks_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(Geo_TracksDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Geo_Tracksdir)/$$f'"; \
+ $(Geo_TracksDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Geo_Tracksdir)/$$f"; \
+ done
+
+uninstall-Geo_TracksDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Geo_Tracks_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Geo_Tracksdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Geo_Tracksdir)/$$f"; \
+ done
+install-UtilsDATA: $(Utils_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Utilsdir)" || $(mkdir_p) "$(DESTDIR)$(Utilsdir)"
+ @list='$(Utils_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(UtilsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Utilsdir)/$$f'"; \
+ $(UtilsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Utilsdir)/$$f"; \
+ done
+
+uninstall-UtilsDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Utils_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Utilsdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Utilsdir)/$$f"; \
+ done
+install-Utils_LWPDATA: $(Utils_LWP_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(Utils_LWPdir)" || $(mkdir_p) "$(DESTDIR)$(Utils_LWPdir)"
+ @list='$(Utils_LWP_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(Utils_LWPDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(Utils_LWPdir)/$$f'"; \
+ $(Utils_LWPDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(Utils_LWPdir)/$$f"; \
+ done
+
+uninstall-Utils_LWPDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(Utils_LWP_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(Utils_LWPdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(Utils_LWPdir)/$$f"; \
+ done
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+ $(mkdir_p) $(distdir)/Geo $(distdir)/Geo/Filter $(distdir)/Geo/GPX $(distdir)/Geo/Gpsdrive $(distdir)/Geo/OSM $(distdir)/Geo/Tracks $(distdir)/Utils $(distdir)/Utils/LWP
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(DATA)
+installdirs:
+ for dir in "$(DESTDIR)$(Geodir)" "$(DESTDIR)$(Geo_Filterdir)" "$(DESTDIR)$(Geo_GPXdir)" "$(DESTDIR)$(Geo_Gpsdrivedir)" "$(DESTDIR)$(Geo_OSMdir)" "$(DESTDIR)$(Geo_Tracksdir)" "$(DESTDIR)$(Utilsdir)" "$(DESTDIR)$(Utils_LWPdir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-libtool
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-GeoDATA install-Geo_FilterDATA \
+ install-Geo_GPXDATA install-Geo_GpsdriveDATA \
+ install-Geo_OSMDATA install-Geo_TracksDATA install-UtilsDATA \
+ install-Utils_LWPDATA
+
+install-exec-am:
+
+install-info: install-info-am
+
+install-man:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-GeoDATA uninstall-Geo_FilterDATA \
+ uninstall-Geo_GPXDATA uninstall-Geo_GpsdriveDATA \
+ uninstall-Geo_OSMDATA uninstall-Geo_TracksDATA \
+ uninstall-UtilsDATA uninstall-Utils_LWPDATA uninstall-info-am
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ distclean distclean-generic distclean-libtool distdir dvi \
+ dvi-am html html-am info info-am install install-GeoDATA \
+ install-Geo_FilterDATA install-Geo_GPXDATA \
+ install-Geo_GpsdriveDATA install-Geo_OSMDATA \
+ install-Geo_TracksDATA install-UtilsDATA install-Utils_LWPDATA \
+ install-am install-data install-data-am install-exec \
+ install-exec-am install-info install-info-am install-man \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-GeoDATA uninstall-Geo_FilterDATA \
+ uninstall-Geo_GPXDATA uninstall-Geo_GpsdriveDATA \
+ uninstall-Geo_OSMDATA uninstall-Geo_TracksDATA \
+ uninstall-UtilsDATA uninstall-Utils_LWPDATA uninstall-am \
+ uninstall-info-am
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/scripts/osm/perl_lib/Utils/Debug.pm b/scripts/osm/perl_lib/Utils/Debug.pm
new file mode 100644
index 0000000..4312bf9
--- /dev/null
+++ b/scripts/osm/perl_lib/Utils/Debug.pm
@@ -0,0 +1,169 @@
+##################################################################
+package Utils::Debug;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( $DEBUG $VERBOSE
+ mem_info
+ mem_usage
+ print_time
+ time_estimate
+ );
+
+our $DEBUG = 0;
+our $VERBOSE = 0;
+
+use strict;
+use warnings;
+
+use IO::File;
+use Utils::Math;
+
+
+# print the time elapsed since starting
+# starting_time is the first argument
+sub print_time($){
+ my $start_time = shift;
+ return unless $DEBUG||$VERBOSE;
+ my $time_diff = time()-$start_time;
+ if ( $time_diff > 1 ) {
+ printf STDERR " in %.0f sec", $time_diff;
+ }
+ printf STDERR "\n";
+}
+
+my $mem_statistics={};
+
+# get memory usage from /proc Filesystem
+sub mem_usage(;$){
+ my $type = shift||'';
+ my $proc_file = "/proc/$$/statm";
+ my $msg = '';
+ if ( -r $proc_file ) {
+ my $fh = IO::File->new("<$proc_file");
+ my $statm = $fh->getline();
+ $fh->close();
+ $statm or return "";
+ chomp $statm;
+ my @statm = split(/\s+/,$statm);
+ return unless @statm;
+ my $vsz = ($statm[0]*4)/1024;
+ my $rss = ($statm[1]*4)/1024;
+ # printf STDERR " PID: $$ ";
+ $mem_statistics->{"max vsz"} = max($mem_statistics->{"max vsz"},$vsz) if $vsz;
+ $mem_statistics->{"max rss"} = max($mem_statistics->{"max rss"},$rss) if $rss;
+ return $rss if $type eq "rss";
+ return $vsz if $type eq "vsz";
+ return $mem_statistics->{"max rss"} if $type eq "max rss";
+ return $mem_statistics->{"max vsz"} if $type eq "max vsz";
+ $msg .= sprintf( "MEM:%.0fMB",$vsz);
+ $msg .= sprintf( "(A:%.0fF:%.0f)",mem_info("MemTotal"),mem_info("MemFree"))
+ if $DEBUG>3 || $VERBOSE >3;
+ $msg .= sprintf( "RSS: %.0f MB ",$rss)
+ if $DEBUG>7 || $VERBOSE>7;
+ #$msg .= mem_info();
+ }
+ return $msg;
+}
+
+
+# get memory usage from /proc Filesystem
+sub mem_info(;$){
+ my $type = shift||'';
+ my $proc_file = "/proc/meminfo";
+ my $msg = '';
+ if ( -r $proc_file ) {
+ my $fh = IO::File->new("<$proc_file");
+ my $mem={};
+ while ( my $line = $fh->getline() ) {
+ my ($k,$v)=split(/\:\s*/,$line);
+ $v =~ s/ kB//;
+ $mem->{$k}=$v/1024;
+ }
+ $fh->close();
+ if ( $type ) {
+ return $mem->{$type};
+ } else {
+ $msg .= "Mem ";
+ $msg .= sprintf( "free: %.0f MB ",$mem->{MemFree});
+ $msg .= sprintf( "total: %.0f MB ",$mem->{MemTotal});
+ }
+ }
+ return $msg;
+}
+
+
+# returns a time estimation for the rest of the process
+sub time_estimate($$$){
+ my $start_time = shift; # Time the process was started
+ my $elem_no = shift||1; # The number of the current element
+ my $elem_max = shift; # the maximum number of possible elements
+
+ my $time_diff=time()-$start_time;
+ my $time_estimated= $time_diff/$elem_no*$elem_max;
+ my $unit="min";
+ my $factor=60;
+ my $digits=0;
+ if ( $time_estimated >7200 ) {
+ $unit="h";
+ $factor=60*60;
+ $digits=2;
+ }
+ if ( $time_estimated <4*60 ) {
+ $unit="sec";
+ $factor=1;
+ $digits=0;
+ }
+ my $msg = sprintf( " %.${digits}f(%.${digits}f)%s",
+ $time_diff/$factor,$time_estimated/$factor,$unit);
+ if ( $DEBUG >4 || $VERBOSE>6 ) {
+ $msg .= " since start: $time_diff sec".
+ sprintf(" (estimate: %.2f sec)",$time_estimated).
+ " element $elem_no($elem_max) ";
+ }
+ if ( $DEBUG >2 || $VERBOSE>2 ) {
+ $msg .= sprintf(" %.2f%% ",100*$elem_no/$elem_max);
+ }
+ if ( $DEBUG >2 || $VERBOSE>2 ) {
+ $msg .= sprintf(" %d(%d) ",$elem_no,$elem_max);
+ }
+ return $msg;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Debug.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Utils/File.pm b/scripts/osm/perl_lib/Utils/File.pm
new file mode 100644
index 0000000..b8e58e2
--- /dev/null
+++ b/scripts/osm/perl_lib/Utils/File.pm
@@ -0,0 +1,171 @@
+##################################################################
+package Utils::File;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( data_open
+ file_needs_re_generation
+ mkdir_if_needed
+ newest_unpacked_filename
+ expand_filename
+ );
+use strict;
+use warnings;
+
+use IO::File;
+use Utils::Debug;
+
+use File::Basename;
+use File::Copy;
+use File::Path;
+use Time::Local;
+
+# -----------------------------------------------------------------------------
+# Expand ~/ against Homedir of user
+sub expand_filename($){
+ my $filename = shift;
+ $filename =~ s/^\~/$ENV{HOME}/;
+ return $filename;
+}
+
+# -----------------------------------------------------------------------------
+# Open Data File in predefined Directories
+sub data_open($){
+ my $filename = expand_filename(shift);
+ my $fh;
+
+ # If it's already an open File
+ if ( ref($filename) =~ m/IO::File/ ) {
+ return $filename;
+ }
+
+ if ( $filename eq "-" ) {
+ $fh = IO::File->new('<&STDIN');
+ $fh or die("cannot open $filename: $!");
+ return $fh;
+ } else {
+ # Note: This test is wrong for pipes...
+ my $size = (-s $filename)||0;
+ if ( $size < 270 ) {
+ warn "cannot Open $filename ($size) Bytes is too small)\n"
+ if $VERBOSE || $DEBUG;
+ return undef;
+ }
+ }
+
+ printf STDERR "Opening $filename\n" if $DEBUG;
+ if ( $filename =~ m/\.gz$/ ) {
+ $fh = IO::File->new("gzip -dc $filename|")
+ or die("cannot open $filename: $!");
+ } elsif ( $filename =~ m/\.bz2$/ ) {
+ $fh = IO::File->new("bzip2 -dc $filename|")
+ or die("cannot open $filename: $!");
+ } elsif ( $filename =~ m/\.7z$/ ) {
+ printf STDERR "Opening $filename with 7z\n" if $DEBUG;
+ $fh = IO::File->new("7z e -so $filename |")
+ or die("cannot open $filename: $!");
+ } else {
+ $fh = IO::File->new("$filename",'r')
+ or die("cannot open $filename: $!");
+ }
+ return $fh;
+}
+
+# ------------------------------------------------------------------
+# Open Data File in predefined Directories
+sub file_needs_re_generation($$){
+ my $src_filename = expand_filename(shift);
+ my $dst_filename = expand_filename(shift);
+
+ unless ( -e $src_filename ){
+ print STDERR "No Update makes sense, since we lack the source File: $src_filename\n"
+ if $VERBOSE>1;
+ return 0;
+ }
+
+ # dst file does not exist
+ unless ( $dst_filename && -e $dst_filename ){
+ print STDERR "Update needed. $dst_filename has no size\n"
+ if $VERBOSE>1;
+ return 1;
+ }
+
+ my ($src_mtime) = (stat($src_filename))[9] || 0;
+ my ($dst_mtime) = (stat($dst_filename))[9] || 0;
+
+ my $update_needed=$src_mtime > $dst_mtime;
+ if ( $VERBOSE>5 ) {
+ print STDERR "Update needed.\n";
+ print STDERR localtime($dst_mtime)."\t$dst_filename is ";
+ print STDERR ($update_needed?"older":"newer")." than \n";
+ print STDERR localtime($src_mtime)."\t$src_filename\n";
+ }
+ return $update_needed;
+}
+
+# ------------------------------------------------------------------
+# Given a filename it checks if we have an unpacked
+# Version which is new enough
+# ARGS: filename.osm.gz|filename.osm
+# RETURNS:
+# filename.osm if: it exists and is the newest
+# filename.osm.gz: if no current filename.osm exists
+# undef: if we cant find any of the files
+sub newest_unpacked_filename($){
+ my $filename = shift;
+
+ my $filename_unpacked = $filename;
+ $filename_unpacked =~ s/\.(gz|bz2|bz)$//;
+ if ( file_needs_re_generation($filename,$filename_unpacked)) {
+ return $filename if -s $filename;
+ } else {
+ return $filename_unpacked if -s $filename_unpacked;
+ }
+ return undef;
+}
+
+# ------------------------------------------------------------------
+# Create Directory if needed and die if not possible
+sub mkdir_if_needed($){
+ my $dir = expand_filename(shift);
+ -d "$dir" or mkpath "$dir"
+ or die "Cannot create Directory $dir: $!\n";
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+File.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Utils/LWP/Utils.pm b/scripts/osm/perl_lib/Utils/LWP/Utils.pm
new file mode 100644
index 0000000..d1ca367
--- /dev/null
+++ b/scripts/osm/perl_lib/Utils/LWP/Utils.pm
@@ -0,0 +1,134 @@
+##################################################################
+package Utils::LWP::Utils;
+##################################################################
+
+use Exporter;
+@ISA = qw( Exporter );
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@EXPORT = qw( mirror_file
+ $PROXY
+ $NO_MIRROR);
+
+use strict;
+use warnings;
+
+use LWP::UserAgent;
+
+use Utils::Debug;
+
+our $PROXY='';
+
+our $NO_MIRROR=0;
+
+our $lwp_last_was_bytes=0;
+our $lwp_bytes=0;
+our $lwp_timer=0;
+{
+ no warnings;
+ eval {
+ sub LWP::Debug::debug {
+ my $out_string = shift;
+ if ( $out_string =~ m/read (\d+) bytes/) {
+ my $anz = $1;
+ $lwp_bytes += $anz;
+ if ( time() > $lwp_timer+1){
+ printf STDERR"LWP: got %d Bytes (%.4f MB)\r",$lwp_bytes,$lwp_bytes/1024/1024
+ if $DEBUG>3 || $VERBOSE>4;
+ $lwp_last_was_bytes=1;
+ $lwp_timer = time();
+ }
+ } else {
+ if ( $lwp_last_was_bytes) {
+ $out_string ="\n".$out_string;
+ $lwp_bytes=0;
+ }
+ printf STDERR "LWP: $out_string\n"
+ if $DEBUG>3 || $VERBOSE>6;
+ $lwp_last_was_bytes=0;
+ }
+ };
+ }
+}
+
+sub mirror_file($$){
+ my $url = shift;
+ my $local_filename = shift;
+
+ my $mirror=1;
+
+
+ return 1 if $NO_MIRROR;
+
+ # LPW::UserAgent initialisieren
+ my $ua = LWP::UserAgent->new;
+
+ # Set Proxy from Environment
+ if (!$PROXY) {
+ $PROXY ||= $ENV{'PROXY'};
+ $PROXY ||= $ENV{'http_proxy'};
+ print "Set Proxy to $PROXY\n"
+ if $PROXY && ( $DEBUG >2|| $VERBOSE>4);
+ }
+ if ( $PROXY ){
+ $PROXY = "http://$PROXY" unless $PROXY =~ m,^.?.tp://,;
+ $PROXY = "$PROXY/" unless $PROXY =~ m,/$,;
+ $ua->proxy(['http','ftp'],$PROXY);
+ }
+
+ #$ua->level("+trace") if $DEBUG;
+
+ print STDERR "mirror_file($url --> $local_filename)\n" if $DEBUG>2 || $VERBOSE>2;
+ my $response = $ua->mirror($url,$local_filename);
+# printf STDERR "success = %d <%s>",$response->is_success,$response->status_line if $DEBUG;
+
+ if ( ! $response->is_success ) {
+ if ( $response->status_line =~ /^304/ ) {
+ print "mirror_file($url): NOT MODIFIED\n" if $DEBUG ;
+ $mirror=2;
+ } else {
+ print "mirror_file($url): COULD NOT GET\n";
+ print sprintf("ERROR: %s\n",$response->message)
+ if $DEBUG || $VERBOSE;
+ $mirror=0;
+ }
+ } else {
+ print STDERR "mirror_file($url): OK\n" if $DEBUG>1 || $VERBOSE>4;
+ }
+ return $mirror;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Utils.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut
diff --git a/scripts/osm/perl_lib/Utils/Math.pm b/scripts/osm/perl_lib/Utils/Math.pm
new file mode 100644
index 0000000..984b91c
--- /dev/null
+++ b/scripts/osm/perl_lib/Utils/Math.pm
@@ -0,0 +1,65 @@
+##################################################################
+package Utils::Math;
+##################################################################
+
+use strict;
+use warnings;
+
+use Exporter;
+use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $VERSION);
+@ISA = qw( Exporter );
+@EXPORT = qw(min max);
+
+use Math::Trig;
+
+sub min($$){
+ my $a = shift;
+ my $b = shift;
+ return $b if ! defined $a;
+ return $a if ! defined $b;
+ return $a<$b?$a:$b;
+}
+
+sub max($$){
+ my $a = shift;
+ my $b = shift;
+ return $b if ! defined $a;
+ return $a if ! defined $b;
+ return $a>$b?$a:$b;
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+math.pm
+
+=head1 COPYRIGHT
+
+Copyright 2006, Jörg Ostertag
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+=head1 AUTHOR
+
+Jörg Ostertag (planet-count-for-openstreetmap@ostertag.name)
+
+=head1 SEE ALSO
+
+http://www.openstreetmap.org/
+
+=cut