Statistics
| Revision:

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

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

    
217
import java.awt.Image;
218
import java.awt.geom.Rectangle2D;
219
import java.awt.image.BufferedImage;
220
import java.io.IOException;
221
import java.util.List;
222

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

    
244
/**
245
 * @author fjp
246
 *
247
 */
248
public class VectorialEditableAdapter extends EditableAdapter implements
249
                ReadableVectorial, BoundedShapes {
250
        protected ReadableVectorial ova;
251

    
252
        protected Quadtree index;
253

    
254
        protected Rectangle2D fullExtent;
255

    
256
        protected Image selectionImage;
257

    
258
        protected BufferedImage handlersImage;
259

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

    
279
        public VectorialEditableAdapter() {
280
                super();
281
        }
282

    
283
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
284
                ova = rv;
285
                try {
286
                        setOriginalDataSource(rv.getRecordset());
287
                } catch (DriverLoadException e) {
288
                        e.printStackTrace();
289
                }
290
        }
291

    
292
        /*
293
         * (non-Javadoc)
294
         *
295
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#start()
296
         */
297
        public void start() throws DriverIOException {
298
                ova.start();
299
        }
300

    
301
        public IWriter getWriter() {
302
                if (ova.getDriver() instanceof IWriteable)
303
                {
304
                        IWriter writer = ((IWriteable) ova.getDriver()).getWriter();
305
                        if (writer instanceof ISpatialWriter)
306
                                return writer;
307
                }
308
                return null;
309
        }
310

    
311
        /*
312
         * (non-Javadoc)
313
         *
314
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#stop()
315
         */
316
        public void stop() throws DriverIOException {
317
                ova.stop();
318
        }
319

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

    
349
        }
350

    
351
        /*
352
         * (non-Javadoc)
353
         *
354
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
355
         */
356
        public int getShapeType() throws DriverIOException {
357
                return ova.getShapeType();
358
        }
359

    
360
        public ReadableVectorial getOriginalAdapter() {
361
                return ova;
362
        }
363

    
364
        public VectorialDriver getDriver() {
365
                return ova.getDriver();
366
        }
367

    
368
        public void setDriver(VectorialDriver driver) {
369
                this.ova.setDriver(driver);
370
        }
371

    
372
        public DriverAttributes getDriverAttributes() {
373
                return ova.getDriverAttributes();
374
        }
375

    
376
        /**
377
         * DOCUMENT ME!
378
         *
379
         * @throws EditionException
380
         *             DOCUMENT ME!
381
         */
382
        public void startEdition(int sourceType) throws EditionException {
383
                super.startEdition(sourceType);
384
                Driver drv = ova.getDriver();
385
                if (drv instanceof IWriteable)
386
                {
387
                        setWriter(((IWriteable) drv).getWriter());
388
                }
389

    
390

    
391
                try {
392
                        expansionFile.open();
393
                        if (index == null || fullExtent == null) {
394
                                // TODO: Si la capa dispone de un ?ndice espacial, hacer
395
                                // algo aqu? para que se use ese ?ndice espacial.
396
                                index = new Quadtree();
397

    
398
                                for (int i = 0; i < ova.getShapeCount(); i++) {
399
                                        IGeometry g = null;
400
                                        try {
401
                                                g = ((DefaultFeature) ova.getFeature(i)).getGeometry();
402
                                        } catch (DriverException e1) {
403
                                                // TODO Auto-generated catch block
404
                                                e1.printStackTrace();
405
                                        }
406

    
407
                                        if (g == null) {
408
                                                continue;
409
                                        }
410

    
411
                                        Rectangle2D r = g.getBounds2D();
412
                                        Envelope e = new Envelope(r.getX(),
413
                                                        r.getX() + r.getWidth(), r.getY(), r.getY()
414
                                                                        + r.getHeight());
415
                                        index.insert(e, new Integer(i));
416
                                        if (fullExtent == null) {
417
                                                fullExtent = r;
418
                                        } else {
419
                                                fullExtent = fullExtent.createUnion(r);
420
                                        }
421
                                }
422
                        }
423
                } catch (DriverIOException e) {
424
                        throw new EditionException(e);
425
                } catch (IOException e) {
426
                        throw new EditionException(e);
427
                }
428

    
429
                System.err.println("Se han metido en el ?ndice "
430
                                + index.queryAll().size() + " geometr?as");
431
        }
432

    
433
        /*
434
         * (non-Javadoc)
435
         *
436
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
437
         */
438
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
439
                int calculatedIndex = getCalculatedIndex(index);
440
                Integer integer = new Integer(calculatedIndex);
441
                // Si no est? en el fichero de expansi?n
442
                DefaultRowEdited edRow = null;
443
                if (!relations.containsKey(integer)) {
444
                        try {
445
                                edRow = new DefaultRowEdited(ova.getFeature(calculatedIndex),
446
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
447
                                // /System.out.println("Piden la feature con ID= " + index);
448
                                /*
449
                                 * Exception e = new Exception(); e.printStackTrace();
450
                                 */
451
                        } catch (DriverException e) {
452
                                // TODO Auto-generated catch block
453
                                e.printStackTrace();
454
                        }
455

    
456
                        return edRow;
457
                } else {
458
                        int num = ((Integer) relations.get(integer)).intValue();
459
                        IRowEdited aux = expansionFile.getRow(num);
460
                        edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux
461
                                        .getStatus(), index);
462
                        return edRow;
463
                }
464
        }
465

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

    
486
                IFeature feat = null;
487
                delRows.set(index, true);
488
                // Si la geometr?a no ha sido modificada
489
                if (!relations.containsKey(integer)) {
490

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

    
512
                }
513
                setSelection(new FBitSet());
514
                fireAfterRemoveRow(index, sourceType);
515
                return feat;
516
        }
517

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

    
544
                IFeature featAnt = null;
545
                System.err.println("Modifica una Row en la posici?n: "
546
                                + calculatedIndex);
547
                // Si la geometr?a no ha sido modificada
548
                if (!relations.containsKey(integer)) {
549
                        int newPosition = expansionFile.addRow(feat,
550
                                        IRowEdited.STATUS_MODIFIED);
551
                        relations.put(integer, new Integer(newPosition));
552

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

    
573
                        // Obtenemos la geometr?a para actualiza el ?ndice
574
                        // espacialposteriormente
575
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
576

    
577
                        /*
578
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
579
                         * fichero de expansi?n en el que se encuentra la geometr?a
580
                         * modificada
581
                         */
582
                        num = expansionFile.modifyRow(num, feat);
583

    
584
                        /*
585
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
586
                         * fichero de expansi?n.
587
                         */
588
                        relations.put(integer, new Integer(num));
589

    
590
                        // Se modifica el ?ndice espacial
591
                        Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
592
                        Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
593
                        this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
594
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
595
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
596
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
597
                                        .getY(), r.getY() + r.getHeight()), new Integer(
598
                                        calculatedIndex));
599
                }
600
                fireAfterModifyRow(calculatedIndex, sourceType);
601
                return posAnteriorInExpansionFile;
602
        }
603

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

    
626
                // Llega el CalculatedIndex
627
                /*
628
                 * Si la acci?n de modificar se realiz? sobre una geometr?a original
629
                 */
630
                if (previousExpansionFileIndex == -1) {
631

    
632
                        // Se obtiene la geometr?a para actualizar el ?ndice
633
                        // IGeometry g = ((DefaultFeature)
634
                        // getRow(calculatedIndex).getLinkedRow()).getGeometry();
635
                        int inverse = getInversedIndex(calculatedIndex);
636
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
637
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
638
                                        sourceType);
639
                        if (cancel)
640
                                return;
641
                        IGeometry g = df.getGeometry();
642
                        // IGeometry g = ova.getShape(calculatedIndex);
643
                        Rectangle2D r = g.getBounds2D();
644

    
645
                        // Se elimina de las relaciones y del fichero de expansi?n
646
                        relations.remove(new Integer(calculatedIndex));
647
                        expansionFile.deleteLastRow();
648

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

    
674
                        Rectangle2D r = g.getBounds2D();
675
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
676
                                        .getY(), r.getY() + r.getHeight()), new Integer(
677
                                        calculatedIndex));
678

    
679
                        // Se actualiza la relaci?n de ?ndices
680
                        // Integer integer = new Integer(geometryIndex);
681
                        relations.put(new Integer(calculatedIndex), new Integer(
682
                                        previousExpansionFileIndex));
683

    
684
                        // Se recupera la geometr?a
685
                        // expansionFile.validateRow(previousExpansionFileIndex);
686

    
687
                        // Se actualizan los ?ndices
688
                        // g = ((IFeature)
689
                        // (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
690
                        // System.out.println("Anterior a la que volvemos : " +
691
                        // g.toString());
692
                        g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
693
                        r = g.getBounds2D();
694
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
695
                                        .getY(), r.getY() + r.getHeight()), new Integer(
696
                                        calculatedIndex));
697

    
698
                }
699
                fireAfterModifyRow(calculatedIndex, sourceType);
700
        }
701

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

    
723
                return calculatedIndex;
724
        }
725

    
726
        /**
727
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
728
         * en el fichero original
729
         *
730
         * @param index
731
         *            DOCUMENT ME!
732
         *
733
         * @throws IOException
734
         * @throws DriverIOException
735
         */
736
        public void undoRemoveRow(int index, int sourceType) throws IOException,
737
                        DriverIOException {
738
                super.undoRemoveRow(index, sourceType);
739

    
740
                IGeometry g = null;
741
                g = ((IFeature) getRow(getInversedIndex(index)).getLinkedRow()).getGeometry();
742

    
743
                Rectangle2D r = g.getBounds2D();
744
                this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
745
                                .getY(), r.getY() + r.getHeight()), new Integer(index));
746
        }
747

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

    
768
                super.undoAddRow(calculatedIndex, sourceType);
769
                setSelection(new FBitSet());
770
        }
771

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

    
805
        /**
806
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
807
         */
808
        public Rectangle2D getFullExtent() throws DriverIOException {
809
                if (fullExtent == null) {
810
                        fullExtent = ova.getFullExtent();
811
                }
812
                return fullExtent;
813
        }
814

    
815
        /**
816
         * Use it BEFORE writing to a file.
817
         *
818
         * @return real full extent.
819
         * @throws DriverIOException
820
         */
821
        public Rectangle2D reCalculateFullExtent() throws DriverIOException {
822
                if (getShapeCount() > 0) {
823
                        fullExtent = getShape(0).getBounds2D();
824
                        for (int i = 1; i < getShapeCount(); i++) {
825
                                fullExtent.add(getShape(i).getBounds2D());
826
                        }
827
                } else {
828
                        fullExtent = ova.getFullExtent();
829
                }
830
                return fullExtent;
831
        }
832

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

    
853
                        feat = new DefaultFeature(geom, regAtt, numReg + "");
854
                } catch (DriverIOException e) {
855
                        throw new DriverException(e);
856
                } catch (DriverLoadException e) {
857
                        throw new DriverException(e);
858
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
859
                        throw new DriverException(e);
860
                }
861
                return feat;
862
        }
863

    
864
        public void stopEdition(IWriter writer, int sourceType)
865
                        throws EditionException {
866
                ISpatialWriter spatialWriter = (ISpatialWriter) writer;
867
                spatialWriter.setFlatness(getFlatness());
868
                super.stopEdition(writer, sourceType);
869
                try {
870
                        ova.getDriver().reLoad();
871
                } catch (IOException e) {
872
                        e.printStackTrace();
873
                        throw new EditionException(e);
874
                }
875
        }
876

    
877
        public Rectangle2D getShapeBounds(int index) throws IOException {
878
                // Solo se utiliza cuando el driver es BoundedShapes
879
                // Si no est? en el fichero de expansi?n
880
                Integer integer = new Integer((int) index);
881
                if (!relations.containsKey(integer)) {
882
                        if (ova.getDriver() instanceof BoundedShapes) {
883
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
884
                                return bs.getShapeBounds(index);
885
                        } else {
886
                                return ova.getDriver().getShape(index).getBounds2D();
887
                        }
888

    
889
                } else {
890
                        int num = ((Integer) relations.get(integer)).intValue();
891
                        DefaultRowEdited feat;
892
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
893
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
894
                                return null;
895
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
896
                        return geom.getBounds2D();// getGeometry();
897
                }
898

    
899
        }
900

    
901
        public int getShapeType(int index) {
902
                try {
903
                        return ova.getShapeType();
904
                } catch (DriverIOException e) {
905
                        // TODO Auto-generated catch block
906
                        e.printStackTrace();
907
                }
908
                return FShape.MULTI;
909
        }
910

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

    
942
                return feats;
943
        }
944

    
945
        public void setSpatialIndex(SpatialIndex spatialIndex) {
946
                index = (Quadtree) spatialIndex;
947
        }
948

    
949
        public void setFullExtent(Rectangle2D fullExtent2) {
950
                fullExtent = fullExtent2;
951
        }
952

    
953
        /**
954
         * DOCUMENT ME!
955
         *
956
         * @return DOCUMENT ME!
957
         */
958
        public Image getSelectionImage() {
959
                return selectionImage;
960
        }
961

    
962
        public Image getHandlersImage() {
963
                return handlersImage;
964
        }
965

    
966
        /**
967
         * DOCUMENT ME!
968
         *
969
         * @param i
970
         *            DOCUMENT ME!
971
         */
972
        public void setSelectionImage(Image i) {
973
                selectionImage = i;
974
        }
975

    
976
        public void setHandlersImage(BufferedImage handlersImage) {
977
                this.handlersImage = handlersImage;
978
        }
979

    
980
        public double getFlatness() {
981
                return flatness;
982
        }
983

    
984
        public void setFlatness(double d) {
985
                flatness=d;
986
        }
987
}