Mercurial > dive4elements > river
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 : |