--- web/googlemap.cgi 2007/12/02 19:05:29 13
+++ web/googlemap.cgi 2007/12/07 03:44:12 27
@@ -4,86 +4,224 @@
use strict;
use HTML::GoogleMaps;
+use CGI;
use CGI::Carp qw/fatalsToBrowser/;
+use File::Find;
use Data::Dump qw/dump/;
-# http://localhost/
-my $map_key = 'ABQIAAAAVQ5szt9Jd8ws6vgfVQOEmhT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQ1cKf0DwFJcwtpESJEI0hL8QgtYg';
-
-my $trace = '/home/dpavlin/x/openmoko/gps/foo.loc';
-
-my $map = HTML::GoogleMaps->new(key => $map_key);
-#$map->center(point => "Zagreb, Hrvatska");
-
-sub deg {
- my $a = shift;
- if ( $a =~ m/^(\d+)(\d\d\.\d\d+)$/ ) {
- return sprintf("%1.6f", $1 + ( $2 / 60 ));
- } else {
- warn "## skipped $a\n";
- return;
- }
-}
+use lib '../lib';
+use blib;
+use NMEA;
-my $got_it;
+my $trace_path = '../nmea/';
-sub recalc {
- my ( $lat, $lat_ns, $lon, $lon_ew ) = @_;
-
- $lat = -$lat if $lat_ns eq 'S';
- $lon = -$lon if $lon_ew eq 'W';
-
- return if ( $got_it->{ $lat . $lon }++ );
-
- $lat = deg( $lat ) || return;
- $lon = deg( $lon ) || return;
-
- warn "## $lon $lat\n";
+# http://localhost/
+my $map_key = 'ABQIAAAAVQ5szt9Jd8ws6vgfVQOEmhT2yXp_ZAY8_ufC3CFXhHIE1NvwkxQ1cKf0DwFJcwtpESJEI0hL8QgtYg';
- return [ $lon, $lat ];
-}
+my @traces;
+find({ wanted => sub {
+ push @traces, $_ if -f $_;
+}}, $trace_path);
+
+my $q = CGI->new;
+
+print $q->header;
+
+my $head = '';
+my $html = join('', qq{
+
Select GPS NMEA dump
+ },
+ $q->start_form( -id => 'trace_frm' ),
+ $q->popup_menu(
+ -name => 'trace',
+ -values => [
+ map {
+ "$_ (" . (stat("$trace_path/$_"))[7] . " bytes)"
+ }
+ sort {
+ (stat("$trace_path/$a"))[9] <=> (stat("$trace_path/$b"))[9]
+ } @traces
+ ],
+ -onChange => 'trace_frm.submit()',
+ ),
+ $q->submit( -value => 'Show trace' ),
+ $q->br,
+ 'Draw ',
+ $q->popup_menu(
+ -name => 'points_filter',
+ -values => [ 'all', 'every', 'total of' ],
+ ),
+ $q->textfield(
+ -name => 'points_count',
+ -value => '',
+ -size => 2,
+ -onChange => 'trace_frm.submit()',
+ ),
+ ' points and ',
+ $q->popup_menu(
+ -name => 'placemark_filter',
+ -values => [ 'total of', 'every' ],
+ ),
+ $q->textfield(
+ -name => 'placemark_count',
+ -value => 5,
+ -size => 2,
+ -onChange => 'trace_frm.submit()',
+ ),
+ ' placemarks',
+ $q->end_form,
+);
+
+
+
+if ( my $trace = $q->param('trace') ) {
+ $trace =~ s/\s.+$//;
+
+ $trace = "$trace_path/$trace";
+
+ my $center_point;
+ my @points;
+ my @placemarks;
+
+ open(my $fh, '<', $trace) || die "can't open $trace: $!";
+ while( <$fh> ) {
-open(my $fh, '<', $trace) || die "can't open $trace: $!";
-while( <$fh> ) {
- if ( m/\$GPRMC/ ) {
- chomp;
- my @a = split(/,/,$_);
+ my $hash = NMEA->line( $_ ) || next;
- next unless $#a = 12;
+ my $point = [ $hash->{lon}, $hash->{lat} ];
+ $center_point ||= $point;
- warn "## [$#a] $_\n";
+ push @points, $point;
- my ( undef, $time, $validity, $lat, $lat_ns, $lon, $lon_ew, $speed, $course, $date, $var, $var_ew ) = @a;
+ push @placemarks, {
+ point => $point,
+ html => join('
',
+ map {
+ ucfirst($_) . ': ' . $hash->{$_}
+ } ( qw/number time lat lon speed course/ )
+ ),
+ };
- next unless $validity eq 'A';
+ }
+ close($fh);
- my $point = recalc( $lat, $lat_ns, $lon, $lon_ew ) || next;
+ if ( $#points >= 0 ) {
- $map->add_marker(
- point => $point,
- html => "Time: $time
Validity: $validityLat: $lat $lat_ns
Lon: $lon $lon_ew
Speed: $speed
Course: $course",
- ) if $validity eq 'A';
+ my $map = HTML::GoogleMaps->new(
+ key => $map_key,
+ width => '800px',
+ height => '600px',
+ );
+ #$map->center(point => "Zagreb, Hrvatska");
+
+ #$map->zoom(10);
+ $map->v2_zoom(20);
+ $map->controls("large_map_control", "map_type_control");
+ $map->map_type('hybrid');
+ $map->center( $center_point ) if $q->param('line') && $center_point;
+
+ sub filter_array {
+ my $o = {@_};
+ my ( $count, $filter, $code ) =
+ ( $o->{count}, $o->{filter}, $o->{code} ) ;
+ confess "no CODE?" unless ref($code) eq 'CODE';
+ my @array = @{ $o->{array} };
+
+ warn "count: $count filter: $filter\n";
+
+ my $code_calls = 0;
+
+ if ( $count && $filter =~ m/every/ ) {
+ foreach my $o ( 0 .. $#array ) {
+ next unless $o % $count == 0;
+ $code->( $array[$o] );
+ $code_calls++;
+ }
+ } elsif ( $count && $filter =~ m/total/ ) {
+ # total of
+ if ( $count < 2 ) {
+ # first
+ if ( $array[0]) {
+ $code->( $array[0] );
+ $code_calls++;
+ };
+ # last
+ if ( $count > 1 && $#array > 0 ) {
+ $code->( $array[$#array] );
+ $code_calls++;
+ };
+ return $code_calls;
+ }
+
+ my $d = $#array / ( $count - 1 );
+ foreach my $p ( 0 .. $count - 1 ) {
+ my $o = int($p * $d);
+ die "no element $p at $o from total of ",$#array + 1 unless $array[$o];
+ $code->( $array[$o] );
+ $code_calls++;
+ }
+ } else {
+ # show every
+ foreach my $e ( @array ) {
+ $code->( $e );
+ $code_calls++;
+ }
+ }
+ return $code_calls;
+ }
+
+ my @poly_points;
+ my $points = filter_array(
+ count => $q->param('points_count'),
+ filter => $q->param('points_filter'),
+ code => sub {
+ my $point = shift;
+ push @poly_points, $point;
+ },
+ array => \@points,
+ );
+
+ die "hum?" unless $#poly_points == $points - 1;
+
+ $map->add_polyline( points => [ @poly_points ] ) if @poly_points;
+
+ my $placemarks = filter_array(
+ count => $q->param('placemark_count'),
+ filter => $q->param('placemark_filter'),
+ code => sub {
+ my $placemark = shift;
+ $map->add_marker( %$placemark, noformat => 1 );
+ },
+ array => \@placemarks,
+ );
+
+ my ( $map_div, $map_script );
+ ( $head, $map_div, $map_script ) = $map->render;
+
+ $html .= join('',
+$#points + 1, ' points from ', $q->param('trace'), ' showing ',
+ $points ? $points . ' points' . ( $placemarks ? ' and ' : '' ) : '',
+ $placemarks ? $placemarks . ' placemarks' : '',
+ qq{
+$map_div
+$map_script
+GPS - NMEA sentence information
+ });
+
+ } else {
+ $html .= 'No points found for ' . $q->param('trace') . '';
}
-}
-close($fh);
-
-#$map->zoom(10);
-#$map->v2_zoom(0);
-$map->controls("large_map_control", "map_type_control");
-$map->map_type('hybrid');
-my ($head, $map_div, $map_script) = $map->render;
+}
-print "Content-type: text/html\n\r\n\r";
print qq{
+
Read GPS - NMEA sentence and display it on GoogleMaps
-$head
+$head
+
-$map_div
-
-$map_script
-GPS - NMEA sentence information
+$html
};