    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/tools/shape/IndexFrame.java $
    002    /*----------------------------------------
    003     Coyright 2003 IDgis BV
    004
    005     This library is free software; you can redistribute it and/or
    006     modify it under the terms of the GNU Lesser General Public
    007     License as published by the Free Software Foundation; either
    008     version 2.1 of the License, or (at your option) any later version.
    009
    010     This library is distributed in the hope that it will be useful,
    011     but WITHOUT ANY WARRANTY; without even the implied warranty of
    012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    013     Lesser General Public License for more details.
    014
    015     You should have received a copy of the GNU Lesser General Public
    016     License along with this library; if not, write to the Free Software
    017     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    018     ----------------------------------------*/
    019
    020    package org.deegree.tools.shape;
    021
    022    import java.awt.BorderLayout;
    023    import java.awt.Container;
    024    import java.awt.GridLayout;
    025    import java.awt.event.ActionEvent;
    026    import java.awt.event.ActionListener;
    027    import java.io.File;
    028
    029    import javax.swing.JButton;
    030    import javax.swing.JCheckBox;
    031    import javax.swing.JFrame;
    032    import javax.swing.JLabel;
    033    import javax.swing.JOptionPane;
    034    import javax.swing.JPanel;
    035    import javax.swing.JProgressBar;
    036    import javax.swing.event.ChangeEvent;
    037    import javax.swing.event.ChangeListener;
    038
    039    import org.deegree.datatypes.QualifiedName;
    040    import org.deegree.framework.log.ILogger;
    041    import org.deegree.framework.log.LoggerFactory;
    042    import org.deegree.io.dbaseapi.DBaseIndex;
    043    import org.deegree.io.rtree.HyperBoundingBox;
    044    import org.deegree.io.rtree.HyperPoint;
    045    import org.deegree.io.rtree.RTree;
    046    import org.deegree.io.shpapi.ShapeFile;
    047    import org.deegree.model.feature.Feature;
    048    import org.deegree.model.spatialschema.Envelope;
    049    import org.deegree.model.spatialschema.Geometry;
    050    import org.deegree.model.spatialschema.GeometryFactory;
    051    import org.deegree.model.spatialschema.Point;
    052
    053    public class IndexFrame extends JFrame implements ActionListener, ChangeListener {
    054
    055        private static final ILogger LOG = LoggerFactory.getLogger( IndexFrame.class );
    056
    057        protected JCheckBox geometryCheckBox;
    058
    059        protected JCheckBox[] checkboxes;
    060
    061        protected ShapeFile shapeFile;
    062
    063        protected String[] properties;
    064
    065        protected JButton cancel;
    066
    067        protected Indexing indexing = null;
    068
    069        protected String fileName;
    070
    071        protected boolean hasGeometry;
    072
    073        protected boolean[] hasIndex;
    074
    075        protected JCheckBox[] uniqueBoxes;
    076
    077        class Indexing extends Thread {
    078            boolean stop = false;
    079
    080            IndexFrame frame;
    081
    082            Indexing( IndexFrame frame ) {
    083                this.frame = frame;
    084            }
    085
    086            public void run() {
    087                Container container = getContentPane();
    088                container.removeAll();
    089                container.setLayout( new GridLayout( 3, 1 ) );
    090
    091                int features = shapeFile.getRecordNum();
    092                container.add( new JLabel( "Indexing..." ) );
    093                JProgressBar progressBar = new JProgressBar( 1, features );
    094                progressBar.setStringPainted( true );
    095                container.add( progressBar );
    096                cancel = new JButton( "Cancel" );
    097                cancel.addActionListener( frame );
    098                container.add( cancel );
    099                pack();
    100
    101                boolean geometry = false;
    102                DBaseIndex[] index = new DBaseIndex[properties.length];
    103                RTree rtree = null;
    104
    105                try {
    106                    String[] dataTypes = shapeFile.getDataTypes();
    107                    int[] lengths = shapeFile.getDataLengths();
    108
    109                    if ( geometryCheckBox.isSelected() && !hasGeometry ) {
    110                        geometry = true;
    111                        rtree = new RTree( 2, 11, fileName + ".rti" );
    112                    }
    113
    114                    boolean indexes = false;
    115                    for ( int i = 0; i < index.length; i++ ) {
    116                        if ( checkboxes[i].isSelected() && !hasIndex[i] ) {
    117                            index[i] = DBaseIndex.createIndex(
    118                                                               fileName + "$" + properties[i],
    119                                                               properties[i],
    120                                                               lengths[i],
    121                                                               uniqueBoxes[i].isSelected(),
    122                                                               ( dataTypes[i].equalsIgnoreCase( "N" )
    123                                                                 || dataTypes[i].equalsIgnoreCase( "I" ) || dataTypes[i].equalsIgnoreCase( "F" ) ) );
    124                            indexes = true;
    125                        } else
    126                            index[i] = null;
    127                    }
    128
    129                    if ( geometry || indexes ) {
    130                        for ( int i = 1; i < features + 1; i++ ) {
    131                            Feature feature = shapeFile.getFeatureByRecNo( i );
    132
    133                            if ( geometry ) {
    134                                Geometry[] geometries = feature.getGeometryPropertyValues();
    135                                if ( geometries.length == 0 ) {
    136                                    LOG.logInfo( "no geometries at recno" + i );
    137                                    continue;
    138                                }
    139                                Envelope envelope = null;
    140                                // TODO: deal with more than one geometry; handle geometry=null (allowed
    141                                // in shapefile)
    142                                envelope = ( feature.getDefaultGeometryPropertyValue() ).getEnvelope();
    143                                if ( envelope == null ) { // assume a Point-geometry
    144                                    Point pnt = (Point) geometries[0];
    145                                    envelope = GeometryFactory.createEnvelope( pnt.getX(), pnt.getY(), pnt.getX(),
    146                                                                               pnt.getY(), null );
    147                                }
    148                                HyperBoundingBox box = new HyperBoundingBox(
    149                                                                             new HyperPoint( envelope.getMin().getAsArray() ),
    150                                                                             new HyperPoint( envelope.getMax().getAsArray() ) );
    151                                rtree.insert( new Integer( i ), box );
    152                            }
    153
    154                            for ( int j = 0; j < index.length; j++ ) {
    155                                if ( index[j] != null ) {
    156                                    QualifiedName qn = new QualifiedName( properties[j] );
    157                                    index[j].addKey( (Comparable) feature.getDefaultProperty( qn ), i );
    158                                }
    159                            }
    160
    161                            progressBar.setValue( i );
    162
    163                            synchronized ( this ) {
    164                                if ( stop ) {
    165                                    shapeFile.close();
    166                                    if ( geometry ) {
    167                                        rtree.close();
    168                                        new File( fileName + ".rti" ).delete();
    169                                    }
    170                                    for ( int j = 0; j < index.length; j++ ) {
    171                                        if ( index[j] != null ) {
    172                                            index[j].close();
    173                                            new File( fileName + "$" + properties[j] + ".ndx" ).delete();
    174                                        }
    175                                    }
    176                                    System.exit( 3 );
    177                                }
    178                            }
    179                        }
    180                    }
    181
    182                    try {
    183                        if ( geometry ) {
    184                            rtree.close();
    185                        }
    186                        shapeFile.close();
    187
    188                        for ( int i = 0; i < index.length; i++ )
    189                            if ( index[i] != null )
    190                                index[i].close();
    191                    } catch ( Exception e ) {
    192                        e.printStackTrace();
    193                        JOptionPane.showMessageDialog( frame, e );
    194                        System.exit( 1 );
    195                    }
    196
    197                    if ( !geometryCheckBox.isSelected() && hasGeometry ) {
    198                        new File( fileName + ".rti" ).delete();
    199                    }
    200
    201                    for ( int i = 0; i < index.length; i++ ) {
    202                        if ( !checkboxes[i].isSelected() && hasIndex[i] ) {
    203                            new File( fileName + "$" + properties[i] + ".ndx" ).delete();
    204                        }
    205                    }
    206
    207                    System.exit( 0 );
    208                } catch ( Exception ex ) {
    209                    ex.printStackTrace();
    210                    JOptionPane.showMessageDialog( frame, ex );
    211                    System.exit( 1 );
    212                }
    213            }
    214
    215            public void stopIndexing() {
    216                synchronized ( this ) {
    217                    stop = true;
    218                }
    219            }
    220        }
    221
    222        public IndexFrame( File file ) throws Exception {
    223            super( "Deegree" );
    224            fileName = file.getPath();
    225            fileName = fileName.substring( 0, fileName.length() - 4 );
    226            shapeFile = new ShapeFile( fileName );
    227            properties = shapeFile.getProperties();
    228
    229            Container container = getContentPane();
    230            container.setLayout( new BorderLayout() );
    231            int size = properties.length;
    232            JPanel panel = new JPanel( new GridLayout( 10 + 2, 2 ) );
    233
    234            panel.add( new JLabel( "Attributes" ) );
    235            panel.add( new JLabel( "Unique" ) );
    236
    237            hasGeometry = shapeFile.hasRTreeIndex();
    238            hasIndex = new boolean[size];
    239            for ( int i = 0; i < size; i++ )
    240                hasIndex[i] = shapeFile.hasDBaseIndex( properties[i] );
    241
    242            checkboxes = new JCheckBox[size];
    243            uniqueBoxes = new JCheckBox[size];
    244
    245            geometryCheckBox = new JCheckBox( "Geometry" );
    246            geometryCheckBox.setSelected( hasGeometry );
    247
    248            panel.add( geometryCheckBox );
    249            panel.add( new JCheckBox( "" ) ).setEnabled( false );
    250
    251            for ( int i = 0; i < checkboxes.length; i++ ) {
    252                checkboxes[i] = new JCheckBox( properties[i] );
    253                checkboxes[i].setSelected( hasIndex[i] );
    254                if ( i < 10 ) {
    255                    panel.add( checkboxes[i] );
    256
    257                    uniqueBoxes[i] = (JCheckBox) panel.add( new JCheckBox( "" ) );
    258                    if ( hasIndex[i] ) {
    259                        uniqueBoxes[i].setSelected( shapeFile.isUnique( properties[i] ) );
    260                    } else {
    261                        checkboxes[i].addChangeListener( this );
    262                    }
    263                    uniqueBoxes[i].setEnabled( false );
    264                }
    265            }
    266
    267            JButton start = new JButton( "Start indexing" );
    268            start.addActionListener( this );
    269            container.add( "South", start );
    270            container.add( "Center", panel );
    271
    272            setBounds( 100, 100, 100, 100 );
    273            pack();
    274
    275            setResizable( true );
    276        }
    277
    278        /**
    279         * @param e
    280         */
    281        public void actionPerformed( ActionEvent e ) {
    282            if ( e.getSource() == cancel ) {
    283                if ( indexing != null ) {
    284                    if ( JOptionPane.showConfirmDialog( this, "Cancel indexing?", "Question", JOptionPane.YES_NO_OPTION ) == JOptionPane.YES_OPTION )
    285                        indexing.stopIndexing();
    286                }
    287            } else {
    288                if ( hasGeometry != geometryCheckBox.isSelected() ) {
    289                    indexing = new Indexing( this );
    290                    indexing.start();
    291                    return;
    292                }
    293
    294                for ( int i = 0; i < hasIndex.length; i++ ) {
    295                    if ( hasIndex[i] != checkboxes[i].isSelected() ) {
    296                        indexing = new Indexing( this );
    297                        indexing.start();
    298                        return;
    299                    }
    300                }
    301
    302                JOptionPane.showMessageDialog( this, "Nothing changed" );
    303            }
    304        }
    305
    306        /**
    307         * @param e
    308         */
    309        public void stateChanged( ChangeEvent e ) {
    310            JCheckBox checkbox = (JCheckBox) e.getSource();
    311
    312            for ( int i = 0; i < checkboxes.length; i++ ) {
    313                if ( checkbox == checkboxes[i] ) {
    314                    uniqueBoxes[i].setEnabled( checkbox.isSelected() );
    315                    if ( !checkbox.isSelected() ) {
    316                        uniqueBoxes[i].setSelected( false );
    317                    }
    318                    break;
    319                }
    320            }
    321        }
    322    }