Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / VectorialEditableAdapter.java @ 4193

History | View | Annotate | Download (25.5 KB)

1
/*
2
 * Created on 12-ene-2006 by fjp
3
 *
4
 * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
5
 *
6
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
7
 *
8
 * This program is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU General Public License
10
 * as published by the Free Software Foundation; either version 2
11
 * of the License, or (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, write to the Free Software
20
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21
 *
22
 * For more information, contact:
23
 *
24
 *  Generalitat Valenciana
25
 *   Conselleria d'Infraestructures i Transport
26
 *   Av. Blasco Ib??ez, 50
27
 *   46010 VALENCIA
28
 *   SPAIN
29
 *
30
 *      +34 963862235
31
 *   gvsig@gva.es
32
 *      www.gvsig.gva.es
33
 *
34
 *    or
35
 *
36
 *   IVER T.I. S.A
37
 *   Salamanca 50
38
 *   46005 Valencia
39
 *   Spain
40
 *
41
 *   +34 963163400
42
 *   dac@iver.es
43
 */
44
/* CVS MESSAGES:
45
 *
46
 * $Id: VectorialEditableAdapter.java 4193 2006-02-24 07:57:58Z fjp $
47
 * $Log$
48
 * Revision 1.33  2006-02-24 07:57:58  fjp
49
 * FUNCIONA!!! (Creo)
50
 *
51
 * Revision 1.32  2006/02/23 17:55:45  fjp
52
 * Preparando para poder editar con el EditionManager
53
 *
54
 * Revision 1.31  2006/02/21 16:44:08  fjp
55
 * Preparando para poder editar con el EditionManager
56
 *
57
 * Revision 1.30  2006/02/20 18:14:59  fjp
58
 * Preparando para poder editar con el EditionManager
59
 *
60
 * Revision 1.29  2006/02/20 10:32:54  fjp
61
 * Preparando para poder editar con el EditionManager
62
 *
63
 * Revision 1.28  2006/02/17 13:40:03  fjp
64
 * Preparando para poder editar con el EditionManager
65
 *
66
 * Revision 1.27  2006/02/17 10:41:14  fjp
67
 * Evento de edici?n lanzado cuando una capa se pone en edici?n
68
 *
69
 * Revision 1.26  2006/02/17 08:21:19  fjp
70
 * *** empty log message ***
71
 *
72
 * Revision 1.25  2006/02/16 09:38:10  fjp
73
 * Preparando compatibilidad para bases de datos (y de paso, acelerando :-)
74
 *
75
 * Revision 1.24  2006/02/16 09:06:28  caballero
76
 * commandStack
77
 *
78
 * Revision 1.23  2006/02/15 18:16:02  fjp
79
 * POR TERMINAR
80
 *
81
 * Revision 1.22  2006/02/13 18:18:31  fjp
82
 * POR TERMINAR
83
 *
84
 * Revision 1.21  2006/02/10 13:28:23  caballero
85
 * poder cambiar la selecci?n
86
 *
87
 * Revision 1.20  2006/02/09 13:11:54  caballero
88
 * *** empty log message ***
89
 *
90
 * Revision 1.19  2006/02/08 16:45:29  caballero
91
 * elimnar c?dio no usado
92
 *
93
 * Revision 1.18  2006/02/08 15:18:45  caballero
94
 * control de las rows eliminadas
95
 *
96
 * Revision 1.17  2006/02/07 10:18:44  caballero
97
 * Con BoundedShape
98
 *
99
 * Revision 1.16  2006/02/06 12:01:41  caballero
100
 * driver del ova
101
 *
102
 * Revision 1.15  2006/02/03 14:09:32  fjp
103
 * Preparando edici?n
104
 *
105
 * Revision 1.14  2006/02/03 12:16:33  fjp
106
 * Preparando edici?n
107
 *
108
 * Revision 1.13  2006/02/03 11:54:12  caballero
109
 * tablas con vectorialEditableAdapter en edici?n
110
 *
111
 * Revision 1.11  2006/01/31 08:10:05  caballero
112
 * cambio de feature a row
113
 *
114
 * Revision 1.10  2006/01/30 08:18:14  caballero
115
 * m?todos para deshacer y rehacer
116
 *
117
 * Revision 1.9  2006/01/23 17:30:28  caballero
118
 * coger los datos del ova
119
 *
120
 * Revision 1.8  2006/01/23 16:16:16  caballero
121
 * getRowIndex
122
 *
123
 * Revision 1.7  2006/01/20 08:37:10  fjp
124
 * Preparando la edici?n
125
 *
126
 * Revision 1.6  2006/01/19 12:48:20  caballero
127
 * poder modificar su vectorial Adapter
128
 *
129
 * Revision 1.5  2006/01/19 09:28:11  fjp
130
 * Preparando la edici?n
131
 *
132
 * Revision 1.4  2006/01/17 10:24:02  fjp
133
 * Preparando edici?n
134
 *
135
 * Revision 1.3  2006/01/16 12:47:38  fjp
136
 * Preparando edici?n
137
 *
138
 * Revision 1.2  2006/01/16 11:23:00  fjp
139
 * Preparando edici?n
140
 *
141
 * Revision 1.1  2006/01/12 13:39:14  fjp
142
 * preaparar edicion
143
 *
144
 *
145
 */
146
package com.iver.cit.gvsig.fmap.edition;
147

    
148
import java.awt.geom.Rectangle2D;
149
import java.io.IOException;
150
import java.util.List;
151

    
152
import com.hardcode.driverManager.DriverLoadException;
153
import com.hardcode.gdbms.engine.data.DataSource;
154
import com.hardcode.gdbms.engine.values.Value;
155
import com.iver.cit.gvsig.fmap.DriverException;
156
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
157
import com.iver.cit.gvsig.fmap.core.FShape;
158
import com.iver.cit.gvsig.fmap.core.IFeature;
159
import com.iver.cit.gvsig.fmap.core.IGeometry;
160
import com.iver.cit.gvsig.fmap.core.IRow;
161
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
162
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
163
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
164
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
165
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
166
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
167
import com.iver.cit.gvsig.fmap.layers.FBitSet;
168
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
169
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
170
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter;
171
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
172
import com.vividsolutions.jts.geom.Envelope;
173
import com.vividsolutions.jts.index.quadtree.Quadtree;
174

    
175
/**
176
 * @author fjp
177
 *
178
 */
179
public class VectorialEditableAdapter extends EditableAdapter implements ReadableVectorial, BoundedShapes {
180
        protected VectorialAdapter ova;
181
        //private VectorialDriver driver;
182
        protected Quadtree index;
183
        
184
        
185
        /* private class MyFeatureIterator implements IFeatureIterator
186
        {
187
                int numReg = 0;
188
                Rectangle2D rect;
189
                String epsg;
190
                IFeatureIterator origFeatIt;
191
                boolean bHasNext = true;
192
                
193
                public MyFeatureIterator(Rectangle2D r, String strEPSG) throws DriverException
194
                {
195
                        rect = r;
196
                        epsg = strEPSG;
197
                        origFeatIt = ova.getFeatureIterator(r, epsg);
198
                }
199
                public boolean hasNext() throws DriverException {
200
                                return bHasNext;
201
                }
202

203
                public IFeature next() throws DriverException {
204
                        IFeature aux = origFeatIt.next();
205
                        return null;
206
                }
207

208
                public void closeIterator() throws DriverException {
209
                        
210
                }
211
                
212
        } */
213
        
214
        public VectorialEditableAdapter(){
215
                super();
216
        }
217
        public void setOriginalVectorialAdapter(ReadableVectorial rv){
218
                ova=(VectorialAdapter)rv;
219
                try {
220
                        setOriginalDataSource(rv.getRecordset());
221
                } catch (DriverLoadException e) {
222
                        // TODO Auto-generated catch block
223
                        e.printStackTrace();
224
                }
225
        }
226
        /*
227
         * (non-Javadoc)
228
         *
229
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#start()
230
         */
231
        public void start() throws DriverIOException {
232
                ova.start();
233
        }
234

    
235
        /*
236
         * (non-Javadoc)
237
         *
238
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#stop()
239
         */
240
        public void stop() throws DriverIOException {
241
                ova.stop();
242
        }
243

    
244
        /*
245
         * (non-Javadoc)
246
         *
247
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
248
         */
249
        public IGeometry getShape(int rowIndex) throws DriverIOException {
250
                // Si no est? en el fichero de expansi?n
251
                int calculatedIndex=getCalculatedIndex(rowIndex);
252
                Integer integer = new Integer(calculatedIndex);
253
                if (!relations.containsKey(integer)) {
254
                        // Si ha sido eliminada
255
                        /*if (delRows.get(integer.intValue())) {
256
                                return null;
257
                        } else {*/
258
                                return ova.getShape(calculatedIndex);
259
                        //}
260
                } else {
261
                        int num = ((Integer) relations.get(integer)).intValue();
262
                        DefaultRowEdited feat;
263
                        try {
264
                                feat = (DefaultRowEdited) expansionFile.getRow(num);
265
                                return ((IFeature)feat.getLinkedRow()).getGeometry().cloneGeometry();//getGeometry();
266
                        } catch (IOException e) {
267
                                e.printStackTrace();
268
                                throw new DriverIOException(e);
269
                        }
270
                }
271

    
272
        }
273

    
274
        /*
275
         * (non-Javadoc)
276
         *
277
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
278
         */
279
        public int getShapeType() throws DriverIOException {
280
                return ova.getShapeType();
281
        }
282
        public VectorialAdapter getOriginalAdapter(){
283
                return ova;
284
        }
285
        public VectorialDriver getDriver() {
286
                return ova.getDriver();
287
        }
288
        public void setDriver(VectorialDriver driver) {
289
                this.ova.setDriver(driver);
290
        }
291
        public DriverAttributes getDriverAttributes(){
292
                return ova.getDriverAttributes();
293
        }
294

    
295
         /**
296
     * DOCUMENT ME!
297
     *
298
     * @throws EditionException DOCUMENT ME!
299
     */
300
    public void startEdition() throws EditionException {
301
        super.startEdition();
302

    
303
        try {
304
            expansionFile.open();
305

    
306
            // TODO: Si la capa dispone de un ?ndice espacial, hacer
307
            // algo aqu? para que se use ese ?ndice espacial.
308
            index = new Quadtree();
309

    
310
            for (int i = 0; i < ova.getShapeCount(); i++) {
311
                IGeometry g=null;
312
                                try {
313
                                        g = ((DefaultFeature) ova.getFeature(i)).getGeometry();
314
                                } catch (DriverException e1) {
315
                                        // TODO Auto-generated catch block
316
                                        e1.printStackTrace();
317
                                }
318

    
319
                if (g == null) {
320
                    continue;
321
                }
322

    
323
                Rectangle2D r = g.getBounds2D();
324
                Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(),
325
                        r.getY(), r.getY() + r.getHeight());
326
                index.insert(e, new Integer(i));
327
            }
328
        } catch (DriverIOException e) {
329
            throw new EditionException(e);
330
        } catch (IOException e) {
331
            throw new EditionException(e);
332
        }
333

    
334
        System.err.println("Se han metido en el ?ndice " +
335
            index.queryAll().size() + " geometr?as");
336
    }
337

    
338
    /* (non-Javadoc)
339
     * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
340
     */
341
    public IRowEdited getRow(int index) throws DriverIOException, IOException {
342
            int calculatedIndex=getCalculatedIndex(index);
343
            Integer integer = new Integer(calculatedIndex);
344
        //Si no est? en el fichero de expansi?n
345
            DefaultRowEdited edRow=null;            
346
        if (!relations.containsKey(integer)) {
347
                        try {
348
                                edRow = new DefaultRowEdited(ova.getFeature(calculatedIndex),
349
                                        DefaultRowEdited.STATUS_ORIGINAL, index);
350
                                System.out.println("Piden la feature con ID= " + index);
351
                                // Exception e = new Exception();
352
                                // e.printStackTrace();
353
                        } catch (DriverException e) {
354
                                // TODO Auto-generated catch block
355
                                e.printStackTrace();
356
                        }
357

    
358
            return edRow;
359
        } else {
360
            int num = ((Integer) relations.get(integer)).intValue();
361
            IRowEdited aux = expansionFile.getRow(num);
362
            edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux.getStatus(), index);
363
            return edRow;
364
        }
365
    } 
366
    /**
367
     * Elimina una geometria. Si es una geometr?a original de la capa en
368
     * edici?n se marca como eliminada (haya sido modificada o no). Si es una
369
     * geometr?a a?adida posteriormente se invalida en el fichero de
370
     * expansi?n, para que una futura compactaci?n termine con ella.
371
     *
372
     * @param index ?ndice de la geometr?a.
373
     *
374
     * @throws DriverIOException
375
     * @throws IOException
376
     */
377
    public IRow doRemoveRow(int index) throws DriverIOException, IOException {
378
        //Llega el calculatedIndex
379
            Integer integer = new Integer(index);
380

    
381
        IFeature feat = null;
382
        delRows.set(index, true);
383
        //Si la geometr?a no ha sido modificada
384
        if (!relations.containsKey(integer)) {
385

    
386
            try {
387
                                feat = (DefaultFeature) (ova.getFeature(index));
388
                        } catch (DriverException e) {
389
                                // TODO Auto-generated catch block
390
                                e.printStackTrace();
391
                        }
392
       } else {
393
                        int num = ((Integer) relations.get(integer)).intValue();
394
                        feat = (IFeature) expansionFile.getRow(num).getLinkedRow();
395
                        //expansionFile.invalidateRow(num);
396
                }
397
        System.err.println("Elimina una Row en la posici?n: " + index);
398
        //Se actualiza el ?ndice
399
        if (feat != null) {
400
            Rectangle2D r = feat.getGeometry().getBounds2D();
401
            boolean borrado=this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(),
402
                    r.getY(), r.getY() + r.getHeight()), new Integer(index));
403
            System.out.println("Est? borrado : "+ borrado);
404
            System.out.println("Index.lenght : "+ this.index.size());
405

    
406
        }
407
        setSelection(new FBitSet());
408
        return feat;
409
    }
410
    /**
411
     * Si se intenta modificar una geometr?a original de la capa en edici?n se
412
     * a?ade al fichero de expansi?n y se registra la posici?n en la que se
413
     * a?adi?. Si se intenta modificar una geometria que se encuentra en el
414
     * fichero de expansi?n (por ser nueva o original pero modificada) se
415
     * invoca el m?todo modifyGeometry y se actualiza el ?ndice de la
416
     * geometria en el fichero.
417
     *
418
     * @param calculatedIndex DOCUMENT ME!
419
     * @param feat DOCUMENT ME!
420
     *
421
     * @return position inside ExpansionFile
422
     *
423
     * @throws IOException
424
     * @throws DriverIOException
425
     */
426
    public int doModifyRow(int calculatedIndex, IRow feat)
427
        throws IOException, DriverIOException {
428
        int posAnteriorInExpansionFile = -1;
429
        Integer integer = new Integer(calculatedIndex);
430

    
431
        IFeature featAnt = null;
432
        System.err.println("Modifica una Row en la posici?n: " + calculatedIndex);
433
        //Si la geometr?a no ha sido modificada
434
        if (!relations.containsKey(integer)) {
435
                int newPosition = expansionFile.addRow(feat);
436
            relations.put(integer, new Integer(newPosition));
437

    
438
            //Se actualiza el ?ndice espacial
439
            try {
440
                                featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
441
                        } catch (DriverException e) {
442
                                // TODO Auto-generated catch block
443
                                e.printStackTrace();
444
                        }
445

    
446
            Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
447
            Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
448
            this.index.remove(new Envelope(rAnt.getX(),
449
                    rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
450
                    rAnt.getY() + rAnt.getHeight()), new Integer(calculatedIndex));
451
            this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
452
                    r.getY(), r.getY() + r.getHeight()), new Integer(calculatedIndex));
453
        } else {
454
            //Obtenemos el ?ndice en el fichero de expansi?n
455
            int num = ((Integer) relations.get(integer)).intValue();
456
            posAnteriorInExpansionFile = num;
457

    
458
            //Obtenemos la geometr?a para actualiza el ?ndice espacialposteriormente
459
            featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
460

    
461
            /*
462
             * Se modifica la geometr?a y nos guardamos el ?ndice dentro del fichero
463
             * de expansi?n en el que se encuentra la geometr?a modificada
464
             */
465
            num = expansionFile.modifyRow(num, feat);
466

    
467
            /*
468
             * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el fichero
469
             * de expansi?n.
470
             */
471
            relations.put(integer, new Integer(num));
472

    
473
            //Se modifica el ?ndice espacial
474
            Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
475
            Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
476
            this.index.remove(new Envelope(rAnt.getX(),
477
                    rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
478
                    rAnt.getY() + rAnt.getHeight()), new Integer(calculatedIndex));
479
            this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
480
                    r.getY(), r.getY() + r.getHeight()), new Integer(calculatedIndex));
481
        }
482

    
483
        return posAnteriorInExpansionFile;
484
    }
485
    /**
486
     * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
487
     * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
488
     * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
489
     * expansi?n antes de ser modificada y se pone el puntero de escritura del
490
     * expansion file a justo despues de la penultima geometr?a
491
     *
492
     * @param geometryIndex ?ndice de la geometr?a que se quiere deshacer su
493
     *        modificaci?n
494
     * @param previousExpansionFileIndex ?ndice que ten?a antes la geometr?a en
495
     *        el expansionFile. Si vale -1 quiere decir que es una
496
     *        modificaci?n de una geometr?a original y por tanto no hay que
497
     *        actualizar el mapa de indices sino eliminar su entrada.
498
     *
499
     * @throws IOException
500
     * @throws DriverIOException
501
     */
502
    public void undoModifyRow(int geometryIndex, int previousExpansionFileIndex)
503
        throws IOException, DriverIOException {
504
       //Llega el CalculatedIndex
505
            /*
506
         * Si la acci?n de modificar se realiz? sobre una geometr?a original
507
         */
508
        if (previousExpansionFileIndex == -1) {
509
            //Se obtiene la geometr?a para actualizar el ?ndice
510
            IGeometry g = ((DefaultFeature) getRow(geometryIndex).getLinkedRow()).getGeometry();
511
            Rectangle2D r = g.getBounds2D();
512

    
513
            //Se elimina de las relaciones y del fichero de expansi?n
514
            relations.remove(new Integer(geometryIndex));
515
            expansionFile.deleteLastRow();
516

    
517
            //Se actualizan los ?ndices
518
            IGeometry gAnt = ((DefaultFeature) getRow(geometryIndex)
519
                                                   .getLinkedRow()).getGeometry();
520
            Rectangle2D rAnt = gAnt.getBounds2D();
521
            this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(),
522
                    r.getY(), r.getY() + r.getHeight()),
523
                new Integer(geometryIndex));
524
            this.index.insert(new Envelope(rAnt.getX(),
525
                    rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
526
                    rAnt.getY() + rAnt.getHeight()), new Integer(geometryIndex));
527
        } else {
528
            //Se obtiene la geometr?a para actualizar el ?ndice
529
            IGeometry g = null;
530
            int inverse = getInversedIndex(geometryIndex);
531
            g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
532
            System.out.println("Actual: " + g.toString());
533

    
534
            Rectangle2D r = g.getBounds2D();
535
            this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(),
536
                    r.getY(), r.getY() + r.getHeight()),
537
                new Integer(geometryIndex));
538

    
539
            //Se actualiza la relaci?n de ?ndices
540
            //Integer integer = new Integer(geometryIndex);
541
            relations.put(new Integer(geometryIndex),
542
                new Integer(previousExpansionFileIndex));
543

    
544
            //Se recupera la geometr?a
545
            //expansionFile.validateRow(previousExpansionFileIndex);
