Statistics
| Revision:

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

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

    
223
import java.awt.Image;
224
import java.awt.geom.Rectangle2D;
225
import java.awt.image.BufferedImage;
226
import java.io.IOException;
227
import java.util.List;
228

    
229
import com.hardcode.driverManager.Driver;
230
import com.hardcode.driverManager.DriverLoadException;
231
import com.hardcode.gdbms.engine.data.DataSource;
232
import com.hardcode.gdbms.engine.values.Value;
233
import com.iver.cit.gvsig.fmap.DriverException;
234
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
235
import com.iver.cit.gvsig.fmap.core.DefaultRow;
236
import com.iver.cit.gvsig.fmap.core.FShape;
237
import com.iver.cit.gvsig.fmap.core.IFeature;
238
import com.iver.cit.gvsig.fmap.core.IGeometry;
239
import com.iver.cit.gvsig.fmap.core.IRow;
240
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
241
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
242
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
243
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
244
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
245
import com.iver.cit.gvsig.fmap.layers.FBitSet;
246
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
247
import com.vividsolutions.jts.geom.Envelope;
248
import com.vividsolutions.jts.index.SpatialIndex;
249
import com.vividsolutions.jts.index.quadtree.Quadtree;
250

    
251
/**
252
 * @author fjp
253
 *
254
 */
255
public class VectorialEditableAdapter extends EditableAdapter implements
256
                ReadableVectorial, BoundedShapes {
257
        protected ReadableVectorial ova;
258

    
259
        protected Quadtree index;
260

    
261
        protected Rectangle2D fullExtent;
262

    
263
        protected Image selectionImage;
264

    
265
        protected BufferedImage handlersImage;
266

    
267
        private double flatness=0.8;
268
        /*
269
         * private class MyFeatureIterator implements IFeatureIterator { int numReg =
270
         * 0; Rectangle2D rect; String epsg; IFeatureIterator origFeatIt; boolean
271
         * bHasNext = true;
272
         *
273
         * public MyFeatureIterator(Rectangle2D r, String strEPSG) throws
274
         * DriverException { rect = r; epsg = strEPSG; origFeatIt =
275
         * ova.getFeatureIterator(r, epsg); } public boolean hasNext() throws
276
         * DriverException { return bHasNext; }
277
         *
278
         * public IFeature next() throws DriverException { IFeature aux =
279
         * origFeatIt.next(); return null; }
280
         *
281
         * public void closeIterator() throws DriverException {
282
         *  }
283
         *  }
284
         */
285

    
286
        public VectorialEditableAdapter() {
287
                super();
288
        }
289

    
290
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
291
                ova = rv;
292
                try {
293
                        setOriginalDataSource(rv.getRecordset());
294
                } catch (DriverLoadException e) {
295
                        e.printStackTrace();
296
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
297
                        // TODO Auto-generated catch block
298
                        e.printStackTrace();
299
                }
300
        }
301

    
302
        /*
303
         * (non-Javadoc)
304
         *
305
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#start()
306
         */
307
        public void start() throws DriverIOException {
308
                ova.start();
309
        }
310

    
311
        public IWriter getWriter() {
312
                if (ova.getDriver() instanceof IWriteable)
313
                {
314
                        IWriter writer = ((IWriteable) ova.getDriver()).getWriter();
315
                        if (writer instanceof ISpatialWriter)
316
                                return writer;
317
                }
318
                return null;
319
        }
320

    
321
        /*
322
         * (non-Javadoc)
323
         *
324
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#stop()
325
         */
326
        public void stop() throws DriverIOException {
327
                ova.stop();
328
        }
329

    
330
        /*
331
         * (non-Javadoc)
332
         *
333
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
334
         */
335
        public IGeometry getShape(int rowIndex) throws DriverIOException {
336
                // Si no est? en el fichero de expansi?n
337
                int calculatedIndex = getCalculatedIndex(rowIndex);
338
                Integer integer = new Integer(calculatedIndex);
339
                if (!relations.containsKey(integer)) {
340
                        // Si ha sido eliminada
341
                        /*
342
                         * if (delRows.get(integer.intValue())) { return null; } else {
343
                         */
344
                        return ova.getShape(calculatedIndex);
345
                        // }
346
                } else {
347
                        int num = ((Integer) relations.get(integer)).intValue();
348
                        DefaultRowEdited feat;
349
                        try {
350
                                feat = (DefaultRowEdited) expansionFile.getRow(num);
351
                                return ((IFeature) feat.getLinkedRow()).getGeometry()
352
                                                .cloneGeometry();// getGeometry();
353
                        } catch (IOException e) {
354
                                e.printStackTrace();
355
                                throw new DriverIOException(e);
356
                        }
357
                }
358

    
359
        }
360

    
361
        /*
362
         * (non-Javadoc)
363
         *
364
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
365
         */
366
        public int getShapeType() throws DriverIOException {
367
                return ova.getShapeType();
368
        }
369

    
370
        public ReadableVectorial getOriginalAdapter() {
371
                return ova;
372
        }
373

    
374
        public VectorialDriver getDriver() {
375
                return ova.getDriver();
376
        }
377

    
378
        public void setDriver(VectorialDriver driver) {
379
                this.ova.setDriver(driver);
380
        }
381

    
382
        public DriverAttributes getDriverAttributes() {
383
                return ova.getDriverAttributes();
384
        }
385

    
386
        /**
387
         * DOCUMENT ME!
388
         *
389
         * @throws EditionException
390
         *             DOCUMENT ME!
391
         */
392
        public void startEdition(int sourceType) throws EditionException {
393
                super.startEdition(sourceType);
394
                Driver drv = ova.getDriver();
395
                if (drv instanceof IWriteable)
396
                {
397
                        setWriter(((IWriteable) drv).getWriter());
398
                }
399

    
400

    
401
                try {
402
                        expansionFile.open();
403
                        if (index == null || fullExtent == null) {
404
                                // TODO: Si la capa dispone de un ?ndice espacial, hacer
405
                                // algo aqu? para que se use ese ?ndice espacial.
406
                                index = new Quadtree();
407

    
408
                                for (int i = 0; i < ova.getShapeCount(); i++) {
409
                                        IGeometry g = null;
410
                                        try {
411
                                                g = ((DefaultFeature) ova.getFeature(i)).getGeometry();
412
                                        } catch (DriverException e1) {
413
                                                // TODO Auto-generated catch block
414
                                                e1.printStackTrace();
415
                                        }
416

    
417
                                        if (g == null) {
418
                                                continue;
419
                                        }
420

    
421
                                        Rectangle2D r = g.getBounds2D();
422
                                        Envelope e = new Envelope(r.getX(),
423
                                                        r.getX() + r.getWidth(), r.getY(), r.getY()
424
                                                                        + r.getHeight());
425
                                        index.insert(e, new Integer(i));
426
                                        if (fullExtent == null) {
427
                                                fullExtent = r;
428
                                        } else {
429
                                                fullExtent = fullExtent.createUnion(r);
430
                                        }
431
                                }
432
                        }
433
                } catch (DriverIOException e) {
434
                        throw new EditionException(e);
435
                } catch (IOException e) {
436
                        throw new EditionException(e);
437
                }
438

    
439
                System.err.println("Se han metido en el ?ndice "
440
                                + index.queryAll().size() + " geometr?as");
441
        }
442

    
443
        /*
444
         * (non-Javadoc)
445
         *
446
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
447
         */
448
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
449
                int calculatedIndex = getCalculatedIndex(index);
450
                Integer integer = new Integer(calculatedIndex);
451
                // Si no est? en el fichero de expansi?n
452
                DefaultRowEdited edRow = null;
453
                if (!relations.containsKey(integer)) {
454
                        try {
455
                                edRow = new DefaultRowEdited(ova.getFeature(calculatedIndex),
456
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
457
                                return createExternalRow(edRow, 0);
458
                        } catch (DriverException e) {
459
                                // TODO Auto-generated catch block
460
                                e.printStackTrace();
461
                        }
462

    
463
                        return edRow;
464
                } else {
465
                        int num = ((Integer) relations.get(integer)).intValue();
466
                        IRowEdited aux = expansionFile.getRow(num);
467
                        edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux
468
                                        .getStatus(), index);
469
                        
470
                        return edRow;
471
                }
472
        }
473

    
474
        /**
475
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
476
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
477
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
478
         * una futura compactaci?n termine con ella.
479
         *
480
         * @param index
481
         *            ?ndice de la geometr?a.
482
         *
483
         * @throws DriverIOException
484
         * @throws IOException
485
         */
486
        public IRow doRemoveRow(int index, int sourceType)
487
                        throws DriverIOException, IOException {
488
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
489
                if (cancel)
490
                        return null;
491
                // Llega el calculatedIndex
492
                Integer integer = new Integer(index);
493

    
494
                IFeature feat = null;
495
                delRows.set(index, true);
496
                // Si la geometr?a no ha sido modificada
497
                if (!relations.containsKey(integer)) {
498

    
499
                        try {
500
                                feat = (DefaultFeature) (ova.getFeature(index));
501
                        } catch (DriverException e) {
502
                                // TODO Auto-generated catch block
503
                                e.printStackTrace();
504
                        }
505
                } else {
506
                        int num = ((Integer) relations.get(integer)).intValue();
507
                        feat = (IFeature) expansionFile.getRow(num).getLinkedRow();
508
                        // expansionFile.invalidateRow(num);
509
                }
510
                System.err.println("Elimina una Row en la posici?n: " + index);
511
                // Se actualiza el ?ndice
512
                if (feat != null) {
513
                        Rectangle2D r = feat.getGeometry().getBounds2D();
514
                        boolean borrado = this.index.remove(new Envelope(r.getX(), r.getX()
515
                                        + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
516
                                        new Integer(index));
517
                        System.out.println("Est? borrado : " + borrado);
518
                        System.out.println("Index.lenght : " + this.index.size());
519

    
520
                }
521
                setSelection(new FBitSet());
522
                fireAfterRemoveRow(index, sourceType);
523
                return feat;
524
        }
525

    
526
        /**
527
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
528
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
529
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
530
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
531
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
532
         * fichero.
533
         *
534
         * @param calculatedIndex
535
         *            DOCUMENT ME!
536
         * @param feat
537
         *            DOCUMENT ME!
538
         *
539
         * @return position inside ExpansionFile
540
         *
541
         * @throws IOException
542
         * @throws DriverIOException
543
         */
544
        public int doModifyRow(int calculatedIndex, IRow feat, int sourceType)
545
                        throws IOException, DriverIOException {
546
                boolean cancel = fireBeforeModifyRow(feat, calculatedIndex, sourceType);
547
                if (cancel)
548
                        return -1;
549
                int posAnteriorInExpansionFile = -1;
550
                Integer integer = new Integer(calculatedIndex);
551

    
552
                IFeature featAnt = null;
553
                System.err.println("Modifica una Row en la posici?n: "
554
                                + calculatedIndex);
555
                // Si la geometr?a no ha sido modificada
556
                if (!relations.containsKey(integer)) {
557
                        int newPosition = expansionFile.addRow(feat,
558
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
559
                        relations.put(integer, new Integer(newPosition));
560

    
561
                        // Se actualiza el ?ndice espacial
562
                        try {
563
                                featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
564
                        } catch (DriverException e) {
565
                                e.printStackTrace();
566
                        }
567
                        IGeometry g = featAnt.getGeometry();
568
                        Rectangle2D rAnt = g.getBounds2D();
569
                        Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
570
                        this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
571
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
572
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
573
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
574
                                        .getY(), r.getY() + r.getHeight()), new Integer(
575
                                        calculatedIndex));
576
                } else {
577
                        // Obtenemos el ?ndice en el fichero de expansi?n
578
                        int num = ((Integer) relations.get(integer)).intValue();
579
                        posAnteriorInExpansionFile = num;
580

    
581
                        // Obtenemos la geometr?a para actualiza el ?ndice
582
                        // espacialposteriormente
583
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
584

    
585
                        /*
586
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
587
                         * fichero de expansi?n en el que se encuentra la geometr?a
588
                         * modificada
589
                         */
590
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
591

    
592
                        /*
593
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
594
                         * fichero de expansi?n.
595
                         */
596
                        relations.put(integer, new Integer(num));
597

    
598
                        // Se modifica el ?ndice espacial
599
                        Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
600
                        Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
601
                        this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
602
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
603
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
604
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
605
                                        .getY(), r.getY() + r.getHeight()), new Integer(
606
                                        calculatedIndex));
607
                }
608
                fireAfterModifyRow(calculatedIndex, sourceType);
609
                return posAnteriorInExpansionFile;
610
        }
