svn - r34327 - in trunk/modules/plugin/arcsde/datastore/src: main/java/org/geotools/arcsde/raster/gce main/java/org/geotools/arcsde/raster/io main/java/org/geotools/arcsde/raster/jai test/java/org/geotools/arcsde/raster/gce

1 message Options
Embed this post
Permalink
svn_geotools

svn - r34327 - in trunk/modules/plugin/arcsde/datastore/src: main/java/org/geotools/arcsde/raster/gce main/java/org/geotools/arcsde/raster/io main/java/org/geotools/arcsde/raster/jai test/java/org/geotools/arcsde/raster/gce

Reply Threaded More More options
Print post
Permalink
Author: groldan
Date: 2009-11-04 14:13:17 -0500 (Wed, 04 Nov 2009)
New Revision: 34327

Added:
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java
Modified:
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/NativeTileReader.java
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/PromotingTileReader.java
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileFetchCommand.java
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReader.java
   trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDEImageReader.java
   trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java
Log:
GEOT-2616, random access to tiles for ArcSDERenderedImage.getTile(x, y)

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -62,7 +62,6 @@
 import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
 import org.geotools.coverage.grid.io.AbstractGridFormat;
 import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.data.DataSourceException;
 import org.geotools.data.DefaultServiceInfo;
 import org.geotools.data.ServiceInfo;
 import org.geotools.factory.Hints;
@@ -439,15 +438,6 @@
                 pb.add(translateY);
                 pb.add(new InterpolationNearest());
 
-                if (queries.size() > 0) {
-                    try {
-                        LOGGER.info("Forcing loading data for mosaic as per GEOT-");
-                        // image.getData();
-                    } catch (RuntimeException e) {
-                        throw new DataSourceException("Error fetching arcsde raster", e);
-                    }
-                }
-
                 image = JAI.create("scale", pb);
                 log.log(image, query.getRasterId(), "03_scale");
 

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -20,6 +20,9 @@
 import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.WeakHashMap;
@@ -310,12 +313,17 @@
                 LOGGER.fine("connecting to ArcSDE Raster: " + coverageUrl);
             }
         } else if (input instanceof File) {
+            String path = ((File) input).getPath();
+            while(path.indexOf('\\') > -1){
+                path = path.replace('\\', '/');
+            }
+            URI uri;
             try {
-                coverageUrl = ((File) input).toURI().toURL().toExternalForm();
-            } catch (MalformedURLException e) {
-                throw new IllegalArgumentException("Can't create coverage URL out of (file) "
-                        + ((File) input).getAbsolutePath());
-            }
+                uri = new URI(path);
+            } catch (URISyntaxException e) {
+                throw new IllegalArgumentException(path);
+            }
+            coverageUrl = uri.toString();
             if (LOGGER.isLoggable(Level.FINE)) {
                 LOGGER.fine("connectiong via file-hack to ArcSDE Raster: " + coverageUrl);
             }

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/NativeTileReader.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/NativeTileReader.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/NativeTileReader.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -19,7 +19,6 @@
 
 import java.awt.Dimension;
 import java.awt.Rectangle;
-import java.io.EOFException;
 import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -40,7 +39,6 @@
 import com.esri.sde.sdk.client.SeRasterConstraint;
 import com.esri.sde.sdk.client.SeRow;
 import com.esri.sde.sdk.client.SeSqlConstruct;
-import com.esri.sde.sdk.client.SeStreamOp;
 
 /**
  * Offers an iterator like interface to fetch ArcSDE raster tiles.
@@ -71,15 +69,6 @@
 
     private TileFetchCommand tileFetchCommand;
 
-    /**
-     * {@link SeStreamOp} held to be closed at {@link #dispose()}
-     *
-     * @see #execute()
-     */
-    private SeQuery preparedQuery;
-
-    private TileInfo[] nextTile;
-
     private boolean started;
 
     private final int bitmaskDataLength;
@@ -262,30 +251,6 @@
     }
 
     /**
-     * @see org.geotools.arcsde.raster.io.TileReader#hasNext()
-     */
-    public boolean hasNext() throws IOException {
-        if (!started) {
-            execute();
-            try {
-                nextTile = session.issue(tileFetchCommand);
-            } catch (IOException e) {
-                dispose();
-                throw e;
-            } catch (RuntimeException e) {
-                dispose();
-                throw e;
-            }
-            started = true;
-            if (nextTile == null) {
-                dispose();
-                LOGGER.fine("No tiles to fetch at all, releasing connection");
-            }
-        }
-        return nextTile != null;
-    }
-
-    /**
      * Creates and executes the {@link SeQuery} that's used to fetch the required tiles from the
      * specified raster, and stores (as member variables) the {@link SeRow} to fetch the tiles from
      * and the {@link SeQuery} to be closed at the TileReader's disposal
@@ -293,7 +258,12 @@
      * @throws IOException
      */
     private void execute() throws IOException {
+        final Rectangle requestedTiles = this.requestedTiles;
+        this.tileFetchCommand = execute(requestedTiles);
+    }
 
+    private TileFetchCommand execute(final Rectangle rasterTiles) throws IOException {
+
         final int rasterIndex = rasterInfo.getRasterIndex(rasterId);
         final int tileWidth = rasterInfo.getTileWidth(rasterId);
         final int tileHeight = rasterInfo.getTileHeight(rasterId);
@@ -312,10 +282,10 @@
                 bandsToQuery[bandN - 1] = bandN;
             }
 
-            int minTileX = requestedTiles.x;
-            int minTileY = requestedTiles.y;
-            int maxTileX = minTileX + requestedTiles.width - 1;
-            int maxTileY = minTileY + requestedTiles.height - 1;
+            int minTileX = rasterTiles.x;
+            int minTileY = rasterTiles.y;
+            int maxTileX = minTileX + rasterTiles.width - 1;
+            int maxTileY = minTileY + rasterTiles.height - 1;
             if (LOGGER.isLoggable(Level.FINE)) {
                 LOGGER.fine("Requesting tiles [x=" + minTileX + "-" + maxTileX + ", y=" + minTileY
                         + "-" + maxTileY + "] from tile range [x=0-"
@@ -325,8 +295,8 @@
             // SDEPoint tileOrigin = rAttr.getTileOrigin();
 
             if (LOGGER.isLoggable(Level.FINE)) {
-                Rectangle tiledImageSize = new Rectangle(0, 0, tileWidth * requestedTiles.width,
-                        tileHeight * requestedTiles.height);
+                Rectangle tiledImageSize = new Rectangle(0, 0, tileWidth * rasterTiles.width,
+                        tileHeight * rasterTiles.height);
 
                 LOGGER.fine("Tiled image size: " + tiledImageSize);
             }
@@ -346,15 +316,15 @@
          * Obtain the ISession this tile reader will work with until exhausted
          */
         try {
-            // lets share connections as we're going to do read only operations
-            final boolean transactional = false;
-            this.session = sessionPool.getSession(transactional);
-            // System.err.println("----> Using " + session + " to read raster #" + rasterId
-            // + " on Thread " + Thread.currentThread().getName() + ". Tile set: "
-            // + requestedTiles);
-            if (LOGGER.isLoggable(Level.FINER)) {
-                LOGGER.finer("Using " + session + " to read raster #" + rasterId + " on Thread "
-                        + Thread.currentThread().getName() + ". Tile set: " + requestedTiles);
+            if (this.session == null) {
+                // lets share connections as we're going to do read only operations
+                final boolean transactional = false;
+                this.session = sessionPool.getSession(transactional);
+                if (LOGGER.isLoggable(Level.FINER)) {
+                    LOGGER.finer("Using " + session + " to read raster #" + rasterId
+                            + " on Thread " + Thread.currentThread().getName() + ". Tile set: "
+                            + rasterTiles);
+                }
             }
         } catch (UnavailableConnectionException e) {
             // really bad luck..
@@ -371,22 +341,19 @@
         final SeRow row = queryCommand.getSeRow();
 
         final int numberOfBands = getNumberOfBands();
-        this.tileFetchCommand = new TileFetchCommand(row, pixelsPerTile, numberOfBands);
-        this.preparedQuery = queryCommand.getPreparedQuery();
+        final SeQuery preparedQuery = queryCommand.getPreparedQuery();
+        TileFetchCommand fetchCommand = new TileFetchCommand(preparedQuery, row, pixelsPerTile,
+                numberOfBands);
+        return fetchCommand;
     }
 
     /**
-     * @see org.geotools.arcsde.raster.io.TileReader#next()
+     * @see org.geotools.arcsde.raster.io.TileReader#getTile(int, int)
      */
-    public TileInfo[] next() throws IOException {
-        final TileInfo[] bandTiles;
-        final boolean hasNext = hasNext();
-        if (hasNext) {
-            bandTiles = nextTile();
-        } else {
-            throw new IllegalStateException("There're no more tiles to fetch");
-        }
+    public TileInfo[] getTile(final int tileX, final int tileY) throws IOException {
 
+        final TileInfo[] bandTiles = fetchTile(tileX, tileY);
+
         try {
             final int numberOfBands = getNumberOfBands();
             for (int bandN = 0; bandN < numberOfBands; bandN++) {
@@ -431,13 +398,79 @@
         return bandTiles;
     }
 
-    private TileInfo[] nextTile() throws IOException {
-        if (nextTile == null) {
+    private int lastTileX = -1;
+
+    private int lastTileY = -1;
+
+    private TileInfo[] fetchTile(final int tileX, final int tileY) throws IOException {
+
+        TileInfo[] tileInfo = null;
+
+        if (isConsecutive(tileX, tileY)) {
+            while (lastTileX != tileX || lastTileY != tileY) {
+                tileInfo = nextTile();
+            }
+        } else {
+            tileInfo = fetchSingleTile(tileX, tileY);
+        }
+
+        return tileInfo;
+    }
+
+    /**
+     * Executes a separate request to fetch this single tile
+     *
+     * @throws IOException
+     */
+    private TileInfo[] fetchSingleTile(final int tileX, final int tileY) throws IOException {
+        LOGGER.info("fetchSingleTile " + tileX + ", " + tileY);
+        final int rasterTileX = requestedTiles.x + tileX;
+        final int rasterTileY = requestedTiles.y + tileY;
+        final int width = 1;
+        final int height = 1;
+        final Rectangle requestTiles = new Rectangle(rasterTileX, rasterTileY, width, height);
+
+        final TileFetchCommand command = execute(requestTiles);
+        final SeQuery query = command.getQuery();
+        final TileInfo[] tile;
+        try {
+            tile = session.issue(command);
+            session.close(query);
+        } catch (IOException e) {
+            session.close(query);
             dispose();
-            throw new EOFException("No more tiles to read");
+            throw e;
+        } catch (RuntimeException e) {
+            session.close(query);
+            dispose();
+            throw e;
         }
-        TileInfo[] curr = nextTile;
 
+        return tile;
+    }
+
+    /**
+     * Determines whether the tile defined by {@code tileX, tileY} is consecutive to the original
+     * request, whether it is exactly the next in the stream or any other one that follows the last
+     * tile fetched from the original request.
+     */
+    private boolean isConsecutive(final int tileX, final int tileY) {
+        if (tileX > lastTileX && tileY >= lastTileY) {
+            return true;
+        }
+        if (tileX <= lastTileX && tileY > lastTileY) {
+            return true;
+        }
+        return false;
+    }
+
+    private TileInfo[] nextTile() throws IOException {
+        if (!started) {
+            execute();
+            started = true;
+        }
+
+        TileInfo[] nextTile;
         try {
             nextTile = session.issue(tileFetchCommand);
         } catch (IOException e) {
@@ -449,10 +482,22 @@
         }
         if (nextTile == null) {
             dispose();
-            LOGGER.finer("There're no more tiles to fetch");
+            throw new IllegalStateException("There're no more tiles to fetch");
         }
 
-        return curr;
+        if (lastTileY == -1) {
+            lastTileY = 0;
+        }
+        lastTileX++;
+        if (lastTileX == getTilesWide()) {
+            lastTileX = 0;
+            lastTileY++;
+        }
+
+        if (lastTileX == getTilesWide() - 1 && lastTileY == getTilesHigh() - 1) {
+            dispose();
+        }
+        return nextTile;
     }
 
     /**
@@ -466,13 +511,22 @@
                 LOGGER.finer("TileReader disposing " + session + " on Thread "
                         + Thread.currentThread().getName());
             }
-            try {
-                session.close(this.preparedQuery);
-            } catch (Exception e) {
-                LOGGER.log(Level.WARNING, "Closing tile reader's prepared Query", e);
+            if (tileFetchCommand != null) {
+                try {
+                    SeQuery preparedQuery = this.tileFetchCommand.getQuery();
+                    session.close(preparedQuery);
+                } catch (Exception e) {
+                    LOGGER.log(Level.WARNING, "Closing tile reader's prepared Query", e);
+                }
             }
+            tileFetchCommand = null;
+            if (LOGGER.isLoggable(Level.FINER)) {
+                LOGGER.finer("Disposing " + session + " on thread "
+                        + Thread.currentThread().getName());
+            }
             session.dispose();
             session = null;
+            started = false;
         }
     }
 
@@ -487,4 +541,20 @@
     protected void finalize() {
         dispose();
     }
+
+    public int getMinTileX() {
+        return requestedTiles.x;
+    }
+
+    public int getMinTileY() {
+        return requestedTiles.y;
+    }
+
+    public int getPyramidLevel() {
+        return pyramidLevel;
+    }
+
+    public long getRasterId() {
+        return rasterId;
+    }
 }

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/PromotingTileReader.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/PromotingTileReader.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/PromotingTileReader.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -95,16 +95,15 @@
         return nativeReader.getTilesWide();
     }
 
-    public boolean hasNext() throws IOException {
-        return nativeReader.hasNext();
-    }
-
-    public TileInfo[] next() throws IOException {
+    /**
+     * @see org.geotools.arcsde.raster.io.TileReader#getTile(int, int)
+     */
+    public TileInfo[] getTile(final int tileX, final int tileY) throws IOException {
         final int numberOfBands = getNumberOfBands();
         final TileInfo[] promotedBandInfo = new TileInfo[numberOfBands];
 
         try {
-            final TileInfo[] nativeBandInfo = nativeReader.next();
+            final TileInfo[] nativeBandInfo = nativeReader.getTile(tileX, tileY);
 
             for (int bandN = 0; bandN < numberOfBands; bandN++) {
                 TileInfo nativeData = nativeBandInfo[bandN];
@@ -277,4 +276,20 @@
     public void dispose() {
         this.nativeReader.dispose();
     }
+
+    public int getMinTileX() {
+        return nativeReader.getMinTileX();
+    }
+
+    public int getMinTileY() {
+        return nativeReader.getMinTileY();
+    }
+
+    public int getPyramidLevel() {
+        return nativeReader.getPyramidLevel();
+    }
+
+    public long getRasterId() {
+        return nativeReader.getRasterId();
+    }
 }

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileFetchCommand.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileFetchCommand.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileFetchCommand.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -9,6 +9,7 @@
 
 import com.esri.sde.sdk.client.SeConnection;
 import com.esri.sde.sdk.client.SeException;
+import com.esri.sde.sdk.client.SeQuery;
 import com.esri.sde.sdk.client.SeRaster;
 import com.esri.sde.sdk.client.SeRasterTile;
 import com.esri.sde.sdk.client.SeRow;
@@ -18,24 +19,34 @@
  *
  * @author Gabriel Roldan (OpenGeo)
  * @since 2.5.8
- * @source $URL$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/io/TileFetchCommand.java $
  */
 class TileFetchCommand extends Command<TileInfo[]> {
 
+    private final SeQuery preparedQuery;
+
     private final SeRow row;
 
     private final int pixelsPerTile;
 
-    private int numberOfBands;
+    private final int numberOfBands;
 
     private TileDataFetcher dataFetcher;
 
-    public TileFetchCommand(final SeRow row, final int pixelsPerTile, final int numberOfBands) {
+    public TileFetchCommand(final SeQuery preparedQuery, final SeRow row, final int pixelsPerTile,
+            final int numberOfBands) {
+        this.preparedQuery = preparedQuery;
         this.row = row;
         this.pixelsPerTile = pixelsPerTile;
         this.numberOfBands = numberOfBands;
     }
 
+    public SeQuery getQuery() {
+        return preparedQuery;
+    }
+
     @Override
     public TileInfo[] execute(ISession session, SeConnection connection) throws SeException,
             IOException {

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReader.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReader.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReader.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -20,7 +20,13 @@
 import java.io.IOException;
 
 /**
- * Offers an iterator like interface to read ArcSDE raster tiles into a {@code byte[]}
+ * Offers a random access interface to the tile data for a raster request.
+ * <p>
+ * Implementations are expected to perform better when the tiles are requested in sequential x/y
+ * order (e.g., 0,0; 1,0; 2,0; 0,1; 1,1; 2,1 for 3x2 tile set), though they're required to be able
+ * to return any randomly requested tile, probably by being forced to issue a separate request to
+ * the server or do some cacheing.
+ * </p>
  *
  * @author Gabriel Roldan (OpenGeo)
  * @since 2.5.4
@@ -73,12 +79,6 @@
     public abstract int getBytesPerTile();
 
     /**
-     * @return whether there are more tiles to fetch
-     * @throws IOException
-     */
-    public abstract boolean hasNext() throws IOException;
-
-    /**
      * Fetches a tile and fills {@code tileData} with its raw pixel data packaged as bytes according
      * to the number of bits per sample
      *
@@ -91,7 +91,7 @@
      * @throws {@link IllegalArgumentException} if tileData is not null and its size is less than
      *         {@link #getBytesPerTile()}
      */
-    public abstract TileInfo[] next() throws IOException;
+    public abstract TileInfo[] getTile(int tileX, int tileY) throws IOException;
 
     /**
      * Disposes any resource being held by this TileReader, making the TileReader unusable and the
@@ -99,4 +99,12 @@
      */
     public abstract void dispose();
 
+    public abstract long getRasterId();
+
+    public abstract int getPyramidLevel();
+
+    public abstract int getMinTileX();
+
+    public abstract int getMinTileY();
+
 }
\ No newline at end of file

Modified: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDEImageReader.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDEImageReader.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDEImageReader.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -1,12 +1,7 @@
 package org.geotools.arcsde.raster.jai;
 
-import java.awt.Point;
 import java.awt.image.BufferedImage;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
 import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.Iterator;
@@ -17,10 +12,8 @@
 import javax.imageio.metadata.IIOMetadata;
 import javax.media.jai.PlanarImage;
 
-import org.geotools.arcsde.raster.io.TileInfo;
 import org.geotools.arcsde.raster.io.TileReader;
 
-import com.sun.media.imageioimpl.common.SimpleRenderedImage;
 
 public class ArcSDEImageReader extends ImageReader {
 
@@ -94,95 +87,4 @@
     public void setInput(Object input, boolean seekForwardOnly, boolean ignoreMetadata) {
         this.tileReader = (TileReader) input;
     }
-
-    @SuppressWarnings("unchecked")
-    private static class ArcSDETiledRenderedImage extends SimpleRenderedImage {
-
-        private TileReader tileReader;
-
-        public ArcSDETiledRenderedImage(TileReader tileReader, ImageTypeSpecifier typeSpec) {
-            this.tileReader = tileReader;
-            super.colorModel = typeSpec.getColorModel();
-            super.sampleModel = typeSpec.getSampleModel();
-            super.height = tileReader.getTilesHigh() * tileReader.getTileHeight();
-            super.width = tileReader.getTilesWide() * tileReader.getTileWidth();
-            super.minX = 0;
-            super.minY = 0;
-            super.tileGridXOffset = 0;
-            super.tileGridYOffset = 0;
-            super.tileHeight = tileReader.getTileHeight();
-            super.tileWidth = tileReader.getTileWidth();
-        }
-
-        private WritableRaster[][] tileCache = null;
-
-        /**
-         * @see java.awt.image.RenderedImage#getTile(int, int)
-         */
-        public Raster getTile(final int tileX, final int tileY) {
-            System.err.printf("getTile(%d, %d) %s\n", tileX, tileY, this.toString());
-            if (tileCache == null) {
-                tileCache = new WritableRaster[tileReader.getTilesWide()][tileReader.getTilesHigh()];
-            }
-
-            WritableRaster currentTile = tileCache[tileX][tileY];
-            if (currentTile == null) {
-                final int tilesWide = tileReader.getTilesWide();
-                final int tilesHigh = tileReader.getTilesHigh();
-
-                for (int ty = 0; ty < tilesHigh; ty++) {
-                    for (int tx = 0; tx < tilesWide; tx++) {
-
-                        currentTile = tileCache[tx][ty];
-
-                        if (currentTile == null) {
-                            int x = tileXToX(tx);
-                            int y = tileYToY(ty);
-                            // System.err.println("fetching tile " + tx + "," + ty);
-                            currentTile = fetchTile(x, y);
-                            tileCache[tx][ty] = currentTile;
-                        }
-                        if (tx == tileX && ty == tileY) {
-                            return currentTile;
-                        }
-                    }
-                }
-            }
-            // currentTile = tileCache[tileX][tileY];
-            return currentTile;
-        }
-
-        private WritableRaster fetchTile(final int xOrigin, final int yOrigin) {
-            final int numBands = sampleModel.getNumBands();
-
-            final SampleModel tileSampleModel = super.sampleModel.createCompatibleSampleModel(
-                    tileWidth, tileHeight);
-
-            DataBuffer dataBuffer = sampleModel.createDataBuffer();
-            TileInfo[] tileInfo;
-            try {
-                tileInfo = tileReader.next();
-            } catch (IOException e) {
-                throw new RuntimeException(e);
-            }
-            
-            for (int bandN = 0; bandN < numBands; bandN++) {
-                TileInfo bandData = tileInfo[bandN];
-                bandData.fill(dataBuffer, bandN);
-//                byte[] rawBandData = tileInfo.getTileData();
-//
-//                final int numPixels = tileWidth * tileHeight;
-//                for (int pixelN = 0; pixelN < numPixels; pixelN++) {
-//                    int val = rawBandData[2 * pixelN + 1] & 0xFF;
-//                    dataBuffer.setElem(bandN, pixelN, val);
-//                }
-            }
-
-            WritableRaster currentTile;
-            currentTile = Raster.createWritableRaster(tileSampleModel, dataBuffer, new Point(
-                    xOrigin, yOrigin));
-            return currentTile;
-        }
-
-    }
 }

Added: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java                        (rev 0)
+++ trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -0,0 +1,147 @@
+/**
+ *
+ */
+package org.geotools.arcsde.raster.jai;
+
+import java.awt.Point;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.io.IOException;
+
+import javax.imageio.ImageTypeSpecifier;
+
+import org.apache.commons.collections.map.LRUMap;
+import org.geotools.arcsde.raster.io.TileInfo;
+import org.geotools.arcsde.raster.io.TileReader;
+
+import com.sun.media.imageioimpl.common.SimpleRenderedImage;
+
+@SuppressWarnings("unchecked")
+class ArcSDETiledRenderedImage extends SimpleRenderedImage {
+
+    private TileReader tileReader;
+
+    public ArcSDETiledRenderedImage(final TileReader tileReader, final ImageTypeSpecifier typeSpec) {
+        this.tileReader = tileReader;
+        super.colorModel = typeSpec.getColorModel();
+        super.sampleModel = typeSpec.getSampleModel();
+        super.height = tileReader.getTilesHigh() * tileReader.getTileHeight();
+        super.width = tileReader.getTilesWide() * tileReader.getTileWidth();
+        super.minX = 0;
+        super.minY = 0;
+        super.tileGridXOffset = 0;
+        super.tileGridYOffset = 0;
+        super.tileHeight = tileReader.getTileHeight();
+        super.tileWidth = tileReader.getTileWidth();
+    }
+
+    /**
+     * @see java.awt.image.RenderedImage#getTile(int, int)
+     */
+    public Raster getTile(final int tileX, final int tileY) {
+        // System.err.printf("getTile(%d, %d) %s\n", tileX, tileY, this.toString());
+
+        final TileKey key = newKey(tileX, tileY);
+        WritableRaster currentTile = getCached(key);
+        if (currentTile != null) {
+            return currentTile;
+        }
+
+        final int xOrigin = tileXToX(tileX);
+        final int yOrigin = tileYToY(tileY);
+
+        final int numBands = sampleModel.getNumBands();
+
+        final SampleModel tileSampleModel = super.sampleModel.createCompatibleSampleModel(
+                tileWidth, tileHeight);
+
+        DataBuffer dataBuffer = sampleModel.createDataBuffer();
+        TileInfo[] tileInfo;
+        try {
+            tileInfo = tileReader.getTile(tileX, tileY);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        for (int bandN = 0; bandN < numBands; bandN++) {
+            TileInfo bandData = tileInfo[bandN];
+            bandData.fill(dataBuffer, bandN);
+        }
+
+        currentTile = Raster.createWritableRaster(tileSampleModel, dataBuffer, new Point(xOrigin,
+                yOrigin));
+        cache(key, currentTile);
+
+        return currentTile;
+    }
+
+    private TileKey newKey(final int tileX, final int tileY) {
+        final long rasterId = tileReader.getRasterId();
+        final int pyramidLevel = tileReader.getPyramidLevel();
+        final int rasterTileX = tileReader.getMinTileX() + tileX;
+        final int rasterTileY = tileReader.getMinTileY() + tileY;
+
+        TileKey tileKey = new TileKey(rasterId, pyramidLevel, tileX, tileY, rasterTileX,
+                rasterTileY);
+        return tileKey;
+    }
+
+    private static final LRUMap cache = new LRUMap(5);
+
+    private void cache(TileKey key, WritableRaster tile) {
+        cache.put(key, tile);
+    }
+
+    private WritableRaster getCached(TileKey key) {
+        WritableRaster tile = (WritableRaster) cache.get(key);
+        return tile;
+    }
+
+    private static class TileKey {
+        private int tileX, tileY;
+
+        private long rasterId;
+
+        private int pyramidLevel;
+
+        private int rasterTileX;
+
+        private int rasterTileY;
+
+        public TileKey(long rasterId, int pyramidLevel, int tileX, int tileY, int rasterTileX,
+                int rasterTileY) {
+            this.rasterId = rasterId;
+            this.pyramidLevel = pyramidLevel;
+            this.tileX = tileX;
+            this.tileY = tileY;
+            this.rasterTileX = rasterTileX;
+            this.rasterTileY = rasterTileY;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof TileKey)) {
+                return false;
+            }
+            TileKey t = (TileKey) o;
+            return rasterId == t.rasterId && pyramidLevel == t.pyramidLevel
+                    && rasterTileX == t.rasterTileX && rasterTileY == t.rasterTileY;
+        }
+
+        @Override
+        public int hashCode() {
+            return (17 ^ pyramidLevel) + rasterTileX * rasterTileY;
+        }
+
+        public int getTileX() {
+            return tileX;
+        }
+
+        public int getTileY() {
+            return tileY;
+        }
+
+    }
+}
\ No newline at end of file


Property changes on: trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Id URL
Added: svn:eol-style
   + native

Modified: trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java 2009-11-04 16:32:24 UTC (rev 34326)
+++ trunk/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java 2009-11-04 19:13:17 UTC (rev 34327)
@@ -120,7 +120,7 @@
         final AbstractGridCoverage2DReader reader = getReader();
         assertNotNull("Couldn't obtain a reader for " + tableName, reader);
 
-        final int count = 0;
+        final int count = 10;
         long time = 0;
         // warm up
         _testIMG_USGSQUAD_SGBASE(reader);
@@ -239,7 +239,11 @@
         assertNotNull("read coverage returned null", coverage);
 
         RenderedImage image = coverage.view(ViewType.PHOTOGRAPHIC).getRenderedImage();
+        Stopwatch sw = new Stopwatch();
+        sw.start();
         writeToDisk(image, "testRead_" + tableName);
+        sw.stop();
+        LOGGER.info("wrote in " + sw.getTimeString());
     }
 
     @Test


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
GeoTools-commits mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-commits