public static GridCoverage2D removeNovalues(GridCoverage2D geodata) { // need to adapt it, for now do it dirty HashMap<String, Double> params = getRegionParamsFromGridCoverage(geodata); int height = params.get(ROWS).intValue(); int width = params.get(COLS).intValue(); WritableRaster tmpWR = createDoubleWritableRaster(width, height, null, null, null); WritableRandomIter tmpIter = RandomIterFactory.createWritable(tmpWR, null); RenderedImage readRI = geodata.getRenderedImage(); RandomIter readIter = RandomIterFactory.create(readRI, null); for (int r = 0; r < height; r++) { for (int c = 0; c < width; c++) { double value = readIter.getSampleDouble(c, r, 0); if (Double.isNaN(value) || Float.isNaN((float) value) || Math.abs(value - -9999.0) < .0000001) { tmpIter.setSample(c, r, 0, Double.NaN); } else { tmpIter.setSample(c, r, 0, value); } } } geodata = buildCoverage("newcoverage", tmpWR, params, geodata.getCoordinateReferenceSystem()); return geodata; }
// This method is similar to the testBandMerge method but it tests the ExtendedBandMergeOpImage // class private void testExtendedBandMerge(RenderedImage[] sources, boolean noDataUsed, boolean roiUsed) { // Optional No Data Range used Range[] noData; // Source image data type int dataType = sources[0].getSampleModel().getDataType(); // If no Data are present, the No Data Range associated is used if (noDataUsed) { switch (dataType) { case DataBuffer.TYPE_BYTE: noData = noDataByte; break; case DataBuffer.TYPE_USHORT: noData = noDataUShort; break; case DataBuffer.TYPE_SHORT: noData = noDataShort; break; case DataBuffer.TYPE_INT: noData = noDataInt; break; case DataBuffer.TYPE_FLOAT: noData = noDataFloat; break; case DataBuffer.TYPE_DOUBLE: noData = noDataDouble; break; default: throw new IllegalArgumentException("Wrong data type"); } } else { noData = null; } // ROI to use ROI roi = null; if (roiUsed) { roi = roiData; } // New array ofr the transformed source images RenderedOp[] translated = new RenderedOp[sources.length]; List<AffineTransform> transform = new ArrayList<AffineTransform>(); for (int i = 0; i < sources.length; i++) { // Translation coefficients int xTrans = (int) (Math.random() * 10); int yTrans = (int) (Math.random() * 10); // Translation operation AffineTransform tr = AffineTransform.getTranslateInstance(xTrans, yTrans); // Addition to the transformations list transform.add(tr); // Translation of the image translated[i] = TranslateDescriptor.create(sources[i], (float) xTrans, (float) yTrans, null, null); } // Definition of the final image dimensions ImageLayout layout = new ImageLayout(); layout.setMinX(sources[0].getMinX()); layout.setMinY(sources[0].getMinY()); layout.setWidth(sources[0].getWidth()); layout.setHeight(sources[0].getHeight()); RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout); // BandMerge operation RenderedOp merged = BandMergeDescriptor.create(noData, destNoData, hints, transform, roi, translated); Assert.assertNotNull(merged.getTiles()); // Check if the bands number is the same assertEquals(BAND_NUMBER, merged.getNumBands()); // Upper-Left tile indexes int minTileX = merged.getMinTileX(); int minTileY = merged.getMinTileY(); // Raster object Raster upperLeftTile = merged.getTile(minTileX, minTileY); // Tile bounds int minX = upperLeftTile.getMinX(); int minY = upperLeftTile.getMinY(); int maxX = upperLeftTile.getWidth() + minX; int maxY = upperLeftTile.getHeight() + minY; // Source corners final int dstMinX = merged.getMinX(); final int dstMinY = merged.getMinY(); final int dstMaxX = merged.getMaxX(); final int dstMaxY = merged.getMaxY(); Point2D ptDst = new Point2D.Double(0, 0); Point2D ptSrc = new Point2D.Double(0, 0); // Cycle on all the tile Bands for (int b = 0; b < BAND_NUMBER; b++) { RandomIter iter = RandomIterFactory.create(translated[b], null); // Source corners final int srcMinX = translated[b].getMinX(); final int srcMinY = translated[b].getMinY(); final int srcMaxX = translated[b].getMaxX(); final int srcMaxY = translated[b].getMaxY(); // Cycle on the y-axis for (int x = minX; x < maxX; x++) { // Cycle on the x-axis for (int y = minY; y < maxY; y++) { // Calculated value double value = upperLeftTile.getSampleDouble(x, y, b); // If the tile pixels are outside the image bounds, then no data is set. if (x < dstMinX || x >= dstMaxX || y < dstMinY || y >= dstMaxY) { value = destNoData; } // Set the x,y destination pixel location ptDst.setLocation(x, y); // Map destination pixel to source pixel transform.get(b).transform(ptDst, ptSrc); // Source pixel indexes int srcX = round(ptSrc.getX()); int srcY = round(ptSrc.getY()); double valueOld = destNoData; // Check if the pixel is inside the source bounds if (!(srcX < srcMinX || srcX >= srcMaxX || srcY < srcMinY || srcY >= srcMaxY)) { // Old band value valueOld = iter.getSampleDouble(srcX, srcY, 0); } // ROI CHECK boolean contained = true; if (roiUsed) { if (!roi.contains(x, y)) { contained = false; // Comparison if the final value is not inside a ROI assertEquals(value, destNoData, TOLERANCE); } } if (contained) { // If no Data are present, no data check is performed if (noDataUsed) { switch (dataType) { case DataBuffer.TYPE_BYTE: byte sampleB = ImageUtil.clampRoundByte(value); byte sampleBOld = ImageUtil.clampRoundByte(valueOld); if (noData[0].contains(sampleBOld)) { assertEquals(sampleB, destNoData, TOLERANCE); } else { assertEquals(sampleB, valueOld, TOLERANCE); } break; case DataBuffer.TYPE_USHORT: short sampleUS = ImageUtil.clampRoundUShort(value); short sampleUSOld = ImageUtil.clampRoundUShort(valueOld); if (noData[0].contains(sampleUSOld)) { assertEquals(sampleUS, destNoData, TOLERANCE); } else { assertEquals(sampleUS, valueOld, TOLERANCE); } break; case DataBuffer.TYPE_SHORT: short sampleS = ImageUtil.clampRoundShort(value); short sampleSOld = ImageUtil.clampRoundShort(valueOld); if (noData[0].contains(sampleSOld)) { assertEquals(sampleS, destNoData, TOLERANCE); } else { assertEquals(sampleS, valueOld, TOLERANCE); } break; case DataBuffer.TYPE_INT: int sampleI = ImageUtil.clampRoundInt(value); int sampleIOld = ImageUtil.clampRoundInt(valueOld); if (noData[0].contains(sampleIOld)) { assertEquals(sampleI, destNoData, TOLERANCE); } else { assertEquals(sampleI, valueOld, TOLERANCE); } break; case DataBuffer.TYPE_FLOAT: float sampleF = ImageUtil.clampFloat(value); float sampleFOld = ImageUtil.clampFloat(valueOld); if (noData[0].contains(sampleFOld)) { assertEquals(sampleF, destNoData, TOLERANCE); } else { assertEquals(sampleF, valueOld, TOLERANCE); } break; case DataBuffer.TYPE_DOUBLE: if (noData[0].contains(valueOld)) { assertEquals(value, destNoData, TOLERANCE); } else { assertEquals(value, valueOld, TOLERANCE); } break; default: throw new IllegalArgumentException("Wrong data type"); } } else { // Else a simple value comparison is done assertEquals(value, valueOld, TOLERANCE); } } } } } // Disposal of the output image merged.dispose(); }
/** * Checking if NoData and ROI are defined correctly * * @param indexed * @param image * @param roi * @param nodata * @param destNoData */ private void checkNoDataROI( RenderedImage indexed, RenderedImage image, ROI roi, Range nodata, int destNoData) { // Ensure the dimensions are the same assertEquals(indexed.getMinX(), image.getMinX()); assertEquals(indexed.getMinY(), image.getMinY()); assertEquals(indexed.getWidth(), image.getWidth()); assertEquals(indexed.getHeight(), image.getHeight()); boolean roiExists = roi != null; boolean nodataExists = nodata != null; // Simply ensure no exception is thrown if (!nodataExists && !roiExists) { PlanarImage.wrapRenderedImage(indexed).getTiles(); return; } if (nodataExists) { nodata = RangeFactory.convertToDoubleRange(nodata); } RandomIter roiIter = null; Rectangle roiBounds = null; if (roiExists) { PlanarImage roiIMG = roi.getAsImage(); roiIter = RandomIterFactory.create(roiIMG, null, true, true); roiBounds = roi.getBounds(); } // Else check ROI and NoData RandomIter sourceIter = RandomIterFactory.create(image, null, true, true); RandomIter destIter = RandomIterFactory.create(indexed, null, true, true); // Start the iteration (we iterate only the first band) int w = image.getWidth(); int h = image.getHeight(); int minX = image.getMinX(); int minY = image.getMinY(); int maxX = minX + w; int maxY = minY + h; int limx = minX - image.getTileGridXOffset(); int limy = minY - image.getTileGridYOffset(); Rectangle translated = new Rectangle(limx, limy, w, h); for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { double src = sourceIter.getSampleDouble(x, y, 0); double dest = destIter.getSampleDouble(x, y, 0); boolean valid = true; // ROI Check if (roiExists && !(roiBounds.contains(x, y) && roiIter.getSample(x, y, 0) > 0) && translated.contains(x, y)) { valid = false; } // NoData Check if (nodataExists && nodata.contains(src)) { valid = false; } if (!valid) { assertEquals(destNoData, dest, TOLERANCE); } } } }
@Execute public void process() throws Exception { if (!concatOr(outIntensity == null, doReset)) { return; } checkNull( inVelocity, pUpperThresVelocity, pLowerThresVelocity, // inWaterDepth, pUpperThresWaterdepth, pLowerThresWaterdepth, // inErosionDepth, pUpperThresErosionDepth, pLowerThresErosionDepth, // inDepositsThickness, pUpperThresDepositsThickness, pLowerThresDepositsThickness // ); // do autoboxing only once double maxWD = pUpperThresWaterdepth; double minWD = pLowerThresWaterdepth; double maxV = pUpperThresVelocity; double minV = pLowerThresVelocity; double maxED = pUpperThresErosionDepth; double minED = pLowerThresErosionDepth; double maxDT = pUpperThresDepositsThickness; double minDT = pLowerThresDepositsThickness; RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inWaterDepth); int nCols = regionMap.getCols(); int nRows = regionMap.getRows(); RandomIter waterdepthIter = CoverageUtilities.getRandomIterator(inWaterDepth); RandomIter velocityIter = CoverageUtilities.getRandomIterator(inVelocity); RandomIter erosiondepthIter = CoverageUtilities.getRandomIterator(inErosionDepth); RandomIter depositThicknessIter = CoverageUtilities.getRandomIterator(inDepositsThickness); WritableRaster outWR = CoverageUtilities.createDoubleWritableRaster(nCols, nRows, null, null, doubleNovalue); WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null); pm.beginTask("Processing map...", nRows); for (int r = 0; r < nRows; r++) { if (isCanceled(pm)) { return; } for (int c = 0; c < nCols; c++) { double h = waterdepthIter.getSampleDouble(c, r, 0); double v = velocityIter.getSampleDouble(c, r, 0); double ed = erosiondepthIter.getSampleDouble(c, r, 0); double dt = depositThicknessIter.getSampleDouble(c, r, 0); if (isNovalue(h) && isNovalue(v) && isNovalue(ed) && isNovalue(dt)) { continue; } else if (!isNovalue(h) && !isNovalue(v) && !isNovalue(ed) && !isNovalue(dt)) { double value = 0.0; if (h > maxWD || v > maxV || dt > maxDT || ed > maxED) { value = INTENSITY_HIGH; } else if ((h <= maxWD && h > minWD) || // (v <= maxV && v > minV) || // (dt <= maxDT && dt > minDT) || // (ed <= maxED && ed > minED)) { value = INTENSITY_MEDIUM; } else if (h <= minWD || v <= minV || dt <= minDT || ed <= minED) { value = INTENSITY_LOW; } else { throw new ModelsIllegalargumentException( "No intensity could be calculated for h = " + h + " and v = " + v + " and ed = " + ed + " and dt = " + dt, this, pm); } outIter.setSample(c, r, 0, value); } else { pm.errorMessage( "WARNING: a cell was found in which one of velocity, water depth, erosion depth or deposit thickness are novalue, while the other not. /nThe maps should be covering the exact same cells. /nGoing on ignoring the cell: " + c + "/" + r); } } pm.worked(1); } pm.done(); outIntensity = CoverageUtilities.buildCoverage( "intensity", outWR, regionMap, inWaterDepth.getCoordinateReferenceSystem()); }