/** * Perform decomposition for given tile. * * @param targetBand The target band. * @param targetTile The current tile associated with the target band to be computed. * @throws OperatorException If an error occurs during computation of the filtered value. */ public void computeTile(final Band targetBand, final Tile targetTile) { PolBandUtils.PolSourceBand srcBandList = bandMap.get(targetBand); if (!clusterCentersComputed) { computeTerrainClusterCenters(srcBandList, op); } final Rectangle targetRectangle = targetTile.getRectangle(); final int x0 = targetRectangle.x; final int y0 = targetRectangle.y; final int w = targetRectangle.width; final int h = targetRectangle.height; final int maxY = y0 + h; final int maxX = x0 + w; final ProductData targetData = targetTile.getDataBuffer(); final TileIndex trgIndex = new TileIndex(targetTile); // System.out.println("x0 = " + x0 + ", y0 = " + y0 + ", w = " + w + ", h = " + h); for (int y = y0; y < maxY; ++y) { trgIndex.calculateStride(y); for (int x = x0; x < maxX; ++x) { targetData.setElemIntAt(trgIndex.getIndex(x), getOutputClusterIndex(x, y)); } } }
@Override public void computeTile(Band band, Tile targetTile, ProgressMonitor pm) throws OperatorException { ProductData dataBuffer = targetTile.getRawSamples(); Rectangle rectangle = targetTile.getRectangle(); try { productReader.readBandRasterData( band, rectangle.x, rectangle.y, rectangle.width, rectangle.height, dataBuffer, pm); targetTile.setRawSamples(dataBuffer); } catch (IOException e) { throw new OperatorException(e); } }
/** * Called by the framework in order to compute the stack of tiles for the given target bands. * * <p>The default implementation throws a runtime exception with the message "not implemented". * * @param targetTiles The current tiles to be computed for each target band. * @param targetRectangle The area in pixel coordinates to be computed (same for all rasters in * <code>targetRasters</code>). * @param pm A progress monitor which should be used to determine computation cancelation * requests. * @throws OperatorException if an error occurs during computation of the target rasters. */ @Override public void computeTileStack( Map<Band, Tile> targetTiles, Rectangle targetRectangle, ProgressMonitor pm) throws OperatorException { final int x0 = targetRectangle.x; final int y0 = targetRectangle.y; final int w = targetRectangle.width; final int h = targetRectangle.height; // System.out.println("x0 = " + x0 + ", y0 = " + y0 + ", w = " + w + ", h = " + h); double[] tileOverlapPercentage = {0.0, 0.0}; try { if (!isElevationModelAvailable) { getElevationModel(); } computeTileOverlapPercentage(x0, y0, w, h, tileOverlapPercentage); // System.out.println("x0 = " + x0 + ", y0 = " + y0 + ", w = " + w + ", h = " + h + // ", tileOverlapPercentageMin = " + tileOverlapPercentage[0] + // ", tileOverlapPercentageMax = " + tileOverlapPercentage[1]); } catch (Exception e) { throw new OperatorException(e); } final Tile latTile = targetTiles.get(targetProduct.getBand(LATITUDE_BAND_NAME)); final Tile lonTile = targetTiles.get(targetProduct.getBand(LONGITUDE_BAND_NAME)); final ProductData latData = latTile.getDataBuffer(); final ProductData lonData = lonTile.getDataBuffer(); final double[][] latArray = new double[h][w]; final double[][] lonArray = new double[h][w]; for (int r = 0; r < h; r++) { Arrays.fill(latArray[r], noDataValue); Arrays.fill(lonArray[r], noDataValue); } final int ymin = Math.max(y0 - (int) (tileSize * tileOverlapPercentage[1]), 0); final int ymax = y0 + h + (int) (tileSize * Math.abs(tileOverlapPercentage[0])); final int xmax = x0 + w; final PositionData posData = new PositionData(); final GeoPos geoPos = new GeoPos(); try { if (reGridMethod) { final double[] latLonMinMax = new double[4]; computeImageGeoBoundary(x0, xmax, ymin, ymax, latLonMinMax); final double latMin = latLonMinMax[0]; final double latMax = latLonMinMax[1]; final double lonMin = latLonMinMax[2]; final double lonMax = latLonMinMax[3]; final int nLat = (int) ((latMax - latMin) / delLat) + 1; final int nLon = (int) ((lonMax - lonMin) / delLon) + 1; final double[][] tileDEM = new double[nLat + 1][nLon + 1]; double alt; for (int i = 0; i < nLat; i++) { final double lat = latMin + i * delLat; for (int j = 0; j < nLon; j++) { double lon = lonMin + j * delLon; if (lon >= 180.0) { lon -= 360.0; } geoPos.setLocation(lat, lon); alt = dem.getElevation(geoPos); if (alt == demNoDataValue) { continue; } tileDEM[i][j] = alt; if (!getPosition(lat, lon, alt, x0, y0, w, h, posData)) { continue; } final int ri = (int) Math.round(posData.rangeIndex); final int ai = (int) Math.round(posData.azimuthIndex); if (ri < x0 || ri >= x0 + w || ai < y0 || ai >= y0 + h) { continue; } latArray[ai - y0][ri - x0] = lat; lonArray[ai - y0][ri - x0] = lon; } } } else { final double[][] localDEM = new double[ymax - ymin + 2][w + 2]; final TileGeoreferencing tileGeoRef = new TileGeoreferencing(sourceProduct, x0, ymin, w, ymax - ymin); final boolean valid = DEMFactory.getLocalDEM( dem, demNoDataValue, demResamplingMethod, tileGeoRef, x0, ymin, w, ymax - ymin, sourceProduct, true, localDEM); if (!valid) { return; } for (int y = ymin; y < ymax; y++) { final int yy = y - ymin; for (int x = x0; x < xmax; x++) { final int xx = x - x0; double alt = localDEM[yy + 1][xx + 1]; if (alt == demNoDataValue) { continue; } tileGeoRef.getGeoPos(x, y, geoPos); if (!geoPos.isValid()) { continue; } double lat = geoPos.lat; double lon = geoPos.lon; if (lon >= 180.0) { lon -= 360.0; } if (orbitMethod) { double[] latlon = jOrbit.lp2ell(new Point(x + 0.5, y + 0.5), meta); lat = latlon[0] * Constants.RTOD; lon = latlon[1] * Constants.RTOD; alt = dem.getElevation(new GeoPos(lat, lon)); } if (!getPosition(lat, lon, alt, x0, y0, w, h, posData)) { continue; } final int ri = (int) Math.round(posData.rangeIndex); final int ai = (int) Math.round(posData.azimuthIndex); if (ri < x0 || ri >= x0 + w || ai < y0 || ai >= y0 + h) { continue; } latArray[ai - y0][ri - x0] = lat; lonArray[ai - y0][ri - x0] = lon; } } } // todo should replace the following code with Delaunay interpolation final TileIndex trgIndex = new TileIndex(latTile); for (int y = y0; y < y0 + h; y++) { final int yy = y - y0; trgIndex.calculateStride(y); for (int x = x0; x < x0 + w; x++) { final int xx = x - x0; final int index = trgIndex.getIndex(x); if (latArray[yy][xx] == noDataValue) { latData.setElemDoubleAt(index, fillHole(xx, yy, latArray)); } else { latData.setElemDoubleAt(index, latArray[yy][xx]); } if (lonArray[yy][xx] == noDataValue) { lonData.setElemDoubleAt(index, fillHole(xx, yy, lonArray)); } else { lonData.setElemDoubleAt(index, lonArray[yy][xx]); } } } } catch (Throwable e) { OperatorUtils.catchOperatorException(getId(), e); } }
/** * Called by the framework in order to compute a tile for the given target band. * * <p>The default implementation throws a runtime exception with the message "not implemented". * * @param targetBand The target band. * @param targetTile The current tile associated with the target band to be computed. * @param pm A progress monitor which should be used to determine computation cancelation * requests. * @throws OperatorException If an error occurs during computation of the target raster. */ @Override public void computeTile(Band targetBand, Tile targetTile, ProgressMonitor pm) throws OperatorException { try { final Band sourceBand = sourceProduct.getBand(targetBand.getName()); final Tile srcTile = getSourceTile(sourceBand, targetTile.getRectangle()); final Stx stx = sourceBand.getStx(); double origMin = stx.getMinimum(); double origMax = stx.getMaximum(); ScalingType scaling = verifyScaling(targetScaling, dataType); final double newMin = getMin(dataType); final double newMax = getMax(dataType); final double newRange = newMax - newMin; if (origMax <= newMax && origMin >= newMin && sourceBand.getDataType() < ProductData.TYPE_FLOAT32) scaling = ScalingType.NONE; final ProductData srcData = srcTile.getRawSamples(); final ProductData dstData = targetTile.getRawSamples(); final double srcNoDataValue = sourceBand.getNoDataValue(); final double destNoDataValue = targetBand.getNoDataValue(); if (scaling == ScalingType.LINEAR_PEAK_CLIPPED) { final Histogram histogram = new Histogram(stx.getHistogramBins(), origMin, origMax); final int[] bitCounts = histogram.getBinCounts(); double rightPct = 0.025; for (int i = bitCounts.length - 1; i > 0; --i) { if (bitCounts[i] > 10) { rightPct = i / (double) bitCounts.length; break; } } final Range autoStretchRange = histogram.findRange(0.025, rightPct); origMin = autoStretchRange.getMin(); origMax = autoStretchRange.getMax(); } else if (scaling == ScalingType.LINEAR_CLIPPED) { final Histogram histogram = new Histogram(stx.getHistogramBins(), origMin, origMax); final Range autoStretchRange = histogram.findRangeFor95Percent(); origMin = autoStretchRange.getMin(); origMax = autoStretchRange.getMax(); } final double origRange = origMax - origMin; final int numElem = dstData.getNumElems(); double srcValue; for (int i = 0; i < numElem; ++i) { srcValue = srcData.getElemDoubleAt(i); if (srcValue == srcNoDataValue) { dstData.setElemDoubleAt(i, destNoDataValue); } else { if (scaling == ScalingType.NONE) dstData.setElemDoubleAt(i, srcValue); else if (scaling == ScalingType.TRUNC) dstData.setElemDoubleAt(i, truncate(srcValue, newMin, newMax)); else if (scaling == ScalingType.LOGARITHMIC) dstData.setElemDoubleAt(i, logScale(srcValue, origMin, newMin, origRange, newRange)); else { if (srcValue > origMax) srcValue = origMax; if (srcValue < origMin) srcValue = origMin; dstData.setElemDoubleAt(i, scale(srcValue, origMin, newMin, origRange, newRange)); } } } targetTile.setRawSamples(dstData); } catch (Exception e) { throw new OperatorException(e.getMessage()); } }