Skip to main content

Reference Library

Go Search
Reference Library
  
Reference Library > Wiki Pages > Hot Spot Rendering  

Hot Spot Rendering

 
Overview
 
Hot Spot rendering in MDNS uses a Gaussian density mapping function and can easily be overlayed on your custom maps - whether tiled or not. The following example is on a tiled Virtual Earth map.
 
Hot Spot Example
 
To support hot-spot within the new VE TEmplate II - use must implement IPreDrawHandler. For example:
 
using System;

using System.Drawing;

using ISC.MapDotNetServer.Common;

using ISC.MapDotNetServer.Controls;

using ISC.MapDotNetServer.Controls.VirtualEarth;

using ISC.MapDotNetServer.VETemplate.Handler;

 

public class HotSpotPreDrawHandler : IPreDrawHandler

{

    /// <summary>

    /// Takes a MapControlBridge just prior to drawing a tile.

    /// Here you can make modifications to the MapRequest object for custom tile drawing.

    /// This is useful in creating overlays on the tile itself (e.g. hot-spot)

    /// </summary>

    /// <param name="mcb">MapControlBridge.</param>

    /// <param name="rp">Tile request processor.</param>

    public bool DrawSetup(

        MapControlBridge mcb,

        RequestProcessor rp)

    {

        // use a bleed so tiles align better and feature near the edge do not get clipped

        // 1.0625 will add an 8-pixel bleed around the tile

        mcb.MapRequest.BleedRatio = 1.0625;

 

        // add hotspot layer - "traffic crashes" is the name of the layer we want to show a denisty map for

        Layer layer = mcb.MapRequest.Map.GetLayerByID("Traffic Crashes");

        if (layer != null)

        {

            AddHotSpot(mcb, layer);

        }

 

        // continue processing tile in RequestProcessor

        return true;

    }

 

 

    /// <summary>

    /// Add a crash hot-spot layer

    /// </summary>

    /// <param name="mcb">MapControlBridge.</param>

    /// <param name="layer">The layer to density map.</param>

    public void AddHotSpot(MapControlBridge mcb, Layer layer)

    {

        // get map request from MapControlBridge

        MapRequest request = mcb.MapRequest;

 

        // computational envelope must be in the resultant map units (for VE this is mercator)

        // since we are tiling, expand envelope to capture adjacent tile data so tile mozaic is correct

        // otherwise you will not pick up thermal points from nearby tiles and the mozaic will show tile boundaries

        // here we expand the hot spot computational envelope by a 33% margin all the way around

        // if we need look further into the adjacent tiles, reduce the denominator (3.0)

        Envelope cEnv = request.RequestEnvelope.Clone();

        cEnv.Expand(cEnv.MagX / 3.0);

 

        // setup query envelope - the map is in mercator but crash data is in WGS84 which we are querying

        Envelope qEnv = Tiles.ConvertMercEnvelopeToDegrees(cEnv);

 

        // this is an instance of the hot spot rendering engine

        HotSpotHelper helper = new HotSpotHelper();

 

        // setup an appropriate looking color matrix

        // you can tweak this to get different color schemes - note the first integer in each set of 4 is the alpha

        // because we are using Virtual Earth tile opacity, we want an opaque except for the very edge

        helper.ARGBColorMatrix = new int[][] { 

                                     new int[] {0,0,0,0},

                                     new int[] {128,0,0,255},

                                     new int[] {255,0,0,224},

                                     new int[] {255,0,0,192},

                                     new int[] {255,32,0,160},

                                     new int[] {255,64,0,128},

                                     new int[] {255,128,0,64},

                                     new int[] {255,160,0,32},

                                     new int[] {255,192,0,0},

                                     new int[] {255,224,0,0},

                                     new int[] {255,255,0,0}

                               };

 

        // this lets the hot spot helper know what projection we are projecting the source data to to perform

        // computations on

        // 50000 happens to be the SRID of the VE mercator projection as defined in the spatial database used for this example. 

        // Note that you will need to add this defiition as it is not standard

        

        // MDNS versions prior to 6.5

        /*

        helper.ProjectionCoordSys = new CoordSys(); 

        helper.ProjectionCoordSys.ProjectionID = "50000";

        */

 

        // As of 6.5

        ProjCoordSys cs = new ProjCoordSys();

        cs.ID = 50000;

        helper.ProjectionCoordSys = cs;

 

        // compute a rough max magnitude based on current tile mapscale

        // we must use absolute max-value instead of auto-computed since we are tiling

        // since each tile may have a different density, we can not auto-compute the max (the tile mozaic will not line up)

        // note in this case max value changes with changes in VE zoom level and the computation is not linear

        double maxValue = Math.Pow(cEnv.MagX, 1.125) / 100.0;

 

        // render hotspot map

        Bitmap bmp = helper.GenerateThermalPNG(mcb,

            layer,             // layer to analyze

            qEnv,              // query envelope in datasource map units

            cEnv,              // computational envelope in VE Mercator

            null,              // optional where clause

            null,              // you can sum an attribute column, null means count features only

            HotSpotHelper.NegativeSumBehavior.Discard,  // how to handle negative sum (previous field must be used)

            64,                // number of grid cells across (cells deep are computed from envelope)

            5,                 // filter size in grid cells

            2,                 // filter radius in grid cells

            0,                 // minimum sample value (you can increase this to set a rendering threshold)

            maxValue,          // maximum value per grid cell (Double.NaN will use auto-compute)

            32);               // 0 - max color depth or a positive integrer limiting the max number of colors displayed

 

        // if the hot spot renderer returned a bitmap

        if (bmp != null)

        {

            // add it as a map request overlay

            request.Overlay = new OverlayPNG();

            request.Overlay.OverlayEnvelope = cEnv;

            request.Overlay.LoadPNG32(bmp);

        }

        else

        {

            // clear the overlay in the map request

            request.Overlay = null;

        }

    }

}

 
Customization to support your datasets in Virtual Earth:
 
Add implementation of IPreDrawHandler to your VE Template II configuration
Make sure to add the class name (in this example HotSpotPreDrawHandler) to the preDrawClassFactor field in the record in tblConfig in your tile database for the map (map ID) you are rendering.

Map Configuration File
Because you are overlaying color gradient regions on to your VE map, you must use a JPEG OUTPUTFORMAT in your map file. PNG is supported by the MapDotNet Server product - but unfortunately, it is not well supported by all browsers. Using JPEG will require you to set the VETileOpacity metadata tag in your map file file. A value of 0.4 is a good start.

Make sure you spatial database has a definition for the VE Mercator Projection
The example here uses PostGIS custom projection (id = 5000) with a Proj4 string of: +proj=merc +lat_0=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +ellps=sphere +a=6378137 +b=6378137 +units=m +nadgrids=@null +no_defs

Understand Your Data
Serveral factors in the above code will need adjusting based on your data:
  • ProjectionCoordSys on the HotSpotHelper - must be set to your custom VE Mercator projection ID or string
  • The computation of the max cell value based on the density of your data
  • The query envelope must be in the units your data resides in

Issues with 3D Obliques
Keep in mind the VE managed 3D control will pull tiles from adjacent zoom levels when viewing an oblique and therefore hot spot rendering may not line up in the tile mozaic in 3D. You will probably only want to use hot spot rendering in 2D or you will need to scale the hot spot grid size and max grid values with zoom level changes.

 

Last modified at 11/11/2008 6:10 PM  by WEB\mark