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.model; felix@1122: gernotbelger@9425: import java.io.Serializable; felix@1975: import java.util.List; felix@1975: gernotbelger@9425: import org.apache.log4j.Logger; gernotbelger@9425: import org.dive4elements.artifactdatabase.state.Facet; teichmann@5831: import org.dive4elements.artifacts.Artifact; teichmann@5831: import org.dive4elements.artifacts.CallContext; teichmann@5831: import org.dive4elements.artifacts.DataProvider; teichmann@5831: import org.dive4elements.river.artifacts.WaterLineArtifact; gernotbelger@9425: import org.dive4elements.river.artifacts.geom.Lines; gernotbelger@9425: import org.dive4elements.river.artifacts.geom.Lines.LineData; gernotbelger@9425: import org.dive4elements.river.artifacts.states.DefaultState.ComputeType; teichmann@5831: import org.dive4elements.river.model.FastCrossSectionLine; felix@1122: felix@1122: /** felix@1122: * Facet for Waterlines in Cross Sections. felix@1122: */ gernotbelger@9425: public class CrossSectionWaterLineFacet extends DataFacet implements FacetTypes { gernotbelger@9425: gernotbelger@9425: private static final LineData NO_LINE_DATA = new Lines.LineData(new double[][] {}, 0d, 0d); gernotbelger@9425: gernotbelger@9425: private static final long serialVersionUID = 1L; felix@1122: teichmann@8202: /** Private log to use. */ gernotbelger@9425: private static Logger log = Logger.getLogger(CrossSectionWaterLineFacet.class); felix@1122: gernotbelger@9425: private final Serializable waterLineIndex; felix@1122: gernotbelger@9429: public CrossSectionWaterLineFacet(final int facetIndex, final String description, final ComputeType type, final String hash, final String stateId, gernotbelger@9425: final Serializable waterLineIndex) { gernotbelger@9429: this(facetIndex, CROSS_SECTION_WATER_LINE, description, type, hash, stateId, waterLineIndex); felix@1122: } felix@1122: felix@3272: /** felix@3272: * Trivial constructor, set (maybe localized) description. gernotbelger@9425: * gernotbelger@9425: * @param facetIndex gernotbelger@9425: * Index of this facet. gernotbelger@9425: * @param waterLineIndex gernotbelger@9425: * Determines which water-line the artifact will return. Depends on the implementation of the artifact. gernotbelger@9425: * Is serializable because this class is, must be immutable because only the reference is copied in gernotbelger@9425: * 'deepCopy' gernotbelger@9425: * @param name gernotbelger@9425: * 'type' of this facet. gernotbelger@9425: * @param description gernotbelger@9425: * (maybe) localized user-visible description. felix@3272: */ gernotbelger@9425: public CrossSectionWaterLineFacet(final int facetIndex, final String name, final String description, final ComputeType type, final String hash, gernotbelger@9425: final String stateId, final Serializable waterLineIndex) { gernotbelger@9425: super(facetIndex, name, description, type, hash, stateId); gernotbelger@9425: gernotbelger@9425: this.waterLineIndex = waterLineIndex; felix@3198: } felix@3198: felix@1122: /** felix@1975: * Gets waterline (crossed with cross section) of waterlevel. gernotbelger@9425: * FIXME: the cross section facets delgate fetching the data to the artifact, which in turn (in most cases) re-calculate gernotbelger@9425: * the artifact on every call.... gernotbelger@9425: * Instead this should work like other facets that rely on the hashed computation. felix@1122: */ gernotbelger@9425: @Override gernotbelger@9425: public Object getData(final Artifact artifact, final CallContext context) { teichmann@8202: log.debug("Get data for cross section water line"); felix@1122: gernotbelger@9425: final List providers = context.getDataProvider(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA); felix@1975: if (providers.size() < 1) { teichmann@8202: log.warn("Could not find Cross-Section data provider."); gernotbelger@9425: return NO_LINE_DATA; felix@1975: } sascha@3076: gernotbelger@9425: final DataProvider dataProvider = providers.get(0); gernotbelger@9425: gernotbelger@9425: final FastCrossSectionLine crossSection = (FastCrossSectionLine) dataProvider.provideData(CrossSectionFacet.BLACKBOARD_CS_MASTER_DATA, null, context); gernotbelger@9425: if (crossSection == null) gernotbelger@9425: return NO_LINE_DATA; gernotbelger@9425: gernotbelger@9425: Object nextKm = dataProvider.provideData(CrossSectionFacet.BLACKBOARD_CS_NEXT_KM, null, context); gernotbelger@9425: Object prevKm = dataProvider.provideData(CrossSectionFacet.BLACKBOARD_CS_PREV_KM, null, context); felix@3272: if (prevKm == null) felix@3272: prevKm = new Double(-1d); felix@3272: if (nextKm == null) felix@3272: nextKm = new Double(-1d); felix@1975: felix@4506: if (!(artifact instanceof WaterLineArtifact)) { teichmann@8202: log.error("CrossSectionWaterLineFacet needs WaterLineArtifact"); gernotbelger@9425: return NO_LINE_DATA; felix@4506: } felix@1122: gernotbelger@9425: final WaterLineArtifact lineArtifact = (WaterLineArtifact) artifact; gernotbelger@9425: gernotbelger@9425: final double currentKm = crossSection.getKm(); gernotbelger@9425: gernotbelger@9425: final double waterLevel = lineArtifact.getWaterLevel(this.type, this.hash, this.stateId, currentKm, this.waterLineIndex, (Double) nextKm, gernotbelger@9499: (Double) prevKm, context); gernotbelger@9425: if (Double.isNaN(waterLevel)) gernotbelger@9425: return NO_LINE_DATA; gernotbelger@9425: gernotbelger@9425: return Lines.createWaterLines(crossSection.getPoints(), waterLevel); felix@1122: } felix@1122: felix@1136: /** Do a deep copy. */ sascha@3076: @Override felix@1122: public Facet deepCopy() { gernotbelger@9425: final CrossSectionWaterLineFacet copy = new CrossSectionWaterLineFacet(this.getIndex(), this.name, this.description, this.type, this.hash, this.stateId, gernotbelger@9425: this.waterLineIndex); felix@1122: copy.set(this); felix@1122: return copy; felix@1122: } gernotbelger@9425: }