Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1000 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / VectorialEditableAdapter.java @ 11885

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

    
250
import java.awt.Image;
251
import java.awt.geom.Rectangle2D;
252
import java.awt.image.BufferedImage;
253
import java.io.IOException;
254
import java.util.List;
255

    
256
import com.hardcode.driverManager.Driver;
257
import com.hardcode.driverManager.DriverLoadException;
258
import com.hardcode.gdbms.engine.data.DataSource;
259
import com.hardcode.gdbms.engine.values.Value;
260
import com.iver.cit.gvsig.fmap.DriverException;
261
import com.iver.cit.gvsig.fmap.DriverIOExceptionType;
262
import com.iver.cit.gvsig.fmap.DriverNotLoadedExceptionType;
263
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
264
import com.iver.cit.gvsig.fmap.core.FShape;
265
import com.iver.cit.gvsig.fmap.core.IFeature;
266
import com.iver.cit.gvsig.fmap.core.IGeometry;
267
import com.iver.cit.gvsig.fmap.core.IRow;
268
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
269
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
270
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
271
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
272
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
273
import com.iver.cit.gvsig.fmap.layers.FBitSet;
274
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
275
import com.vividsolutions.jts.geom.Envelope;
276
import com.vividsolutions.jts.index.SpatialIndex;
277
import com.vividsolutions.jts.index.quadtree.Quadtree;
278

    
279
/**
280
 * @author fjp
281
 *
282
 */
283
public class VectorialEditableAdapter extends EditableAdapter implements
284
                ReadableVectorial, BoundedShapes {
285
        protected ReadableVectorial ova;
286

    
287
        protected Quadtree index;
288

    
289
        protected Rectangle2D fullExtent;
290

    
291
        protected Image selectionImage;
292

    
293
        protected BufferedImage handlersImage;
294

    
295
        //private double flatness=0.8;
296
        /*
297
         * private class MyFeatureIterator implements IFeatureIterator { int numReg =
298
         * 0; Rectangle2D rect; String epsg; IFeatureIterator origFeatIt; boolean
299
         * bHasNext = true;
300
         *
301
         * public MyFeatureIterator(Rectangle2D r, String strEPSG) throws
302
         * DriverException { rect = r; epsg = strEPSG; origFeatIt =
303
         * ova.getFeatureIterator(r, epsg); } public boolean hasNext() throws
304
         * DriverException { return bHasNext; }
305
         *
306
         * public IFeature next() throws DriverException { IFeature aux =
307
         * origFeatIt.next(); return null; }
308
         *
309
         * public void closeIterator() throws DriverException {
310
         *  }
311
         *  }
312
         */
313

    
314
        public VectorialEditableAdapter() {
315
                super();
316
        }
317

    
318
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
319
                ova = rv;
320
                try {
321
                        setOriginalDataSource(rv.getRecordset());
322
                } catch (DriverLoadException e) {
323
                        e.printStackTrace();
324
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
325
                        // TODO Auto-generated catch block
326
                        e.printStackTrace();
327
                }
328
        }
329

    
330
        /*
331
         * (non-Javadoc)
332
         *
333
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#start()
334
         */
335
        public void start() throws DriverIOException {
336
                ova.start();
337
        }
338

    
339
        public IWriter getWriter() {
340
                if (ova.getDriver() instanceof IWriteable)
341
                {
342
                        IWriter writer = ((IWriteable) ova.getDriver()).getWriter();
343
                        if (writer instanceof ISpatialWriter)
344
                                return writer;
345
                }
346
                return null;
347
        }
348

    
349
        /*
350
         * (non-Javadoc)
351
         *
352
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#stop()
353
         */
354
        public void stop() throws DriverIOException {
355
                ova.stop();
356
        }
357

    
358
        /*
359
         * (non-Javadoc)
360
         *
361
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
362
         */
363
        public IGeometry getShape(int rowIndex) throws DriverIOException {
364
                // Si no est? en el fichero de expansi?n
365
                int calculatedIndex = getCalculatedIndex(rowIndex);
366
                Integer integer = new Integer(calculatedIndex);
367
                if (!relations.containsKey(integer)) {
368
                        // Si ha sido eliminada
369
                        /*
370
                         * if (delRows.get(integer.intValue())) { return null; } else {
371
                         */
372
                        return ova.getShape(calculatedIndex);
373
                        // }
374
                } else {
375
                        int num = ((Integer) relations.get(integer)).intValue();
376
                        DefaultRowEdited feat;
377
                        try {
378
                                feat = (DefaultRowEdited) expansionFile.getRow(num);
379
                                return ((IFeature) feat.getLinkedRow()).getGeometry()
380
                                                .cloneGeometry();// getGeometry();
381
                        } catch (IOException e) {
382
                                e.printStackTrace();
383
                                throw new DriverIOException(e);
384
                        }
385
                }
386

    
387
        }
388

    
389
        /*
390
         * (non-Javadoc)
391
         *
392
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
393
         */
394
        public int getShapeType() throws DriverIOException {
395
                return ova.getShapeType();
396
        }
397

    
398
        public ReadableVectorial getOriginalAdapter() {
399
                return ova;
400
        }
401

    
402
        public VectorialDriver getDriver() {
403
                return ova.getDriver();
404
        }
405

    
406
        public void setDriver(VectorialDriver driver) {
407
                this.ova.setDriver(driver);
408
        }
409

    
410
        public DriverAttributes getDriverAttributes() {
411
                return ova.getDriverAttributes();
412
        }
413
        /**
414
         * DOCUMENT ME!
415
         *
416
         * @throws EditionException
417
         *             DOCUMENT ME!
418
         */
419
        public void startEdition(int sourceType) throws EditionException {
420
                super.startEdition(sourceType);
421
                Driver drv = ova.getDriver();
422
                if (drv instanceof IWriteable)
423
                {
424
                        setWriter(((IWriteable) drv).getWriter());
425
                }
426

    
427

    
428
                try {
429
                        expansionFile.open();
430
                        if (index == null || fullExtent == null) {
431
                                // TODO: Si la capa dispone de un ?ndice espacial, hacer
432
                                // algo aqu? para que se use ese ?ndice espacial.
433
                                index = new Quadtree();
434
                                for (int i = 0; i < ova.getShapeCount(); i++) {
435
                                        Rectangle2D r=null;
436
                                        if (ova.getDriver() instanceof BoundedShapes) {
437
                                                r = ((BoundedShapes) ova.getDriver()).getShapeBounds(i);
438
                                        } else {
439
                                                IGeometry g = null;
440
                                                try {
441
                                                        g = ((DefaultFeature) ova.getFeature(i))
442
                                                                        .getGeometry();
443
                                                } catch (DriverException e1) {
444
                                                        e1.printStackTrace();
445
                                                }
446

    
447
                                                if (g == null) {
448
                                                        continue;
449
                                                }
450

    
451
                                                r = g.getBounds2D();
452
                                        }
453
                                        Envelope e = new Envelope(r.getX(),
454
                                                        r.getX() + r.getWidth(), r.getY(), r.getY()
455
                                                                        + r.getHeight());
456
                                        index.insert(e, new Integer(i));
457
                                        if (fullExtent == null) {
458
                                                fullExtent = r;
459
                                        } else {
460
                                                fullExtent = fullExtent.createUnion(r);
461
                                        }
462
                                }
463
                        }
464
                } catch (DriverIOException e) {
465
                        throw new EditionException(e);
466
                } catch (IOException e) {
467
                        throw new EditionException(e);
468
                }
469

    
470
                System.err.println("Se han metido en el ?ndice "
471
                                + index.queryAll().size() + " geometr?as");
472
        }
473

    
474
        /*
475
         * (non-Javadoc)
476
         *
477
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
478
         */
479
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
480
                int calculatedIndex = getCalculatedIndex(index);
481
                Integer integer = new Integer(calculatedIndex);
482
                // Si no est? en el fichero de expansi?n
483
                DefaultRowEdited edRow = null;
484
                if (!relations.containsKey(integer)) {
485
                        try {
486
                                edRow = new DefaultRowEdited(ova.getFeature(calculatedIndex),
487
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
488
                                return createExternalRow(edRow, 0);
489
                        } catch (DriverException e) {
490
                                e.printStackTrace();
491
                                throw new DriverIOException(e);
492
                        }
493

    
494
//                        return edRow;
495
                } else {
496
                        int num = ((Integer) relations.get(integer)).intValue();
497
                        IRowEdited aux = expansionFile.getRow(num);
498
                        edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux
499
                                        .getStatus(), index);
500

    
501
                        return edRow;
502
                }
503
        }
504

    
505
        /**
506
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
507
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
508
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
509
         * una futura compactaci?n termine con ella.
510
         *
511
         * @param index
512
         *            ?ndice de la geometr?a.
513
         *
514
         * @throws DriverIOException
515
         * @throws IOException
516
         */
517
        public IRow doRemoveRow(int index, int sourceType)
518
                        throws DriverIOException, IOException {
519
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
520
                if (cancel)
521
                        return null;
522
                // Llega el calculatedIndex
523
                Integer integer = new Integer(index);
524

    
525
                IFeature feat = null;
526
                delRows.set(index, true);
527
                // Si la geometr?a no ha sido modificada
528
                if (!relations.containsKey(integer)) {
529

    
530
                        try {
531
                                feat = (DefaultFeature) (ova.getFeature(index));
532
                        } catch (DriverException e) {
533
                                // TODO Auto-generated catch block
534
                                e.printStackTrace();
535
                        }
536
                } else {
537
                        int num = ((Integer) relations.get(integer)).intValue();
538
                        feat = (IFeature) expansionFile.getRow(num).getLinkedRow();
539
                        // expansionFile.invalidateRow(num);
540
                }
541
                System.err.println("Elimina una Row en la posici?n: " + index);
542
                // Se actualiza el ?ndice
543
                if (feat != null) {
544
                        Rectangle2D r = feat.getGeometry().getBounds2D();
545
                        boolean borrado = this.index.remove(new Envelope(r.getX(), r.getX()
546
                                        + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
547
                                        new Integer(index));
548
                        System.out.println("Est? borrado : " + borrado);
549
                        System.out.println("Index.lenght : " + this.index.size());
550
                        isFullExtentDirty = true;
551
                }
552
                setSelection(new FBitSet());
553
                fireAfterRemoveRow(index, sourceType);
554
                return feat;
555
        }
556

    
557
        /**
558
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
559
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
560
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
561
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
562
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
563
         * fichero.
564
         *
565
         * @param calculatedIndex
566
         *            DOCUMENT ME!
567
         * @param feat
568
         *            DOCUMENT ME!
569
         *
570
         * @return position inside ExpansionFile
571
         *
572
         * @throws IOException
573
         * @throws DriverIOException
574
         */
575
        public int doModifyRow(int calculatedIndex, IRow feat, int sourceType)
576
                        throws IOException, DriverIOException {
577
                boolean cancel = fireBeforeModifyRow(feat, calculatedIndex, sourceType);
578
                if (cancel)
579
                        return -1;
580
                int posAnteriorInExpansionFile = -1;
581
                Integer integer = new Integer(calculatedIndex);
582

    
583
                IFeature featAnt = null;
584
//                System.err.println("Modifica una Row en la posici?n: "
585
//                                + calculatedIndex);
586
                // Si la geometr?a no ha sido modificada
587
                if (!relations.containsKey(integer)) {
588
                        int newPosition = expansionFile.addRow(feat,
589
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
590
                        relations.put(integer, new Integer(newPosition));
591

    
592
                        if (sourceType == EditionEvent.GRAPHIC) {
593
                                // Se actualiza el ?ndice espacial
594
                                try {
595
                                        featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
596
                                } catch (DriverException e) {
597
                                        e.printStackTrace();
598
                                }
599
                                IGeometry g = featAnt.getGeometry();
600
                                Rectangle2D rAnt = g.getBounds2D();
601
                                Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
602
                                this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
603
                                                + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
604
                                                + rAnt.getHeight()), new Integer(calculatedIndex));
605
                                this.index.insert(new Envelope(r.getX(), r.getX()
606
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
607
                                                new Integer(calculatedIndex));
608
                        }
609
                } else {
610
                        // Obtenemos el ?ndice en el fichero de expansi?n
611
                        int num = ((Integer) relations.get(integer)).intValue();
612
                        posAnteriorInExpansionFile = num;
613

    
614
                        // Obtenemos la geometr?a para actualiza el ?ndice
615
                        // espacialposteriormente
616
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
617

    
618
                        /*
619
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
620
                         * fichero de expansi?n en el que se encuentra la geometr?a
621
                         * modificada
622
                         */
623
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
624

    
625
                        /*
626
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
627
                         * fichero de expansi?n.
628
                         */
629
                        relations.put(integer, new Integer(num));
630
                        if (sourceType == EditionEvent.GRAPHIC) {
631
                                // Se modifica el ?ndice espacial
632
                                Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
633
                                Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
634
                                this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
635
                                                + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
636
                                                + rAnt.getHeight()), new Integer(calculatedIndex));
637
                                this.index.insert(new Envelope(r.getX(), r.getX()
638
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
639
                                                new Integer(calculatedIndex));
640
                        }
641
                }
642
                isFullExtentDirty = true;
643
                fireAfterModifyRow(calculatedIndex, sourceType);
644
                return posAnteriorInExpansionFile;
645
        }
646

    
647
        /**
648
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
649
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
650
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
651
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
652
         * expansion file a justo despues de la penultima geometr?a
653
         *
654
         * @param calculatedIndex
655
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
656
         * @param previousExpansionFileIndex
657
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
658
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
659
         *            original y por tanto no hay que actualizar el mapa de indices
660
         *            sino eliminar su entrada.
661
         *
662
         * @throws IOException
663
         * @throws DriverIOException
664
         */
665
        public void undoModifyRow(int calculatedIndex,
666
                        int previousExpansionFileIndex, int sourceType) throws IOException,
667
                        DriverIOException {
668

    
669
                // Llega el CalculatedIndex
670
                /*
671
                 * Si la acci?n de modificar se realiz? sobre una geometr?a original
672
                 */
673
                if (previousExpansionFileIndex == -1) {
674

    
675
                        // Se obtiene la geometr?a para actualizar el ?ndice
676
                        // IGeometry g = ((DefaultFeature)
677
                        // getRow(calculatedIndex).getLinkedRow()).getGeometry();
678
                        int inverse = getInversedIndex(calculatedIndex);
679
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
680
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
681
                                        sourceType);
682
                        if (cancel)
683
                                return;
684
                        IGeometry g = df.getGeometry();
685
                        // IGeometry g = ova.getShape(calculatedIndex);
686
                        Rectangle2D r = g.getBounds2D();
687

    
688
                        // Se elimina de las relaciones y del fichero de expansi?n
689
                        relations.remove(new Integer(calculatedIndex));
690
                        expansionFile.deleteLastRow();
691

    
692
                        // Se actualizan los ?ndices
693
                        IGeometry gAnt = ova.getShape(calculatedIndex);
694
                        /*
695
                         * IGeometry gAnt = ((DefaultFeature) getRow(calculatedIndex)
696
                         * .getLinkedRow()).getGeometry();
697
                         */
698
                        Rectangle2D rAnt = gAnt.getBounds2D();
699
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
700
                                        .getY(), r.getY() + r.getHeight()), new Integer(
701
                                        calculatedIndex));
702
                        this.index.insert(new Envelope(rAnt.getX(), rAnt.getX()
703
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
704
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
705
                } else {
706
                        // Se obtiene la geometr?a para actualizar el ?ndice
707
                        IGeometry g = null;
708
                        int inverse = getInversedIndex(calculatedIndex);
709
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
710
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
711
                                        sourceType);
712
                        if (cancel)
713
                                return;
714
                        g = df.getGeometry();
715
                        System.out.println("Actual: " + g.toString());
716

    
717
                        Rectangle2D r = g.getBounds2D();
718
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
719
                                        .getY(), r.getY() + r.getHeight()), new Integer(
720
                                        calculatedIndex));
721

    
722
                        // Se actualiza la relaci?n de ?ndices
723
                        // Integer integer = new Integer(geometryIndex);
724
                        relations.put(new Integer(calculatedIndex), new Integer(
725
                                        previousExpansionFileIndex));
726

    
727
                        // Se recupera la geometr?a
728
                        // expansionFile.validateRow(previousExpansionFileIndex);
729

    
730
                        // Se actualizan los ?ndices
731
                        // g = ((IFeature)
732
                        // (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
733
                        // System.out.println("Anterior a la que volvemos : " +
734
                        // g.toString());
735
                        g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
736
                        r = g.getBounds2D();
737
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
738
                                        .getY(), r.getY() + r.getHeight()), new Integer(
739
                                        calculatedIndex));
740

    
741
                }
742
                fireAfterModifyRow(calculatedIndex, sourceType);
743
        }
744

    
745
        /**
746
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
747
         * en la tabla relations.
748
         *
749
         * @param feat
750
         *            geometr?a a guardar.
751
         *
752
         * @return calculatedIndex
753
         *
754
         * @throws DriverIOException
755
         * @throws IOException
756
         */
757
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException,
758
                        IOException {
759
                int calculatedIndex = super.doAddRow(feat, sourceType);
760
                // Actualiza el ?ndice espacial
761
                IGeometry g = ((IFeature) feat).getGeometry();
762
                Rectangle2D r = g.getBounds2D();
763
                index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
764
                                r.getY() + r.getHeight()), new Integer(calculatedIndex));
765
                isFullExtentDirty = true;
766
                return calculatedIndex;
767
        }
768

    
769
        /**
770
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
771
         * en el fichero original
772
         *
773
         * @param index
774
         *            DOCUMENT ME!
775
         *
776
         * @throws IOException
777
         * @throws DriverIOException
778
         */
779
        public void undoRemoveRow(int index, int sourceType) throws IOException,
780
                        DriverIOException {
781
                super.undoRemoveRow(index, sourceType);
782

    
783
                IGeometry g = null;
784
                g = ((IFeature) getRow(getInversedIndex(index)).getLinkedRow()).getGeometry();
785

    
786
                Rectangle2D r = g.getBounds2D();
787
                this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
788
                                .getY(), r.getY() + r.getHeight()), new Integer(index));
789
        }
790

    
791
        /**
792
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
793
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
794
         * relaci?n del mapa de relaciones
795
         *
796
         * @param index
797
         *            ?ndice de la geometr?a que se a?adi?
798
         *
799
         * @throws DriverIOException
800
         * @throws IOException
801
         */
802
        public void undoAddRow(int calculatedIndex, int sourceType)
803
                        throws DriverIOException, IOException {
804
                int inverse = getInversedIndex(calculatedIndex);
805
                IGeometry g = ((IFeature) getRow(inverse).getLinkedRow()).getGeometry();
806
                Rectangle2D r = g.getBounds2D();
807
                this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
808
                                .getY(), r.getY() + r.getHeight()),
809
                                new Integer(calculatedIndex));
810

    
811
                super.undoAddRow(calculatedIndex, sourceType);
812
                setSelection(new FBitSet());
813
        }
814

    
815
        /**
816
         * Obtiene las geometr?as que se encuentran en el rect?ngulo que se pasa
817
         * como par?metro haciendo uso del ?ndice espacial
818
         *
819
         * @param r
820
         *            Rect?ngulo indicando la porci?n del espacio para el cual se
821
         *            quiere saber los ?ndices de las geometr?as que se encuentran
822
         *            dentro de ?l
823
         *
824
         * @return Array de ?ndices para su uso con getGeometry, removeGeometry, ...
825
         */
826
        /*
827
         * public int[] getRowsIndexes_OL(Rectangle2D r) { Envelope e = new
828
         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
829
         * r.getHeight()); List l = index.query(e); int[] indexes = new
830
         * int[l.size()];
831
         *
832
         * for (int index = 0; index < l.size(); index++) { Integer i = (Integer)
833
         * l.get(index); indexes[index] = getInversedIndex(i.intValue()); }
834
         *
835
         * return indexes; }
836
         */
837
        /**
838
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
839
         */
840
        public int getShapeCount() throws DriverIOException {
841
                try {
842
                        return getRowCount();
843
                } catch (IOException e) {
844
                        throw new DriverIOException(e);
845
                }
846
        }
847

    
848
        /**
849
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
850
         */
851
        public Rectangle2D getFullExtent() throws DriverIOException {
852
                if (fullExtent == null) {
853
                        fullExtent = ova.getFullExtent();
854
                }
855

    
856
                if (isFullExtentDirty) {
857
                        fullExtent = reCalculateFullExtent();
858
                        isFullExtentDirty = false;
859
                }
860
                return fullExtent;
861
        }
862

    
863
        /**
864
         * Use it BEFORE writing to a file.
865
         *
866
         * @return real full extent.
867
         * @throws DriverIOException
868
         */
869
        public Rectangle2D reCalculateFullExtent() throws DriverIOException {
870
                if (getShapeCount() > 0) {
871
                        fullExtent = getShape(0).getBounds2D();
872
                        for (int i = 1; i < getShapeCount(); i++) {
873
                                fullExtent.add(getShape(i).getBounds2D());
874
                        }
875
                } else {
876
                        fullExtent = ova.getFullExtent();
877
                }
878
                return fullExtent;
879
        }
880

    
881
        /**
882
         * En la implementaci?n por defecto podemos hacer que cada feature tenga ID =
883
         * numero de registro. En el DBAdapter podr?amos "overrride" este m?todo y
884
         * poner como ID de la Feature el campo ?nico escogido en la base de datos.
885
         *
886
         * @param numReg
887
         * @return
888
         * @throws DriverException
889
         */
890
        public IFeature getFeature(int numReg) throws DriverException {
891
                IGeometry geom;
892
                IFeature feat = null;
893
                try {
894
                        geom = getShape(numReg);
895
                        DataSource rs = getRecordset();
896
                        Value[] regAtt = new Value[rs.getFieldCount()];
897
                        for (int fieldId = 0; fieldId < rs.getFieldCount(); fieldId++) {
898
                                regAtt[fieldId] = rs.getFieldValue(numReg, fieldId);
899
                        }
900
                        feat = new DefaultFeature(geom, regAtt, numReg + "");
901
                } catch (DriverIOException e) {
902
                        DriverIOExceptionType type =
903
                                new DriverIOExceptionType();
904
                        type.setDriverName(this.getDriver().getName());
905
                        throw new DriverException(e, type);
906

    
907
                } catch (DriverLoadException e) {
908
                        DriverNotLoadedExceptionType type =
909
                                new DriverNotLoadedExceptionType();
910
                        type.setDriverName(getDriver().getName());
911
                        throw new DriverException(e, type);
912

    
913

    
914
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
915

    
916
                        throw new DriverException(e);
917
                }
918
                return feat;
919
        }
920

    
921
        public void stopEdition(IWriter writer, int sourceType)
922
                        throws EditionException {
923
//                ISpatialWriter spatialWriter = (ISpatialWriter) writer;
924
//                spatialWriter.setFlatness(FConverter.flatness);
925
                super.stopEdition(writer, sourceType);
926
                try {
927
                        ova.getDriver().reload();
928
                } catch (IOException e) {
929
                        e.printStackTrace();
930
                        throw new EditionException(e);
931
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
932
                        e.printStackTrace();
933
                        throw new EditionException(e);
934
                }
935
                index=null;
936
                writer=null;
937
        }
938

    
939
        public Rectangle2D getShapeBounds(int index) throws IOException {
940
                // Solo se utiliza cuando el driver es BoundedShapes
941
                // Si no est? en el fichero de expansi?n
942
                Integer integer = new Integer((int) index);
943
                if (!relations.containsKey(integer)) {
944
                        if (ova.getDriver() instanceof BoundedShapes) {
945
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
946
                                return bs.getShapeBounds(index);
947
                        } else {
948
                                return ova.getDriver().getShape(index).getBounds2D();
949
                        }
950

    
951
                } else {
952
                        int num = ((Integer) relations.get(integer)).intValue();
953
                        DefaultRowEdited feat;
954
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
955
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
956
                                return null;
957
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
958
                        return geom.getBounds2D();// getGeometry();
959
                }
960

    
961
        }
962

    
963
        public int getShapeType(int index) {
964
                try {
965
                        return ova.getShapeType();
966
                } catch (DriverIOException e) {
967
                        // TODO Auto-generated catch block
968
                        e.printStackTrace();
969
                }
970
                return FShape.MULTI;
971
        }
972

    
973
        /**
974
         * Usar solo cuando est?s seguro de que puedes gastar memoria. Nosotros lo
975
         * usamos para las b?squedas por ?ndice espacial con el handle. La idea es
976
         * usarlo una vez, guardar las geometr?as que necesitas en ese extent y
977
         * trabajar con ellas hasta el siguiente cambio de extent.
978
         *
979
         * @param r
980
         * @param strEPSG
981
         * @return
982
         * @throws DriverException
983
         */
984
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG)
985
                        throws DriverException {
986
                // En esta clase suponemos random access.
987
                // Luego tendremos otra clase que sea VectorialEditableDBAdapter
988
                // que reescribir? este m?todo.
989
                Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
990
                List l = index.query(e);
991
                IRowEdited[] feats = new IRowEdited[l.size()];
992
                try {
993
                        for (int index = 0; index < l.size(); index++) {
994
                                Integer i = (Integer) l.get(index);
995
                                int inverse = getInversedIndex(i.intValue());
996
                                feats[index] = (IRowEdited) getRow(inverse);
997
                        }
998
                } catch (IOException ex) {
999
                        DriverIOExceptionType type =
1000
                                new DriverIOExceptionType();
1001
                        type.setDriverName(this.getDriver().getName());
1002
                        throw new DriverException(ex, type);
1003

    
1004
                } catch (DriverLoadException ex) {
1005
                        DriverNotLoadedExceptionType type =
1006
                                new DriverNotLoadedExceptionType();
1007
                        type.setDriverName(getDriver().getName());
1008
                        throw new DriverException(ex, type);
1009
                } catch (DriverIOException ex) {
1010
                        DriverIOExceptionType type =
1011
                                new DriverIOExceptionType();
1012
                        type.setDriverName(this.getDriver().getName());
1013
                        throw new DriverException(ex, type);
1014
                }
1015
                return feats;
1016
        }
1017

    
1018
        public void setSpatialIndex(SpatialIndex spatialIndex) {
1019
                index = (Quadtree) spatialIndex;
1020
        }
1021

    
1022
        public void setFullExtent(Rectangle2D fullExtent2) {
1023
                fullExtent = fullExtent2;
1024
        }
1025

    
1026
        /**
1027
         * DOCUMENT ME!
1028
         *
1029
         * @return DOCUMENT ME!
1030
         */
1031
        public Image getSelectionImage() {
1032
                return selectionImage;
1033
        }
1034

    
1035
        public Image getHandlersImage() {
1036
                return handlersImage;
1037
        }
1038

    
1039
        /**
1040
         * DOCUMENT ME!
1041
         *
1042
         * @param i
1043
         *            DOCUMENT ME!
1044
         */
1045
        public void setSelectionImage(Image i) {
1046
                selectionImage = i;
1047
        }
1048

    
1049
        public void setHandlersImage(BufferedImage handlersImage) {
1050
                this.handlersImage = handlersImage;
1051
        }
1052

    
1053
        public void cancelEdition(int sourceType) throws IOException {
1054
                super.cancelEdition(sourceType);
1055
                index=null;
1056
                setWriter(null);
1057
                System.gc();
1058
        }
1059

    
1060
//        public double getFlatness() {
1061
//                return flatness;
1062
//        }
1063
//
1064
//        public void setFlatness(double d) {
1065
//                flatness=d;
1066
//        }
1067

    
1068
}