use of org.esa.snap.core.datamodel.TiePointGrid in project snap-novasar-reader by bcdev.
the class NovaSARProductDirectory method addTiePointGrids.
// ========================================================================================================================================================================================
// Function to
// ========================================================================================================================================================================================
@Override
protected void addTiePointGrids(final Product product) {
final int sourceImageWidth = product.getSceneRasterWidth();
final int sourceImageHeight = product.getSceneRasterHeight();
final int gridWidth = 11;
final int gridHeight = 11;
final int subSamplingX = (int) ((float) sourceImageWidth / (float) (gridWidth - 1));
final int subSamplingY = (int) ((float) sourceImageHeight / (float) (gridHeight - 1));
// WGS 84: equatorial Earth radius in m
double a = Constants.semiMajorAxis;
// WGS 84: polar Earth radius in m
double b = Constants.semiMinorAxis;
// Get slant range to first pixel and pixel spacing
final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
// in m
final double slantRangeToFirstPixel = absRoot.getAttributeDouble(AbstractMetadata.slant_range_to_first_pixel, 0);
// in m
final double rangeSpacing = absRoot.getAttributeDouble(AbstractMetadata.range_spacing, 0);
final boolean srgrFlag = absRoot.getAttributeInt(AbstractMetadata.srgr_flag) != 0;
final boolean isDescending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("DESCENDING");
final boolean isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right");
// Get scene center latitude
final GeoPos sceneCenterPos = product.getSceneGeoCoding().getGeoPos(new PixelPos(sourceImageWidth / 2.0f, sourceImageHeight / 2.0f), null);
// in deg
double sceneCenterLatitude = sceneCenterPos.lat;
// Get near range incidence angle
final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
final MetadataElement origMetaData = origProdRoot.getElement("metadata");
final MetadataElement imageGenerationParameters = origMetaData.getElement("Image_Generation_Parameters");
// Get the Incidence Angle Coefficients string
final String incAngleCoeffs = imageGenerationParameters.getAttributeString("IncAngleCoeffs", defStr);
// Convert it to a tokeniser
StringTokenizer st = new StringTokenizer(incAngleCoeffs);
// Extract the first token substring (which is the near edge incidence angle) as a double
final double nearRangeIncidenceAngle = Double.parseDouble(st.nextToken());
final double alpha1 = nearRangeIncidenceAngle * Constants.DTOR;
final double lambda = sceneCenterLatitude * Constants.DTOR;
final double cos2 = FastMath.cos(lambda) * FastMath.cos(lambda);
final double sin2 = FastMath.sin(lambda) * FastMath.sin(lambda);
final double e2 = (b * b) / (a * a);
final double rt = a * Math.sqrt((cos2 + e2 * e2 * sin2) / (cos2 + e2 * sin2));
final double rt2 = rt * rt;
double groundRangeSpacing;
if (srgrFlag) {
// ground range - so use as is
groundRangeSpacing = rangeSpacing;
} else {
// slant range - so convert to ground range
groundRangeSpacing = rangeSpacing / FastMath.sin(alpha1);
}
// in radians
double deltaPsi = groundRangeSpacing / rt;
final double r1 = slantRangeToFirstPixel;
final double rtPlusH = Math.sqrt(rt2 + r1 * r1 + 2.0 * rt * r1 * FastMath.cos(alpha1));
final double rtPlusH2 = rtPlusH * rtPlusH;
final double theta1 = FastMath.acos((r1 + rt * FastMath.cos(alpha1)) / rtPlusH);
final double psi1 = alpha1 - theta1;
double psi = psi1;
float[] incidenceAngles = new float[gridWidth];
final int n = gridWidth * subSamplingX;
int k = 0;
for (int i = 0; i < n; i++) {
final double ri = Math.sqrt(rt2 + rtPlusH2 - 2.0 * rt * rtPlusH * FastMath.cos(psi));
final double alpha = FastMath.acos((rtPlusH2 - ri * ri - rt2) / (2.0 * ri * rt));
if (i % subSamplingX == 0) {
int index = k++;
incidenceAngles[index] = (float) (alpha * Constants.RTOD);
}
if (!srgrFlag) {
// complex
groundRangeSpacing = rangeSpacing / FastMath.sin(alpha);
deltaPsi = groundRangeSpacing / rt;
}
psi = psi + deltaPsi;
}
float[] incidenceAngleList = new float[gridWidth * gridHeight];
for (int j = 0; j < gridHeight; j++) {
System.arraycopy(incidenceAngles, 0, incidenceAngleList, j * gridWidth, gridWidth);
}
final TiePointGrid incidentAngleGrid = new TiePointGrid(OperatorUtils.TPG_INCIDENT_ANGLE, gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, incidenceAngleList);
incidentAngleGrid.setUnit(Unit.DEGREES);
product.addTiePointGrid(incidentAngleGrid);
// addSlantRangeTime(product, imageGenerationParameters);
}
use of org.esa.snap.core.datamodel.TiePointGrid in project s1tbx by senbox-org.
the class Radarsat2ProductDirectory method addTiePointGrids.
@Override
protected void addTiePointGrids(final Product product) {
final int sourceImageWidth = product.getSceneRasterWidth();
final int sourceImageHeight = product.getSceneRasterHeight();
final int gridWidth = 11;
final int gridHeight = 11;
final int subSamplingX = (int) ((float) sourceImageWidth / (float) (gridWidth - 1));
final int subSamplingY = (int) ((float) sourceImageHeight / (float) (gridHeight - 1));
// WGS 84: equatorial Earth radius in m
double a = Constants.semiMajorAxis;
// WGS 84: polar Earth radius in m
double b = Constants.semiMinorAxis;
// get slant range to first pixel and pixel spacing
final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
// in m
final double slantRangeToFirstPixel = absRoot.getAttributeDouble(AbstractMetadata.slant_range_to_first_pixel, 0);
// in m
final double rangeSpacing = absRoot.getAttributeDouble(AbstractMetadata.range_spacing, 0);
final boolean srgrFlag = absRoot.getAttributeInt(AbstractMetadata.srgr_flag) != 0;
final boolean isDescending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("DESCENDING");
final boolean isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right");
// get scene center latitude
final GeoPos sceneCenterPos = product.getSceneGeoCoding().getGeoPos(new PixelPos(sourceImageWidth / 2.0f, sourceImageHeight / 2.0f), null);
// in deg
double sceneCenterLatitude = sceneCenterPos.lat;
// get near range incidence angle
final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
final MetadataElement productElem = origProdRoot.getElement("product");
final MetadataElement imageGenerationParameters = productElem.getElement("imageGenerationParameters");
final MetadataElement sarProcessingInformation = imageGenerationParameters.getElement("sarProcessingInformation");
final MetadataElement incidenceAngleNearRangeElem = sarProcessingInformation.getElement("incidenceAngleNearRange");
final double nearRangeIncidenceAngle = (float) incidenceAngleNearRangeElem.getAttributeDouble("incidenceAngleNearRange", 0);
final double alpha1 = nearRangeIncidenceAngle * Constants.DTOR;
final double lambda = sceneCenterLatitude * Constants.DTOR;
final double cos2 = FastMath.cos(lambda) * FastMath.cos(lambda);
final double sin2 = FastMath.sin(lambda) * FastMath.sin(lambda);
final double e2 = (b * b) / (a * a);
final double rt = a * Math.sqrt((cos2 + e2 * e2 * sin2) / (cos2 + e2 * sin2));
final double rt2 = rt * rt;
double groundRangeSpacing;
if (srgrFlag) {
// detected
groundRangeSpacing = rangeSpacing;
} else {
groundRangeSpacing = rangeSpacing / FastMath.sin(alpha1);
}
// in radian
double deltaPsi = groundRangeSpacing / rt;
final double r1 = slantRangeToFirstPixel;
final double rtPlusH = Math.sqrt(rt2 + r1 * r1 + 2.0 * rt * r1 * FastMath.cos(alpha1));
final double rtPlusH2 = rtPlusH * rtPlusH;
final double theta1 = FastMath.acos((r1 + rt * FastMath.cos(alpha1)) / rtPlusH);
final double psi1 = alpha1 - theta1;
double psi = psi1;
float[] incidenceAngles = new float[gridWidth];
final int n = gridWidth * subSamplingX;
int k = 0;
for (int i = 0; i < n; i++) {
final double ri = Math.sqrt(rt2 + rtPlusH2 - 2.0 * rt * rtPlusH * FastMath.cos(psi));
final double alpha = FastMath.acos((rtPlusH2 - ri * ri - rt2) / (2.0 * ri * rt));
if (i % subSamplingX == 0) {
int index = k++;
if (!flipToSARGeometry && (isDescending && isAntennaPointingRight || (!isDescending && !isAntennaPointingRight))) {
// flip
index = gridWidth - 1 - index;
}
incidenceAngles[index] = (float) (alpha * Constants.RTOD);
}
if (!srgrFlag) {
// complex
groundRangeSpacing = rangeSpacing / FastMath.sin(alpha);
deltaPsi = groundRangeSpacing / rt;
}
psi = psi + deltaPsi;
}
float[] incidenceAngleList = new float[gridWidth * gridHeight];
for (int j = 0; j < gridHeight; j++) {
System.arraycopy(incidenceAngles, 0, incidenceAngleList, j * gridWidth, gridWidth);
}
final TiePointGrid incidentAngleGrid = new TiePointGrid(OperatorUtils.TPG_INCIDENT_ANGLE, gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, incidenceAngleList);
incidentAngleGrid.setUnit(Unit.DEGREES);
product.addTiePointGrid(incidentAngleGrid);
addSlantRangeTime(product, imageGenerationParameters);
}
use of org.esa.snap.core.datamodel.TiePointGrid in project s1tbx by senbox-org.
the class Radarsat2ProductDirectory method addGeoCoding.
@Override
protected void addGeoCoding(final Product product) {
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 MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
final MetadataElement productElem = origProdRoot.getElement("product");
final MetadataElement imageAttributes = productElem.getElement("imageAttributes");
final MetadataElement geographicInformation = imageAttributes.getElement("geographicInformation");
final MetadataElement geolocationGrid = geographicInformation.getElement("geolocationGrid");
final MetadataElement[] geoGrid = geolocationGrid.getElements();
float[] latList = new float[geoGrid.length];
float[] lngList = new float[geoGrid.length];
int gridWidth = 0, gridHeight = 0;
int i = 0;
for (MetadataElement imageTiePoint : geoGrid) {
final MetadataElement geodeticCoordinate = imageTiePoint.getElement("geodeticCoordinate");
final MetadataElement latitude = geodeticCoordinate.getElement("latitude");
final MetadataElement longitude = geodeticCoordinate.getElement("longitude");
latList[i] = (float) latitude.getAttributeDouble("latitude", 0);
lngList[i] = (float) longitude.getAttributeDouble("longitude", 0);
final MetadataElement imageCoordinate = imageTiePoint.getElement("imageCoordinate");
final double pix = imageCoordinate.getAttributeDouble("pixel", 0);
if (pix == 0) {
if (gridWidth == 0)
gridWidth = i;
++gridHeight;
}
++i;
}
if (flipToSARGeometry) {
float[] flippedLatList = new float[geoGrid.length];
float[] flippedLonList = new float[geoGrid.length];
int is, id;
if (isAscending) {
if (isAntennaPointingRight) {
// flip upside down
for (int r = 0; r < gridHeight; r++) {
is = r * gridWidth;
id = (gridHeight - r - 1) * gridWidth;
for (int c = 0; c < gridWidth; c++) {
flippedLatList[id + c] = latList[is + c];
flippedLonList[id + c] = lngList[is + c];
}
}
} else {
// flip upside down then left to right
for (int r = 0; r < gridHeight; r++) {
is = r * gridWidth;
id = (gridHeight - r) * gridWidth;
for (int c = 0; c < gridWidth; c++) {
flippedLatList[id - c - 1] = latList[is + c];
flippedLonList[id - c - 1] = lngList[is + c];
}
}
}
} else {
if (isAntennaPointingRight) {
// flip left to right
for (int r = 0; r < gridHeight; r++) {
is = r * gridWidth;
id = r * gridWidth + gridWidth;
for (int c = 0; c < gridWidth; c++) {
flippedLatList[id - c - 1] = latList[is + c];
flippedLonList[id - c - 1] = lngList[is + c];
}
}
} else {
// no flipping is needed
flippedLatList = latList;
flippedLonList = lngList;
}
}
latList = flippedLatList;
lngList = flippedLonList;
}
double subSamplingX = (double) (product.getSceneRasterWidth() - 1) / (gridWidth - 1);
double subSamplingY = (double) (product.getSceneRasterHeight() - 1) / (gridHeight - 1);
final TiePointGrid latGrid = new TiePointGrid(OperatorUtils.TPG_LATITUDE, gridWidth, gridHeight, 0.5f, 0.5f, subSamplingX, subSamplingY, latList);
latGrid.setUnit(Unit.DEGREES);
final TiePointGrid lonGrid = new TiePointGrid(OperatorUtils.TPG_LONGITUDE, gridWidth, gridHeight, 0.5f, 0.5f, subSamplingX, subSamplingY, lngList, TiePointGrid.DISCONT_AT_180);
lonGrid.setUnit(Unit.DEGREES);
final TiePointGeoCoding tpGeoCoding = new TiePointGeoCoding(latGrid, lonGrid);
if (product.getTiePointGrid(OperatorUtils.TPG_LATITUDE) == null) {
product.addTiePointGrid(latGrid);
product.addTiePointGrid(lonGrid);
}
setLatLongMetadata(product, latGrid, lonGrid);
if (product.getSceneGeoCoding() == null) {
product.setSceneGeoCoding(tpGeoCoding);
}
}
use of org.esa.snap.core.datamodel.TiePointGrid in project s1tbx by senbox-org.
the class Radarsat2ProductDirectory method addSlantRangeTime.
private void addSlantRangeTime(final Product product, final MetadataElement imageGenerationParameters) {
class coefList {
double utcSeconds = 0.0;
double grOrigin = 0.0;
final List<Double> coefficients = new ArrayList<>();
}
final List<coefList> segmentsArray = new ArrayList<>();
for (MetadataElement elem : imageGenerationParameters.getElements()) {
if (elem.getName().equalsIgnoreCase("slantRangeToGroundRange")) {
final coefList coef = new coefList();
segmentsArray.add(coef);
coef.utcSeconds = ReaderUtils.getTime(elem, "zeroDopplerAzimuthTime", standardDateFormat).getMJD() * 24 * 3600;
coef.grOrigin = elem.getElement("groundRangeOrigin").getAttributeDouble("groundRangeOrigin", 0);
final String coeffStr = elem.getAttributeString("groundToSlantRangeCoefficients", "");
if (!coeffStr.isEmpty()) {
final StringTokenizer st = new StringTokenizer(coeffStr);
while (st.hasMoreTokens()) {
coef.coefficients.add(Double.parseDouble(st.nextToken()));
}
}
}
}
final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
final double lineTimeInterval = absRoot.getAttributeDouble(AbstractMetadata.line_time_interval, 0);
final ProductData.UTC startTime = absRoot.getAttributeUTC(AbstractMetadata.first_line_time, AbstractMetadata.NO_METADATA_UTC);
final double startSeconds = startTime.getMJD() * 24 * 3600;
final double pixelSpacing = absRoot.getAttributeDouble(AbstractMetadata.range_spacing, 0);
final boolean isDescending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("DESCENDING");
final boolean isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right");
final int gridWidth = 11;
final int gridHeight = 11;
final int sceneWidth = product.getSceneRasterWidth();
final int sceneHeight = product.getSceneRasterHeight();
final int subSamplingX = sceneWidth / (gridWidth - 1);
final int subSamplingY = sceneHeight / (gridHeight - 1);
final float[] rangeDist = new float[gridWidth * gridHeight];
final float[] rangeTime = new float[gridWidth * gridHeight];
final coefList[] segments = segmentsArray.toArray(new coefList[segmentsArray.size()]);
int k = 0;
int c = 0;
for (int j = 0; j < gridHeight; j++) {
final double time = startSeconds + (j * lineTimeInterval);
while (c < segments.length && segments[c].utcSeconds < time) ++c;
if (c >= segments.length)
c = segments.length - 1;
final coefList coef = segments[c];
final double GR0 = coef.grOrigin;
final double s0 = coef.coefficients.get(0);
final double s1 = coef.coefficients.get(1);
final double s2 = coef.coefficients.get(2);
final double s3 = coef.coefficients.get(3);
final double s4 = coef.coefficients.get(4);
for (int i = 0; i < gridWidth; i++) {
int x = i * subSamplingX;
final double GR = x * pixelSpacing;
final double g = GR - GR0;
final double g2 = g * g;
// SlantRange = s0 + s1(GR - GR0) + s2(GR-GR0)^2 + s3(GRGR0)^3 + s4(GR-GR0)^4;
rangeDist[k++] = (float) (s0 + s1 * g + s2 * g2 + s3 * g2 * g + s4 * g2 * g2);
}
}
// get slant range time in nanoseconds from range distance in meters
for (int i = 0; i < rangeDist.length; i++) {
int index = i;
if (// flip for descending RS2
!flipToSARGeometry && (isDescending && isAntennaPointingRight || !isDescending && !isAntennaPointingRight))
index = rangeDist.length - 1 - i;
// in ns
rangeTime[index] = (float) (rangeDist[i] / Constants.halfLightSpeed * Constants.oneBillion);
}
final TiePointGrid slantRangeGrid = new TiePointGrid(OperatorUtils.TPG_SLANT_RANGE_TIME, gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, rangeTime);
product.addTiePointGrid(slantRangeGrid);
slantRangeGrid.setUnit(Unit.NANOSECONDS);
}
use of org.esa.snap.core.datamodel.TiePointGrid in project s1tbx by senbox-org.
the class RadarsatProductDirectory method addRSATTiePointGrids.
private void addRSATTiePointGrids(final Product product, final BinaryRecord sceneRec, final BinaryRecord detProcRec) {
final int gridWidth = 11;
final int gridHeight = 11;
final int sceneWidth = product.getSceneRasterWidth();
final int sceneHeight = product.getSceneRasterHeight();
final int subSamplingX = sceneWidth / (gridWidth - 1);
final int subSamplingY = sceneHeight / (gridHeight - 1);
final float[] rangeDist = new float[gridWidth * gridHeight];
final float[] rangeTime = new float[gridWidth * gridHeight];
int k = 0;
for (int j = 0; j < gridHeight; j++) {
final int y = Math.min(j * subSamplingY, sceneHeight - 1);
// meters
final double slantRangeToFirstPixel = imageFiles[0].getSlantRangeToFirstPixel(y);
double slantRangeToMidPixel = imageFiles[0].getSlantRangeToMidPixel(y);
final double slantRangeToLastPixel = imageFiles[0].getSlantRangeToLastPixel(y);
if (slantRangeToMidPixel == 0.0) {
slantRangeToMidPixel = slantRangeToFirstPixel + ((slantRangeToLastPixel - slantRangeToFirstPixel) / 2.0);
}
final double[] polyCoef = computePolynomialCoefficients(slantRangeToFirstPixel, slantRangeToMidPixel, slantRangeToLastPixel, sceneWidth);
for (int i = 0; i < gridWidth; i++) {
final int x = i * subSamplingX;
rangeDist[k++] = (float) (polyCoef[0] + polyCoef[1] * x + polyCoef[2] * x * x);
}
}
// get slant range time in nanoseconds from range distance in meters
for (k = 0; k < rangeDist.length; k++) {
// in ns
rangeTime[k] = (float) ((rangeDist[k] / Constants.halfLightSpeed) * Constants.oneBillion);
}
final TiePointGrid slantRangeGrid = new TiePointGrid(OperatorUtils.TPG_SLANT_RANGE_TIME, gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, rangeTime);
slantRangeGrid.setUnit(Unit.NANOSECONDS);
product.addTiePointGrid(slantRangeGrid);
if (detProcRec == null)
return;
// earth radius
final double r = calculateEarthRadius(sceneRec);
final double eph_orb_data = detProcRec.getAttributeDouble("Ephemeris orbit data1");
// orbital altitude
final double h = eph_orb_data - r;
// incidence angle
final float[] angles = new float[gridWidth * gridHeight];
k = 0;
for (int j = 0; j < gridHeight; j++) {
for (int i = 0; i < gridWidth; i++) {
final double RS = rangeDist[k];
final double a = ((h * h) - (RS * RS) + (2.0 * r * h)) / (2.0 * RS * r);
angles[k] = (float) (FastMath.acos(a) * Constants.RTOD);
k++;
}
}
final TiePointGrid incidentAngleGrid = new TiePointGrid(OperatorUtils.TPG_INCIDENT_ANGLE, gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, angles);
incidentAngleGrid.setUnit(Unit.DEGREES);
product.addTiePointGrid(incidentAngleGrid);
}
Aggregations