Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java @ 2024:2bb160b2768e
New facet, will ease converting other facets to be able to contribute to area computations.
flys-artifacts/trunk@3481 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Tue, 20 Dec 2011 09:00:51 +0000 |
parents | 07b176b14205 |
children | c03aeb0cf46b |
line wrap: on
line source
package de.intevation.flys.artifacts; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.w3c.dom.Document; import de.intevation.artifacts.Artifact; import de.intevation.artifacts.ArtifactFactory; import de.intevation.artifacts.CallMeta; import de.intevation.flys.artifacts.model.CrossSectionFacet; import de.intevation.flys.model.CrossSection; import de.intevation.flys.model.CrossSectionLine; import de.intevation.flys.artifacts.model.CrossSectionFactory; import de.intevation.artifacts.common.ArtifactNamespaceContext; import de.intevation.artifacts.common.utils.XMLUtils; import de.intevation.flys.artifacts.states.StaticState; import de.intevation.artifactdatabase.state.Facet; import de.intevation.artifactdatabase.state.State; /** * Artifact describing a cross-section. */ public class CrossSectionArtifact extends StaticFLYSArtifact { /** Access ids of doc. */ public static final String XPATH_IDS = "/art:action/art:ids/@value"; /** Name of Artifact. */ public static final String CS_ARTIFACT_NAME = "cross_section"; /** Name of state. */ public static final String STATIC_STATE_NAME = "state.cross_section"; /** Name of data item keeping the position. */ public static final String DATA_KM = "cross_section.km"; /** Name of data item keeping the database id of this c.s.. */ public static final String DATA_DBID = "cross_section.dbid"; /** Name of data item keeping the database id of this c.s.. */ public static final String DATA_IS_MASTER = "cross_section.master?"; /** Own logger. */ private static final Logger logger = Logger.getLogger(CrossSectionArtifact.class); /** Return given name. */ @Override public String getName() { return CS_ARTIFACT_NAME; } /** Store ids, create a CrossSectionFacet. */ @Override public void setup( String identifier, ArtifactFactory factory, Object context, CallMeta callMeta, Document data) { logger.info("CrossSectionArtifact.setup"); super.setup(identifier, factory, context, callMeta, data); String ids = XMLUtils.xpathString( data, XPATH_IDS, ArtifactNamespaceContext.INSTANCE); if (ids != null && ids.length() > 0) { addStringData(DATA_DBID, ids); logger.debug("CrossSectionArtifacts db-id: " + ids); } else { throw new IllegalArgumentException("No attribute 'ids' found!"); } // Assume we start at km 0. addStringData(DATA_KM, "0"); addStringData(DATA_IS_MASTER, "0"); List<Facet> fs = new ArrayList<Facet>(); CrossSection cs = CrossSectionFactory.getCrossSection(Integer.valueOf(ids)); fs.add(new CrossSectionFacet(0, cs.getDescription())); StaticState state = (StaticState) getCurrentState(context); if (!fs.isEmpty()) { facets.put(getCurrentStateId(), fs); } } /** Do not copy data from daddyfact. */ @Override protected void initialize( Artifact artifact, Object context, CallMeta callMeta) { // do nothing } /** * Create and return a new StaticState with charting output. */ @Override public State getCurrentState(Object cc) { final List<Facet> fs = facets.get(getCurrentStateId()); StaticState state = new StaticState(STATIC_STATE_NAME) { @Override public Object staticCompute(List<Facet> facets) { if (facets != null) { facets.addAll(fs); } return null; } }; state.addDefaultChartOutput("cross_section", fs); return state; } /** * Get a list containing the one and only State. * @param context ignored. * @return list with one and only state. */ @Override protected List<State> getStates(Object context) { ArrayList<State> states = new ArrayList<State>(); states.add(getCurrentState(context)); return states; } // TODO all data access needs proper caching. /** * Get a DataItem casted to int (0 if fails). */ public int getDataAsIntNull(String dataName) { String val = getDataAsString(dataName); try { return Integer.valueOf(val); } catch (NumberFormatException e) { logger.warn("Could not get data " + dataName + " as int", e); return 0; } } /** Returns database-id of cross-section (from data). */ protected int getDBID() { return getDataAsIntNull(DATA_DBID); } /** * Return position (km) from data, 0 if not found. */ protected double getKm() { String val = getDataAsString(DATA_KM); try { return Double.valueOf(val); } catch (NumberFormatException e) { logger.warn("Could not get data " + DATA_KM + " as double", e); return 0; } } /** Returns true if artifact is set to be a "master" (other facets will * refer to this). */ public boolean isMaster() { return !getDataAsString(DATA_IS_MASTER).equals("0"); } /** * Get points of Profile of cross section at given kilometer. * * @return an array holding coordinates of points of profile ( * in the form {{x1, x2} {y1, y2}} ). */ public double [][] getCrossSectionData() { logger.info("getCrossSectionData() for cross_section.km " + getDataAsString(DATA_KM)); CrossSectionLine line = searchCrossSectionLine(); return line != null ? line.fetchCrossSectionProfile() : null; } /** * Get CrossSectionLine spatially closest to what is specified in the data * "cross_section.km". * * @return CrossSectionLine closest to "cross_section.km". */ public CrossSectionLine searchCrossSectionLine() { double wishKM = getKm(); CrossSection crossSection = CrossSectionFactory.getCrossSection(getDBID()); logger.debug("dbid " + getDBID() + " : " + crossSection); List<CrossSectionLine> crossSectionLines = crossSection.getLines(); // Get the cross section closest to requested km. // Naive, linear approach. CrossSectionLine oldLine = crossSectionLines.get(0); double oldDiff = Math.abs(wishKM - oldLine.getKm().doubleValue()); for (CrossSectionLine line: crossSectionLines) { double diff = Math.abs(wishKM - line.getKm().doubleValue()); if (diff > oldDiff) { break; } oldDiff = diff; oldLine = line; } return oldLine; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :