changeset 544:33f93898cbbf

Added RasterObject for caching the Rastertiles to get a better performance geo-backend/trunk@508 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Tim Englich <tim.englich@intevation.de>
date Tue, 05 Jan 2010 14:09:53 +0000
parents fac02bf1c685
children 347c84467478
files geo-backend/ChangeLog geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java
diffstat 3 files changed, 134 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/geo-backend/ChangeLog	Mon Jan 04 15:22:09 2010 +0000
+++ b/geo-backend/ChangeLog	Tue Jan 05 14:09:53 2010 +0000
@@ -1,3 +1,12 @@
+2010-01-05  Tim Englich  <tim.englich@intevation.de>
+
+	* src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (handleResultSet): 
+	  Switched to return the RasterObject instead of the depth in an Rasterquery.
+	  This should help to get a better performance.
+	* src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java (RasterObject): 
+	  Added new Object for Caching Rastertiles and all Informations that are
+	  required for calculating the Depth to a given Coordinate.
+
 2010-01-04  Tim Englich  <tim.englich@intevation.de>
 
 	* src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (handleResultSet): 
--- a/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java	Mon Jan 04 15:22:09 2010 +0000
+++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java	Tue Jan 05 14:09:53 2010 +0000
@@ -8,8 +8,6 @@
 import java.sql.SQLException;
 import java.sql.SQLWarning;
 import java.sql.Statement;
-import java.util.HashMap;
-import java.util.Vector;
 
 import org.apache.log4j.Logger;
 
@@ -20,19 +18,19 @@
 import com.esri.sde.sdk.client.SeExtent;
 import com.esri.sde.sdk.client.SeFilter;
 import com.esri.sde.sdk.client.SeLayer;
-import com.esri.sde.sdk.client.SeObjectId;
 import com.esri.sde.sdk.client.SeQuery;
 import com.esri.sde.sdk.client.SeQueryInfo;
 import com.esri.sde.sdk.client.SeRaster;
 import com.esri.sde.sdk.client.SeRasterAttr;
 import com.esri.sde.sdk.client.SeRasterBand;
-import com.esri.sde.sdk.client.SeRasterColumn;
 import com.esri.sde.sdk.client.SeRasterConstraint;
 import com.esri.sde.sdk.client.SeRasterTile;
 import com.esri.sde.sdk.client.SeRow;
 import com.esri.sde.sdk.client.SeShape;
 import com.esri.sde.sdk.client.SeShapeFilter;
 import com.esri.sde.sdk.client.SeSqlConstruct;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.Point;
 import com.vividsolutions.jts.geom.Polygon;
@@ -50,10 +48,6 @@
      */
     private static Logger log = Logger.getLogger(ArcSDEStatement.class);
     
