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 **************************************************************************************************/