Geo::Heatmap for Google Maps
Yesterday I released a new Version of Geo::Heatmap (0.16) it should be available on the CPAN mirror of your choice
Please see my older post to the same aucasinosonline topic
Two major changes:
- I got rid of Image::Magik (which ain’t fun to install) and replaced it with Imager which installs easily
- The example provided now uses the Version 3 of the Google Maps API
The example (Geo::Heatmap Demonstration) still looks the same
Coding example
The “calling” HTML
<head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0; padding: 0 } #map-canvas { height: 100% } </style> <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=&sensor=true"> </script> <script type="text/javascript"> 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); </script> </head> <body> <div id="map-canvas"/> </body>
The (f)cgi script
#!/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 => 'File', root_dir => '/tmp/domainmap' ); 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'); # in this case the zoom scale is static - basically it is the count of the tile with the most values $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, } ); $ghm->cache($cache); $ghm->return_points( \&get_points ); my $image = $ghm->tile($tile); my $length = length($image); print "Content-type: image/png\n"; print "Content-length: $length \n\n"; binmode STDOUT; print $image; } 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; }
Posted: December 6th, 2013 under Perl.