view artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/QualityMeasurementFactory.java @ 8587:07c9ac22f611

(issue1755) Generalise BedQuality result handling The bedquality calculation now produces a result for each time period which has BedQualityResultValues for each specific result type. Formally this was split up in density, porosity and diameter classes with some bedload diameter classes mixed in for extra fun. The intent of this commit is to allow more shared code and generic access patterns to the BedQuality results.
author Andre Heinecke <andre.heinecke@intevation.de>
date Wed, 18 Mar 2015 18:42:08 +0100
parents e4606eae8ea5
children 2e11fc7f5d35
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.Date;
import java.util.HashMap;
import java.util.Map;

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

import org.dive4elements.river.backend.SedDBSessionHolder;


public class QualityMeasurementFactory {

    private static Logger log = Logger.getLogger(QualityMeasurementFactory.class);

    private static final String SQL_BED_MEASUREMENT =
        "SELECT st.km       as km," +
        "       st.datum    as datum," +
        "       sp.tiefevon as depth1," +
        "       sp.tiefebis as depth2," +
        "       sa.d10      as d10," +
        "       sa.dm       as dm," +
        "       sa.d16      as d16," +
        "       sa.d20      as d20," +
        "       sa.d25      as d25," +
        "       sa.d30      as d30," +
        "       sa.d40      as d40," +
        "       sa.d50      as d50," +
        "       sa.d60      as d60," +
        "       sa.d70      as d70," +
        "       sa.d75      as d75," +
        "       sa.d80      as d80," +
        "       sa.d84      as d84," +
        "       sa.d90      as d90," +
        "       sa.dmin     as dmin," +
        "       sa.dmax     as dmax " +
        "FROM sohltest st " +
        "    JOIN station sn ON sn.stationid = st.stationid " +
        "    JOIN gewaesser gw ON gw.gewaesserid = sn.gewaesserid " +
        "    JOIN sohlprobe sp ON sp.sohltestid = st.sohltestid " +
        "    JOIN siebanalyse sa ON sa.sohlprobeid = sp.sohlprobeid " +
        "WHERE gw.name = :name AND " +
        "      st.km IS NOT NULL AND " +
        "      sp.tiefevon IS NOT NULL AND " +
        "      sp.tiefebis IS NOT NULL AND " + // TODO: Test if char diameter ist null.
        "      st.km BETWEEN :from - 0.001 AND :to + 0.001 AND " +
        "      st.datum BETWEEN :start AND :end " +
        "ORDER BY st.km";

    private static final String SQL_BEDLOAD_MEASUREMENT =
        "SELECT m.km    as km," +
        "       m.datum as datum," +
        "       m.dm    as dm," +
        "       m.d10   as d10," +
        "       m.d16   as d16," +
        "       m.d20   as d20," +
        "       m.d25   as d25," +
        "       m.d30   as d30," +
        "       m.d40   as d40," +
        "       m.d50   as d50," +
        "       m.d60   as d60," +
        "       m.d70   as d70," +
        "       m.d75   as d75," +
        "       m.d80   as d80," +
        "       m.d84   as d84," +
        "       m.d90   as d90," +
        "       m.dmin  as dmin," +
        "       m.dmax  as dmax " +
        "FROM messung m" +
        "    JOIN station sn ON sn.stationid = m.stationid" +
        "    JOIN gewaesser gw ON gw.gewaesserid = sn.gewaesserid " +
        "WHERE gw.name = :name AND " +
        "      m.km IS NOT NULL AND " +
        "      m.d10 IS NOT NULL AND" + //TODO: Add all other char. diameter.
        "      m.km BETWEEN :from - 0.001 AND :to + 0.001 AND" +
        "      m.datum BETWEEN :start AND :end " +
        "ORDER BY m.km";

