Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / VectorialEditableAdapter.java @ 6323

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

    
226
import java.awt.Image;
227
import java.awt.geom.Rectangle2D;
228
import java.awt.image.BufferedImage;
229
import java.io.IOException;
230
import java.util.List;
231

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

    
254
/**
255
 * @author fjp
256
 *
257
 */
258
public class VectorialEditableAdapter extends EditableAdapter implements
259
                ReadableVectorial, BoundedShapes {
260
        protected ReadableVectorial ova;
261

    
262
        protected Quadtree index;
263

    
264
        protected Rectangle2D fullExtent;
265

    
266
        protected Image selectionImage;
267

    
268
        protected BufferedImage handlersImage;
269

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

    
289
        public VectorialEditableAdapter() {
290
                super();
291
        }
292

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

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

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

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

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

    
362
        }
363

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

    
373
        public ReadableVectorial getOriginalAdapter() {
374
                return ova;
375
        }
376

    
377
        public VectorialDriver getDriver() {
378
                return ova.getDriver();
379
        }
380

    
381
        public void setDriver(VectorialDriver driver) {
382
                this.ova.setDriver(driver);
383
        }
384

    
385
        public DriverAttributes getDriverAttributes() {
386
                return ova.getDriverAttributes();
387
        }
388

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

    
403

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

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

    
420
                                        if (g == null) {
421
                                                continue;
422
                                        }
423

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

    
442
                System.err.println("Se han metido en el ?ndice "
443
                                + index.queryAll().size() + " geometr?as");
444
        }
445

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

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

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

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

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

    
523
                }
524
                setSelection(new FBitSet());
525
                fireAfterRemoveRow(index, sourceType);
526
                return feat;
527
        }
528

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

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

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

    
584
                        // Obtenemos la geometr?a para actualiza el ?ndice
585
                        // espacialposteriormente
586
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
587

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

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

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

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

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

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

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

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

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

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

    
695
                        // Se recupera la geometr?a
696
                        // expansionFile.validateRow(previousExpansionFileIndex);
697

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

    
709
                }
710
                fireAfterModifyRow(calculatedIndex, sourceType);
711
        }
712

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

    
734
                return calculatedIndex;
735
        }
736

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

    
751
                IGeometry g = null;
752
                g = ((IFeature) getRow(getInversedIndex(index)).getLinkedRow()).getGeometry();
753

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

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

    
779
                super.undoAddRow(calculatedIndex, sourceType);
780
                setSelection(new FBitSet());
781
        }
782

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

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

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

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

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

    
875
        public void stopEdition(IWriter writer, int sourceType)
876
                        throws EditionException {
877
                ISpatialWriter spatialWriter = (ISpatialWriter) writer;
878
                spatialWriter.setFlatness(getFlatness());
879
                super.stopEdition(writer, sourceType);
880
                try {
881
                        ova.getDriver().reload();
882
                } catch (IOException e) {
883
                        e.printStackTrace();
884
                        throw new EditionException(e);
885
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
886
                        e.printStackTrace();
887
                        throw new EditionException(e);
888
                }
889
        }
890

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

    
903
                } else {
904
                        int num = ((Integer) relations.get(integer)).intValue();
905
                        DefaultRowEdited feat;
906
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
907
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
908
                                return null;
909
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
910
                        return geom.getBounds2D();// getGeometry();
911
                }
912

    
913
        }
914

    
915
        public int getShapeType(int index) {
916
                try {
917
                        return ova.getShapeType();
918
                } catch (DriverIOException e) {
919
                        // TODO Auto-generated catch block
920
                        e.printStackTrace();
921
                }
922
                return FShape.MULTI;
923
        }
924

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

    
956
                return feats;
957
        }
958

    
959
        public void setSpatialIndex(SpatialIndex spatialIndex) {
960
                index = (Quadtree) spatialIndex;
961
        }
962

    
963
        public void setFullExtent(Rectangle2D fullExtent2) {
964
                fullExtent = fullExtent2;
965
        }
966

    
967
        /**
968
         * DOCUMENT ME!
969
         *
970
         * @return DOCUMENT ME!
971
         */
972
        public Image getSelectionImage() {
973
                return selectionImage;
974
        }
975

    
976
        public Image getHandlersImage() {
977
                return handlersImage;
978
        }
979

    
980
        /**
981
         * DOCUMENT ME!
982
         *
983
         * @param i
984
         *            DOCUMENT ME!
985
         */
986
        public void setSelectionImage(Image i) {
987
                selectionImage = i;
988
        }
989

    
990
        public void setHandlersImage(BufferedImage handlersImage) {
991
                this.handlersImage = handlersImage;
992
        }
993

    
994
        public double getFlatness() {
995
                return flatness;
996
        }
997

    
998
        public void setFlatness(double d) {
999
                flatness=d;
1000
        }
1001
}