Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I'm creating a bubble map using Leaflet JS. Everything is working smoothly (LeafletJS is awesome!) but now I'd like to try flannery compensation on the bubbles.

I can't find the math anywhere though. Best explainations I've been able to find say you have to multiply radius by either 1.4 or 1.8, which just seems a bit useless.

What is the math used for Flannery compensation?

share|improve this question
add comment

2 Answers 2

up vote 2 down vote accepted
Flannery Appearance Compensation case:
Pj = 1.0083 * (Valj/ValMin)^0.5716 * Pmin

Where:
Pj = point size of the j'th feature
Valj = value of the j'th feature
ValMin = minimum value
Pmin = minimum point size
^0.5 is to the power of 0.5 (square root)
^0.5716 is to the power of 0.5716 

More to be found at http://forums.esri.com/Thread.asp?c=93&f=1730&t=213906.

share|improve this answer
    
Pmin seems to act more like a maximum point size, but it works. Thanks! –  Martijn May 25 at 14:48
add comment

I wrote up a little JS function based on @zimmi's formula that takes in a geojson, the name of the attribute, and the value for the minimum point size. Based on that it puts circles on the map.

var flanneryCompensation = function(geojsonName, attributeName, pMin) {
    // Creates a Flannery Appearence Compensation
    var geojsonLayer = L.geoJson(geojsonName);

    var valMin = Number.POSITIVE_INFINITY;;
    geojsonLayer.eachLayer(function (layer) {
        // Get minimum value of all features
        var value = layer.feature.properties[attributeName];
        if (value < valMin) valMin = value;
    });

    geojsonLayer.eachLayer(function (layer) {
        var value = layer.feature.properties[attributeName];

        // Flannery Appearance Compensation case:
        pValue = 1.0083 * Math.pow(value/valMin, 0.5716) * pMin

        var circleLayer = L.circle(layer._latlng, pValue);
        circleLayer.bindPopup(String(value));
        circleLayer.addTo(map);
    });
};

A JSFiddle with some sample data: http://jsfiddle.net/mwvdlee/jH2EY/1/

share|improve this answer
    
The "^" is an XOR in javascript, so results were not as expected. Changing the actual Flannery line to pValue = 1.0083 * Math.pow(value/valMin, 0.5716) * pMin makes it work. jsfiddle.net/mwvdlee/jH2EY/1 –  Martijn May 25 at 14:42
    
@Martijn Cool, thanks for catching that. I updated my answer. –  ustroetz May 25 at 17:28
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.