Click here to Skip to main content
Click here to Skip to main content

GHeat .NET

By , 21 Jun 2010
 
SampleWebPage.PNG - Click to enlarge image

Introduction

This is a fast and free heat mapping tool.

Background

I had the need for a flexible and scalable heat mapping application. A quick Google search lead me to gheat. While playing with the application, I found it slow and not flexible enough to suit my needs. There was no way to quickly and easily add points and the tile generating was slow. So I decided to attempt a port to C# and here I am now.

Using the Code

For simplicity, I have already written all of the code to get anyone started right out of the box.

UI (In VB)

I have made a session wrapper to store the points for each session. They are accessed through "SessionHandler.PointManager".

Map.aspx contains the code that adds the points to the map.

Dim pm As gheat.PointManager
pm = SessionHandler.PointManager
If pm.PointCount = 0 Then pm.LoadPointsFromFile("points.txt")

To add points dynamically, it is as simple as calling the AddPoint which is in the class PointManager.

pm.AddPoint(New GMap.NET.PointLatLng(30.123866, -92.070673))

If you wish to have to add points via post, I would suggest have a loop that adds each point. Below is an example:

'Post data would look like x,y|x,y
Dim lineSplit() As String
For Each line As String In Request("Address").Split("|")
lineSplit = line.Split(",")
pm.AddPoint(New GMap.NET.PointLatLng(lineSplit(0), lineSplit(1)))
Next

Displaying the Tiles

Tile.aspx contains the code necessary to display the tiles.

Dim image As System.Drawing.Bitmap
Dim stream As New System.IO.MemoryStream()
'Make sure nothing else is being sent
Response.Clear()
'Set the content type
Response.ContentType = "image/png"
'Get the tile image
image = gheat.GHeat.GetTile(SessionHandler.PointManager, _
Request("colorScheme"), CInt(Request("zoom")), CInt(Request("x")), CInt(Request("y")))

'Must save the image to a stream because png's need a stream that can seek back and forth.
image.Save(DirectCast(stream, System.IO.Stream), System.Drawing.Imaging.ImageFormat.Png)
stream.WriteTo(Response.OutputStream)
'Don't do anything else and send it to the requester
Response.Flush()

The Guts (In C#)

Internally the library Gheat.Net is about 99% identical to the python version. It supports the same color schemes, dots, file structure, and points files. The organization is slightly different in an attempt to streamline and make it more efficient. All of the tiles are generated as needed, but all empty tiles are cached and done so per color scheme, per zoom. Other caching was done for the color scheme and dots, so any additions will not be picked up unless the site is restarted. There is no config file but it is necessary to specify the directory where the dots and color schemes are. This MUST be done prior to any other GHeat code execution, so for web apps it must be done on Application_Start.

   Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
        Dim baseDirectory As String = HttpRuntime.AppDomainAppPath

        gheat.Settings.BaseDirectory = baseDirectory + "__\etc\"
    End Sub

How Does It Work? (The Idea)

  • Points are drawn onto tiles, the more points the more intense the color (Darker).
  • Based on the intensity of the color (darkness) in the tile on a scale of 0-255, it is mapped to the color scheme which is 255 pixels high.
  • Pixel by pixel is mapped and changed based on the color scheme
  • The tile is trimmed due to it having to be larger to accommodate points on the edges of a tile.
  • Tile is sent out.
  • Everyone now smiles. ;)

Bonus

While testing, I created a small winform app that goes though a bunch of tiles and stitches them together. This is located in the GheatDeskTop app.

TilesStiched.png
Dim pm As New gheat.PointManager()
Dim g As Graphics
Dim tempImage As System.Drawing.Bitmap
Dim zoom As Integer = 4
Dim startX As Integer = 2
Dim startY As Integer = 5
Dim maxX As Integer = startX + 10
Dim maxY As Integer = startY + 10
Dim canvasImage As New System.Drawing.Bitmap(maxX * 256 - (startX * 256), _
maxY * 256 - (startY * 256), System.Drawing.Imaging.PixelFormat.Format32bppArgb)

gheat.Settings.BaseDirectory = "..\..\..\gheatWeb\__\etc\"

g = Graphics.FromImage(canvasImage)

pm.LoadPointsFromFile("..\..\..\points.txt")

For x As Integer = startX To maxX
    For y As Integer = startY To maxY
        tempImage = gheat.GHeat.GetTile(pm, "classic", zoom, x, y)
        g.DrawImage(tempImage, New System.Drawing.PointF(x * 256 - _
		(startX * 256), y * 256 - (startY * 256)))
    Next
Next
PictureBox1.Image = canvasImage

Thanks

Thanks to the original gheat project, I would never have thought of how to implement it without the source code.

Image multiplication via a blending images project.

Mercator projection thanks to Great Maps. I would have included the source, but it was extremely large so I just compiled a DLL and included it with the project. I did modify the source slightly to allow for weighted points. Maybe I will one day explain how that works.

