/** * Initializes this operator and sets the one and only target product. * * <p>The target product can be either defined by a field of type {@link Product} annotated with * the {@link TargetProduct TargetProduct} annotation or by calling {@link #setTargetProduct} * method. * * <p>The framework calls this method after it has created this operator. Any client code that * must be performed before computation of tile data should be placed here. * * @throws OperatorException If an error occurs during operator initialisation. * @see #getTargetProduct() */ @Override public void initialize() throws OperatorException { try { absRoot = AbstractMetadata.getAbstractedMetadata(sourceProduct); getSourceImageDimension(); getMetadata(); computeSensorPositionsAndVelocities(); createTargetProduct(); if (externalDEMFile == null) { DEMFactory.checkIfDEMInstalled(demName); } DEMFactory.validateDEM(demName, sourceProduct); if (reGridMethod) { computeDEMTraversalSampleInterval(); } else if (orbitMethod) { meta = new SLCImage(absRoot); jOrbit = new Orbit(absRoot, 3); } } catch (Throwable e) { OperatorUtils.catchOperatorException(getId(), e); } }
/** * Get elevation model. * * @throws Exception The exceptions. */ private synchronized void getElevationModel() throws Exception { if (isElevationModelAvailable) return; try { if (externalDEMFile != null) { // if external DEM file is specified by user dem = new FileElevationModel(externalDEMFile, demResamplingMethod, externalDEMNoDataValue); demNoDataValue = externalDEMNoDataValue; demName = externalDEMFile.getPath(); } else { dem = DEMFactory.createElevationModel(demName, demResamplingMethod); demNoDataValue = dem.getDescriptor().getNoDataValue(); } } catch (Throwable t) { t.printStackTrace(); } isElevationModelAvailable = true; }
/** * 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); } }