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
/Oracle
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