/** * 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)); } } }
/** * 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); } }