sascha@2561: package de.intevation.flys.artifacts.model; sascha@2561: sascha@2561: import java.io.Serializable; sascha@2561: sascha@2561: import java.text.SimpleDateFormat; sascha@2561: sascha@2561: import java.util.ArrayList; sascha@2561: import java.util.Collections; sascha@2561: import java.util.Comparator; sascha@2561: import java.util.Date; sascha@2561: import java.util.HashMap; sascha@2561: import java.util.List; sascha@2561: import java.util.Map; sascha@2561: sascha@2561: import org.apache.log4j.Logger; sascha@2561: sascha@2561: import org.hibernate.SQLQuery; sascha@2561: import org.hibernate.Session; sascha@2561: sascha@2561: import org.hibernate.type.StandardBasicTypes; sascha@2561: sascha@2561: import org.w3c.dom.Document; sascha@2561: import org.w3c.dom.Element; sascha@2561: sascha@2561: public class FixingsOverview sascha@2561: implements Serializable sascha@2561: { sascha@2561: private static Logger log = Logger.getLogger(FixingsOverview.class); sascha@2561: sascha@2561: public static final double EPSILON = 1e-5; sascha@2561: public static final double EPSILON2 = 1e-1; sascha@2561: sascha@2632: public static final String DATE_FORMAT = "dd.MM.yyyy"; sascha@2564: sascha@2561: public static final String SQL_RIVER_ID = sascha@2561: "SELECT" + sascha@2561: " id AS river_id," + sascha@2561: " km_up " + sascha@2561: "FROM rivers " + sascha@2561: "WHERE" + sascha@2561: " name = :name"; sascha@2561: sascha@2561: public static final String SQL_GAUGES = sascha@2561: "SELECT" + sascha@2561: " g.id AS gauge_id," + sascha@2561: " r.a AS a," + sascha@2561: " r.b AS b " + sascha@2561: "FROM gauges g" + sascha@2561: " JOIN ranges r ON g.range_id = r.id " + sascha@2561: "WHERE" + sascha@2561: " g.river_id = :river_id " + sascha@2561: "ORDER BY r.a"; sascha@2561: sascha@2561: public static final String SQL_DISCHARGE_SECTORS = sascha@2561: "SELECT" + sascha@2561: " g.id AS gauge_id," + sascha@2561: " nmv.name AS name," + sascha@2561: " CAST(mv.value AS NUMERIC(38,2)) AS value " + sascha@2561: "FROM gauges g" + sascha@2561: " JOIN main_values mv ON g.id = mv.gauge_id" + sascha@2561: " JOIN named_main_values nmv ON nmv.id = mv.named_value_id" + sascha@2561: " JOIN main_value_types mvt ON nmv.type_id = mvt.id " + sascha@2561: "WHERE" + sascha@2561: " mvt.name = 'Q' AND (" + sascha@2561: " nmv.name = 'MNQ' OR" + sascha@2561: " nmv.name LIKE 'MNQ(%' OR" + sascha@2561: " nmv.name = 'MQ' OR" + sascha@2561: " nmv.name LIKE 'MQ(%' OR" + sascha@2561: " nmv.name = 'MHQ' OR" + sascha@2561: " nmv.name LIKE 'MHQ(%' OR" + sascha@2561: " nmv.name = 'HQ5' OR" + sascha@2561: " nmv.name LIKE 'HQ5(%') AND" + sascha@2561: " g.river_id = :river_id " + sascha@2561: "ORDER BY" + sascha@2561: " g.id"; sascha@2561: sascha@2561: public static final String SQL_FIXINGS = sascha@2561: "SELECT" + sascha@2561: " id AS wst_id," + sascha@2561: " description " + sascha@2561: "FROM wsts " + sascha@2561: "WHERE" + sascha@2561: " river_id = :river_id AND kind = 2"; sascha@2561: sascha@2561: public static final String SQL_FIXING_COLUMNS = sascha@2561: "SELECT" + sascha@2561: " wc.id AS wst_column_id," + sascha@2561: " ti.start_time AS start_time," + sascha@2561: " wc.name AS name " + sascha@2561: "FROM wst_columns wc" + sascha@2561: " JOIN time_intervals ti ON wc.time_interval_id = ti.id " + sascha@2561: "WHERE" + sascha@2561: " wc.wst_id = :wst_id " + sascha@2561: "ORDER BY position"; sascha@2561: sascha@2561: public static final String SQL_FIXING_COLUMN_Q_RANGES = sascha@2561: "SELECT" + sascha@2561: " wqr.q AS q," + sascha@2561: " r.a AS start_km," + sascha@2561: " r.b AS stop_km " + sascha@2561: "FROM wst_column_q_ranges wcqr" + sascha@2561: " JOIN wst_q_ranges wqr ON wcqr.wst_q_range_id = wqr.id" + sascha@2561: " JOIN ranges r ON wqr.range_id = r.id " + sascha@2561: "WHERE" + sascha@2561: " wcqr.wst_column_id = :column_id " + sascha@2561: "ORDER BY r.a"; sascha@2561: sascha@2561: public static final String SQL_FIXING_COLUMN_KM_RANGE = sascha@2561: "SELECT" + sascha@2561: " MIN(position) AS start_km," + sascha@2561: " MAX(position) AS stop_km " + sascha@2561: "FROM" + sascha@2561: " wst_column_values " + sascha@2562: "WHERE" + sascha@2561: " wst_column_id = :column_id"; sascha@2561: sascha@2561: public static class Range implements Serializable { sascha@2561: sascha@2561: protected double start; sascha@2561: protected double end; sascha@2561: sascha@2561: public Range() { sascha@2561: } sascha@2561: sascha@2561: public Range(double start, double end) { sascha@2561: this.start = start; sascha@2561: this.end = end; sascha@2561: } sascha@2561: sascha@2562: public double getStart() { sascha@2562: return start; sascha@2562: } sascha@2562: sascha@2562: public double getEnd() { sascha@2562: return end; sascha@2562: } sascha@2562: sascha@2561: public boolean disjoint(Range other) { sascha@2561: return start > other.end || other.start > end; sascha@2561: } sascha@2561: sascha@2562: public boolean intersects(Range other) { sascha@2562: return !disjoint(other); sascha@2562: } sascha@2562: sascha@2565: public void extend(Range other) { sascha@2565: if (other.start < start) start = other.start; sascha@2565: if (other.end > end ) end = other.end; sascha@2565: } sascha@2565: sascha@2561: public boolean clip(Range other) { sascha@2561: if (disjoint(other)) return false; sascha@2561: sascha@2561: if (other.start > start) start = other.start; sascha@2561: if (other.end < end ) end = other.end; sascha@2561: sascha@2561: return true; sascha@2561: } sascha@2561: sascha@2561: public boolean inside(double x) { sascha@2561: return x > start-EPSILON && x < end+EPSILON; sascha@2561: } sascha@2561: } // class Range sascha@2561: sascha@2561: public static class GaugeRange extends Range { sascha@2561: sascha@2561: private static final class Sector implements Serializable { sascha@2561: sascha@2561: int sector; sascha@2561: double value; sascha@2561: sascha@2561: Sector(int sector, double value) { sascha@2561: this.sector = sector; sascha@2561: this.value = value; sascha@2561: } sascha@2561: sascha@2561: } // class Sector sascha@2561: sascha@2561: protected int gaugeId; sascha@2561: sascha@2561: protected Map mainValues; sascha@2561: protected List sectors; sascha@2561: sascha@2561: public GaugeRange() { sascha@2561: } sascha@2561: sascha@2561: public GaugeRange(double start, double end, int gaugeId) { sascha@2561: super(start, end); sascha@2561: this.gaugeId = gaugeId; sascha@2561: mainValues = new HashMap(); sascha@2561: sectors = new ArrayList(3); sascha@2561: } sascha@2561: sascha@2561: public void addMainValue(String label, Double value) { sascha@2561: int idx = label.indexOf('('); sascha@2561: if (idx >= 0) { sascha@2561: label = label.substring(0, idx); sascha@2561: } sascha@2561: mainValues.put(label, value); sascha@2561: } sascha@2561: sascha@2561: protected Double getMainValue(String label) { sascha@2561: Double v = mainValues.get(label); sascha@2561: if (v == null) { sascha@2561: log.warn("Missing main value '" sascha@2561: + label + "' for gauge " + gaugeId); sascha@2561: } sascha@2561: return v; sascha@2561: } sascha@2561: sascha@2561: public void buildClasses() { sascha@2561: Double mnq = getMainValue("MNQ"); sascha@2561: Double mq = getMainValue("MQ"); sascha@2561: Double mhq = getMainValue("MHQ"); sascha@2561: Double hq5 = getMainValue("HQ5"); sascha@2561: sascha@2561: Double [][] pairs = { sascha@2561: { mnq, mq }, sascha@2561: { mq, mhq }, sascha@2561: { hq5, hq5 } }; sascha@2561: sascha@2561: for (int c = 0; c < pairs.length; ++c) { sascha@2561: Double [] pair = pairs[c]; sascha@2561: if (pair[0] != null && pair[1] != null) { sascha@2561: double value = 0.5*(pair[0] + pair[1]); sascha@2561: sectors.add(new Sector(c, value)); sascha@2561: } sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: public int classify(double value) { sascha@2561: for (Sector sector: sectors) { sascha@2561: if (value < sector.value) { sascha@2561: return sector.sector; sascha@2561: } sascha@2561: } sascha@2561: return sectors.size(); sascha@2561: } sascha@2561: } // class GaugeRange sascha@2561: sascha@2562: public static class GaugeFinder { sascha@2562: sascha@2562: protected List gauges; sascha@2562: protected boolean isKmUp; sascha@2562: sascha@2562: public GaugeFinder(List gauges) { sascha@2562: this(gauges, true); sascha@2562: } sascha@2562: sascha@2562: public GaugeFinder( sascha@2562: List gauges, sascha@2562: boolean isKmUp sascha@2562: ) { sascha@2562: this.gauges = gauges; sascha@2562: this.isKmUp = isKmUp; sascha@2562: } sascha@2562: sascha@2562: public boolean getIsKmUp() { sascha@2562: return isKmUp; sascha@2562: } sascha@2562: sascha@2562: public void setIsKmUp(boolean isKmUp) { sascha@2562: this.isKmUp = isKmUp; sascha@2562: } sascha@2562: sascha@2562: public GaugeRange find(Range range) { sascha@2562: double km = isKmUp ? range.start : range.end; sascha@2562: for (GaugeRange gauge: gauges) { sascha@2562: if (gauge.inside(km)) { sascha@2562: return gauge; sascha@2562: } sascha@2562: } sascha@2562: return null; sascha@2562: } sascha@2562: sascha@2562: public GaugeRange find(int gaugeId) { sascha@2562: for (GaugeRange gauge: gauges) { sascha@2562: if (gauge.gaugeId == gaugeId) { sascha@2562: return gauge; sascha@2562: } sascha@2562: } sascha@2562: return null; sascha@2562: } sascha@2562: sascha@2562: public boolean loadDischargeSectors(Session session, int riverId) { sascha@2562: sascha@2562: SQLQuery query = session.createSQLQuery(SQL_DISCHARGE_SECTORS) sascha@2562: .addScalar("gauge_id", StandardBasicTypes.INTEGER) sascha@2562: .addScalar("name", StandardBasicTypes.STRING) sascha@2562: .addScalar("value", StandardBasicTypes.DOUBLE); sascha@2562: sascha@2562: query.setInteger("river_id", riverId); sascha@2562: sascha@2562: List list = query.list(); sascha@2562: sascha@2562: if (list.isEmpty()) { sascha@2562: log.warn("River " + riverId + " has no discharge sectors."); sascha@2562: return false; sascha@2562: } sascha@2562: sascha@2562: GaugeRange gauge = null; sascha@2562: sascha@2562: for (Object [] row: list) { sascha@2562: int gaugeId = (Integer)row[0]; sascha@2562: String label = (String) row[1]; sascha@2562: Double value = (Double) row[2]; sascha@2562: sascha@2562: if (gauge == null || gauge.gaugeId != gaugeId) { sascha@2562: if ((gauge = find(gaugeId)) == null) { sascha@2562: log.warn("Cannot find gauge for id " + gaugeId + "."); sascha@2562: continue; sascha@2562: } sascha@2562: } sascha@2562: sascha@2562: gauge.addMainValue(label, value); sascha@2562: } sascha@2562: sascha@2562: for (GaugeRange g: gauges) { sascha@2562: g.buildClasses(); sascha@2562: } sascha@2562: sascha@2562: return true; sascha@2562: } sascha@2562: } // class GaugeFinder sascha@2562: sascha@2561: public static class QRange extends Range { sascha@2561: sascha@2561: protected double q; sascha@2561: sascha@2561: public QRange() { sascha@2561: } sascha@2561: sascha@2561: public QRange(double start, double end, double q) { sascha@2561: super(start, end); sascha@2561: this.q = q; sascha@2561: } sascha@2561: } // class QRange sascha@2561: sascha@2561: public static class SectorRange extends Range { sascha@2561: sascha@2561: protected int sector; sascha@2561: sascha@2561: public SectorRange() { sascha@2561: } sascha@2561: sascha@2562: public SectorRange(SectorRange other) { sascha@2562: start = other.start; sascha@2562: end = other.end; sascha@2562: sector = other.sector; sascha@2562: } sascha@2562: sascha@2561: public SectorRange(double start, double end, int sector) { sascha@2561: super(start, end); sascha@2561: this.sector = sector; sascha@2561: } sascha@2561: sascha@2562: public int getSector() { sascha@2562: return sector; sascha@2562: } sascha@2562: sascha@2561: public boolean enlarge(SectorRange other) { sascha@2561: if (sector == other.sector sascha@2561: && Math.abs(end-other.start) < EPSILON2) { sascha@2561: end = other.end; sascha@2561: return true; sascha@2561: } sascha@2561: return false; sascha@2561: } sascha@2561: } // class SectorRange sascha@2561: sascha@2561: public static class Fixing implements Serializable { sascha@2561: sascha@2561: public static final Comparator DATE_CMP = sascha@2561: new Comparator() { sascha@2561: @Override sascha@2561: public int compare(Column a, Column b) { sascha@2561: return a.startTime.compareTo(b.startTime); sascha@2561: } sascha@2561: }; sascha@2561: sascha@2563: public interface Filter { sascha@2563: sascha@2563: boolean accept(Column column); sascha@2563: sascha@2563: } // interface Filter sascha@2563: sascha@2561: public class Column extends Range { sascha@2561: sascha@2561: protected int columnId; sascha@2561: protected Date startTime; sascha@2561: protected String name; sascha@2561: sascha@2562: protected List sectors; sascha@2561: sascha@2561: public Column() { sascha@2561: } sascha@2561: sascha@2561: public Column(int columnId, Date startTime, String name) { sascha@2561: this.columnId = columnId; sascha@2561: this.startTime = startTime; sascha@2561: this.name = name; sascha@2561: sascha@2562: sectors = new ArrayList(); sascha@2561: } sascha@2561: sascha@2563: public int getId() { sascha@2563: return columnId; sascha@2563: } sascha@2563: sascha@2561: public Fixing getFixing() { sascha@2561: return Fixing.this; sascha@2561: } sascha@2561: sascha@2563: public Date getStartTime() { sascha@2563: return startTime; sascha@2563: } sascha@2563: sascha@2563: public String getName() { sascha@2563: return name; sascha@2563: } sascha@2563: sascha@2707: public String getDescription() { sascha@2707: return Fixing.this.description + "/" + name; sascha@2707: } sascha@2707: sascha@2562: public List getSectors() { sascha@2562: return sectors; sascha@2562: } sascha@2561: sascha@2563: public List getSectors(Range range) { sascha@2563: sascha@2563: List result = sascha@2563: new ArrayList(sectors.size()); sascha@2563: sascha@2563: for (SectorRange src: sectors) { sascha@2563: SectorRange dst = new SectorRange(src); sascha@2613: if (range == null || dst.clip(range)) { sascha@2563: result.add(dst); sascha@2563: } sascha@2563: } sascha@2563: sascha@2563: return result; sascha@2563: } sascha@2563: sascha@2562: public void buildSectors(GaugeRange gauge, List qRanges) { sascha@2561: sascha@2561: for (QRange qRange: qRanges) { sascha@2561: SectorRange sector = new SectorRange( sascha@2561: qRange.start, qRange.end, sascha@2561: gauge.classify(qRange.q)); sascha@2561: if (sectors.isEmpty() sascha@2561: || !sectors.get(sectors.size()-1).enlarge(sector)) { sascha@2561: sectors.add(sector); sascha@2561: } sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: public void loadKmRange(SQLQuery query) { sascha@2561: query.setInteger("column_id", columnId); sascha@2561: sascha@2561: List kms = query.list(); sascha@2561: sascha@2561: if (kms.isEmpty()) { sascha@2561: log.warn("No km range for column " + columnId + "."); sascha@2561: } sascha@2561: else { sascha@2561: Object [] obj = kms.get(0); sascha@2561: start = (Double)obj[0]; sascha@2561: end = (Double)obj[1]; sascha@2561: } sascha@2561: } sascha@2561: sascha@2562: public void loadQRanges( sascha@2562: SQLQuery query, sascha@2562: GaugeFinder gaugeFinder sascha@2562: ) { sascha@2561: query.setInteger("column_id", columnId); sascha@2561: List list = query.list(); sascha@2561: sascha@2562: List qRanges = new ArrayList(list.size()); sascha@2562: sascha@2561: for (Object [] row: list) { sascha@2561: double q = (Double)row[0]; sascha@2561: double start = (Double)row[1]; sascha@2561: double end = (Double)row[2]; sascha@2561: QRange qRange = new QRange(start, end, q); sascha@2561: if (qRange.clip(this)) { sascha@2561: qRanges.add(qRange); sascha@2561: } sascha@2561: } sascha@2562: sascha@2562: GaugeRange gauge = gaugeFinder.find(this); sascha@2562: sascha@2562: if (gauge != null) { sascha@2562: buildSectors(gauge, qRanges); sascha@2562: } sascha@2562: else { sascha@2562: log.warn("No gauge found for column " + columnId + "."); sascha@2562: } sascha@2561: } sascha@2561: } // class Column sascha@2561: sascha@2562: protected int wstId; sascha@2562: protected String description; sascha@2561: protected List columns; sascha@2561: sascha@2561: public Fixing() { sascha@2561: } sascha@2561: sascha@2563: public int getId() { sascha@2563: return wstId; sascha@2563: } sascha@2563: sascha@2563: public String getDescription() { sascha@2563: return description; sascha@2563: } sascha@2563: sascha@2561: public Fixing(int wstId, String description) { sascha@2561: this.wstId = wstId; sascha@2561: this.description = description; sascha@2561: columns = new ArrayList(); sascha@2561: } sascha@2561: sascha@2561: public void loadColumns(SQLQuery query) { sascha@2561: query.setInteger("wst_id", wstId); sascha@2561: List list = query.list(); sascha@2561: for (Object [] row: list) { sascha@2561: int columnId = (Integer)row[0]; sascha@2561: Date startTime = (Date) row[1]; sascha@2561: String name = (String) row[2]; sascha@2561: columns.add(new Column(columnId, startTime, name)); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: public void loadColumnsKmRange(SQLQuery query) { sascha@2561: for (Column column: columns) { sascha@2561: column.loadKmRange(query); sascha@2561: } sascha@2561: } sascha@2561: sascha@2565: public void adjustExtent(Range extent) { sascha@2565: for (Column column: columns) { sascha@2565: extent.extend(column); sascha@2565: } sascha@2565: } sascha@2565: sascha@2562: public void loadColumnsQRanges( sascha@2562: SQLQuery query, sascha@2562: GaugeFinder gaugeFinder sascha@2562: ) { sascha@2561: for (Column column: columns) { sascha@2562: column.loadQRanges(query, gaugeFinder); sascha@2561: } sascha@2561: } sascha@2561: sascha@2563: public void addAllColumns( sascha@2563: List allColumns, sascha@2563: Range range, sascha@2563: Filter filter sascha@2563: ) { sascha@2562: for (Column column: columns) { sascha@2613: if ((range == null || column.intersects(range)) sascha@2613: && (filter == null || filter.accept(column))) { sascha@2562: allColumns.add(column); sascha@2562: } sascha@2562: } sascha@2561: } sascha@2561: } // class Fixing sascha@2561: sascha@2561: sascha@2562: protected String riverName; sascha@2562: protected int riverId; sascha@2562: protected boolean isKmUp; sascha@2562: protected List fixings; sascha@2562: protected Range extent; sascha@2561: sascha@2561: public FixingsOverview() { sascha@2561: fixings = new ArrayList(); sascha@2565: extent = new Range(Double.MAX_VALUE, -Double.MAX_VALUE); sascha@2561: } sascha@2561: sascha@2561: public FixingsOverview(String riverName) { sascha@2561: this(); sascha@2561: this.riverName = riverName; sascha@2561: } sascha@2561: sascha@2561: protected boolean loadRiver(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_RIVER_ID) sascha@2561: .addScalar("river_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("km_up", StandardBasicTypes.BOOLEAN); sascha@2561: sascha@2561: query.setString("name", riverName); sascha@2561: sascha@2561: List list = query.list(); sascha@2561: sascha@2561: if (list.isEmpty()) { sascha@2561: log.warn("No river '" + riverName + "' found."); sascha@2561: return false; sascha@2561: } sascha@2561: sascha@2561: Object [] row = list.get(0); sascha@2561: sascha@2561: riverId = (Integer)row[0]; sascha@2561: isKmUp = (Boolean)row[1]; sascha@2561: sascha@2561: return true; sascha@2561: } sascha@2561: sascha@2562: protected GaugeFinder loadGauges(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_GAUGES) sascha@2561: .addScalar("gauge_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("a", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("b", StandardBasicTypes.DOUBLE); sascha@2561: sascha@2561: query.setInteger("river_id", riverId); sascha@2561: sascha@2561: List list = query.list(); sascha@2561: sascha@2561: if (list.isEmpty()) { sascha@2561: log.warn("River " + riverId + " has no gauges."); sascha@2562: return null; sascha@2561: } sascha@2561: sascha@2562: List gauges = new ArrayList(); sascha@2562: sascha@2561: for (Object [] row: list) { sascha@2561: int gaugeId = (Integer)row[0]; sascha@2561: double start = (Double) row[1]; sascha@2561: double end = (Double) row[2]; sascha@2561: GaugeRange gauge = new GaugeRange(start, end, gaugeId); sascha@2561: gauges.add(gauge); sascha@2561: } sascha@2561: sascha@2562: return new GaugeFinder(gauges, isKmUp); sascha@2561: } sascha@2561: sascha@2561: sascha@2561: protected void loadFixings(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXINGS) sascha@2561: .addScalar("wst_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("description", StandardBasicTypes.STRING); sascha@2561: sascha@2561: query.setInteger("river_id", riverId); sascha@2561: sascha@2561: List list = query.list(); sascha@2561: sascha@2561: if (list.isEmpty()) { sascha@2561: log.warn("River " + riverId + " has no fixings."); sascha@2561: // Its pretty fine to have no fixings. sascha@2561: } sascha@2561: sascha@2561: for (Object [] row: list) { sascha@2561: int wstId = (Integer)row[0]; sascha@2561: String description = (String) row[1]; sascha@2561: Fixing fixing = new Fixing(wstId, description); sascha@2561: fixings.add(fixing); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: protected void loadFixingsColumns(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMNS) sascha@2561: .addScalar("wst_column_id", StandardBasicTypes.INTEGER) sascha@2561: .addScalar("start_time", StandardBasicTypes.DATE) sascha@2561: .addScalar("name", StandardBasicTypes.STRING); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2561: fixing.loadColumns(query); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: protected void loadFixingsColumnsKmRange(Session session) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMN_KM_RANGE) sascha@2561: .addScalar("start_km", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("stop_km", StandardBasicTypes.DOUBLE); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2561: fixing.loadColumnsKmRange(query); sascha@2561: } sascha@2561: } sascha@2561: sascha@2562: protected void loadFixingsColumnsQRanges( sascha@2562: Session session, sascha@2562: GaugeFinder gaugeFinder sascha@2562: ) { sascha@2561: SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMN_Q_RANGES) sascha@2561: .addScalar("q", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("start_km", StandardBasicTypes.DOUBLE) sascha@2561: .addScalar("stop_km", StandardBasicTypes.DOUBLE); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2562: fixing.loadColumnsQRanges(query, gaugeFinder); sascha@2561: } sascha@2561: } sascha@2561: sascha@2565: protected void adjustExtent() { sascha@2565: for (Fixing fixing: fixings) { sascha@2565: fixing.adjustExtent(extent); sascha@2565: } sascha@2565: } sascha@2565: sascha@2561: public boolean load(Session session) { sascha@2561: sascha@2565: if (!loadRiver(session)) { sascha@2561: return false; sascha@2561: } sascha@2561: sascha@2562: GaugeFinder gaugeFinder = loadGauges(session); sascha@2561: sascha@2562: if (gaugeFinder == null sascha@2562: || !gaugeFinder.loadDischargeSectors(session, riverId)) { sascha@2561: return false; sascha@2561: } sascha@2561: sascha@2561: loadFixings(session); sascha@2561: loadFixingsColumns(session); sascha@2561: loadFixingsColumnsKmRange(session); sascha@2565: sascha@2565: adjustExtent(); sascha@2565: sascha@2562: loadFixingsColumnsQRanges(session, gaugeFinder); sascha@2561: sascha@2561: return true; sascha@2561: } sascha@2561: sascha@2563: public static final Range FULL_EXTENT = sascha@2562: new Range(-Double.MAX_VALUE, Double.MAX_VALUE); sascha@2562: sascha@2563: public static final Fixing.Filter ACCEPT = new Fixing.Filter() { sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return true; sascha@2563: } sascha@2563: }; sascha@2563: sascha@2563: public static class NotFilter implements Fixing.Filter { sascha@2563: protected Fixing.Filter child; sascha@2563: sascha@2563: public NotFilter(Fixing.Filter child) { sascha@2563: this.child = child; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return !child.accept(column); sascha@2563: } sascha@2563: } // class NotFilter sascha@2563: sascha@2563: public static abstract class ComponentFilter implements Fixing.Filter { sascha@2563: protected List children; sascha@2563: sascha@2744: public ComponentFilter() { sascha@2744: children = new ArrayList(); sascha@2744: } sascha@2744: sascha@2563: public ComponentFilter(List children) { sascha@2563: this.children = children; sascha@2563: } sascha@2744: sascha@2744: public void add(Fixing.Filter filter) { sascha@2744: children.add(filter); sascha@2744: } sascha@2563: } // class ComponentFilter sascha@2563: sascha@2563: public static class OrFilter extends ComponentFilter { sascha@2563: sascha@2744: public OrFilter() { sascha@2744: } sascha@2744: sascha@2563: public OrFilter(List children) { sascha@2563: super(children); sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: for (Fixing.Filter child: children) { sascha@2563: if (child.accept(column)) { sascha@2563: return true; sascha@2563: } sascha@2563: } sascha@2563: return false; sascha@2563: } sascha@2563: } // class OrFilter sascha@2563: sascha@2563: public static class AndFilter extends ComponentFilter { sascha@2563: sascha@2744: public AndFilter() { sascha@2744: } sascha@2744: sascha@2563: public AndFilter(List children) { sascha@2563: super(children); sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: for (Fixing.Filter child: children) { sascha@2563: if (!child.accept(column)) { sascha@2563: return false; sascha@2563: } sascha@2563: } sascha@2563: return true; sascha@2563: } sascha@2563: } // class AndFilter sascha@2563: sascha@2563: public static class IdFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected int columnId; sascha@2563: sascha@2563: public IdFilter(int columnId) { sascha@2563: this.columnId = columnId; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return column.getId() == columnId; sascha@2563: } sascha@2563: } // class IdFilter sascha@2563: sascha@2563: public static class DateFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected Date date; sascha@2563: sascha@2563: public DateFilter(Date date) { sascha@2563: this.date = date; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: return date.equals(column.getStartTime()); sascha@2563: } sascha@2563: } // class DateFilter sascha@2563: sascha@2563: public static class DateRangeFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected Date start; sascha@2563: protected Date end; sascha@2563: sascha@2563: public DateRangeFilter(Date start, Date end) { sascha@2563: this.start = start; sascha@2563: this.end = end; sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: Date date = column.getStartTime(); sascha@2563: return start.compareTo(date) <= 0 && end.compareTo(date) >= 0; sascha@2563: } sascha@2563: } // class DateRangeFilter sascha@2563: sascha@2563: public static class SectorRangeFilter implements Fixing.Filter { sascha@2563: sascha@2563: protected int min; sascha@2563: protected int max; sascha@2563: sascha@2563: public SectorRangeFilter(int min, int max) { sascha@2563: this.min = Math.min(min, max); sascha@2563: this.max = Math.max(min, max); sascha@2563: } sascha@2563: sascha@2563: @Override sascha@2563: public boolean accept(Fixing.Column column) { sascha@2563: for (SectorRange s: column.getSectors()) { sascha@2563: int v = s.getSector(); sascha@2563: if (v >= min && v <= max) { sascha@2563: return true; sascha@2563: } sascha@2563: } sascha@2563: return false; sascha@2563: } sascha@2563: } // class SectorRangeFilter sascha@2563: sascha@2561: public void generateOverview(Document document) { sascha@2563: generateOverview(document, FULL_EXTENT, ACCEPT); sascha@2562: } sascha@2562: sascha@2608: public List filter(Range range, Fixing.Filter filter) { sascha@2561: List allColumns = new ArrayList(); sascha@2561: sascha@2561: for (Fixing fixing: fixings) { sascha@2563: fixing.addAllColumns(allColumns, range, filter); sascha@2561: } sascha@2561: sascha@2561: Collections.sort(allColumns, Fixing.DATE_CMP); sascha@2561: sascha@2608: return allColumns; sascha@2608: } sascha@2608: sascha@2608: public void generateOverview( sascha@2608: Document document, sascha@2608: Range range, sascha@2608: Fixing.Filter filter sascha@2608: ) { sascha@2608: List allColumns = filter(range, filter); sascha@2608: sascha@2561: Element fixingsElement = document.createElement("fixings"); sascha@2561: sascha@2561: Element riverElement = document.createElement("river"); sascha@2561: sascha@2561: riverElement.setAttribute("from", String.valueOf(extent.start)); sascha@2561: riverElement.setAttribute("to", String.valueOf(extent.end)); sascha@2561: riverElement.setAttribute("rid", String.valueOf(riverId)); sascha@2565: riverElement.setAttribute("name", riverName); sascha@2561: sascha@2561: fixingsElement.appendChild(riverElement); sascha@2561: sascha@2564: SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT); sascha@2561: sascha@2561: Element esE = document.createElement("events"); sascha@2561: sascha@2561: for (Fixing.Column column: allColumns) { sascha@2561: sascha@2563: List sectors = column.getSectors(range); sascha@2561: sascha@2561: if (!sectors.isEmpty()) { sascha@2561: Element eE = document.createElement("event"); sascha@2707: eE.setAttribute("description", sascha@2707: String.valueOf(column.getDescription())); sascha@2561: eE.setAttribute("cid", String.valueOf(column.columnId)); sascha@2561: eE.setAttribute("date", df.format(column.startTime)); sascha@2561: sascha@2561: for (SectorRange sector: sectors) { sascha@2561: Element sE = document.createElement("sector"); sascha@2561: sascha@2561: sE.setAttribute("from", String.valueOf(sector.start)); sascha@2561: sE.setAttribute("to", String.valueOf(sector.end)); sascha@2561: sE.setAttribute("class", String.valueOf(sector.sector)); sascha@2561: sascha@2561: eE.appendChild(sE); sascha@2561: } sascha@2561: sascha@2561: esE.appendChild(eE); sascha@2561: } sascha@2561: } sascha@2561: sascha@2561: fixingsElement.appendChild(esE); sascha@2561: sascha@2561: document.appendChild(fixingsElement); sascha@2561: } sascha@2561: } sascha@2561: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :