Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java @ 2060:3ffb7195173f
Validate user defined Qs based on the start kilometer ('Q free').
flys-artifacts/trunk@3553 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Wed, 28 Dec 2011 12:39:35 +0000 |
parents | cd9bcdcf6597 |
children | f021080cb409 |
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; import de.intevation.flys.utils.FLYSUtils; /** * 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 flagging whether we think that we are master. */ public static final String DATA_IS_MASTER = "cross_section.master?"; /** Name of data item flagging whether we are the newest. */ public static final String DATA_IS_NEWEST = "cross_section.newest?"; /** 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!"); } List<Facet> fs = new ArrayList<Facet>(); CrossSection cs = CrossSectionFactory.getCrossSection(Integer.valueOf(ids)); CrossSectionLine csl = cs.getLines().get(0); // Find min-km of cross sections, than set DATA_KM to min(DATA_KM, minCross). if (csl != null) { double masterKm = Double.valueOf(getDataAsString(DATA_KM)); if (masterKm < csl.getKm().doubleValue()) { addStringData(DATA_KM, csl.getKm().toString()); } } fs.add(new CrossSectionFacet(0, cs.getDescription())); // Find out if we are newest. boolean isNewest = CrossSectionFactory.isNewest(cs); String newString = (isNewest) ? "1" : "0"; addStringData(DATA_IS_NEWEST, newString); addStringData(DATA_IS_MASTER, newString); StaticState state = (StaticState) getCurrentState(context); if (!fs.isEmpty()) { facets.put(getCurrentStateId(), fs); } } /** Copy km where master-artifact "starts". */ @Override protected void initialize( Artifact artifact, Object context, CallMeta callMeta) { WINFOArtifact winfo = (WINFOArtifact) artifact; double[] range = FLYSUtils.getKmRange(winfo); double min = 0.0f; if (range != null && range.length > 0) { min = range[0]; } this.addStringData(DATA_KM, Double.toString(min)); } /** * 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; } /** * Determines Facets initial disposition regarding activity (think of * selection in Client ThemeList GUI). This will be checked one time * when the facet enters a collections describe document. * * @param outputName Ignored. * @param facetName Ignored. * @param index Ignored. * @return 0 if not active */ @Override public int getInitialFacetActivity(String outputName, String facetName, int index) { return (getDataAsString(DATA_IS_NEWEST) != null && getDataAsString(DATA_IS_NEWEST).equals("1")) ? 1 : 0; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :