1313import  java .net .URISyntaxException ;
1414import  java .net .URL ;
1515import  java .time .OffsetDateTime ;
16+ import  java .time .ZoneOffset ;
1617import  java .time .format .DateTimeFormatter ;
1718import  java .time .format .DateTimeParseException ;
1819import  java .util .ArrayList ;
@@ -732,6 +733,10 @@ else if (TEMPORAL_AXIS_LABELS.contains(label)) {
732733                        extent .add (BigDecimal .valueOf (Double .parseDouble (minT )));
733734                        extent .add (BigDecimal .valueOf (Double .parseDouble (maxT )));
734735                    }
736+                     // units of the time dimension 
737+                     if  (label .toUpperCase ().equals (TimeUnit .YEAR .name ())) {
738+                         dim .setUnit (TimeUnit .YEAR .getAbbrv ());
739+                     }
735740                    dim .setExtent (extent );
736741                    cubeDimensions .put (label , dim );
737742                }
@@ -896,15 +901,15 @@ else if (TEMPORAL_AXIS_LABELS.contains(label)) {
896901        // TODO what to put when there is no time axis in the original coverage? 
897902        CollectionTemporalExtent  temporalExtent  = new  CollectionTemporalExtent ();
898903        List <List <OffsetDateTime >> intervals  = new  ArrayList <>();
899- 
904+         List <OffsetDateTime > interval  = new  ArrayList <>();
905+         DateTimeFormatter  fmt  = OffsetDateTimeSerializer .FORMATTER ;
906+         
900907        if  (hasTimeCrs ) {
901908            // 1+ time dimensions: 
902909            for  (DimensionTemporal  dim  : timeDims ) {
903910                String  minT  = dim .getExtent ().get (0 );
904911                String  maxT  = dim .getExtent ().get (1 );
905- 
906-                 List <OffsetDateTime > interval  = new  ArrayList <>();
907-                 DateTimeFormatter  fmt  = OffsetDateTimeSerializer .FORMATTER ;
912+                 
908913                try  {
909914                    //STAC requires format: https://www.rfc-editor.org/rfc/rfc3339#section-5.6 
910915                    interval .add (OffsetDateTime .parse (minT , fmt ));
@@ -917,9 +922,29 @@ else if (TEMPORAL_AXIS_LABELS.contains(label)) {
917922                }
918923
919924                log .debug ("Time interval : "  + interval );
920- 
921925                intervals .add (interval );
922926            }
927+         } else  {
928+             // fetch other dimension with temporal type: 
929+             List <DimensionOther > otherTimeDims  = cubeDimensions .values ().stream ()
930+                     .filter (dim  -> dim  instanceof  DimensionOther )
931+                     .filter (dim  -> TimeUnit .getAllAbbrv ().contains (((DimensionOther )dim ).getUnit ()))
932+                     .map (dim  -> (DimensionOther ) dim )
933+                     .collect (Collectors .toList ());
934+             
935+             switch  (otherTimeDims .size ()) {
936+             case  0 :
937+                 log .warn ("No time dimension found in coverage {}." , coverageID );
938+                 break ;
939+             case  1 :
940+                 DimensionOther  tDim  = otherTimeDims .get (0 );
941+                 interval .addAll (toTimeExtent (tDim ));
942+                 intervals .add (interval );
943+                 break ;
944+             default : 
945+                 log .warn ("Multiple \" other\"  time dimension found." );
946+                 break ;
947+             }
923948        }
924949        temporalExtent .setInterval (intervals );
925950        collectionExtent .setTemporal (temporalExtent );
@@ -1036,18 +1061,26 @@ else if (TEMPORAL_AXIS_LABELS.contains(label)) {
10361061        String  tempStep  = metadataElement .getChildText ("Temporal_Step" , gmlNS );
10371062        if  (null  != tempStep ) {
10381063            if  (!hasTimeCrs ) {
1039-                 log .warn ("Temporal step provided but time axis not found in coverage {}." , coverageID );
1040- 
10411064                // fetch other dimension with temporal type: 
10421065                List <DimensionOther > otherTimeDims  = cubeDimensions .values ().stream ()
10431066                        .filter (dim  -> TypeEnum .TEMPORAL .equals (dim .getType ()))
10441067                        .filter (dim  -> dim  instanceof  DimensionOther )
10451068                        .map (dim  -> (DimensionOther ) dim )
10461069                        .collect (Collectors .toList ()); //Java 9: .toList()); 
1070+                 otherTimeDims .addAll (cubeDimensions .values ().stream ()
1071+                         .filter (dim  -> dim  instanceof  DimensionOther )
1072+                         .filter (dim  -> TimeUnit .getAllAbbrv ().contains (((DimensionOther )dim ).getUnit ()))
1073+                         .map (dim  -> (DimensionOther ) dim )
1074+                         .collect (Collectors .toList ()));
10471075
10481076                for  (DimensionOther  dim  : otherTimeDims ) {
10491077                    dim .setStep (tempStep );
10501078                }
1079+                 
1080+                 if  (otherTimeDims .isEmpty ()) {
1081+                     log .warn ("Temporal step provided but time dimension not found in coverage {}." , coverageID );
1082+                     // (..or heuristic for converting other to time is incomplete) 
1083+                 }
10511084            } else  {
10521085                DimensionTemporal  dim  = timeDims .get (0 );
10531086                dim .setStep (tempStep );
@@ -1364,4 +1397,33 @@ else if (TEMPORAL_AXIS_LABELS.contains(label)) {
13641397
13651398        return  currentCollection ;
13661399    }
1400+ 
1401+     /** 
1402+      * Converts the numeric extent of a dimension of type "other" but 
1403+      * with temporal meaning, to time extent (heuristic). 
1404+      *  
1405+      * @return from/to timestamp of the given time dimension. 
1406+      */ 
1407+     private  static  final  List <OffsetDateTime > toTimeExtent (DimensionOther  dim ) {
1408+         if  (TypeEnum .TEMPORAL  != dim .getType ()) {
1409+             log .warn ("Input dimension is not temporal" );
1410+             //return null; 
1411+             // lenient because if type is TEMPORAL the dimension is serialized as TemporalDim anyway in STAC! 
1412+         }
1413+         
1414+         List <OffsetDateTime > timeExtent  = null ;
1415+         
1416+         if  (dim .getUnit ().equals (TimeUnit .YEAR .getAbbrv ())) {
1417+             int  yFrom  = dim .getExtent ().get (0 ).toBigInteger ().intValue ();
1418+             int  yUntl  = dim .getExtent ().get (1 ).toBigInteger ().intValue ();
1419+             OffsetDateTime  from  = OffsetDateTime .of (yFrom , 1 , 1 , 0 , 0 , 0 , 0 , ZoneOffset .UTC );
1420+             OffsetDateTime  untl  = OffsetDateTime .of (yUntl , 12 , 31 , 23 , 59 , 59 , 0 , ZoneOffset .UTC );
1421+             timeExtent  = Arrays .asList (from , untl );
1422+         } else  {
1423+             log .error ("No time decoding implemented for unit: {}" , dim .getUnit ());
1424+         }
1425+         
1426+         return  timeExtent ;
1427+     }
1428+         
13671429}
0 commit comments