546

    
547
            //Se actualizan los ?ndices
548
            // g = ((IFeature) (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
549
            // System.out.println("Anterior a la que volvemos : " + g.toString());
550
            g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
551
            r = g.getBounds2D();
552
            this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
553
                    r.getY(), r.getY() + r.getHeight()),
554
                new Integer(geometryIndex));
555
        }
556
    }
557

    
558
    /**
559
     * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
560
     * en la tabla relations.
561
     *
562
     * @param feat geometr?a a guardar.
563
     *
564
     * @return calculatedIndex
565
     *
566
     * @throws DriverIOException
567
     * @throws IOException
568
     */
569
    public int doAddRow(IRow feat) throws DriverIOException, IOException {
570
        int calculatedIndex=super.doAddRow(feat);
571
                // Actualiza el ?ndice espacial
572
        IGeometry g = ((IFeature)feat).getGeometry();
573
        Rectangle2D r = g.getBounds2D();
574
        index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
575
                r.getY() + r.getHeight()), new Integer(calculatedIndex));
576

    
577
        return calculatedIndex;
578
    }
579
    /**
580
     * Se desmarca como invalidada en el fichero de expansion o como eliminada
581
     * en el fichero original
582
     *
583
     * @param index DOCUMENT ME!
584
     *
585
     * @throws IOException
586
     * @throws DriverIOException
587
     */
588
    public void undoRemoveRow(int index) throws IOException, DriverIOException {
589
       super.undoRemoveRow(index);
590

    
591
        IGeometry g = null;
592
        g = ((IFeature) getRow(index).getLinkedRow()).getGeometry();
593

    
594
        Rectangle2D r = g.getBounds2D();
595
        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
596
                r.getY(), r.getY() + r.getHeight()), new Integer(index));
597
    }
598
    /**
599
     * Se elimina del final del fichero de expansi?n poniendo el puntero de
600
     * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar
601
     * la relaci?n del mapa de relaciones
602
     *
603
     * @param index ?ndice de la geometr?a que se a?adi?
604
     *
605
     * @throws DriverIOException
606
     * @throws IOException
607
     */
608
    public void undoAddRow(int calculatedIndex) throws DriverIOException, IOException {
609
            int inverse = getInversedIndex(calculatedIndex);
610
        IGeometry g = ((IFeature) getRow(inverse).getLinkedRow()).getGeometry();
611
        Rectangle2D r = g.getBounds2D();
612
        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(),
613
                r.getY(), r.getY() + r.getHeight()), new Integer(calculatedIndex));
614

    
615
        super.undoAddRow(calculatedIndex);
616
        setSelection(new FBitSet());
617
    }
618
    /**
619
     * Obtiene las geometr?as que se encuentran en el rect?ngulo que se pasa
620
     * como par?metro haciendo uso del ?ndice espacial
621
     *
622
     * @param r Rect?ngulo indicando la porci?n del espacio para el cual se
623
     *        quiere saber los ?ndices de las geometr?as que se encuentran
624
     *        dentro de ?l
625
     *
626
     * @return Array de ?ndices para su uso con getGeometry, removeGeometry,
627
     *         ...
628
     */
629
    public int[] getRowsIndexes_OL(Rectangle2D r) {
630
        Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
631
                r.getY() + r.getHeight());
632
        List l = index.query(e);
633
        int[] indexes = new int[l.size()];
634

    
635
        for (int index = 0; index < l.size(); index++) {
636
            Integer i = (Integer) l.get(index);
637
            indexes[index] = getInversedIndex(i.intValue());
638
        }
639

    
640
        return indexes;
641
    }
642
    /**
643
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
644
         */
645
        public int getShapeCount() throws DriverIOException {
646
                try {
647
                        return getRowCount();
648
                }  catch (IOException e) {
649
                        throw new DriverIOException(e);
650
                }
651
        }
652

    
653
        /**
654
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
655
         */
656
        public Rectangle2D getFullExtent() throws DriverIOException {
657
                // TODO: Recalcularlo cada vez que se a?ade un addRow
658
                return ova.getFullExtent();
659
        }
660
    /**
661
     * En la implementaci?n por defecto podemos hacer que cada
662
     * feature tenga ID = numero de registro.
663
     * En el DBAdapter podr?amos "overrride" este m?todo y poner
664
     * como ID de la Feature el campo ?nico escogido en
665
     * la base de datos.
666
     * @param numReg
667
     * @return
668
     * @throws DriverException
669
     */
670
    public IFeature getFeature(int numReg) throws DriverException
671
    {
672
        IGeometry geom;
673
        IFeature feat = null;
674
        try {
675
            geom = getShape(numReg);
676
            DataSource rs = getRecordset();
677
            Value[] regAtt = new Value[rs.getFieldCount()];
678
            for (int fieldId=0; fieldId < rs.getFieldCount(); fieldId++ )
679
            {
680
                regAtt[fieldId] =  rs.getFieldValue(numReg, fieldId);
681
            }
682

    
683
            feat = new DefaultFeature(geom, regAtt, numReg + "");
684
        } catch (DriverIOException e) {
685
            throw new DriverException(e);
686
        } catch (DriverLoadException e) {
687
            throw new DriverException(e);
688
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
689
            throw new DriverException(e);
690
        }
691
        return feat;
692
    }
693
        public void stopEdition(IWriter writer) throws EditionException {
694
                super.stopEdition(writer);
695
                try {
696
                        ova.getDriver().reLoad();
697
                } catch (IOException e) {
698
                        e.printStackTrace();
699
                        throw new EditionException(e);
700
                }
701
        }
702
        public Rectangle2D getShapeBounds(int index) throws IOException {
703
                //Solo se utiliza cuando el driver es BoundedShapes
704
//                 Si no est? en el fichero de expansi?n
705
                Integer integer = new Integer((int) index);
706
                if (!relations.containsKey(integer)) {
707
                        if (ova.getDriver() instanceof BoundedShapes){
708
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
709
                                return bs.getShapeBounds(index);
710
                        }else{
711
                                return ova.getDriver().getShape(index).getBounds2D();
712
                        }
713

    
714
                } else {
715
                        int num = ((Integer) relations.get(integer)).intValue();
716
                        DefaultRowEdited feat;
717
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
718
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
719
                                return null;
720
                        IGeometry geom = ((IFeature)feat.getLinkedRow()).getGeometry();
721
                        return geom.getBounds2D();//getGeometry();
722
                }
723

    
724
        }
725
        public int getShapeType(int index) {
726
                try {
727
                        return ova.getShapeType();
728
                } catch (DriverIOException e) {
729
                        // TODO Auto-generated catch block
730
                        e.printStackTrace();
731
                }
732
                return FShape.MULTI;
733
        }
734
        /**
735
         * Usar solo cuando est?s seguro de que puedes
736
         * gastar memoria. Nosotros lo usamos para las 
737
         * b?squedas por ?ndice espacial con el handle.
738
         * La idea es usarlo una vez, guardar las geometr?as que 
739
         * necesitas en ese extent y trabajar con ellas
740
         * hasta el siguiente cambio de extent.
741
         * @param r
742
         * @param strEPSG
743
         * @return
744
         * @throws DriverException
745
         */
746
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG) throws DriverException {
747
                // En esta clase suponemos random access.
748
                // Luego tendremos otra clase que sea VectorialEditableDBAdapter
749
                // que reescribir? este m?todo.
750
        Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
751
        List l = index.query(e);
752
        IRowEdited[] feats = new IRowEdited[l.size()];
753
        try {
754
                for (int index = 0; index < l.size(); index++) {
755
                    Integer i = (Integer) l.get(index);
756
                    int inverse = getInversedIndex(i.intValue());
757
                                feats[index] = (IRowEdited) getRow(inverse);
758
                }
759
                } catch (DriverIOException e1) {
760
                        throw new DriverException(e1);
761
                } catch (IOException e1) {
762
                        throw new DriverException(e1);
763
                }
764
                
765
                return feats;
766
        }
767
        
768

    
769
}