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