/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2014, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.display2d.ext.isoline.symbolizer; import org.apache.sis.util.logging.Logging; import org.geotoolkit.display2d.GO2Utilities; import org.geotoolkit.display2d.style.*; import org.geotoolkit.display2d.style.renderer.SymbolizerRendererService; import org.geotoolkit.process.ProcessDescriptor; import org.geotoolkit.process.ProcessFinder; import org.geotoolkit.processing.coverage.CoverageProcessingRegistry; import org.geotoolkit.processing.coverage.isoline2.IsolineDescriptor2; import org.geotoolkit.style.function.Categorize; import org.geotoolkit.style.function.Interpolate; import org.geotoolkit.style.function.InterpolationPoint; import org.geotoolkit.style.function.Jenks; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Function; import org.opengis.style.ColorMap; import org.opengis.style.RasterSymbolizer; import org.opengis.util.NoSuchIdentifierException; import java.awt.*; import java.util.*; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; /** * @author Quentin Boileau (Geomatys) */ public class CachedIsolineSymbolizer extends CachedSymbolizer<IsolineSymbolizer> { private static final Logger LOGGER = Logging.getLogger("org.geotoolkit.display2d.ext.isoline.symbolizer"); private CachedRasterSymbolizer cachedRS; private ProcessDescriptor isolineDesc; private double[] steps = null; private boolean dynamicColorMap = false; public CachedIsolineSymbolizer(IsolineSymbolizer symbol, SymbolizerRendererService service) { super(symbol, service); RasterSymbolizer rasterSymbolizer = styleElement.getRasterSymbolizer(); if (rasterSymbolizer != null) { this.cachedRS = (CachedRasterSymbolizer) GO2Utilities.getCached(rasterSymbolizer, null); this.steps = extractSteps(rasterSymbolizer); } else { this.cachedRS = null; } try { this.isolineDesc = ProcessFinder.getProcessDescriptor(CoverageProcessingRegistry.NAME, IsolineDescriptor2.NAME); } catch (NoSuchIdentifierException e) { LOGGER.log(Level.WARNING, e.getMessage(), e); } } /** * {@inheritDoc } */ @Override public float getMargin(Object candidate, float coeff) { return cachedRS.getMargin(candidate, coeff); } /** * {@inheritDoc } */ @Override protected void evaluate() { if(!isNotEvaluated) return; if (cachedRS != null) { cachedRS.evaluate(); } isNotEvaluated = false; } /** * {@inheritDoc } */ @Override public boolean isStatic(){ return cachedRS.isStatic(); } /** * {@inheritDoc } */ @Override public VisibilityState isStaticVisible(){ return cachedRS.isStaticVisible(); } /** * {@inheritDoc } */ @Override public boolean isVisible(Object candidate) { return cachedRS.isVisible(candidate); } public CachedRasterSymbolizer getCachedRasterSymbolizer() { return cachedRS; } public ProcessDescriptor getIsolineDesc() { return isolineDesc; } public double[] getSteps() { if (!dynamicColorMap && steps != null) { return steps; } else { if (getCachedRasterSymbolizer() != null) { return extractSteps(getCachedRasterSymbolizer().getSource()); } } return new double[0]; } /** * Extract isolines steps from RasterSymbolizer ColorMap. * @param rasterSymbolizer * @return */ private double[] extractSteps(RasterSymbolizer rasterSymbolizer) { Set<Double> steps = new HashSet<Double>(); if (rasterSymbolizer != null && rasterSymbolizer.getColorMap() != null) { ColorMap colorMap = rasterSymbolizer.getColorMap(); Function function = colorMap.getFunction(); if (function instanceof Interpolate) { Interpolate interpolate = (Interpolate) function; List<InterpolationPoint> points = interpolate.getInterpolationPoints(); for (InterpolationPoint point : points) { steps.add(point.getData().doubleValue()); } dynamicColorMap = false; } else if (function instanceof Categorize) { Categorize categorize = (Categorize) function; Map<Expression, Expression> thresholds = categorize.getThresholds(); for (Map.Entry<Expression, Expression> entry : thresholds.entrySet()) { Expression key = entry.getKey(); Double step = key.evaluate(null, Double.class); if (step!= null && !step.isNaN() && !step.isInfinite()) { steps.add(step); } } dynamicColorMap = false; } else if (function instanceof Jenks) { Jenks jenks = (Jenks) function; Map<Double, Color> jenksColorMap = jenks.getColorMap(); if (jenksColorMap != null) { for (Double jenksStep : jenksColorMap.keySet()) { if (jenksStep != null && !jenksStep.isNaN()) { steps.add(jenksStep); } } } dynamicColorMap = true; } } int i = 0; Iterator<Double> iterator = steps.iterator(); double[] stepsArray = new double[steps.size()]; while (iterator.hasNext()) { stepsArray[i++] = iterator.next(); } return stepsArray; } }