Statistics
| Revision:

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

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

    
259
import java.awt.Image;
260
import java.awt.geom.Rectangle2D;
261
import java.awt.image.BufferedImage;
262
import java.io.IOException;
263
import java.util.List;
264

    
265
import org.cresques.cts.ICoordTrans;
266

    
267
import com.hardcode.driverManager.Driver;
268
import com.hardcode.driverManager.DriverLoadException;
269
import com.hardcode.gdbms.engine.data.DataSource;
270
import com.hardcode.gdbms.engine.values.Value;
271
import com.iver.cit.gvsig.fmap.DriverException;
272
import com.iver.cit.gvsig.fmap.DriverIOExceptionType;
273
import com.iver.cit.gvsig.fmap.DriverNotLoadedExceptionType;
274
import com.iver.cit.gvsig.fmap.core.DefaultFeature;
275
import com.iver.cit.gvsig.fmap.core.FNullGeometry;
276
import com.iver.cit.gvsig.fmap.core.FShape;
277
import com.iver.cit.gvsig.fmap.core.IFeature;
278
import com.iver.cit.gvsig.fmap.core.IGeometry;
279
import com.iver.cit.gvsig.fmap.core.IRow;
280
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
281
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
282
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
283
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
284
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
285
import com.iver.cit.gvsig.fmap.layers.FBitSet;
286
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
287
import com.vividsolutions.jts.geom.Envelope;
288
import com.vividsolutions.jts.index.SpatialIndex;
289
import com.vividsolutions.jts.index.quadtree.Quadtree;
290

    
291
/**
292
 * @author fjp
293
 *
294
 */
295
public class VectorialEditableAdapter extends EditableAdapter implements
296
                ReadableVectorial, BoundedShapes {
297
        protected ReadableVectorial ova;
298

    
299
        protected Quadtree index;
300

    
301
        protected Rectangle2D fullExtent;
302

    
303
        protected Image selectionImage;
304

    
305
        protected BufferedImage handlersImage;
306

    
307
        private ICoordTrans ct;
308

    
309
        //private double flatness=0.8;
310
        /*
311
         * private class MyFeatureIterator implements IFeatureIterator { int numReg =
312
         * 0; Rectangle2D rect; String epsg; IFeatureIterator origFeatIt; boolean
313
         * bHasNext = true;
314
         *
315
         * public MyFeatureIterator(Rectangle2D r, String strEPSG) throws
316
         * DriverException { rect = r; epsg = strEPSG; origFeatIt =
317
         * ova.getFeatureIterator(r, epsg); } public boolean hasNext() throws
318
         * DriverException { return bHasNext; }
319
         *
320
         * public IFeature next() throws DriverException { IFeature aux =
321
         * origFeatIt.next(); return null; }
322
         *
323
         * public void closeIterator() throws DriverException {
324
         *  }
325
         *  }
326
         */
327

    
328
        public VectorialEditableAdapter() {
329
                super();
330
        }
331

    
332
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
333
                ova = rv;
334
                try {
335
                        setOriginalDataSource(rv.getRecordset());
336
                } catch (DriverLoadException e) {
337
                        e.printStackTrace();
338
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
339
                        // TODO Auto-generated catch block
340
                        e.printStackTrace();
341
                }
342
        }
343

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

    
353
        public IWriter getWriter() {
354
                if (ova.getDriver() instanceof IWriteable)
355
                {
356
                        IWriter writer = ((IWriteable) ova.getDriver()).getWriter();
357
                        if (writer instanceof ISpatialWriter)
358
                                return writer;
359
                }
360
                return null;
361
        }
362

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

    
372
        /*
373
         * (non-Javadoc)
374
         *
375
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
376
         */
377
        public IGeometry getShape(int rowIndex) throws DriverIOException {
378
                // Si no est? en el fichero de expansi?n
379
                int calculatedIndex = getCalculatedIndex(rowIndex);
380
                Integer integer = new Integer(calculatedIndex);
381
                if (!relations.containsKey(integer)) {
382
                        // Si ha sido eliminada
383
                        /*
384
                         * if (delRows.get(integer.intValue())) { return null; } else {
385
                         */
386
                        return ova.getShape(calculatedIndex);
387
                        // }
388
                } else {
389
                        int num = ((Integer) relations.get(integer)).intValue();
390
                        DefaultRowEdited feat;
391
                        try {
392
                                feat = (DefaultRowEdited) expansionFile.getRow(num);
393
                                return ((IFeature) feat.getLinkedRow()).getGeometry()
394
                                                .cloneGeometry();// getGeometry();
395
                        } catch (IOException e) {
396
                                e.printStackTrace();
397
                                throw new DriverIOException(e);
398
                        }
399
                }
400

    
401
        }
402

    
403
        /*
404
         * (non-Javadoc)
405
         *
406
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
407
         */
408
        public int getShapeType() throws DriverIOException {
409
                return ova.getShapeType();
410
        }
411

    
412
        public ReadableVectorial getOriginalAdapter() {
413
                return ova;
414
        }
415

    
416
        public VectorialDriver getDriver() {
417
                return ova.getDriver();
418
        }
419

    
420
        public void setDriver(VectorialDriver driver) {
421
                this.ova.setDriver(driver);
422
        }
423

    
424
        public DriverAttributes getDriverAttributes() {
425
                return ova.getDriverAttributes();
426
        }
427
        /**
428
         * Inserta las coordenadas de transformaci?n.
429
         *
430
         * @param ct Coordenadas de transformaci?n.
431
         */
432
        public void setCoordTrans(ICoordTrans ct) {
433
                this.ct=ct;
434
        }
435

    
436
        /**
437
         * DOCUMENT ME!
438
         *
439
         * @throws EditionException
440
         *             DOCUMENT ME!
441
         */
442
        public void startEdition(int sourceType) throws EditionException {
443
                super.startEdition(sourceType);
444
                Driver drv = ova.getDriver();
445
                if (drv instanceof IWriteable)
446
                {
447
                        setWriter(((IWriteable) drv).getWriter());
448
                }
449

    
450

    
451
                try {
452
                        expansionFile.open();
453
                        if (index == null || fullExtent == null) {
454
                                // TODO: Si la capa dispone de un ?ndice espacial, hacer
455
                                // algo aqu? para que se use ese ?ndice espacial.
456
                                index = new Quadtree();
457
                                for (int i = 0; i < ova.getShapeCount(); i++) {
458
                                        Rectangle2D r=null;
459
                                        if (ova.getDriver() instanceof BoundedShapes) {
460
                                                r = ((BoundedShapes) ova.getDriver()).getShapeBounds(i);
461
                                        } else {
462
                                                IGeometry g = null;
463
                                                try {
464
                                                        g = ((DefaultFeature) ova.getFeature(i))
465
                                                                        .getGeometry();
466
                                                } catch (DriverException e1) {
467
                                                        e1.printStackTrace();
468
                                                }
469

    
470
                                                if (g == null) {
471
                                                        continue;
472
                                                }
473

    
474
                                                r = g.getBounds2D();
475
                                        }
476
                                        if (ct != null) {
477
                                                r = ct.convert(r);
478
                                        }
479
                                        Envelope e = new Envelope(r.getX(),
480
                                                        r.getX() + r.getWidth(), r.getY(), r.getY()
481
                                                                        + r.getHeight());
482
                                        index.insert(e, new Integer(i));
483
                                        if (fullExtent == null) {
484
                                                fullExtent = r;
485
                                        } else {
486
                                                fullExtent = fullExtent.createUnion(r);
487
                                        }
488
                                }
489
                        }
490
                } catch (DriverIOException e) {
491
                        throw new EditionException(e);
492
                } catch (IOException e) {
493
                        throw new EditionException(e);
494
                }
495

    
496
                System.err.println("Se han metido en el ?ndice "
497
                                + index.queryAll().size() + " geometr?as");
498
        }
499

    
500
        /*
501
         * (non-Javadoc)
502
         *
503
         * @see com.iver.cit.gvsig.fmap.edition.IEditableSource#getRow(int)
504
         */
505
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
506
                start();
507
                int calculatedIndex = getCalculatedIndex(index);
508
                Integer integer = new Integer(calculatedIndex);
509
                // Si no est? en el fichero de expansi?n
510
                DefaultRowEdited edRow = null;
511
                if (!relations.containsKey(integer)) {
512
                        try {
513
                                edRow = new DefaultRowEdited(ova.getFeature(calculatedIndex),
514
                                                DefaultRowEdited.STATUS_ORIGINAL, index);
515
                                stop();
516
                                return createExternalRow(edRow, 0);
517
                        } catch (DriverException e) {
518
                                e.printStackTrace();
519
                                throw new DriverIOException(e);
520
                        }
521

    
522
//                        return edRow;
523
                } else {
524
                        int num = ((Integer) relations.get(integer)).intValue();
525
                        IRowEdited aux = expansionFile.getRow(num);
526
                        edRow = new DefaultRowEdited(aux.getLinkedRow().cloneRow(), aux
527
                                        .getStatus(), index);
528
                        stop();
529
                        return edRow;
530
                }
531
        }
532

    
533
        /**
534
         * Elimina una geometria. Si es una geometr?a original de la capa en edici?n
535
         * se marca como eliminada (haya sido modificada o no). Si es una geometr?a
536
         * a?adida posteriormente se invalida en el fichero de expansi?n, para que
537
         * una futura compactaci?n termine con ella.
538
         *
539
         * @param index
540
         *            ?ndice de la geometr?a.
541
         *
542
         * @throws DriverIOException
543
         * @throws IOException
544
         */
545
        public IRow doRemoveRow(int index, int sourceType)
