Banner

Sunday, 20 April 2008

Proportional symbol mapping with OpenLayers

This blog post shows how the new release of OpenLayers (2.6) and GeoJSON can be utilised to make proportional symbol maps. The performance is very good compared to choropleth world maps.

This map shows the population in each country of the world in 2005. The population numbers (medium variant) were downloaded from UNdata. For the purpose of symbolisation, these are conceived as conceptual point data. The symbols are placed in the centre of each country, even though the data represents the country as a whole. The population data are provided as a GeoJSON FeatureCollection containing point coordinates (longitude/latitude) and parameters (name and population of country).

Proportional symbols can be geometric or pictographic. I’m using circles on the map above, which have been the most frequently used geometric symbol. Scalable pictographic symbols are harder to create in a web interface. I will try different methods at a later stage.

The size of the circle areas are mathematically scaled in direct proportion of the population data. This is the JavaScript formula:

Math.sqrt(value / maxValue) * maxSize

The maximum symbol size is chosen to minimise the symbol overlap. People tend to underestimate the size of larger symbols, and an alternative to mathematical scaling is perceptual scaling. The underestimation is here taken into account when constructing the formula.

The new 2.6 release of OpenLayers has some powerful styling capabilities. When the user zooms the map, the circles are automatically scaled to keep their relative size. This map shows the effect:

Thanks to the OpenLayers developers and contributors for making a great product!

Reference:
Thematic Cartography and Geographic Visualization, Second Edition 2005, Terry A. Slocum et al., Pearson Education, Inc

1 comment:

openid said...

Thanks so much for posting this! I've been looking for more info about proportional markers using OpenLayers for a while and was so happy to find your post.

I haven't tried out the code yet but I'm looking forward to it.