Skip to content

Commit 3415518

Browse files
support period 1m etc. in RA requests
1 parent 7f3d60a commit 3415518

File tree

3 files changed

+105
-21
lines changed

3 files changed

+105
-21
lines changed

calvalus-production/src/main/java/com/bc/calvalus/production/cli/CalvalusHadoopParameters.java

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.bc.calvalus.processing.ra.RAConfig;
44
import com.bc.calvalus.processing.ra.RARegions;
5+
import com.bc.calvalus.production.util.DateRangeCalculator;
56
import com.bc.ceres.binding.BindingException;
67
import org.locationtech.jts.geom.Geometry;
78
import org.locationtech.jts.operation.union.CascadedPolygonUnion;
@@ -168,28 +169,32 @@ public String compositingPeriodDateRange(String compositingPeriod) {
168169
}
169170

170171
private String computePeriodialDateRanges(String period, String compositingPeriod, String min, String max) {
171-
StringBuilder accu = new StringBuilder();
172-
Calendar cursor = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
173-
cursor.setTime(dateOf(min));
174-
Calendar end = new GregorianCalendar();
175-
end.setTime(dateOf(max));
176-
int periodDays = Integer.parseInt(period);
177-
int compositingDays = Integer.parseInt(compositingPeriod);
178-
while (! cursor.after(end)) {
179-
if (accu.length() > 0) {
180-
accu.append(",");
181-
}
182-
accu.append('[');
183-
accu.append(dateStringOf(cursor.getTime()));
184-
accu.append(":");
185-
cursor.add(Calendar.DATE, compositingDays - 1);
186-
accu.append(dateStringOf(cursor.getTime()));
187-
accu.append("]");
188-
cursor.add(Calendar.DATE, periodDays - compositingDays + 1);
189-
}
190-
return accu.toString();
172+
return DateRangeCalculator.periodicalDateRanges(min, max, period, compositingPeriod);
191173
}
192174

175+
// private String computePeriodialDateRanges1(String period, String compositingPeriod, String min, String max) {
176+
// StringBuilder accu = new StringBuilder();
177+
// Calendar cursor = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
178+
// cursor.setTime(dateOf(min));
179+
// Calendar end = new GregorianCalendar();
180+
// end.setTime(dateOf(max));
181+
// int periodDays = Integer.parseInt(period);
182+
// int compositingDays = Integer.parseInt(compositingPeriod);
183+
// while (! cursor.after(end)) {
184+
// if (accu.length() > 0) {
185+
// accu.append(",");
186+
// }
187+
// accu.append('[');
188+
// accu.append(dateStringOf(cursor.getTime()));
189+
// accu.append(":");
190+
// cursor.add(Calendar.DATE, compositingDays - 1);
191+
// accu.append(dateStringOf(cursor.getTime()));
192+
// accu.append("]");
193+
// cursor.add(Calendar.DATE, periodDays - compositingDays + 1);
194+
// }
195+
// return accu.toString();
196+
// }
197+
193198
/**
194199
* Function for use in production type translation rules.
195200
* "<parameters> <regionSource>/calvalus/home/martin/region_data/BH.zip</regionSource> <regionSourceAttributeName>HID</regionSourceAttributeName> <goodPixelExpression>pixel_classif_flags.IDEPIX_CLOUD == 0 and pixel_classif_flags.IDEPIX_CLOUD_AMBIGUOUS == 0 and pixel_classif_flags.IDEPIX_CLOUD_BUFFER == 0 and pixel_classif_flags.IDEPIX_CLOUD_SHADOW == 0 and pixel_classif_flags.IDEPIX_SNOW_ICE == 0 and floating_vegetation == 0 and conc_chl &gt; 0.01</goodPixelExpression> <bands> <band> <name>conc_chl</name> <numBins>100</numBins> <min>0</min> <max>100</max> </band> <band> <name>iop_agelb</name> <numBins>15</numBins> <min>0</min> <max>15</max> </band> <band> <name>c2rcc_secchi_depth_3</name> <numBins>15</numBins> <min>0</min> <max>15</max> </band> </bands> <percentiles>90</percentiles> <writePixelValues>true</writePixelValues> <writePerRegion>true</writePerRegion> <writeSeparateHistogram>true</writeSeparateHistogram> </parameters>"

calvalus-production/src/main/java/com/bc/calvalus/production/util/DateRangeCalculator.java

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@
1919
import com.bc.calvalus.commons.DateRange;
2020
import com.bc.calvalus.commons.DateUtils;
2121

22+
import java.text.ParseException;
23+
import java.text.SimpleDateFormat;
2224
import java.util.ArrayList;
2325
import java.util.Calendar;
2426
import java.util.Date;
2527
import java.util.GregorianCalendar;
2628
import java.util.List;
29+
import java.util.TimeZone;
2730
import java.util.regex.Matcher;
2831
import java.util.regex.Pattern;
2932

@@ -46,6 +49,23 @@ public static List<DateRange> fromDateList(Date... dateList) {
4649
return dateRangeList;
4750
}
4851

52+
private static final SimpleDateFormat ISO_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
53+
static {
54+
ISO_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
55+
}
56+
57+
private static String dateStringOf(Date date) {
58+
return ISO_DATE_FORMAT.format(date);
59+
}
60+
61+
private static Date dateOf(String date) {
62+
try {
63+
return ISO_DATE_FORMAT.parse(date);
64+
} catch (ParseException e) {
65+
throw new RuntimeException("failed to parse " + date, e);
66+
}
67+
}
68+
4969
/**
5070
* By default the stepping and compositing periods are given in full days.
5171
* Additional the periods can be specified in weeks (using "w" as suffix),
@@ -56,9 +76,59 @@ public static List<DateRange> fromDateList(Date... dateList) {
5676
* The week containing the 30 Dec is 8 days long to include the 31 Dec, too.
5777
* In leap years the week containing the 28 Feb is 8 days long
5878
* to include the 29 Feb, too.
59-
* If you dont't want this behaviour you can specify 7 days as period instead.
79+
* If you don't want this behaviour you can specify 7 days as period instead.
6080
*
6181
*/
82+
public static String periodicalDateRanges(String min, String max, String steppingPeriodLength, String compositingPeriodLength) {
83+
StringBuilder accu = new StringBuilder();
84+
GregorianCalendar cursor = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
85+
cursor.setTime(dateOf(min));
86+
GregorianCalendar end = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
87+
end.setTime(dateOf(max));
88+
end.add(Calendar.DAY_OF_MONTH, 1);
89+
90+
Period steppingPeriod = parsePeriod(steppingPeriodLength);
91+
Period compositingPeriod = parsePeriod(compositingPeriodLength);
92+
93+
while (true) {
94+
95+
// determine start and end of period
96+
final Date periodStart = cursor.getTime();
97+
compositingPeriod.next(cursor);
98+
cursor.add(Calendar.SECOND, -1);
99+
final Date periodEnd = cursor.getTime();
100+
// check whether end of period exceeds end of overall interval
101+
if (cursor.after(end)) {
102+
break;
103+
}
104+
if (accu.length() > 0) {
105+
accu.append(",");
106+
}
107+
accu.append('[');
108+
accu.append(dateStringOf(periodStart));
109+
accu.append(":");
110+
accu.append(dateStringOf(cursor.getTime()));
111+
accu.append("]");
112+
// proceed by one period length
113+
cursor.setTime(periodStart);
114+
steppingPeriod.next(cursor);
115+
}
116+
return accu.toString();
117+
}
118+
119+
/**
120+
* By default the stepping and compositing periods are given in full days.
121+
* Additional the periods can be specified in weeks (using "w" as suffix),
122+
* month (using "m" as suffix) or years (using "y" as suffix).
123+
* <p>
124+
* The weekly option extends 2 weeks of the year to being 8 days long to
125+
* get a continuous stepping over multiple years.
126+
* The week containing the 30 Dec is 8 days long to include the 31 Dec, too.
127+
* In leap years the week containing the 28 Feb is 8 days long
128+
* to include the 29 Feb, too.
129+
* If you don't want this behaviour you can specify 7 days as period instead.
130+
*
131+
*/
62132
public static List<DateRange> fromMinMax(Date minDate, Date maxDate, String steppingPeriodLength, String compositingPeriodLength) {
63133
List<DateRange> dateRangeList = new ArrayList<>();
64134

calvalus-production/src/test/java/com/bc/calvalus/production/util/DateRangeCalculatorTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,4 +381,13 @@ public void testNext() throws ParseException {
381381
period.next(cal);
382382
assertEquals("2016-03-11", DATE_FORMAT.format(cal.getTime()));
383383
}
384+
385+
@Test
386+
public void testPeriodicalDateRanges() throws ParseException {
387+
String result = DateRangeCalculator.periodicalDateRanges("2020-01-01", "2020-12-31", "1m", "1w");
388+
assertEquals("[2020-01-01:2020-01-07],[2020-02-01:2020-02-07],[2020-03-01:2020-03-07]," +
389+
"[2020-04-01:2020-04-07],[2020-05-01:2020-05-07],[2020-06-01:2020-06-07]," +
390+
"[2020-07-01:2020-07-07],[2020-08-01:2020-08-07],[2020-09-01:2020-09-07]," +
391+
"[2020-10-01:2020-10-07],[2020-11-01:2020-11-07],[2020-12-01:2020-12-07]", result);
392+
}
384393
}

0 commit comments

Comments
 (0)