611

    
612
        /**
613
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
614
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
615
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
616
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
617
         * expansion file a justo despues de la penultima geometr?a
618
         *
619
         * @param calculatedIndex
620
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
621
         * @param previousExpansionFileIndex
622
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
623
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
624
         *            original y por tanto no hay que actualizar el mapa de indices
625
         *            sino eliminar su entrada.
626
         *
627
         * @throws IOException
628
         * @throws DriverIOException
629
         */
630
        public void undoModifyRow(int calculatedIndex,
631
                        int previousExpansionFileIndex, int sourceType) throws IOException,
632
                        DriverIOException {
633

    
634
                // Llega el CalculatedIndex
635
                /*
636
                 * Si la acci?n de modificar se realiz? sobre una geometr?a original
637
                 */
638
                if (previousExpansionFileIndex == -1) {
639

    
640
                        // Se obtiene la geometr?a para actualizar el ?ndice
641
                        // IGeometry g = ((DefaultFeature)
642
                        // getRow(calculatedIndex).getLinkedRow()).getGeometry();
643
                        int inverse = getInversedIndex(calculatedIndex);
644
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
645
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
646
                                        sourceType);
647
                        if (cancel)
648
                                return;
649
                        IGeometry g = df.getGeometry();
650
                        // IGeometry g = ova.getShape(calculatedIndex);
651
                        Rectangle2D r = g.getBounds2D();
652

    
653
                        // Se elimina de las relaciones y del fichero de expansi?n
654
                        relations.remove(new Integer(calculatedIndex));
655
                        expansionFile.deleteLastRow();
656

    
657
                        // Se actualizan los ?ndices
658
                        IGeometry gAnt = ova.getShape(calculatedIndex);
659
                        /*
660
                         * IGeometry gAnt = ((DefaultFeature) getRow(calculatedIndex)
661
                         * .getLinkedRow()).getGeometry();
662
                         */
663
                        Rectangle2D rAnt = gAnt.getBounds2D();
664
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
665
                                        .getY(), r.getY() + r.getHeight()), new Integer(
666
                                        calculatedIndex));
667
                        this.index.insert(new Envelope(rAnt.getX(), rAnt.getX()
668
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
669
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
670
                } else {
671
                        // Se obtiene la geometr?a para actualizar el ?ndice
672
                        IGeometry g = null;
673
                        int inverse = getInversedIndex(calculatedIndex);
674
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
675
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
676
                                        sourceType);
677
                        if (cancel)
678
                                return;
679
                        g = df.getGeometry();
680
                        System.out.println("Actual: " + g.toString());
681

    
682
                        Rectangle2D r = g.getBounds2D();
683
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
684
                                        .getY(), r.getY() + r.getHeight()), new Integer(
685
                                        calculatedIndex));
686

    
687
                        // Se actualiza la relaci?n de ?ndices
688
                        // Integer integer = new Integer(geometryIndex);
689
                        relations.put(new Integer(calculatedIndex), new Integer(
690
                                        previousExpansionFileIndex));
691

    
692
                        // Se recupera la geometr?a
693
                        // expansionFile.validateRow(previousExpansionFileIndex);
694

    
695
                        // Se actualizan los ?ndices
696
                        // g = ((IFeature)
697
                        // (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
698
                        // System.out.println("Anterior a la que volvemos : " +
699
                        // g.toString());
700
                        g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
701
                        r = g.getBounds2D();
702
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
703
                                        .getY(), r.getY() + r.getHeight()), new Integer(
704
                                        calculatedIndex));
705

    
706
                }
707
                fireAfterModifyRow(calculatedIndex, sourceType);
708
        }
709

    
710
        /**
711
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
712
         * en la tabla relations.
713
         *
714
         * @param feat
715
         *            geometr?a a guardar.
716
         *
717
         * @return calculatedIndex
718
         *
719
         * @throws DriverIOException
720
         * @throws IOException
721
         */
722
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException,
723
                        IOException {
724
                int calculatedIndex = super.doAddRow(feat, sourceType);
725
                // Actualiza el ?ndice espacial
726
                IGeometry g = ((IFeature) feat).getGeometry();
727
                Rectangle2D r = g.getBounds2D();
728
                index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
729
                                r.getY() + r.getHeight()), new Integer(calculatedIndex));
730

    
731
                return calculatedIndex;
732
        }
733

    
734
        /**
735
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
736
         * en el fichero original
737
         *
738
         * @param index
739
         *            DOCUMENT ME!
740
         *
741
         * @throws IOException
742
         * @throws DriverIOException
743
         */
744
        public void undoRemoveRow(int index, int sourceType) throws IOException,
745
                        DriverIOException {
746
                super.undoRemoveRow(index, sourceType);
747

    
748
                IGeometry g = null;
749
                g = ((IFeature) getRow(getInversedIndex(index)).getLinkedRow()).getGeometry();
750

    
751
                Rectangle2D r = g.getBounds2D();
752
                this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
753
                                .getY(), r.getY() + r.getHeight()), new Integer(index));
754
        }
755

    
756
        /**
757
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
758
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
759
         * relaci?n del mapa de relaciones
760
         *
761
         * @param index
762
         *            ?ndice de la geometr?a que se a?adi?
763
         *
764
         * @throws DriverIOException
765
         * @throws IOException
766
         */
767
        public void undoAddRow(int calculatedIndex, int sourceType)
768
                        throws DriverIOException, IOException {
769
                int inverse = getInversedIndex(calculatedIndex);
770
                IGeometry g = ((IFeature) getRow(inverse).getLinkedRow()).getGeometry();
771
                Rectangle2D r = g.getBounds2D();
772
                this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
773
                                .getY(), r.getY() + r.getHeight()),
774
                                new Integer(calculatedIndex));
775

    
776
                super.undoAddRow(calculatedIndex, sourceType);
777
                setSelection(new FBitSet());
778
        }
779

    
780
        /**
781
         * Obtiene las geometr?as que se encuentran en el rect?ngulo que se pasa
782
         * como par?metro haciendo uso del ?ndice espacial
783
         *
784
         * @param r
785
         *            Rect?ngulo indicando la porci?n del espacio para el cual se
786
         *            quiere saber los ?ndices de las geometr?as que se encuentran
787
         *            dentro de ?l
788
         *
789
         * @return Array de ?ndices para su uso con getGeometry, removeGeometry, ...
790
         */
791
        /*
792
         * public int[] getRowsIndexes_OL(Rectangle2D r) { Envelope e = new
793
         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
794
         * r.getHeight()); List l = index.query(e); int[] indexes = new
795
         * int[l.size()];
796
         *
797
         * for (int index = 0; index < l.size(); index++) { Integer i = (Integer)
798
         * l.get(index); indexes[index] = getInversedIndex(i.intValue()); }
799
         *
800
         * return indexes; }
801
         */
802
        /**
803
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
804
         */
805
        public int getShapeCount() throws DriverIOException {
806
                try {
807
                        return getRowCount();
808
                } catch (IOException e) {
809
                        throw new DriverIOException(e);
810
                }
811
        }
812

    
813
        /**
814
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
815
         */
816
        public Rectangle2D getFullExtent() throws DriverIOException {
817
                if (fullExtent == null) {
818
                        fullExtent = ova.getFullExtent();
819
                }
820
                return fullExtent;
821
        }
822

    
823
        /**
824
         * Use it BEFORE writing to a file.
825
         *
826
         * @return real full extent.
827
         * @throws DriverIOException
828
         */
829
        public Rectangle2D reCalculateFullExtent() throws DriverIOException {
830
                if (getShapeCount() > 0) {
831
                        fullExtent = getShape(0).getBounds2D();
832
                        for (int i = 1; i < getShapeCount(); i++) {
833
                                fullExtent.add(getShape(i).getBounds2D());
834
                        }
835
                } else {
836
                        fullExtent = ova.getFullExtent();
837
                }
838
                return fullExtent;
839
        }
840

    
841
        /**
842
         * En la implementaci?n por defecto podemos hacer que cada feature tenga ID =
843
         * numero de registro. En el DBAdapter podr?amos "overrride" este m?todo y
844
         * poner como ID de la Feature el campo ?nico escogido en la base de datos.
845
         *
846
         * @param numReg
847
         * @return
848
         * @throws DriverException
849
         */
850
        public IFeature getFeature(int numReg) throws DriverException {
851
                IGeometry geom;
852
                IFeature feat = null;
853
                try {
854
                        geom = getShape(numReg);
855
                        DataSource rs = getRecordset();
856
                        Value[] regAtt = new Value[rs.getFieldCount()];
857
                        for (int fieldId = 0; fieldId < rs.getFieldCount(); fieldId++) {
858
                                regAtt[fieldId] = rs.getFieldValue(numReg, fieldId);
859
                        }
860

    
861
                        feat = new DefaultFeature(geom, regAtt, numReg + "");
862
                } catch (DriverIOException e) {
863
                        throw new DriverException(e);
864
                } catch (DriverLoadException e) {
865
                        throw new DriverException(e);
866
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
867
                        throw new DriverException(e);
868
                }
869
                return feat;
870
        }
