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'