Coloring a map

In this recipe we will show how to fill different regions of a map with different colors. We will use the PolygonParser class from the previous recipe in order to get the geographical boundaries of the Canadian provinces and we are going to combine it with the crime severity index data from Statistics Canada available at http://www.statcan.gc.ca/pub/85-004-x/2009001/t009-eng.htm. Provinces with a darker gray (more red color in the code), will have higher crime severity index while provinces that are of a lighter gray color (more yellow in the code) will have lower crime severity index. This is illustrated in the following screenshot:

Coloring a map

Getting ready

This recipe greatly relies on the Parsing data to use as region fill recipe; we suggest you read it before continuing.

How to do it...

The following steps show you how to color a map:

  1. Create the CrimeData class that has a name, a crime severity index, and a boundaries property
  2. Combine the regional data from the Natural Earth (https://www.google.com/fusiontables/DataSource?dsrcid=424517) and the crime data from Statistics Canada (http://www.statcan.gc.ca/pub/85-004-x/2009001/t009-eng.htm) to generate our data. One entry will look like the following listing:
    data.push(new CrimeData("Prince Edward Island", 62.8, '{"type":"Polygon","coordinates":[[[-63.811,46.469],[-63.784,46.455],[-63.737,46.48],[-63.681,46.562],[-63.534,46.541],[-63.456,46.504],[-63.413,46.512],[-63.369,46.508],[-63.286,46.46],[-63.129,46.422],[-62.964,46.428],[-62.712,46.45],[-62.682,46.459],[-62.423,46.478],[-62.164,46.487],[-62.074,46.466],[-62.041,46.446],[-62.024,46.422],[-62.172,46.355],[-62.32,46.278],[-62.526,46.203],[-62.552,46.166],[-62.539,46.098],[-62.543,46.029],[-62.503,46.023]...));
  3. Create the map that we will show the data on:
    _map = new Map();
    _map.size = new Size(1000, 500);
    
    _map.center = new Location(-95.11, 52.57, "EPSG:4326");
    _map.resolution = new Resolution(10000, "EPSG:900913");
               
    var bing:Bing = new Bing("Ar3-LKk-acyISMevsF2bqH70h21mzr_FN9AhHfi7pS26F5hMH1DmpI7PBK1VCLBk","Aerial");
    _map.addLayer(bing);
  4. Loop over the data and find the minimum and maximum value of the crime severity index.
  5. With those values in hand, compute a scaleRatio value that will be used to determine the color of a region.
  6. Loop over the data once again to create all the regions and add their color:
    for (i = 0; i < data.length; i++) {
      polygonVector = PolygonParser.parseData(data[i].boundaries);
      for (j = 0; j < polygonVector.length; j++) {
        polygonFeature = new PolygonFeature(polygonVector[j]);
        rule = new Rule();
    
        green =  240 - Math.round((data[i].crimeSeverityIndex - minValue) * scalingFactor);
        color = (red << 16) | (green << 8) | blue;
        fill = new SolidFill(color, .8);
        stroke = new Stroke(0xffffff, 2);
        symbolizer = new PolygonSymbolizer(fill, stroke);
        rule.symbolizers.push(symbolizer);
        style = new Style();
        style.rules.push(rule);
        polygonFeature.style = style;
        polygonFeature.addEventListener(MouseEvent.ROLL_OVER, _onFeatureOver);
        _polygonVector.push(polygonFeature);
        _crimeDataVector.push(data[i]);
        regionLayer.addFeature(polygonFeature);
      }
    }
  7. Create the class HoveringLabel.as, so that when a user rolls over a region we can display information about it.
  8. Add TitleSprite, to indicate what our map is about.
  9. Add a listener over the regions so that we can move the hovering label to the right place when the user rolls over a province. Here is the listener function:
    private function _onFeatureOver(event:MouseEvent):void {
      _hoveringLabel.x = mouseX - 75;
      _hoveringLabel.y = mouseY;
      _hoveringLabel.changeText(
    _crimeDataVector[_polygonVector.indexOf(event.target)].name, _crimeDataVector[_polygonVector.indexOf(event.target)].crimeSeverityIndex);
    }

How it works...

A big part of the work was done in the previous recipe and we will re-use the PolygonParser class to get the boundaries of every province in Canada. The parsing process returns a Polygon instance, but in order to use it, we need to encapsulate it inside a PolygonFeature class so that we can add it to the VectorLayer class.

Let's take this moment to look in how many classes our data is encapsulated in. First we put it in a LinearRing class, then a Polygon class, then a PolygonFeature class, then a VectorLayer class, and finally into a Map class. It's quite a long process, but it is not that difficult once you know it.

Now we need to calculate our scalingFactor value. To do so we need to find our minimum and maximum crime severity index . Here is how we do it:

var scalingFactor:Number = 240 / (maxValue – minValue);

The 240 value is the range over which our color will change. With the scaling factor in hand, we can loop over the data and generate the visual for each province.

What we are going to do to get the color for each region is this: we start with the color yellow, which is no blue, maximum red (255 over 255), and a lot of green (240 over 255). Depending on whether the crime severity index is high or not, we are going to remove a lot of or a little green from our starting yellow, making our color more red (since there is no blue, removing green only leaves red). Using the scalingFactor variable, we can calculate how much green we remove.

green = 240 - Math.round((data[i].crimeSeverityIndex - minValue) * scalingFactor);

Now that we computed our color, we need to assign it to the PolygonFeature class. This process is a bit tedious too; simple but tedious. Most of the code in step 6 is about assigning the color to the PolygonFeature class. We need to create instances of SolidFill, Stroke, PolygonSymbolizer, Rule, and Style just to assign a color to a region, but once it is done it looks really great.

There's more...

Now that we showed how to display data over regions you can modify our code to suit your needs.

Using different countries

The data from Natural Earth comprises the boundaries for all the regions of the Earth. Be it the regions of France or the prefectures of Japan, you can find the boundaries in the Natural Earth spreadsheets, available at https://www.google.com/fusiontables/DataSource?dsrcid=394713. Now all you need is data to be represented on a map.

Using another color range

For this recipe we used a color range of yellow going to red but you could use any color range just by using the technique we used but by modifying another color instead of the green.

What you could also do, is create the same region twice, the bottom one being white and the second one being a color of your choice. By modifying the alpha of the colored region, let's say from 0.5 to 1, you would get a range over that color (from light to dark).

See also

  • The Overlaying a heat map recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.219.217