    /** Transform query result into objects, use INSTANCE singleton. */
    public static final class QualityMeasurementResultTransformer
    extends BasicTransformerAdapter {

        // Make a singleton
        public static QualityMeasurementResultTransformer INSTANCE =
            new QualityMeasurementResultTransformer();

        private QualityMeasurementResultTransformer() {
        }

        /** tuples is a row. */
        @Override
        public Object transformTuple(Object[] tuple, String[] aliases) {
            Map<String, Double> map = new HashMap<String, Double>();
            double km = 0;
            Date d = null;
            double depth1 = Double.NaN;
            double depth2 = Double.NaN;
            for (int i = 0; i < tuple.length; ++i) {
                if (tuple[i] != null) {
                    if (aliases[i].equals("km")) {
                        km = ((Number) tuple[i]).doubleValue();
                    }
                    else if (aliases[i].equals("datum")) {
                        d = (Date) tuple[i];
                    }
                    else if (aliases[i].equals("depth1")) {
                        depth1 = ((Number) tuple[i]).doubleValue();
                    }
                    else if (aliases[i].equals("depth2")) {
                        depth2 = ((Number) tuple[i]).doubleValue();
                    }
                    else {
                        map.put(aliases[i], ((Double) tuple[i])/1000);
                    }
                }
            }
            return new QualityMeasurement(km, d, depth1, depth2, map);
        }
    } // class BasicTransformerAdapter

    private QualityMeasurementFactory() {
    }

    protected static QualityMeasurements load(
        Session session,
        String river,
        double from,
        double to,
        Date start,
        Date end,
        String statement
    ) {
        SQLQuery query = session.createSQLQuery(statement)
            .addScalar("km", StandardBasicTypes.DOUBLE)
            .addScalar("datum", StandardBasicTypes.DATE)
            .addScalar("dm", StandardBasicTypes.DOUBLE)
            .addScalar("d10", StandardBasicTypes.DOUBLE)
            .addScalar("d16", StandardBasicTypes.DOUBLE)
            .addScalar("d20", StandardBasicTypes.DOUBLE)
            .addScalar("d25", StandardBasicTypes.DOUBLE)
            .addScalar("d30", StandardBasicTypes.DOUBLE)
            .addScalar("d40", StandardBasicTypes.DOUBLE)
            .addScalar("d50", StandardBasicTypes.DOUBLE)
            .addScalar("d60", StandardBasicTypes.DOUBLE)
            .addScalar("d70", StandardBasicTypes.DOUBLE)
            .addScalar("d75", StandardBasicTypes.DOUBLE)
            .addScalar("d80", StandardBasicTypes.DOUBLE)
            .addScalar("d84", StandardBasicTypes.DOUBLE)
            .addScalar("d90", StandardBasicTypes.DOUBLE)
            .addScalar("dmin", StandardBasicTypes.DOUBLE)
            .addScalar("dmax", StandardBasicTypes.DOUBLE);

        if (statement.equals(SQL_BED_MEASUREMENT)) {
            query.addScalar("depth1", StandardBasicTypes.DOUBLE);
            query.addScalar("depth2", StandardBasicTypes.DOUBLE);
        }

        query.setString("name", river);
        query.setDouble("from", from);
        query.setDouble("to", to);
        query.setDate("start", start);
        query.setDate("end", end);

        query.setResultTransformer(
            QualityMeasurementResultTransformer.INSTANCE);

        return new QualityMeasurements(query.list());
    }

    /** Get all measurements. */
    public static QualityMeasurements getBedMeasurements(
        String river,
        double from,
        double to,
        Date start,
        Date end) {
        Session session = SedDBSessionHolder.HOLDER.get();
        try {
            return load(session, river, from, to, start, end,
            SQL_BED_MEASUREMENT);
        }
        finally {
            //session.close();
        }
    }

    public static QualityMeasurements getBedloadMeasurements(
        String river,
        double from,
        double to,
        Date start,
        Date end
    ) {
        Session session = SedDBSessionHolder.HOLDER.get();
        try {
            return load(
                session,
                river,
                from,
                to,
                start,
                end,
                SQL_BEDLOAD_MEASUREMENT);
        }
        finally {
            //session.close();
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org