546
                        throws DriverIOException, IOException {
547
                boolean cancel = fireBeforeRemoveRow(index, sourceType);
548
                if (cancel)
549
                        return null;
550
                // Llega el calculatedIndex
551
                Integer integer = new Integer(index);
552

    
553
                IFeature feat = null;
554
                delRows.set(index, true);
555
                // Si la geometr?a no ha sido modificada
556
                if (!relations.containsKey(integer)) {
557

    
558
                        try {
559
                                feat = (DefaultFeature) (ova.getFeature(index));
560
                        } catch (DriverException e) {
561
                                // TODO Auto-generated catch block
562
                                e.printStackTrace();
563
                        }
564
                } else {
565
                        int num = ((Integer) relations.get(integer)).intValue();
566
                        feat = (IFeature) expansionFile.getRow(num).getLinkedRow();
567
                        // expansionFile.invalidateRow(num);
568
                }
569
                System.err.println("Elimina una Row en la posici?n: " + index);
570
                // Se actualiza el ?ndice
571
                if (feat != null) {
572
                        Rectangle2D r = feat.getGeometry().getBounds2D();
573
                        boolean borrado = this.index.remove(new Envelope(r.getX(), r.getX()
574
                                        + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
575
                                        new Integer(index));
576
                        System.out.println("Est? borrado : " + borrado);
577
                        System.out.println("Index.lenght : " + this.index.size());
578
                        isFullExtentDirty = true;
579
                }
580
                setSelection(new FBitSet());
581
                fireAfterRemoveRow(index, sourceType);
582
                return feat;
583
        }
584

    
585
        /**
586
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
587
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
588
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
589
         * fichero de expansi?n (por ser nueva o original pero modificada) se invoca
590
         * el m?todo modifyGeometry y se actualiza el ?ndice de la geometria en el
591
         * fichero.
592
         *
593
         * @param calculatedIndex
594
         *            DOCUMENT ME!
595
         * @param feat
596
         *            DOCUMENT ME!
597
         *
598
         * @return position inside ExpansionFile
599
         *
600
         * @throws IOException
601
         * @throws DriverIOException
602
         */
603
        public int doModifyRow(int calculatedIndex, IRow feat, int sourceType)
604
                        throws IOException, DriverIOException {
605
                boolean cancel = fireBeforeModifyRow(feat, calculatedIndex, sourceType);
606
                if (cancel)
607
                        return -1;
608
                int posAnteriorInExpansionFile = -1;
609
                Integer integer = new Integer(calculatedIndex);
610

    
611
                IFeature featAnt = null;
612
//                System.err.println("Modifica una Row en la posici?n: "
613
//                                + calculatedIndex);
614
                // Si la geometr?a no ha sido modificada
615
                if (!relations.containsKey(integer)) {
616
                        int newPosition = expansionFile.addRow(feat,
617
                                        IRowEdited.STATUS_MODIFIED, actualIndexFields);
618
                        relations.put(integer, new Integer(newPosition));
619

    
620
                        if (sourceType == EditionEvent.GRAPHIC) {
621
                                // Se actualiza el ?ndice espacial
622
                                try {
623
                                        featAnt = (DefaultFeature) (ova.getFeature(calculatedIndex));
624
                                } catch (DriverException e) {
625
                                        e.printStackTrace();
626
                                }
627
                                IGeometry g = featAnt.getGeometry();
628
                                Rectangle2D rAnt = g.getBounds2D();
629
                                Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
630
                                this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
631
                                                + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
632
                                                + rAnt.getHeight()), new Integer(calculatedIndex));
633
                                this.index.insert(new Envelope(r.getX(), r.getX()
634
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
635
                                                new Integer(calculatedIndex));
636
                        }
637
                } else {
638
                        // Obtenemos el ?ndice en el fichero de expansi?n
639
                        int num = ((Integer) relations.get(integer)).intValue();
640
                        posAnteriorInExpansionFile = num;
641

    
642
                        // Obtenemos la geometr?a para actualiza el ?ndice
643
                        // espacialposteriormente
644
                        featAnt = (IFeature) expansionFile.getRow(num).getLinkedRow();
645

    
646
                        /*
647
                         * Se modifica la geometr?a y nos guardamos el ?ndice dentro del
648
                         * fichero de expansi?n en el que se encuentra la geometr?a
649
                         * modificada
650
                         */
651
                        num = expansionFile.modifyRow(num, feat, actualIndexFields);
652

    
653
                        /*
654
                         * Actualiza la relaci?n del ?ndice de la geometr?a al ?ndice en el
655
                         * fichero de expansi?n.
656
                         */
657
                        relations.put(integer, new Integer(num));
658
                        if (sourceType == EditionEvent.GRAPHIC) {
659
                                // Se modifica el ?ndice espacial
660
                                Rectangle2D rAnt = featAnt.getGeometry().getBounds2D();
661
                                Rectangle2D r = ((IFeature) feat).getGeometry().getBounds2D();
662
                                this.index.remove(new Envelope(rAnt.getX(), rAnt.getX()
663
                                                + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
664
                                                + rAnt.getHeight()), new Integer(calculatedIndex));
665
                                this.index.insert(new Envelope(r.getX(), r.getX()
666
                                                + r.getWidth(), r.getY(), r.getY() + r.getHeight()),
667
                                                new Integer(calculatedIndex));
668
                        }
669
                }
670
                isFullExtentDirty = true;
671
                fireAfterModifyRow(calculatedIndex, sourceType);
672
                return posAnteriorInExpansionFile;
673
        }
674

    
675
        /**
676
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
677
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
678
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
679
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
680
         * expansion file a justo despues de la penultima geometr?a
681
         *
682
         * @param calculatedIndex
683
         *            ?ndice de la geometr?a que se quiere deshacer su modificaci?n
684
         * @param previousExpansionFileIndex
685
         *            ?ndice que ten?a antes la geometr?a en el expansionFile. Si
686
         *            vale -1 quiere decir que es una modificaci?n de una geometr?a
687
         *            original y por tanto no hay que actualizar el mapa de indices
688
         *            sino eliminar su entrada.
689
         *
690
         * @throws IOException
691
         * @throws DriverIOException
692
         */
693
        public void undoModifyRow(int calculatedIndex,
694
                        int previousExpansionFileIndex, int sourceType) throws IOException,
695
                        DriverIOException {
696

    
697
                // Llega el CalculatedIndex
698
                /*
699
                 * Si la acci?n de modificar se realiz? sobre una geometr?a original
700
                 */
701
                if (previousExpansionFileIndex == -1) {
702

    
703
                        // Se obtiene la geometr?a para actualizar el ?ndice
704
                        // IGeometry g = ((DefaultFeature)
705
                        // getRow(calculatedIndex).getLinkedRow()).getGeometry();
706
                        int inverse = getInversedIndex(calculatedIndex);
707
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
708
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
709
                                        sourceType);
710
                        if (cancel)
711
                                return;
712
                        IGeometry g = df.getGeometry();
713
                        // IGeometry g = ova.getShape(calculatedIndex);
714
                        Rectangle2D r = g.getBounds2D();
715

    
716
                        // Se elimina de las relaciones y del fichero de expansi?n
717
                        relations.remove(new Integer(calculatedIndex));
718
                        expansionFile.deleteLastRow();
719

    
720
                        // Se actualizan los ?ndices
721
                        IGeometry gAnt = ova.getShape(calculatedIndex);
722
                        /*
723
                         * IGeometry gAnt = ((DefaultFeature) getRow(calculatedIndex)
724
                         * .getLinkedRow()).getGeometry();
725
                         */
726
                        Rectangle2D rAnt = gAnt.getBounds2D();
727
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
728
                                        .getY(), r.getY() + r.getHeight()), new Integer(
729
                                        calculatedIndex));
730
                        this.index.insert(new Envelope(rAnt.getX(), rAnt.getX()
731
                                        + rAnt.getWidth(), rAnt.getY(), rAnt.getY()
732
                                        + rAnt.getHeight()), new Integer(calculatedIndex));
733
                } else {
734
                        // Se obtiene la geometr?a para actualizar el ?ndice
735
                        IGeometry g = null;
736
                        int inverse = getInversedIndex(calculatedIndex);
737
                        DefaultFeature df = (DefaultFeature) getRow(inverse).getLinkedRow();
738
                        boolean cancel = fireBeforeModifyRow(df, calculatedIndex,
739
                                        sourceType);
740
                        if (cancel)
741
                                return;
742
                        g = df.getGeometry();
743
                        System.out.println("Actual: " + g.toString());
744

    
745
                        Rectangle2D r = g.getBounds2D();
746
                        this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
747
                                        .getY(), r.getY() + r.getHeight()), new Integer(
748
                                        calculatedIndex));
749

    
750
                        // Se actualiza la relaci?n de ?ndices
751
                        // Integer integer = new Integer(geometryIndex);
752
                        relations.put(new Integer(calculatedIndex), new Integer(
753
                                        previousExpansionFileIndex));
754

    
755
                        // Se recupera la geometr?a
756
                        // expansionFile.validateRow(previousExpansionFileIndex);
757

    
758
                        // Se actualizan los ?ndices
759
                        // g = ((IFeature)
760
                        // (expansionFile.getRow(previousExpansionFileIndex).getLinkedRow())).getGeometry();
761
                        // System.out.println("Anterior a la que volvemos : " +
762
                        // g.toString());
763
                        g = ((DefaultFeature) getRow(inverse).getLinkedRow()).getGeometry();
764
                        r = g.getBounds2D();
765
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
766
                                        .getY(), r.getY() + r.getHeight()), new Integer(
767
                                        calculatedIndex));
768

    
769
                }
770
                fireAfterModifyRow(calculatedIndex, sourceType);
771
        }
772

    
773
        /**
774
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
775
         * en la tabla relations.
776
         *
777
         * @param feat
778
         *            geometr?a a guardar.
779
         *
780
         * @return calculatedIndex
781
         *
782
         * @throws DriverIOException
783
         * @throws IOException
784
         */
785
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException,
786
                        IOException {
787
                int calculatedIndex = super.doAddRow(feat, sourceType);
788
                // Actualiza el ?ndice espacial
789
                IGeometry g = ((IFeature) feat).getGeometry();
790
                Rectangle2D r = g.getBounds2D();
791
                index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
792
                                r.getY() + r.getHeight()), new Integer(calculatedIndex));
793
                isFullExtentDirty = true;
794
                return calculatedIndex;
795
        }
796

    
797
        /**
798
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
799
         * en el fichero original
800
         *
801
         * @param index
802
         *            DOCUMENT ME!
803
         *
804
         * @throws IOException
805
         * @throws DriverIOException
806
         */
807
        public void undoRemoveRow(int index, int sourceType) throws IOException,
808
                        DriverIOException {
809
                super.undoRemoveRow(index, sourceType);
810

    
811
                IGeometry g = null;
812
                g = ((IFeature) getRow(getInversedIndex(index)).getLinkedRow()).getGeometry();
813

    
814
                Rectangle2D r = g.getBounds2D();
815
                this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r
816
                                .getY(), r.getY() + r.getHeight()), new Integer(index));
817
        }
818

    
819
        /**
820
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
821
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar la
822
         * relaci?n del mapa de relaciones
823
         *
824
         * @param index
825
         *            ?ndice de la geometr?a que se a?adi?
826
         *
827
         * @throws DriverIOException
828
         * @throws IOException
829
         */
830
        public void undoAddRow(int calculatedIndex, int sourceType)
831
                        throws DriverIOException, IOException {
832
                int inverse = getInversedIndex(calculatedIndex);
833
                IGeometry g = ((IFeature) getRow(inverse).getLinkedRow()).getGeometry();
834
                Rectangle2D r = g.getBounds2D();
835
                this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(), r
836
                                .getY(), r.getY() + r.getHeight()),
837
                                new Integer(calculatedIndex));
838

    
839
                super.undoAddRow(calculatedIndex, sourceType);
840
                setSelection(new FBitSet());
841
        }
842

    
843
        /**
844
         * Obtiene las geometr?as que se encuentran en el rect?ngulo que se pasa
845
         * como par?metro haciendo uso del ?ndice espacial
846
         *
847
         * @param r
848
         *            Rect?ngulo indicando la porci?n del espacio para el cual se
849
         *            quiere saber los ?ndices de las geometr?as que se encuentran
850
         *            dentro de ?l
851
         *
852
         * @return Array de ?ndices para su uso con getGeometry, removeGeometry, ...
853
         */
854
        /*
855
         * public int[] getRowsIndexes_OL(Rectangle2D r) { Envelope e = new
856
         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
857
         * r.getHeight()); List l = index.query(e); int[] indexes = new
858
         * int[l.size()];
859
         *
860
         * for (int index = 0; index < l.size(); index++) { Integer i = (Integer)
861
         * l.get(index); indexes[index] = getInversedIndex(i.intValue()); }
862
         *
863
         * return indexes; }
864
         */
865
        /**
866
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
867
         */
868
        public int getShapeCount() throws DriverIOException {
869
                try {
870
                        return getRowCount();
871
                } catch (IOException e) {
872
                        throw new DriverIOException(e);
873
                }
874
        }
875

    
876
        /**
877
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
878
         */
879
        public Rectangle2D getFullExtent() throws DriverIOException {
880
                if (fullExtent == null) {
881
                        fullExtent = ova.getFullExtent();
882
                }
883

    
884
                if (isFullExtentDirty) {
885
                        fullExtent = reCalculateFullExtent();
886
                        isFullExtentDirty = false;
887
                }
888

    
889
                return fullExtent;
890
        }
891

    
892
        /**
893
         * Use it BEFORE writing to a file.
894
         *
895
         * @return real full extent.
896
         * @throws DriverIOException
897
         */
898
        public Rectangle2D reCalculateFullExtent() throws DriverIOException {
899
                if (getShapeCount() > 0) {
900
                        fullExtent = getShape(0).getBounds2D();
901
                        for (int i = 1; i < getShapeCount(); i++) {
902
                                IGeometry geom=getShape(i);
903
                                if (fullExtent==null) {
904
                                        fullExtent=geom.getBounds2D();
905
                                        continue;
906
                                }
907
                                if (!(geom instanceof FNullGeometry)) {
908
                                        fullExtent.add(geom.getBounds2D());
909
                                }
910
                        }
911
                } else {
912
                        fullExtent = ova.getFullExtent();
913
                }
914
                return fullExtent;
915
        }
916

    
917
        /**
918
         * En la implementaci?n por defecto podemos hacer que cada feature tenga ID =
919
         * numero de registro. En el DBAdapter podr?amos "overrride" este m?todo y
920
         * poner como ID de la Feature el campo ?nico escogido en la base de datos.
921
         *
922
         * @param numReg
923
         * @return
924
         * @throws DriverException
925
         */
926
        public IFeature getFeature(int numReg) throws DriverException {
927
                IGeometry geom;
928
                IFeature feat = null;
929
                try {
930
                        geom = getShape(numReg);
931
                        DataSource rs = getRecordset();
932
                        Value[] regAtt = new Value[rs.getFieldCount()];
933
                        for (int fieldId = 0; fieldId < rs.getFieldCount(); fieldId++) {
934
                                regAtt[fieldId] = rs.getFieldValue(numReg, fieldId);
935
                        }
936
                        feat = new DefaultFeature(geom, regAtt, numReg + "");
937
                } catch (DriverIOException e) {
938
                        DriverIOExceptionType type =
939
                                new DriverIOExceptionType();
940
                        type.setDriverName(this.getDriver().getName());
941
                        throw new DriverException(e, type);
942

    
943
                } catch (DriverLoadException e) {
944
                        DriverNotLoadedExceptionType type =
945
                                new DriverNotLoadedExceptionType();
946
                        type.setDriverName(getDriver().getName());
947
                        throw new DriverException(e, type);
948

    
949

    
950
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
951

    
952
                        throw new DriverException(e);
953
                }
954
                return feat;
955
        }
956

    
957
        public void stopEdition(IWriter writer, int sourceType)
958
                        throws EditionException {
959
//                ISpatialWriter spatialWriter = (ISpatialWriter) writer;
960
//                spatialWriter.setFlatness(FConverter.flatness);
961
                super.stopEdition(writer, sourceType);
962
//                try {
963
//                        ova.getDriver().reload();
964
//                } catch (IOException e) {
965
//                        e.printStackTrace();
966
//                        throw new EditionException(e);
967
//                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
968
//                        e.printStackTrace();
969
//                        throw new EditionException(e);
970
//                }
971
                index=null;
972
                writer=null;
973
        }
974

    
975
        public Rectangle2D getShapeBounds(int index) throws IOException {
976
                // Solo se utiliza cuando el driver es BoundedShapes
977
                // Si no est? en el fichero de expansi?n
978
                Integer integer = new Integer((int) index);
979
                if (!relations.containsKey(integer)) {
980
                        if (ova.getDriver() instanceof BoundedShapes) {
981
                                BoundedShapes bs = (BoundedShapes) ova.getDriver();
982
                                return bs.getShapeBounds(index);
983
                        } else {
984
                                return ova.getDriver().getShape(index).getBounds2D();
985
                        }
986

    
987
                } else {
988
                        int num = ((Integer) relations.get(integer)).intValue();
989
                        DefaultRowEdited feat;
990
                        feat = (DefaultRowEdited) expansionFile.getRow(num);
991
                        if (feat.getStatus() == IRowEdited.STATUS_DELETED)
992
                                return null;
993
                        IGeometry geom = ((IFeature) feat.getLinkedRow()).getGeometry();
994
                        return geom.getBounds2D();// getGeometry();
995
                }
996

    
997
        }
