use of com.google.maps.android.geometry.Point in project wigle-wifi-wardriving by wiglenet.
the class HeatmapTileProvider method convolve.
/**
* Applies a 2D Gaussian convolution to the input grid, returning a 2D grid cropped of padding.
*
* @param grid Raw input grid to convolve: dimension (dim + 2 * radius) x (dim + 2 * radius)
* ie dim * dim with padding of size radius
* @param kernel Pre-computed Gaussian kernel of size radius * 2 + 1
* @return the smoothened grid
*/
static double[][] convolve(double[][] grid, double[] kernel) {
// Calculate radius size
int radius = (int) Math.floor((double) kernel.length / 2.0);
// Padded dimension
int dimOld = grid.length;
// Calculate final (non padded) dimension
int dim = dimOld - 2 * radius;
// Upper and lower limits of non padded (inclusive)
int lowerLimit = radius;
int upperLimit = radius + dim - 1;
// Convolve horizontally
double[][] intermediate = new double[dimOld][dimOld];
// Need to convolve every point (including those outside of non-padded area)
// but only need to add to points within non-padded area
int x, y, x2, xUpperLimit, initial;
double val;
for (x = 0; x < dimOld; x++) {
for (y = 0; y < dimOld; y++) {
// for each point (x, y)
val = grid[x][y];
// only bother if something there
if (val != 0) {
// need to "apply" convolution from that point to every point in
// (max(lowerLimit, x - radius), y) to (min(upperLimit, x + radius), y)
xUpperLimit = ((upperLimit < x + radius) ? upperLimit : x + radius) + 1;
// Replace Math.max
initial = (lowerLimit > x - radius) ? lowerLimit : x - radius;
for (x2 = initial; x2 < xUpperLimit; x2++) {
// multiplier for x2 = x - radius is kernel[0]
// x2 = x + radius is kernel[radius * 2]
// so multiplier for x2 in general is kernel[x2 - (x - radius)]
intermediate[x2][y] += val * kernel[x2 - (x - radius)];
}
}
}
}
// Convolve vertically
double[][] outputGrid = new double[dim][dim];
// Similarly, need to convolve every point, but only add to points within non-padded area
// However, we are adding to a smaller grid here (previously, was to a grid of same size)
int y2, yUpperLimit;
// Don't care about convolving parts in horizontal padding - wont impact inner
for (x = lowerLimit; x < upperLimit + 1; x++) {
for (y = 0; y < dimOld; y++) {
// for each point (x, y)
val = intermediate[x][y];
// only bother if something there
if (val != 0) {
// need to "apply" convolution from that point to every point in
// (x, max(lowerLimit, y - radius) to (x, min(upperLimit, y + radius))
// Don't care about
yUpperLimit = ((upperLimit < y + radius) ? upperLimit : y + radius) + 1;
// replace math.max
initial = (lowerLimit > y - radius) ? lowerLimit : y - radius;
for (y2 = initial; y2 < yUpperLimit; y2++) {
// Similar logic to above
// subtract, as adding to a smaller grid
outputGrid[x - radius][y2 - radius] += val * kernel[y2 - (y - radius)];
}
}
}
}
return outputGrid;
}
Aggregations