Skip to content

Commit dab7883

Browse files
committed
refactoring, add PixelGeoCoding to subset reader, updated tests
1 parent 180c8cf commit dab7883

File tree

10 files changed

+168
-92
lines changed

10 files changed

+168
-92
lines changed

core/src/main/java/com/bc/fiduceo/reader/slstr/SlstrPixelLocator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class SlstrPixelLocator extends SNAP_PixelLocator {
1010

1111
private final Transform transform;
1212

13-
SlstrPixelLocator(GeoCoding geoCoding, Transform transform) {
13+
public SlstrPixelLocator(GeoCoding geoCoding, Transform transform) {
1414
super(geoCoding);
1515

1616
this.transform = transform;

core/src/main/java/com/bc/fiduceo/reader/slstr/SlstrReader.java

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
import static com.bc.fiduceo.reader.slstr.VariableType.NADIR_1km;
3434
import static com.bc.fiduceo.reader.slstr.VariableType.NADIR_500m;
35+
import static com.bc.fiduceo.reader.slstr.utility.ManifestUtil.getObliqueGridOffset;
3536
import static ucar.ma2.DataType.INT;
3637

3738
public class SlstrReader extends SNAP_Reader {
@@ -118,7 +119,7 @@ public void open(File file) throws IOException {
118119
}
119120
openCached(manifestFile, "Sen3");
120121

121-
final int obliqueGridOffset = getObliqueGridOffset();
122+
final int obliqueGridOffset = getObliqueGridOffset(product.getMetadataRoot());
122123
transformFactory = new TransformFactory(product.getSceneRasterWidth(),
123124
product.getSceneRasterHeight(),
124125
obliqueGridOffset);
@@ -354,37 +355,6 @@ private void setOrbitNodeInfo(AcquisitionInfo acquisitionInfo) {
354355
}
355356
}
356357

357-
private int getObliqueGridOffset() {
358-
final MetadataElement metadataRoot = product.getMetadataRoot();
359-
final MetadataElement manifestElement = metadataRoot.getElement("Manifest");
360-
final MetadataElement metadataElement = manifestElement.getElement("metadataSection");
361-
final MetadataElement productInformationElement = metadataElement.getElement("slstrProductInformation");
362-
363-
int nadirTrackOffset = -1;
364-
int obliqueTrackOffset = -1;
365-
final MetadataElement[] elements = productInformationElement.getElements();
366-
for (final MetadataElement element : elements) {
367-
if (element.getName().equalsIgnoreCase("nadirImageSize")) {
368-
final MetadataAttribute grid = element.getAttribute("grid");
369-
if (grid.getData().getElemString().equalsIgnoreCase("1 km")) {
370-
nadirTrackOffset = ManifestUtil.extractTrackOffset(element);
371-
}
372-
}
373-
if (element.getName().equalsIgnoreCase("obliqueImageSize")) {
374-
final MetadataAttribute grid = element.getAttribute("grid");
375-
if (grid.getData().getElemString().equalsIgnoreCase("1 km")) {
376-
obliqueTrackOffset = ManifestUtil.extractTrackOffset(element);
377-
}
378-
}
379-
}
380-
381-
if (nadirTrackOffset < 0 | obliqueTrackOffset < 0) {
382-
throw new RuntimeException("Unable to extract raster offsets from metadata.");
383-
}
384-
385-
return nadirTrackOffset - obliqueTrackOffset;
386-
}
387-
388358
private void ensureTimingVector() {
389359
if (subs_times == null) {
390360
final MetadataElement metadataRoot = product.getMetadataRoot();

core/src/main/java/com/bc/fiduceo/reader/slstr/utility/ManifestUtil.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,37 @@
55

66
public class ManifestUtil {
77

8-
public static int extractTrackOffset(MetadataElement element) {
8+
public static int getObliqueGridOffset(MetadataElement metadataRoot) {
9+
final MetadataElement manifestElement = metadataRoot.getElement("Manifest");
10+
final MetadataElement metadataElement = manifestElement.getElement("metadataSection");
11+
final MetadataElement productInformationElement = metadataElement.getElement("slstrProductInformation");
12+
13+
int nadirTrackOffset = -1;
14+
int obliqueTrackOffset = -1;
15+
final MetadataElement[] elements = productInformationElement.getElements();
16+
for (final MetadataElement element : elements) {
17+
if (element.getName().equalsIgnoreCase("nadirImageSize")) {
18+
final MetadataAttribute grid = element.getAttribute("grid");
19+
if (grid.getData().getElemString().equalsIgnoreCase("1 km")) {
20+
nadirTrackOffset = ManifestUtil.extractTrackOffset(element);
21+
}
22+
}
23+
if (element.getName().equalsIgnoreCase("obliqueImageSize")) {
24+
final MetadataAttribute grid = element.getAttribute("grid");
25+
if (grid.getData().getElemString().equalsIgnoreCase("1 km")) {
26+
obliqueTrackOffset = ManifestUtil.extractTrackOffset(element);
27+
}
28+
}
29+
}
30+
31+
if (nadirTrackOffset < 0 | obliqueTrackOffset < 0) {
32+
throw new RuntimeException("Unable to extract raster offsets from metadata.");
33+
}
34+
35+
return nadirTrackOffset - obliqueTrackOffset;
36+
}
37+
38+
static int extractTrackOffset(MetadataElement element) {
939
final MetadataAttribute trackOffset = element.getAttribute("trackOffset");
1040
final String trackOffsetString = trackOffset.getData().getElemString();
1141
return Integer.parseInt(trackOffsetString);

core/src/main/java/com/bc/fiduceo/reader/slstr_subset/SlstrRegriddedSubsetReader.java

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,44 @@
88
import com.bc.fiduceo.geometry.LineString;
99
import com.bc.fiduceo.geometry.Polygon;
1010
import com.bc.fiduceo.location.PixelLocator;
11-
import com.bc.fiduceo.location.PixelLocatorFactory;
1211
import com.bc.fiduceo.reader.*;
12+
import com.bc.fiduceo.reader.slstr.utility.TransformFactory;
13+
import com.bc.fiduceo.reader.snap.SNAP_PixelLocator;
1314
import com.bc.fiduceo.reader.time.TimeLocator;
1415
import com.bc.fiduceo.reader.time.TimeLocator_MicrosSince2000;
1516
import com.bc.fiduceo.store.FileSystemStore;
1617
import com.bc.fiduceo.store.Store;
1718
import com.bc.fiduceo.store.ZipStore;
1819
import com.bc.fiduceo.util.NetCDFUtils;
1920
import com.bc.fiduceo.util.TimeUtils;
21+
import org.esa.s3tbx.dataio.s3.Manifest;
22+
import org.esa.s3tbx.dataio.s3.XfduManifest;
23+
import org.esa.snap.core.dataio.geocoding.*;
24+
import org.esa.snap.core.dataio.geocoding.forward.PixelForward;
25+
import org.esa.snap.core.dataio.geocoding.inverse.PixelQuadTreeInverse;
26+
import org.esa.snap.core.datamodel.MetadataElement;
2027
import org.esa.snap.core.datamodel.ProductData;
2128
import org.esa.snap.core.util.StringUtils;
29+
import org.w3c.dom.Document;
30+
import org.xml.sax.InputSource;
31+
import org.xml.sax.SAXException;
2232
import ucar.ma2.DataType;
2333
import ucar.ma2.*;
2434
import ucar.nc2.NetcdfFile;
2535
import ucar.nc2.Variable;
2636

37+
import javax.xml.parsers.DocumentBuilderFactory;
38+
import javax.xml.parsers.ParserConfigurationException;
2739
import java.io.File;
2840
import java.io.IOException;
41+
import java.io.StringReader;
2942
import java.text.ParseException;
3043
import java.util.*;
3144
import java.util.regex.Matcher;
3245
import java.util.regex.Pattern;
3346
import java.util.zip.ZipFile;
3447

48+
import static com.bc.fiduceo.reader.slstr.utility.ManifestUtil.getObliqueGridOffset;
3549
import static com.bc.fiduceo.util.NetCDFUtils.scaleIfNecessary;
3650
import static ucar.ma2.DataType.INT;
3751
import static ucar.nc2.NetcdfFiles.openInMemory;
@@ -40,15 +54,16 @@ public class SlstrRegriddedSubsetReader implements Reader {
4054

4155
private final ReaderContext _readerContext;
4256
private final boolean _nadirView;
43-
private final String LONGITUDE_VAR_NAME = "longitude_tx";
44-
private final String LATITUDE_VAR_NAME = "latitude_tx";
57+
private final String LONGITUDE_VAR_NAME = "longitude_in";
58+
private final String LATITUDE_VAR_NAME = "latitude_in";
4559
private TreeMap<String, NetcdfFile> _ncFiles;
4660
private ArrayList<Variable> _variables;
4761
private HashMap<String, Variable> _variablesLUT;
4862
private String _manifest;
4963
private PixelLocator pixelLocator;
5064
private TimeLocator_MicrosSince2000 _timeLocator;
5165
private long[] _timeStamps2000;
66+
private TransformFactory transformFactory;
5267

5368
public SlstrRegriddedSubsetReader(ReaderContext readerContext, boolean nadirView) {
5469
_readerContext = readerContext;
@@ -71,6 +86,21 @@ public void open(File file) throws IOException {
7186
_manifest = new String(store.getBytes(keyManifest.first()));
7287
openNcFiles(store);
7388
initVariables();
89+
90+
final InputSource is = new InputSource(new StringReader(_manifest));
91+
final Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
92+
final Manifest manifest = XfduManifest.createManifest(document);
93+
94+
final MetadataElement metadataRoot = new MetadataElement("root");
95+
metadataRoot.addElement(manifest.getMetadata());
96+
final int obliqueGridOffset = getObliqueGridOffset(metadataRoot);
97+
final Dimension productSize = getProductSize();
98+
99+
transformFactory = new TransformFactory(productSize.getNx() * 2,
100+
productSize.getNy() * 2,
101+
obliqueGridOffset);
102+
} catch (ParserConfigurationException | SAXException e) {
103+
throw new IOException(e.getMessage());
74104
} finally {
75105
store.close();
76106
}
@@ -79,6 +109,7 @@ public void open(File file) throws IOException {
79109
@Override
80110
public void close() throws IOException {
81111
_ncFiles.clear();
112+
transformFactory = null;
82113
}
83114

84115
@Override
@@ -100,8 +131,12 @@ public AcquisitionInfo read() throws IOException {
100131
private void extractGeometries(AcquisitionInfo acquisitionInfo) throws IOException {
101132
final GeometryFactory geometryFactory = _readerContext.getGeometryFactory();
102133
final BoundingPolygonCreator boundingPolygonCreator = new BoundingPolygonCreator(new Interval(250, 250), geometryFactory);
103-
final Array longitude = _variablesLUT.get(LONGITUDE_VAR_NAME).read();
104-
final Array latitude = _variablesLUT.get(LATITUDE_VAR_NAME).read();
134+
135+
final Variable lonVariable = _variablesLUT.get(LONGITUDE_VAR_NAME);
136+
final Array longitude = NetCDFUtils.readAndScaleIfNecessary(lonVariable);
137+
final Variable latVariable = _variablesLUT.get(LATITUDE_VAR_NAME);
138+
final Array latitude = NetCDFUtils.readAndScaleIfNecessary(latVariable);
139+
105140
final Geometry boundingGeometry = boundingPolygonCreator.createBoundingGeometry(longitude, latitude);
106141
if (!boundingGeometry.isValid()) {
107142
throw new RuntimeException("Detected invalid bounding geometry");
@@ -147,10 +182,24 @@ public String getRegEx() {
147182
@Override
148183
public PixelLocator getPixelLocator() throws IOException {
149184
if (pixelLocator == null) {
150-
final Array longitude = _variablesLUT.get(LONGITUDE_VAR_NAME).read();
151-
final Array latitude = _variablesLUT.get(LATITUDE_VAR_NAME).read();
185+
final Variable lonVariable = _variablesLUT.get(LONGITUDE_VAR_NAME);
186+
final Array longitude = NetCDFUtils.readAndScaleIfNecessary(lonVariable);
187+
final Variable latVariable = _variablesLUT.get(LATITUDE_VAR_NAME);
188+
final Array latitude = NetCDFUtils.readAndScaleIfNecessary(latVariable);
152189
final int[] shape = latitude.getShape();
153-
pixelLocator = PixelLocatorFactory.getSwathPixelLocator(longitude, latitude, shape[1], shape[0]);
190+
191+
final GeoRaster geoRaster = new GeoRaster((double[]) longitude.get1DJavaArray(DataType.DOUBLE),
192+
(double[]) latitude.get1DJavaArray(DataType.DOUBLE),
193+
LONGITUDE_VAR_NAME, LATITUDE_VAR_NAME,
194+
shape[1], shape[0], shape[1], shape[0],
195+
1.0, 0.5, 0.5, 1.0, 1.0);
196+
197+
final ForwardCoding forward = ComponentFactory.getForward(PixelForward.KEY);
198+
final InverseCoding inverse = ComponentFactory.getInverse(PixelQuadTreeInverse.KEY);
199+
final ComponentGeoCoding componentGeoCoding = new ComponentGeoCoding(geoRaster, forward, inverse, GeoChecks.ANTIMERIDIAN);
200+
componentGeoCoding.initialize();
201+
202+
pixelLocator = new SNAP_PixelLocator(componentGeoCoding);
154203
}
155204
return pixelLocator;
156205
}

core/src/test/java/com/bc/fiduceo/TestData.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public class TestData {
107107
public static final String SLSTR_S3A_GEOMETRY = "POLYGON((169.3240509033203 83.7747802734375,169.69239807128906 82.9089126586914,169.9518280029297 82.0425796508789,170.1349639892578 81.17589569091797,170.2621612548828 80.30894470214844,170.34710693359375 79.44176483154297,170.39923095703128 78.57439422607422,170.4256134033203 77.70684814453125,170.43130493164062 76.83914184570312,170.4200897216797 75.9712905883789,170.3948211669922 75.1032943725586,170.3578643798828 74.23516845703125,170.31150817871094 73.37557983398438,-150.1357879638672 68.54389953613281,-148.5464630126953 69.24473571777344,-146.85427856445312 69.93047332763672,-145.05076599121094 70.59950256347656,-143.12680053710938 71.24998474121094,-141.07395935058594 71.88002014160156,-138.88314819335938 72.48741149902344,-136.5452117919922 73.06970977783203,-134.0511932373047 73.62413787841797,-131.3943328857422 74.14793395996094,-128.56874084472656 74.63796997070312,-125.5705108642578 75.09088134765625,-122.4310836791992 75.49915313720703,169.3240509033203 83.7747802734375))";
108108
public static final String SLSTR_S3A_AXIS_GEOMETRY = "LINESTRING(-141.54843139648438 81.09320831298828,-145.39883422851562 80.44935607910156,-148.76324462890625 79.76988983154297,-151.71571350097656 79.06163024902344,-154.31826782226562 78.32980346679688,-156.62396240234375 77.57853698730469,-158.6761016845703 76.81105041503906,-160.51385498046878 76.03009033203125,-162.16822814941406 75.23777770996094,-163.66510009765625 74.43582153320312,-165.0253143310547 73.6255874633789,-166.26788330078125 72.80826568603516,-167.39700317382812 71.9930648803711)";
109109

110-
public static final String SLSTR_S3A_SUBSET_GEOMETRY_NADIR = "POLYGON((-3.6059465890532283 -25.83171070667771,-4.345504921512899 -23.67864966189537,-5.052072612521223 -21.520252164726024,-5.728582321482214 -19.357061619885766,-6.37765716254036 -17.189568690832207,-6.876289272507739 -15.461472451383527,-9.12879558299108 -16.049479602572756,-11.394288612408165 -16.61363566749959,-13.672762795816437 -17.152907111528886,-15.964104321709264 -17.666325891819774,-18.268145294360917 -18.152904337946932,-20.57531176627247 -18.60994342420135,-20.10950018672568 -20.816586841507654,-19.64196757071521 -23.022254278473003,-19.17169653558319 -25.22683658674446,-18.6975794442004 -27.430220475843065,-18.316647922477475 -29.183193062900383,-15.802946517978485 -28.735338550717177,-13.311672466783627 -28.241151165591027,-10.844300390148879 -27.70193352839235,-8.402016394859132 -27.11917511036397,-5.985816523722878 -26.494335474052875,-3.6059465890532283 -25.83171070667771))";
110+
public static final String SLSTR_S3A_SUBSET_GEOMETRY_NADIR = "POLYGON((-3.605947 -25.831709,-4.345505 -23.678649999999998,-5.052073 -21.520253000000004,-5.7285819999999985 -19.357061,-6.377657 -17.189569,-6.876289 -15.461471999999999,-9.131362 -16.047251000000003,-11.394941 -16.607987999999995,-13.671509 -17.155166,-15.968603 -17.663905,-18.269608 -18.157285999999996,-20.575312 -18.609944000000002,-20.109500000000004 -20.816586999999995,-19.641969 -23.022255,-19.171696999999998 -25.226836000000002,-18.697578999999998 -27.430221,-18.316648999999998 -29.183193000000003,-15.807929999999999 -28.733388,-13.315321999999998 -28.243854999999993,-10.84056 -27.702752999999998,-8.400936999999999 -27.118316000000004,-5.984294 -26.500103000000006,-3.605947 -25.831709))";
111111
public static final String SLSTR_S3A_SUBSET_GEOMETRY_OBLIQUE = "POLYGON((-8.878673644279557 -27.236764407917907,-9.53544928644125 -25.04967680985631,-10.168283586553411 -22.85918001143884,-10.77966001357282 -20.665598368117607,-11.371805324633522 -18.469237570892084,-11.830750577579213 -16.719139725495783,-14.111707091253587 -17.25351940512691,-16.405503939106993 -17.761861031693723,-18.711951540661282 -18.243180789270152,-20.092489043445035 -18.516825426872682,-19.619832834325003 -20.72437811748543,-19.144536603427568 -22.930904108536893,-18.665514146303046 -25.136288353275976,-18.18158387263854 -27.340416146148723,-17.792023457963918 -29.09393425591276,-15.282864211399815 -28.6363146380642,-12.796449865715998 -28.132648799227454,-10.334198582889915 -27.584267693764158,-8.878673644279557 -27.236764407917907))";
112112

113113
public static final String MYD012KM_AQ_GEOMETRY = "POLYGON((-120.74213409423832 68.62024688720705,-120.30563354492188 70.80646514892578,-119.72577667236328 72.99201202392578,-118.85693359375001 75.1676025390625,-117.59951782226565 77.33758544921875,-115.6713638305664 79.48979949951172,-112.61078643798828 81.6218948364258,-107.26968383789062 83.70146942138672,-96.62190246582033 85.66376495361328,-94.63011932373047 85.88507080078125,-176.4346160888672 85.02908325195312,167.89881896972656 82.63666534423828,161.38035583496094 80.52845001220703,156.9112091064453 78.12504577636719,152.57432556152344 74.17381286621094,150.42385864257812 71.04139709472656,157.0630340576172 70.52552032470703,163.29258728027344 69.77429962158203,169.0470428466797 68.82127380371094,174.27406311035156 67.68644714355469,178.98196411132812 66.39373779296875,-176.81396484375 64.96495056152344,-173.0399169921875 63.432212829589844,-169.67312622070312 61.80479812622071,-169.29559326171875 61.602462768554695,-158.47267150878906 65.08183288574219,-152.23338317871094 66.42942810058594,-146.80239868164062 67.30343627929688,-140.41331481933594 68.03364562988281,-129.48439025878906 68.64893341064453,-120.74213409423832 68.62024688720705))";

core/src/test/java/com/bc/fiduceo/reader/slstr/utility/ManifestUtilTest.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,29 @@
33
import org.esa.snap.core.datamodel.MetadataAttribute;
44
import org.esa.snap.core.datamodel.MetadataElement;
55
import org.esa.snap.core.datamodel.ProductData;
6+
import org.junit.Before;
67
import org.junit.Test;
78

89
import static org.junit.Assert.assertEquals;
10+
import static org.junit.Assert.fail;
911

1012
public class ManifestUtilTest {
1113

14+
private MetadataElement root;
15+
private MetadataElement productInformation;
16+
17+
@Before
18+
public void setUp() {
19+
root = new MetadataElement("root");
20+
final MetadataElement manifest = new MetadataElement("Manifest");
21+
final MetadataElement metadataSection = new MetadataElement("metadataSection");
22+
productInformation = new MetadataElement("slstrProductInformation");
23+
24+
metadataSection.addElement(productInformation);
25+
manifest.addElement(metadataSection);
26+
root.addElement(manifest);
27+
}
28+
1229
@Test
1330
public void testExtractTrackOffset() {
1431
final MetadataElement element = new MetadataElement("whatever");
@@ -17,4 +34,34 @@ public void testExtractTrackOffset() {
1734
final int offset = ManifestUtil.extractTrackOffset(element);
1835
assertEquals(235, offset);
1936
}
37+
38+
@Test
39+
public void testGetObliqueGridOffset_missingElements() {
40+
try {
41+
ManifestUtil.getObliqueGridOffset(root);
42+
fail("RuntimeException expected");
43+
} catch (RuntimeException expected) {
44+
}
45+
}
46+
47+
@Test
48+
public void testGetObliqueGridOffset() {
49+
final MetadataElement nadirImageSize = new MetadataElement("nadirImageSize");
50+
MetadataAttribute gridAttribute = new MetadataAttribute("grid", new ProductData.ASCII("1 km"), true);
51+
nadirImageSize.addAttribute(gridAttribute);
52+
MetadataAttribute nadirOffsetAttribute = new MetadataAttribute("trackOffset", new ProductData.ASCII("550"), true);
53+
nadirImageSize.addAttribute(nadirOffsetAttribute);
54+
55+
final MetadataElement obliqueImageSize = new MetadataElement("obliqueImageSize");
56+
gridAttribute = new MetadataAttribute("grid", new ProductData.ASCII("1 km"), true);
57+
obliqueImageSize.addAttribute(gridAttribute);
58+
nadirOffsetAttribute = new MetadataAttribute("trackOffset", new ProductData.ASCII("300"), true);
59+
obliqueImageSize.addAttribute(nadirOffsetAttribute);
60+
61+
productInformation.addElement(nadirImageSize);
62+
productInformation.addElement(obliqueImageSize);
63+
64+
final int offset = ManifestUtil.getObliqueGridOffset(root);
65+
assertEquals(250, offset);
66+
}
2067
}

0 commit comments

Comments
 (0)