use of org.esa.s1tbx.insar.gpf.support.SARPosition in project s1tbx by senbox-org.
the class RangeDopplerGeocodingOp method createLayoverShadowMask.
private synchronized void createLayoverShadowMask() {
if (isLayoverShadowMaskAvailable)
return;
final Dimension tileSize = new Dimension(sourceImageWidth, 10);
final Rectangle[] tileRectangles = OperatorUtils.getAllTileRectangles(sourceProduct, tileSize, 0);
final StatusProgressMonitor status = new StatusProgressMonitor(StatusProgressMonitor.TYPE.SUBTASK);
status.beginTask("Creating Layover/Shadow Mask... ", tileRectangles.length);
final ThreadExecutor executor = new ThreadExecutor();
layoverShadowMask = new byte[sourceImageHeight][sourceImageWidth];
try {
for (final Rectangle rectangle : tileRectangles) {
final ThreadRunnable worker = new ThreadRunnable() {
@Override
public void process() {
final int x0 = rectangle.x;
final int y0 = rectangle.y;
final int w = rectangle.width;
final int h = rectangle.height;
final int xMax = x0 + w;
final int yMax = y0 + h;
final double[][] localDEM = new double[h + 2][w + 2];
final TileGeoreferencing tileGeoRef = new TileGeoreferencing(sourceProduct, x0, y0, w, h);
try {
final boolean valid = DEMFactory.getLocalDEM(dem, demNoDataValue, demResamplingMethod, tileGeoRef, x0, y0, w, h, sourceProduct, true, localDEM);
if (!valid) {
saveLayoverShadowMask = false;
System.out.println("Cannot create layover/shadow mask due to the absent of DEM");
return;
}
} catch (Throwable e) {
OperatorUtils.catchOperatorException(getId(), e);
}
final SARPosition sarPosition = new SARPosition(firstLineUTC, lastLineUTC, lineTimeInterval, wavelength, rangeSpacing, sourceImageWidth, srgrFlag, nearEdgeSlantRange, nearRangeOnLeft, orbit, srgrConvParams);
sarPosition.setTileConstraints(x0, y0, w, h);
final SARPosition.PositionData posData = new SARPosition.PositionData();
final GeoPos geoPos = new GeoPos();
float[] slrs = new float[w];
float[] elev = new float[w];
float[] azIndex = new float[w];
float[] rgIndex = new float[w];
boolean[] savePixel = new boolean[w];
for (int y = y0; y < yMax; ++y) {
final int yy = y - y0;
Arrays.fill(slrs, 0.0f);
Arrays.fill(elev, 0.0f);
Arrays.fill(azIndex, 0.0f);
Arrays.fill(rgIndex, 0.0f);
Arrays.fill(savePixel, Boolean.FALSE);
for (int x = x0; x < xMax; ++x) {
final int xx = x - x0;
Double alt = localDEM[yy + 1][xx + 1];
if (alt.equals(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;
}
GeoUtils.geo2xyzWGS84(lat, lon, alt, posData.earthPoint);
if (!sarPosition.getPosition(posData))
continue;
int rIndex = (int) posData.rangeIndex;
int aIndex = (int) posData.azimuthIndex;
if (rIndex >= 0 && rIndex < sourceImageWidth && aIndex >= 0 && aIndex < sourceImageHeight) {
azIndex[xx] = (float) posData.azimuthIndex;
rgIndex[xx] = (float) posData.rangeIndex;
slrs[xx] = (float) posData.slantRange;
elev[xx] = computeElevationAngle(posData.slantRange, posData.earthPoint, posData.sensorPos);
savePixel[xx] = true;
} else {
savePixel[xx] = false;
}
}
computeLayoverShadow(x0, y0, w, h, savePixel, slrs, elev, azIndex, rgIndex);
}
}
};
executor.execute(worker);
status.worked(1);
}
executor.complete();
} catch (Throwable e) {
OperatorUtils.catchOperatorException(getId(), e);
} finally {
status.done();
}
isLayoverShadowMaskAvailable = true;
}
use of org.esa.s1tbx.insar.gpf.support.SARPosition in project s1tbx by senbox-org.
the class SARSimulationOp method computeTileStack.
/**
* 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".</p>
*
* @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);
OverlapPercentage tileOverlapPercentage = null;
try {
if (!isElevationModelAvailable) {
getElevationModel();
}
tileOverlapPercentage = computeTileOverlapPercentage(x0, y0, w, h);
} catch (Exception e) {
throw new OperatorException(e);
}
final Tile targetTile = targetTiles.get(targetProduct.getBand(SIMULATED_BAND_NAME));
final ProductData masterBuffer = targetTile.getDataBuffer();
ProductData demBandBuffer = null;
ProductData zeroHeightBandBuffer = null;
ProductData localIncidenceAngleBandBuffer = null;
ProductData layoverShadowMaskBuffer = null;
if (saveDEM) {
demBandBuffer = targetTiles.get(targetProduct.getBand(demBandName)).getDataBuffer();
}
if (saveZeroHeightSimulation) {
zeroHeightBandBuffer = targetTiles.get(targetProduct.getBand(zeroHeightSimulationBandName)).getDataBuffer();
}
if (saveLocalIncidenceAngle) {
localIncidenceAngleBandBuffer = targetTiles.get(targetProduct.getBand(simulatedLocalIncidenceAngleBandName)).getDataBuffer();
}
if (saveLayoverShadowMask) {
layoverShadowMaskBuffer = targetTiles.get(targetProduct.getBand(layoverShadowMaskBandName)).getDataBuffer();
}
final int ymin = Math.max(y0 - (int) (h * tileOverlapPercentage.tileOverlapUp), 0);
final int ymax = Math.min(y0 + h + (int) (h * tileOverlapPercentage.tileOverlapDown), sourceImageHeight);
final int xmin = Math.max(x0 - (int) (w * tileOverlapPercentage.tileOverlapLeft), 0);
final int xmax = Math.min(x0 + w + (int) (w * tileOverlapPercentage.tileOverlapRight), sourceImageWidth);
final SARPosition sarPosition = new SARPosition(firstLineUTC, lastLineUTC, lineTimeInterval, wavelength, rangeSpacing, sourceImageWidth, srgrFlag, nearEdgeSlantRange, nearRangeOnLeft, orbit, srgrConvParams);
sarPosition.setTileConstraints(x0, y0, w, h);
final SARPosition.PositionData posData = new SARPosition.PositionData();
final GeoPos geoPos = new GeoPos();
double[] slrs = null;
double[] elev = null;
double[] azIndex = null;
double[] rgIndex = null;
boolean[] savePixel = null;
try {
if (reGridMethod) {
final double[] latLonMinMax = new double[4];
computeImageGeoBoundary(xmin, 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];
final double[][] neighbourDEM = new double[3][3];
Double alt;
if (saveLayoverShadowMask) {
slrs = new double[nLon];
elev = new double[nLon];
azIndex = new double[nLon];
rgIndex = new double[nLon];
savePixel = new boolean[nLon];
}
for (int i = 0; i < nLat; i++) {
final double lat = latMin + i * delLat;
if (saveLayoverShadowMask) {
Arrays.fill(slrs, 0.0);
Arrays.fill(elev, 0.0);
Arrays.fill(azIndex, 0.0);
Arrays.fill(rgIndex, 0.0);
Arrays.fill(savePixel, Boolean.FALSE);
}
for (int j = 0; j < nLon; j++) {
double lon = lonMin + j * delLon;
if (lon >= 180.0) {
lon -= 360.0;
}
if (saveZeroHeightSimulation) {
alt = 1.0;
} else {
geoPos.setLocation(lat, lon);
alt = dem.getElevation(geoPos);
if (alt.equals(demNoDataValue))
continue;
}
tileDEM[i][j] = alt;
GeoUtils.geo2xyzWGS84(lat, lon, alt, posData.earthPoint);
if (!sarPosition.getPosition(posData))
continue;
final LocalGeometry localGeometry = new LocalGeometry(lat, lon, delLat, delLon, posData.earthPoint, posData.sensorPos);
final double[] localIncidenceAngles = { SARGeocoding.NonValidIncidenceAngle, SARGeocoding.NonValidIncidenceAngle };
int r = 0;
for (int ii = Math.max(0, i - 1); ii <= i + 1; ++ii) {
ii = Math.min(nLat, ii);
int c = 0;
double neighbourLat = latMin + ii * delLat;
for (int jj = Math.max(0, j - 1); jj <= j + 1; ++jj) {
jj = Math.min(nLon, jj);
neighbourDEM[r][c] = tileDEM[ii][jj];
if (neighbourDEM[r][c] == 0) {
if (saveZeroHeightSimulation) {
neighbourDEM[r][c] = 1;
} else {
geoPos.setLocation(neighbourLat, lonMin + jj * delLon);
neighbourDEM[r][c] = dem.getElevation(geoPos);
}
tileDEM[ii][jj] = neighbourDEM[r][c];
}
++c;
}
++r;
}
SARGeocoding.computeLocalIncidenceAngle(localGeometry, demNoDataValue, false, true, false, 0, 0, 0, 0, neighbourDEM, // in degrees
localIncidenceAngles);
if (localIncidenceAngles[1] == SARGeocoding.NonValidIncidenceAngle) {
continue;
}
final double v = computeBackscatteredPower(localIncidenceAngles[1]);
saveSimulatedData(posData.azimuthIndex, posData.rangeIndex, v, x0, y0, w, h, targetTile, masterBuffer);
int idx = 0;
if (saveDEM || saveLocalIncidenceAngle)
idx = targetTile.getDataBufferIndex((int) posData.rangeIndex, (int) posData.azimuthIndex);
if (saveDEM && idx >= 0) {
demBandBuffer.setElemDoubleAt(idx, alt);
}
if (saveZeroHeightSimulation) {
saveSimulatedData(posData.azimuthIndex, posData.rangeIndex, 1, x0, y0, w, h, targetTile, zeroHeightBandBuffer);
}
if (saveLocalIncidenceAngle && idx >= 0) {
localIncidenceAngleBandBuffer.setElemDoubleAt(idx, localIncidenceAngles[1]);
}
if (saveLayoverShadowMask) {
int rIndex = (int) posData.rangeIndex;
int aIndex = (int) posData.azimuthIndex;
if (rIndex >= x0 && rIndex < x0 + w && aIndex >= y0 && aIndex < y0 + h) {
azIndex[j] = posData.azimuthIndex;
rgIndex[j] = posData.rangeIndex;
slrs[j] = posData.slantRange;
elev[j] = computeElevationAngle(posData.slantRange, posData.earthPoint, posData.sensorPos);
savePixel[j] = true;
} else {
savePixel[j] = false;
}
}
}
if (saveLayoverShadowMask) {
computeLayoverShadow(x0, y0, w, h, savePixel, slrs, elev, azIndex, rgIndex, targetTile, layoverShadowMaskBuffer);
}
}
} else {
final int widthExt = xmax - xmin;
final int heightExt = ymax - ymin;
if (saveLayoverShadowMask) {
slrs = new double[widthExt];
elev = new double[widthExt];
azIndex = new double[widthExt];
rgIndex = new double[widthExt];
savePixel = new boolean[widthExt];
}
final double[][] localDEM = new double[heightExt + 2][widthExt + 2];
final TileGeoreferencing tileGeoRef = new TileGeoreferencing(targetProduct, xmin, ymin, widthExt, heightExt);
if (saveZeroHeightSimulation) {
for (double[] aLocalDEM : localDEM) {
Arrays.fill(aLocalDEM, 1);
}
} else {
final boolean valid = DEMFactory.getLocalDEM(dem, demNoDataValue, demResamplingMethod, tileGeoRef, xmin, ymin, widthExt, heightExt, sourceProduct, true, localDEM);
if (!valid)
return;
}
for (int y = ymin; y < ymax; y++) {
final int yy = y - ymin;
if (saveLayoverShadowMask) {
Arrays.fill(slrs, 0.0);
Arrays.fill(elev, 0.0);
Arrays.fill(azIndex, 0.0);
Arrays.fill(rgIndex, 0.0);
Arrays.fill(savePixel, Boolean.FALSE);
}
for (int x = xmin; x < xmax; x++) {
final int xx = x - xmin;
Double alt = localDEM[yy + 1][xx + 1];
if (alt.equals(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));
}
GeoUtils.geo2xyzWGS84(lat, lon, alt, posData.earthPoint);
if (!sarPosition.getPosition(posData))
continue;
final LocalGeometry localGeometry = new LocalGeometry(x, y, tileGeoRef, posData.earthPoint, posData.sensorPos);
final double[] localIncidenceAngles = { SARGeocoding.NonValidIncidenceAngle, SARGeocoding.NonValidIncidenceAngle };
SARGeocoding.computeLocalIncidenceAngle(localGeometry, demNoDataValue, false, true, false, xmin, ymin, x, y, localDEM, // in degrees
localIncidenceAngles);
if (localIncidenceAngles[1] == SARGeocoding.NonValidIncidenceAngle)
continue;
final double v = computeBackscatteredPower(localIncidenceAngles[1]);
saveSimulatedData(posData.azimuthIndex, posData.rangeIndex, v, x0, y0, w, h, targetTile, masterBuffer);
int idx = 0;
if (saveDEM || saveLocalIncidenceAngle)
idx = targetTile.getDataBufferIndex((int) posData.rangeIndex, (int) posData.azimuthIndex);
if (saveDEM && idx >= 0) {
demBandBuffer.setElemDoubleAt(idx, alt);
}
if (saveZeroHeightSimulation) {
saveSimulatedData(posData.azimuthIndex, posData.rangeIndex, 1, x0, y0, w, h, targetTile, zeroHeightBandBuffer);
}
if (saveLocalIncidenceAngle && idx >= 0) {
localIncidenceAngleBandBuffer.setElemDoubleAt(idx, localIncidenceAngles[1]);
}
if (saveLayoverShadowMask) {
int rIndex = (int) posData.rangeIndex;
int aIndex = (int) posData.azimuthIndex;
if (rIndex >= x0 && rIndex < x0 + w && aIndex >= y0 && aIndex < y0 + h) {
azIndex[xx] = posData.azimuthIndex;
rgIndex[xx] = posData.rangeIndex;
slrs[xx] = posData.slantRange;
elev[xx] = computeElevationAngle(posData.slantRange, posData.earthPoint, posData.sensorPos);
savePixel[xx] = true;
} else {
savePixel[xx] = false;
}
}
}
if (saveLayoverShadowMask) {
computeLayoverShadow(x0, y0, w, h, savePixel, slrs, elev, azIndex, rgIndex, targetTile, layoverShadowMaskBuffer);
}
}
}
} catch (Throwable e) {
OperatorUtils.catchOperatorException(getId(), e);
}
}
use of org.esa.s1tbx.insar.gpf.support.SARPosition in project s1tbx by senbox-org.
the class DEMAssistedCoregistrationOp method computeSlavePixPos.
private PixelPos[][] computeSlavePixPos(final int x0, final int y0, final int w, final int h, Metadata slvMetadata) throws Exception {
try {
// Compute lat/lon boundaries for target tile
final double[] latLonMinMax = new double[4];
computeImageGeoBoundary(x0, x0 + w, y0, y0 + h, latLonMinMax);
final double extralat = (latLonMinMax[1] - latLonMinMax[0]) * tileExtensionPercent / 100.0;
final double extralon = (latLonMinMax[3] - latLonMinMax[2]) * tileExtensionPercent / 100.0;
final double latMin = latLonMinMax[0] - extralat;
final double latMax = latLonMinMax[1] + extralat;
final double lonMin = latLonMinMax[2] - extralon;
final double lonMax = latLonMinMax[3] + extralon;
// Compute lat/lon indices in DEM for the boundaries;
final PixelPos upperLeft = dem.getIndex(new GeoPos(latMax, lonMin));
final PixelPos lowerRight = dem.getIndex(new GeoPos(latMin, lonMax));
final int latMaxIdx = (int) Math.floor(upperLeft.getY());
final int latMinIdx = (int) Math.ceil(lowerRight.getY());
final int lonMinIdx = (int) Math.floor(upperLeft.getX());
final int lonMaxIdx = (int) Math.ceil(lowerRight.getX());
final EarthGravitationalModel96 egm = EarthGravitationalModel96.instance();
// Loop through all DEM points bounded by the indices computed above. For each point,
// get its lat/lon and its azimuth/range indices in target image;
final int numLines = latMinIdx - latMaxIdx;
final int numPixels = lonMaxIdx - lonMinIdx;
final double[][] masterAz = new double[numLines][numPixels];
final double[][] masterRg = new double[numLines][numPixels];
final double[][] slaveAz = new double[numLines][numPixels];
final double[][] slaveRg = new double[numLines][numPixels];
final double[][] lat = new double[numLines][numPixels];
final double[][] lon = new double[numLines][numPixels];
final SARPosition mstSARPosition = new SARPosition(mstMetadata.firstLineTime, mstMetadata.lastLineTime, mstMetadata.lineTimeInterval, mstMetadata.wavelength, mstMetadata.rangeSpacing, mstMetadata.sourceImageWidth, mstMetadata.srgrFlag, mstMetadata.nearEdgeSlantRange, mstMetadata.nearRangeOnLeft, mstMetadata.orbit, mstMetadata.srgrConvParams);
final SARPosition slvSARPosition = new SARPosition(slvMetadata.firstLineTime, slvMetadata.lastLineTime, slvMetadata.lineTimeInterval, slvMetadata.wavelength, slvMetadata.rangeSpacing, slvMetadata.sourceImageWidth, slvMetadata.srgrFlag, slvMetadata.nearEdgeSlantRange, slvMetadata.nearRangeOnLeft, slvMetadata.orbit, slvMetadata.srgrConvParams);
final SARPosition.PositionData posData = new SARPosition.PositionData();
final PixelPos pix = new PixelPos();
boolean noValidSlavePixPos = true;
for (int l = 0; l < numLines; l++) {
for (int p = 0; p < numPixels; p++) {
pix.setLocation(lonMinIdx + p, latMaxIdx + l);
GeoPos gp = dem.getGeoPos(pix);
lat[l][p] = gp.lat;
lon[l][p] = gp.lon;
Double alt = dem.getElevation(gp);
if (alt.equals(demNoDataValue)) {
// get corrected elevation for 0
alt = (double) egm.getEGM(gp.lat, gp.lon);
}
GeoUtils.geo2xyzWGS84(gp.lat, gp.lon, alt, posData.earthPoint);
if (mstSARPosition.getPosition(posData)) {
masterAz[l][p] = posData.azimuthIndex;
masterRg[l][p] = posData.rangeIndex;
if (slvSARPosition.getPosition(posData)) {
slaveAz[l][p] = posData.azimuthIndex;
slaveRg[l][p] = posData.rangeIndex;
noValidSlavePixPos = false;
continue;
}
}
masterAz[l][p] = invalidIndex;
masterRg[l][p] = invalidIndex;
}
}
if (noValidSlavePixPos) {
return null;
}
// Compute azimuth/range offsets for pixels in target tile using Delaunay interpolation
final org.jlinda.core.Window tileWindow = new org.jlinda.core.Window(y0, y0 + h - 1, x0, x0 + w - 1);
final double rgAzRatio = mstMetadata.rangeSpacing / mstMetadata.azimuthSpacing;
final double[][] latArray = new double[(int) tileWindow.lines()][(int) tileWindow.pixels()];
final double[][] lonArray = new double[(int) tileWindow.lines()][(int) tileWindow.pixels()];
final double[][] azArray = new double[(int) tileWindow.lines()][(int) tileWindow.pixels()];
final double[][] rgArray = new double[(int) tileWindow.lines()][(int) tileWindow.pixels()];
for (double[] data : azArray) {
Arrays.fill(data, invalidIndex);
}
for (double[] data : rgArray) {
Arrays.fill(data, invalidIndex);
}
TriangleInterpolator.ZData[] dataList = new TriangleInterpolator.ZData[] { new TriangleInterpolator.ZData(slaveAz, azArray), new TriangleInterpolator.ZData(slaveRg, rgArray), new TriangleInterpolator.ZData(lat, latArray), new TriangleInterpolator.ZData(lon, lonArray) };
TriangleInterpolator.gridDataLinear(masterAz, masterRg, dataList, tileWindow, rgAzRatio, 1, 1, invalidIndex, 0);
boolean allElementsAreNull = true;
final PixelPos[][] slavePixelPos = new PixelPos[h][w];
Double alt;
for (int yy = 0; yy < h; yy++) {
for (int xx = 0; xx < w; xx++) {
if (rgArray[yy][xx] == invalidIndex || azArray[yy][xx] == invalidIndex || rgArray[yy][xx] < 0 || rgArray[yy][xx] >= slvMetadata.sourceImageWidth || azArray[yy][xx] < 0 || azArray[yy][xx] >= slvMetadata.sourceImageHeight) {
slavePixelPos[yy][xx] = null;
} else {
if (maskOutAreaWithoutElevation) {
alt = dem.getElevation(new GeoPos(latArray[yy][xx], lonArray[yy][xx]));
if (!alt.equals(demNoDataValue)) {
slavePixelPos[yy][xx] = new PixelPos(rgArray[yy][xx], azArray[yy][xx]);
allElementsAreNull = false;
} else {
slavePixelPos[yy][xx] = null;
}
} else {
slavePixelPos[yy][xx] = new PixelPos(rgArray[yy][xx], azArray[yy][xx]);
allElementsAreNull = false;
}
}
}
}
if (allElementsAreNull) {
return null;
}
return slavePixelPos;
} catch (Throwable e) {
OperatorUtils.catchOperatorException("computeSlavePixPos", e);
}
return null;
}
Aggregations