/* * Constellation - An open source and standard compliant SDI * http://www.constellation-sdi.org * * Copyright 2014 Geomatys. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.constellation.json.binding; import org.constellation.json.util.StyleUtilities; import org.geotoolkit.filter.DefaultLiteral; import org.geotoolkit.style.StyleConstants; import org.geotoolkit.style.function.Method; import org.geotoolkit.style.function.Mode; import java.awt.*; import java.util.ArrayList; import java.util.List; import static org.apache.sis.util.ArgumentChecks.ensureNonNull; import static org.constellation.json.util.StyleFactories.SF; import static org.constellation.json.util.StyleUtilities.listType; /** * @author Fabien Bernard (Geomatys). * @version 0.9 * @since 0.9 */ public final class Interpolate implements Function { private static final long serialVersionUID = 1L; private List<InterpolationPoint> points = new ArrayList<InterpolationPoint>(); private Double interval; private String nanColor; public Interpolate() { } public Interpolate(final org.geotoolkit.style.function.Interpolate interpolate) { ensureNonNull("interpolate", interpolate); if (interpolate.getInterpolationPoints() != null) { for (final org.geotoolkit.style.function.InterpolationPoint point : interpolate.getInterpolationPoints()) { this.points.add(new InterpolationPoint(point)); if (nanColor == null && point.getData() instanceof Double && Double.isNaN((double) point.getData())) { if (point.getValue() instanceof DefaultLiteral) { final Object colorHex = ((DefaultLiteral) point.getValue()).getValue(); nanColor = StyleUtilities.toHex(((Color) colorHex)); } } } this.interval = (double) interpolate.getInterpolationPoints().size(); } } public List<InterpolationPoint> getPoints() { return points; } public void setPoints(final List<InterpolationPoint> points) { this.points = points; } /** * Calculate points for palette and return the list of interpolation points. * @return {@code List<InterpolationPoint>} */ public List<InterpolationPoint> reComputePoints(final Integer nbPoints) { //remove nan point if exists because it is added later, and it cause error for max/min values final List<InterpolationPoint> nullPoints = new ArrayList<>(); for (final InterpolationPoint ip : points) { if(ip.getData() == null){ nullPoints.add(ip); } } points.removeAll(nullPoints); final org.geotoolkit.style.function.Interpolate inter = SF.interpolateFunction(StyleConstants.DEFAULT_CATEGORIZE_LOOKUP, listType(points), Method.COLOR, Mode.LINEAR, StyleConstants.DEFAULT_FALLBACK); Double min = null, max= null; // Iteration to find min and max values for (final InterpolationPoint ip : points) { if(min==null && max==null){ min = ip.getData().doubleValue(); max = ip.getData().doubleValue(); } min = Math.min(min,ip.getData().doubleValue()); max = Math.max(max,ip.getData().doubleValue()); } //init final InterpolationPoint list and coefficient final List<InterpolationPoint> recomputePoints = new ArrayList<>(); if(nanColor !=null){ final InterpolationPoint nanPoint = new InterpolationPoint(); nanPoint.setColor(nanColor); nanPoint.setData(Double.NaN); recomputePoints.add(nanPoint); } if(max !=null && min != null){ double coefficient = max-min; if(nbPoints!=null){ if(coefficient!=1){ coefficient = coefficient/(nbPoints-1); } // Loop to create points with new point evaluation for (int i = 0; i < nbPoints; i++) { final double val = min + (coefficient * i); final Color color = inter.evaluate(val, Color.class); final InterpolationPoint point = new InterpolationPoint(); point.setColor(StyleUtilities.toHex(color)); point.setData(val); recomputePoints.add(point); } } } return recomputePoints; } public double getInterval() { return interval; } public void setInterval(Double interval) { this.interval = interval; } public String getNanColor() { return nanColor; } public void setNanColor(String nanColor) { this.nanColor = nanColor; } public org.opengis.filter.expression.Function toType() { //remove nan point if exists because it is added later, and it cause error for max/min values final List<InterpolationPoint> nullPoints = new ArrayList<>(); for (final InterpolationPoint ip : points) { if (ip.getData() == null) { nullPoints.add(ip); } } points.removeAll(nullPoints); if (nanColor != null) { final InterpolationPoint nanPoint = new InterpolationPoint(); nanPoint.setColor(nanColor); nanPoint.setData(Double.NaN); points.add(nanPoint); } return SF.interpolateFunction(StyleConstants.DEFAULT_CATEGORIZE_LOOKUP, listType(points), Method.COLOR, Mode.LINEAR, StyleConstants.DEFAULT_FALLBACK); } }