use of org.geotools.coverage.processing.CoverageProcessor in project structr by structr.
the class GetWCSHistogramFunction method apply.
@Override
public Object apply(final ActionContext ctx, final Object caller, final Object[] sources) throws FrameworkException {
try {
assertArrayHasMinLengthAndTypes(sources, 3, String.class, String.class, Geometry.class, Number.class, Number.class, Number.class);
final String baseUrl = (String) sources[0];
final String coverageId = (String) sources[1];
final Geometry geometry = (Geometry) sources[2];
final GridCoverage2D coverage = getWCSCoverage(baseUrl, coverageId, geometry);
final CoverageProcessor processor = CoverageProcessor.getInstance();
final Operation operation = processor.getOperation("Histogram");
final ParameterValueGroup params = operation.getParameters();
final int numBins = sources.length > 3 ? parseInt(sources[3], 256) : 256;
final double lowValue = sources.length > 4 ? parseDouble(sources[4], 0.0) : 0.0;
final double cutoffPercentage = sources.length > 5 ? parseDouble(sources[5], 0.005) : 0.005;
final double[] extrema = getExtrema(coverage, 0);
params.parameter("source0").setValue(coverage);
params.parameter("numBins").setValue(new int[] { numBins });
params.parameter("lowValue").setValue(new double[] { lowValue });
params.parameter("highValue").setValue(new double[] { extrema[1] });
final NumberFormat format = new DecimalFormat("#,###,##0.00");
final GridCoverage2D result = (GridCoverage2D) processor.doOperation(params);
final Histogram histogram = (Histogram) result.getProperty("histogram");
final int[] bins = histogram.getBins(0);
final Double binWidth = histogram.getHighValue()[0] / (double) numBins;
final Map<String, Object> map = new LinkedHashMap<>();
List<String> binNames = new LinkedList<>();
List<Integer> binData = new LinkedList<>();
int lastIndex = 0;
int restBin = 0;
double maxCount = 0;
for (int i = 0; i < bins.length; i++) {
final double d = i;
binNames.add(format.format(binWidth * d));
binData.add(bins[i]);
if (bins[i] > maxCount) {
maxCount = bins[i];
}
}
// combine all bins whose value is below a given threshold (maxCount * cutoffPercentage)
int threshold = Double.valueOf(maxCount * cutoffPercentage).intValue();
for (int i = 0; i < bins.length; i++) {
// find index of last bin with more than x elements
if (bins[i] > threshold) {
lastIndex = i;
}
}
// collect the sum of all the bins below the threshold
for (int i = lastIndex; i < bins.length; i++) {
restBin += bins[i];
}
binNames = binNames.subList(0, lastIndex);
binData = binData.subList(0, lastIndex);
// add a single bin with all the rest
binNames.add("> " + format.format(binWidth * lastIndex));
binData.add(restBin);
// remove all bins that have less than threshold elements
map.put("names", binNames);
map.put("bins", binData);
return map;
} catch (ArgumentNullException pe) {
// silently ignore null arguments
return "";
} catch (ArgumentCountException pe) {
logParameterError(caller, sources, pe.getMessage(), ctx.isJavaScriptContext());
return usage(ctx.isJavaScriptContext());
} catch (ArgumentTypeException te) {
logParameterError(caller, sources, te.getMessage(), ctx.isJavaScriptContext());
return usage(ctx.isJavaScriptContext());
}
}
use of org.geotools.coverage.processing.CoverageProcessor in project geowave by locationtech.
the class RasterIngestRunner method processPreviousScene.
@SuppressWarnings({ "rawtypes", "unchecked" })
protected void processPreviousScene() {
if (!ingestOptions.isCoveragePerBand()) {
// ingest as single image for all bands
if (!lastSceneBands.isEmpty()) {
// we are sorting by band name to ensure a consistent order for
// bands
final TreeMap<String, RasterBandData> sceneData = new TreeMap<>();
Writer writer;
// get coverage info, ensuring that all coverage names are the
// same
String coverageName = null;
for (final SimpleFeature band : lastSceneBands) {
RasterBandData bandData;
try {
bandData = getBandData(band);
if (coverageName == null) {
coverageName = bandData.name;
} else if (!coverageName.equals(bandData.name)) {
LOGGER.warn("Unable to use band data as the band coverage name '" + bandData.name + "' is unexpectedly different from default name '" + coverageName + "'");
}
final String bandName = band.getAttribute(BandFeatureIterator.BAND_ATTRIBUTE_NAME).toString();
sceneData.put(bandName, bandData);
} catch (IOException | TemplateException e) {
LOGGER.warn("Unable to read band data", e);
}
}
if (coverageName == null) {
LOGGER.warn("No valid bands found for scene");
lastSceneBands.clear();
return;
}
final GridCoverage2D mergedCoverage;
if (sceneData.size() == 1) {
mergedCoverage = sceneData.firstEntry().getValue().coverage;
} else {
final CoverageProcessor processor = CoverageProcessor.getInstance();
final AbstractOperation op = (AbstractOperation) processor.getOperation("BandMerge");
final ParameterValueGroup params = op.getParameters();
final List<GridCoverage2D> sources = new ArrayList<>();
for (final RasterBandData bandData : sceneData.values()) {
sources.add(bandData.coverage);
}
params.parameter("Sources").setValue(sources);
params.parameter(BandMerge.TRANSFORM_CHOICE).setValue(TransformList.FIRST.toString());
mergedCoverage = (GridCoverage2D) op.doOperation(params, null);
}
final String[] thisSceneBands = sceneData.keySet().toArray(new String[] {});
if (bandsIngested == null) {
// this means this is the first scene
// setup adapter and other required info
final Map<String, String> metadata = new HashMap<>();
final double[][] noDataValues = new double[sceneData.size()][];
int b = 0;
// merge metadata from all readers
for (final RasterBandData bandData : sceneData.values()) {
try {
final String[] metadataNames = bandData.reader.getMetadataNames();
if ((metadataNames != null) && (metadataNames.length > 0)) {
for (final String metadataName : metadataNames) {
metadata.put(metadataName, bandData.reader.getMetadataValue(metadataName));
}
}
} catch (final Exception e) {
LOGGER.warn("Unable to get metadata for coverage '" + coverageName + "'.", e);
}
noDataValues[b++] = new double[] { bandData.nodataValue };
}
final RasterDataAdapter adapter = new RasterDataAdapter(coverageName, metadata, mergedCoverage, ingestOptions.getTileSize(), ingestOptions.isCreatePyramid(), ingestOptions.isCreateHistogram(), noDataValues, new NoDataMergeStrategy());
store.addType(adapter, indices);
writer = store.createWriter(adapter.getTypeName());
writerCache.put(coverageName, writer);
bandsIngested = thisSceneBands;
} else if (!Arrays.equals(bandsIngested, thisSceneBands)) {
LOGGER.warn("The bands in this scene ('" + Arrays.toString(thisSceneBands) + "') differ from the previous scene ('" + Arrays.toString(bandsIngested) + "'). To merge bands all scenes must use the same bands. Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.ENTITY_ID_ATTRIBUTE_NAME) + "'.");
lastSceneBands.clear();
return;
} else {
writer = writerCache.get(coverageName);
if (writer == null) {
LOGGER.warn("Unable to find writer for coverage '" + coverageName + "'. Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.ENTITY_ID_ATTRIBUTE_NAME) + "'.");
lastSceneBands.clear();
return;
}
}
writer.write(mergedCoverage);
lastSceneBands.clear();
}
}
}
use of org.geotools.coverage.processing.CoverageProcessor in project geowave by locationtech.
the class RasterIngestRunner method processPreviousScene.
protected void processPreviousScene() {
if (!ingestOptions.isCoveragePerBand()) {
// ingest as single image for all bands
if (!lastSceneBands.isEmpty()) {
// we are sorting by band name to ensure a consistent order for
// bands
final TreeMap<String, BandData> sceneData = new TreeMap<>();
Writer writer;
// get coverage info, ensuring that all coverage names are the
// same
String coverageName = null;
for (final SimpleFeature band : lastSceneBands) {
BandData bandData;
try {
bandData = getBandData(band);
if (coverageName == null) {
coverageName = bandData.name;
} else if (!coverageName.equals(bandData.name)) {
LOGGER.warn("Unable to use band data as the band coverage name '" + bandData.name + "' is unexpectedly different from default name '" + coverageName + "'");
}
final String bandName = band.getAttribute(BandFeatureIterator.BAND_ATTRIBUTE_NAME).toString();
sceneData.put(bandName, bandData);
} catch (IOException | TemplateException e) {
LOGGER.warn("Unable to read band data", e);
}
}
if (coverageName == null) {
LOGGER.warn("No valid bands found for scene");
lastSceneBands.clear();
return;
}
final GridCoverage2D mergedCoverage;
if (sceneData.size() == 1) {
mergedCoverage = sceneData.firstEntry().getValue().coverage;
} else {
final CoverageProcessor processor = CoverageProcessor.getInstance();
final AbstractOperation op = (AbstractOperation) processor.getOperation("BandMerge");
final ParameterValueGroup params = op.getParameters();
final List<GridCoverage2D> sources = new ArrayList<>();
for (final BandData b : sceneData.values()) {
sources.add(b.coverage);
}
params.parameter("Sources").setValue(sources);
params.parameter(BandMerge.TRANSFORM_CHOICE).setValue(TransformList.FIRST.toString());
mergedCoverage = (GridCoverage2D) op.doOperation(params, null);
}
final String[] thisSceneBands = sceneData.keySet().toArray(new String[] {});
if (bandsIngested == null) {
// this means this is the first scene
// setup adapter and other required info
final Map<String, String> metadata = new HashMap<>();
// merge metadata from all readers
for (final BandData b : sceneData.values()) {
final String[] mdNames = b.reader.getMetadataNames();
if ((mdNames != null) && (mdNames.length > 0)) {
for (final String mdName : mdNames) {
metadata.put(mdName, b.reader.getMetadataValue(mdName));
}
}
}
final double[][] noDataValues = new double[sceneData.size()][];
int b = 0;
for (final String bandName : sceneData.keySet()) {
noDataValues[b++] = new double[] { getNoDataValueFromName(bandName) };
}
final RasterDataAdapter adapter = new RasterDataAdapter(coverageName, metadata, mergedCoverage, ingestOptions.getTileSize(), ingestOptions.isCreatePyramid(), ingestOptions.isCreateHistogram(), noDataValues, new NoDataMergeStrategy());
store.addType(adapter, indices);
writer = store.createWriter(adapter.getTypeName());
writerCache.put(coverageName, writer);
bandsIngested = thisSceneBands;
} else if (!Arrays.equals(bandsIngested, thisSceneBands)) {
LOGGER.warn("The bands in this scene ('" + Arrays.toString(thisSceneBands) + "') differ from the previous scene ('" + Arrays.toString(bandsIngested) + "'). To merge bands all scenes must use the same bands. Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.PRODUCT_ID_ATTRIBUTE_NAME) + "'.");
lastSceneBands.clear();
return;
} else {
writer = writerCache.get(coverageName);
if (writer == null) {
LOGGER.warn("Unable to find writer for coverage '" + coverageName + "'. Skipping scene'" + lastSceneBands.get(0).getAttribute(SceneFeatureIterator.PRODUCT_ID_ATTRIBUTE_NAME) + "'.");
lastSceneBands.clear();
return;
}
}
writer.write(mergedCoverage);
lastSceneBands.clear();
if (!ingestOptions.isRetainImages()) {
for (final BandData b : sceneData.values()) {
if (!b.geotiffFile.delete()) {
LOGGER.warn("Unable to delete '" + b.geotiffFile.getAbsolutePath() + "'");
}
}
}
}
}
}
use of org.geotools.coverage.processing.CoverageProcessor in project hortonmachine by TheHortonMachine.
the class OmsRasterReprojector method process.
@Execute
public void process() throws Exception {
if (!concatOr(outRaster == null, doReset)) {
return;
}
CoordinateReferenceSystem targetCrs = CrsUtilities.getCrsFromEpsg(pCode, null);
Interpolation interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
if (pInterpolation.equals(BILINEAR)) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
} else if (pInterpolation.equals(BICUBIC)) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
}
CoordinateReferenceSystem sourceCrs = inRaster.getCoordinateReferenceSystem();
// if (!CrsUtilities.isCrsValid(sourceCrs)) {
// throw new ModelsIllegalargumentException("Source projection not supported.", this);
// }
GridGeometry2D gridGeometry = null;
if (pXres != null && pYres != null) {
RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inRaster);
double n = regionMap.getNorth();
double s = regionMap.getSouth();
double e = regionMap.getEast();
double w = regionMap.getWest();
Polygon polygon = GeometryUtilities.createPolygonFromEnvelope(new Envelope(w, e, s, n));
MathTransform transform = CRS.findMathTransform(sourceCrs, targetCrs);
Geometry targetGeometry = JTS.transform(polygon, transform);
Envelope env = targetGeometry.getEnvelopeInternal();
n = env.getMaxY();
s = env.getMinY();
w = env.getMinX();
e = env.getMaxX();
int newCols = (int) Math.round((e - w) / pXres);
int newRows = (int) Math.round((n - s) / pYres);
gridGeometry = CoverageUtilities.gridGeometryFromRegionValues(n, s, e, w, newCols, newRows, targetCrs);
pm.message("Using supplied gridgeometry: " + gridGeometry);
}
pm.beginTask("Reprojecting...", IHMProgressMonitor.UNKNOWN);
try {
if (gridGeometry == null) {
if (interpolation == null) {
outRaster = (GridCoverage2D) Operations.DEFAULT.resample(inRaster, targetCrs);
} else {
outRaster = (GridCoverage2D) Operations.DEFAULT.resample(inRaster, targetCrs, null, interpolation);
}
} else {
outRaster = (GridCoverage2D) Operations.DEFAULT.resample(inRaster, targetCrs, gridGeometry, interpolation);
}
} catch (CoverageProcessingException e) {
CoverageProcessor processor = new CoverageProcessor();
ParameterValueGroup params = processor.getOperation("Resample").getParameters();
params.parameter("Source").setValue(inRaster);
// params.parameter("Source").value = this.coverage
params.parameter("CoordinateReferenceSystem").setValue(targetCrs);
outRaster = (GridCoverage2D) processor.doOperation(params);
}
pm.done();
}
use of org.geotools.coverage.processing.CoverageProcessor in project geowave by locationtech.
the class RasterIngestRunner method getBandData.
protected BandData getBandData(final SimpleFeature band) throws IOException, TemplateException {
final Map<String, Object> model = new HashMap<>();
final SimpleFeatureType type = band.getFeatureType();
for (final AttributeDescriptor attr : type.getAttributeDescriptors()) {
final String attrName = attr.getLocalName();
final Object attrValue = band.getAttribute(attrName);
if (attrValue != null) {
model.put(attrName, attrValue);
}
}
final String coverageName = FreeMarkerTemplateUtils.processTemplateIntoString(coverageNameTemplate, model);
final File geotiffFile = DownloadRunner.getDownloadFile(band, landsatOptions.getWorkspaceDir());
final GDALGeoTiffReader reader = new GDALGeoTiffReader(geotiffFile);
GridCoverage2D coverage = reader.read(null);
reader.dispose();
if ((ingestOptions.getCoverageConverter() != null) && !ingestOptions.getCoverageConverter().trim().isEmpty()) {
// a converter was supplied, attempt to use it
final Landsat8BandConverterSpi converter = getConverter(ingestOptions.getCoverageConverter());
if (converter != null) {
coverage = converter.convert(coverageName, coverage, band);
}
}
if (ingestOptions.isSubsample()) {
coverage = (GridCoverage2D) RasterUtils.getCoverageOperations().filteredSubsample(coverage, ingestOptions.getScale(), ingestOptions.getScale(), null);
}
// its unclear whether cropping should be done first or subsampling
if (ingestOptions.isCropToSpatialConstraint()) {
boolean cropped = false;
final Filter filter = landsatOptions.getCqlFilter();
if (filter != null) {
final ExtractGeometryFilterVisitorResult geometryAndCompareOp = ExtractGeometryFilterVisitor.getConstraints(filter, GeometryUtils.getDefaultCRS(), SceneFeatureIterator.SHAPE_ATTRIBUTE_NAME);
Geometry geometry = geometryAndCompareOp.getGeometry();
if (geometry != null) {
// go ahead and intersect this with the scene geometry
final Geometry sceneShape = (Geometry) band.getAttribute(SceneFeatureIterator.SHAPE_ATTRIBUTE_NAME);
if (geometry.contains(sceneShape)) {
cropped = true;
} else {
geometry = geometry.intersection(sceneShape);
final CoverageProcessor processor = CoverageProcessor.getInstance();
final AbstractOperation op = (AbstractOperation) processor.getOperation("CoverageCrop");
final ParameterValueGroup params = op.getParameters();
params.parameter("Source").setValue(coverage);
try {
final MathTransform transform = CRS.findMathTransform(GeometryUtils.getDefaultCRS(), coverage.getCoordinateReferenceSystem(), true);
params.parameter(Crop.CROP_ROI.getName().getCode()).setValue(JTS.transform(geometry, transform));
final double nodataValue = getNoDataValue(band);
params.parameter(Crop.NODATA.getName().getCode()).setValue(RangeFactory.create(nodataValue, nodataValue));
params.parameter(Crop.DEST_NODATA.getName().getCode()).setValue(new double[] { nodataValue });
coverage = (GridCoverage2D) op.doOperation(params, null);
cropped = true;
} catch (InvalidParameterValueException | ParameterNotFoundException | FactoryException | MismatchedDimensionException | TransformException e) {
LOGGER.warn("Unable to crop image", e);
}
}
}
if (!cropped) {
LOGGER.warn("Option to crop spatially was set but no spatial constraints were provided in CQL expression");
}
}
}
return new BandData(coverageName, coverage, reader, geotiffFile);
}
Aggregations