Statistics
| Revision:

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

History | View | Annotate | Download (25.4 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 4191 2006-02-23 17:55:45Z fjp $
47
 * $Log$
48
 * Revision 1.32  2006-02-23 17:55:45  fjp
49
 * Preparando para poder editar con el EditionManager
50
 *
51
 * Revision 1.31  2006/02/21 16:44:08  fjp
52
 * Preparando para poder editar con el EditionManager
53
 *
54
 * Revision 1.30  2006/02/20 18:14:59  fjp
55
 * Preparando para poder editar con el EditionManager
56
 *
57
 * Revision 1.29  2006/02/20 10:32:54  fjp
58
 * Preparando para poder editar con el EditionManager
59
 *
60
 * Revision 1.28  2006/02/17 13:40:03  fjp
61
 * Preparando para poder editar con el EditionManager
62
 *
63
 * Revision 1.27  2006/02/17 10:41:14  fjp
64
 * Evento de edici?n lanzado cuando una capa se pone en edici?n
65
 *
66
 * Revision 1.26  2006/02/17 08:21:19  fjp
67
 * *** empty log message ***
68
 *
69
 * Revision 1.25  2006/02/16 09:38:10  fjp
70
 * Preparando compatibilidad para bases de datos (y de paso, acelerando :-)
71
 *
72
 * Revision 1.24  2006/02/16 09:06:28  caballero
73
 * commandStack
74
 *
75
 * Revision 1.23  2006/02/15 18:16:02  fjp
76
 * POR TERMINAR
77
 *
78
 * Revision 1.22  2006/02/13 18:18:31  fjp
79
 * POR TERMINAR
80
 *
81
 * Revision 1.21  2006/02/10 13:28:23  caballero
82
 * poder cambiar la selecci?n
83
 *
84
 * Revision 1.20  2006/02/09 13:11:54  caballero
85
 * *** empty log message ***
86
 *
87
 * Revision 1.19  2006/02/08 16:45:29  caballero
88
 * elimnar c?dio no usado
89
 *
90
 * Revision 1.18  2006/02/08 15:18:45  caballero
91
 * control de las rows eliminadas
92
 *
93
 * Revision 1.17  2006/02/07 10:18:44  caballero
94
 * Con BoundedShape
95
 *
96
 * Revision 1.16  2006/02/06 12:01:41  caballero
97
 * driver del ova
98
 *
99
 * Revision 1.15  2006/02/03 14:09:32  fjp
100
 * Preparando edici?n
101
 *
102
 * Revision 1.14  2006/02/03 12:16:33  fjp
103
 * Preparando edici?n
104
 *
105
 * Revision 1.13  2006/02/03 11:54:12  caballero
106
 * tablas con vectorialEditableAdapter en edici?n
107
 *
108
 * Revision 1.11  2006/01/31 08:10:05  caballero
109
 * cambio de feature a row
110
 *
111
 * Revision 1.10  2006/01/30 08:18:14  caballero
112
 * m?todos para deshacer y rehacer
113
 *
114
 * Revision 1.9  2006/01/23 17:30:28  caballero
115
 * coger los datos del ova
116
 *
117
 * Revision 1.8  2006/01/23 16:16:16  caballero
118
 * getRowIndex
119
 *
120
 * Revision 1.7  2006/01/20 08:37:10  fjp
121
 * Preparando la edici?n
122
 *
123
 * Revision 1.6  2006/01/19 12:48:20  caballero
124
 * poder modificar su vectorial Adapter
125
 *
126
 * Revision 1.5  2006/01/19 09:28:11  fjp
127
 * Preparando la edici?n
128
 *
129
 * Revision 1.4  2006/01/17 10:24:02  fjp
130
 * Preparando edici?n
131
 *
132
 * Revision 1.3  2006/01/16 12:47:38  fjp
133
 * Preparando edici?n
134
 *
135
 * Revision 1.2  2006/01/16 11:23:00  fjp
136
 * Preparando edici?n
137
 *
138
 * Revision 1.1  2006/01/12 13:39:14  fjp
139
 * preaparar edicion
140
 *
141
 *
142
 */
143
package com.iver.cit.gvsig.fmap.edition;
144

    
145
import java.awt.geom.Rectangle2D;
146
import java.io.IOException;
147
import java.util.List;
148

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

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

200
                public IFeature next() throws DriverException {
201
                        IFeature aux = origFeatIt.next();
202
                        return null;
203
                }
204

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

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

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

    
269
        }
270

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

    
292
         /**
293
     * DOCUMENT ME!
294
     *
295
     * @throws EditionException DOCUMENT ME!
296
     */
297
    public void startEdition() throws EditionException {
298
        super.startEdition();
299

    
300
        try {
301
            expansionFile.open();
302

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

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

    
316
                if (g == null) {
317
                    continue;
318
                }
319

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

    
331
        System.err.println("Se han metido en el ?ndice " +
332
            index.queryAll().size() + " geometr?as");
333
    }
334

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

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

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

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

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

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

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

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

    
455
            //Obtenemos la geometr?a para actualiza el ?ndice espacialposteriormente
456
            featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
457

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

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

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

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

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

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

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

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

    
541
            //Se recupera la geometr?a
542
            //expansionFile.validateRow(previousExpansionFileIndex);
543

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

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

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

    
588
        IGeometry g = null;
589
        g = ((IFeature) getRow(index).getLinkedRow()).getGeometry();
590

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

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

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

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

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

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

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

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

    
766
}