ingo@1115: /*
ingo@1115: * Copyright (c) 2010 by Intevation GmbH
ingo@1115: *
ingo@1115: * This program is free software under the LGPL (>=v2.1)
ingo@1115: * Read the file LGPL.txt coming with the software for details
ingo@1115: * or visit http://www.gnu.org/licenses/ if it does not exist.
ingo@1115: */
ingo@1115:
tim@455: package de.intevation.gnv.math;
tim@455:
sascha@779: import com.vividsolutions.jts.geom.Coordinate;
sascha@779:
sascha@779: import de.intevation.gnv.geobackend.base.Result;
sascha@779:
sascha@779: import de.intevation.gnv.geobackend.base.query.QueryExecutor;
sascha@779: import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;
sascha@779:
sascha@779: import de.intevation.gnv.geobackend.base.query.exception.QueryException;
sascha@779:
sascha@779: import de.intevation.gnv.geobackend.sde.datasources.RasterObject;
sascha@779:
sascha@779: import de.intevation.gnv.utils.WKTUtils;
sascha@779:
sascha@779: import java.lang.ref.SoftReference;
sascha@779:
tim@457: import java.util.ArrayList;
tim@455: import java.util.Collection;
tim@455:
tim@455: import org.apache.log4j.Logger;
tim@455:
tim@455: /**
sascha@805: * This implementation uses the geo backend to query a depth via
sascha@805: * a raster layer stored in the database.
sascha@805: *
sascha@780: * @author Tim Englich
sascha@780: * @author Sascha L. Teichmann
tim@455: */
sascha@805: public class QueriedXYDepth
sascha@805: implements XYDepth
sascha@805: {
tim@455: private static Logger log = Logger.getLogger(QueriedXYDepth.class);
sascha@778:
sascha@458: private static final String queryID = "rasterQuery";
sascha@778:
sascha@458: private QueryExecutor queryExecutor;
sascha@778:
sascha@458: private ArrayList> rasterData;
sascha@462:
sascha@462: private RasterObject last;
sascha@463:
sascha@463: private int interpolation;
sascha@778:
sascha@805: /**
sascha@805: * Default construtor. Interpolation method is bilinear.
sascha@805: */
tim@455: public QueriedXYDepth() {
sascha@463: this(RasterObject.BILINEAR);
sascha@463: }
sascha@463:
sascha@805: /**
sascha@805: * Constructor to create a QueriedXYDepth with a given interpolation
sascha@805: * method.
sascha@805: * @param interpolation The interpolation method.
sascha@805: */
sascha@463: public QueriedXYDepth(int interpolation) {
sascha@463: this.interpolation = interpolation;
sascha@458: rasterData = new ArrayList>();
sascha@458: queryExecutor = QueryExecutorFactory.getInstance().getQueryExecutor();
tim@455: }
tim@455:
tim@455: public double depth(Coordinate coordinate) {
tim@457: double resultValue = Double.NaN;
sascha@778:
sascha@458: RasterObject ro = getRasterObject(coordinate);
sascha@778:
sascha@458: if (ro == null) {
tim@457: try {
sascha@801: String[] filterValues =
sascha@801: new String[] { WKTUtils.toWKT(coordinate) };
sascha@801: Collection result = queryExecutor.executeQuery(
sascha@801: queryID, filterValues);
sascha@458: for (Result row: result) {
sascha@458: if ((ro = (RasterObject)row.getObject(0)) != null) {
sascha@801: rasterData.add(
sascha@801: new SoftReference(last = ro));
sascha@458: }
sascha@458: break;
sascha@458: }
tim@457: } catch (QueryException e) {
sascha@458: log.error(e, e);
tim@457: }
tim@457: }
sascha@458: return ro != null
sascha@463: ? ro.getValue(coordinate, interpolation)
sascha@778: : Double.NaN;
tim@455: }
sascha@778:
sascha@463: private RasterObject getRasterObject(Coordinate coordinate) {
sascha@462: if (last != null && last.contains(coordinate)) {
sascha@462: return last;
sascha@462: }
sascha@458: for (int i = rasterData.size()-1; i >= 0; --i) {
sascha@458: SoftReference ref = rasterData.get(i);
sascha@458: RasterObject ro = ref.get();
sascha@462: if (ro != null && ro.contains(coordinate)) {
sascha@462: return last = ro;
tim@457: }
tim@457: }
tim@457: return null;
tim@457: }
sascha@836: }