diff geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java @ 547:23d5cc37dd5b

Fixed access to raster data. geo-backend/trunk@518 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sat, 09 Jan 2010 12:41:26 +0000
parents 210716612c30
children 7615ee5d1345
line wrap: on
line diff
--- a/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java	Fri Jan 08 14:40:08 2010 +0000
+++ b/geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java	Sat Jan 09 12:41:26 2010 +0000
@@ -37,9 +37,9 @@
 import com.vividsolutions.jts.io.WKTReader;
 
 
-		/**
- * @author Tim Englich <tim.englich@intevation.de>
- *
+/**
+ * @author Tim Englich         (tim.englich@intevation.de)
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
  */
 public class ArcSDEStatement implements Statement {
 
@@ -484,7 +484,13 @@
 	 * @throws SeException
 	 */
     private ResultSet handleResultSet(SeQuery pSeQuery, boolean isRaster, Geometry geometry) throws SeException {
-        log.debug("ArcSDEStatement,handleResultSet()");
+
+        boolean debug = log.isDebugEnabled();
+
+        if (debug) {
+            log.debug("ArcSDEStatement.handleResultSet()");
+        }
+
         SDEResultSet lSet = new SDEResultSet();
         SeRow row = null;;
         int lCount;
@@ -495,7 +501,8 @@
                     // analyze cols of result set
                     SeColumnDefinition[] lCols = row.getColumns();
                     for (SeColumnDefinition lCol : lCols) {
-                        lSet.addCol(new ColDefinition(lCol.getName(), lCol.getType()));// notice: esri-types have been copied into colDefinition class!
+                        lSet.addCol(new ColDefinition(lCol.getName(), lCol.getType()));
+                        // notice: esri-types have been copied into colDefinition class!
                     }
                 }
                 short lNumCols = row.getNumColumns();
@@ -507,44 +514,30 @@
             }
         }else{
             try {
-               
-                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();
+                SeRasterAttr    attr       = row.getRaster(0);
+                SeRaster        raster     = attr.getRasterInfo();
+                SeRasterBand [] bands      = raster.getBands();
+                SeRasterBand    rasterBand = bands[0];
                 
                 SeExtent extent = rasterBand.getExtent();
-                log.debug("Extent: "+ extent.getMinX() +" "+extent.getMinY()+" "+extent.getMaxX()+ " "+extent.getMaxY() );
-                log.debug("Querygeometry: "+geometry.toText());
+
+                /*
+                if (debug) {
+                    log.debug("Extent: " + 
+                        extent.getMinX() + " " + extent.getMinY() + " "+
+                        extent.getMaxX() + " " + extent.getMaxY());
+                    log.debug("Query geometry: "+geometry.toText());
+                }
+                */
                 
                 double x = ((Point)geometry).getX();
                 double y = ((Point)geometry).getY();
-                boolean isPointInRaster = false;
-                if ((x >= extent.getMinX() && x <= extent.getMaxX()) && (y >= extent.getMinY() && y <= extent.getMaxY())){
-                    isPointInRaster = true;
-                }
-                
-                double dxNature = x - extent.getMinX();
-                double dyNature = extent.getMaxY() - y;//y-extent.getMinY();
-                double widthNature = extent.getMaxX()-extent.getMinX(); 
-                double heightNature = extent.getMaxY()-extent.getMinY();
-                
-                int pixelX = (int)Math.round(dxNature * width / widthNature);
-                int pixelY = (int)Math.round(dyNature * height/ heightNature);
-                
-                log.debug("Rasterdimesion (Pixel) " + width + " / " + height);
-                log.debug ("Required Pixel: " + pixelX + " / "+ pixelY);
-                int bandNumber = rasterBand.getBandNumber();
-                log.debug("BAND-ID "+rasterBand.getId().longValue());
-                int maxLevel = 0;
-                log.debug("Maxlevel: "+maxLevel);
+
+                boolean isPointInRaster =
+                        x >= extent.getMinX() && x <= extent.getMaxX() 
+                    &&  y >= extent.getMinY() && y <= extent.getMaxY();
                 
                 if (isPointInRaster){
                                         
@@ -552,41 +545,111 @@
                         pSeQuery.execute();
                         row = pSeQuery.fetch();
                     }
+
+                    double midX = 0.5d*(extent.getMinX() + extent.getMaxX());
+                    double midY = 0.5d*(extent.getMinY() + extent.getMaxY());
+
+                    SDEPoint origin = rasterBand.getTileOrigin();
+
+                    double maxX = origin.getX() < midX 
+                        ? extent.getMaxX()
+                        : extent.getMinX();
+
+                    double maxY = origin.getY() < midY
+                        ? extent.getMaxY()
+                        : extent.getMinY();
+
+                    /*
+                    0                         = origin.getX()*mx + bx
+                    rasterBand.getBandWidth() = maxX             + bx
+
+                    rasterBand.getBandWidth() = (maxX-origin.getX())*mx
+                    */
+
+                    double mx = rasterBand.getBandWidth()/(maxX-origin.getX());
+                    double bx = -origin.getX()*mx;
+                    double px = mx*x + bx;
+
+                    double my = rasterBand.getBandHeight()/(maxY-origin.getY());
+                    double by = -origin.getY()*my;
+                    double py = my*y + by;
+
+                    /*
+                    if (debug) {
+                        log.debug("p(x, y): " + px + " / " + py);
+                    }
+                    */
+
                     SeRasterConstraint constraint = new SeRasterConstraint();
-                    constraint.setLevel(maxLevel);
-                    constraint.setBands(bandNumber);
-                    constraint.setEnvelope(pixelX / rasterSize, pixelY / rasterSize, pixelX / rasterSize, pixelY / rasterSize);
+                    constraint.setLevel(0); // best resolution
+                    constraint.setBands(rasterBand.getBandNumber());
+                    int tx = (int)Math.floor(px / rasterBand.getTileWidth());
+                    int ty = (int)Math.floor(py / rasterBand.getTileHeight());
+                    constraint.setEnvelope(tx, ty, tx, ty);
+
                     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());
-                        
-                        
+
+                    if (tile != null){
                         double[] tileValues = new double[tile.getNumPixels()];
                         tileValues = tile.getPixels(tileValues);
-                        lSet.addCol(new ColDefinition("tile",ColDefinition.FLOAT64));
+                        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);
+
+                        /*
+                        0             = wx1*mt + bt
+                        tileWidth-EPS = wx2*mt + bt
+                        tileWidth-EPS = mt*(wx2 - wx1)
+                        */
+
+                        double wx1 = (rasterBand.getTileWidth()*tx - bx)/mx;
+                        double wx2 = (rasterBand.getTileWidth()*(tx+1) - bx)/mx;
+                        double mxt = (rasterBand.getTileWidth()-1e-5d)/(wx2 - wx1);
+                        double bxt = -wx1*mxt;
+
+                        double wy1 = (rasterBand.getTileHeight()*ty - by)/my;
+                        double wy2 = (rasterBand.getTileHeight()*(ty+1) - by)/my;
+                        double myt = (rasterBand.getTileHeight()-1e-5d)/(wy2 - wy1);
+                        double byt = -wy1*myt;
+
+                        RasterObject ro = new RasterObject(
+                            mxt, bxt,
+                            myt, byt,
+                            tile.getColumnIndex(),
+                            tile.getRowIndex(),
+                            tileValues,
+                            rasterBand.getTileWidth(),
+                            rasterBand.getTileHeight());
+                        lBackingRow.addObject(ro, 0);
                         lSet.addRow(lBackingRow);
+
+                        /*
+                        if (debug) {
+                            log.debug("x / y: " + x + " / " + y);
+                            log.debug("wx1: " + wx1);
+                            log.debug("wx1 -> " + (wx1*mxt+bxt));
+                            log.debug("wx2: " + wx2);
+                            log.debug("wx2 -> " + (wx2*mxt+bxt));
+                            log.debug("wx2 - wx1: " + Math.abs(wx2-wx1));
+                            log.debug("wy2 - wy1: " + Math.abs(wy2-wy1));
+                            log.debug("pix: " + (x*mxt + bxt)+ " " + (y*myt + byt));
+                            log.debug("requesting tile: " + tx + " / " + ty);
+                            log.debug("got tile: " + tile.getColumnIndex() + " / " + tile.getRowIndex());
+                            log.debug("tile orig: " +  origin.getX() + " / " +  origin.getY());
+                            log.debug("tile width: " + rasterBand.getTileWidth());
+                            log.debug("tile height: " + rasterBand.getTileHeight());
+                            log.debug("Rasterdimesion (Pixel) " + 
+                                rasterBand.getBandWidth() + " / " + rasterBand.getBandHeight());
+                            log.debug("BAND-ID "+rasterBand.getId().longValue());
+                            log.debug("Pixels: "+ tile.getNumPixels());
+                            log.debug("Column / Row "+tile.getColumnIndex()+" / "+tile.getRowIndex());
+                        }
+                        */
                      }
-                    
-                }else{
-                    log.debug("The Query doesn't deliver any Information because the Point is located outside the Raster.");
+                }
+                else{
+                    log.debug("The Query doesn't deliver any Information " +
+                        "because the Point is located outside the Raster.");
                 }
             } catch (Exception e) {
                 log.error(e,e);
@@ -613,6 +676,6 @@
 
     public <T> T unwrap(Class<T> iface) throws SQLException {
         return null;
+    
     }
-
 }

http://dive4elements.wald.intevation.org