Statistics
| Revision:

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

History | View | Annotate | Download (27.6 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 5223 2006-05-16 16:07:19Z fjp $
47
 * $Log$
48
 * Revision 1.51  2006-05-16 16:07:19  fjp
49
 * snapping. Revisar
50
 *
51
 * Revision 1.50  2006/05/16 07:07:46  caballero
52
 * Modificar la geometr?a desde fuera
53
 *
54
 * Revision 1.49  2006/05/15 10:52:23  caballero
55
 * Saber si se realiza una operaci?n desde la vista o desde la tabla.
56
 *
57
 * Revision 1.48  2006/05/09 15:58:37  caballero
58
 * Para el IGN
59
 *
60
 * Revision 1.47  2006/05/09 10:28:28  caballero
61
 * faltaba controlar undo y redo
62
 *
63
 * Revision 1.46  2006/04/27 06:44:56  caballero
64
 * Soluci?n undo y redo de anotaciones
65
 *
66
 * Revision 1.45  2006/04/18 06:56:55  caballero
67
 * Cambiar VectorialAdapter por ReadableVectorial
68
 *
69
 * Revision 1.44  2006/04/12 17:13:39  fjp
70
 * *** empty log message ***
71
 *
72
 * Revision 1.43  2006/04/11 12:12:29  fjp
73
 * Con edici?n en PostGIS y guardando pseudo-arcos en los shapes.
74
 *
75
 * Revision 1.42  2006/04/11 06:53:20  fjp
76
 * Preparando el driver de escritura PostGIS
77
 *
78
 * Revision 1.41  2006/04/04 11:27:16  fjp
79
 * Consola escuchando bien y selecci?n en tabla sincronizada cuando hay edici?n
80
 *
81
 * Revision 1.40  2006/04/03 11:04:48  caballero
82
 * Posibilidad de a?adir una anotaci?n
83
 *
84
 * Revision 1.39  2006/03/29 06:26:37  caballero
85
 * acelerar con una imagen las herramientas
86
 *
87
 * Revision 1.38  2006/03/23 16:20:52  fjp
88
 * Un fallo un tanto inverosimil con el mapOverview
89
 *
90
 * Revision 1.37  2006/03/23 10:08:11  caballero
91
 * calculo del fullExtent recorriendo todas las geometr?as
92
 *
93
 * Revision 1.36  2006/03/22 11:46:29  caballero
94
 * Editar capa de anotaciones
95
 *
96
 * Revision 1.35  2006/02/28 18:15:22  fjp
97
 * Consola de CAD
98
 *
99
 * Revision 1.34  2006/02/24 11:30:32  fjp
100
 * FUNCIONA!!! (Creo)
101
 *
102
 * Revision 1.33  2006/02/24 07:57:58  fjp
103
 * FUNCIONA!!! (Creo)
104
 *
105
 * Revision 1.32  2006/02/23 17:55:45  fjp
106
 * Preparando para poder editar con el EditionManager
107
 *
108
 * Revision 1.31  2006/02/21 16:44:08  fjp
109
 * Preparando para poder editar con el EditionManager
110
 *
111
 * Revision 1.30  2006/02/20 18:14:59  fjp
112
 * Preparando para poder editar con el EditionManager
113
 *
114
 * Revision 1.29  2006/02/20 10:32:54  fjp
115
 * Preparando para poder editar con el EditionManager
116
 *
117
 * Revision 1.28  2006/02/17 13:40:03  fjp
118
 * Preparando para poder editar con el EditionManager
119
 *
120
 * Revision 1.27  2006/02/17 10:41:14  fjp
121
 * Evento de edici?n lanzado cuando una capa se pone en edici?n
122
 *
123
 * Revision 1.26  2006/02/17 08:21:19  fjp
124
 * *** empty log message ***
125
 *
126
 * Revision 1.25  2006/02/16 09:38:10  fjp
127
 * Preparando compatibilidad para bases de datos (y de paso, acelerando :-)
128
 *
129
 * Revision 1.24  2006/02/16 09:06:28  caballero
130
 * commandStack
131
 *
132
 * Revision 1.23  2006/02/15 18:16:02  fjp
133
 * POR TERMINAR
134
 *
135
 * Revision 1.22  2006/02/13 18:18:31  fjp
136
 * POR TERMINAR
137
 *
138
 * Revision 1.21  2006/02/10 13:28:23  caballero
139
 * poder cambiar la selecci?n
140
 *
141
 * Revision 1.20  2006/02/09 13:11:54  caballero
142
 * *** empty log message ***
143
 *
144
 * Revision 1.19  2006/02/08 16:45:29  caballero
145
 * elimnar c?dio no usado
146
 *
147
 * Revision 1.18  2006/02/08 15:18:45  caballero
148
 * control de las rows eliminadas
149
 *
150
 * Revision 1.17  2006/02/07 10:18:44  caballero
151
 * Con BoundedShape
152
 *
153
 * Revision 1.16  2006/02/06 12:01:41  caballero
154
 * driver del ova
155
 *
156
 * Revision 1.15  2006/02/03 14:09:32  fjp
157
 * Preparando edici?n
158
 *
159
 * Revision 1.14  2006/02/03 12:16:33  fjp
160
 * Preparando edici?n
161
 *
162
 * Revision 1.13  2006/02/03 11:54:12  caballero
163
 * tablas con vectorialEditableAdapter en edici?n
164
 *
165
 * Revision 1.11  2006/01/31 08:10:05  caballero
166
 * cambio de feature a row
167
 *
168
 * Revision 1.10  2006/01/30 08:18:14  caballero
169
 * m?todos para deshacer y rehacer
170
 *
171
 * Revision 1.9  2006/01/23 17:30:28  caballero
172
 * coger los datos del ova
173
 *
174
 * Revision 1.8  2006/01/23 16:16:16  caballero
175
 * getRowIndex
176
 *
177
 * Revision 1.7  2006/01/20 08:37:10  fjp
178
 * Preparando la edici?n
179
 *
180
 * Revision 1.6  2006/01/19 12:48:20  caballero
181
 * poder modificar su vectorial Adapter
182
 *
183
 * Revision 1.5  2006/01/19 09:28:11  fjp
184
 * Preparando la edici?n
185
 *
186
 * Revision 1.4  2006/01/17 10:24:02  fjp
187
 * Preparando edici?n
188
 *
189
 * Revision 1.3  2006/01/16 12:47:38  fjp
190
 * Preparando edici?n
191
 *
192
 * Revision 1.2  2006/01/16 11:23:00  fjp
193
 * Preparando edici?n
194
 *
195
 * Revision 1.1  2006/01/12 13:39:14  fjp
196
 * preaparar edicion
197
 *
198
 *
199
 */
200
package com.iver.cit.gvsig.fmap.edition;
201

    
202
import java.awt.Image;
203
import java.awt.geom.Rectangle2D;
204
import java.awt.image.BufferedImage;
205
import java.io.IOException;
206
import java.util.List;
207

    
208
import com.hardcode.driverManager.DriverLoadException;
209
import com.hardcode.gdbms.engine.data.DataSource;
210
import com.hardcode.gdbms.engine.values.Value;
211
import com.iver.cit.gvsig.fmap.DriverException;
212
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
213
import com.iver.cit.gvsig.fmap.core.FShape;
214
import com.iver.cit.gvsig.fmap.core.IFeature;
215
import com.iver.cit.gvsig.fmap.core.IGeometry;
216
import com.iver.cit.gvsig.fmap.core.IRow;
217
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
218
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
219
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
220
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
221
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
222
import com.iver.cit.gvsig.fmap.layers.FBitSet;
223
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
224
import com.vividsolutions.jts.geom.Envelope;
225
import com.vividsolutions.jts.index.SpatialIndex;
226
import com.vividsolutions.jts.index.quadtree.Quadtree;
227

    
228
/**
229
 * @author fjp
230
 * 
231
 */
232
public class VectorialEditableAdapter extends EditableAdapter implements
233
                ReadableVectorial, BoundedShapes {
234
        protected ReadableVectorial ova;
235

    
236
        protected Quadtree index;
237

    
238
        protected Rectangle2D fullExtent;
239

    
240
        protected Image selectionImage;
241

    
242
        protected BufferedImage handlersImage;
243

    
244
        /*
245
         * private class MyFeatureIterator implements IFeatureIterator { int numReg =
246
         * 0; Rectangle2D rect; String epsg; IFeatureIterator origFeatIt; boolean
247
         * bHasNext = true;
248
         * 
249
         * public MyFeatureIterator(Rectangle2D r, String strEPSG) throws
250
         * DriverException { rect = r; epsg = strEPSG; origFeatIt =
251
         * ova.getFeatureIterator(r, epsg); } public boolean hasNext() throws
252
         * DriverException { return bHasNext; }
253
         * 
254
         * public IFeature next() throws DriverException { IFeature aux =
255
         * origFeatIt.next(); return null; }
256
         * 
257
         * public void closeIterator() throws DriverException {
258
         *  }
259
         *  }
260
         */
261

    
262
        public VectorialEditableAdapter() {
263
                super();
264
        }
265

    
266
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
267
                ova = rv;
268
                try {
269
                        setOriginalDataSource(rv.getRecordset());
270
                } catch (DriverLoadException e) {
271
                        e.printStackTrace();
272
                }
273
        }
274

    
275
        /*
276
         * (non-Javadoc)
277
         * 
278
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#start()
279
         */
280
        public void start() throws DriverIOException {
281
                ova.start();
282
        }
283

    
284
        /*
285
         * (non-Javadoc)
286
         * 
287
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#stop()
288
         */
289
        public void stop() throws DriverIOException {
290
                ova.stop();
291
        }
292

    
293
        /*
294
         * (non-Javadoc)
295
         * 
296
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
297
         */
298
        public IGeometry getShape(int rowIndex) throws DriverIOException {
299
                // Si no est? en el fichero de expansi?n
300
                int calculatedIndex = getCalculatedIndex(rowIndex);
301
                Integer integer = new Integer(calculatedIndex);
302
                if (!relations.containsKey(integer)) {
303
                        // Si ha sido eliminada
304
                        /*
305
                         * if (delRows.get(integer.intValue())) { return null; } else {
306
                         */
307
                        return ova.getShape(calculatedIndex);
308
                        // }
309
                } else {
310
                        int num = ((Integer) relations.get(integer)).intValue();
311
                        DefaultRowEdited feat;
312
                        try {
313
                                feat = (DefaultRowEdited) expansionFile.getRow(num);
314
                                return ((IFeature) feat.getLinkedRow()).getGeometry()
315
                                                .cloneGeometry();// getGeometry();
316
                        } catch (IOException e) {
317
                                e.printStackTrace();
318
                                throw new DriverIOException(e);
319
                        }
320
                }
321

    
322
        }
323

    
324
        /*
325
         * (non-Javadoc)
326
         * 
327
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
328
         */
329
        public int getShapeType() throws DriverIOException {
330
                return ova.getShapeType();
331
        }
332

    
333
        public ReadableVectorial getOriginalAdapter() {
334
                return ova;
335
        }
336

    
337
        public VectorialDriver getDriver() {
338
                return ova.getDriver();
339
        }
340

    
341
        public void setDriver(VectorialDriver driver) {
342
                this.ova.setDriver(driver);
343
        }
344

    
345
        public DriverAttributes getDriverAttributes() {
346
                return ova.getDriverAttributes();
347
        }
348

    
349
        /**
350
         * DOCUMENT ME!
351
         * 
352
         * @throws EditionException
353
         *             DOCUMENT ME!
354
         */
355
        public void startEdition(int sourceType) throws EditionException {
356
                super.startEdition(sourceType);
357

    
358
                try {
359
                        expansionFile.open();
360
                        if (index == null || fullExtent == null) {
361
                                // TODO: Si la capa dispone de un ?ndice espacial, hacer
362
                                // algo aqu? para que se use ese ?ndice espacial.
363
                                index = new Quadtree();
364

    
365
                                for (int i = 0; i < ova.getShapeCount(); i++) {
366
                                        IGeometry g = null;
367
                                        try {
368
                                                g = ((DefaultFeature) ova.getFeature(i)).getGeometry();
369
                                        } catch (DriverException e1) {
370
                                                // TODO Auto-generated catch block
371
                                                e1.printStackTrace();
372
                                        }
373

    
374
                                        if (g == null) {
375
                                                continue;
376
                                        }
377

    
378
                                        Rectangle2D r = g.getBounds2D();
379
                                        Envelope e = new Envelope(r.getX(),
380
                                                        r.getX() + r.getWidth(), r.getY(), r.getY()
381
                                                                        + r.getHeight());
382
                                        index.insert(e, new Integer(i));
383
                                        if (fullExtent == null) {
384
                                                fullExtent = r;
385
                                        } else {
386
                                                fullExtent = fullExtent.createUnion(r);
387
                                        }
388
                                }
389
                        }
390
                } catch (DriverIOException e) {
391
                        throw new EditionException(e);
392
                } catch (IOException e) {
393
                        throw new EditionException(e);
394
                }
395

    
396
                System.err.println("Se han metido en el ?ndice "
397
                                + index.queryAll().size() + " geometr?as");
398
        }
399

    
400
        /*
401
         * (non-Javadoc)
402
         * 
403
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
404
         */
405
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
406
                int calculatedIndex = getCalculatedIndex(index);
407
                Integer integer = new Integer(calculatedIndex);
408
                // Si no est? en el fichero de expansi?n
409
                DefaultRowEdited edRow = null;
410
                if (!relations.containsKey(integer)) {
411
                        try {
412
                                edRow = new DefaultRowEdited(ova.getFeature(calculatedIndex),
413
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
414
                                // /System.out.println("Piden la feature con ID= " + index);
415
                                /*
416
                                 * Exception e = new Exception(); e.printStackTrace();
417
                                 */
418
                        } catch (DriverException e) {
419
                                // TODO Auto-generated catch block
420
                                e.printStackTrace();
421
                        }
422

    
423
                        return edRow;
424
                } else {
425
                        int num = ((Integer) relations.get(integer)).intValue();
426
                        IRowEdited aux = expansionFile.getRow(num);
427
                        edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux
428
                                        .getStatus(), index);
429
                        return edRow;
430
                }
431
        }
432

    
433
        /**
434
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
435
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
436
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
437
         * una futura compactaci?n termine con ella.
438
         * 
439
         * @param index
440
         *            ?ndice de la geometr?a.
441
         * 
442
         * @throws DriverIOException
443
         * @throws IOException
444
         */
445
        public IRow doRemoveRow(int index, int sourceType)
446
                        throws DriverIOException, IOException {
447
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
448
                if (cancel)
449
                        return null;
450
                // Llega el calculatedIndex
451
                Integer integer = new Integer(index);
452

    
453
                IFeature feat = null;
454
                delRows.set(index, true);
455
                // Si la geometr?a no ha sido modificada
456
                if (!relations.containsKey(integer)) {
457

    
458
                        try {
459
                                feat = (DefaultFeature) (ova.getFeature(index));
460
                        } catch (DriverException e) {
461
                                // TODO Auto-generated catch block
462
                                e.printStackTrace();
463
                        }
464
                } else {
465
                        int num = ((Integer) relations.get(integer)).intValue();
466
                        feat = (IFeature) expansionFile.getRow(num).getLinkedRow();
467
                        // expansionFile.invalidateRow(num);
468
                }
469
                System.err.println("Elimina una Row en la posici?n: " + index);
470
                // Se actualiza el ?ndice
471
                if (feat != null) {
472
                        Rectangle2D r = feat.getGeometry().getBounds2D();
473
                        boolean borrado = this.index.remove(new Envelope(r.getX(), r.getX()
474
                                        + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
475
                                        new Integer(index));
476
                        System.out.println("Est? borrado : " + borrado);
477
                        System.out.println("Index.lenght : " + this.index.size());
478

    
479
                }
480
                setSelection(new FBitSet());
481
                fireAfterRemoveRow(index, sourceType);
482
                return feat;
483
        }
484

    
485
        /**
486
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
487
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
488
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
489
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
490
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
491
         * fichero.
492
         * 
493
         * @param calculatedIndex
494
         *            DOCUMENT ME!
495
         * @param feat
496
         *            DOCUMENT ME!
497
         * 
498
         * @return position inside ExpansionFile
499
         * 
500
         * @throws IOException
501
         * @throws DriverIOException
502
         */
503
        public int doModifyRow(int calculatedIndex, IRow feat, int sourceType)
504
                        throws IOException, DriverIOException {
505
                boolean cancel = fireBeforeModifyRow(feat, calculatedIndex, sourceType);
506
                if (cancel)
507
                        return -1;
508
                int posAnteriorInExpansionFile = -1;
509
                Integer integer = new Integer(calculatedIndex);
510

    
511
                IFeature featAnt = null;
512
                System.err.println("Modifica una Row en la posici?n: "
513
                                + calculatedIndex);
514
                // Si la geometr?a no ha sido modificada
515
                if (!relations.containsKey(integer)) {
516
                        int newPosition = expansionFile.addRow(feat,
517
                                        IRowEdited.STATUS_MODIFIED);
518
                        relations.put(integer, new Integer(newPosition));
519

    
520
                        // Se actualiza el ?ndice espacial
521
                        try {
522
                                featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
523
                        } catch (DriverException e) {
524
                                e.printStackTrace();
525
                        }
526
                        IGeometry g = featAnt.getGeometry();
527
                        Rectangle2D rAnt = g.getBounds2D();
528
                        Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
529
                        this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
530
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
531
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
532
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
533
                                        .getY(), r.getY() + r.getHeight()), new Integer(
534
                                        calculatedIndex));
535
                } else {
536
                        // Obtenemos el ?ndice en el fichero de expansi?n
537
                        int num = ((Integer) relations.get(integer)).intValue();
538
                        posAnteriorInExpansionFile = num;
539

    
540
                        // Obtenemos la geometr?a para actualiza el ?ndice
541
                        // espacialposteriormente
542
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
543

    
544
                        /*
545
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
546
                         * fichero de expansi?n en el que se encuentra la geometr?a
547
                         * modificada
548
                         */
549
                        num = expansionFile.modifyRow(num, feat);
550

    
551
                        /*
552
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
553
                         * fichero de expansi?n.
554
                         */
555
                        relations.put(integer, new Integer(num));
556

    
557
                        // Se modifica el ?ndice espacial
558
                        Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
559
                        Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
560
                        this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
561
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
562
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
563
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
564
                                        .getY(), r.getY() + r.getHeight()), new Integer(
565
                                        calculatedIndex));
