#! /usr/bin/perl # A program to convert DeLorme Street Atlas 8 route files to a file # ready to import into MySQL for GpsDrive. # Time-stamp: <2005-09-13 12:20:49 ccurley sa2gpsdrive> # Copyright 2005 through the last date of modification, Charles Curley. # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA # You can also contact the Free Software Foundation at # http://www.fsf.org/ # You can export a route from DeLorme Street Atlas 8 (and possibly # other versions) with "File-> Export Route as Lat/Long File". The # default file name is rpoints.txt. The result is a point per line, # latitude followed by longitude, with a space and a comma in # between. Really simple. This program massages that format into a # MySQL import script, ready to import into MySQL for GpsDrive. # The default waypoint type is 'DeLorme', but you can change that with # a command line option, -t. The resulting script will first delete # all waypoints of that type, so you can make corrections and try as # you go. This also means you should NOT make any other waypoints this # type. # You can set a value for filtering waypoints with the -n option, # where n is an integer from 1 on up. The program will send the first, # last and every nth waypoint to the output file. # In addition, you may use a text editor to add an optional third # column to any line. The script uses this field for the name for that # waypoint, and any line with a name added will also be sent to the # output file, even if it is not one of the -nth entries. Use a comma # for the delimiter, so commas in the name are verboten. Single quotes # are escaped, so that MySQL won't choke on them. # The default waypoint name is the waypoint count, followed by the # type. So if you set N to 1 (the default) the waypoint's name on the # screen gives you the line in the source file to which to add a # name. You can then re-filter the source file with a larger N, which # will give you a sparser set of waypoints. Use this to force # inclusion of important waypoints like intersection. # The default input file is rpoints.txt (How's that for user friendly? # :-). You may specify another with the -i option. The output file is # the base name of the file (i.e. without any extension) plus the # extension .sql. So the default output file is rpoints.sql. The # output file is delivered to your maps directory as specified in your # gpsdrive configuration file, .gpsdrive/gpsdriverc. # In addition, this program generates another file you may use when # you are done using the waypoints to delete them from the # database. That file has the extension .del.sql, and is also # delivered to your maps directory. use strict; use Getopt::Std; use File::Basename; # Get the name of the database, and user name and password to log in # to MySQL from the gpsdrive config file. my $input = $ENV{HOME} . '/.gpsdrive/gpsdriverc'; my $dbname; my $dbuser; my $dbpass; my $dbtable; my $dbhostname; my $mapdir; open (SOURCE, "< $input") or die "Couldn't open input file $input.\n"; while () { chop (); my @line = split ('='); chop ($line[0]); if ($line[0] eq 'dbname') { # print "Examining $line[0] is set to $line[1].\n"; $dbname = $line[1]; $dbname =~ s/^\s+//; # strip leading spaces. $dbname =~ s/\s+$//; # strip trailing spaces. } elsif ($line[0] eq 'dbuser') { # print "Examining $line[0] is set to $line[1].\n"; $dbuser = $line[1]; $dbuser =~ s/^\s+//; # strip leading spaces. $dbuser =~ s/\s+$//; # strip trailing spaces. } elsif ($line[0] eq 'dbpass') { # print "Examining $line[0] is set to $line[1].\n"; $dbpass = $line[1]; $dbpass =~ s/^\s+//; # strip leading spaces. $dbpass =~ s/\s+$//; # strip trailing spaces. } elsif ($line[0] eq 'dbtable') { # print "Examining $line[0] is set to $line[1].\n"; $dbtable = $line[1]; $dbtable =~ s/^\s+//; # strip leading spaces. $dbtable =~ s/\s+$//; # strip trailing spaces. } elsif ($line[0] eq 'dbhostname') { # print "Examining $line[0] is set to $line[1].\n"; $dbhostname = $line[1]; $dbhostname =~ s/^\s+//; # strip leading spaces. $dbhostname =~ s/\s+$//; # strip trailing spaces. } elsif ($line[0] eq 'mapdir') { # print "Examining $line[0] is set to $line[1].\n"; $mapdir = $line[1]; $mapdir =~ s/^\s+//; # strip leading spaces. $mapdir =~ s/\s+$//; # strip trailing spaces. } } # The input file default value $input = "rpoints.txt"; # The default type value my $type = 'DeLorme'; # Increment for filtering waypoints. Use only every nth point. my $nth = 1; # Shall we determine our extreme points? my $points = 0; my $i = 0; # generic counter sub oops { print "$0: a script to convert DeLorme route points files to GspDrive waypoints.\n"; print "options: -i: input file; -t: waypoint type; -n: use every nth point.\n"; print "-p: print the extremes of north/south/east/west travel.\n"; } my %option = (); getopts ("hi:n:pt:", \%option); if ($option{h}) { &oops (); exit (0); } if ($option{i}) { $input = $option{i}; } if ($option{n}) { $nth = $option{n}; } if ($option{t}) { $type = $option{t}; } if ($option{p}) { $points = $option{p}; } # print "Filtering file $input\n"; # print "Waypoint type is $type\n"; # Get rid of any path and prepend that of the map directory. my $output = $mapdir . basename($input); # remove the extension, if any. my @output = split (/\./, $output); if ($#output) { $#output--; $output = join ('.', @output); } # print ("file base name is $output\n"); # Open read only & count the lines, so we can get the last # one. Initialize to the extreme of travel on the planet. my $total = my $lines = 0; my $north = -90; my $south = 90; my $east = -180; my $west = 180; my ($nl, $sl, $el, $wl); open (SOURCE, "< $input") or die "Couldn't open input file $input.\n"; while () { # split the line. if ($points) { $lines++; chop (); chop (); my @line = split (','); $line[0] =~ s/^\s+//; $line[0] =~ s/\s+$//; $line[1] =~ s/^\s+//; $line[1] =~ s/\s+$//; if ($north < $line[0]) { $north = $line[0]; $nl = $lines; } if ($south > $line[0]) { $south = $line[0]; $sl = $lines; } if ($east < $line[1]) { $east = $line[1]; $el = $lines; } if ($west > $line[1]) { $west = $line[1]; $wl = $lines; } } } $total = $.; # The total count of lines. # print ("$nl, $sl, $el, $wl\n$north, $south, $east, $west"); # Open for read only. open (SOURCE, "< $input") or die "Couldn't open input file $input.\n"; # Open for write, create and truncate open (SINK, "> $output.del.sql") or die "Couldn't open output file $output.del.sql\n"; print SINK "use $dbname;\n"; print SINK "delete from $dbtable where type='$type';\n"; # Open for write, create and truncate open (SINK, "> $output.sql") or die "Couldn't open output file $output.sql.\n"; print SINK "use $dbname;\n"; print SINK "delete from $dbtable where type='$type';\n"; my $count = $lines = 0; my $name = ''; while () { chomp; $lines++; # split the line. my @line = split (','); if ($points) { # If there's no name and this line is one of the extreme # travel points, add a name. if ($lines == $nl && !length ($line[2])) { $line[2] = 'Northernmost Point.'; } if ($lines == $sl && !length ($line[2])) { $line[2] = 'Southernmost Point.'; } if ($lines == $el && !length ($line[2])) { $line[2] = 'Easternmost Point.'; } if ($lines == $wl && !length ($line[2])) { $line[2] = 'Westernmost Point.'; } } # On every nth line, any line with a comment, the last line, or the first line... $i++; if ($i == $nth || length ($line[2]) || $lines == $total || $lines == 1) { if ($i == $nth) { $i=0; $count++; } if (length ($line[2])) { $name = $line[2]; # Trim leading & trailing whitespace $name =~ s/^\s+//; $name =~ s/\s+$//; # Escape single quotes. $name =~ s/\'/\\\'/g; } elsif ($lines == 1) { $name = 'Start'; } elsif ($lines == $total) { $name = 'Finish'; } else { $name = "$count $type waypoint"; } # Turn spaces into underscores for GpsDrive's benefit. $name =~ s/ /\_/g; print SINK "INSERT INTO $dbtable VALUES ('$name', '$type', '0', '$line[0]', '$line[1]', '', 0, '0', 0, NULL);\n"; $line[2] = ''; } undef (@line); } print ("Feed the output file into MySQL like so:\n\n\$ mysql -u$dbuser -p$dbpass < $output.sql\n"); exit (0);