Geo-Heatmap

 view release on metacpan or  search on metacpan

lib/Geo/Heatmap.pm  view on Meta::CPAN

  my @density;
  my $bin = $self->bin;
  foreach my $p (@$ps) {
    my @d = Google_Coord_to_Pix($value, $p->[0], $p->[1]);
    my $ix = $d[1] - $r{PXW};
    my $iy = $d[0] - $r{PYN};
    $density[int($ix/$bin)][int($iy/$bin)] ++;
    printf "%s %s %s %s\n", $ix, $iy, $ix % $bin, $iy % $bin if $self->debug >5;
  }
  
  my $maxval = ($bin)**2;
  # $zoom_scale->{$z} |= 0;
  my $defscale = $zoom_scale->{$z} > 0 ? $zoom_scale->{$z} : $maxval;
  $defscale *= 1.1 ;
  my $scale = 500/log($defscale);
  my $max = 256/$bin - 1;
  my $dmax = 0;
  
  for (my $i = 0; $i <= $max; $i++) {
    for (my $j = 0; $j <= $max; $j++) {
      my $xc  = $i*$bin;
      my $yc  = $j*$bin;
      my $xlc = $xc+$bin;
      my $ylc = $yc+$bin;
      my $d = $density[$i][$j] ? $density[$i][$j] : 1;
      $dmax = $d > $dmax ? $d : $dmax;
      my $color_index = int(500-log($d)*$scale);
      $color_index = 5 if $color_index < 1;
      $color_index = -1 if $d < 3;
      my $color = $palette->[$color_index];
      # from percent to RGB - gna
      my $rgb = Imager::Color->new( $color->[0] * 2.55, $color->[1]*2.55, $color->[2]*2.55 );
      $image->box(color=> $rgb, xmin=>$xc,  ymin=>$yc,
                               xmax=>$xlc, ymax=>$ylc, filled=>1);

#      $image->Draw(fill=>"rgb($rgb)" , primitive=>'rectangle', points=>"$xc,$yc $xlc,$ylc");
      printf "[%s][%s] %s %s\n", $i, $j, $d, $color_index if $self->debug > 0;
    }
  }
  
  if ($self->logfile) {
    open (LOG, ">>". $self->logfile);
    printf LOG  "densitylog:  x y z pointcount: %s %s %s %s\n", $x, $y, $z, $dmax;
    close LOG;
  }
  
  $image->write(data => \$ubblob, type => 'png');
  $self->cache->set($mca, $ubblob);
  return $ubblob;
}

1;


__END__

=pod

=head1 NAME

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

see the script directory for creating a scale

for a real life example see 

http://www.trust-box.at/dev/gm/GoogleMapsHeatmap/www/GoogleMapsHeatmap.html

for Dokumentation see

=head1 HOMEPAGE

http://www.trust-box.at/googlemaps-geoheatmap/

=head1 REQUIRES

  Moose
  CHI
  Imager

=head1 METHODS

=head2 tile

  tile();

  return the tile image in png format

=head1 ATTRIBUTES

  debug
  cache
  logfile
  return_points
  zoom_scale
  palette

=head2 USAGE

Create a Heatmap layer for GoogleMaps

=head3 The HTML part

=begin html

<pre>
<code>
  &lt;head&gt;
     &lt;meta name="viewport" content="initial-scale=1.0, user-scalable=no" /&gt;
     &lt;style type="text/css"&gt;
       html { height: 100% }
       body { height: 100%; margin: 0; padding: 0 }
       #map-canvas { height: 100% }
     &lt;/style&gt;
     &lt;script type="text/javascript"
       src="https://maps.googleapis.com/maps/api/js?key=<yourapikey>&sensor=true"&gt;
     &lt;/script&gt;
     &lt;script type="text/javascript"&gt;
       var overlayMaps = [{
         getTileUrl: function(coord, zoom) {
           return "hm.fcgi?tile="+coord.x+"+"+coord.y+"+"+zoom;
         },
 
         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);
 
     &lt;/script&gt;
   &lt;/head&gt;
   &lt;body&gt;
     &lt;div id="map-canvas"/&gt;
  &lt;/body&gt;
</code>
</pre>
<br>

=end html

=head3 The (f)cgi part

=begin html

<pre>
<code>
  #!/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');



( run in 4.243 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )