## Thursday, July 14, 2011

### Data decimation

The some times u just cant send out 100s of MBs of data, hell sometimes you cant process it. Basically you need to decimate the results into a usable shape. The average joe understands averages and maximums. So break it down based on what you need to see for the current level of zoom.

function decimate($points,$bounds)
{
$lngcnt = 20;$latcnt = 20;

$cdl = array(); foreach($points as &$p) {$lngper = ($p['long'] -$bounds[1])/($bounds[3] -$bounds[1]);
$latper = ($p['lat']  - $bounds[0])/($bounds[2] - $bounds[0]);$latidx = intVal($latcnt*$latper);
$lngidx = intVal($lngcnt*$lngper);$val = $p['cpm']; #create arrays if needed if(!isset($cdl[$lngidx])) {$cdl[$lngidx] = array(); } if(!isset($cdl[$lngidx][$latidx]))
{
$cdl[$lngidx][$latidx] = array();$cp = &$cdl[$lngidx][$latidx];$cp['sum'] = $val;$cp['cnt'] = 1;
$cp['max'] =$val;
$cp['max_long'] =$p['long'];
$cp['max_lat'] =$p['lat'];
# $cp['min'] =$val;
# $cp['min_long'] =$p['long'];
# $cp['min_lat'] =$p['lat'];
}
else
{
$cp = &$cdl[$lngidx][$latidx];
$cp['sum'] +=$val;
$cp['cnt']++; if ($val > $cp['max']) {$cp['max']      = $val;$cp['max_long'] = $p['long'];$cp['max_lat']  = $p['lat']; } # if ($val < $cp['min']) # { #$cp['min']      = $val; #$cp['min_long'] = $p['long']; #$cp['min_lat']  = $p['lat']; # } } }$res = array();
foreach($cdl as$lng => &$lngcdl) { foreach($lngcdl as $lat => &$cp)
{
if($cp['cnt'] > 0) {$pnt = array();
$pnt['cpm'] =$cp['sum']/$cp['cnt'];$pnt['long1']    = ($bounds[3] -$bounds[1])*$lng/$lngcnt + $bounds[1];$pnt['lat1']     = ($bounds[2] -$bounds[0])*$lat/$latcnt + $bounds[0];$pnt['long2']    = ($bounds[3] -$bounds[1])*($lng+1)/$lngcnt + $bounds[1];$pnt['lat2']     = ($bounds[2] -$bounds[0])*($lat+1)/$latcnt + $bounds[0];$pnt['max']      = $cp['max'] ;$pnt['max_long'] = $cp['max_long'];$pnt['max_lat']  = $cp['max_lat'] ; #$pnt['min']      = $cp['min'] ; #$pnt['min_long'] = $cp['min_long']; #$pnt['min_lat']  = $cp['min_lat'] ; array_push($res, $pnt); } } } return$res;
}