changeset 2380:e237a08acf6e

Create fast cross section lines in the backend now. flys-backend/trunk@3696 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 17 Jan 2012 16:56:38 +0000
parents 8be27b950dbe
children aa777d1aba38
files flys-backend/ChangeLog flys-backend/src/main/java/de/intevation/flys/model/CrossSection.java flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java flys-backend/src/main/java/de/intevation/flys/model/FastCrossSectionLine.java
diffstat 4 files changed, 164 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- 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	<sascha.teichmann@intevation.de>
+
+	* 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	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/model/CrossSection.java(getLines):
--- 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<FastCrossSectionLine> 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<Object []> results = sqlQuery.list();
+
+        ArrayList<Point2D> points = new ArrayList<Point2D>(500);
+        ArrayList<FastCrossSectionLine> lines =
+            new ArrayList<FastCrossSectionLine>();
+
+        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<Point2D>(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 :
--- 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() {
--- /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<FastCrossSectionLine> KM_CMP =
+        new Comparator<FastCrossSectionLine>() {
+            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<Point2D> points;
+
+    public FastCrossSectionLine() {
+    }
+
+    public FastCrossSectionLine(double km) {
+        this.km = km;
+    }
+
+    public FastCrossSectionLine(double km, List<Point2D> 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<Point2D> getPoints() {
+        return points;
+    }
+
+    public void setPoints(List<Point2D> points) {
+        this.points = points;
+    }
+
+    public double [][] fetchCrossSectionProfile() {
+        return CrossSectionLine.fetchCrossSectionProfile(points);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org