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