Statistics
| Revision:

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

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

    
244
import java.awt.Image;
245
import java.awt.geom.Rectangle2D;
246
import java.awt.image.BufferedImage;
247
import java.io.IOException;
248
import java.util.List;
249

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

    
273
/**
274
 * @author fjp
275
 *
276
 */
277
public class VectorialEditableAdapter extends EditableAdapter implements
278
                ReadableVectorial, BoundedShapes {
279
        protected ReadableVectorial ova;
280

    
281
        protected Quadtree index;
282

    
283
        protected Rectangle2D fullExtent;
284

    
285
        protected Image selectionImage;
286

    
287
        protected BufferedImage handlersImage;
288

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

    
308
        public VectorialEditableAdapter() {
309
                super();
310
        }
311

    
312
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
313
                ova = rv;
314
                try {
315
                        setOriginalDataSource(rv.getRecordset());
316
                } catch (DriverLoadException e) {
317
                        e.printStackTrace();
318
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
319
                        // TODO Auto-generated catch block
320
                        e.printStackTrace();
321
                }
322
        }
323

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

    
333
        public IWriter getWriter() {
334
                if (ova.getDriver() instanceof IWriteable)
335
                {
336
                        IWriter writer = ((IWriteable) ova.getDriver()).getWriter();
337
                        if (writer instanceof ISpatialWriter)
338
                                return writer;
339
                }
340
                return null;
341
        }
342

    
343
        /*
344
         * (non-Javadoc)
345
         *
346
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#stop()
347
         */
348
        public void stop() throws DriverIOException {
349
                ova.stop();
350
        }
351

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

    
381
        }
382

    
383
        /*
384
         * (non-Javadoc)
385
         *
386
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
387
         */
388
        public int getShapeType() throws DriverIOException {
389
                return ova.getShapeType();
390
        }
391

    
392
        public ReadableVectorial getOriginalAdapter() {
393
                return ova;
394
        }
395

    
396
        public VectorialDriver getDriver() {
397
                return ova.getDriver();
398
        }
399

    
400
        public void setDriver(VectorialDriver driver) {
401
                this.ova.setDriver(driver);
402
        }
403

    
404
        public DriverAttributes getDriverAttributes() {
405
                return ova.getDriverAttributes();
406
        }
407

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

    
422

    
423
                try {
424
                        expansionFile.open();
425
                        if (index == null || fullExtent == null) {
426
                                // TODO: Si la capa dispone de un ?ndice espacial, hacer
427
                                // algo aqu? para que se use ese ?ndice espacial.
428
                                index = new Quadtree();
429

    
430
                                for (int i = 0; i < ova.getShapeCount(); i++) {
431
                                        IGeometry g = null;
432
                                        try {
433
                                                g = ((DefaultFeature) ova.getFeature(i)).getGeometry();
434
                                        } catch (DriverException e1) {
435
                                                // TODO Auto-generated catch block
436
                                                e1.printStackTrace();
437
                                        }
438

    
439
                                        if (g == null) {
440
                                                continue;
441
                                        }
442

    
443
                                        Rectangle2D r = g.getBounds2D();
444
                                        Envelope e = new Envelope(r.getX(),
445
                                                        r.getX() + r.getWidth(), r.getY(), r.getY()
446
                                                                        + r.getHeight());
447
                                        index.insert(e, new Integer(i));
448
                                        if (fullExtent == null) {
449
                                                fullExtent = r;
450
                                        } else {
451
                                                fullExtent = fullExtent.createUnion(r);
452
                                        }
453
                                }
454
                        }
455
                } catch (DriverIOException e) {
456
                        throw new EditionException(e);
457
                } catch (IOException e) {
458
                        throw new EditionException(e);
459
                }
460

    
461
                System.err.println("Se han metido en el ?ndice "
462
                                + index.queryAll().size() + " geometr?as");
463
        }
464

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

    
485
//                        return edRow;
486
                } else {
487
                        int num = ((Integer) relations.get(integer)).intValue();
488
                        IRowEdited aux = expansionFile.getRow(num);
489
                        edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux
490
                                        .getStatus(), index);
491

    
492
                        return edRow;
493
                }
494
        }
495

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

    
516
                IFeature feat = null;
517
                delRows.set(index, true);
518
                // Si la geometr?a no ha sido modificada
519
                if (!relations.containsKey(integer)) {
520

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

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

    
574
                IFeature featAnt = null;
575
//                System.err.println("Modifica una Row en la posici?n: "
576
//                                + calculatedIndex);
577
                // Si la geometr?a no ha sido modificada
578
                if (!relations.containsKey(integer)) {
579
                        int newPosition = expansionFile.addRow(feat,
580
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
581
                        relations.put(integer, new Integer(newPosition));
582

    
583
                        if (sourceType == EditionEvent.GRAPHIC) {
584
                                // Se actualiza el ?ndice espacial
585
                                try {
586
                                        featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
587
                                } catch (DriverException e) {
588
                                        e.printStackTrace();
589
                                }
590
                                IGeometry g = featAnt.getGeometry();
591
                                Rectangle2D rAnt = g.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()
597
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
598
                                                new Integer(calculatedIndex));
599
                        }
600
                } else {
601
                        // Obtenemos el ?ndice en el fichero de expansi?n
602
                        int num = ((Integer) relations.get(integer)).intValue();
603
                        posAnteriorInExpansionFile = num;
604

    
605
                        // Obtenemos la geometr?a para actualiza el ?ndice
606
                        // espacialposteriormente
607
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
608

    
609
                        /*
610
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
611
                         * fichero de expansi?n en el que se encuentra la geometr?a
612
                         * modificada
613
                         */
614
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
615

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

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

    
660
                // Llega el CalculatedIndex
661
                /*
662
                 * Si la acci?n de modificar se realiz? sobre una geometr?a original
663
                 */
664
                if (previousExpansionFileIndex == -1) {
665

    
666
                        // Se obtiene la geometr?a para actualizar el ?ndice
667
                        // IGeometry g = ((DefaultFeature)
668
                        // getRow(calculatedIndex).getLinkedRow()).getGeometry();
669
                        int inverse = getInversedIndex(calculatedIndex);
670
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
671
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
672
                                        sourceType);
673
                        if (cancel)
674
                                return;
675
                        IGeometry g = df.getGeometry();
676
                        // IGeometry g = ova.getShape(calculatedIndex);
677
                        Rectangle2D r = g.getBounds2D();
678

    
679
                        // Se elimina de las relaciones y del fichero de expansi?n
680
                        relations.remove(new Integer(calculatedIndex));
681
                        expansionFile.deleteLastRow();
682

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

    
708
                        Rectangle2D r = g.getBounds2D();
709
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
710
                                        .getY(), r.getY() + r.getHeight()), new Integer(
711
                                        calculatedIndex));
712

    
713
                        // Se actualiza la relaci?n de ?ndices
714
                        // Integer integer = new Integer(geometryIndex);
715
                        relations.put(new Integer(calculatedIndex), new Integer(
716
                                        previousExpansionFileIndex));
717

    
718
                        // Se recupera la geometr?a
719
                        // expansionFile.validateRow(previousExpansionFileIndex);
720

    
721
                        // Se actualizan los ?ndices
722
                        // g = ((IFeature)
723
                        // (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
724
                        // System.out.println("Anterior a la que volvemos : " +
725
                        // g.toString());
726
                        g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
727
                        r = g.getBounds2D();
728
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
729
                                        .getY(), r.getY() + r.getHeight()), new Integer(
730
                                        calculatedIndex));
731

    
732
                }
733
                fireAfterModifyRow(calculatedIndex, sourceType);
734
        }
735

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

    
760
        /**
761
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
762
         * en el fichero original
763
         *
764
         * @param index
765
         *            DOCUMENT ME!
766
         *
767
         * @throws IOException
768
         * @throws DriverIOException
769
         */
770
        public void undoRemoveRow(int index, int sourceType) throws IOException,
771
                        DriverIOException {
772
                super.undoRemoveRow(index, sourceType);
773

    
774
                IGeometry g = null;
775
                g = ((IFeature) getRow(getInversedIndex(index)).getLinkedRow()).getGeometry();
776

    
777
                Rectangle2D r = g.getBounds2D();
778
                this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
779
                                .getY(), r.getY() + r.getHeight()), new Integer(index));
780
        }
781

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

    
802
                super.undoAddRow(calculatedIndex, sourceType);
803
                setSelection(new FBitSet());
804
        }
805

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

    
839
        /**
840
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
841
         */
842
        public Rectangle2D getFullExtent() throws DriverIOException {
843
                if (fullExtent == null) {
844
                        fullExtent = ova.getFullExtent();
845
                }
846

    
847
                if (isFullExtentDirty) {
848
                        fullExtent = reCalculateFullExtent();
849
                        isFullExtentDirty = false;
850
                }
851
                return fullExtent;
852
        }
853

    
854
        /**
855
         * Use it BEFORE writing to a file.
856
         *
857
         * @return real full extent.
858
         * @throws DriverIOException
859
         */
860
        public Rectangle2D reCalculateFullExtent() throws DriverIOException {
861
                if (getShapeCount() > 0) {
862
                        fullExtent = getShape(0).getBounds2D();
863
                        for (int i = 1; i < getShapeCount(); i++) {
864
                                fullExtent.add(getShape(i).getBounds2D());
865
                        }
866
                } else {
867
                        fullExtent = ova.getFullExtent();
868
                }
869
                return fullExtent;
870
        }
871

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

    
898
                } catch (DriverLoadException e) {
899
                        DriverNotLoadedExceptionType type =
900
                                new DriverNotLoadedExceptionType();
901
                        type.setDriverName(getDriver().getName());
902
                        throw new DriverException(e, type);
903

    
904

    
905
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
906

    
907
                        throw new DriverException(e);
908
                }
909
                return feat;
910
        }
911

    
912
        public void stopEdition(IWriter writer, int sourceType)
913
                        throws EditionException {
914
                ISpatialWriter spatialWriter = (ISpatialWriter) writer;
915
//                spatialWriter.setFlatness(FConverter.flatness);
916
                super.stopEdition(writer, sourceType);
917
                try {
918
                        ova.getDriver().reload();
919
                } catch (IOException e) {
920
                        e.printStackTrace();
921
                        throw new EditionException(e);
922
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
923
                        e.printStackTrace();
924
                        throw new EditionException(e);
925
                }
926
        }
927

    
928
        public Rectangle2D getShapeBounds(int index) throws IOException {
929
                // Solo se utiliza cuando el driver es BoundedShapes
930
                // Si no est? en el fichero de expansi?n
931
                Integer integer = new Integer((int) index);
932
                if (!relations.containsKey(integer)) {
933
                        if (ova.getDriver() instanceof BoundedShapes) {
934
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
935
                                return bs.getShapeBounds(index);
936
                        } else {
937
                                return ova.getDriver().getShape(index).getBounds2D();
938
                        }
939

    
940
                } else {
941
                        int num = ((Integer) relations.get(integer)).intValue();
942
                        DefaultRowEdited feat;
943
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
944
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
945
                                return null;
946
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
947
                        return geom.getBounds2D();// getGeometry();
948
                }
949

    
950
        }
951

    
952
        public int getShapeType(int index) {
953
                try {
954
                        return ova.getShapeType();
955
                } catch (DriverIOException e) {
956
                        // TODO Auto-generated catch block
957
                        e.printStackTrace();
958
                }
959
                return FShape.MULTI;
960
        }
961

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

    
993
                } catch (DriverLoadException ex) {
994
                        DriverNotLoadedExceptionType type =
995
                                new DriverNotLoadedExceptionType();
996
                        type.setDriverName(getDriver().getName());
997
                        throw new DriverException(ex, type);
998
                } catch (DriverIOException ex) {
999
                        DriverIOExceptionType type =
1000
                                new DriverIOExceptionType();
1001
                        type.setDriverName(this.getDriver().getName());
1002
                        throw new DriverException(ex, type);
1003
                }
1004
                return feats;
1005
        }
1006

    
1007
        public void setSpatialIndex(SpatialIndex spatialIndex) {
1008
                index = (Quadtree) spatialIndex;
1009
        }
1010

    
1011
        public void setFullExtent(Rectangle2D fullExtent2) {
1012
                fullExtent = fullExtent2;
1013
        }
1014

    
1015
        /**
1016
         * DOCUMENT ME!
1017
         *
1018
         * @return DOCUMENT ME!
1019
         */
1020
        public Image getSelectionImage() {
1021
                return selectionImage;
1022
        }
1023

    
1024
        public Image getHandlersImage() {
1025
                return handlersImage;
1026
        }
1027

    
1028
        /**
1029
         * DOCUMENT ME!
1030
         *
1031
         * @param i
1032
         *            DOCUMENT ME!
1033
         */
1034
        public void setSelectionImage(Image i) {
1035
                selectionImage = i;
1036
        }
1037

    
1038
        public void setHandlersImage(BufferedImage handlersImage) {
1039
                this.handlersImage = handlersImage;
1040
        }
1041

    
1042
//        public double getFlatness() {
1043
//                return flatness;
1044
//        }
1045
//
1046
//        public void setFlatness(double d) {
1047
//                flatness=d;
1048
//        }
1049

    
1050
}