-
Notifications
You must be signed in to change notification settings - Fork 5
/
WeatherSource.java
134 lines (116 loc) · 5.5 KB
/
WeatherSource.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* © 2021. TU Dortmund University,
* Institute of Energy Systems, Energy Efficiency and Energy Economics,
* Research group Distribution grid planning and operation
*/
package edu.ie3.datamodel.io.source;
import edu.ie3.datamodel.exceptions.SourceException;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueData;
import edu.ie3.datamodel.io.factory.timeseries.TimeBasedWeatherValueFactory;
import edu.ie3.datamodel.models.timeseries.individual.IndividualTimeSeries;
import edu.ie3.datamodel.models.timeseries.individual.TimeBasedValue;
import edu.ie3.datamodel.models.value.WeatherValue;
import edu.ie3.datamodel.utils.Try;
import edu.ie3.util.interval.ClosedInterval;
import java.time.ZonedDateTime;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.locationtech.jts.geom.Point;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Abstract class for WeatherSource by Csv and Sql Data */
public abstract class WeatherSource {
protected static final Logger log = LoggerFactory.getLogger(WeatherSource.class);
protected TimeBasedWeatherValueFactory weatherFactory;
protected Map<Point, IndividualTimeSeries<WeatherValue>> coordinateToTimeSeries;
protected IdCoordinateSource idCoordinateSource;
protected static final String COORDINATE_ID = "coordinateid";
protected WeatherSource(
IdCoordinateSource idCoordinateSource, TimeBasedWeatherValueFactory weatherFactory) {
this.idCoordinateSource = idCoordinateSource;
this.weatherFactory = weatherFactory;
}
/**
* Method to retrieve the fields found in the source.
*
* @param entityClass class of the source
* @return an option for fields found in the source
*/
public abstract <C extends WeatherValue> Optional<Set<String>> getSourceFields(
Class<C> entityClass);
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
public abstract Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval) throws SourceException;
public abstract Map<Point, IndividualTimeSeries<WeatherValue>> getWeather(
ClosedInterval<ZonedDateTime> timeInterval, Collection<Point> coordinates)
throws SourceException;
public abstract Optional<TimeBasedValue<WeatherValue>> getWeather(
ZonedDateTime date, Point coordinate) throws SourceException;
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/**
* Converts a field to value map into TimeBasedWeatherValueData, extracts the coordinate id from
* the field map and uses the {@link IdCoordinateSource} to map it to a point
*
* @param fieldMap the field to value map for one TimeBasedValue
* @return the TimeBasedWeatherValueData
*/
protected Optional<TimeBasedWeatherValueData> toTimeBasedWeatherValueData(
Map<String, String> fieldMap) {
String coordinateValue = fieldMap.remove(COORDINATE_ID);
fieldMap.putIfAbsent("uuid", UUID.randomUUID().toString());
int coordinateId = Integer.parseInt(coordinateValue);
Optional<Point> coordinate = idCoordinateSource.getCoordinate(coordinateId);
if (coordinate.isEmpty()) {
log.warn("Unable to match coordinate ID {} to a point", coordinateId);
return Optional.empty();
}
return Optional.of(new TimeBasedWeatherValueData(fieldMap, coordinate.get()));
}
/**
* Maps a collection of TimeBasedValues into time series for each contained coordinate point
*
* @param timeBasedValues the values to map
* @return a map of coordinate point to time series
*/
protected Map<Point, IndividualTimeSeries<WeatherValue>> mapWeatherValuesToPoints(
Collection<TimeBasedValue<WeatherValue>> timeBasedValues) {
Map<Point, Set<TimeBasedValue<WeatherValue>>> coordinateToValues =
timeBasedValues.stream()
.collect(
Collectors.groupingBy(
timeBasedWeatherValue -> timeBasedWeatherValue.getValue().getCoordinate(),
Collectors.toSet()));
Map<Point, IndividualTimeSeries<WeatherValue>> coordinateToTimeSeriesMap = new HashMap<>();
for (Map.Entry<Point, Set<TimeBasedValue<WeatherValue>>> entry :
coordinateToValues.entrySet()) {
Set<TimeBasedValue<WeatherValue>> values = entry.getValue();
IndividualTimeSeries<WeatherValue> timeSeries = new IndividualTimeSeries<>(null, values);
coordinateToTimeSeriesMap.put(entry.getKey(), timeSeries);
}
return coordinateToTimeSeriesMap;
}
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
/**
* Converts a stream of fields to value map into a TimeBasedValue, removes the "tid"
*
* @param factory TimeBasedWeatherValueFactory
* @param inputStream stream of fields to convert into TimeBasedValues
* @return a list of that TimeBasedValues
*/
public List<TimeBasedValue<WeatherValue>> buildTimeBasedValues(
TimeBasedWeatherValueFactory factory, Stream<Map<String, String>> inputStream)
throws SourceException {
return Try.scanStream(
inputStream.map(
fieldsToAttributes -> {
fieldsToAttributes.remove("tid");
Optional<TimeBasedWeatherValueData> data =
toTimeBasedWeatherValueData(fieldsToAttributes);
return factory.get(data.get());
}),
"TimeBasedValue<WeatherValue>")
.transform(Stream::toList, SourceException::new)
.getOrThrow();
}
}