Thematic map contd.

Posted by jsharma on Oracle Blogs See other posts from Oracle Blogs or by jsharma
Published on Mon, 1 Jul 2013 14:45:39 +0000 Indexed on 2013/07/01 16:25 UTC
Read the original article Hit count: 284

Filed under:

The previous post (creating a thematic map) described the use of an advanced style (color ranged-bucket style). The bucket style definition object has an attribute ('classification') which specifies the data classification scheme to use. It's values can be one of {'equal', 'quantile', 'logarithmic', 'custom'}. We use logarithmic in the previous example. Here we'll describe how to use a custom algorithm for classification. Specifically the Jenks Natural Breaks algorithm. We'll use the Javascript implementation in geostats.js

The sample code above needs a few changes which are listed below.

Include the geostats.js file after or before including oraclemapsv2.js

<script src="geostats.js"></script>

Modify the bucket style definition to use custom classification

   bucketStyleDef = {
      numClasses : colorSeries[colorName].classes,
      classification: 'custom', //'logarithmic',  // use a logarithmic scale 
      algorithm: jenksFromGeostats,
      styles: theStyles,
      gradient:  useGradient? 'linear' : 'off'
    };

The function, which implements the custom classification scheme, is specified as the algorithm attribute value. It must accept two input parameters, an array of OM.feature and the name of the feature attribute (e.g. TOTPOP) to use in the classification, and must return an array of buckets (i.e. an array of or OM.style.Bucket  or OM.style.RangedBucket in this case).

However the algorithm also needs to know the number of classes (i.e. the number of buckets to create). So we use a global to pass that info in. (Note: This bug/oversight will be fixed and the custom algorithm will be passed 3 parameters: the features array, attribute name, and number of classes).

So createBucketColorStyle() has the following changes

var numClasses ;
function createBucketColorStyle(
colorName, colorSeries, rangeName, useGradient)
{
   var theBucketStyle;
   var bucketStyleDef;
   var theStyles = [];
   //var numClasses ;

numClasses = colorSeries[colorName].classes;
...

and the function jenksFromGeostats is defined as

function jenksFromGeostats(featureArray, columnName)
{
   var items = [] ; // array of attribute values to be classified

   $.each(featureArray, function(i, feature) {
        items.push(parseFloat(feature.getAttributeValue(columnName)));
   });

   // create the geostats object
   var theSeries = new geostats(items);
   // call getJenks which returns an array of bounds
   var theClasses = theSeries.getJenks(
numClasses);
   if(theClasses)
   {
    theClasses[theClasses.length-1]=parseFloat(theClasses[theClasses.length-1])+1;
   }
   else
   {
    alert(' empty result from getJenks');
   }
   var theBuckets = [], aBucket=null ;
   for(var k=0; k<
numClasses; k++)
   {
            aBucket = new OM.style.RangedBucket(
            {low:parseFloat(theClasses[k]),
              high:parseFloat(theClasses[k+1])
            });

            theBuckets.push(aBucket);
    }
    return theBuckets;
}

A screenshot of the resulting map with 5 classes is shown below.


It is also possible to simply create the buckets and supply them when defining the Bucket style instead of specifying the function (algorithm). In that case the bucket style definition object would be

   bucketStyleDef = {
      numClasses : colorSeries[colorName].classes,
      classification: 'custom', 
      buckets: theBuckets, //since we are supplying all the buckets
      styles: theStyles,
      gradient:  useGradient? 'linear' : 'off'
    };



© Oracle Blogs or respective owner

Related posts about /Oracle