aheinecke@7105: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde aheinecke@7105: * Software engineering by Intevation GmbH aheinecke@7105: * aheinecke@7105: * This file is Free Software under the GNU AGPL (>=v3) aheinecke@7105: * and comes with ABSOLUTELY NO WARRANTY! Check out the aheinecke@7105: * documentation coming with Dive4Elements River for details. aheinecke@7105: */ aheinecke@7105: aheinecke@7105: package org.dive4elements.river.exports; aheinecke@7105: aheinecke@7157: import org.dive4elements.river.artifacts.D4EArtifact; aheinecke@7157: import org.dive4elements.artifactdatabase.state.ArtifactAndFacet; aheinecke@7157: import org.dive4elements.river.jfree.Bounds; aheinecke@7157: import org.dive4elements.river.themes.ThemeDocument; andre@8723: import org.dive4elements.river.artifacts.model.FacetTypes; andre@8730: import org.dive4elements.river.artifacts.access.RiverAccess; andre@8730: import org.dive4elements.river.artifacts.model.ZoomScale; andre@8730: import org.dive4elements.river.artifacts.context.RiverContext; andre@8730: import org.dive4elements.river.artifacts.resources.Resources; andre@8723: andre@8723: import org.jfree.data.Range; andre@8723: andre@8723: import java.util.List; andre@8723: import java.util.ArrayList; andre@8723: andre@8723: import org.apache.log4j.Logger; aheinecke@7157: aheinecke@7105: public class LongitudinalSectionGenerator2 extends DiagramGenerator aheinecke@7105: { tom@8856: private static Logger log = Logger.getLogger( tom@8856: LongitudinalSectionGenerator2.class); andre@8723: andre@8723: /** Wrapper around the doOut info for postprocessing. */ andre@8723: protected static class SuperBundle andre@8723: { andre@8723: public ArtifactAndFacet bundle; andre@8723: public ThemeDocument theme; andre@8723: boolean visible; tom@8856: public SuperBundle( tom@8856: ArtifactAndFacet bundle, tom@8856: ThemeDocument theme, tom@8856: boolean visible tom@8856: ) { andre@8723: this.bundle = bundle; andre@8723: this.theme = theme; andre@8723: this.visible = visible; andre@8723: } andre@8723: }; andre@8723: andre@8723: protected List postOutAF; andre@8723: aheinecke@7105: public static final String I18N_CHART_SHORT_SUBTITLE = aheinecke@7105: "chart.longitudinal.section.shortsubtitle"; aheinecke@7105: aheinecke@7105: public static final String I18N_CHART_LOCATION_SUBTITLE = aheinecke@7105: "chart.longitudinal.section.locsubtitle"; aheinecke@7105: andre@8730: public static final String I18N_CHART_DISTANCE_SUBTITLE = andre@8730: "chart.longitudinal.section.subtitle"; andre@8730: andre@8730: public static final String I18N_SUBTITLE_RADIUS = andre@8730: "chart.subtitle.radius"; andre@8730: andre@8730: @Override aheinecke@7105: public String getDefaultChartSubtitle() { aheinecke@7105: double[] dist = getRange(); andre@8730: rrenkert@7807: String parts = ""; rrenkert@7807: if (subTitleParts != null && !subTitleParts.isEmpty()) { rrenkert@7807: for (String p : subTitleParts) { andre@8730: parts += " " + p; rrenkert@7807: } rrenkert@7807: } aheinecke@7105: if (dist == null || dist.length != 2 || aheinecke@7105: Double.isNaN(dist[0]) || Double.isNaN(dist[1])) { teichmann@7118: Object [] args = new Object[] {getRiverName()}; rrenkert@7807: return msg(I18N_CHART_SHORT_SUBTITLE, "", args) + parts; teichmann@7118: } teichmann@7118: teichmann@7118: if (Math.abs(dist[0] - dist[1]) < 1E-5) { teichmann@7118: Object [] args = new Object[] {getRiverName(), dist[1]}; rrenkert@7807: return msg(I18N_CHART_LOCATION_SUBTITLE, "", args) + parts; aheinecke@7105: } andre@8730: Object [] args = new Object[] {getRiverName(), dist[0], dist[1]}; andre@8730: return msg(I18N_CHART_DISTANCE_SUBTITLE, "", args) + parts; aheinecke@7105: } aheinecke@7157: andre@8723: protected void calculateRadius() { andre@8723: // Fixed range in settings is preferred andre@8723: Range candidate = getRangeForAxisFromSettings("X"); andre@8723: Bounds dataBounds = getXBounds(0); andre@8723: if (candidate == null) { andre@8723: candidate = getDomainAxisRange(); // Diagram is zoomed andre@8723: if (candidate != null && dataBounds == null) { andre@8723: log.debug("Can't calculate the zoom without any X bounds."); andre@8723: candidate = null; andre@8723: } else if (candidate != null) { andre@8723: // domainAxisRange is relative so we have to take andre@8723: // this into account. andre@8723: Bounds bounds = andre@8723: calculateZoom(dataBounds, candidate); andre@8723: candidate = new Range(bounds.getLower().doubleValue(), andre@8723: bounds.getUpper().doubleValue()); andre@8723: log.debug("Using X Range from zoom."); andre@8723: } andre@8723: } else { andre@8723: log.debug("Using X Range from settings."); andre@8723: } andre@8723: andre@8723: if (candidate == null) { andre@8723: if (dataBounds == null) { andre@8723: // Diagram is empty. andre@8723: candidate = new Range(0d, 0d); andre@8725: log.debug("Empty diagram using fake Range"); andre@8725: } else { andre@8725: // Diagram is not zoomed andre@8725: candidate = new Range(dataBounds.getLower().doubleValue(), andre@8725: dataBounds.getUpper().doubleValue()); andre@8725: log.debug("Using Full X Range."); andre@8723: } andre@8723: } andre@8723: log.debug("startkm for Radius is: " + candidate.getLowerBound() + andre@8723: " endkm: " + candidate.getUpperBound()); andre@8730: andre@8730: // This might not be neccessary if every facet uses only the andre@8730: // radius and does not do its own zoomscale calculation. andre@8723: context.putContextValue("startkm", candidate.getLowerBound()); andre@8723: context.putContextValue("endkm", candidate.getUpperBound()); andre@8723: context.putContextValue("bounds_defined", true); andre@8730: andre@8730: RiverContext fc = (RiverContext)context.globalContext(); andre@8730: ZoomScale scales = (ZoomScale)fc.get("zoomscale"); andre@8730: RiverAccess access = new RiverAccess((D4EArtifact)getMaster()); andre@8730: String river = access.getRiverName(); andre@8730: andre@8730: double radius = scales.getRadius(river, candidate.getLowerBound(), andre@8730: candidate.getUpperBound()); andre@8730: context.putContextValue("radius", radius); andre@8723: } andre@8723: andre@8723: @Override andre@8723: protected void postProcess() { andre@8723: if (postOutAF == null) { andre@8723: log.debug("PostProcess without bundles to process"); andre@8723: return; andre@8723: } andre@8723: andre@8723: // fake startkm and endkm for the dry run andre@8723: context.putContextValue("startkm", 0d); andre@8723: context.putContextValue("endkm", 42d); andre@8723: for (SuperBundle superbundle: postOutAF) { tom@8789: // Dry run with fake start /end andre@8723: // to get the filtered facets also included andre@8723: // in the x axis range. andre@8723: super.doOut(superbundle.bundle, superbundle.theme, false); andre@8723: } andre@8723: andre@8723: calculateRadius(); // This calculates the real start and end km's andre@8730: andre@8723: for (SuperBundle superbundle: postOutAF) { tom@8856: super.doOut( tom@8856: superbundle.bundle, tom@8856: superbundle.theme, tom@8856: superbundle.visible); andre@8723: } andre@8723: } andre@8723: aheinecke@7157: /* We override doOut here to save the startkm and endkm in the aheinecke@7157: * context. Some facets will deliver different data because of aheinecke@7157: * that setting. It is mainly used in MINFO where it causes aheinecke@7157: * adaptive smoothing on the data if you are zoomed out do aheinecke@7157: * reduce the static in the curve. */ aheinecke@7157: @Override aheinecke@7157: public void doOut( aheinecke@7157: ArtifactAndFacet bundle, aheinecke@7157: ThemeDocument theme, aheinecke@7157: boolean visible aheinecke@7157: ) { andre@8723: String facetName = bundle.getFacetName(); andre@8723: if (FacetTypes.IS.FILTERED(facetName)) { andre@8723: // We can only process the filtered (smoothed) facets andre@8723: // after we know the diagram's extend to correctly calculate andre@8723: // the radius of the filter / smoothing operation. So andre@8723: // we postprocess them. andre@8723: andre@8723: SuperBundle superbundle = new SuperBundle(bundle, theme, visible); andre@8723: if (postOutAF == null) { andre@8723: postOutAF = new ArrayList(); andre@8723: } andre@8723: postOutAF.add(superbundle); andre@8731: if (visible) { andre@8731: log.debug("Adding radius subtitle."); andre@8731: andre@8731: addSubtitle(Resources.getMsg( andre@8731: getCallContext().getMeta(), tom@8737: I18N_SUBTITLE_RADIUS) + ": $RADIUS"); andre@8731: } rrenkert@7877: return; rrenkert@7877: } aheinecke@7157: super.doOut(bundle, theme, visible); aheinecke@7157: } aheinecke@7105: } aheinecke@7105: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :