diff --git a/pom.xml b/pom.xml
index 2cb672d..69d855c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
com.airbus.snap
snap-novasar-reader
- 1.1.1
+ 1.2.0
nbm
NovaSAR Product Reader
@@ -23,48 +23,102 @@
org.esa.snap
ceres-core
${snap.version}
+
+
+ com.sun
+ tools
+
+
org.esa.snap
ceres-jai
${snap.version}
+
+
+ com.sun
+ tools
+
+
org.esa.snap
ceres-glayer
${snap.version}
+
+
+ com.sun
+ tools
+
+
org.esa.snap
ceres-binio
${snap.version}
+
+
+ com.sun
+ tools
+
+
org.esa.snap
snap-core
${snap.version}
+
+
+ com.sun
+ tools
+
+
org.esa.snap
snap-engine-utilities
${snap.version}
+
+
+ com.sun
+ tools
+
+
org.esa.s1tbx
s1tbx-commons
${s1tbx.version}
+
+
+ com.sun
+ tools
+
+
org.esa.s1tbx
s1tbx-io
${s1tbx.version}
+
+
+ com.sun
+ tools
+
+
junit
junit
- 4.13.1
+ 4.12
+
+
+ com.sun
+ tools
+
+
diff --git a/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductDirectory.java b/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductDirectory.java
index b8f529e..6f62c1c 100644
--- a/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductDirectory.java
+++ b/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductDirectory.java
@@ -58,6 +58,7 @@
import java.util.Set;
import java.util.StringTokenizer;
+
//========================================================================================================================================================================================
// Class to represent a NovaSAR Product Directory
//========================================================================================================================================================================================
@@ -72,6 +73,7 @@ public class NovaSARProductDirectory extends XMLProductDirectory
private static final DateFormat standardDateFormat = ProductData.UTC.createDateFormat("yyyy-MM-dd HH:mm:ss");
+ // doesn't seem to amount to anything, I assume it's part of the RS2 loader that's not included for NovaSAR
private static final boolean flipToSARGeometry = System.getProperty(SystemUtils.getApplicationContextId() + ".flip.to.sar.geometry", "false").equals("true");
private final transient Map polarizationMap = new HashMap<>(4);
@@ -102,7 +104,8 @@ protected void addImageFile(final String imgPath, final MetadataElement newRoot)
{
boolean valid = false;
int dataType = ProductData.TYPE_INT32;
- if (name.startsWith("image")) {
+ // AFAIK, these are the only three names of files which are valid.
+ if (name.equals("image_HH.tif") || name.equals("image_VV.tif") || name.equals("image_HV.tif") || name.equals("image_VH.tif")) {
valid = true;
} else if (name.startsWith("rh") || name.startsWith("rv"))
{
@@ -185,13 +188,19 @@ protected void addBands(final Product product)
{
String bandName;
+ String betaBandName;
boolean real = true;
Band lastRealBand = null;
String unit;
+ final String defStr = AbstractMetadata.NO_METADATA_STRING;
final MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
+ final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
+ final MetadataElement productElem = origProdRoot.getElement("metadata");
final int width = absRoot.getAttributeInt(AbstractMetadata.num_samples_per_line);
final int height = absRoot.getAttributeInt(AbstractMetadata.num_output_lines);
+ final MetadataElement imageGenerationParameters = productElem.getElement("Image_Generation_Parameters");
+ final String radScaling = imageGenerationParameters.getAttributeString("RadiometricScaling");
final Set keys = bandImageFileMap.keySet(); // The set of keys in the map.
for (String key : keys)
@@ -228,7 +237,8 @@ protected void addBands(final Product product)
}
else
{
- ReaderUtils.createVirtualIntensityBand(product, lastRealBand, band, '_' + getPol(imgName));
+ betaBandName = radScaling + "_Intensity_";
+ ReaderUtils.createVirtualIntensityBand(product, lastRealBand, band, betaBandName, getPol(imgName));
}
real = !real;
}
@@ -244,8 +254,11 @@ protected void addBands(final Product product)
product.addBand(band);
bandMap.put(band, new ImageIOFile.BandInfo(band, img, i, b));
-
- SARReader.createVirtualIntensityBand(product, band, '_' + getPol(imgName));
+ betaBandName = radScaling + "_Amplitude_" + getPol(imgName);
+ SARReader.createVirtualIntensityBand(product, band, getPol(imgName));
+ final String snapBandName = "Intensity" + getPol(imgName);
+ Band snapBand = product.getBand(snapBandName);
+ snapBand.setName(betaBandName);
}
}
}
@@ -476,7 +489,7 @@ protected void addAbstractedMetadataHeader(final MetadataElement root) throws IO
// Verify Product Format (e.g. GEOTIFF)
final String pf = imageAttributes.getAttributeString("ProductFormat", defStr);
- verifyProductFormat(pf);
+ // verifyProductFormat(pf); // removed as wasn't really useful
// Extract Number of Lines in Image
AbstractMetadata.setAttribute(absRoot, AbstractMetadata.num_output_lines, imageAttributes.getAttributeInt("NumberOfLinesInImage", defInt));
@@ -756,6 +769,7 @@ protected void addGeoCoding(final Product product)
MetadataElement absRoot = AbstractMetadata.getAbstractedMetadata(product);
final boolean isAscending = absRoot.getAttributeString(AbstractMetadata.PASS).equals("ASCENDING");
+ // final boolean isAscending = false;
final boolean isAntennaPointingRight = absRoot.getAttributeString(AbstractMetadata.antenna_pointing).equals("right");
final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
@@ -795,67 +809,6 @@ protected void addGeoCoding(final Product product)
}
}
- if (flipToSARGeometry)
- {
- float[] flippedLatList = new float[numberOfTiepoints];
- float[] flippedLonList = new float[numberOfTiepoints];
- 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
- { // descending
-
- 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);
@@ -901,6 +854,7 @@ private static void setLatLongMetadata(Product product, TiePointGrid latGrid, Ti
//========================================================================================================================================================================================
// Function to
//========================================================================================================================================================================================
+
@Override
protected void addTiePointGrids(final Product product)
{
@@ -970,11 +924,6 @@ protected void addTiePointGrids(final Product product)
if (i % subSamplingX == 0)
{
int index = k++;
-
- if (!flipToSARGeometry && (isDescending && isAntennaPointingRight || (!isDescending && !isAntennaPointingRight))) {// flip
- index = gridWidth - 1 - index;
- }
-
incidenceAngles[index] = (float) (alpha * Constants.RTOD);
}
@@ -986,6 +935,7 @@ protected void addTiePointGrids(final Product product)
}
float[] incidenceAngleList = new float[gridWidth * gridHeight];
+
for (int j = 0; j < gridHeight; j++)
{
System.arraycopy(incidenceAngles, 0, incidenceAngleList, j * gridWidth, gridWidth);
@@ -1086,11 +1036,7 @@ class coefList
// get slant range time in nanoseconds from range distance in meters
for (int i = 0; i < rangeDist.length; i++)
{
- int index = i;
- if (!flipToSARGeometry && (isDescending && isAntennaPointingRight || !isDescending && !isAntennaPointingRight)) // flip for descending RS2
- index = rangeDist.length - 1 - i;
-
- rangeTime[index] = (float) (rangeDist[i] / Constants.halfLightSpeed * Constants.oneBillion); // in ns
+ rangeTime[i] = (float) (rangeDist[i] / Constants.halfLightSpeed * Constants.oneBillion); // in ns
}
final TiePointGrid slantRangeGrid = new TiePointGrid(OperatorUtils.TPG_SLANT_RANGE_TIME,gridWidth, gridHeight, 0, 0, subSamplingX, subSamplingY, rangeTime);
diff --git a/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductReader.java b/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductReader.java
index 24ee1ea..fb87a83 100644
--- a/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductReader.java
+++ b/src/main/java/com/airbus/snap/dataio/novasar/NovaSARProductReader.java
@@ -57,9 +57,9 @@ public class NovaSARProductReader extends SARReader {
private static final String lutgamma = "lutGamma";
private static final String lutbeta = "lutBeta";
- private boolean isAscending;
- private boolean isAntennaPointingRight;
+ private String polarisation;
+ // Doesn't seem to lead anywhere? Assume only ever returns FALSE
private static final boolean flipToSARGeometry = System.getProperty(SystemUtils.getApplicationContextId() +
".flip.to.sar.geometry", "false").equals("true");
@@ -111,15 +111,14 @@ protected Product readProductNodesImpl() throws IOException {
final Product product = dataDir.createProduct();
final MetadataElement absMeta = AbstractMetadata.getAbstractedMetadata(product);
- isAscending = absMeta.getAttributeString(AbstractMetadata.PASS).equals("ASCENDING");
- isAntennaPointingRight = absMeta.getAttributeString(AbstractMetadata.antenna_pointing).equals("right");
+ polarisation = absMeta.getAttributeString(AbstractMetadata.mds1_tx_rx_polar);
addCalibrationLUT(product);
product.getGcpGroup();
product.setFileLocation(fileFromInput);
product.setProductReader(this);
setQuicklookBandName(product);
- addQuicklook(product, Quicklook.DEFAULT_QUICKLOOK_NAME, getQuicklookFile());
+ addQuicklook(product, Quicklook.DEFAULT_QUICKLOOK_NAME, getQuicklookFile(polarisation));
addPauliQuicklooks(product);
return product;
@@ -133,10 +132,11 @@ private NovaSARProductDirectory createDirectory(final File fileFromInput) {
return new NovaSARProductDirectory(fileFromInput);
}
- private File getQuicklookFile() {
+ private File getQuicklookFile(final String polarisation) {
try {
- if(dataDir.exists(dataDir.getRootFolder() + "BrowseImage.tif")) {
- return dataDir.getFile(dataDir.getRootFolder() + "BrowseImage.tif");
+ final String fname = "QL_image_" + polarisation + ".tif";
+ if(dataDir.exists(dataDir.getRootFolder() + fname)) {
+ return dataDir.getFile(dataDir.getRootFolder() + fname);
}
} catch (IOException e) {
SystemUtils.LOG.severe("Unable to load quicklook " + dataDir.getProductName());
@@ -182,17 +182,14 @@ private static Band[] pauliVirtualBands(final Product product) {
* @throws IOException if can't read lut
*/
private void addCalibrationLUT(final Product product) throws IOException {
-
- final boolean flipLUT = flipToSARGeometry && ((isAscending && !isAntennaPointingRight) || (!isAscending && isAntennaPointingRight));
final MetadataElement origProdRoot = AbstractMetadata.getOriginalProductMetadata(product);
- readCalibrationLUT(lutsigma, origProdRoot, flipLUT);
- readCalibrationLUT(lutgamma, origProdRoot, flipLUT);
- readCalibrationLUT(lutbeta, origProdRoot, flipLUT);
+ readCalibrationLUT(lutsigma, origProdRoot);
+ readCalibrationLUT(lutgamma, origProdRoot);
+ readCalibrationLUT(lutbeta, origProdRoot);
}
- private void readCalibrationLUT(final String lutName, final MetadataElement root,
- final boolean flipLUT) throws IOException {
+ private void readCalibrationLUT(final String lutName, final MetadataElement root) throws IOException {
InputStream is;
if(dataDir.exists(dataDir.getRootFolder() + lutName + ".xml")) {
is = dataDir.getInputStream(dataDir.getRootFolder() + lutsigma + ".xml");
@@ -211,14 +208,6 @@ private void readCalibrationLUT(final String lutName, final MetadataElement root
final Element gainsElem = rootElement.getChild("gains");
final String gainsValue = gainsElem.getValue().trim().replace(" ", " ");
final double[] gainsArray = toDoubleArray(gainsValue, " ");
- if (flipLUT) {
- double tmp;
- for (int i = 0; i < gainsArray.length / 2; i++) {
- tmp = gainsArray[i];
- gainsArray[i] = gainsArray[gainsArray.length - i - 1];
- gainsArray[gainsArray.length - i - 1] = tmp;
- }
- }
final MetadataElement lut = new MetadataElement(lutName);
root.addElement(lut);
@@ -258,154 +247,61 @@ protected void readBandRasterDataImpl(int sourceOffsetX, int sourceOffsetY, int
final ImageIOFile.BandInfo bandInfo = dataDir.getBandInfo(destBand);
if (bandInfo != null && bandInfo.img != null) {
- if (isAscending) {
- readAscendingRasterBand(sourceOffsetX, sourceOffsetY, sourceStepX, sourceStepY,
- destBuffer, destOffsetX, destOffsetY, destWidth, destHeight,
- 0, bandInfo.img, bandInfo.bandSampleOffset, isAntennaPointingRight);
- } else {
- readDescendingRasterBand(sourceOffsetX, sourceOffsetY, sourceStepX, sourceStepY,
- destBuffer, destOffsetX, destOffsetY, destWidth, destHeight,
- 0, bandInfo.img, bandInfo.bandSampleOffset, isAntennaPointingRight);
- }
+ readRasterBand(sourceOffsetX, sourceOffsetY, sourceStepX, sourceStepY,
+ destBuffer, destOffsetX, destOffsetY, destWidth, destHeight,
+ 0, bandInfo.img, bandInfo.bandSampleOffset);
}
}
- private void readAscendingRasterBand(final int sourceOffsetX, final int sourceOffsetY,
- final int sourceStepX, final int sourceStepY,
- final ProductData destBuffer,
- final int destOffsetX, final int destOffsetY,
- final int destWidth, final int destHeight,
- final int imageID, final ImageIOFile img,
- final int bandSampleOffset,
- final boolean isAntennaPointingRight) throws IOException {
+ private void readRasterBand(final int sourceOffsetX, final int sourceOffsetY,
+ final int sourceStepX, final int sourceStepY,
+ final ProductData destBuffer,
+ final int destOffsetX, final int destOffsetY,
+ final int destWidth, final int destHeight,
+ final int imageID, final ImageIOFile img,
+ final int bandSampleOffset) throws IOException {
+ /*
+ This function takes a strip of data and reads it into the result.
+ image.getdata reads from the source data (TIFF in our case) to give the input strip.
+ destbuffer.setElem writes that strip to the output (destination buffer)
+ */
final Raster data;
- synchronized (dataDir) {
- final ImageReader reader = img.getReader();
- final ImageReadParam param = reader.getDefaultReadParam();
- param.setSourceSubsampling(sourceStepX, sourceStepY,
- sourceOffsetX % sourceStepX,
- sourceOffsetY % sourceStepY);
-
- final RenderedImage image = reader.readAsRenderedImage(0, param);
- if (flipToSARGeometry) {
- if (isAntennaPointingRight) { // flip the image up side down
- data = image.getData(new Rectangle(destOffsetX,
- Math.max(0, img.getSceneHeight() - destOffsetY - destHeight),
- destWidth, destHeight));
- } else { // flip the image upside down, then flip it left to right
- data = image.getData(new Rectangle(Math.max(0, img.getSceneWidth() - destOffsetX - destWidth),
- Math.max(0, img.getSceneHeight() - destOffsetY - destHeight),
- destWidth, destHeight));
- }
- } else {
- data = image.getData(new Rectangle(destOffsetX, destOffsetY, destWidth, destHeight));
- }
- }
-
- final int w = data.getWidth();
- final int h = data.getHeight();
- final DataBuffer dataBuffer = data.getDataBuffer();
- final SampleModel sampleModel = data.getSampleModel();
- final int sampleOffset = imageID + bandSampleOffset;
-
- if (flipToSARGeometry) {
- final int[] dArray = new int[dataBuffer.getSize()];
- sampleModel.getSamples(0, 0, w, h, imageID + bandSampleOffset, dArray, dataBuffer);
-
- int srcStride, destStride;
- if (isAntennaPointingRight) { // flip the image upside down
- for (int r = 0; r < h; r++) {
- srcStride = r * w;
- destStride = (h - r - 1) * w;
- for (int c = 0; c < w; c++) {
- destBuffer.setElemIntAt(destStride + c, dArray[srcStride + c]);
- }
- }
- } else { // flip the image upside down, then flip it left to right
- for (int r = 0; r < h; r++) {
- srcStride = r * w;
- destStride = (h - r) * w;
- for (int c = 0; c < w; c++) {
- destBuffer.setElemIntAt(destStride - c - 1, dArray[srcStride + c]);
- }
- }
- }
- } else { // no flipping is needed
- sampleModel.getSamples(0, 0, w, h, sampleOffset, (int[]) destBuffer.getElems(), dataBuffer);
- }
- }
-
- private void readDescendingRasterBand(final int sourceOffsetX, final int sourceOffsetY,
- final int sourceStepX, final int sourceStepY,
- final ProductData destBuffer,
- final int destOffsetX, final int destOffsetY,
- final int destWidth, final int destHeight,
- final int imageID, final ImageIOFile img,
- final int bandSampleOffset,
- final boolean isAntennaPointingRight) throws IOException {
-
- final Raster data;
- try {
- synchronized (dataDir) {
- final ImageReader reader = img.getReader();
- final ImageReadParam param = reader.getDefaultReadParam();
- param.setSourceSubsampling(sourceStepX, sourceStepY,
- sourceOffsetX % sourceStepX,
- sourceOffsetY % sourceStepY);
-
- final RenderedImage image = reader.readAsRenderedImage(0, param);
- if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right
- data = image.getData(new Rectangle(Math.max(0, img.getSceneWidth() - destOffsetX - destWidth),
- destOffsetY, destWidth, destHeight));
- } else {
- data = image.getData(new Rectangle(destOffsetX, destOffsetY, destWidth, destHeight));
- }
- }
-
- final int w = data.getWidth();
- final int h = data.getHeight();
- final DataBuffer dataBuffer = data.getDataBuffer();
- final SampleModel sampleModel = data.getSampleModel();
- final int sampleOffset = imageID + bandSampleOffset;
-
- if(destBuffer.getType() == ProductData.TYPE_FLOAT32) {
- if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right
- final float[] dArray = new float[dataBuffer.getSize()];
- sampleModel.getSamples(0, 0, w, h, sampleOffset, dArray, dataBuffer);
-
- int srcStride, destStride;
- for (int r = 0; r < h; r++) {
- srcStride = r * w;
- destStride = r * w + w;
- for (int c = 0; c < w; c++) {
- destBuffer.setElemFloatAt(destStride - c - 1, dArray[srcStride + c]);
- }
- }
- } else { // no flipping is needed
- sampleModel.getSamples(0, 0, w, h, sampleOffset, (float[]) destBuffer.getElems(), dataBuffer);
- }
- } else {
- if (flipToSARGeometry && isAntennaPointingRight) { // flip the image left to right
- final int[] dArray = new int[dataBuffer.getSize()];
- sampleModel.getSamples(0, 0, w, h, sampleOffset, dArray, dataBuffer);
-
- int srcStride, destStride;
- for (int r = 0; r < h; r++) {
- srcStride = r * w;
- destStride = r * w + w;
- for (int c = 0; c < w; c++) {
- destBuffer.setElemIntAt(destStride - c - 1, dArray[srcStride + c]);
- }
- }
- } else { // no flipping is needed
- sampleModel.getSamples(0, 0, w, h, sampleOffset, (int[]) destBuffer.getElems(), dataBuffer);
- }
- }
- } catch (Exception e) {
+ try {
+ // synchronized block, only one thread can read from the source data at a time (why?)
+ // gets used a lot, subsamples when zoomed out.
+ synchronized (dataDir) {
+ final ImageReader reader = img.getReader();
+ final ImageReadParam param = reader.getDefaultReadParam();
+ param.setSourceSubsampling(sourceStepX, sourceStepY,
+ sourceOffsetX % sourceStepX,
+ sourceOffsetY % sourceStepY);
+
+ final RenderedImage image = reader.readAsRenderedImage(0, param);
+
+ data = image.getData(new Rectangle(destOffsetX,
+ destOffsetY,
+ destWidth, destHeight));
+ }
+
+ final int width = data.getWidth();
+ final int height = data.getHeight();
+ final DataBuffer dataBuffer = data.getDataBuffer();
+ final SampleModel sampleModel = data.getSampleModel();
+ final int sampleOffset = imageID + bandSampleOffset;
+
+ if(destBuffer.getType() == ProductData.TYPE_FLOAT32) {
+ sampleModel.getSamples(0, 0, width, height, sampleOffset, (float[]) destBuffer.getElems(), dataBuffer);
+ } else {
+ sampleModel.getSamples(0, 0, width, height, sampleOffset, (int[]) destBuffer.getElems(), dataBuffer);
+ }
+
+
+ } catch (Exception e) {
e.printStackTrace();
- }
+ // throw e;
+ }
}
-}
+} // End of class definition