Heat maps, also known as density maps, are a type of overlay on a map used to represent data using different colors. Heat maps are often used to show the data hot spots on a map. The data used in these overlays usually takes one of two forms:
- Color coded polygons or polylines – In this form, the polygons and polylines are based on some metric related to those shapes. Creating this type of heat map is fairly easy as you simply need to assign a color to the shape when adding it to the map.
- Point based data – This form uses point-based data where the colors of the heat map are based on the density of the data points on the map. Creating these types of heat maps is a bit more complex.
In this blog post I describe how I came up with a solution for creating heat maps in native Windows Store apps and document the reusable library that I created. Full source code can be downloaded from the MSDN Code Samples here.
In Windows Store apps our main option for doing any kind of graphics generation is to use DirectX in C++ or SharpDX from C# or VB. If you have little to no experience with either of these libraries, it can a pretty painful learning curve.
There is one issue with this: The WebView control does not support transparent backgrounds. We can use an opacity, but then we end up with a whitish shadow in the empty heat map area. To solve this, we can capture the image information from the HTML5 canvas and return it as a data string to our native code. We can then add an Image control to our custom control and set the source of the Image to this data string. This approach worked well with data sets of 5,000 or less points, but often blocked the UI thread for a few seconds.
Not being content with this, I started to make some tweaks. Creating density heat maps is a two-step process:
- Draw each data point on the map as a semi-transparent gray scale radial gradient. This creates an alpha mask of the heat map.
- Map a color gradient to each pixel based on the alpha value of each pixel.
To optimize the first part, rather than drawing the radial gradients, I created an image of the required gradient in an image editor. I then scaled the image and drew it to the canvas. This worked faster than drawing the radial gradients. A second optimization was around the pixel color mapping step. I retrieved the pixels from the Canvas using the getImageData function. This creates an array that consists of 4 cells for each pixel on the canvas. In a heat map that is 1600 x 900 pixels in size there are 1,440,000 pixels. This means that during the colorization step, the code has to loop through an array that has 5,760,000 cells. It was this process that was mainly locking up the UI thread.
The HeatMapLayer class provides a number of properties which can be used to customize how the heat map is rendered. Here is a list of the different properties available:
|HeatGradient||GradientStopCollection||A color gradient used to colorize the heat map.|
|Intensity||double||Intensity of the heat map. A value between 0 and 1.|
|Locations||LocationCollection||Collection of locations to plot on the heat map.|
|ParentMap||Map||A reference to the parent Bing Maps control.|
|Radius||double||Radius of data point in meters.|
|EnableHardEdge||bool||Gives all values the same opacity to create a hard edge on each data point. When set to false (default) the data points will use a fading opacity towards the edges.|
The heat map will not render until the ParentMap property is assigned. All the properties with the exception of this one support data binding. If you decided to add a heat map to your map using XAML you will need to set the ParentMap property in your code behind. Here is an example of how to add a heat map to your map using XAML.
You can then set the ParentMap property using the following code. You also can data bind the Location property, but for simplicity in this example I have just set it from code.
Alternatively, you can create the heat map completely from code and add it as a child of the map. The following is an example of how to add a HeatMapLayer to Bing Maps using code.
The full source code for this library and a sample app that demonstrates how to use the different features of this library can be found here. Here is a screenshot of the test app that is included in this library.
If you are looking for some other great resources on Bing Maps for Windows Store apps, look through this blog and check out all the Bing Maps MSDN code samples.