# HG changeset patch # User Tim Englich # Date 1262700593 0 # Node ID 33f93898cbbfe321f5ced531e2075949de55cdc7 # Parent fac02bf1c68580f0dbf1d0440cf471400b703dac Added RasterObject for caching the Rastertiles to get a better performance geo-backend/trunk@508 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r fac02bf1c685 -r 33f93898cbbf geo-backend/ChangeLog --- 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 + + * 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 * src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java (handleResultSet): diff -r fac02bf1c685 -r 33f93898cbbf geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/ArcSDEStatement.java --- 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 tiles = new HashMap(); - - 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."); } diff -r fac02bf1c685 -r 33f93898cbbf geo-backend/src/main/java/de/intevation/gnv/geobackend/sde/datasources/RasterObject.java --- /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 + * + */ +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; + } + +}