changeset 548:ccd976fc0f7b

Implemented bilinear interpolation on raster tiles. geo-backend/trunk@520 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sat, 09 Jan 2010 16:12:10 +0000
parents 23d5cc37dd5b
children 0dcf068fb552
files geo-backend/ChangeLog geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java
diffstat 2 files changed, 71 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/geo-backend/ChangeLog	Sat Jan 09 12:41:26 2010 +0000
+++ b/geo-backend/ChangeLog	Sat Jan 09 16:12:10 2010 +0000
@@ -1,3 +1,8 @@
+2009-01-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java:
+	  Implemented bilinear interpolation.
+
 2009-01-09	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java:
--- a/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java	Sat Jan 09 12:41:26 2010 +0000
+++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java	Sat Jan 09 16:12:10 2010 +0000
@@ -89,6 +89,71 @@
         return getValue(coordinate, NEAREST_NEIGHBOR);
     }
 
+    public final double interpolateBilinear(double px, double py) {
+
+        if (px < 0.5d) { // left border
+            if (py < 0.5d) { // upper left edge
+                return rasterData[0];
+            }
+            if (py > tileHeight-0.5d) { // lower left edge
+                return rasterData[rasterData.length-tileWidth];
+            }
+            // center left
+            int    i = (int)(py -= 0.5d);
+            double t = py - i;
+            i *= tileWidth;
+            return (1d-t)*rasterData[i] + t*rasterData[i+tileWidth];
+        }
+
+        if (px > tileWidth-0.5d) { // right border
+            if (py < 0.5d) { // upper right edge
+                return rasterData[tileWidth-1];
+            }
+            if (py > tileHeight-0.5d) { // lower right edge
+                return rasterData[rasterData.length-1];
+            }
+            // center right
+            int    i = (int)(py -= 0.5d);
+            double t = py - i;
+            i = i*tileWidth + tileWidth-1;
+            return (1d-t)*rasterData[i] + t*rasterData[i+tileWidth];
+        }
+
+        if (py < 0.5d) { // top border
+            int    i = (int)(px -= 0.5d);
+            double t = px - i;
+            return (1d-t)*rasterData[i] + t*rasterData[i+1];
+        }
+
+        if (py > tileHeight-0.5d) { // bottom border
+            int    i = (int)(px -= 0.5d);
+            double t = px - i;
+            i += rasterData.length-tileWidth;
+            return (1d-t)*rasterData[i] + t*rasterData[i+1];
+        }
+
+        // center
+        int    i  = (int)(py -= 0.5d);
+        int    j  = (int)(px -= 0.5d);
+        double ti = py - i;
+        double tj = px - j;
+
+        int idx = i*tileWidth + j;
+
+        double v1j1 = rasterData[idx];
+        double v2j1 = rasterData[idx+1];
+
+        idx += tileWidth;
+
+        double v1j2 = rasterData[idx];
+        double v2j2 = rasterData[idx+1];
+
+        double v1 = (1d-tj)*v1j1 + tj*v2j1;
+        double v2 = (1d-tj)*v1j2 + tj*v2j2;
+
+        return (1d-ti)*v1 + ti*v2;
+    }
+
     public double getValue(Coordinate coordinate, int interpolationType) {
 
         double px = mx*coordinate.x + bx;
@@ -98,11 +163,9 @@
             return Double.NaN;
         }
 
-        /*
         if (interpolationType == BILINEAR) {
-            // TODO: implement me!
+            return interpolateBilinear(px, py);
         }
-        */
 
         int posX = Math.min(tileWidth-1,  (int)Math.round(px));
         int posY = Math.min(tileHeight-1, (int)Math.round(py));

http://dive4elements.wald.intevation.org