--- 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: $validity
Lat: $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 };