view gnv-artifacts/src/main/java/de/intevation/gnv/math/QueriedXYDepth.java @ 1129:ccfa07b88476

merged geo-backend
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:14:01 +0200
parents f953c9a559d8
children
line wrap: on
line source
/*
 * Copyright (c) 2010 by Intevation GmbH
 *
 * This program is free software under the LGPL (>=v2.1)
 * Read the file LGPL.txt coming with the software for details
 * or visit http://www.gnu.org/licenses/ if it does not exist.
 */

package de.intevation.gnv.math;

import com.vividsolutions.jts.geom.Coordinate;

import de.intevation.gnv.geobackend.base.Result;

import de.intevation.gnv.geobackend.base.query.QueryExecutor;
import de.intevation.gnv.geobackend.base.query.QueryExecutorFactory;

import de.intevation.gnv.geobackend.base.query.exception.QueryException;

import de.intevation.gnv.geobackend.sde.datasources.RasterObject;

import de.intevation.gnv.utils.WKTUtils;

import java.lang.ref.SoftReference;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.log4j.Logger;

/**
 * This implementation uses the geo backend to query a depth via
 * a raster layer stored in the database.
 *
 * @author <a href="mailto:tim.englich@intevation.de">Tim Englich</a>
 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
 */
public class QueriedXYDepth
implements   XYDepth
{
    private static Logger log = Logger.getLogger(QueriedXYDepth.class);

    private static final String queryID = "rasterQuery";

    private QueryExecutor queryExecutor;

    private ArrayList<SoftReference<RasterObject>> rasterData;

    private RasterObject last;

    private int interpolation;

    /**
     * Default construtor. Interpolation method is bilinear.
     */
    public QueriedXYDepth() {
        this(RasterObject.BILINEAR);
    }

    /**
     * Constructor to create a QueriedXYDepth with a given interpolation
     * method.
     * @param interpolation The interpolation method.
     */
    public QueriedXYDepth(int interpolation) {
        this.interpolation = interpolation;
        rasterData    = new ArrayList<SoftReference<RasterObject>>();
        queryExecutor = QueryExecutorFactory.getInstance().getQueryExecutor();
    }

    public double depth(Coordinate coordinate) {
        double resultValue = Double.NaN;

        RasterObject ro = getRasterObject(coordinate);

        if (ro == null) {
            try {
                String[] filterValues =
                    new String[] { WKTUtils.toWKT(coordinate) };
                Collection<Result> result = queryExecutor.executeQuery(
                    queryID, filterValues);
                for (Result row: result) {
                    if ((ro = (RasterObject)row.getObject(0)) != null) {
                        rasterData.add(
                            new SoftReference<RasterObject>(last = ro));
                    }
                    break;
                }
            } catch (QueryException e) {
                log.error(e, e);
            }
        }
        return ro != null
            ? ro.getValue(coordinate, interpolation)
            : Double.NaN;
    }

    private RasterObject getRasterObject(Coordinate coordinate) {
        if (last != null && last.contains(coordinate)) {
            return last;
        }
        for (int i = rasterData.size()-1; i >= 0; --i) {
            SoftReference<RasterObject> ref = rasterData.get(i);
            RasterObject ro = ref.get();
            if (ro != null && ro.contains(coordinate)) {
                return last = ro;
            }
        }
        return null;
    }
}

http://dive4elements.wald.intevation.org