Creating thematic boundaries

A very useful application of boundary data is to use them to create thematic maps, based upon some external data for example income per ward. Although, this example uses some simple fictictious values, the principles can be applied to real data. The data needs to be held in .csv format and uses a primary key (ADMIN_UNIT_ID) to link to the boundaries.
First create a .csv file as follows. Note you will need to set the path of this file in the code:
| ADMIN_UNIT_ID | MY_VALUE |
|---|---|
| 41423 | 2 |
| 41425 | 2 |
| 41428 | 3 |
| 41422 | 3 |
| 41431 | 4 |
| 41429 | 4 |
| 41421 | 5 |
| 41427 | 5 |
| 41424 | 5 |
| 41426 | 7 |
| 41430 | 7 |
The styling is acomplished as in the this example or using a Styled Layer Descriptor(SLD) that is held externaly to the HTML document.
Second, we need to tell the browser to pull in the OS OpenSpace JavaScript API:
<script type= "text/javascript"src="http://openspace.ordnancesurvey.co.uk/osmapapi/openspace.js?key=insert_your_api_key_here"></script>
Next, in the body, we need to tell JavaScript to run our initialisation function on loading the page:
<body onload="init();">
Next we need to add a map div element; this is the HTML element that will contain the map:
<div id="map" style="width: 502px; height: 304px; border: 1px solid black;"></div>
Then we add the map and the European boundaries:
<script type="text/javascript">var osMap, store, boundaryLayer, ruleLow, ruleMedium, ruleHigh, context;var dataTable = {};var primaryKey = "ADMIN_UNIT_ID";var valueKey = "MY_VALUE";function init(){osMap = new OpenSpace.Map('map');readCSV();boundaryLayer = createBoundaryLayer();osMap.addLayer(boundaryLayer);osMap.setCenter(new OpenSpace.MapPoint(390000, 550000), 0);}function readCSV(){store = new dojox.data.CsvStore({url: "MY_VALUES.csv", label: primaryKey});var request = store.fetch({onComplete: gotCSVData});}function gotCSVData(items, request){for (var i = 0; i < items.length; i++){var item = items[i];var row = {};var attrs = store.getAttributes(item);for (var key in attrs){var value = store.getValue(item, attrs[key]);if (OpenLayers.String.isNumeric(value))value = parseFloat(value);row[attrs[key]] = value;}dataTable[store.getValue(item, primaryKey)] = row;}}function createBoundaryLayer(){var context = function(feature){var key = feature.attributes[primaryKey];var value = dataTable[key];return value;};var style = new OpenLayers.Style();var ruleLow = new OpenLayers.Rule({context: context,filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LESS_THAN,property: "MY_VALUE",value: 5}),symbolizer: {fillColor: "red", fillOpacity: 0.4, strokeColor: "black"}});var ruleMedium = new OpenLayers.Rule({context: context,filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO,property: "MY_VALUE",value: 5}),symbolizer: {fillColor: "yellow", fillOpacity: 0.4, strokeColor: "black"}});var ruleHigh = new OpenLayers.Rule({context: context,filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,property: "MY_VALUE",value: 6}),symbolizer: {fillColor: "green", fillOpacity: 0.4, strokeColor: "black"}});style.addRules([ruleLow, ruleMedium, ruleHigh]);var styleMap = new OpenLayers.StyleMap(style);styleMap.addUniqueValueRules("default", valueKey, context);boundaryLayer = new OpenSpace.Layer.Boundary("Boundaries", {strategies: [new OpenSpace.Strategy.BBOX()],area_code: ["EUR"],styleMap: styleMap });return boundaryLayer;}</script>
Let's break this up:
We start a script tag to contain our code:
<script type="text/javascript">
Then we declare our global variables:
var osMap, store, boundaryLayer, ruleLow, ruleMedium, ruleHigh, context;var dataTable = {};var primaryKey = "ADMIN_UNIT_ID";var valueKey = "MY_VALUE";
Now we define our init function:
function init(){
Then we create a new OS OpenSpace map object and pass it our 'map' element id. This is the HTML div that will hold the map:
osMap = new OpenSpace.Map('map');
Then we call the function that reads our csv file into a data table:
readCSV();
Call the function that creates a boundary layer based on values stored in the data table:
boundaryLayer = createBoundaryLayer();
And add it to the map:
osMap.addLayer(boundaryLayer);osMap.setCenter(new OpenSpace.MapPoint(390000, 550000), 0);}
This function reads the .csv data
function readCSV(){store = new dojox.data.CsvStore({url: "MY_VALUES.csv", label: primaryKey});var request = store.fetch({onComplete: gotCSVData});}
This function reads the data into a data table object i.e. temporary extra attributes for boundary features, whose id matches the selected id in the .csv file:
function gotCSVData(items, request){for (var i = 0; i < items.length; i++){var item = items[i];var row = {};var attrs = store.getAttributes(item);for (var key in attrs){var value = store.getValue(item, attrs[key]);if (OpenLayers.String.isNumeric(value))value = parseFloat(value);row[attrs[key]] = value;}dataTable[store.getValue(item, primaryKey)] = row;}}
This is the function that is used to create the boundary layer:
function createBoundaryLayer(){
Each boundary feature is sent to this variable and its value returned to the rule:
var context = function(feature){var key = feature.attributes[primaryKey];var value = dataTable[key];return value;};
Define a new style:
var style = new OpenLayers.Style();
Add rules that define how we want to style our .csv data:
var ruleLow = new OpenLayers.Rule({context: context,filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.LESS_THAN,property: "MY_VALUE",value: 5}),symbolizer: {fillColor: "red", fillOpacity: 0.4, strokeColor: "black"}});var ruleMedium = new OpenLayers.Rule({context: context,filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.EQUAL_TO,property: "MY_VALUE",value: 5}),symbolizer: {fillColor: "yellow", fillOpacity: 0.4, strokeColor: "black"}});var ruleHigh = new OpenLayers.Rule({context: context,filter: new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,property: "MY_VALUE",value: 6}),symbolizer: {fillColor: "green", fillOpacity: 0.4, strokeColor: "black"}});
Add these rules to the style:
style.addRules([ruleLow, ruleMedium, ruleHigh]);
And then the style map:
var styleMap = new OpenLayers.StyleMap(style);
Add value rules to our style map:
styleMap.addUniqueValueRules("default", valueKey, context);
Create the boundary layer and return it to the init function:
boundaryLayer = new OpenSpace.Layer.Boundary("Boundaries", {strategies: [new OpenSpace.Strategy.BBOX()],area_code: ["EUR"],styleMap: styleMap });return boundaryLayer;}
Finally close the script:
</script>
The full code can be found below:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>OpenSpace Tutorial - Example 14</title>
<script type="text/javascript" src="http://openspace.ordnancesurvey.co.uk/osmapapi/openspace.js?key= insert_your_api_key_here "></script>
<script type="text/javascript">
var osMap, store, boundaryLayer, ruleLow, ruleMedium, ruleHigh, context;
var dataTable = {};
var primaryKey = "ADMIN_UNIT_ID";
var valueKey = "MY_VALUE";
function init()
{
osMap = new OpenSpace.Map('map');
readCSV();
boundaryLayer = createBoundaryLayer();
osMap.addLayer(boundaryLayer);
osMap.setCenter(new OpenSpace.MapPoint(390000, 550000), 0);
}
function readCSV()
{
store = new dojox.data.CsvStore({url: "MY_VALUES.csv", label: primaryKey});
var request = store.fetch({onComplete: gotCSVData});
}
function gotCSVData(items, request)
{
for (var i = 0; i < items.length; i++)
{
var item = items[i];
var row = {};
var attrs = store.getAttributes(item);
for (var key in attrs)
{
var value = store.getValue(item, attrs[key]);
if (OpenLayers.String.isNumeric(value))
value = parseFloat(value);
row[attrs[key]] = value;
}
dataTable[store.getValue(item, primaryKey)] = row;
}
}
function createBoundaryLayer()
{
var context = function(feature)
{
var key = feature.attributes[primaryKey];
var value = dataTable[key];
return value;
};
var style = new OpenLayers.Style();
//add rules that take return from feature fed into context
var ruleLow = new OpenLayers.Rule(
{
context: context,
filter: new OpenLayers.Filter.Comparison(
{
type: OpenLayers.Filter.Comparison.LESS_THAN,
property: "MY_VALUE",
value: 5
}),
symbolizer: {fillColor: "red", fillOpacity: 0.4, strokeColor: "black"}
});
var ruleMedium = new OpenLayers.Rule(
{
context: context,
filter: new OpenLayers.Filter.Comparison(
{
type: OpenLayers.Filter.Comparison.EQUAL_TO,
property: "MY_VALUE",
value: 5
}),
symbolizer: {fillColor: "yellow", fillOpacity: 0.4, strokeColor: "black"}
});
var ruleHigh = new OpenLayers.Rule(
{
context: context,
filter: new OpenLayers.Filter.Comparison(
{
type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
property: "MY_VALUE",
value: 6
}),
symbolizer: {fillColor: "green", fillOpacity: 0.4, strokeColor: "black"}
});
style.addRules([ruleLow, ruleMedium, ruleHigh]);
var styleMap = new OpenLayers.StyleMap(style);
styleMap.addUniqueValueRules("default", valueKey, context);
boundaryLayer = new OpenSpace.Layer.Boundary("Boundaries", {
strategies: [new OpenSpace.Strategy.BBOX()],
area_code: ["EUR"],
styleMap: styleMap });
return boundaryLayer;
}
</script>
</head>
<body onload="init()">
<H1><font size="3" face="Verdana">
</font></H1>
<div id="map" style="width: 502px; height: 304px; border: 1px solid black;">
</div>
</body>
</html>
![OS OpenSpace [logo]](/images/openspace-logo.jpg)