/* This program 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, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.opentripplanner.graph_builder.impl.ned; import java.util.ArrayList; import java.util.List; import org.geotools.coverage.AbstractCoverage; import org.geotools.coverage.grid.GridCoverage2D; import org.geotools.geometry.GeneralEnvelope; import org.opengis.coverage.CannotEvaluateException; import org.opengis.coverage.Coverage; import org.opengis.coverage.PointOutsideCoverageException; import org.opengis.coverage.SampleDimension; import org.opengis.geometry.DirectPosition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Stitches together multiple elevation maps into a single elevation map, * hackily. This is horrible, but the geotools way of doing things is * too slow. * @author novalis * */ public class UnifiedGridCoverage extends AbstractCoverage { private static final long serialVersionUID = -7798801307087575896L; private static Logger log = LoggerFactory.getLogger(UnifiedGridCoverage.class); private ArrayList<Coverage> regions; private List<VerticalDatum> datums; protected UnifiedGridCoverage(CharSequence name, Coverage coverage, List<VerticalDatum> datums) { super(name, coverage); regions = new ArrayList<Coverage>(); regions.add(coverage); this.datums = datums; } @Override public Object evaluate(DirectPosition point) throws PointOutsideCoverageException, CannotEvaluateException { /* we don't care about this */ return null; } public double[] evaluate(DirectPosition point, double[] values) throws PointOutsideCoverageException, CannotEvaluateException { for (Coverage region : regions) { // GeneralEnvelope has a contains method, OpenGIS Envelope does not GeneralEnvelope env = ((GeneralEnvelope)region.getEnvelope()); // avoid incurring exception construction overhead when there are many regions if (env.contains(point)) { double[] result; double x = point.getOrdinate(0); double y = point.getOrdinate(1); try { result = region.evaluate(point, values); for (VerticalDatum datum : datums) { if (datum.covers(x, y)) { result[0] += datum.interpolatedHeight(x, y); return result; } } //if we get here, all vdatums failed. log.error("Failed to convert elevation at " + y + ", " + x + " from NAVD88 to NAD83"); } catch (PointOutsideCoverageException e) { continue; } return result; } } /* not found */ log.warn("Point not found: " + point); return null; } @Override public int getNumSampleDimensions() { return regions.get(0).getNumSampleDimensions(); } @Override public SampleDimension getSampleDimension(int index) throws IndexOutOfBoundsException { return regions.get(0).getSampleDimension(index); } public void add(GridCoverage2D regionCoverage) { regions.add(regionCoverage); } }