private void copyStx(RasterDataNode sourceRaster, RasterDataNode targetRaster) { final Stx sourceStx = sourceRaster.getStx(); final Histogram sourceHistogram = sourceStx.getHistogram(); final Histogram targetHistogram = new Histogram( sourceStx.getHistogramBinCount(), sourceHistogram.getLowValue(0), sourceHistogram.getHighValue(0), 1); System.arraycopy( sourceHistogram.getBins(0), 0, targetHistogram.getBins(0), 0, sourceStx.getHistogramBinCount()); final Stx targetStx = new Stx( sourceStx.getMinimum(), sourceStx.getMaximum(), sourceStx.getMean(), sourceStx.getStandardDeviation(), sourceStx.getCoefficientOfVariation(), sourceStx.getEquivalentNumberOfLooks(), sourceStx.isLogHistogram(), sourceStx.isIntHistogram(), targetHistogram, sourceStx.getResolutionLevel()); targetRaster.setStx(targetStx); }
private static void copyData( ProductData sourceBuffer, int sourcePos, ProductData destBuffer, int destPos, int destLength) { System.arraycopy( sourceBuffer.getElems(), sourcePos, destBuffer.getElems(), destPos, destLength); }
@Override public synchronized void readBandData( Band destBand, int sourceOffsetX, int sourceOffsetY, int sourceWidth, int sourceHeight, int sourceStepX, int sourceStepY, ProductData destBuffer, ProgressMonitor pm) throws IOException, InvalidRangeException { final Variable variable = variableMap.get(destBand); DataType prodtype = variable.getDataType(); float[] fbuffer; short[] sbuffer; int[] ibuffer; byte[] bbuffer; Object buffer; if (prodtype == DataType.FLOAT) { fbuffer = (float[]) destBuffer.getElems(); Arrays.fill(fbuffer, Float.NaN); buffer = fbuffer; } else if (prodtype == DataType.SHORT) { sbuffer = (short[]) destBuffer.getElems(); Arrays.fill(sbuffer, (short) -999); buffer = sbuffer; } else if (prodtype == DataType.BYTE) { bbuffer = (byte[]) destBuffer.getElems(); Arrays.fill(bbuffer, (byte) 255); buffer = bbuffer; } else { ibuffer = (int[]) destBuffer.getElems(); Arrays.fill(ibuffer, -999); buffer = ibuffer; } if (rowInfo == null) { rowInfo = createRowInfos(); } final int height = sceneHeight; final int width = sceneWidth; final ISINGrid grid = this.grid; // loop over lines try { int[] lineOffsets = new int[1]; int[] lineLengths = new int[1]; int[] stride = new int[1]; stride[0] = 1; // for (int y = sourceOffsetY; y < sourceOffsetY + sourceHeight; y++) { for (int y = sourceOffsetY; y < sourceOffsetY + sourceHeight; y += sourceStepY) { if (pm.isCanceled()) { break; } final int rowIndex = (height - 1) - y; final RowInfo rowInfo = this.rowInfo[rowIndex]; if (rowInfo != null) { final int lineOffset = rowInfo.offset; final int lineLength = rowInfo.length; lineOffsets[0] = lineOffset; lineLengths[0] = lineLength; final Object bindata; synchronized (ncFile) { bindata = variable.read().section(lineOffsets, lineLengths, stride).copyTo1DJavaArray(); } int lineIndex0 = 0; for (int x = sourceOffsetX; x < sourceOffsetX + sourceWidth; x++) { final double lon = x * 360.0 / width; final int binIndex = grid.getBinIndex(rowIndex, lon); int lineIndex = -1; for (int i = lineIndex0; i < lineLength; i++) { int binidx = bins[lineOffset + i]; if (binidx >= binIndex) { if (binidx == binIndex) { lineIndex = i; } lineIndex0 = i; break; } } if (lineIndex >= 0) { final int rasterIndex = sourceWidth * (y - sourceOffsetY) + (x - sourceOffsetX); System.arraycopy(bindata, lineIndex, buffer, rasterIndex, 1); } } pm.worked(1); } } } finally { pm.done(); } }
/** The product reader for Radarsat2 products. */ public class Radarsat2ProductReader extends AbstractProductReader { protected Radarsat2ProductDirectory dataDir = null; private static final String lutsigma = "lutSigma"; private static final String lutgamma = "lutGamma"; private static final String lutbeta = "lutBeta"; private boolean isAscending; private boolean isAntennaPointingRight; private static final boolean flipToSARGeometry = System.getProperty(SystemUtils.getApplicationContextId() + ".flip.to.sar.geometry", "false") .equals("true"); /** * Constructs a new abstract product reader. * * @param readerPlugIn the reader plug-in which created this reader, can be <code>null</code> for * internal reader implementations */ public Radarsat2ProductReader(final ProductReaderPlugIn readerPlugIn) { super(readerPlugIn); } /** * Closes the access to all currently opened resources such as file input streams and all * resources of this children directly owned by this reader. Its primary use is to allow the * garbage collector to perform a vanilla job. * * <p> * * <p>This method should be called only if it is for sure that this object instance will never be * used again. The results of referencing an instance of this class after a call to <code>close() * </code> are undefined. * * <p> * * <p>Overrides of this method should always call <code>super.close();</code> after disposing this * instance. * * @throws java.io.IOException if an I/O error occurs */ @Override public void close() throws IOException { if (dataDir != null) { dataDir.close(); dataDir = null; } super.close(); } /** * Provides an implementation of the <code>readProductNodes</code> interface method. Clients * implementing this method can be sure that the input object and eventually the subset * information has already been set. * * <p> * * <p>This method is called as a last step in the <code>readProductNodes(input, subsetInfo)</code> * method. * * @throws java.io.IOException if an I/O error occurs */ @Override protected Product readProductNodesImpl() throws IOException { Product product; try { final File fileFromInput = ReaderUtils.getFileFromInput(getInput()); dataDir = createDirectory(fileFromInput); dataDir.readProductDirectory(); product = dataDir.createProduct(); addCalibrationLUT(product, fileFromInput.getParentFile()); product.getGcpGroup(); product.setFileLocation(fileFromInput); product.setProductReader(this); product.setModified(false); final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product); isAscending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("ASCENDING"); isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right"); } catch (Exception e) { Debug.trace(e.toString()); final IOException ioException = new IOException(e.getMessage()); ioException.initCause(e); throw ioException; } return product; } protected Radarsat2ProductDirectory createDirectory(final File fileFromInput) { return new Radarsat2ProductDirectory(fileFromInput, fileFromInput.getParentFile()); } /** * Read the LUT for use in calibration * * @param product the target product * @param folder the folder containing the input * @throws IOException if can't read lut */ private static void addCalibrationLUT(final Product product, final File folder) throws IOException { final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product); final boolean isAscending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("ASCENDING"); final boolean isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right"); final boolean flipLUT = flipToSARGeometry && ((isAscending && !isAntennaPointingRight) || (!isAscending && isAntennaPointingRight)); final File sigmaLUT = new File(folder, lutsigma + ".xml"); final File gammaLUT = new File(folder, lutgamma + ".xml"); final File betaLUT = new File(folder, lutbeta + ".xml"); final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product); readCalibrationLUT(sigmaLUT, lutsigma, origProdRoot, flipLUT); readCalibrationLUT(gammaLUT, lutgamma, origProdRoot, flipLUT); readCalibrationLUT(betaLUT, lutbeta, origProdRoot, flipLUT); } private static void readCalibrationLUT( final File file, final String lutName, final MetadataElement root, final boolean flipLUT) throws IOException { if (!file.exists()) return; final org.jdom.Document xmlDoc = XMLSupport.LoadXML(file.getAbsolutePath()); final Element rootElement = xmlDoc.getRootElement(); final Element offsetElem = rootElement.getChild("offset"); final double offset = Double.parseDouble(offsetElem.getValue()); final Element gainsElem = rootElement.getChild("gains"); double[] gainsArray = StringUtils.toDoubleArray(gainsElem.getValue().trim(), " "); if (flipLUT) { double tmp; for (int i = 0; i < gainsArray.length / 2; i++) { tmp = gainsArray[i]; gainsArray[i] = gainsArray[gainsArray.length - i - 1]; gainsArray[gainsArray.length - i - 1] = tmp; } } final MetadataElement lut = new MetadataElement(lutName); root.addElement(lut); final MetadataAttribute offsetAttrib = new MetadataAttribute("offset", ProductData.TYPE_FLOAT64); offsetAttrib.getData().setElemDouble(offset); lut.addAttribute(offsetAttrib); final MetadataAttribute gainsAttrib = new MetadataAttribute("gains", ProductData.TYPE_FLOAT64, gainsArray.length); gainsAttrib.getData().setElems(gainsArray); lut.addAttribute(gainsAttrib); } /** {@inheritDoc} */ @Override protected void readBandRasterDataImpl( int sourceOffsetX, int sourceOffsetY, int sourceWidth, int sourceHeight, int sourceStepX, int sourceStepY, Band destBand, int destOffsetX, int destOffsetY, int destWidth, int destHeight, ProductData destBuffer, ProgressMonitor pm) throws IOException { final ImageIOFile.BandInfo bandInfo = dataDir.getBandInfo(destBand); if (bandInfo != null && bandInfo.img != null) { if (isAscending) { readAscendingRasterBand( sourceOffsetX, sourceOffsetY, sourceStepX, sourceStepY, destBuffer, destOffsetX, destOffsetY, destWidth, destHeight, 0, bandInfo.img, bandInfo.bandSampleOffset, isAntennaPointingRight); } else { readDescendingRasterBand( sourceOffsetX, sourceOffsetY, sourceStepX, sourceStepY, destBuffer, destOffsetX, destOffsetY, destWidth, destHeight, 0, bandInfo.img, bandInfo.bandSampleOffset, isAntennaPointingRight); } } } public void readAscendingRasterBand( final int sourceOffsetX, final int sourceOffsetY, final int sourceStepX, final int sourceStepY, final ProductData destBuffer, final int destOffsetX, final int destOffsetY, final int destWidth, final int destHeight, final int imageID, final ImageIOFile img, final int bandSampleOffset, final boolean isAntennaPointingRight) throws IOException { final Raster data; synchronized (dataDir) { final ImageReader reader = img.getReader(); final ImageReadParam param = reader.getDefaultReadParam(); param.setSourceSubsampling( sourceStepX, sourceStepY, sourceOffsetX % sourceStepX, sourceOffsetY % sourceStepY); final RenderedImage image = reader.readAsRenderedImage(0, param); if (flipToSARGeometry) { if (isAntennaPointingRight) { // flip the image up side down data = image.getData( new Rectangle( destOffsetX, img.getSceneHeight() - destOffsetY - destHeight, destWidth, destHeight)); } else { // flip the image upside down, then flip it left to right data = image.getData( new Rectangle( img.getSceneWidth() - destOffsetX - destWidth, img.getSceneHeight() - destOffsetY - destHeight, destWidth, destHeight)); } } else { data = image.getData(new Rectangle(destOffsetX, destOffsetY, destWidth, destHeight)); } } final DataBuffer dataBuffer = data.getDataBuffer(); final SampleModel sampleModel = data.getSampleModel(); final int sampleOffset = imageID + bandSampleOffset; if (flipToSARGeometry) { final int[] dArray = new int[destWidth * destHeight]; sampleModel.getSamples( 0, 0, destWidth, destHeight, imageID + bandSampleOffset, dArray, dataBuffer); int srcStride, destStride; if (isAntennaPointingRight) { // flip the image upside down for (int r = 0; r < destHeight; r++) { srcStride = r * destWidth; destStride = (destHeight - r - 1) * destWidth; for (int c = 0; c < destWidth; c++) { destBuffer.setElemIntAt(destStride + c, dArray[srcStride + c]); } } } else { // flip the image upside down, then flip it left to right for (int r = 0; r < destHeight; r++) { srcStride = r * destWidth; destStride = (destHeight - r) * destWidth; for (int c = 0; c < destWidth; c++) { destBuffer.setElemIntAt(destStride - c - 1, dArray[srcStride + c]); } } } } else { // no flipping is needed sampleModel.getSamples( 0, 0, destWidth, destHeight, sampleOffset, (int[]) destBuffer.getElems(), dataBuffer); } } public void readDescendingRasterBand( final int sourceOffsetX, final int sourceOffsetY, final int sourceStepX, final int sourceStepY, final ProductData destBuffer, final int destOffsetX, final int destOffsetY, final int destWidth, final int destHeight, final int imageID, final ImageIOFile img, final int bandSampleOffset, final boolean isAntennaPointingRight) throws IOException { final Raster data; synchronized (dataDir) { final ImageReader reader = img.getReader(); final ImageReadParam param = reader.getDefaultReadParam(); param.setSourceSubsampling( sourceStepX, sourceStepY, sourceOffsetX % sourceStepX, sourceOffsetY % sourceStepY); final RenderedImage image = reader.readAsRenderedImage(0, param); if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right data = image.getData( new Rectangle( img.getSceneWidth() - destOffsetX - destWidth, destOffsetY, destWidth, destHeight)); } else { data = image.getData(new Rectangle(destOffsetX, destOffsetY, destWidth, destHeight)); } } final DataBuffer dataBuffer = data.getDataBuffer(); final SampleModel sampleModel = data.getSampleModel(); final int sampleOffset = imageID + bandSampleOffset; if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right final int[] dArray = new int[destWidth * destHeight]; sampleModel.getSamples(0, 0, destWidth, destHeight, sampleOffset, dArray, dataBuffer); int srcStride, destStride; for (int r = 0; r < destHeight; r++) { srcStride = r * destWidth; destStride = r * destWidth + destWidth; for (int c = 0; c < destWidth; c++) { destBuffer.setElemIntAt(destStride - c - 1, dArray[srcStride + c]); } } } else { // no flipping is needed sampleModel.getSamples( 0, 0, destWidth, destHeight, sampleOffset, (int[]) destBuffer.getElems(), dataBuffer); } } }