566
                }
567
                fireAfterModifyRow(calculatedIndex, sourceType);
568
                return posAnteriorInExpansionFile;
569
        }
570

    
571
        /**
572
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
573
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
574
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
575
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
576
         * expansion file a justo despues de la penultima geometr?a
577
         * 
578
         * @param calculatedIndex
579
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
580
         * @param previousExpansionFileIndex
581
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
582
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
583
         *            original y por tanto no hay que actualizar el mapa de indices
584
         *            sino eliminar su entrada.
585
         * 
586
         * @throws IOException
587
         * @throws DriverIOException
588
         */
589
        public void undoModifyRow(int calculatedIndex,
590
                        int previousExpansionFileIndex, int sourceType) throws IOException,
591
                        DriverIOException {
592

    
593
                // Llega el CalculatedIndex
594
                /*
595
                 * Si la acci?n de modificar se realiz? sobre una geometr?a original
596
                 */
597
                if (previousExpansionFileIndex == -1) {
598

    
599
                        // Se obtiene la geometr?a para actualizar el ?ndice
600
                        // IGeometry g = ((DefaultFeature)
601
                        // getRow(calculatedIndex).getLinkedRow()).getGeometry();
602
                        int inverse = getInversedIndex(calculatedIndex);
603
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
604
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
605
                                        sourceType);
606
                        if (cancel)
607
                                return;
608
                        IGeometry g = df.getGeometry();
609
                        // IGeometry g = ova.getShape(calculatedIndex);
610
                        Rectangle2D r = g.getBounds2D();
611

    
612
                        // Se elimina de las relaciones y del fichero de expansi?n
613
                        relations.remove(new Integer(calculatedIndex));
614
                        expansionFile.deleteLastRow();
615

    
616
                        // Se actualizan los ?ndices
617
                        IGeometry gAnt = ova.getShape(calculatedIndex);
618
                        /*
619
                         * IGeometry gAnt = ((DefaultFeature) getRow(calculatedIndex)
620
                         * .getLinkedRow()).getGeometry();
621
                         */
622
                        Rectangle2D rAnt = gAnt.getBounds2D();
623
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
624
                                        .getY(), r.getY() + r.getHeight()), new Integer(
625
                                        calculatedIndex));
626
                        this.index.insert(new Envelope(rAnt.getX(), rAnt.getX()
627
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
628
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
629
                } else {
630
                        // Se obtiene la geometr?a para actualizar el ?ndice
631
                        IGeometry g = null;
632
                        int inverse = getInversedIndex(calculatedIndex);
633
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
634
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
635
                                        sourceType);
636
                        if (cancel)
637
                                return;
638
                        g = df.getGeometry();
639
                        System.out.println("Actual: " + g.toString());
640

    
641
                        Rectangle2D r = g.getBounds2D();
642
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
643
                                        .getY(), r.getY() + r.getHeight()), new Integer(
644
                                        calculatedIndex));
645

    
646
                        // Se actualiza la relaci?n de ?ndices
647
                        // Integer integer = new Integer(geometryIndex);
648
                        relations.put(new Integer(calculatedIndex), new Integer(
649
                                        previousExpansionFileIndex));
650

    
651
                        // Se recupera la geometr?a
652
                        // expansionFile.validateRow(previousExpansionFileIndex);
653

    
654
                        // Se actualizan los ?ndices
655
                        // g = ((IFeature)
656
                        // (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
657
                        // System.out.println("Anterior a la que volvemos : " +
658
                        // g.toString());
659
                        g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
660
                        r = g.getBounds2D();
661
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
662
                                        .getY(), r.getY() + r.getHeight()), new Integer(
663
                                        calculatedIndex));
664

    
665
                }
666
                fireAfterModifyRow(calculatedIndex, sourceType);
667
        }
668

    
669
        /**
670
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
671
         * en la tabla relations.
672
         * 
673
         * @param feat
674
         *            geometr?a a guardar.
675
         * 
676
         * @return calculatedIndex
677
         * 
678
         * @throws DriverIOException
679
         * @throws IOException
680
         */
681
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException,
682
                        IOException {
683
                int calculatedIndex = super.doAddRow(feat, sourceType);
684
                // Actualiza el ?ndice espacial
685
                IGeometry g = ((IFeature) feat).getGeometry();
686
                Rectangle2D r = g.getBounds2D();
687
                index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
688
                                r.getY() + r.getHeight()), new Integer(calculatedIndex));
689

    
690
                return calculatedIndex;
691
        }
692

    
693
        /**
694
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
695
         * en el fichero original
696
         * 
697
         * @param index
698
         *            DOCUMENT ME!
699
         * 
700
         * @throws IOException
701
         * @throws DriverIOException
702
         */
703
        public void undoRemoveRow(int index, int sourceType) throws IOException,
704
                        DriverIOException {
705
                super.undoRemoveRow(index, sourceType);
706

    
707
                IGeometry g = null;
708
                g = ((IFeature) getRow(index).getLinkedRow()).getGeometry();
709

    
710
                Rectangle2D r = g.getBounds2D();
711
                this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
712
                                .getY(), r.getY() + r.getHeight()), new Integer(index));
713
        }
714

    
715
        /**
716
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
717
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
718
         * relaci?n del mapa de relaciones
719
         * 
720
         * @param index
721
         *            ?ndice de la geometr?a que se a?adi?
722
         * 
723
         * @throws DriverIOException
724
         * @throws IOException
725
         */
726
        public void undoAddRow(int calculatedIndex, int sourceType)
727
                        throws DriverIOException, IOException {
728
                int inverse = getInversedIndex(calculatedIndex);
729
                IGeometry g = ((IFeature) getRow(inverse).getLinkedRow()).getGeometry();
730
                Rectangle2D r = g.getBounds2D();
731
                this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
732
                                .getY(), r.getY() + r.getHeight()),
733
                                new Integer(calculatedIndex));
734

    
735
                super.undoAddRow(calculatedIndex, sourceType);
736
                setSelection(new FBitSet());
737
        }
738

    
739
        /**
740
         * Obtiene las geometr?as que se encuentran en el rect?ngulo que se pasa
741
         * como par?metro haciendo uso del ?ndice espacial
742
         * 
743
         * @param r
744
         *            Rect?ngulo indicando la porci?n del espacio para el cual se
745
         *            quiere saber los ?ndices de las geometr?as que se encuentran
746
         *            dentro de ?l
747
         * 
748
         * @return Array de ?ndices para su uso con getGeometry, removeGeometry, ...
749
         */
750
        /*
751
         * public int[] getRowsIndexes_OL(Rectangle2D r) { Envelope e = new
752
         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
753
         * r.getHeight()); List l = index.query(e); int[] indexes = new
754
         * int[l.size()];
755
         * 
756
         * for (int index = 0; index < l.size(); index++) { Integer i = (Integer)
757
         * l.get(index); indexes[index] = getInversedIndex(i.intValue()); }
758
         * 
759
         * return indexes; }
760
         */
761
        /**
762
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
763
         */
764
        public int getShapeCount() throws DriverIOException {
765
                try {
766
                        return getRowCount();
767
                } catch (IOException e) {
768
                        throw new DriverIOException(e);
769
                }
770
        }
771

    
772
        /**
773
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
774
         */
775
        public Rectangle2D getFullExtent() throws DriverIOException {
776
                if (fullExtent == null) {
777
                        fullExtent = ova.getFullExtent();
778
                }
779
                return fullExtent;
780
        }
781

    
782
        /**
783
         * Use it BEFORE writing to a file.
784
         * 
785
         * @return real full extent.
786
         * @throws DriverIOException
787
         */
788
        public Rectangle2D reCalculateFullExtent() throws DriverIOException {
789
                if (getShapeCount() > 0) {
790
                        fullExtent = getShape(0).getBounds2D();
791
                        for (int i = 1; i < getShapeCount(); i++) {
792
                                fullExtent.add(getShape(i).getBounds2D());
793
                        }
794
                } else {
795
                        fullExtent = ova.getFullExtent();
796
                }
797
                return fullExtent;
798
        }
799

    
800
        /**
801
         * En la implementaci?n por defecto podemos hacer que cada feature tenga ID =
802
         * numero de registro. En el DBAdapter podr?amos "overrride" este m?todo y
803
         * poner como ID de la Feature el campo ?nico escogido en la base de datos.
804
         * 
805
         * @param numReg
806
         * @return
807
         * @throws DriverException
808
         */
809
        public IFeature getFeature(int numReg) throws DriverException {
810
                IGeometry geom;
811
                IFeature feat = null;
812
                try {
813
                        geom = getShape(numReg);
814
                        DataSource rs = getRecordset();
815
                        Value[] regAtt = new Value[rs.getFieldCount()];
816
                        for (int fieldId = 0; fieldId < rs.getFieldCount(); fieldId++) {
817
                                regAtt[fieldId] = rs.getFieldValue(numReg, fieldId);
818
                        }
819

    
820
                        feat = new DefaultFeature(geom, regAtt, numReg + "");
821
                } catch (DriverIOException e) {
822
                        throw new DriverException(e);
823
                } catch (DriverLoadException e) {
824
                        throw new DriverException(e);
825
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
826
                        throw new DriverException(e);
827
                }
828
                return feat;
829
        }
830

    
831
        public void stopEdition(IWriter writer, int sourceType)
832
                        throws EditionException {
833
                super.stopEdition(writer, sourceType);
834
                try {
835
                        ova.getDriver().reLoad();
836
                } catch (IOException e) {
837
                        e.printStackTrace();
838
                        throw new EditionException(e);
839
                }
840
        }
841

    
842
        public Rectangle2D getShapeBounds(int index) throws IOException {
843
                // Solo se utiliza cuando el driver es BoundedShapes
844
                // Si no est? en el fichero de expansi?n
845
                Integer integer = new Integer((int) index);
846
                if (!relations.containsKey(integer)) {
847
                        if (ova.getDriver() instanceof BoundedShapes) {
848
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
849
                                return bs.getShapeBounds(index);
850
                        } else {
851
                                return ova.getDriver().getShape(index).getBounds2D();
852
                        }
853

    
854
                } else {
855
                        int num = ((Integer) relations.get(integer)).intValue();
856
                        DefaultRowEdited feat;
857
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
858
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
859
                                return null;
860
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
861
                        return geom.getBounds2D();// getGeometry();
862
                }
863

    
864
        }
865

    
866
        public int getShapeType(int index) {
867
                try {
868
                        return ova.getShapeType();
869
                } catch (DriverIOException e) {
870
                        // TODO Auto-generated catch block
871
                        e.printStackTrace();
872
                }
873
                return FShape.MULTI;
874
        }
875

    
876
        /**
877
         * Usar solo cuando est?s seguro de que puedes gastar memoria. Nosotros lo
878
         * usamos para las b?squedas por ?ndice espacial con el handle. La idea es
879
         * usarlo una vez, guardar las geometr?as que necesitas en ese extent y
880
         * trabajar con ellas hasta el siguiente cambio de extent.
881
         * 
882
         * @param r
883
         * @param strEPSG
884
         * @return
885
         * @throws DriverException
886
         */
887
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG)
888
                        throws DriverException {
889
                // En esta clase suponemos random access.
890
                // Luego tendremos otra clase que sea VectorialEditableDBAdapter
891
                // que reescribir? este m?todo.
892
                Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
893
                List l = index.query(e);
894
                IRowEdited[] feats = new IRowEdited[l.size()];
895
                try {
896
                        for (int index = 0; index < l.size(); index++) {
897
                                Integer i = (Integer) l.get(index);
898
                                int inverse = getInversedIndex(i.intValue());
899
                                feats[index] = (IRowEdited) getRow(inverse);
900
                        }
901
                } catch (DriverIOException e1) {
902
                        throw new DriverException(e1);
903
                } catch (IOException e1) {
904
                        throw new DriverException(e1);
905
                }
906

    
907
                return feats;
908
        }
909

    
910
        public void setSpatialIndex(SpatialIndex spatialIndex) {
911
                index = (Quadtree) spatialIndex;
912
        }
913

    
914
        public void setFullExtent(Rectangle2D fullExtent2) {
915
                fullExtent = fullExtent2;
916
        }
917

    
918
        /**
919
         * DOCUMENT ME!
920
         * 
921
         * @return DOCUMENT ME!
922
         */
923
        public Image getSelectionImage() {
924
                return selectionImage;
925
        }
926

    
927
        public Image getHandlersImage() {
928
                return handlersImage;
929
        }
930

    
931
        /**
932
         * DOCUMENT ME!
933
         * 
934
         * @param i
935
         *            DOCUMENT ME!
936
         */
937
        public void setSelectionImage(Image i) {
938
                selectionImage = i;
939
        }
940

    
941
        public void setHandlersImage(BufferedImage handlersImage) {
942
                this.handlersImage = handlersImage;
943
        }
944
}