871

    
872
        public void stopEdition(IWriter writer, int sourceType)
873
                        throws EditionException {
874
                ISpatialWriter spatialWriter = (ISpatialWriter) writer;
875
                spatialWriter.setFlatness(getFlatness());
876
                super.stopEdition(writer, sourceType);
877
                try {
878
                        ova.getDriver().reLoad();
879
                } catch (IOException e) {
880
                        e.printStackTrace();
881
                        throw new EditionException(e);
882
                }
883
        }
884

    
885
        public Rectangle2D getShapeBounds(int index) throws IOException {
886
                // Solo se utiliza cuando el driver es BoundedShapes
887
                // Si no est? en el fichero de expansi?n
888
                Integer integer = new Integer((int) index);
889
                if (!relations.containsKey(integer)) {
890
                        if (ova.getDriver() instanceof BoundedShapes) {
891
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
892
                                return bs.getShapeBounds(index);
893
                        } else {
894
                                return ova.getDriver().getShape(index).getBounds2D();
895
                        }
896

    
897
                } else {
898
                        int num = ((Integer) relations.get(integer)).intValue();
899
                        DefaultRowEdited feat;
900
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
901
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
902
                                return null;
903
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
904
                        return geom.getBounds2D();// getGeometry();
905
                }
906

    
907
        }
908

    
909
        public int getShapeType(int index) {
910
                try {
911
                        return ova.getShapeType();
912
                } catch (DriverIOException e) {
913
                        // TODO Auto-generated catch block
914
                        e.printStackTrace();
915
                }
916
                return FShape.MULTI;
917
        }
918

    
919
        /**
920
         * Usar solo cuando est?s seguro de que puedes gastar memoria. Nosotros lo
921
         * usamos para las b?squedas por ?ndice espacial con el handle. La idea es
922
         * usarlo una vez, guardar las geometr?as que necesitas en ese extent y
923
         * trabajar con ellas hasta el siguiente cambio de extent.
924
         *
925
         * @param r
926
         * @param strEPSG
927
         * @return
928
         * @throws DriverException
929
         */
930
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG)
931
                        throws DriverException {
932
                // En esta clase suponemos random access.
933
                // Luego tendremos otra clase que sea VectorialEditableDBAdapter
934
                // que reescribir? este m?todo.
935
                Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
936
                List l = index.query(e);
937
                IRowEdited[] feats = new IRowEdited[l.size()];
938
                try {
939
                        for (int index = 0; index < l.size(); index++) {
940
                                Integer i = (Integer) l.get(index);
941
                                int inverse = getInversedIndex(i.intValue());
942
                                feats[index] = (IRowEdited) getRow(inverse);
943
                        }
944
                } catch (DriverIOException e1) {
945
                        throw new DriverException(e1);
946
                } catch (IOException e1) {
947
                        throw new DriverException(e1);
948
                }
949

    
950
                return feats;
951
        }
952

    
953
        public void setSpatialIndex(SpatialIndex spatialIndex) {
954
                index = (Quadtree) spatialIndex;
955
        }
956

    
957
        public void setFullExtent(Rectangle2D fullExtent2) {
958
                fullExtent = fullExtent2;
959
        }
960

    
961
        /**
962
         * DOCUMENT ME!
963
         *
964
         * @return DOCUMENT ME!
965
         */
966
        public Image getSelectionImage() {
967
                return selectionImage;
968
        }
969

    
970
        public Image getHandlersImage() {
971
                return handlersImage;
972
        }
973

    
974
        /**
975
         * DOCUMENT ME!
976
         *
977
         * @param i
978
         *            DOCUMENT ME!
979
         */
980
        public void setSelectionImage(Image i) {
981
                selectionImage = i;
982
        }
983

    
984
        public void setHandlersImage(BufferedImage handlersImage) {
985
                this.handlersImage = handlersImage;
986
        }
987

    
988
        public double getFlatness() {
989
                return flatness;
990
        }
991

    
992
        public void setFlatness(double d) {
993
                flatness=d;
994
        }
995
}