A CGI script to plot GnuAIS data on Google Maps


I've been a very satisfied user of Shipplotter for a while, but I've been happy to discover an open source project giving some AIS decoding capabilities to Linux as well, since I'm more and more moving away from Windows.
GnuAIS works fine with audio coming from the "packet" socket of my FT817/FT857, however I've been unable to run the provided GUI. Map is displayed on the screen but nothing else happens.
Since all received data can be optionally logged into a MySQL database, I thought  I might as well use that source for an alternative plotting on maps that could in the futurer be integrataed with other sources (es. ACARS).
My home pc was already running a LAMP (Linux, Apache, MySQL, Perl) platform to support my radio experiments, so all I had to do was gluing together some pieces.
Goggle Maps interaction happens via HTML::GoogleMaps which I found on CPAN.
Database interaction happens via the usual library, while and makes the magic in the Apache interaction.
Please find below an almost functional script: to make it work
Additional info:
Known issues:

# gnuias_display - a CGI to plot data from GnuAIS
# (c) 2010 Stefano Sinagra IZ0MJE
# released under GNU/GPL v3 license

  use CGI qw/:standard -nosticky/;

  use DBI;
  use DateTime;
  use HTML::GoogleMaps;

### change settings in this block
# db settings
$dbname='DBI:mysql:<database name>:<host>';
$dbuser='<db user>';
$dbpass='<db password>';
# Google Maps settings
$map_key="<Google maps API key>";
# home station coordinates
$home_long=<your home longitude>;
$home_lat=<your home latitude>;

# db connection
$dbh = DBI->connect($dbname,$dbuser,$dbpass) or die DBI->errstr;

$sth = $dbh->prepare('(select mmsi, latitude, longitude, name, destination, ais_position.time from ais_position left join ais_vesseldata using (mmsi) order by ais_position.time desc) union (select mmsi, latitude, longitude, "shore station", "n/a", null from ais_basestation);') or die "Couldn't prepare statement: " . $dbh->errstr; 

### map embedding
$map = HTML::GoogleMaps->new(
    key => $map_key,
    height =>480,
    width =>940);
$map->controls(large_map_control, map_type_control);
$map->center( [$home_long,$home_lat] );
$map->add_marker(point => [$home_long,$home_lat],html => "basestation", noformat => 1 );

 $marker = 65;
 while (@data = $sth->fetchrow_array()) {
    $char = chr($marker);
    if ($data[4] eq "") { $data[4]="unknown"; }
    if ($data[3] eq "shore station") { $popup = "$data[0] $data[3]";
        } else { $popup = "$data[0] $data[3] dest. $data[4]";}
    $map->add_marker(point => [$data[2],$data[1]], html => $popup, noformat => 1, icon => $char ) };

my ($head, $map_div) = $map->onload_render;

       print header,
        h1('AIS monitoring'),
        '<body onload="html_googlemaps_initialize()">',

print $map_div;

print $head;

print hr;


        # Read the matching records and print them out
        print "<table border=1>";
        print "<tr BGCOLOR='#C0C0C0'><th>marker</th><th>mmsi</th><th>lat</th><th>lon</th><th>description</th><th>destination</th></tr>";
        $marker = 65;
        while (@data = $sth->fetchrow_array()) {
            $char = chr($marker);
            print "<tr><td align=center>", $char , "</td><td>", $data[0],"</td><td>", $data[1], "</td><td>", $data[2], "</td><td>", $data[3], "</td><td>", $data[4], "</td></tr>";}
        print "</table>";

    print "<p><a href= target='_blank'>Search ship data in ITU database</a>";

Contact:indirizzo come immagine per diminuire lo spam

Published:  21Nov10 - Home