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; felix@2723: felix@2723: import java.util.ArrayList; felix@2733: import java.util.Arrays; felix@2723: import java.util.List; felix@2733: import java.util.Map; aheinecke@6693: import java.util.HashMap; felix@2723: felix@2723: import org.apache.log4j.Logger; felix@2723: felix@2723: import org.w3c.dom.Document; felix@2723: teichmann@5831: import org.dive4elements.artifactdatabase.state.Facet; felix@2723: teichmann@5831: import org.dive4elements.artifacts.Artifact; teichmann@5831: import org.dive4elements.artifacts.ArtifactFactory; teichmann@5831: import org.dive4elements.artifacts.CallMeta; felix@2733: teichmann@5831: import org.dive4elements.river.artifacts.model.FacetTypes; teichmann@5831: import org.dive4elements.river.artifacts.model.WQKms; felix@2733: teichmann@5831: import org.dive4elements.river.artifacts.states.DefaultState; felix@2733: teichmann@5831: import org.dive4elements.river.artifacts.model.Calculation; teichmann@5831: import org.dive4elements.river.artifacts.model.CalculationResult; tom@8478: import org.dive4elements.river.artifacts.model.DischargeTables; teichmann@5831: tom@8478: import org.dive4elements.river.artifacts.access.RiverAccess; teichmann@5831: teichmann@5831: import org.dive4elements.river.model.Gauge; teichmann@5831: import org.dive4elements.river.model.River; aheinecke@6693: import org.dive4elements.river.model.DischargeTable; teichmann@5831: felix@2723: felix@2723: /** felix@3046: * Artifact to get discharge curves at gauges. felix@2723: */ felix@2723: public class GaugeDischargeArtifact felix@2723: extends WINFOArtifact felix@2723: implements FacetTypes felix@2723: { teichmann@8202: /** The log for this class. */ teichmann@8202: private static Logger log = Logger.getLogger(GaugeDischargeArtifact.class); felix@2723: felix@2723: /** The name of the artifact. */ felix@2733: public static final String ARTIFACT_NAME = "gaugedischarge"; felix@2723: aheinecke@6693: /** The name a facet should have */ aheinecke@6693: protected String facetWishName; felix@2723: felix@2723: /** felix@2723: * Trivial Constructor. felix@2723: */ felix@2723: public GaugeDischargeArtifact() { teichmann@8202: log.debug("GaugeDischargeArtifact.GaugeDischargeArtifact()"); felix@2723: } felix@2723: felix@2723: felix@2723: /** felix@2723: * Gets called from factory, to set things up. felix@2723: * Especially, when loaded via datacage mechanisms, provide the felix@2723: * data document. felix@2723: * @param data filled with stuff from dc, if any. felix@2723: */ felix@2723: @Override felix@2723: public void setup( felix@2723: String identifier, felix@2723: ArtifactFactory factory, felix@2723: Object context, felix@2723: CallMeta callMeta, rrenkert@7842: Document data, rrenkert@7842: List loadFacets) felix@2723: { teichmann@8202: log.debug("GaugeDischargeArtifact.setup"); teichmann@5867: String ids = StaticD4EArtifact.getDatacageIDValue(data); felix@3051: addStringData("ids", ids); teichmann@8202: log.debug("id for gaugedischarge: " + ids); aheinecke@6693: String[] splitIds = ids.split(";"); aheinecke@6693: /* We assume that if an id's string with a ; is given that the aheinecke@6693: * format is ;; aheinecke@6693: * so that a specific discharge table can be selected */ aheinecke@6693: if (splitIds.length > 2) { aheinecke@6693: facetWishName = splitIds[2]; aheinecke@6693: } rrenkert@7842: super.setup(identifier, factory, context, callMeta, data, loadFacets); felix@2723: } felix@2723: felix@2723: felix@2723: /** Return the name of this artifact. */ felix@2723: public String getName() { felix@2723: return ARTIFACT_NAME; felix@2723: } felix@2723: felix@2723: felix@2723: /** felix@2723: * Setup state and facet, copy from master artifact. felix@2723: */ felix@2723: @Override felix@2723: protected void initialize(Artifact art, Object context, CallMeta meta) { teichmann@8202: log.debug("GaugeDischargeArtifact.initialize"); felix@2723: List fs = new ArrayList(); teichmann@5867: D4EArtifact artifact = (D4EArtifact) art; felix@3046: importData(artifact, "river"); felix@2723: felix@2723: // Get the location(s) felix@3051: //importData(artifact, "ld_mode", ld_from, ld_to, ld_locations felix@2733: addStringData("ld_from", "0"); felix@2733: addStringData("ld_to", "1000"); felix@2733: addStringData("ld_mode", "distance"); felix@2733: felix@2723: DefaultState state = (DefaultState) getCurrentState(context); felix@2723: state.computeInit(this, hash(), context, meta, fs); sascha@3076: if (!fs.isEmpty()) { teichmann@8202: log.debug("Facets to add in GaugeDischargeArtifact.initialize. (" sascha@3076: + state.getID() + "/ " + getCurrentStateId() + ")."); bjoern@4497: addFacets(getCurrentStateId(), fs); sascha@3076: } sascha@3076: else { teichmann@8202: log.debug("No facets to add in GaugeDischargeArtifact.initialize (" felix@3046: + state.getID() + "/ "+getCurrentStateId()+")."); felix@2723: } felix@2723: } felix@2723: felix@2723: felix@3051: /** Get the Gauges name which came with datacage data-document. */ felix@3051: public String getGaugeName() { aheinecke@6693: if (getDataAsString("ids") == null) { aheinecke@6693: return null; aheinecke@6693: } aheinecke@6693: return getDataAsString("ids").split(";")[0]; felix@3051: } felix@3051: felix@3051: felix@3051: /** Get the Gauges which came with datacage data-document. */ felix@3051: public Gauge getGauge() { tom@8478: return new RiverAccess((D4EArtifact)this).getRiver() tom@8478: .determineGaugeByName(getGaugeName()); felix@2723: } felix@2733: felix@2733: felix@2733: /** felix@2733: * Returns the data that is used to create discharge curves. felix@3051: * @return CalculationResult with WQKms. felix@2733: */ felix@2733: public CalculationResult getDischargeCurveData() { felix@2733: tom@8478: River river = new RiverAccess((D4EArtifact)this).getRiver(); felix@2733: if (river == null) { felix@2733: return error(new WQKms[0], "no.river.selected"); felix@2733: } felix@3051: /* felix@3051: // This one would allow to automatically pick the right Gauge. teichmann@5865: double [] distance = RiverUtils.getKmRange(this); teichmann@8202: log.debug("getDischargeCurveData: get range"); felix@2733: felix@2733: if (distance == null) { felix@2733: return error(new WQKms[0], "no.range.found"); felix@2733: } felix@2733: felix@2733: List gauges = river.determineGauges(distance[0], distance[1]); teichmann@8202: log.debug("getDischargeCurveData: got " + gauges.size() + " gauges"); felix@2733: felix@2733: if (gauges.isEmpty()) { felix@2733: return error(new WQKms[0], "no.gauge.selected"); felix@2733: } felix@2733: felix@2733: String [] names = new String[gauges.size()]; felix@2733: felix@2733: for (int i = 0; i < names.length; ++i) { felix@2733: names[i] = gauges.get(i).getName(); teichmann@8202: log.debug("getDischargeCurveData: name " + names[i]); felix@2733: } felix@3051: */ felix@2733: aheinecke@6693: Map map; felix@2733: aheinecke@6693: String[] ids = getDataAsString("ids").split(";"); aheinecke@6693: if (ids.length > 1) { aheinecke@6693: /* We assume that if an id's string with a ; is given that the aheinecke@6693: * format is ;; aheinecke@6693: * so that a specific discharge table can be selected */ aheinecke@6693: int tableId = 0; aheinecke@6693: try { aheinecke@6693: tableId = Integer.parseInt(ids[1]); aheinecke@6693: } catch (NumberFormatException e) { tom@8856: log.error("Discharge tables ids string is wrong. " tom@8856: + "Format is " tom@8856: + ";;" tom@8856: + " Fix your Datacage!"); aheinecke@6693: // Let's rather break down completly then show the wrong data. aheinecke@6693: return null; aheinecke@6693: } tom@8856: DischargeTable table = DischargeTable.getDischargeTableById( tom@8856: tableId); aheinecke@6693: map = new HashMap(); tom@8856: map.put(getGaugeName(), DischargeTables.loadDischargeTableValues( tom@8856: table)); aheinecke@6693: } else { tom@8856: DischargeTables dt = new DischargeTables( tom@8856: river.getName(), getGaugeName()); aheinecke@6693: map = dt.getValues(); aheinecke@6693: } felix@2733: felix@2733: ArrayList res = new ArrayList(); felix@2733: aheinecke@6693: Gauge gauge = river.determineGaugeByName(getGaugeName()); felix@3051: felix@3051: String name = getGaugeName(); felix@3051: double [][] values = map.get(name); felix@3051: if (values == null) { teichmann@8202: log.error("No values for this gauge / discharge found."); felix@3591: return error(new WQKms[0], "no.gauge.found"); felix@2733: } tom@8361: for (int i = 0 ; i < values[1].length; i++) { tom@8361: values[1][i] = values[1][i]/100d + gauge.getDatum().doubleValue(); felix@3051: } tom@8361: double [] kms = new double[values[1].length]; felix@3051: Arrays.fill(kms, gauge.getStation().doubleValue()); tom@8361: res.add(new WQKms(kms, values[0], values[1], name)); felix@2733: felix@2733: return new CalculationResult( felix@2733: res.toArray(new WQKms[res.size()]), felix@2733: new Calculation()); felix@2733: } aheinecke@6693: aheinecke@6693: /** Gets the facet wish name. aheinecke@6693: * aheinecke@6693: * This is a hack to enable setting the name of the facet / theme in the aheinecke@6693: * UI from the datacage setting. */ aheinecke@6693: public String getFacetWishName() { aheinecke@6693: return facetWishName; aheinecke@6693: } felix@2723: } felix@2723: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :