NAME

Geo::Heatmap - generate a density map (aka heatmap) overlay layer for Google Maps, see the www directory in the distro how it works

VERSION

version 0.15

REQUIRES

Moose
Storable
CHI
Imager
METHODS

tile

tile(); return the tile image in png format ATTRIBUTES

debug cache logfile return_points zoom_scale palette USAGE

Create a Heatmap layer for GoogleMaps The HTML part

tileSize: new google.maps.Size(256, 256), isPng: true, opacity: 0.4 }]; function initialize() { var mapOptions = { center: new google.maps.LatLng(48.2130, 16.375), zoom: 9 }; var map = new google.maps.Map(document.getElementById("map-canvas"), mapOptions); var overlayMap = new google.maps.ImageMapType(overlayMaps[0]); map.overlayMapTypes.setAt(0,overlayMap); } google.maps.event.addDomListener(window, 'load', initialize); </script> </head> <body> <div id="map-canvas"/> </body>

The (f)cgi part


  #!/usr/bin/env perl  use strict;
  use FCGI;
  use DBI;
  use CHI;
  use FindBin qw/$Bin/;
  use lib "$Bin/../lib";
  
  use Geo::Heatmap;
  
  #my $cache = CHI->new( driver  => 'Memcached::libmemcached',
  #    servers    => [ "127.0.0.1:11211" ],
  #    namespace  => 'GoogleMapsHeatmap',
  #);
  
  
  my $cache = CHI->new( driver => 'File',
           root_dir => '/tmp/GoogleMapsHeatmap'
       );
  
  
  our $dbh = DBI->connect("dbi:Pg:dbname=gisdb", 'gisdb', 'gisdb', {AutoCommit => 0});
  
  my $request = FCGI::Request();
  
  while ($request->Accept() >= 0) {
    my $env = $request->GetEnvironment();
    my $p = $env->{'QUERY_STRING'};
  
    my ($tile) = ($p =~ /tile=(.+)/);
    $tile =~ s/\+/ /g;
  
    # package needs a CHI Object for caching
    #               a Function Reference to get LatLOng within a Google Tile
    #               maximum number of points per zoom level
  
    my $ghm = Geo::Heatmap->new();
    $ghm->palette('palette.store');
    $ghm->zoom_scale( {
      1 => 298983,
      2 => 177127,
      3 => 104949,
      4 => 90185,
      5 => 70338,
      6 => 37742,
      7 => 28157,
      8 => 12541,
      9 => 3662,
      10 => 1275,
      11 => 417,
      12 => 130,
      13 => 41,
      14 => 18,
      15 => 10,
      16 => 6,
      17 => 2,
      18 => 0,
    } );
  
  sub get_points {
    my $r = shift;
  
    my $sth = $dbh->prepare( qq(select ST_AsEWKT(geom) from geodata
                           where geom &&
                ST_SetSRID(ST_MakeBox2D(ST_Point($r->{LATN}, $r->{LNGW}),
                                        ST_Point($r->{LATS}, $r->{LNGE})
                          ),4326))
                );
  
    $sth->execute();
  
    my @p;
    while (my @r = $sth->fetchrow) {
      my ($x, $y) = ($r[0] =~/POINT\((.+?) (.+?)\)/);
      push (@p, [$x ,$y]);
    }
    $sth->finish;
    return \@p;
  }
  
  

You need a color palette (one is included) to encode values to colors, in Storable Format as an arrayref of arrayrefs eg

[50] = [34, 45, 56]

which means that a normalized value of 50 would lead to an RGB color of 34% red , 45% blue, 56% green.

zoom_scale

The maximum number of points for a given google zoom scale. You would be able to extract to values from the denisity log or derive them from your data in some cunning way

You need a color palette (one is included) to encode values to colors, in Storable Format as an arrayref of arrayrefs eg

[50] = [34, 45, 56]

which means that a normalized value of 50 would lead to an RGB color of 34% red , 45% blue, 56% green.

zoom_scale

The maximum number of points for a given google zoom scale. You would be able to extract to values from the denisity log or derive them from your data in some cunning way

>>>>>>> topic-imager =item cache

You need some caching for the tiles otherwise the map would be quite slow. Use a CHI object with the cache you like

return_points

A function reference which expects a single hashref as a parameter which defines two LAT/LONG points to get all data points within this box:

$r->{LATN}, $r->{LNGW}), $r->{LATS}, $r->{LNGE}

The function has to return an arrayref of arrayrefs of the points within the box

tile

Returns the rendered image

AUTHOR

Mark Hofstetter <hofstettm@cpan.org>

Thanks to 
brian d foy
Marcel Gruenauer
David Steinbrunner

TODO

  • put more magic in calculation of zoom scales
  • make more things configurable
  • add even more tests

COPYRIGHT AND LICENSE

This software is copyright (c) 2013 by Mark Hofstetter

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

1 POD Error

The following errors were encountered while parsing the POD:

Around line 368:

You forgot a '=back' before '=head1'