On Tue, Apr 29, 2008 at 8:23 AM, Jody Garnett wrote:
>
> Sweet - can you post some examples to the email list Michael? I will punt
> them onto the user guide for you ...
> Jody
>
Hi Jody - here's the start of a class for doing neighbourhood operations.
After waxing lyrical about ImageWorker this probably isn't the best
example :-) but I'll be doing more soon with masking etc. Feel free
to use and hack this code for whatever.
cheers
Michael
/*
* CafeAnimal: a program to simulate vertebrate population dynamics in changing
landscapes
*
*/
package org.cafeanimal.geo.gridlayer;
import java.awt.RenderingHints;
import java.awt.image.RenderedImage;
import javax.media.jai.BorderExtender;
import javax.media.jai.KernelJAI;
import javax.media.jai.operator.BorderDescriptor;
import javax.media.jai.operator.ConvolveDescriptor;
import javax.media.jai.operator.CropDescriptor;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.CoverageFactoryFinder;
import org.geotools.coverage.grid.GridCoverageFactory;
import org.geotools.geometry.Envelope2D;
import org.geotools.image.ImageWorker;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
/**
* Class for neighbourhood-based operations
* on grid layers.
*
* @author Michael Bedward <[EMAIL PROTECTED]>
*/
public class CAGridNbrOp {
private GridCoverage2D grid;
private ImageWorker iworker;
public CAGridNbrOp(GridCoverage2D grid) {
this.grid = grid;
iworker = new ImageWorker(grid.getData().getRenderedImage());
}
/**
* Search for grid locations with a total neighbourhood value greater than
* or equal to a specified minimum. The neighbourhood is a circle.
*
* Note: at present this operates in pixel coordinates.
*
* @param minValue the threshold value for neighbourhood total
* @param searchRadius radius of the circular search neighbourhood (in
pixels)
* @return a new binary grid layer
*/
public GridCoverage2D focalThreshold(float minValue, int searchRadius) {
convolve( createCircleMask(searchRadius) );
iworker.binarize(minValue);
CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
Envelope2D envelope = new Envelope2D(crs, 0, 0, w, h);
GridCoverageFactory factory =
CoverageFactoryFinder.getGridCoverageFactory(null);
return factory.create(name, img, envelope);
}
private void convolve(float[] kernelMatrix) {
int kernelW = (int) (Math.sqrt(kernelMatrix.length)+1.0E-6);
int borderW = kernelW / 2;
RenderingHints hints = iworker.getRenderingHints();
RenderedImage img = iworker.getRenderedImage();
img = BorderDescriptor.create(
img, borderW, borderW, borderW, borderW,
BorderExtender.createInstance(BorderExtender.BORDER_ZERO),
hints);
KernelJAI kernel = new KernelJAI(
kernelW, kernelW, kernelMatrix);
img = ConvolveDescriptor.create(
img, kernel, hints);
img = CropDescriptor.create(
img, (float)borderW, (float)borderW,
(float)grid.getPixelWidth(), (float)grid.getPixelHeight(),
hints);
iworker.setImage(img);
}
private float[] createCircleMask(int radius) {
int width = 2 * radius + 1;
float[] matrix = new float[width * width];
int x;
double r2 = radius * radius;
double y2;
for (int row = 0; row < radius; row++) {
y2 = Math.pow(radius - row, 2);
x = (int) Math.round(Math.sqrt(r2 - y2));
int upper0 = row * width + radius - x;
int lower0 = (width - row - 1) * width + radius - x;
for (int i = 0; i < 2 * x + 1; i++) {
matrix[upper0 + i] = 1;
matrix[lower0 + i] = 1;
}
}
int mid0 = radius * width;
for (int i = 0; i < width; i++) {
matrix[mid0 + i] = 1;
}
return matrix;
}
}
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
_______________________________________________
Geotools-gt2-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users