# HG changeset patch # User Sascha L. Teichmann # Date 1326819398 0 # Node ID e237a08acf6e40de0a1d40a0973fdde5ac6b44f6 # Parent 8be27b950dbe50edd48bd55c1075dfd42456f256 Create fast cross section lines in the backend now. flys-backend/trunk@3696 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 8be27b950dbe -r e237a08acf6e flys-backend/ChangeLog --- a/flys-backend/ChangeLog Mon Jan 16 14:52:40 2012 +0000 +++ b/flys-backend/ChangeLog Tue Jan 17 16:56:38 2012 +0000 @@ -1,3 +1,16 @@ +2012-01-17 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/model/FastCrossSectionLine.java: + New. Cacheable representation of the cross section line. + + * src/main/java/de/intevation/flys/model/CrossSectionLine.java: + Add a new isValid() method. + + * src/main/java/de/intevation/flys/model/CrossSection.java: + Added method getFastLines() to fetch the lines (FastCrossSectionLines) + directly with a single SQL statement and without expensive + intermediate representations. + 2012-01-16 Sascha L. Teichmann * src/main/java/de/intevation/flys/model/CrossSection.java(getLines): diff -r 8be27b950dbe -r e237a08acf6e flys-backend/src/main/java/de/intevation/flys/model/CrossSection.java --- a/flys-backend/src/main/java/de/intevation/flys/model/CrossSection.java Mon Jan 16 14:52:40 2012 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/CrossSection.java Tue Jan 17 16:56:38 2012 +0000 @@ -3,6 +3,9 @@ import java.io.Serializable; import java.util.List; +import java.util.ArrayList; + +import java.awt.geom.Point2D; import javax.persistence.Entity; import javax.persistence.Id; @@ -20,8 +23,11 @@ import java.math.BigDecimal; import org.hibernate.Session; +import org.hibernate.SQLQuery; import org.hibernate.Query; +import org.hibernate.type.StandardBasicTypes; + import de.intevation.flys.backend.SessionHolder; @Entity @@ -31,6 +37,14 @@ { public static final MathContext PRECISION = new MathContext(6); + public static final String SQL_FAST_CROSS_SECTION_LINES = + "SELECT km, x, y, csl.id AS csl_id " + + "FROM cross_section_lines csl JOIN cross_section_points csp " + + "ON csp.cross_section_line_id = csl.id " + + "WHERE csl.cross_section_id = :cs_id AND " + + "km between :from_km AND :to_km " + + "ORDER BY csl.id, csp.col_pos"; + private Integer id; private River river; private TimeInterval timeInterval; @@ -118,5 +132,67 @@ return query.list(); } + + public List getFastLines( + double startKm, + double endKm + ) { + Session session = SessionHolder.HOLDER.get(); + + SQLQuery sqlQuery = session.createSQLQuery(SQL_FAST_CROSS_SECTION_LINES) + .addScalar("km", StandardBasicTypes.DOUBLE) + .addScalar("x", StandardBasicTypes.DOUBLE) + .addScalar("y", StandardBasicTypes.DOUBLE) + .addScalar("csl_id", StandardBasicTypes.INTEGER); + + sqlQuery + .setInteger("cs_id", getId()) + .setDouble("from_km", startKm) + .setDouble("to_km", endKm); + + List results = sqlQuery.list(); + + ArrayList points = new ArrayList(500); + ArrayList lines = + new ArrayList(); + + Integer lastId = null; + Double lastKm = null; + + for (Object [] result: results) { + Double km = (Double)result[0]; + Double x = (Double)result[1]; + Double y = (Double)result[2]; + Integer id = (Integer)result[3]; + + if (lastId != null && !lastId.equals(id)) { + points.trimToSize(); + FastCrossSectionLine line = + new FastCrossSectionLine(lastKm, points); + lines.add(line); + points = new ArrayList(500); + } + + Point2D p = new Point2D.Double(x, y); + + if (CrossSectionLine.isValid(p)) { + points.add(p); + } + + lastKm = km; + lastId = id; + } + + if (lastId != null) { + points.trimToSize(); + FastCrossSectionLine line = + new FastCrossSectionLine(lastKm, points); + lines.add(line); + } + + lines.trimToSize(); + + return lines; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 8be27b950dbe -r e237a08acf6e flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java --- a/flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java Mon Jan 16 14:52:40 2012 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java Tue Jan 17 16:56:38 2012 +0000 @@ -60,7 +60,11 @@ public static final boolean isValid(double x) { x = Math.abs(x); return x > TOO_SMALL && x < TOO_BIG; - } + } + + public static final boolean isValid(Point2D p) { + return isValid(p.getX()) && isValid(p.getY()); + } public CrossSectionLine() { diff -r 8be27b950dbe -r e237a08acf6e flys-backend/src/main/java/de/intevation/flys/model/FastCrossSectionLine.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-backend/src/main/java/de/intevation/flys/model/FastCrossSectionLine.java Tue Jan 17 16:56:38 2012 +0000 @@ -0,0 +1,70 @@ +package de.intevation.flys.model; + +import java.util.List; +import java.util.Comparator; + +import java.io.Serializable; + +import java.math.BigDecimal; + +import java.awt.geom.Point2D; + +public class FastCrossSectionLine +implements Serializable +{ + public static final double EPSILON = 1e-5; + + public static final Comparator KM_CMP = + new Comparator() { + public int compare( + FastCrossSectionLine a, + FastCrossSectionLine b + ) { + double diff = a.km - b.km; + if (diff < -EPSILON) return -1; + return diff > +EPSILON ? +1 : 0; + } + }; + + protected double km; + protected List points; + + public FastCrossSectionLine() { + } + + public FastCrossSectionLine(double km) { + this.km = km; + } + + public FastCrossSectionLine(double km, List points) { + this(km); + this.points = points; + } + + public FastCrossSectionLine(CrossSectionLine csl) { + BigDecimal kmBD = csl.getKm(); + km = kmBD != null ? kmBD.doubleValue() : 0d; + points = csl.fetchCrossSectionLinesPoints(); + } + + public double getKm() { + return km; + } + + public void setKm(double km) { + this.km = km; + } + + public List getPoints() { + return points; + } + + public void setPoints(List points) { + this.points = points; + } + + public double [][] fetchCrossSectionProfile() { + return CrossSectionLine.fetchCrossSectionProfile(points); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :