Well, my answer is probably overkill, but I found the problem so much fun that I wrote the code for it. This may not be the most efficient way of getting your answer, but it's what I came up with. Any optimization advice would be great!
Here's the sample data file I created:
Mt. Wrangell,AK,62N,144W
Hico,TX,32N,99W
Neotsu,OR,45N,124W
Applegate,CA,39N,121W
Arbuckle,CA,39N,122W
Lakeport,CA,39N,123W
Hot Springs,CA,40N,121W
Here's the program:
#!/usr/bin/perl -w
use strict;
my $data = "test.txt"; # here is the raw latitude/longitude
+ data
my ($xlat, $xlon) = qw(39N 122W); # here's what we'll search for, +/-
+$variance
my (%lat_lon, @lat, @lon, @final_lat, @final_lon, %dups);
my $variance = 1; # change this to the degree variance
+ desired
open (DATA, "<$data") || die "Can't open $data for reading: $!\n";
while (<DATA>) {
chomp;
my ($city, $state, $lat, $lon) = split /,/;
$lat_lon{$lat}{$lon}->[0] = $city;
$lat_lon{$lat}{$lon}->[1] = $state;
}
close (DATA) || die "Can't close $data: $!\n";
# find all lats which are +/- $variance of target lat
foreach my $lat_key (keys %lat_lon) {
my ($lat, $lat_NS, $xlat_NS);
$lat = $1, $lat_NS = $2 if $lat_key =~ /^(\d{1,3})([NS])$/o;
$xlat_NS = $2 if $xlat =~ /^(\d{1,3})([NS])$/o;
if ($xlat_NS eq $lat_NS) {
push (@lat, $lat_key) if ($1 <= $lat + $variance) && ($1 >= $l
+at - $variance);
}
}
# find all lons which are +/- $variance of target lon
foreach my $good_lat (@lat) {
foreach my $lon_key (keys %{$lat_lon{$good_lat}}) {
my ($lon, $lon_WE, $xlon_WE);
$lon = $1, $lon_WE = $2 if $lon_key =~ /^(\d{1,3})([WE])$/o;
$xlon_WE = $2 if $xlon =~ /^(\d{1,3})([WE])$/o;
if ($xlon_WE eq $lon_WE) {
push (@lon, $lon_key) if ($1 <= $lon + $variance) && ($1 >
+= $lon - $variance);
}
}
}
# remove duplicate latitudes and longitudes
foreach (@lat) {
push (@final_lat, $_) unless $dups{$_}++;
}
foreach (@lon) {
push (@final_lon, $_) unless $dups{$_}++;
}
The two arrays, @final_lat and @final_lon, will contain all of the unique latitudes and longitudes which are within $variance of your target latitude and longitude.
Incidentally, the information that you were looking for regarding multi-dimensional arrays is found in Programming Perl, by O'Reilly Books, Second Edition, starting on page 257. You'll want to read through that to see what I was doing with a hash of hashes of arrays.
Cheers!
Update: As mentioned in previous answers, you'll want to check out Text::CSV. My example above will fail if you have a data field with an embedded comma:
"Some city, County", State, 45N, 120W
The quotes will also cause problems if you're trying to eliminate them.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.