view artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentDensityFactory.java @ 6152:0587819960c3

Waterlevel differences & bed height differences: Add new model LinearInterpolated intented to unify the two very similiar calculations. The focus of the current implementation is correctness and not speed! The fact that the data sets more mostly sorted by station is not exploited. Doing so would improve performance significantly.
author Sascha L. Teichmann <teichmann@intevation.de>
date Sun, 02 Jun 2013 17:52:53 +0200
parents af13ceeba52a
children 51f28e5417ee
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.artifacts.model.minfo;

import java.util.List;

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;

import org.apache.log4j.Logger;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.type.StandardBasicTypes;

import org.dive4elements.river.artifacts.cache.CacheFactory;
import org.dive4elements.river.backend.SessionHolder;


public class SedimentDensityFactory
{
    /** Private logger to use here. */
    private static Logger log = Logger.getLogger(SedimentDensityFactory.class);

    private static final String DENSITY_CACHE_NAME = "sedimentdensity";

    /**Query to get sediment density values and kms. */
    private static final String SQL_SELECT_DENSITY =
        "SELECT sdv.station AS km, " +
        "       sdv.density AS density," +
        "       sdv.year AS year " +
        "   FROM sediment_density sd" +
        "       JOIN rivers r ON sd.river_id = r.id " +
        "       JOIN sediment_density_values sdv ON sd.id = sdv.sediment_density_id" +
        "   WHERE r.name = :name";

    private SedimentDensityFactory() {}

    public static SedimentDensity getSedimentDensity(
        String river,
        double startKm,
        double endKm,
        int year
    ) {
        log.debug("getSedimentDensity");
        Cache cache = CacheFactory.getCache(DENSITY_CACHE_NAME);

        if (cache == null) {
            log.debug("Cache not configured.");
            return getSedimentDensityUncached(river, startKm, endKm, year);
        }

        String key = river + startKm + endKm;
        Element element = cache.get(key);
        if (element != null) {
            log.debug("SedimentDensity found in cache!");
            return (SedimentDensity)element.getValue();
        }
        SedimentDensity value =
            getSedimentDensityUncached(river, startKm, endKm, year);

        if (value != null && key != null) {
            log.debug("Store sediment density values in cache.");
            element = new Element(key, value);
            cache.put(element);
        }
        return value;
    }

    private static SedimentDensity getSedimentDensityUncached(
        String river,
        double startKm,
        double endKm,
        int year
    ) {
        log.debug("getSedimentDensityUncached");
        List<Object[]> results = null;
        Session session = SessionHolder.HOLDER.get();
        SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_DENSITY)
            .addScalar("km", StandardBasicTypes.DOUBLE)
            .addScalar("density", StandardBasicTypes.DOUBLE)
            .addScalar("year", StandardBasicTypes.INTEGER);
        sqlQuery.setString("name", river);
        results = sqlQuery.list();
        SedimentDensity density = new SedimentDensity();
        for (Object[] row : results) {
            if (row[0] != null && row[1] != null && row[2] != null) {
                density.addDensity((Double)row[0], (Double)row[1], (Integer)row[2]);
            }
        }

        density.cleanUp();
        return density;
    }
}

http://dive4elements.wald.intevation.org