Mercurial > dive4elements > river
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadFacet.java Thu Apr 25 12:06:39 2013 +0200 @@ -0,0 +1,178 @@ +package org.dive4elements.river.artifacts.model.minfo; + +import org.dive4elements.artifactdatabase.state.Facet; + +import org.dive4elements.artifacts.Artifact; +import org.dive4elements.artifacts.CallContext; + +import org.dive4elements.river.artifacts.FLYSArtifact; + +import org.dive4elements.river.artifacts.model.CalculationResult; +import org.dive4elements.river.artifacts.model.DataFacet; +import org.dive4elements.river.artifacts.model.FacetTypes; + +import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; + +import org.dive4elements.river.model.MeasurementStation; + +import org.dive4elements.river.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 :