felix@2723: package de.intevation.flys.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;
felix@2723: 
felix@2723: import org.apache.log4j.Logger;
felix@2723: 
felix@2723: import org.w3c.dom.Document;
felix@2723: 
felix@2723: import de.intevation.artifactdatabase.state.Facet;
felix@2723: 
felix@2723: import de.intevation.artifacts.Artifact;
felix@2723: import de.intevation.artifacts.ArtifactFactory;
felix@2723: import de.intevation.artifacts.CallMeta;
felix@2723: 
felix@2723: import de.intevation.flys.artifacts.model.FacetTypes;
felix@2733: import de.intevation.flys.artifacts.model.WQKms;
felix@2723: 
felix@2723: import de.intevation.flys.artifacts.states.DefaultState;
felix@2723: 
felix@2733: import de.intevation.flys.artifacts.model.Calculation;
felix@2733: import de.intevation.flys.artifacts.model.CalculationResult;
felix@2733: 
felix@2733: import de.intevation.flys.artifacts.model.DischargeTables;
felix@2733: 
felix@2733: import de.intevation.flys.model.Gauge;
felix@2733: import de.intevation.flys.model.River;
felix@2733: 
felix@2733: import de.intevation.flys.utils.FLYSUtils;
felix@2733: 
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: {
felix@2723:     /** The logger for this class. */
felix@2723:     private static Logger logger = Logger.getLogger(GaugeDischargeArtifact.class);
felix@2723: 
felix@2723:     /** The name of the artifact. */
felix@2733:     public static final String ARTIFACT_NAME = "gaugedischarge";
felix@2723: 
felix@2723: 
felix@2723:     /**
felix@2723:      * Trivial Constructor.
felix@2723:      */
felix@2723:     public GaugeDischargeArtifact() {
felix@3046:         logger.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,
felix@2723:         Document        data)
felix@2723:     {
felix@2723:         logger.debug("GaugeDischargeArtifact.setup");
felix@3051:         String ids = StaticFLYSArtifact.getDatacageIDValue(data);
felix@3051:         addStringData("ids", ids);
felix@3051:         logger.debug("id for gaugedischarge: " + ids);
felix@2723:         super.setup(identifier, factory, context, callMeta, data);
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) {
felix@2723:         logger.debug("GaugeDischargeArtifact.initialize");
felix@2723:         List<Facet> fs = new ArrayList<Facet>();
felix@2723:         FLYSArtifact artifact = (FLYSArtifact) 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()) {
felix@2733:             logger.debug("Facets to add in GaugeDischargeArtifact.initialize. ("
sascha@3076:                 + state.getID() + "/ " + getCurrentStateId() + ").");
sascha@3076:             facets.put(getCurrentStateId(), fs);
sascha@3076:         }
sascha@3076:         else {
felix@2723:             logger.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() {
felix@3051:         return this.getDataAsString("ids");
felix@3051:     }
felix@3051: 
felix@3051: 
felix@3051:     /** Get the Gauges which came with datacage data-document. */
felix@3051:     public Gauge getGauge() {
felix@3051:         River river = FLYSUtils.getRiver(this);
felix@3051:         return river.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: 
felix@2733:         River river = FLYSUtils.getRiver(this);
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.
felix@2733:         double [] distance = FLYSUtils.getKmRange(this);
felix@2733:         logger.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<Gauge> gauges = river.determineGauges(distance[0], distance[1]);
felix@3051:         logger.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();
felix@2733:             logger.debug("getDischargeCurveData: name " + names[i]);
felix@2733:         }
felix@3051:         */
felix@2733: 
felix@3051:         DischargeTables dt = new DischargeTables(river.getName(), getDataAsString("ids"));
felix@2733: 
felix@3051:         Map<String, double [][]> map = dt.getValues(100);
felix@2733: 
felix@2733:         ArrayList<WQKms> res = new ArrayList<WQKms>();
felix@2733: 
felix@3051:         Gauge gauge = river.determineGaugeByName(this.getDataAsString("ids"));
felix@3051: 
felix@3051:         String name = getGaugeName();
felix@3051:         double [][] values = map.get(name);
felix@3051:         if (values == null) {
felix@3051:             logger.error("No values for this gauge / discharge found.");
felix@3591:             return error(new WQKms[0], "no.gauge.found");
felix@2733:         }
felix@3051:         for (int i = 0 ; i < values[0].length; i++) {
felix@3051:             values[0][i] += gauge.getDatum().doubleValue();
felix@3051:         }
felix@3051:         double [] kms = new double[values[0].length];
felix@3051:         Arrays.fill(kms, gauge.getStation().doubleValue());
felix@3051:         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:     }
felix@2723: }
felix@2723: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :