22
33import com .bc .fiduceo .core .Dimension ;
44import com .bc .fiduceo .core .Interval ;
5+ import com .bc .fiduceo .geometry .GeometryFactory ;
6+ import com .bc .fiduceo .geometry .Point ;
57import com .bc .fiduceo .geometry .Polygon ;
68import com .bc .fiduceo .location .PixelLocator ;
79import com .bc .fiduceo .reader .AcquisitionInfo ;
8- import com .bc .fiduceo .reader .Reader ;
910import com .bc .fiduceo .reader .ReaderContext ;
10- import com .bc .fiduceo .reader .snap .SNAP_PixelLocator ;
11+ import com .bc .fiduceo .reader .ReaderUtils ;
12+ import com .bc .fiduceo .reader .netcdf .NetCDFReader ;
1113import com .bc .fiduceo .reader .time .TimeLocator ;
12- import org . esa . snap . core . datamodel . CrsGeoCoding ;
13- import org .geotools . referencing . CRS ;
14- import org .opengis . referencing . FactoryException ;
15- import org .opengis . referencing . crs . CoordinateReferenceSystem ;
16- import org .opengis . referencing . operation . TransformException ;
14+ import com . bc . fiduceo . util . TimeUtils ;
15+ import org .apache . commons . compress . archivers . tar . TarArchiveEntry ;
16+ import org .apache . commons . compress . archivers . tar . TarArchiveInputStream ;
17+ import org .apache . commons . compress . compressors . gzip . GzipCompressorInputStream ;
18+ import org .esa . snap . core . util . io . FileUtils ;
1719import ucar .ma2 .Array ;
1820import ucar .ma2 .ArrayInt ;
1921import ucar .ma2 .InvalidRangeException ;
2022import ucar .nc2 .Variable ;
2123
22- import java .io .File ;
23- import java .io . IOException ;
24- import java .util .Iterator ;
24+ import java .io .* ;
25+ import java .util . ArrayList ;
26+ import java .util .Calendar ;
2527import java .util .List ;
26- import java .util .Set ;
2728
28- public class SmosL1CDailyGriddedReader implements Reader {
29- public SmosL1CDailyGriddedReader (ReaderContext readerContext ) {
29+ class SmosL1CDailyGriddedReader extends NetCDFReader {
3030
31+ private final ReaderContext readerContext ;
32+
33+ private File productDir ;
34+
35+ SmosL1CDailyGriddedReader (ReaderContext readerContext ) {
36+ this .readerContext = readerContext ;
3137 }
3238
3339 @ Override
3440 public void open (File file ) throws IOException {
35- throw new IllegalStateException ("not implemented" );
41+ if (ReaderUtils .isCompressed (file )) {
42+ final String fileName = FileUtils .getFilenameWithoutExtension (file );
43+ final long millis = System .currentTimeMillis ();
44+ productDir = readerContext .createDirInTempDir (fileName + millis );
45+
46+ try {
47+ final File inputFile = extractFromTar (file );
48+ super .open (inputFile );
49+ } catch (Exception e ) {
50+ throw new IOException (e .getMessage ());
51+ }
52+ } else {
53+ throw new IOException ("Unsupported format, this reader accepts only compressed input (tgz)" );
54+ }
3655 }
3756
3857 @ Override
3958 public void close () throws IOException {
40- throw new IllegalStateException ("not implemented" );
59+ super .close ();
60+ if (productDir != null ) {
61+ readerContext .deleteTempFile (productDir );
62+ productDir = null ;
63+ }
4164 }
4265
4366 @ Override
4467 public AcquisitionInfo read () throws IOException {
45- throw new IllegalStateException ("not implemented" );
68+ final AcquisitionInfo acquisitionInfo = new AcquisitionInfo ();
69+ final Array longitudes = arrayCache .get ("lon" );
70+ final Array latitudes = arrayCache .get ("lat" );
71+
72+ final Polygon polygon = extractPolygonFromMinMax (longitudes , latitudes , readerContext .getGeometryFactory ());
73+ acquisitionInfo .setBoundingGeometry (polygon );
74+
75+ final String location = netcdfFile .getLocation ();
76+ final String filename = FileUtils .getFilenameFromPath (location );
77+ final int [] ymd = extractYearMonthDayFromFilename (filename );
78+ final Calendar utcCalendar = TimeUtils .getUTCCalendar ();
79+ utcCalendar .set (Calendar .YEAR , ymd [0 ]);
80+ utcCalendar .set (Calendar .MONTH , ymd [1 ] - 1 ); // month is zero-based tb 2022-09-15
81+ utcCalendar .set (Calendar .DAY_OF_MONTH , ymd [2 ]);
82+
83+ acquisitionInfo .setSensingStart (utcCalendar .getTime ());
84+
85+ utcCalendar .set (Calendar .HOUR , 23 );
86+ utcCalendar .set (Calendar .MINUTE , 59 );
87+ utcCalendar .set (Calendar .SECOND , 59 );
88+
89+ acquisitionInfo .setSensingStop (utcCalendar .getTime ());
90+
91+ return acquisitionInfo ;
92+ }
93+
94+ // package access for testing only tb 2022-09-15
95+ static Polygon extractPolygonFromMinMax (Array longitudes , Array latitudes , GeometryFactory geometryFactory ) {
96+ int size = (int ) longitudes .getSize ();
97+ final double lonMin = longitudes .getDouble (0 );
98+ final double lonMax = longitudes .getDouble (size - 1 );
99+
100+ size = (int ) latitudes .getSize ();
101+ final double latMin = latitudes .getDouble (0 );
102+ final double latMax = latitudes .getDouble (size - 1 );
103+
104+ final Point ll = geometryFactory .createPoint (lonMin , latMin );
105+ final Point ul = geometryFactory .createPoint (lonMin , latMax );
106+ final Point ur = geometryFactory .createPoint (lonMax , latMax );
107+ final Point lr = geometryFactory .createPoint (lonMax , latMin );
108+ final ArrayList <Point > polygonPoints = new ArrayList <>();
109+ polygonPoints .add (ll );
110+ polygonPoints .add (ul );
111+ polygonPoints .add (ur );
112+ polygonPoints .add (lr );
113+ polygonPoints .add (ll );
114+ return geometryFactory .createPolygon (polygonPoints );
46115 }
47116
48117 @ Override
@@ -67,7 +136,12 @@ public TimeLocator getTimeLocator() throws IOException {
67136
68137 @ Override
69138 public int [] extractYearMonthDayFromFilename (String fileName ) {
70- throw new IllegalStateException ("not implemented" );
139+ final String datePart = fileName .substring (19 , 27 );
140+ final int [] ymd = new int [3 ];
141+ ymd [0 ] = Integer .parseInt (datePart .substring (0 , 4 ));
142+ ymd [1 ] = Integer .parseInt (datePart .substring (4 , 6 ));
143+ ymd [2 ] = Integer .parseInt (datePart .substring (6 , 8 ));
144+ return ymd ;
71145 }
72146
73147 @ Override
@@ -97,11 +171,47 @@ public Dimension getProductSize() throws IOException {
97171
98172 @ Override
99173 public String getLongitudeVariableName () {
100- throw new IllegalStateException ( "not implemented" ) ;
174+ return "lon" ;
101175 }
102176
103177 @ Override
104178 public String getLatitudeVariableName () {
105- throw new IllegalStateException ("not implemented" );
179+ return "lat" ;
180+ }
181+
182+
183+ private File extractFromTar (File file ) throws IOException {
184+ TarArchiveInputStream tarIn = null ;
185+ final int oneMb = 1024 * 1024 ;
186+
187+ try {
188+ final BufferedInputStream inputStream = new BufferedInputStream (new FileInputStream (file ));
189+ final GzipCompressorInputStream gzipIn = new GzipCompressorInputStream (inputStream );
190+ tarIn = new TarArchiveInputStream (gzipIn );
191+
192+ TarArchiveEntry entry ;
193+ while ((entry = (TarArchiveEntry ) tarIn .getNextEntry ()) != null ) {
194+ if (entry .isFile ()) {
195+ if (entry .getName ().endsWith (".DBL.nc" )) {
196+ // uncompress and open
197+ int count ;
198+ byte [] data = new byte [oneMb ];
199+ final File targetFile = new File (productDir , entry .getName ());
200+ FileOutputStream fos = new FileOutputStream (targetFile , false );
201+ try (BufferedOutputStream dest = new BufferedOutputStream (fos , oneMb )) {
202+ while ((count = tarIn .read (data , 0 , oneMb )) != -1 ) {
203+ dest .write (data , 0 , count );
204+ }
205+ }
206+ return targetFile ;
207+ }
208+ }
209+ }
210+ throw new IOException ("No suitable netcdf file found in tar" );
211+ } finally {
212+ if (tarIn != null ) {
213+ tarIn .close ();
214+ }
215+ }
106216 }
107217}
0 commit comments