/* * Geotoolkit.org - 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.processing.coverage.mathcalc; import java.util.AbstractMap; import java.util.Set; import java.util.logging.Level; import org.apache.sis.geometry.GeneralDirectPosition; import org.apache.sis.referencing.CRS; import org.opengis.coverage.Coverage; import org.opengis.filter.expression.Expression; import org.opengis.geometry.DirectPosition; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import org.opengis.util.FactoryException; import org.apache.sis.util.logging.Logging; /** * * @author Johann Sorel (Geomatys) */ public class MathCalcCoverageEvaluator implements FillCoverage.SampleEvaluator { private final GeneralDirectPosition positionGeo; private final DynamicPick pick; private final Expression exp; public MathCalcCoverageEvaluator(MathCalcCoverageEvaluator eval) throws FactoryException { this.exp = eval.exp; this.positionGeo = eval.positionGeo.clone(); this.pick = new DynamicPick(eval.pick.coverages, eval.pick.mapping, positionGeo); } public MathCalcCoverageEvaluator(Coverage[] coverages, String[] mapping, Expression exp, CoordinateReferenceSystem crs) throws FactoryException { // prepare dynamic pick object this.exp = exp; positionGeo = new GeneralDirectPosition(crs); pick = new DynamicPick(coverages, mapping, positionGeo); } @Override public void evaluate(DirectPosition position, double[] sampleBuffer) { //update pick object position before evaluation positionGeo.setLocation(position); sampleBuffer[0] = exp.evaluate(pick, Double.class); } @Override public FillCoverage.SampleEvaluator copy() throws FactoryException { return new MathCalcCoverageEvaluator(this); } private static class DynamicPick extends AbstractMap{ private final Coverage[] coverages; private final String[] mapping; private final MathTransform[] baseToCoverage; private final GeneralDirectPosition[] coverageCoord; private final DirectPosition coord; private final double[] sampleBuffer; private DynamicPick(Coverage[] coverages, String[] mapping, DirectPosition coord) throws FactoryException{ this.coverages = coverages; this.mapping = mapping; this.coord = coord; this.sampleBuffer = new double[coverages[0].getNumSampleDimensions()]; baseToCoverage = new MathTransform[coverages.length]; coverageCoord = new GeneralDirectPosition[coverages.length]; for(int i=0;i<coverages.length;i++){ baseToCoverage[i] = CRS.findOperation(coord.getCoordinateReferenceSystem(), coverages[i].getCoordinateReferenceSystem(), null).getMathTransform(); coverageCoord[i] = new GeneralDirectPosition(coverages[i].getCoordinateReferenceSystem()); } } @Override public Object get(Object key) { //search the coverage for given name final String name = String.valueOf(key); int index = -1; for(int i=0;i<mapping.length;i++){ if(mapping[i].equals(name)){ index = i; try { baseToCoverage[i].transform(coord, coverageCoord[i]); } catch (Exception ex) { Logging.getLogger("org.geotoolkit.processing.coverage.mathcalc").log(Level.WARNING, ex.getMessage(), ex); return Double.NaN; } break; } } if(index<0){ // no coverage for this name return Double.NaN; } //find value at given coordinate coverages[index].evaluate(coverageCoord[index],sampleBuffer); return sampleBuffer[0]; } @Override public Set entrySet() { throw new UnsupportedOperationException("Not supported."); } } }