998

    
999
        public int getShapeType(int index) {
1000
                try {
1001
                        return ova.getShapeType();
1002
                } catch (DriverIOException e) {
1003
                        // TODO Auto-generated catch block
1004
                        e.printStackTrace();
1005
                }
1006
                return FShape.MULTI;
1007
        }
1008

    
1009
        /**
1010
         * Usar solo cuando est?s seguro de que puedes gastar memoria. Nosotros lo
1011
         * usamos para las b?squedas por ?ndice espacial con el handle. La idea es
1012
         * usarlo una vez, guardar las geometr?as que necesitas en ese extent y
1013
         * trabajar con ellas hasta el siguiente cambio de extent.
1014
         *
1015
         * @param r
1016
         * @param strEPSG
1017
         * @return
1018
         * @throws DriverException
1019
         */
1020
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG)
1021
                        throws DriverException {
1022
                // En esta clase suponemos random access.
1023
                // Luego tendremos otra clase que sea VectorialEditableDBAdapter
1024
                // que reescribir? este m?todo.
1025
                Envelope e = FConverter.convertRectangle2DtoEnvelope(r);
1026
                List l = index.query(e);
1027
                IRowEdited[] feats = new IRowEdited[l.size()];
1028
                try {
1029
                        for (int index = 0; index < l.size(); index++) {
1030
                                Integer i = (Integer) l.get(index);
1031
                                int inverse = getInversedIndex(i.intValue());
1032
                                feats[index] = (IRowEdited) getRow(inverse);
1033
                        }
1034
                } catch (IOException ex) {
1035
                        DriverIOExceptionType type =
1036
                                new DriverIOExceptionType();
1037
                        type.setDriverName(this.getDriver().getName());
1038
                        throw new DriverException(ex, type);
1039

    
1040
                } catch (DriverLoadException ex) {
1041
                        DriverNotLoadedExceptionType type =
1042
                                new DriverNotLoadedExceptionType();
1043
                        type.setDriverName(getDriver().getName());
1044
                        throw new DriverException(ex, type);
1045
                } catch (DriverIOException ex) {
1046
                        DriverIOExceptionType type =
1047
                                new DriverIOExceptionType();
1048
                        type.setDriverName(this.getDriver().getName());
1049
                        throw new DriverException(ex, type);
1050
                }
1051
                return feats;
1052
        }
1053

    
1054
        public void setSpatialIndex(SpatialIndex spatialIndex) {
1055
                index = (Quadtree) spatialIndex;
1056
        }
1057

    
1058
        public void setFullExtent(Rectangle2D fullExtent2) {
1059
                fullExtent = fullExtent2;
1060
        }
1061

    
1062
        /**
1063
         * DOCUMENT ME!
1064
         *
1065
         * @return DOCUMENT ME!
1066
         */
1067
        public Image getSelectionImage() {
1068
                return selectionImage;
1069
        }
1070

    
1071
        public Image getHandlersImage() {
1072
                return handlersImage;
1073
        }
1074

    
1075
        /**
1076
         * DOCUMENT ME!
1077
         *
1078
         * @param i
1079
         *            DOCUMENT ME!
1080
         */
1081
        public void setSelectionImage(Image i) {
1082
                selectionImage = i;
1083
        }
1084

    
1085
        public void setHandlersImage(BufferedImage handlersImage) {
1086
                this.handlersImage = handlersImage;
1087
        }
1088

    
1089
        public void cancelEdition(int sourceType) throws IOException {
1090
                super.cancelEdition(sourceType);
1091
                index=null;
1092
                setWriter(null);
1093
                System.gc();
1094
        }
1095

    
1096
//        public double getFlatness() {
1097
//                return flatness;
1098
//        }
1099
//
1100
//        public void setFlatness(double d) {
1101
//                flatness=d;
1102
//        }
1103

    
1104
}