Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFacet.java @ 5788:b5d20b3dab4e
Doc.
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Tue, 23 Apr 2013 10:47:29 +0200 |
parents | 4a1bd43e7aa6 |
children |
line wrap: on
line source
package de.intevation.flys.artifacts.model.minfo; import de.intevation.artifactdatabase.state.Facet; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.CallContext; import de.intevation.flys.artifacts.FLYSArtifact; import de.intevation.flys.artifacts.model.CalculationResult; import de.intevation.flys.artifacts.model.DataFacet; import de.intevation.flys.artifacts.model.FacetTypes; import de.intevation.flys.artifacts.states.DefaultState.ComputeType; import de.intevation.flys.model.MeasurementStation; import de.intevation.flys.utils.FLYSUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.log4j.Logger; /** Facet to access various sediment loads. */ public class SedimentLoadFacet extends DataFacet { /** Very own logger. */ private static Logger logger = Logger.getLogger(SedimentLoadFacet.class); /** Used as tolerance value when fetching measurement stations. */ private static double EPSILON = 1e-5; public SedimentLoadFacet() { } public SedimentLoadFacet(int idx, String name, String description, ComputeType type, String stateId, String hash) { super(idx, name, description, type, hash, stateId); } public Object getData(Artifact artifact, CallContext context) { logger.debug("Get data for sediment load at index: " + index); FLYSArtifact flys = (FLYSArtifact) artifact; CalculationResult res = (CalculationResult) flys.compute(context, hash, stateId, type, false); Object[] data = (SedimentLoadResult[]) res.getData(); // TODO CAST TO SPECIFIC CLASS List<MeasurementStation> allStations = FLYSUtils.getRiver(flys).getMeasurementStations(); SedimentLoadResult result = data != null && data.length > index ? (SedimentLoadResult)data[index] : null; if (result == null) { return null; } List<Double> sortedStarts = new ArrayList<Double>(); // Filter stations according to type. List<MeasurementStation> stations = new ArrayList<MeasurementStation>(); for (MeasurementStation station: allStations) { if (station.getRange() == null || station.getMeasurementType() == null) { continue; } if (FacetTypes.IS.SEDIMENT_LOAD_NO_FLOAT(this.getName()) && station.getMeasurementType().equals("Geschiebe")) { stations.add(station); sortedStarts.add(station.getStation()); } else if (!FacetTypes.IS.SEDIMENT_LOAD_NO_FLOAT(this.getName()) && station.getMeasurementType().equals("Schwebstoff")) { stations.add(station); sortedStarts.add(station.getStation()); } } Collections.sort(sortedStarts); // Access data according to type. double[][] sd = getLoadData(result); // Sort by km. TreeMap<Double, Double> sortData = new TreeMap<Double,Double>(); double[] km = sd[0]; double[] load = sd[1]; for (int i = 0 ; i < km.length; i++) { sortData.put(km[i], load[i]); } double[][] values = new double[2][]; values[0] = new double[km.length*3]; values[1] = new double[km.length*3]; List<double[]> kmWithoutStation = new ArrayList<double[]>(); // Find station via its station (km). // TODO use a binarySearch instead of linear absdiff approach int i = 0; for (Map.Entry<Double, Double> entry: sortData.entrySet()) { boolean matchFound = false; // For now, ignore overlaps like (B> next A) for (MeasurementStation station: stations) { if (Math.abs(station.getStation() - entry.getKey()) < EPSILON || station.getRange().containsTolerant(entry.getKey())) { // TODO: In rare cases, two matches can be found. values[0][i*3] = station.getRange().getA().doubleValue() + EPSILON; values[1][i*3] = entry.getValue(); values[0][i*3+1] = station.getRange().getB().doubleValue() - EPSILON; values[1][i*3+1] = entry.getValue(); values[0][i*3+2] = station.getRange().getB().doubleValue(); values[1][i*3+2] = entry.getValue(); matchFound = true; } } // Store points without match for later assessment. if (!matchFound) { logger.warn("measurement without station ("+entry.getKey()+")!"); } i++; } for (int x = 0; x < values[0].length-1; x++) { // Introduce gaps where no data in measurement station. if (Math.abs(values[0][x+1] - values[0][x]) > 3*EPSILON && values[1][x+1] != values[1][x]) { values[0][x] = Double.NaN; values[1][x] = Double.NaN; } } return values; } /** Get data according to type of facet. */ private double[][] getLoadData(SedimentLoadResult result) { if (getName().equals(FacetTypes.SEDIMENT_LOAD_SAND)) return result.getSandData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_COARSE)) return result.getCoarseData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_FINEMIDDLE)) return result.getFineMiddleData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_SUSP_SAND)) return result.getSuspSandData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_SUSP_SAND_BED)) return result.getSuspSandBedData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_SUSP_SEDIMENT)) return result.getSuspSedimentData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_TOTAL_LOAD)) return result.getTotalLoadData(); else if (getName().equals(FacetTypes.SEDIMENT_LOAD_TOTAL)) return result.getTotalData(); else { logger.error("SedimentLoadFacet " + getName() + " cannot determine data type."); return null; } } /** Copy deeply. */ @Override public Facet deepCopy() { SedimentLoadFacet copy = new SedimentLoadFacet(); copy.set(this); copy.type = type; copy.hash = hash; copy.stateId = stateId; return copy; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :