teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.access; felix@4647: teichmann@6102: import gnu.trove.TDoubleArrayList; teichmann@6102: felix@4647: import org.apache.log4j.Logger; felix@4647: teichmann@5867: import org.dive4elements.river.artifacts.D4EArtifact; teichmann@5831: import org.dive4elements.river.artifacts.WINFOArtifact; felix@4850: teichmann@5865: import org.dive4elements.river.utils.RiverUtils; andre@8562: import org.dive4elements.river.utils.DoubleUtil; felix@4647: felix@4850: teichmann@5865: /** For the moment, light-weight wrapper around RiverUtils. */ teichmann@5865: // TODO employ 'Caching' like other Accesses, remove usage of RiverUtils. felix@4647: public class RangeAccess felix@4647: extends RiverAccess felix@4647: { teichmann@8202: private static Logger log = Logger.getLogger(RangeAccess.class); felix@4647: felix@4852: public static enum KM_MODE { RANGE, LOCATIONS, NONE }; felix@4852: andre@8562: /** The default step width between the start end end kilometer. */ andre@8562: public static final double DEFAULT_KM_STEPS = 0.1; andre@8562: felix@4852: double[] kmRange; felix@4852: felix@4824: Double from; felix@4824: felix@4824: Double to; felix@4824: felix@4825: Double step; felix@4825: felix@4852: private KM_MODE mode; felix@4852: teichmann@7055: public RangeAccess() { teichmann@7055: } felix@4647: teichmann@6101: public RangeAccess(D4EArtifact artifact) { felix@4647: super(artifact); felix@4647: } felix@4647: felix@4647: felix@4852: /** Evaluate the ld_mode data of artifact. */ felix@4852: public KM_MODE getKmRangeMode() { felix@4852: if (mode != null) { felix@4852: return mode; felix@4852: } felix@4852: String modeData = getString("ld_mode"); felix@4852: felix@4852: if (modeData == null || modeData.length() == 0) { felix@4852: mode = KM_MODE.NONE; felix@4852: } felix@4852: else if (modeData.equals("distance")) { felix@4852: mode = KM_MODE.RANGE; felix@4852: } felix@4852: else if (modeData.equals("locations")) { felix@4852: mode = KM_MODE.LOCATIONS; felix@4852: } felix@4852: else { felix@4852: mode = KM_MODE.NONE; felix@4852: } teichmann@5282: felix@4852: return mode; felix@4852: } felix@4852: andre@8755: /** Check if the calculation mode is Range. */ andre@8755: public boolean isRange() { andre@8755: return getKmRangeMode() == KM_MODE.RANGE; andre@8755: } andre@8755: felix@4850: /** felix@4850: * Return sorted array of locations at which stuff was calculated felix@4850: * (from ld_locations data), null if not parameterized this way. felix@4850: */ felix@4850: public double[] getLocations() { felix@4850: String locationStr = getString("ld_locations"); felix@4850: felix@4850: if (locationStr == null || locationStr.length() == 0) { felix@4850: if (getArtifact() instanceof WINFOArtifact) { felix@4850: WINFOArtifact winfo = (WINFOArtifact) getArtifact(); tom@8856: if (winfo.getReferenceStartKm() != null tom@8856: && winfo.getReferenceEndKms() != null tom@8856: ) { felix@4850: return new double[] felix@4850: { felix@4850: winfo.getReferenceStartKm().doubleValue(), felix@4850: winfo.getReferenceEndKms()[0] felix@4850: }; felix@4850: } felix@5665: else if (winfo.getReferenceStartKm() != null) { felix@5665: return new double[] felix@5665: { felix@5665: winfo.getReferenceStartKm().doubleValue(), felix@5665: winfo.getReferenceStartKm().doubleValue() felix@5665: }; felix@5665: } felix@4850: } felix@4850: return null; felix@4850: } felix@4850: felix@4850: String[] tmp = locationStr.split(" "); felix@4850: TDoubleArrayList locations = new TDoubleArrayList(); felix@4850: felix@4850: for (String l: tmp) { felix@4850: try { felix@4850: locations.add(Double.parseDouble(l)); felix@4850: } felix@4850: catch (NumberFormatException nfe) { teichmann@8202: log.debug(nfe.getLocalizedMessage(), nfe); felix@4850: } felix@4850: } felix@4850: felix@4850: locations.sort(); felix@4850: felix@4850: return locations.toNativeArray(); felix@4850: } felix@4850: teichmann@6988: public boolean hasFrom() { teichmann@6988: return from != null || (from = getDouble("ld_from")) != null; teichmann@6988: } teichmann@6988: teichmann@6988: public boolean hasTo() { teichmann@6988: return to != null || (to = getDouble("ld_to")) != null; teichmann@6988: } teichmann@6988: andre@8646: /* If left_to_right is set to true this returns andre@8646: * the smaller value of from and to. */ andre@8646: public double getFrom(boolean left_to_right) { andre@8646: if (!left_to_right) { andre@8646: return getFrom(); andre@8646: } andre@8646: double from = getFrom(); andre@8646: double to = getTo(); andre@8646: return from > to ? to : from; andre@8646: } felix@4850: felix@7262: /** Return ld_from data (in km). If not found, the min. */ felix@4824: public double getFrom() { felix@4824: if (from == null) { felix@4824: from = getDouble("ld_from"); felix@4824: } felix@4824: teichmann@8202: if (log.isDebugEnabled()) { teichmann@8202: log.debug("from from data: '" + from + "'"); felix@7262: } felix@7262: felix@7262: if (from == null) { tom@8310: log.warn("No 'from' found. Assume min of river."); felix@7262: return getRiver().determineMinMaxDistance()[0]; felix@4827: } felix@4827: felix@4824: return from.doubleValue(); felix@4824: } felix@4824: andre@8646: /* If left_to_right is set to true this returns andre@8646: * the larger value of from and to. */ andre@8646: public double getTo(boolean left_to_right) { andre@8646: if (!left_to_right) { andre@8646: return getTo(); andre@8646: } andre@8646: double from = getFrom(); andre@8646: double to = getTo(); andre@8646: return from > to ? from : to; andre@8646: } felix@4824: felix@7262: /** Return ld_to data (in km), if not found, the max. */ felix@4824: public double getTo() { felix@4824: if (to == null) { felix@4824: to = getDouble("ld_to"); felix@4824: } felix@4827: teichmann@8202: if (log.isDebugEnabled()) { teichmann@8202: log.debug("to from data: '" + to + "'"); felix@7262: } felix@7262: felix@7262: if (to == null) { tom@8310: log.warn("No 'to' found. Assume max of river."); felix@7262: return getRiver().determineMinMaxDistance()[1]; felix@4827: } felix@4827: felix@4824: return to.doubleValue(); felix@4824: } felix@4824: felix@4824: felix@4825: /** Step width for calculation. */ felix@4825: public Double getStep() { felix@4825: felix@4825: if (step == null) { felix@4825: step = getDouble("ld_step"); felix@4825: } felix@4825: teichmann@8202: if (log.isDebugEnabled()) { teichmann@8202: log.debug("step: '" + step + "'"); felix@4825: } felix@4825: felix@4825: return step; felix@4825: } felix@4825: felix@4825: felix@4647: /** felix@4647: * Get min and max kilometer, independent of parametization felix@4647: * (ld_from/to vs ld_locations). felix@4647: */ felix@4647: public double[] getKmRange() { felix@4853: // TODO store kmRange in field. felix@4853: switch (getKmRangeMode()) { felix@4853: case RANGE: { felix@4853: return getKmFromTo(); felix@4853: } felix@4853: felix@4853: case LOCATIONS: { felix@4853: double[] locs = getLocations(); felix@4853: // if no locations, nPE. felix@4853: if (locs == null) { teichmann@8202: log.warn("no locations to get km range from."); felix@4853: return new double[] { Double.NaN, Double.NaN }; felix@4853: } felix@4853: return new double[] { locs[0], locs[locs.length-1] }; felix@4853: } felix@4853: felix@4853: case NONE: { felix@4853: double[] locs = getLocations(); felix@4853: if (locs != null) { felix@4853: return new double[] { locs[0], locs[locs.length-1] }; felix@4853: } felix@4853: else { felix@4853: return getKmFromTo(); felix@4853: } felix@4853: } felix@4853: } felix@4853: felix@4853: return new double[] { Double.NaN, Double.NaN }; felix@4647: } felix@4647: felix@4647: felix@4647: public double[] getKmFromTo() { teichmann@5865: return RiverUtils.getKmFromTo(this.getArtifact()); felix@4647: } andre@8562: andre@8562: /** andre@8562: * Returns the selected Kms in steps as specified. andre@8562: * andre@8562: * @return Each step for this range. andre@8562: */ andre@8562: public double[] getKmSteps() { andre@8562: double step = getStep(); andre@8562: andre@8562: // transform step from 'm' into 'km' andre@8562: step = step / 1000; andre@8562: andre@8562: if (step == 0d) { andre@8562: step = DEFAULT_KM_STEPS; andre@8562: } andre@8562: andre@8562: return DoubleUtil.explode(getFrom(), getTo(), step); andre@8562: } felix@4647: } felix@4647: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :