001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/tags/2.1/src/org/deegree/io/oraclegeoraster/GeoRasterReader.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2006 by: 006 EXSE, Department of Geography, University of Bonn 007 http://www.giub.uni-bonn.de/deegree/ 008 lat/lon GmbH 009 http://www.lat-lon.de 010 011 This library is free software; you can redistribute it and/or 012 modify it under the terms of the GNU Lesser General Public 013 License as published by the Free Software Foundation; either 014 version 2.1 of the License, or (at your option) any later version. 015 016 This library is distributed in the hope that it will be useful, 017 but WITHOUT ANY WARRANTY; without even the implied warranty of 018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 019 Lesser General Public License for more details. 020 021 You should have received a copy of the GNU Lesser General Public 022 License along with this library; if not, write to the Free Software 023 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 024 025 Contact: 026 027 Andreas Poth 028 lat/lon GmbH 029 Aennchenstr. 19 030 53177 Bonn 031 Germany 032 E-Mail: poth@lat-lon.de 033 034 Prof. Dr. Klaus Greve 035 Department of Geography 036 University of Bonn 037 Meckenheimer Allee 166 038 53115 Bonn 039 Germany 040 E-Mail: greve@giub.uni-bonn.de 041 042 043 ---------------------------------------------------------------------------*/ 044 package org.deegree.io.oraclegeoraster; 045 046 import java.awt.Graphics2D; 047 import java.awt.Image; 048 import java.awt.image.BufferedImage; 049 import java.awt.image.RenderedImage; 050 import java.io.IOException; 051 import java.lang.reflect.Method; 052 import java.sql.Connection; 053 import java.sql.PreparedStatement; 054 import java.sql.ResultSet; 055 import java.sql.SQLException; 056 import java.sql.Statement; 057 import java.util.Properties; 058 059 import oracle.spatial.georaster.GeoRasterException; 060 import oracle.spatial.georaster.JGeoRaster; 061 import oracle.spatial.georaster.JGeoRasterMeta; 062 import oracle.sql.STRUCT; 063 064 import org.deegree.framework.log.ILogger; 065 import org.deegree.framework.log.LoggerFactory; 066 import org.deegree.framework.util.StringTools; 067 import org.deegree.io.DBConnectionPool; 068 import org.deegree.io.JDBCConnection; 069 import org.deegree.model.spatialschema.Envelope; 070 import org.deegree.ogcwebservices.InvalidParameterValueException; 071 072 /** 073 * 074 * 075 * 076 * @version $Revision: 7765 $ 077 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 078 * @author last edited by: $Author: apoth $ 079 * 080 * @version 1.0. $Revision: 7765 $, $Date: 2007-07-16 13:05:57 +0200 (Mo, 16 Jul 2007) $ 081 * 082 * @since 2.0 083 */ 084 public class GeoRasterReader { 085 086 private static final ILogger LOG = LoggerFactory.getLogger( GeoRasterReader.class ); 087 088 /** 089 * 090 * @param grDesc 091 * @param envelope 092 * requested envelope 093 * @param level 094 * requested level (resolution) 095 * @return 096 * @throws SQLException 097 * @throws IOException 098 * @throws GeoRasterException 099 * @throws Exception 100 */ 101 public static RenderedImage exportRaster( GeoRasterDescription grDesc, Envelope envelope ) 102 throws SQLException, IOException, GeoRasterException, Exception { 103 104 DBConnectionPool pool = DBConnectionPool.getInstance(); 105 JDBCConnection jdbc = grDesc.getJdbcConnection(); 106 Connection con = pool.acquireConnection( jdbc.getDriver(), jdbc.getURL(), jdbc.getUser(), jdbc.getPassword() ); 107 108 RenderedImage ri = exportRaster( con, envelope, grDesc.getRdtTable(), grDesc.getTable(), grDesc.getColumn(), 109 grDesc.getIdentification(), grDesc.getLevel() ); 110 111 /* 112 * System.out.println( grDesc.getTable() ); System.out.println( grDesc.getLevel() ); 113 * System.out.println(ri.getWidth() ); System.out.println(ri.getHeight() ); 114 */ 115 116 pool.releaseConnection( con, jdbc.getDriver(), jdbc.getURL(), jdbc.getUser(), jdbc.getPassword() ); 117 118 return ri; 119 } 120 121 /** 122 * 123 * @param connection 124 * connnection to Oracle database 125 * @param envelope 126 * requested area 127 * @param rasterRDT 128 * name of the RDT-table 129 * @param rasterTable 130 * name of the table containing a georaster col 131 * @param geoRasterCol 132 * name of the geoRaster column 133 * @param identification 134 * SQL where clause that identifies the raster of interest 135 * @param level 136 * requested resolution level 137 * @return 138 * @throws SQLException 139 * @throws IOException 140 * @throws GeoRasterException 141 * @throws Exception 142 */ 143 public static RenderedImage exportRaster( Connection connection, Envelope envelope, String rasterRDT, 144 String rasterTable, String geoRasterCol, String identification, int level ) 145 throws Exception { 146 RenderedImage img = null; 147 try { 148 149 int rasterID = readRasterID( connection, identification, rasterTable, geoRasterCol ); 150 151 STRUCT struct = readGeoRasterMetadata( connection, rasterRDT, rasterTable, geoRasterCol, rasterID ); 152 153 int major = connection.getMetaData().getDriverMajorVersion(); 154 int minor = connection.getMetaData().getDriverMinorVersion(); 155 156 LOG.logDebug( "mapping STRUCT to a JGeoRaster object" ); 157 LOG.logDebug( "identified Oracle version: ", major + "." + minor ); 158 159 JGeoRaster jGeoRaster = null; 160 if ( major == 10 && minor == 1 ) { 161 // synthax for Oracle 10g R1 162 Class[] clzz = new Class[] { STRUCT.class }; 163 Method method = JGeoRaster.class.getMethod( "load", clzz ); 164 jGeoRaster = (JGeoRaster)method.invoke( null, new Object[] { struct } ); 165 jGeoRaster = JGeoRaster.load( struct ); 166 } else if ( major == 10 && minor == 2 ) { 167 // synthax for Oracle 10g R2 168 Class[] clzz = new Class[] { STRUCT.class, Connection.class, boolean.class }; 169 Method method = JGeoRaster.class.getMethod( "load", clzz ); 170 Object[] params = new Object[] { struct, connection, false }; 171 jGeoRaster = (JGeoRaster)method.invoke( null, params ); 172 } else { 173 throw new InvalidParameterValueException("Oracle must have version 10.1 or 10.2 for using Georaster functionality" ); 174 } 175 jGeoRaster.setViewerUse( true ); 176 Properties props = jGeoRaster.getProperties(); 177 178 int maxWidth = Integer.parseInt( props.getProperty( "rasterInfo/dimensionSize_column" ) ); 179 int maxHeight = Integer.parseInt( props.getProperty( "rasterInfo/dimensionSize_row" ) ); 180 181 JGeoRasterMeta metaObj = jGeoRaster.getMetadataObject(); 182 183 double xMin = metaObj.getX( 0, 0 ); 184 double xMax = metaObj.getX( maxWidth - 1, maxHeight - 1 ); 185 double sc = Math.pow( 2, level ); 186 double lenX = ( xMax - xMin ) * sc; 187 double yMin = metaObj.getY( 0, 0 ); 188 double yMax = metaObj.getY( maxWidth - 1, maxHeight - 1 ); 189 double lenY = ( yMax - yMin ) * sc; 190 191 int xMinCell = (int) Math.round( ( envelope.getMin().getX() - xMin ) * maxWidth / lenX ); 192 int xMaxCell = (int) Math.round( ( envelope.getMax().getX() - xMin ) * maxWidth / lenX ) - 1; 193 int yMaxCell = (int) Math.round( ( envelope.getMin().getY() - yMin ) * maxHeight / lenY ); 194 int yMinCell = (int) Math.round( ( envelope.getMax().getY() - yMin ) * maxHeight / lenY ) - 1; 195 196 String bb = StringTools.concat( 100, xMinCell, " ", yMinCell, " ", xMaxCell, " ", yMaxCell ); 197 LOG.logInfo( "requested box:", bb ); 198 199 LOG.logDebug( "reading georaster image, with level: " + level ); 200 img = jGeoRaster.getRasterImage( connection, level, xMinCell, yMinCell, xMaxCell, yMaxCell ); 201 202 int xDiff = ( xMaxCell - xMinCell ) + 1; 203 int yDiff = ( yMaxCell - yMinCell ) + 1; 204 if ( img != null && ( img.getWidth() != xDiff || img.getHeight() != yDiff ) && xDiff > 0 && yDiff > 0 ) { 205 // request img size != result 206 LOG.logDebug( StringTools.concat( 100, "request img size != result; new image size: ", xDiff, "x", 207 yDiff ) ); 208 BufferedImage bimg = new BufferedImage( xDiff, yDiff, BufferedImage.TYPE_INT_ARGB ); 209 Graphics2D bg = bimg.createGraphics(); 210 211 int posX = 0; 212 int posY = 0; 213 214 if ( xMinCell < 0 ) { 215 posX = Math.abs( xMinCell ); 216 } 217 if ( yMinCell < 0 ) { 218 posY = Math.abs( yMinCell ); 219 } 220 221 bg.drawImage( (Image) img, posX, posY, null ); 222 bg.dispose(); 223 224 img = bimg; 225 } 226 227 } catch ( SQLException e1 ) { 228 e1.printStackTrace(); 229 String s = StringTools.concat( 1000, e1.getMessage(), " ", rasterTable, "; ", rasterRDT, "; ", 230 geoRasterCol, "; ", identification, "; level: ", level ); 231 throw new RuntimeException( s ); 232 } catch ( Exception e ) { 233 e.printStackTrace(); 234 throw new RuntimeException( e ); 235 } 236 return img; 237 } 238 239 /** 240 * 241 * @param connection 242 * @param rasterRDT 243 * @param rasterTable 244 * @param geoRasterCol 245 * @param rasterID 246 * @return 247 * @throws SQLException 248 */ 249 private static STRUCT readGeoRasterMetadata( Connection connection, String rasterRDT, String rasterTable, 250 String geoRasterCol, int rasterID ) 251 throws SQLException { 252 LOG.logDebug( "reading georaster" ); 253 PreparedStatement ps = connection.prepareStatement( "select " + geoRasterCol + " from " + rasterTable 254 + " a where a." + geoRasterCol + ".rasterid = " + rasterID 255 + " and a." + geoRasterCol + ".rasterdatatable = '" 256 + rasterRDT.toUpperCase() + "'" ); 257 ResultSet resultset = ps.executeQuery(); 258 if ( !resultset.next() ) { 259 throw new SQLException( "No GeoRaster object exists at rasterid = " + rasterID + ", RDT = " + rasterRDT ); 260 } 261 262 STRUCT struct = (STRUCT) resultset.getObject( geoRasterCol.toUpperCase() ); 263 resultset.close(); 264 return struct; 265 } 266 267 /** 268 * returns the rasterID of the requested GeoRaster 269 * 270 * @param connection 271 * @param identification 272 * @param sql 273 * @return 274 * @throws SQLException 275 * @throws GeoRasterException 276 */ 277 private static int readRasterID( Connection connection, String identification, String rasterTable, 278 String geoRasterCol ) 279 throws SQLException, GeoRasterException { 280 281 LOG.logDebug( "reading rasterid " ); 282 283 String sql = "SELECT a." + geoRasterCol + ".rasterid FROM " + rasterTable + " a where " + identification; 284 Statement stmt = connection.createStatement(); 285 ResultSet rs = stmt.executeQuery( sql ); 286 if ( !rs.next() ) { 287 throw new GeoRasterException( "Georaster with identification = " + identification + " not found!" ); 288 } 289 int rasterID = rs.getInt( 1 ); 290 stmt.close(); 291 rs.close(); 292 return rasterID; 293 } 294 295 } 296 /*************************************************************************************************** 297 * Changes to this class. What the people have been up to: $Log$ Revision 1.11 2006/07/05 12:59:09 298 * poth bug fix - raster coordinates calculation for other pyramid levels than '0' 299 * 300 * Revision 1.10 2006/07/03 06:40:13 poth ** empty log message *** 301 * 302 * Revision 1.9 2006/06/30 14:15:29 poth footer added 303 * 304 * 305 **************************************************************************************************/