comparison flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadFacet.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFacet.java@4a1bd43e7aa6
children
comparison
equal deleted inserted replaced
5830:160f53ee0870 5831:bd047b71ab37
1 package org.dive4elements.river.artifacts.model.minfo;
2
3 import org.dive4elements.artifactdatabase.state.Facet;
4
5 import org.dive4elements.artifacts.Artifact;
6 import org.dive4elements.artifacts.CallContext;
7
8 import org.dive4elements.river.artifacts.FLYSArtifact;
9
10 import org.dive4elements.river.artifacts.model.CalculationResult;
11 import org.dive4elements.river.artifacts.model.DataFacet;
12 import org.dive4elements.river.artifacts.model.FacetTypes;
13
14 import org.dive4elements.river.artifacts.states.DefaultState.ComputeType;
15
16 import org.dive4elements.river.model.MeasurementStation;
17
18 import org.dive4elements.river.utils.FLYSUtils;
19
20 import java.util.ArrayList;
21 import java.util.Collections;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.TreeMap;
25
26 import org.apache.log4j.Logger;
27
28
29 /** Facet to access various sediment loads. */
30 public class SedimentLoadFacet
31 extends DataFacet
32 {
33 /** Very own logger. */
34 private static Logger logger = Logger.getLogger(SedimentLoadFacet.class);
35
36 /** Used as tolerance value when fetching measurement stations. */
37 private static double EPSILON = 1e-5;
38
39
40 public SedimentLoadFacet() {
41 }
42
43 public SedimentLoadFacet(int idx, String name, String description,
44 ComputeType type, String stateId, String hash) {
45 super(idx, name, description, type, hash, stateId);
46 }
47
48 public Object getData(Artifact artifact, CallContext context) {
49 logger.debug("Get data for sediment load at index: " + index);
50
51 FLYSArtifact flys = (FLYSArtifact) artifact;
52
53 CalculationResult res = (CalculationResult) flys.compute(context, hash,
54 stateId, type, false);
55
56 Object[] data =
57 (SedimentLoadResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS
58
59 List<MeasurementStation> allStations = FLYSUtils.getRiver(flys).getMeasurementStations();
60 SedimentLoadResult result = data != null && data.length > index ? (SedimentLoadResult)data[index] : null;
61 if (result == null) {
62 return null;
63 }
64
65 List<Double> sortedStarts = new ArrayList<Double>();
66 // Filter stations according to type.
67 List<MeasurementStation> stations = new ArrayList<MeasurementStation>();
68 for (MeasurementStation station: allStations) {
69 if (station.getRange() == null || station.getMeasurementType() == null) {
70 continue;
71 }
72 if (FacetTypes.IS.SEDIMENT_LOAD_NO_FLOAT(this.getName())
73 && station.getMeasurementType().equals("Geschiebe")) {
74 stations.add(station);
75 sortedStarts.add(station.getStation());
76 }
77 else if (!FacetTypes.IS.SEDIMENT_LOAD_NO_FLOAT(this.getName())
78 && station.getMeasurementType().equals("Schwebstoff")) {
79 stations.add(station);
80 sortedStarts.add(station.getStation());
81 }
82 }
83 Collections.sort(sortedStarts);
84
85 // Access data according to type.
86 double[][] sd = getLoadData(result);
87
88 // Sort by km.
89 TreeMap<Double, Double> sortData = new TreeMap<Double,Double>();
90
91 double[] km = sd[0];
92 double[] load = sd[1];
93
94 for (int i = 0 ; i < km.length; i++) {
95 sortData.put(km[i], load[i]);
96 }
97
98 double[][] values = new double[2][];
99 values[0] = new double[km.length*3];
100 values[1] = new double[km.length*3];
101
102 List<double[]> kmWithoutStation = new ArrayList<double[]>();
103
104 // Find station via its station (km).
105 // TODO use a binarySearch instead of linear absdiff approach
106 int i = 0;
107 for (Map.Entry<Double, Double> entry: sortData.entrySet()) {
108 boolean matchFound = false;
109 // For now, ignore overlaps like (B> next A)
110 for (MeasurementStation station: stations) {
111 if (Math.abs(station.getStation() - entry.getKey()) < EPSILON ||
112 station.getRange().containsTolerant(entry.getKey())) {
113 // TODO: In rare cases, two matches can be found.
114 values[0][i*3] = station.getRange().getA().doubleValue() + EPSILON;
115 values[1][i*3] = entry.getValue();
116 values[0][i*3+1] = station.getRange().getB().doubleValue() - EPSILON;
117 values[1][i*3+1] = entry.getValue();
118 values[0][i*3+2] = station.getRange().getB().doubleValue();
119 values[1][i*3+2] = entry.getValue();
120 matchFound = true;
121 }
122 }
123 // Store points without match for later assessment.
124 if (!matchFound) {
125 logger.warn("measurement without station ("+entry.getKey()+")!");
126 }
127 i++;
128 }
129
130 for (int x = 0; x < values[0].length-1; x++) {
131 // Introduce gaps where no data in measurement station.
132 if (Math.abs(values[0][x+1] - values[0][x]) > 3*EPSILON
133 && values[1][x+1] != values[1][x]) {
134 values[0][x] = Double.NaN;
135 values[1][x] = Double.NaN;
136 }
137 }
138
139 return values;
140 }
141
142
143 /** Get data according to type of facet. */
144 private double[][] getLoadData(SedimentLoadResult result) {
145 if (getName().equals(FacetTypes.SEDIMENT_LOAD_SAND))
146 return result.getSandData();
147 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_COARSE))
148 return result.getCoarseData();
149 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_FINEMIDDLE))
150 return result.getFineMiddleData();
151 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_SUSP_SAND))
152 return result.getSuspSandData();
153 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_SUSP_SAND_BED))
154 return result.getSuspSandBedData();
155 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_SUSP_SEDIMENT))
156 return result.getSuspSedimentData();
157 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_TOTAL_LOAD))
158 return result.getTotalLoadData();
159 else if (getName().equals(FacetTypes.SEDIMENT_LOAD_TOTAL))
160 return result.getTotalData();
161 else {
162 logger.error("SedimentLoadFacet " + getName() + " cannot determine data type.");
163 return null;
164 }
165 }
166
167 /** Copy deeply. */
168 @Override
169 public Facet deepCopy() {
170 SedimentLoadFacet copy = new SedimentLoadFacet();
171 copy.set(this);
172 copy.type = type;
173 copy.hash = hash;
174 copy.stateId = stateId;
175 return copy;
176 }
177 }
178 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org