diff gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation2D.java @ 501:70adafe2b9d5

Speed up the "Horizontalschnitte" gnv-artifacts/trunk@584 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Wed, 20 Jan 2010 14:47:30 +0000
parents ab29e4ff2fda
children d9d933e06875
line wrap: on
line diff
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation2D.java	Wed Jan 20 08:50:10 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation2D.java	Wed Jan 20 14:47:30 2010 +0000
@@ -1,19 +1,24 @@
 package de.intevation.gnv.math;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.HashMap;
-import java.util.Collections;
-
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Envelope;
 
 import com.vividsolutions.jts.index.quadtree.Quadtree;
 
+import gnu.trove.TDoubleArrayList;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.math.stat.descriptive.moment.Mean;
+import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
+
 import org.apache.log4j.Logger;
 
 /**
- *  @author Sascha L. Teichmann
+ *  @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
  */
 public final class Interpolation2D
 {
@@ -26,6 +31,108 @@
     private Interpolation2D() {
     }
 
+    private static final double dist(double a, double b) {
+        a -= b;
+        return Math.sqrt(a*a);
+    }
+
+    private static final double OUTLIER_EPS = 0.4d;
+
+    public static final double [] calculateBufferRemoveOutlier(
+        List <? extends Point2d> points
+    ) {
+        HashMap<Integer, ArrayList<Point2d>> iMap = 
+            new HashMap<Integer, ArrayList<Point2d>>();
+
+        HashMap<Integer, ArrayList<Point2d>> jMap = 
+            new HashMap<Integer, ArrayList<Point2d>>();
+
+        for (int k = points.size()-1; k >= 0; --k) {
+            Point2d p = points.get(k);
+
+            ArrayList<Point2d> jList = jMap.get(p.j);
+            ArrayList<Point2d> iList = iMap.get(p.i);
+
+            if (jList == null) {
+                jMap.put(p.j, jList = new ArrayList<Point2d>());
+            }
+            jList.add(p);
+
+            if (iList == null) {
+                iMap.put(p.i, iList = new ArrayList<Point2d>());
+            }
+            iList.add(p);
+        }
+
+        TDoubleArrayList deltas = new TDoubleArrayList();
+
+        Mean mean            = new Mean();
+        StandardDeviation sd = new StandardDeviation();
+
+        for (ArrayList<Point2d> v: jMap.values()) {
+            Collections.sort(v, Point2d.Y_COMPARATOR);
+            for (int i = 1, L = v.size(); i < L; ++i) {
+                double dy = Math.abs(v.get(i).y - v.get(i-1).y);
+                deltas.add(dy);
+                mean.increment(dy);
+                sd  .increment(dy);
+            }
+        }
+
+        deltas.sort();
+
+        double m   = mean.getResult();
+        double s   = sd  .getResult();
+        double eps = OUTLIER_EPS*s;
+
+        int yi = deltas.size() - 1;
+        while (yi > 0 && dist(deltas.get(yi), m) > eps) {
+            --yi;
+        }
+
+        double dyMax = deltas.get(yi) + 1e-5d;
+
+        if (log.isDebugEnabled()) {
+            log.debug("mean  y: " + m);
+            log.debug("sigma y: " + s);
+        }
+
+        deltas.reset();
+        mean.clear();
+        sd  .clear();
+
+        for (ArrayList<Point2d> v: iMap.values()) {
+            Collections.sort(v, Point2d.X_COMPARATOR);
+            for (int i = 1, L = v.size(); i < L; ++i) {
+                double dx = Math.abs(v.get(i).x - v.get(i-1).x);
+                deltas.add(dx);
+                mean.increment(dx);
+                sd  .increment(dx);
+            }
+        }
+
+        deltas.sort();
+
+        m   = mean.getResult();
+        s   = sd  .getResult();
+        eps = OUTLIER_EPS*s;
+
+        int xi = deltas.size() - 1;
+
+        while (xi > 0 && dist(deltas.get(xi), m) > eps) {
+            --xi;
+        }
+
+        double dxMax = deltas.get(xi) + 1e-5d;
+
+        if (log.isDebugEnabled()) {
+            log.debug("mean  y: " + m);
+            log.debug("sigma y: " + s);
+        }
+
+        return new double [] { dxMax, dyMax };
+    }
+
     public static final double [] calculateBuffer(
         List <? extends Point2d> points
     ) {

http://dive4elements.wald.intevation.org