History

  • 21st June, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Corey Fournier
Software Developer
United States United States
Member
Graduate of University of Louisiana at Lafayette in computer science.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionGridded points and weightmemberom20125 Oct '12 - 0:01 
The points I will be using for the heatmap are grid based i.e. one center point for each (10x10km) grid on the map. Each point will have a different weight/value.
 
My question is: How will the heatmap behave/present itself in this scenario?
QuestionTraffic light color-scheme and categorisationmemberom20124 Oct '12 - 22:58 
Yes, I have a series of questions to day Smile | :)
 
Is there a way to make the heatmap show in traffic light colors (or grades between them) to reflect e.g. this:
 
weight > 50 => red
weight > 25 => yellow
weight > 0 => green
 
OR
 
40 < weight < 60 => green
30 < weight < 40 => yellow
60 < weight < 70 => yellow
0 < weight < 30 => red
70 < weight < 100 => red
QuestionHow to maintain heatmap when zoomingmemberom20124 Oct '12 - 22:41 
The heatmap changes when you zoom e.g. a very high intensity in default zoom level fade out as you zoom in and it becomes dots.
 
For my use, I would like to keep the colored areas with the same intensity as I zoom in. Is there a way to do that?
 
There was a post where you recommended to implement IWeightHandler. I suspect this is what I also should do because my heatmap will be based on values i.e. individual predictions for each point.
 
Do you think implementing IWeightHandler will solve the zoom issue above?
If yes, can you give a hint on how to implement IWeightHandler in the code?
QuestionHeatmap not showing (decimal point problem)memberom20124 Oct '12 - 1:28 
I was a bit puzzled when I first saw the demo at work on my own pc. The heatmap was not showing.
 
Just to let other users know, the problem was in LoadPointsFromFile which expects the decimal point to be a dot(.). My country is Denmark and we use comma (,) as the decimal point. The quick fix was to replace the commas in points.txt with semicolon and then replace the points with commas. Finally I changed
item = line.Split(',');
to
item = line.Split(';');
in LoadPointsFromFile. Then the heatmap displayed nicely. I guess the problem can be solved in a more general way but for now this will do.
 
Now I am looking forward to use GHeat in my own application and hoping to get a nice and useful result Smile | :) Thanks for your good work and for making it available to the rest of us!
AnswerRe: Heatmap not showing (decimal point problem)memberCorey Fournier4 Oct '12 - 9:59 
Thanks for posting the information, I have no experience with standards outside the US so it wasn't natural for me to build this in or was it part of the original Gheat project. We all appreciate you sharing this with the community.
QuestionWinRT Versionmemberrollie_pt28 Jul '12 - 8:10 
Hi There!
Are you working on porting this code to WinRT?
 
I think you did an amazing work and now I am trying to port it to WinRT, but getting some issues like SettingsBase and portability between .NET and RT.
 
Great Work once again!
AnswerRe: WinRT VersionmemberCorey Fournier1 Aug '12 - 3:23 
No plan to port it to anything else. The project that prompted me to ported it to .net is not even in use anymore.
QuestionGreat job!memberMember 839626520 May '12 - 0:38 
But it seems it only focus on the US. I have added point in Europe Switzerland, but unless I increase the size of the windows, they remain unvisible.
 
How do you set the focus (Map center) to be somewhere else besides the US?
AnswerRe: Great job!memberAlan Novitskiy19 Jun '12 - 12:15 
It's on line 17 of Map.aspx in the initialize() method.
You may also want to tweak the initial zoom on line 13
 
Cheers,
~Alan
QuestionHow to clear overlay between data changesmemberMember 35401722 Apr '12 - 14:02 
I am using the GHeat with an ASP.net handler that basically passes the map.aspx page an xml file that I parse and for each element I am using the AddPoint method. The problem I am having is that the overlay is not changing when the data changes, the heatmap is not altering as per the new set of data.
 
How can I get the heatmap to refresh and recreated each time the data changes.
 
Thanks in advance
Sean
AnswerRe: How to clear overlay between data changesmemberCorey Fournier10 Apr '12 - 11:31 
Are you maintaining the session?
AnswerRe: How to clear overlay between data changesmemberCorey Fournier10 Apr '12 - 11:33 
Adding points it will show up. Make a call to the ClearPointList when you want to clear them all and load all new points. Thats in the Point Manager.
GeneralRe: How to clear overlay between data changesmemberMember 354017210 Apr '12 - 12:14 
I am maintaining the session, I have done a call to clearpointlist but it does not seem to be clearing the points.
 
I have checked my data and it is sending a new set of data with location for the points, but the heatmap is still just showing the old points.
GeneralRe: How to clear overlay between data changesmemberSeanJCo10 Apr '12 - 13:08 
I have cleared out all session data, and even regenerated a new Session ID. I can see that in Trace my Session is changed and when I remove the PointManager from the Session, it shows as removed. However when I run the page again I still get the heatmap for the old data. I have also tried this with the example Gheatweb loading from the points file and when I remove points for the file the heatmap doesnt change.
GeneralRe: How to clear overlay between data changesmemberCorey Fournier11 Apr '12 - 2:13 
Then I have no answer for you. I would have to trouble shoot it with your code changes and I don't have the time for that. My suggestion would be to put break points were you add the points and where the tiles are generated and determine why the new points are not showing up on the tiles.
GeneralRe: How to clear overlay between data changesmemberSeanJCo11 Apr '12 - 2:50 
I guess from your answer you are having a bad day, not very polite now was it Sigh | :sigh: . I will see if I can figure this out and if I do find out the answer as to why the asp.net web version is not working I will let you know.
GeneralRe: How to clear overlay between data changesmemberCorey Fournier11 Apr '12 - 3:06 
The software is free, I make no money what so ever off of it. I could of not answered any questions at all. How am I not being polite?
 
I would love for you to contribute back and let me what the problem is so we can share it with everyone.
GeneralRe: How to clear overlay between data changesmemberSeanJCo11 Apr '12 - 5:15 
I guess we have a different of opinion as to what is polite and what isn't I just think saying "Then I have no answer for you. I would have to trouble shoot it with your code changes and I don't have the time for that" comes across a bit unpolite. But never mind.
 
I will be happy to share the code after I have found the cause of the problem, the tiles are not being stored in any cache, nor are they being stored in the session, yet each time I change the data it does not change the heatmap. The desktop version works fine, so it my guess that it may be a application level problem, either on the web server at my end or with the Google Map cache. But I will be happy to share my update once I get to the bottom of it.
 
We all do appreciate the effort you went to in programming and porting this code over, its kinda the same reason why I worked on V2 of Google maps for nothing, for the greater good. I will let you know once I figure it out, and in the meantime if you have any pearls of wisdom on the problem, that would be great.
GeneralRe: How to clear overlay between data changesmemberCorey Fournier11 Apr '12 - 10:27 
Just be aware the points are stored in the session. At least that's what i remember.
GeneralRe: How to clear overlay between data changesmemberSeanJCo11 Apr '12 - 11:24 
Thanks Corey for the tip, it does look that way. Once I figure it out I will be more than happy to post the updated code.
 
TTFN
Sean
GeneralRe: How to clear overlay between data changesmemberSeanJCo22 Apr '12 - 6:07 
Corey, bit of an update I have figured out the problem. The GHeat web DLL is not clearing out the session due to the context it is being run in, especially in IIS 7. I have made some code changes and made it so the main project no longer requires the GHeat Web DLL and that seems to have fixed the issue.
 
I have also made some minor changes to how the PointList is being clear to improve the threading, and I have added a function to allow for points to be loaded from a URL.
 
Once I tidy up my code I will be more than happy to share it. Where do I share the code?
 
Cheers
Sean
GeneralRe: How to clear overlay between data changesmemberCorey Fournier20 Jun '12 - 2:00 
I think you would have to send me the code changes and i merge them with the rest of the project.
GeneralRe: How to clear overlay between data changesmemberSeanJCo20 Jun '12 - 10:57 
Corey thats cool, what is the best email to send the code over too.
 
Thanks
Sean
QuestionBackground transparencymemberManuel Pazos22 Feb '12 - 5:37 
Hello,
 
First of all thank you for your great job. I use gheat a lot but found out that when there is no heat map over the googlemap the background color of the generated tile leave the map less legible. I know I can modify the opacity of the heatmap but this change the transparency of the colors too and it is difficult to appreciate the heatmap. Is there any way to make the tiles with no background at all to leave just the heatmap over the googlemap?
 
BTW. An example of IweightHandler to implement weight on a single point with the AddPoint function would be great.
 
Thank you very much,
 
Manuel.
AnswerRe: Background transparencymemberCorey Fournier22 Feb '12 - 8:52 
There is an example of IWeightHandler in one of the other questions.
 
The way GHeat is designed (Original from Python) the overlay color goes away when you zoom down far enough. You could modify the Opacity class to remove the over lay once you zoom to level X. You could also modify the Tile class and remove the over lay all together. You may also check out the parameter changeOpacityWithZoom in the function Generate. This boolean input can turn off the opacity all together, you will also need to set the default Opacity which is also a parameter. Last option is the change the color scheme on the dark side.
//Get the first pixel of the color scheme, on the dark side
colorSchemePixelColor = colorScheme.GetPixel(0, colorScheme.Height - 1);
The back ground color is set by the 255th pixel on the color scheme. You could also just remove the code.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130513.1 | Last Updated 21 Jun 2010
Article Copyright 2010 by Corey Fournier
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid