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 }