-    private static HashMap<String, double[]> tiles = new HashMap<String, double[]>();
-    
-    private static SeRasterBand rasterBand = null;
-    
 	private ArcSDEConnection connection = null;
 	
 	/**
@@ -514,14 +508,14 @@
         }else{
             try {
                
-                if (rasterBand == null){
-                    pSeQuery.execute();
-                    row = pSeQuery.fetch();
-                    SeRasterAttr attr = row.getRaster(0);
-                    SeRaster raster = attr.getRasterInfo();
-                    SeRasterBand[] bands = raster.getBands();
-                    rasterBand = bands[0];
-                }
+                int rasterSize = 128;
+                pSeQuery.execute();
+                row = pSeQuery.fetch();
+                SeRasterAttr attr = row.getRaster(0);
+                SeRaster raster = attr.getRasterInfo();
+                SeRasterBand[] bands = raster.getBands();
+                SeRasterBand rasterBand = bands[0];
+                
                 
                 int height = rasterBand.getBandHeight();
                 int width = rasterBand.getBandWidth();
@@ -553,48 +547,44 @@
                 log.debug("Maxlevel: "+maxLevel);
                 
                 if (isPointInRaster){
-                    int columnIndex = pixelX / 128;
-                    int rowIndex = pixelY / 128;
-                    String tileKey = columnIndex + "/"+ rowIndex;
+                                        
+                    if (row == null){
+                        pSeQuery.execute();
+                        row = pSeQuery.fetch();
+                    }
+                    SeRasterConstraint constraint = new SeRasterConstraint();
+                    constraint.setLevel(maxLevel);
+                    constraint.setBands(bandNumber);
+                    constraint.setEnvelope(pixelX / rasterSize, pixelY / rasterSize, pixelX / rasterSize, pixelY / rasterSize);
+                    pSeQuery.queryRasterTile(constraint);
+                    SeRasterTile tile = row.getRasterTile();
                     
-                    double[] tileValues = tiles.get(tileKey);
-                    if (tileValues == null){
-                        if (row == null){
-                            pSeQuery.execute();
-                            row = pSeQuery.fetch();
-                        }
-                        SeRasterConstraint constraint = new SeRasterConstraint();
-                        constraint.setLevel(maxLevel);
-                        constraint.setBands(bandNumber);
-                        constraint.setEnvelope(pixelX / 128, pixelY / 128, pixelX / 128, pixelY / 128);
-                        pSeQuery.queryRasterTile(constraint);
-                        SeRasterTile tile = row.getRasterTile();
-                     
-                        if(tile != null){
-                            log.debug("BAND-ID Tile "+tile.getBandId().longValue());
-                            log.debug("Pixel "+ tile.getNumPixels());
-                            log.debug("Column / Row "+tile.getColumnIndex()+" / "+tile.getRowIndex());
-                            int localPixelX = pixelX - (tile.getColumnIndex()*128);
-                            int localPixelY = pixelY - (tile.getRowIndex()*128);
-                            int pos = localPixelY*128 +localPixelX;
-                            if (pos < tile.getNumPixels()){
-                                tileValues = new double[tile.getNumPixels()];
-                                tileValues = tile.getPixels(tileValues);
-                                this.tiles.put(tileKey, tileValues);
-                                
-                            }
-                         }
-                    }else{
-                        log.debug("Tile kommt aus dem Cache.");
-                    }
+                    if(tile != null){
+                        log.debug("BAND-ID Tile "+tile.getBandId().longValue());
+                        log.debug("Pixel "+ tile.getNumPixels());
+                        log.debug("Column / Row "+tile.getColumnIndex()+" / "+tile.getRowIndex());
+                        
+                        
+                        double[] tileValues = new double[tile.getNumPixels()];
+                        tileValues = tile.getPixels(tileValues);
+                        lSet.addCol(new ColDefinition("tile",ColDefinition.FLOAT64));
+                        Row lBackingRow = new Row(1);
+                        Envelope envelope = new Envelope(
+                                            new Coordinate(extent.getMinX(), 
+                                                           extent.getMinY()), 
+                                            new Coordinate(extent.getMaxX(), 
+                                                           extent.getMaxY()));
+                        RasterObject ro = new RasterObject(envelope, 
+                                                           tileValues, 
+                                                           rasterSize, 
+                                                           tile.getRowIndex(), 
+                                                           tile.getColumnIndex(),
+                                                           width,
+                                                           height);
+                        lBackingRow.addObject(ro,0);
+                        lSet.addRow(lBackingRow);
+                     }
                     
-                    int localPixelX = pixelX - (columnIndex*128);
-                    int localPixelY = pixelY - (rowIndex*128);
-                    int pos = localPixelY*128 +localPixelX;
-                    lSet.addCol(new ColDefinition("height",ColDefinition.FLOAT64));
-                    Row lBackingRow = new Row(1);
-                    lBackingRow.addObject(tileValues[pos], 0);
-                    lSet.addRow(lBackingRow);
                 }else{
                     log.debug("The Query doesn't deliver any Information because the Point is located outside the Raster.");
                 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java	Tue Jan 05 14:09:53 2010 +0000
@@ -0,0 +1,79 @@
+/**
+ *
+ */
+package de.intevation.gnv.geobackend.sde.datasources;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Envelope;
+
+/**
+ * @author Tim Englich <tim.englich@intevation.de>
+ *
+ */
+public class RasterObject {
+
+    private int rasterSize;
+    private int rowIndex;
+    private int columnIndex;
+    private int rasterWidth;
+    private int rasterHeight;
+    private Envelope envelope = null;
+    private Envelope rasterEnvelope = null;
+    
+    private double[] rasterData = null;
+    /**
+     * Constructor
+     */
+    public RasterObject(Envelope envelope , double[] rasterData, 
+                        int rasterSize, int rowIndex, 
+                        int columnIndex, int rasterWidth, int rasterHeight ){
+        this.envelope = envelope;
+        this.rasterData = rasterData;
+        this.rasterSize = rasterSize;
+        this.rowIndex = rowIndex;
+        this.columnIndex = columnIndex;
+        this.rasterHeight = rasterHeight;
+        this.rasterWidth = rasterWidth;
+    }
+    public synchronized Envelope getEnvelope() {
+        if (this.rasterEnvelope == null){
+            double minX = (columnIndex* rasterSize * 
+                          (envelope.getWidth() / rasterWidth)+ envelope.getMinX());
+            double maxX = minX + (rasterSize * (envelope.getWidth() / rasterWidth));
+            
+            double maxY = envelope.getMaxY() - 
+                          (rowIndex * rasterSize * 
+                          (envelope.getHeight() / rasterHeight));
+            double minY = maxY - 
+                          (rasterSize * (envelope.getHeight() / rasterHeight));
+            this.rasterEnvelope = new Envelope(
+                    new Coordinate(minX, minY), 
+                    new Coordinate(maxX, maxY));
+        }
+        return this.rasterEnvelope;
+    }
+    
+    public synchronized double getValue(Coordinate coordinate){
+        double dxNature = coordinate.x - envelope.getMinX();
+        double dyNature = envelope.getMaxY() - coordinate.y;
+        double widthNature = envelope.getMaxX()-envelope.getMinX(); 
+        double heightNature = envelope.getMaxY()-envelope.getMinY();
+        
+        int pixelX = (int)Math.round(dxNature * rasterWidth / widthNature);
+        int pixelY = (int)Math.round(dyNature * rasterHeight/ heightNature);
+        
+        
+        int localPixelX = pixelX - (columnIndex*rasterSize);
+        int localPixelY = pixelY - (rowIndex*rasterSize);
+        
+        int pos = localPixelY * rasterSize + localPixelX;
+        
+        
+        if (pos < rasterData.length){
+            return this.rasterData[pos];
+        }
+        
+        return Double.NaN;
+    }
+
+}

http://dive4elements.wald.intevation.org