001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_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() 110 && !hasGeometry ) { 111 geometry = true; 112 rtree = new RTree( 2, 11, fileName + ".rti" ); 113 } 114 115 boolean indexes = false; 116 for (int i = 0; i < index.length; i++) { 117 if ( checkboxes[i].isSelected() && !hasIndex[i] ) { 118 index[i] = DBaseIndex.createIndex( fileName 119 + "$" + properties[i], properties[i], lengths[i], uniqueBoxes[i] 120 .isSelected(), ( dataTypes[i].equalsIgnoreCase( "N" ) 121 || dataTypes[i].equalsIgnoreCase( "I" ) || dataTypes[i] 122 .equalsIgnoreCase( "F" ) ) ); 123 indexes = true; 124 } else 125 index[i] = null; 126 } 127 128 if ( geometry || indexes ) { 129 for (int i = 1; i < features + 1; i++) { 130 Feature feature = shapeFile.getFeatureByRecNo( i ); 131 132 if ( geometry ) { 133 Geometry[] geometries = feature.getGeometryPropertyValues(); 134 if ( geometries.length == 0 ) { 135 LOG.logInfo( "no geometries at recno" + i ); 136 continue; 137 } 138 Envelope envelope = null; 139 // TODO: deal with more than one geometry; handle geometry=null (allowed 140 // in shapefile) 141 envelope = ( feature.getDefaultGeometryPropertyValue() ).getEnvelope(); 142 if ( envelope == null ) { // assume a Point-geometry 143 Point pnt = (Point) geometries[0]; 144 envelope = GeometryFactory.createEnvelope( pnt.getX(), pnt.getY(), 145 pnt.getX(), pnt.getY(), null ); 146 } 147 HyperBoundingBox box = new HyperBoundingBox( new HyperPoint( envelope 148 .getMin().getAsArray() ), new HyperPoint( envelope.getMax() 149 .getAsArray() ) ); 150 rtree.insert( new Integer( i ), box ); 151 } 152 153 for (int j = 0; j < index.length; j++) { 154 if ( index[j] != null ) { 155 QualifiedName qn = new QualifiedName( properties[j] ); 156 index[j].addKey( (Comparable) feature.getDefaultProperty( qn ), i ); 157 } 158 } 159 160 progressBar.setValue( i ); 161 162 synchronized (this) { 163 if ( stop ) { 164 shapeFile.close(); 165 if ( geometry ) { 166 rtree.close(); 167 new File( fileName 168 + ".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 174 + "$" + properties[j] + ".ndx" ).delete(); 175 } 176 } 177 System.exit( 3 ); 178 } 179 } 180 } 181 } 182 183 try { 184 if ( geometry ) { 185 rtree.close(); 186 } 187 shapeFile.close(); 188 189 for (int i = 0; i < index.length; i++) 190 if ( index[i] != null ) 191 index[i].close(); 192 } catch (Exception e) { 193 e.printStackTrace(); 194 JOptionPane.showMessageDialog( frame, e ); 195 System.exit( 1 ); 196 } 197 198 if ( !geometryCheckBox.isSelected() && hasGeometry ) { 199 new File( fileName + ".rti" ).delete(); 200 } 201 202 for (int i = 0; i < index.length; i++) { 203 if ( !checkboxes[i].isSelected() && hasIndex[i] ) { 204 new File( fileName + "$" + properties[i] + ".ndx" ).delete(); 205 } 206 } 207 208 System.exit( 0 ); 209 } catch (Exception ex) { 210 ex.printStackTrace(); 211 JOptionPane.showMessageDialog( frame, ex ); 212 System.exit( 1 ); 213 } 214 } 215 216 public void stopIndexing() { 217 synchronized (this) { 218 stop = true; 219 } 220 } 221 } 222 223 public IndexFrame( File file ) 224 throws Exception { 225 super( "Deegree" ); 226 fileName = file.getPath(); 227 fileName = fileName.substring( 0, fileName.length() - 4 ); 228 shapeFile = new ShapeFile( fileName ); 229 properties = shapeFile.getProperties(); 230 231 Container container = getContentPane(); 232 container.setLayout( new BorderLayout() ); 233 int size = properties.length; 234 JPanel panel = new JPanel( new GridLayout( 10 + 2, 2 ) ); 235 236 237 panel.add( new JLabel( "Attributes" ) ); 238 panel.add( new JLabel( "Unique" ) ); 239 240 hasGeometry = shapeFile.hasRTreeIndex(); 241 hasIndex = new boolean[size]; 242 for (int i = 0; i < size; i++) 243 hasIndex[i] = shapeFile.hasDBaseIndex( properties[i] ); 244 245 checkboxes = new JCheckBox[size]; 246 uniqueBoxes = new JCheckBox[size]; 247 248 geometryCheckBox = new JCheckBox( "Geometry" ); 249 geometryCheckBox.setSelected( hasGeometry ); 250 251 panel.add( geometryCheckBox ); 252 panel.add( new JCheckBox( "" ) ).setEnabled( false ); 253 254 for (int i = 0; i < checkboxes.length; i++) { 255 checkboxes[i] = new JCheckBox( properties[i] ); 256 checkboxes[i].setSelected( hasIndex[i] ); 257 if ( i < 10 ) { 258 panel.add( checkboxes[i] ); 259 260 uniqueBoxes[i] = (JCheckBox) panel.add( new JCheckBox( "" ) ); 261 if ( hasIndex[i] ) { 262 uniqueBoxes[i].setSelected( shapeFile.isUnique( properties[i] ) ); 263 } else { 264 checkboxes[i].addChangeListener( this ); 265 } 266 uniqueBoxes[i].setEnabled( false ); 267 } 268 } 269 270 JButton start = new JButton( "Start indexing" ); 271 start.addActionListener( this ); 272 container.add( "South", start ); 273 container.add( "Center", panel ); 274 275 pack(); 276 setResizable( true ); 277 } 278 279 /** 280 * @param e 281 */ 282 public void actionPerformed( ActionEvent e ) { 283 if ( e.getSource() == cancel ) { 284 if ( indexing != null ) { 285 if ( JOptionPane.showConfirmDialog( this, "Cancel indexing?", "Question", 286 JOptionPane.YES_NO_OPTION ) == JOptionPane.YES_OPTION ) 287 indexing.stopIndexing(); 288 } 289 } else { 290 if ( hasGeometry != geometryCheckBox.isSelected() ) { 291 indexing = new Indexing( this ); 292 indexing.start(); 293 return; 294 } 295 296 for (int i = 0; i < hasIndex.length; i++) { 297 if ( hasIndex[i] != checkboxes[i].isSelected() ) { 298 indexing = new Indexing( this ); 299 indexing.start(); 300 return; 301 } 302 } 303 304 JOptionPane.showMessageDialog( this, "Nothing changed" ); 305 } 306 } 307 308 /** 309 * @param e 310 */ 311 public void stateChanged( ChangeEvent e ) { 312 JCheckBox checkbox = (JCheckBox) e.getSource(); 313 314 for (int i = 0; i < checkboxes.length; i++) { 315 if ( checkbox == checkboxes[i] ) { 316 uniqueBoxes[i].setEnabled( checkbox.isSelected() ); 317 if ( !checkbox.isSelected() ) { 318 uniqueBoxes[i].setSelected( false ); 319 } 320 break; 321 } 322 } 323 } 324 }