001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/oraclegeoraster/GeoRasterReader.java $ 002 /*---------------- FILE HEADER ------------------------------------------ 003 004 This file is part of deegree. 005 Copyright (C) 2001-2008 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: 9342 $ 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: 9342 $, $Date: 2007-12-27 13:32:57 +0100 (Do, 27 Dez 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( "Envelope: ", envelope ); 157 LOG.logDebug( "mapping STRUCT to a JGeoRaster object" ); 158 LOG.logDebug( "identified Oracle version: ", major + "." + minor ); 159 160 JGeoRaster jGeoRaster = null; 161 if ( major == 10 && minor == 1 ) { 162 // synthax for Oracle 10g R1 163 Class[] clzz = new Class[] { STRUCT.class }; 164 Method method = JGeoRaster.class.getMethod( "load", clzz ); 165 jGeoRaster = (JGeoRaster) method.invoke( null, new Object[] { struct } ); 166 jGeoRaster = JGeoRaster.load( struct ); 167 } else if ( major == 10 && minor == 2 ) { 168 // synthax for Oracle 10g R2 169 Class[] clzz = new Class[] { STRUCT.class, Connection.class, boolean.class }; 170 Method method = JGeoRaster.class.getMethod( "load", clzz ); 171 Object[] params = new Object[] { struct, connection, false }; 172 jGeoRaster = (JGeoRaster) method.invoke( null, params ); 173 } else { 174 throw new InvalidParameterValueException( 175 "Oracle must have version 10.1 or 10.2 for using Georaster functionality" ); 176 } 177 jGeoRaster.setViewerUse( true ); 178 Properties props = jGeoRaster.getProperties(); 179 180 int maxWidth = Integer.parseInt( props.getProperty( "rasterInfo/dimensionSize_column" ) ); 181 int maxHeight = Integer.parseInt( props.getProperty( "rasterInfo/dimensionSize_row" ) ); 182 183 JGeoRasterMeta metaObj = jGeoRaster.getMetadataObject(); 184 185 double xMin = metaObj.getX( 0, 0 ); 186 double xMax = metaObj.getX( maxWidth - 1, maxHeight - 1 ); 187 double sc = Math.pow( 2, level ); 188 double lenX = ( xMax - xMin ) * sc; 189 double yMin = metaObj.getY( 0, 0 ); 190 double yMax = metaObj.getY( maxWidth - 1, maxHeight - 1 ); 191 double lenY = ( yMax - yMin ) * sc; 192 193 int xMinCell = (int) Math.round( ( envelope.getMin().getX() - xMin ) * maxWidth / lenX ); 194 int xMaxCell = (int) Math.round( ( envelope.getMax().getX() - xMin ) * maxWidth / lenX ) - 1; 195 int yMaxCell = (int) Math.round( ( envelope.getMin().getY() - yMin ) * maxHeight / lenY ); 196 int yMinCell = (int) Math.round( ( envelope.getMax().getY() - yMin ) * maxHeight / lenY ) - 1; 197 198 String bb = StringTools.concat( 100, xMinCell, " ", yMinCell, " ", xMaxCell, " ", yMaxCell ); 199 LOG.logInfo( "requested box:", bb ); 200 201 LOG.logDebug( "reading georaster image, with level: " + level ); 202 img = jGeoRaster.getRasterImage( connection, level, xMinCell, yMinCell, xMaxCell, yMaxCell ); 203 204 int xDiff = ( xMaxCell - xMinCell ) + 1; 205 int yDiff = ( yMaxCell - yMinCell ) + 1; 206 if ( img != null && ( img.getWidth() != xDiff || img.getHeight() != yDiff ) && xDiff > 0 && yDiff > 0 ) { 207 // request img size != result 208 LOG.logDebug( StringTools.concat( 100, "request img size != result; new image size: ", xDiff, "x", 209 yDiff ) ); 210 BufferedImage bimg = new BufferedImage( xDiff, yDiff, BufferedImage.TYPE_INT_ARGB ); 211 Graphics2D bg = bimg.createGraphics(); 212 213 int posX = 0; 214 int posY = 0; 215 216 if ( xMinCell < 0 ) { 217 posX = Math.abs( xMinCell ); 218 } 219 if ( yMinCell < 0 ) { 220 posY = Math.abs( yMinCell ); 221 } 222 223 bg.drawImage( (Image) img, posX, posY, null ); 224 bg.dispose(); 225 226 img = bimg; 227 } 228 229 } catch ( SQLException e1 ) { 230 e1.printStackTrace(); 231 String s = StringTools.concat( 1000, e1.getMessage(), " ", rasterTable, "; ", rasterRDT, "; ", 232 geoRasterCol, "; ", identification, "; level: ", level ); 233 throw new RuntimeException( s ); 234 } catch ( Exception e ) { 235 e.printStackTrace(); 236 throw new RuntimeException( e ); 237 } 238 return img; 239 } 240 241 /** 242 * 243 * @param connection 244 * @param rasterRDT 245 * @param rasterTable 246 * @param geoRasterCol 247 * @param rasterID 248 * @return 249 * @throws SQLException 250 */ 251 private static STRUCT readGeoRasterMetadata( Connection connection, String rasterRDT, String rasterTable, 252 String geoRasterCol, int rasterID ) 253 throws SQLException { 254 LOG.logDebug( "reading georaster" ); 255 PreparedStatement ps = connection.prepareStatement( "select " + geoRasterCol + " from " + rasterTable 256 + " a where a." + geoRasterCol + ".rasterid = " + rasterID 257 + " and a." + geoRasterCol + ".rasterdatatable = '" 258 + rasterRDT.toUpperCase() + "'" ); 259 ResultSet resultset = ps.executeQuery(); 260 if ( !resultset.next() ) { 261 throw new SQLException( "No GeoRaster object exists at rasterid = " + rasterID + ", RDT = " + rasterRDT ); 262 } 263 264 STRUCT struct = (STRUCT) resultset.getObject( geoRasterCol.toUpperCase() ); 265 resultset.close(); 266 return struct; 267 } 268 269 /** 270 * returns the rasterID of the requested GeoRaster 271 * 272 * @param connection 273 * @param identification 274 * @param sql 275 * @return 276 * @throws SQLException 277 * @throws GeoRasterException 278 */ 279 private static int readRasterID( Connection connection, String identification, String rasterTable, 280 String geoRasterCol ) 281 throws SQLException, GeoRasterException { 282 283 LOG.logDebug( "reading rasterid " ); 284 285 String sql = "SELECT a." + geoRasterCol.toUpperCase() + ".rasterid FROM " + rasterTable.toUpperCase() 286 + " a where " + identification; 287 LOG.logDebug( sql ); 288 Statement stmt = connection.createStatement(); 289 ResultSet rs = stmt.executeQuery( sql ); 290 if ( !rs.next() ) { 291 throw new GeoRasterException( "Georaster with identification = " + identification + " not found!" ); 292 } 293 int rasterID = rs.getInt( 1 ); 294 stmt.close(); 295 rs.close(); 296 return rasterID; 297 } 298 299 }