15

I have a list of values each with latitude and longitude. I'm looking to create a translucent heatmap image to overlay on Google Maps. I know there are server side and flash based solutions already, but I want to build this in javascript using the canvas tag.

However, I can't seem to find a concise description of the algorithm used to turn coordinates and values into a heatmap. Can anyone provide or link to one?

Thanks.

eshan
  • 245
  • 1
  • 3
  • 9

4 Answers4

10

The basic idea would be to create a grid and project every lat,lng coord to that grid. I would use a 2D array of ints.

The psuedo-code would be:

for each coord
  cell = coord projected to grid
  increment cell value
end

for 0 to # of passes
  for each row
   for each col
     if grid[row,col] > 0 then
       grid[row,col] += 1
       increment_adjacent_cells(row, col)
     end
   end
  end
end

So, the idea is that the higher the int value, the hotter that cell is. increment_adjacent_cells should increment the values in all 8 adjacent cells.

Kai
  • 9,444
  • 6
  • 46
  • 61
ConsultUtah
  • 6,639
  • 3
  • 32
  • 51
  • 2
    This is the basic idea; but instead of doing multiple passes to "spread" the heat, it'd be better to have something like a circular Gaussian mask that you can just add into the grid at every data point. Also, this question might have useful answers: http://stackoverflow.com/questions/1117048/creating-heatmaps-using-canvas-element – tzaman Feb 26 '10 at 18:33
4

I have tried to solve this in javascript using the canvas element, here is my current result:

http://gist.github.com/346165

I have to fix the gaussian filter and the color mapping, because it doesn't give good results currently.

Jeroen van Dijk
  • 1,029
  • 10
  • 16
  • 1
    That's an interesting thing. I was planning to draw heatmaps with DOM objects (no blur obviously) but your solution could provide some serverside-alike results in terms of the look and feel. Your problem with colors is caused by the `maximum` variable. – naugtur Jun 15 '11 at 11:42
  • 1
    This looks nice - fast and reusable: http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html – naugtur Jun 15 '11 at 11:56
  • 1
    I saved your code as [a jsFiddle here](http://jsfiddle.net/drewnoakes/aewmJ/) for folks to try out. It's an interesting approach but doesn't seem to render a sensible result. Did I miss something? Maybe browsers have changed since you authored this code. – Drew Noakes Jul 29 '13 at 09:21
2

A faster way of building a heatmap could be to use a queue:

Pseudocode:

Add an element to queue (first in heatmap(x,y, val))
While (!queue.isEmpty())
{
    elem = queue.pop()
    queue.push(elem.x + 1, elem.y, val-1)
    queue.push(elem.x - 1, elem.y, val-1)
    queue.push(elem.x, elem.y + 1, val-1)
    queue.push(elem.x, elem.y - 1, val-1)
}

This saves on tons of iterations!

Nick
  • 463
  • 4
  • 13
  • Would this ever finish, every pop, 4 more pushes to the queue, so it would never be empty (or am I being dumb!) ? – Ian May 15 '22 at 11:00
1

Look at this project if you are looking for something that looks more like 'tv weather maps':

https://github.com/optimisme/javascript-temperatureMap

John
  • 11
  • 1