1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
|
#!/usr/bin/perl
# Written by Curt Mills, WE7U
# Released to the public domain.
#
# Script to create Xastir "Overlay" files from "CSV" files of the
# proper format (comma-delimited files).
#
# 1) Creates files in Xastir "log" format if you enter a callsign
# below. These files can then be put in your ~/.xastir/logs/
# directory and brought in via the File->Open Log File menu option.
# If you start with the CSV files in the ~/.xastir/logs/ directory
# and process them there with this script, the output files will be
# placed into the proper place for Xastir to find them.
#
# 2) If no callsign is entered, this script will create files in
# Xastir's "~/.xastir/config/object.log" format. You can then
# replace or append the file to the object.log file, restart Xastir
# or "Reload Object/Item History".
#
# NOTE: These APRS Items will become part of your locally
# owned/transmitted objects, so if you don't want them transmitted,
# turn of Object/Item transmit before bringing them in.
#
# Input: Directory name. If no directory name passed in, it will
# operate on every CSV file in the current directory.
#
# Input format:
# Name N/S lat E/W long // comment fields.............
# SUPPLY,N,34.0000,W,78.0000,ICON,text1,text2,text3,text4,...
#
#
# The name will have spaces removed if it is longer than nine
# characters. If it is still too long, vowels will be removed, then
# it will be truncated to nine characters if still needed. The full
# name will be transmitted as a comment. All other text fields will
# also be transmitted as comments, so that they will all appear in
# the Station Info dialog.
#
# Icons will be a default small red circle unless '/' or '\' is the
# leading character in that field and the next specifies the APRS
# symbol. In that case the two-letter combination will get used as
# the symbol for the Item.
# Change this to match whatever callsign you're running Xastir as,
# so that the APRS Items appear to have been generated locally. You
# can then suck this file in as a "log" file from within Xastir. If
# this field is empty, then instead write the packets out without a
# header, as in Xastir's "object.log" format.
$callsign = "";
if ($callsign ne "") {
$callsign = uc($callsign) . '>APRS:';
}
# Main program. Process every ".csv" file found in the directory.
#
$dirname = shift;
if ($dirname == "") {
$dirname = ".";
}
opendir(DIR, $dirname) or die "Can't opendir $dirname: %!";
while (defined($file = readdir(DIR))) {
chomp $file;
if ( $file =~ /\.csv$/ ) {
# Do something with "$dirname/$file"
&process_file($dirname, $file);
}
else {
# printf("$dirname/$file\n");
}
}
# Process one file. Creates an output file that matches the
# basename but changes the "csv" to "overlay".
#
sub process_file() {
$output_file = $_[1];
$output_file =~ s/\.csv$/.overlay/;
printf("$dirname/$file -> $output_file\n");
open(SOURCE, "< $_[1]")
or die "Couldn't open $path for reading: $!\n";
open(OUTPUT, "> $output_file")
or die "Couldn't open $output_file for writing: $!\n";
while (<SOURCE>) {
&process_line($_);
}
close(SOURCE);
close(OUTPUT);
}
# Process one line. Write the formatted data to the OUTPUT file.
#
sub process_line() {
#printf("$_[0]");
# Parse the CSV line into an array
@list = parse_csv($_[0]);
if (!($list[0] =~ m/Location/i)) {
#print OUTPUT @list;
# As a temporary measure, create items out of each of the lines,
# with a status line for each extra data object so that they
# appear in the Station Info dialog.
&create_items(@list);
}
}
# Create an APRS Item out of each array. Create a status line for
# each extra column associated with a line so that the info shows up
# in the Station Info dialog.
#
# Examples. Name is 3-9 characters:
# )AID #2!4903.50N/07201.75WA
# )G/WB4APR!53 . N\002 . Wd
#
sub create_items {
$name = $_[0];
if ($name eq "") {
printf("Error, name column is empty\n");
}
# If too long, try removing spaces first
if (length($name) > 9) {
$name =~ s/\s//ig;
}
# If still too long, remove vowels
if (length($name) > 9) {
$name =~ s/a//ig;
$name =~ s/e//ig;
$name =~ s/i//ig;
$name =~ s/o//ig;
$name =~ s/u//ig;
}
# Extend to three characters if short
if (length($name) < 3) {
$name = $name . " ";
}
$name = substr($name,0,9);
$name[9] = "\0"; # Terminate name at 9 characters, minimum 3
$n_s = uc( substr($_[1],0,1) );
$latitude = $_[2];
$e_w = uc( substr($_[3],0,1) );
$longitude = $_[4];
if ($_[5] =~ /ICON/i) {
$icon1 = "/";
$icon2 = "/";
}
else {
$icon1 = substr($_[5],0,1);
$icon2 = substr($_[5],1,1);
}
# Convert lat/long to APRS format (or Base-91 Compressed format)
$lat_deg = $latitude;
$lat_deg =~ s/\.\d+$//;
$lat_deg = sprintf("%02d", $lat_deg);
$lat_min = $latitude;
$lat_min =~ s/^\d+\./0./;
$lat_min = $lat_min * 60.0;
$lon_deg = $longitude;
$lon_deg =~ s/\.\d+$//;
$lon_deg = sprintf("%03d", $lon_deg);
$lon_min = $longitude;
$lon_min =~ s/^\d+\./0./;
$lon_min = $lon_min * 60;
# Create an APRS "Item" packet
$line = sprintf("%s)%s!%s%05.2f%s%s%s%05.2f%s%s",
$callsign,
$name,
$lat_deg,
$lat_min,
$n_s,
$icon1,
$lon_deg,
$lon_min,
$e_w,
$icon2);
# Go process the rest of the columns, if any. Create APRS Item
# packets with comments from them.
for ($i = 6; $i < 106; $i++) {
chomp $_[$i];
if ($_[$i] ne "") {
#printf("$_[$i]");
printf(OUTPUT "%s%s\n",
$line,
$_[$i]);
}
}
# Write it out to the file, with the full name as a comment
printf(OUTPUT "%s%s\n",
$line,
$_[0]);
}
# Parse CSV line into an array, removing double-quotes and such if
# found.
#
sub parse_csv {
my $text = shift; # Record containing comma-separated values
my @new = ();
push(@new, $+) while $text =~ m{
# The first part groups the phrase inside the quotes.
# See explanation of this pattern in MRE
"([^\"\\]*(?:\\.[^\"\\]*)*)",?
| ([^,]+),?
| ,
}gx;
push(@new, undef) if substr($text, -1, 1) eq ',';
return @new; # List of values that were comma-separated
}
|