/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2009, 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.pattern; import com.vividsolutions.jts.geom.Geometry; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import org.apache.sis.feature.builder.AttributeRole; import org.apache.sis.feature.builder.FeatureTypeBuilder; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.display2d.GO2Utilities; import org.geotoolkit.display2d.style.CachedSymbolizer; import org.geotoolkit.display2d.style.renderer.SymbolizerRendererService; import org.geotoolkit.process.Process; import org.geotoolkit.process.ProcessDescriptor; import org.geotoolkit.process.ProcessException; import org.geotoolkit.processing.coverage.coveragetovector.CoverageToVectorDescriptor; import org.apache.sis.measure.NumberRange; import org.opengis.filter.expression.Expression; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.operation.TransformException; import org.opengis.style.Symbolizer; import org.apache.sis.util.logging.Logging; import org.opengis.feature.Feature; import org.opengis.feature.FeatureType; /** * * @author Johann Sorel (Geomatys) */ public class CachedPatternSymbolizer extends CachedSymbolizer<PatternSymbolizer>{ public CachedPatternSymbolizer(final PatternSymbolizer symbol, final SymbolizerRendererService<PatternSymbolizer,? extends CachedSymbolizer<PatternSymbolizer>> renderer){ super(symbol,renderer); } public Map<Feature,List<CachedSymbolizer>> getMasks(final GridCoverage2D coverage) throws IOException, TransformException{ final Map<Feature,List<CachedSymbolizer>> features = new LinkedHashMap<>(); final Map<NumberRange,List<CachedSymbolizer>> styles = new LinkedHashMap<>(); final Map<Expression, List<Symbolizer>> categorizes = styleElement.getRanges(); final Expression[] steps = categorizes.keySet().toArray(new Expression[categorizes.size()]); Arrays.sort(steps, new Comparator<Expression>() { @Override public int compare(Expression t1, Expression t2) { if(t1 == null){ return -1; }else if(t2 == null){ return +1; } double d1 = t1.evaluate(null, Double.class); double d2 = t2.evaluate(null, Double.class); double res = d1-d2; if(res < 0){ return -1; }else if(res > 0){ return +1; }else{ return 0; } } }); //fill the numberranges ------------------------------------------------ double last = Double.NEGATIVE_INFINITY; double end = Double.POSITIVE_INFINITY; NumberRange interval; int i=0; for(;i<steps.length-1;i++){ end = steps[i+1].evaluate(null,Double.class); interval = NumberRange.create(last, true, end, false); styles.put(interval, getCached(categorizes.get(steps[i]))); last = end; } //last element end = Double.POSITIVE_INFINITY; styles.put(NumberRange.create(last, true, end, true), getCached(categorizes.get(steps[i])) ); //calculate the polygons ----------------------------------------------- final ProcessDescriptor descriptor = CoverageToVectorDescriptor.INSTANCE; final Integer band = styleElement.getChannel().evaluate(null,Integer.class); final ParameterValueGroup input = descriptor.getInputDescriptor().createValue(); input.parameter(CoverageToVectorDescriptor.COVERAGE.getName().getCode()).setValue(coverage); final Set<NumberRange> nrs = styles.keySet(); input.parameter(CoverageToVectorDescriptor.RANGES.getName().getCode()).setValue(nrs.toArray(new NumberRange[nrs.size()])); input.parameter(CoverageToVectorDescriptor.BAND.getName().getCode()).setValue(band); final Process process = descriptor.createProcess(input); final Geometry[] polygons; try { polygons = (Geometry[]) process.call().parameter( CoverageToVectorDescriptor.GEOMETRIES.getName().getCode()).getValue(); } catch (ProcessException ex) { Logging.getLogger("org.geotoolkit.display2d.ext.pattern").log(Level.WARNING, null, ex); return features; } //build the features --------------------------------------------------- final FeatureTypeBuilder sftBuilder = new FeatureTypeBuilder(); final String geometryField = "geometry"; sftBuilder.setName("DynamicFeature"); sftBuilder.addAttribute(Geometry.class).setName(geometryField).setCRS(coverage.getCoordinateReferenceSystem()).addRole(AttributeRole.DEFAULT_GEOMETRY); final FeatureType sft = sftBuilder.build(); int id = 0; for(Geometry entry : polygons){ final Feature sf = sft.newInstance(); sf.setPropertyValue(geometryField, entry); sf.setPropertyValue("@id", id++); features.put(sf, styles.get(entry.getUserData())); } return features; } private static List<CachedSymbolizer> getCached(final List<Symbolizer> symbols){ final List<CachedSymbolizer> cached = new ArrayList<CachedSymbolizer>(); if(symbols != null){ for(final Symbolizer sy : symbols){ cached.add(GO2Utilities.getCached(sy,null)); } } return cached; } @Override public float getMargin(final Object candidate, final float coeff) { return 0; } @Override protected void evaluate() { } @Override public boolean isVisible(final Object candidate) { return false; } }