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@1825: gernotbelger@9425: import java.io.Serializable; felix@1825: import java.util.ArrayList; felix@1825: import java.util.List; felix@1825: felix@1825: import org.apache.log4j.Logger; teichmann@5831: import org.dive4elements.artifactdatabase.state.Facet; teichmann@5831: import org.dive4elements.artifactdatabase.state.FacetActivity; teichmann@5831: import org.dive4elements.artifacts.Artifact; teichmann@5831: import org.dive4elements.artifacts.ArtifactFactory; teichmann@5831: import org.dive4elements.artifacts.CallContext; teichmann@5831: import org.dive4elements.artifacts.CallMeta; teichmann@5831: import org.dive4elements.artifacts.common.utils.XMLUtils; teichmann@5831: import org.dive4elements.river.artifacts.model.FacetTypes; teichmann@5831: import org.dive4elements.river.artifacts.model.WKms; teichmann@5831: import org.dive4elements.river.artifacts.model.WKmsFactory; gernotbelger@9425: import org.dive4elements.river.artifacts.model.WQKms; teichmann@5831: import org.dive4elements.river.artifacts.model.WQKmsFactory; teichmann@5831: import org.dive4elements.river.artifacts.states.DefaultState; gernotbelger@9425: import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; gernotbelger@9425: import org.w3c.dom.Document; felix@1825: felix@1825: /** felix@1825: * Artifact to access additional "waterlevel/discharge"-type of data, like felix@1825: * fixation measurements. felix@1825: * teichmann@5867: * This artifact neglects (Static)D4EArtifacts capabilities of interaction felix@1825: * with the StateEngine by overriding the getState*-methods. felix@1825: */ gernotbelger@9425: public class StaticWQKmsArtifact extends StaticD4EArtifact implements FacetTypes, WaterLineArtifact { teichmann@8202: /** The log for this class. */ gernotbelger@9425: private static Logger log = Logger.getLogger(StaticWQKmsArtifact.class); felix@1825: gernotbelger@9425: public static final String STATIC_STATE_NAME = "state.additional_wqkms.static"; felix@1825: sascha@3556: private static final String NAME = "staticwqkms"; sascha@3556: sascha@3556: static { sascha@3556: // TODO: Move to configuration. gernotbelger@9425: FacetActivity.Registry.getInstance().register(NAME, new FacetActivity() { gernotbelger@9425: @Override gernotbelger@9425: public Boolean isInitialActive(final Artifact artifact, final Facet facet, final String outputName) { gernotbelger@9425: final String fname = facet.getName(); gernotbelger@9425: return (fname.equals(STATIC_WQKMS) || fname.equals(STATIC_WQKMS_W)); gernotbelger@9425: } gernotbelger@9425: }); sascha@3556: } felix@1825: felix@1825: /** felix@1825: * Trivial Constructor. felix@1825: */ felix@1825: public StaticWQKmsArtifact() { teichmann@8202: log.debug("StaticWQKmsArtifact.StaticWQKmsArtifact"); felix@1825: } felix@1825: felix@1825: /** felix@1825: * Gets called from factory, to set things up. aheinecke@6598: * aheinecke@6598: * If the id's string starts with official- it will be treated as aheinecke@6598: * an Artifact containing official data for the according special aheinecke@6598: * case handling. felix@1825: */ felix@1825: @Override gernotbelger@9425: public void setup(final String identifier, final ArtifactFactory factory, final Object context, final CallMeta callMeta, final Document data, gernotbelger@9425: final List loadFacets) { teichmann@8202: log.debug("StaticWQKmsArtifact.setup"); felix@1825: felix@2124: // Store the 'ids' (from datacage). teichmann@8202: if (log.isDebugEnabled()) { teichmann@8202: log.debug("StaticWQKmsArtifact.setup" + XMLUtils.toString(data)); sascha@3405: } felix@1825: gernotbelger@9425: final String code = getDatacageIDValue(data); felix@2124: addStringData("ids", code); felix@1825: if (code != null) { gernotbelger@9425: final String[] parts = code.split("-"); felix@1825: aheinecke@6598: if (parts.length >= 1) { gernotbelger@9425: final boolean official = parts[0].toLowerCase().startsWith("official"); felix@7637: addStringData("official", official ? "1" : "0"); aheinecke@6598: } aheinecke@6598: felix@1825: if (parts.length >= 4) { gernotbelger@9425: final int col = Integer.parseInt(parts[2]); gernotbelger@9425: final int wst = Integer.parseInt(parts[3]); felix@1825: felix@1900: addStringData("col_pos", parts[2]); gernotbelger@9425: addStringData("wst_id", parts[3]); felix@1825: } felix@1825: } felix@1825: felix@2124: // Do this AFTER we have set the col_pos etc. rrenkert@7842: super.setup(identifier, factory, context, callMeta, data, loadFacets); felix@1825: } felix@1825: felix@1825: /** felix@1825: * Called via setup. felix@1825: * gernotbelger@9425: * @param artifact gernotbelger@9425: * The master-artifact. felix@1825: */ felix@1825: @Override gernotbelger@9425: protected void initialize(final Artifact artifact, final Object context, final CallMeta meta) { teichmann@8202: log.debug("StaticWQKmsArtifact.initialize"); gernotbelger@9425: final D4EArtifact flys = (D4EArtifact) artifact; felix@2124: // TODO: The river is of no interest, so far., also use importData felix@5798: importData(flys, "river"); felix@1825: gernotbelger@9425: final List fs = new ArrayList<>(); felix@1825: gernotbelger@9425: final DefaultState state = (DefaultState) getCurrentState(context); felix@2124: state.computeInit(this, hash(), context, meta, fs); sascha@3076: if (!fs.isEmpty()) { teichmann@8202: log.debug("Facets to add in StaticWQKmsArtifact.initialize ."); bjoern@4497: addFacets(getCurrentStateId(), fs); gernotbelger@9425: } else { gernotbelger@9425: log.debug("No facets to add in StaticWQKmsArtifact.initialize (" + state.getID() + ")."); felix@2124: } felix@1825: } felix@1825: felix@1825: /** felix@1825: * Get WQKms from factory. gernotbelger@9425: * felix@1825: * @return WQKms according to parameterization (can be null); felix@1825: */ felix@2124: public WQKms getWQKms() { teichmann@8202: log.debug("StaticWQKmsArtifact.getWQKms"); felix@1825: gernotbelger@9425: final int col = Integer.parseInt(getDataAsString("col_pos")); gernotbelger@9425: final int wst = Integer.parseInt(getDataAsString("wst_id")); felix@2124: felix@2124: /** TODO do not run twice against db to do this. */ gernotbelger@9425: final String wkmsName = WKmsFactory.getWKmsName(col, wst); felix@2124: gernotbelger@9425: final WQKms res = WQKmsFactory.getWQKms(col, wst); felix@2124: res.setName(wkmsName); felix@2124: return res; felix@1825: } felix@1825: gernotbelger@8876: /** gernotbelger@8876: * Get WQKms from factory. gernotbelger@9425: * gernotbelger@8876: * @return WQKms according to parameterization (can be null); gernotbelger@8876: */ gernotbelger@8876: public WQKms getWQKms(final double from, final double to) { gernotbelger@8876: log.debug("StaticWQKmsArtifact.getWQKms"); gernotbelger@9425: gernotbelger@9425: final int col = Integer.parseInt(getDataAsString("col_pos")); gernotbelger@9425: final int wst = Integer.parseInt(getDataAsString("wst_id")); gernotbelger@9425: gernotbelger@8876: /** TODO do not run twice against db to do this. */ gernotbelger@9425: final String wkmsName = WKmsFactory.getWKmsName(col, wst); gernotbelger@9425: gernotbelger@9425: final WQKms res = WQKmsFactory.getWQKms(col, wst, from, to); gernotbelger@8876: res.setName(wkmsName); gernotbelger@8876: return res; gernotbelger@8876: } gernotbelger@8876: sascha@3556: /** Return specific name. */ felix@1825: @Override felix@2124: public String getName() { sascha@3556: return NAME; felix@2124: } felix@2124: felix@5798: /** felix@5798: * Get points of line describing the surface of water at cross section. felix@5798: * gernotbelger@9425: * @param idx gernotbelger@9425: * Index of facet and in wkms array. gernotbelger@9425: * @param csl gernotbelger@9425: * FastCrossSectionLine to compute water surface agains. gernotbelger@9425: * @param next gernotbelger@9425: * The km of the next crosssectionline. gernotbelger@9425: * @param prev gernotbelger@9425: * The km of the previous crosssectionline. gernotbelger@9425: * @param context gernotbelger@9425: * Ignored in this implementation. felix@5798: * felix@5798: * @return an array holding coordinates of points of surface of water ( felix@5798: * in the form {{x1, x2}, {y1, y2}} ). felix@5798: */ felix@5798: @Override gernotbelger@9425: public double getWaterLevel(final ComputeType type, final String hash, final String stateId, final double currentKm, final Serializable waterLineIndex, gernotbelger@9425: final double nextKm, final double prevKm, final CallContext context) { felix@5798: gernotbelger@9425: final WKms wkms = getWQKms(); felix@5798: felix@5798: // Find W at km. gernotbelger@9425: final double wAtKm = StaticWKmsArtifact.getWAtKm(wkms, currentKm); felix@5798: gernotbelger@9425: if (Double.isNaN(wAtKm)) { gernotbelger@9425: log.warn("Waterlevel at km " + currentKm + " unknown."); gernotbelger@9425: return Double.NaN; felix@5798: } felix@5798: gernotbelger@9425: return wAtKm; felix@5798: } felix@2124: // TODO implement deepCopy. gernotbelger@9425: }