2 #TODO In its infinite wisdom, the XML the NWS gives us (NWS-Stations.xml) is
3 # not consistent wrt to lat lon. Some are in a +/- format, others in [NSEW]
4 # format, also, some aren't even listed. It seems unlikely that the NWS doesn't
5 # know that location of some of its weather stations and in fact they are on
6 # their website, so maybe write a script to grab missing ones and massage them
7 # all to a consistent format.
15 use base qw(XML::SAX::Base);
21 our @ISA = qw(Exporter);
22 our @EXPORT = qw(doSearch AddLatLonSearch AddStationIdSearch AddLocSearch);
26 my @stationidsearches;
33 my $xml_file = dirname(abs_path($0 or $PROGRAM_NAME)) . "/NWS-Stations.xml";
35 my $parser = new XML::Parser( Style => 'Stream' );
36 open(XML, $xml_file) or die "cannot open NWS-Stations.xml file\n";
39 return $searchresults;
50 my ($expat, $name, %atts) = @_;
52 if ($name eq 'station') {
53 $expat->{CurrEntry} = {};
54 $expat->{MatchFound} = 0;
61 my $text = $expat->{Text};
64 if ($expat->in_element('station_id')) {
65 $expat->{CurrEntry}->{station_id} = $text;
66 if (!$expat->{MatchFound}) {
67 foreach $search (@stationidsearches) {
68 if ($text =~ m/$search/i) {
69 $expat->{MatchFound} = 1;
76 if ($expat->in_element('state')) {
77 $expat->{CurrEntry}->{state} = $text;
78 if (!$expat->{MatchFound}) {
79 foreach $search (@statesearches) {
80 if ($text =~ m/$search/i) {
81 $expat->{MatchFound} = 1;
88 if ($expat->in_element('station_name')) {
89 $expat->{CurrEntry}->{station_name} = $text;
90 if (!$expat->{MatchFound}) {
91 foreach $search (@locstrsearches) {
92 if ($text =~ m/$search/i) {
93 $expat->{MatchFound} = 1;
100 # annoyingly, the lat/lon format is not consistent in the XML file,
101 # sometimes its in +/- format, other times N/S E/W, so we convert it right
102 # off to be unifrom in +/-
103 if ($expat->in_element('latitude')){
104 $text =~ s/(\d{1,3}([.]\d{1,3})?)([.]\d{1,3})?[N]/+$1/ or
105 $text =~ s/(\d{1,3}([.]\d{1,3})?)([.]\d{1,3})?[S]/-$1/;
106 $expat->{CurrEntry}->{latitude} = $text;
107 $expat->{currLat} = $text;
111 if ($expat->in_element('longitude')) {
112 $text =~ s/(\d{1,3}([.]\d{1,3})?)([.]\d{1,3})?[E]/+$1/ or
113 $text =~ s/(\d{1,3}([.]\d{1,3})?)([.]\d{1,3})?[W]/-$1/;
114 $expat->{CurrEntry}->{longitude} = $text;
115 if (!$expat->{MatchFound}) {
116 foreach $search (@latlonsearches) {
117 if ($search->[0] eq $expat->{currLat} && $search->[1] eq $text) {
118 $expat->{MatchFound} = 1;
127 my ($expat, $name) = @_;
129 if ($name eq 'station' && $expat->{MatchFound}) {
130 push (@$searchresults, $expat->{CurrEntry});
131 if ($expat->{finish}) {
139 sub AddLatLonSearch {
140 my ($lat, $lon) = @_;
141 push (@latlonsearches, [$lat, $lon]);
144 sub AddStationIdSearch {
146 push (@stationidsearches, $id);
151 push (@locstrsearches, $loc);
156 push (@statesearches, $state);