001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }