001    //$HeadURL$
002    /*----------------    FILE HEADER  ------------------------------------------
003     This file is part of deegree.
004     Copyright (C) 2001-2008 by:
005     Department of Geography, University of Bonn
006     http://www.giub.uni-bonn.de/deegree/
007     lat/lon GmbH
008     http://www.lat-lon.de
009    
010     This library is free software; you can redistribute it and/or
011     modify it under the terms of the GNU Lesser General Public
012     License as published by the Free Software Foundation; either
013     version 2.1 of the License, or (at your option) any later version.
014     This library is distributed in the hope that it will be useful,
015     but WITHOUT ANY WARRANTY; without even the implied warranty of
016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     Lesser General Public License for more details.
018     You should have received a copy of the GNU Lesser General Public
019     License along with this library; if not, write to the Free Software
020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021     Contact:
022    
023     Andreas Poth
024     lat/lon GmbH
025     Aennchenstr. 19
026     53177 Bonn
027     Germany
028     E-Mail: poth@lat-lon.de
029    
030     Prof. Dr. Klaus Greve
031     Department of Geography
032     University of Bonn
033     Meckenheimer Allee 166
034     53115 Bonn
035     Germany
036     E-Mail: greve@giub.uni-bonn.de
037     ---------------------------------------------------------------------------*/
038    
039    package org.deegree.io.oraclegeoraster;
040    
041    import java.io.BufferedReader;
042    import java.io.File;
043    import java.io.FileReader;
044    import java.io.FileWriter;
045    import java.io.IOException;
046    import java.io.PrintWriter;
047    import java.io.Reader;
048    import java.sql.CallableStatement;
049    import java.sql.Connection;
050    import java.sql.ResultSet;
051    import java.sql.SQLException;
052    import java.sql.Statement;
053    import java.text.DecimalFormat;
054    import java.text.NumberFormat;
055    import java.util.Locale;
056    
057    import org.deegree.framework.log.ILogger;
058    import org.deegree.framework.log.LoggerFactory;
059    import org.deegree.framework.util.StringTools;
060    
061    import oracle.jdbc.OraclePreparedStatement;
062    import oracle.spatial.georaster.GeoRasterAdapter;
063    import oracle.sql.STRUCT;
064    
065    /**
066     * This class offers one public static method for importing an image read from a file
067     * into Oracle GeoRaster Database. To work correctly following assumptions are made:
068     * <ul>
069     *  <li>a worldfile is assigend to the image file
070     *  <li>DLLTrigger has been set for RDT-Table
071     *  <li>no mosaicing and pyramid calculations will be perform by this class
072     * </ul>
073     * 
074     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
075     * @author last edited by: $Author: poth $
076     * 
077     * @version. $Revision: 6251 $, $Date: 2007-03-19 16:59:28 +0100 (Mo, 19 Mrz 2007) $
078     */
079    public class GeoRasterWriter {
080    
081        private static final ILogger LOG = LoggerFactory.getLogger( GeoRasterWriter.class );
082    
083        /**
084         * 
085         * @param connection
086         *            database connection
087         * @param imageFile
088         *            absolut path to the image file to import
089         * @param worldFilename
090         *            name of the images worldfile
091         * @param rdtName
092         *            name of the RDT table
093         * @param imageTableName
094         *            name of the tabvle to store the image
095         * @param georColName
096         *            name of the GeoRaster column in imageTableName
097         * @throws Exception
098         */
099        public static void importRaster( Connection connection, String imageFile, String worldFilename, String rdtName,
100                                         String imageTableName, String georColName )
101                                throws Exception {
102    
103            try {
104    
105                connection.setAutoCommit( false );
106    
107                Statement stat = connection.createStatement();
108                String sql = null;
109                ResultSet resSet = null;
110    
111                sql = "select max(id) from " + imageTableName;
112    
113                resSet = stat.executeQuery( sql );
114                if ( !resSet.next() ) {
115                    throw new SQLException( "Error initializing ID" );
116                }
117                int newRasterID = resSet.getInt( 1 );
118                newRasterID++;
119                sql = StringTools.concat( 500, "insert into ", imageTableName, "( ID, ", georColName, ") ", "values ( ",
120                                          newRasterID, ", MDSYS.sdo_geor.init( '", rdtName, "' ) )" );
121                LOG.logInfo( sql );
122                stat.execute( sql );
123    
124                // RASTERPROPERTY 
125                sql = "SELECT  a." + georColName + ".rasterid FROM " + imageTableName + " a where id = " + newRasterID;
126                resSet = stat.executeQuery( sql );
127                LOG.logInfo( sql );
128                if ( !resSet.next() ) {
129                    throw new SQLException( "Error initializing rasterID" );
130                }
131                int rasterID = resSet.getInt( 1 );
132    
133                resSet.close();
134                stat.close();
135    
136                String s7 = StringTools.concat( 500, "SELECT ", georColName, " FROM ", imageTableName, " a where a.",
137                                                georColName, ".rasterid = ? and a.", georColName, ".rasterdatatable = ?" );
138                LOG.logInfo( s7 );
139    
140                OraclePreparedStatement oraclepreparedstatement = (OraclePreparedStatement) connection.prepareStatement( s7 );
141    
142                oraclepreparedstatement.setInt( 1, rasterID );
143                oraclepreparedstatement.setString( 2, rdtName );
144                ResultSet resultset = null;
145    
146                resultset = oraclepreparedstatement.executeQuery();
147    
148                if ( !resultset.next() ) {
149                    throw new SQLException( "No georaster object exists at rasterid = " + rasterID + ", RDT = " + rdtName );
150                }
151    
152                STRUCT struct = (STRUCT) resultset.getObject( georColName.toUpperCase() );
153                oracle.sql.Datum adatum[] = struct.getOracleAttributes();
154                oraclepreparedstatement.close();
155    
156                if ( adatum[0] != null || adatum[1] != null || adatum[4] != null ) {
157    
158                    String s9 = "delete from " + rdtName + " where rasterid = " + rasterID;
159                    CallableStatement callablestatement = connection.prepareCall( s9 );
160                    LOG.logInfo( s9 );
161                    callablestatement.execute();
162                    String s10 = StringTools.concat( 1000, "declare\ngeor SDO_GEORASTER;\nbegin\nselect ", georColName,
163                                                     " into geor from ", imageTableName, " a where a.", georColName,
164                                                     ".rasterid = ", rasterID, " and a.", georColName,
165                                                     ".rasterdatatable = '", rdtName, "' for update;\n",
166                                                     "geor := sdo_geor.init('", rdtName, "', ", rasterID, ");\n",
167                                                     "update ", imageTableName, " a set ", georColName, " = geor where a.",
168                                                     georColName, ".rasterid = ", rasterID, " and a.", georColName,
169                                                     ".rasterdatatable = '", rdtName, "';commit;end;" );
170                    CallableStatement callablestatement1 = connection.prepareCall( s10 );
171                    LOG.logInfo( s10 );
172                    callablestatement1.execute();
173                }
174    
175                File f = null;
176                try {
177                    // FIXME this is not so fine: creatign 2 files, one of which is empty
178                    // not so bad, because they get deleted when Importer ends; fix if time
179                    // availab
180                    f = File.createTempFile( "temp_wld", "tfw" );
181                    f.deleteOnExit();
182                    saveWorldFile( f.getAbsolutePath(), createParsFromWorldfile( new FileReader( worldFilename ) ), true );
183    
184                } catch ( Exception e ) {
185                    LOG.logError( e.getMessage(), e );
186                }
187    
188                STRUCT struct1 = GeoRasterAdapter.loadFromFile( "", imageFile, "WORLDFILE", f.getAbsolutePath() + ".tfw",
189                                                         "blocking=true", struct, connection );
190    
191                if ( struct1 != null ) {
192                    // Raster_relief_imp
193                    String s8 = StringTools.concat( 500, "UPDATE ", imageTableName, " a SET a.", georColName,
194                                                    " = ? WHERE a.", georColName, ".rasterid = ? and a.", georColName,
195                                                    ".rasterdatatable = ?" );
196                    LOG.logInfo( s8 );
197                    OraclePreparedStatement oraclepreparedstatement1 = (OraclePreparedStatement) connection.prepareStatement( s8 );
198                    oraclepreparedstatement1.setObject( 1, struct1 );
199                    oraclepreparedstatement1.setInt( 2, rasterID );
200                    oraclepreparedstatement1.setString( 3, rdtName );
201                    oraclepreparedstatement1.execute();
202                    oraclepreparedstatement1.close();
203                } else {
204                    throw new SQLException( "\nThe georaster object is not loaded correctly!!" );
205                }
206                if ( resultset != null ) {
207                    resultset.close();
208                }
209    
210                connection.commit();
211                LOG.logInfo( "commited" );
212            } catch ( Exception e ) {
213                LOG.logError( e.getMessage(), e );
214                throw new RuntimeException( e );
215            }
216        }
217    
218        public static double[] createParsFromWorldfile( Reader reader )
219                                throws Exception {
220            double[] pars = null;
221            DecimalFormat decimalformat = (DecimalFormat) NumberFormat.getInstance( Locale.ENGLISH );
222            BufferedReader bufferedreader = null;
223            try {
224                bufferedreader = new BufferedReader( reader );
225                double d = decimalformat.parse( bufferedreader.readLine().trim() ).doubleValue();
226                double d1 = decimalformat.parse( bufferedreader.readLine().trim() ).doubleValue();
227                double d2 = decimalformat.parse( bufferedreader.readLine().trim() ).doubleValue();
228                double d3 = decimalformat.parse( bufferedreader.readLine().trim() ).doubleValue();
229                double d4 = decimalformat.parse( bufferedreader.readLine().trim() ).doubleValue();
230                double d5 = decimalformat.parse( bufferedreader.readLine().trim() ).doubleValue();
231    
232                decimalformat = (DecimalFormat) DecimalFormat.getInstance( Locale.GERMAN );
233                decimalformat.setDecimalSeparatorAlwaysShown( true );
234                decimalformat.setGroupingUsed( false );
235                decimalformat.setMinimumFractionDigits( 1 );
236                pars = new double[] { d, d1, d2, d3, d4, d5 };
237    
238            } catch ( Exception e ) {
239                e.printStackTrace();
240            }
241            bufferedreader.close();
242            return pars;
243        }
244    
245        private static void saveWorldFile( String filename, double[] wldPars, boolean reformat )
246                                throws IOException {
247    
248            StringBuffer sb = new StringBuffer();
249    
250            String[] _wldPars = new String[wldPars.length];
251    
252            DecimalFormat decimalformat = null;
253            if ( reformat ) { // reformat numbers to german locale
254                decimalformat = (DecimalFormat) NumberFormat.getInstance( Locale.GERMAN );
255            } else {
256                decimalformat = (DecimalFormat) NumberFormat.getInstance( Locale.ENGLISH );
257            }
258            decimalformat.setDecimalSeparatorAlwaysShown( true );
259            decimalformat.setGroupingUsed( false );
260            decimalformat.setMinimumFractionDigits( 1 );
261            for ( int i = 0; i < _wldPars.length; i++ ) {
262                _wldPars[i] = decimalformat.format( wldPars[i] );
263    
264            }
265    
266            sb.append( _wldPars[0] ).append( "\n" ).append( _wldPars[1] ).append( "\n" );
267            sb.append( _wldPars[2] ).append( "\n" ).append( _wldPars[3] ).append( "\n" );
268            sb.append( _wldPars[4] ).append( "\n" ).append( _wldPars[5] ).append( "\n" );
269    
270            File f = new File( filename + ".tfw" );
271            if ( reformat ) {// reformat also menas: only need this file temporarily
272                f.deleteOnExit();
273            }
274            FileWriter fw = new FileWriter( f );
275            PrintWriter pw = new PrintWriter( fw );
276    
277            pw.print( sb.toString() );
278    
279            pw.close();
280            fw.close();
281        }
282    
283    }