Statistics
| Revision:

root / branches / pilotoDWG / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / DefaultEditableFeatureSource.java @ 1556

History | View | Annotate | Download (13 KB)

1
package com.iver.cit.gvsig.fmap.edition;
2

    
3
import com.iver.cit.gvsig.fmap.core.IGeometry;
4
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
5

    
6
import com.vividsolutions.jts.geom.Envelope;
7
import com.vividsolutions.jts.index.quadtree.Quadtree;
8

    
9
import java.awt.Image;
10
import java.awt.geom.Rectangle2D;
11

    
12
import java.io.IOException;
13

    
14
import java.util.ArrayList;
15
import java.util.BitSet;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.List;
19

    
20

    
21
/**
22
 * DOCUMENT ME!
23
 *
24
 * @author Vicente Caballero Navarro
25
 */
26
public class DefaultEditableFeatureSource implements EditableFeatureSource {
27
        private ExpansionFile expansionFile;
28
        private OriginalFeatureAdapter ofa;
29
        private BitSet delgeometries = new BitSet();
30
        private HashMap relations = new HashMap();
31
        private int numAdd = 0;
32
        private Quadtree index;
33
        private Image selectionImage;
34

    
35
        /**
36
         * Crea un nuevo AbstractEditableFeatureSource.
37
         *
38
         * @param ef DOCUMENT ME!
39
         * @param ofa DOCUMENT ME!
40
         */
41
        public DefaultEditableFeatureSource(ExpansionFile ef,
42
                OriginalFeatureAdapter ofa) {
43
                expansionFile = ef;
44
                this.ofa = ofa;
45
        }
46

    
47
        /**
48
         * M?todo invocado cuando se comienza la edici?n, para poner en marcha las
49
         * estructuras de datos necesarias para la misma, notificar al servidor en
50
         * protocolos en los que sea necesario, ...
51
         *
52
         * @throws EditionException
53
         */
54
        public void startEdition() throws EditionException {
55
                ofa.startEdition();
56

    
57
                index = new Quadtree();
58

    
59
                try {
60
                        for (int i = 0; i < getGeometryCount(); i++) {
61
                                IGeometry g = getGeometry(i);
62
                                Rectangle2D r = g.getBounds2D();
63
                                Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(),
64
                                                r.getY(), r.getY() + r.getHeight());
65
                                index.insert(e, new Integer(i));
66
                        }
67
                } catch (DriverIOException e) {
68
                        e.printStackTrace();
69
                } catch (IOException e) {
70
                        e.printStackTrace();
71
                }
72

    
73
                System.err.println("Se han metido en el ?ndice " +
74
                        index.queryAll().size() + " geometr?as");
75
        }
76

    
77
        /**
78
         * Invocado cuando termina la edici?n. En funci?n de la clase concreta que
79
         * implemente este m?todo se generar? el fichero con los resultados de la
80
         * edici?n, se realizar? una transacci?n a la base de datos, etc.
81
         *
82
         * @throws EditionException
83
         */
84
        public void stopEdition() throws EditionException {
85
                ofa.stopEdition();
86
        }
87

    
88
        /**
89
         * Devuelve el n?mero de geometrias que hay actualmente en edici?n.
90
         *
91
         * @return N?mero de geometr?as.
92
         *
93
         * @throws DriverIOException
94
         */
95
        public int getGeometryCount() throws DriverIOException {
96
                return ofa.getGeometryCount() + numAdd; //expansionFile.getGeometryCount() - relations.size();
97
        }
98

    
99
        /**
100
         * Si el ?ndice se corresponde a una geometria de las originales de la capa
101
         * en edici?n y no ha sido modificada ni eliminada devuelve la geometria
102
         * original. Si ha sido modificada debera de buscar en el fichero de
103
         * expansi?n y si ha sido eliminada debera devolver null
104
         *
105
         * @param index ?ndice de la geometr?a.
106
         *
107
         * @return Geometr?a.
108
         *
109
         * @throws IOException
110
         * @throws DriverIOException
111
         */
112
        public synchronized IGeometry getGeometry(int index)
113
                throws IOException, DriverIOException {
114
                Integer integer = new Integer(index);
115

    
116
                if (!relations.containsKey(integer)) {
117
                        if (delgeometries.get(index)) {
118
                                return null;
119
                        } else {
120
                                return ofa.getGeometry(index);
121
                        }
122
                } else {
123
                        int num = ((Integer) relations.get(integer)).intValue();
124

    
125
                        return expansionFile.getGeometry(num);
126
                }
127
        }
128

    
129
        /**
130
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
131
         * en una tabla asociada.
132
         *
133
         * @param g geometr?a a guardar.
134
         *
135
         * @throws DriverIOException
136
         * @throws IOException
137
         */
138
        public void addGeometry(IGeometry g) throws DriverIOException, IOException {
139
                int virtualIndex = ofa.getGeometryCount() + numAdd;
140
                int pos = expansionFile.addGeometry(g);
141
                relations.put(new Integer(virtualIndex), new Integer(pos));
142
                numAdd++;
143

    
144
                Rectangle2D r = g.getBounds2D();
145
                index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
146
                                r.getY() + r.getHeight()), new Integer(virtualIndex));
147

    
148
                //                System.err.println(this.index.size());
149
        }
150

    
151
        /**
152
         * Elimina una geometria. Si es una geometr?a original de la capa en
153
         * edici?n se marca como eliminada (haya sido modificada o no). Si es una
154
         * geometr?a a?adida posteriormente se invalida en el fichero de
155
         * expansi?n, para que una futura compactaci?n termine con ella.
156
         *
157
         * @param index ?ndice de la geometr?a.
158
         *
159
         * @throws DriverIOException
160
         * @throws IOException
161
         */
162
        public void removeGeometry(int index) throws DriverIOException, IOException {
163
                Integer integer = new Integer(index);
164

    
165
                IGeometry g = null;
166

    
167
                if (!relations.containsKey(integer)) {
168
                        delgeometries.set(index, true);
169
                        g = ofa.getGeometry(index);
170
                } else {
171
                        int num = ((Integer) relations.get(integer)).intValue();
172
                        g = expansionFile.getGeometry(num);
173
                        expansionFile.invalidateGeometry(num);
174
                }
175

    
176
                Rectangle2D r = g.getBounds2D();
177
                this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(),
178
                                r.getY(), r.getY() + r.getHeight()), new Integer(index));
179

    
180
                //                System.err.println(this.index.size());
181
        }
182

    
183
        /**
184
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
185
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
186
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
187
         * fichero de expansi?n (por ser nueva o original pero modificada) se
188
         * invoca el m?todo modifyGeometry y se actualiza el ?ndice de la
189
         * geometria en el fichero.
190
         *
191
         * @param index DOCUMENT ME!
192
         * @param g DOCUMENT ME!
193
         *
194
         * @throws IOException
195
         * @throws DriverIOException
196
         */
197
        public void modifyGeometry(int index, IGeometry g)
198
                throws IOException, DriverIOException {
199
                Integer integer = new Integer(index);
200

    
201
                IGeometry gAnt = null;
202

    
203
                if (!relations.containsKey(integer)) {
204
                        int expansionIndex = expansionFile.addGeometry(g);
205
                        relations.put(integer, new Integer(expansionIndex));
206

    
207
                        //Se actualiza el ?ndice espacial
208
                        gAnt = ofa.getGeometry(index);
209

    
210
                        Rectangle2D rAnt = gAnt.getBounds2D();
211
                        Rectangle2D r = g.getBounds2D();
212
                        this.index.remove(new Envelope(rAnt.getX(),
213
                                        rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
214
                                        rAnt.getY() + rAnt.getHeight()), new Integer(index));
215
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
216
                                        r.getY(), r.getY() + r.getHeight()), new Integer(index));
217
                } else {
218
                        int num = ((Integer) relations.get(integer)).intValue();
219
                        gAnt = expansionFile.getGeometry(num);
220
                        num = expansionFile.modifyGeometry(num, g);
221
                        relations.put(integer, new Integer(num));
222

    
223
                        //Se modifica el ?ndice espacial
224
                        Rectangle2D rAnt = gAnt.getBounds2D();
225
                        Rectangle2D r = g.getBounds2D();
226
                        this.index.remove(new Envelope(rAnt.getX(),
227
                                        rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
228
                                        rAnt.getY() + rAnt.getHeight()), new Integer(index));
229
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
230
                                        r.getY(), r.getY() + r.getHeight()), new Integer(index));
231
                }
232

    
233
                //                System.err.println(this.index.size());
234
        }
235

    
236
        /**
237
         * DOCUMENT ME!
238
         *
239
         * @return DOCUMENT ME!
240
         */
241
        public OriginalFeatureAdapter getOriginalFeatureAdapter() {
242
                return ofa;
243
        }
244

    
245
        /**
246
         * @see com.iver.cit.gvsig.fmap.edition.EditableFeatureSource#compact()
247
         */
248
        public void compact() {
249
                expansionFile.compact(relations);
250
        }
251

    
252
        /**
253
         * @see com.iver.cit.gvsig.fmap.edition.EditableFeatureSource#getGeometriesIndexes(com.vividsolutions.jts.geom.Envelope)
254
         */
255
        public int[] getGeometriesIndexes(Rectangle2D r) {
256
                Envelope e = new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
257
                                r.getY() + r.getHeight());
258
                List l = index.query(e);
259
                int[] indexes = new int[l.size()];
260

    
261
                for (int index = 0; index < l.size(); index++) {
262
                        Integer i = (Integer) l.get(index);
263
                        indexes[index] = i.intValue();
264
                }
265

    
266
                return indexes;
267
        }
268

    
269
        /**
270
         * @see com.iver.cit.gvsig.fmap.edition.EditableFeatureSource#setImage(java.awt.Image)
271
         */
272
        public void setImage(Image i) {
273
                selectionImage = i;
274
        }
275

    
276
        /**
277
         * @see com.iver.cit.gvsig.fmap.edition.EditableFeatureSource#getImage()
278
         */
279
        public Image getImage() {
280
                return selectionImage;
281
        }
282

    
283
        /**
284
         * @see com.iver.cit.gvsig.fmap.edition.EditableFeatureSource#getCommandRecord()
285
         */
286
        public CommandRecord getCommandRecord() {
287
                return null;
288
        }
289

    
290
        /**
291
         * Se elimina del final del fichero de expansi?n poniendo el puntero de
292
         * escritura apuntando al final de la pen?ltima geometr?a. Deber? quitar
293
         * la relaci?n del mapa de relaciones
294
         *
295
         * @param index ?ndice de la geometr?a que se a?adi?
296
         */
297
        public void undoAddGeometry(int index) {
298
                //TODO implementar
299
        }
300

    
301
        /**
302
         * Se desmarca como invalidada en el fichero de expansion o como eliminada
303
         * en el fichero original
304
         *
305
         * @param index DOCUMENT ME!
306
         */
307
        public void undoRemoveGeometry(int index) {
308
                //TODO implementar
309
        }
310

    
311
        /**
312
         * Actualiza en el mapa de ?ndices, la posici?n en la que estaba la
313
         * geometr?a antes de ser modificada. Se marca como v?lida, en caso de que
314
         * fuera una modificaci?n de una geometr?a que estuviese en el fichero de
315
         * expansi?n antes de ser modificada y se pone el puntero de escritura del
316
         * expansion file a justo despues de la penultima geometr?a
317
         *
318
         * @param geometryIndex ?ndice de la geometr?a que se quiere deshacer su
319
         *                   movimiento
320
         * @param previousExpansionFileIndex ?ndice que ten?a antes la geometr?a en
321
         *                   el expansionFile. Si vale -1 quiere decir que es una
322
         *                   modificaci?n de una geometr?a original y por tanto no hay que
323
         *                   actualizar el mapa de indices sino eliminar su entrada.
324
         */
325
        public void undoModifyGeometry(int geometryIndex,
326
                int previousExpansionFileIndex) {
327
                //TODO implementar
328
        }
329

    
330
        /**
331
         * A?ade una geometria al fichero de expansi?n y guarda la correspondencia
332
         * en una tabla asociada.
333
         *
334
         * @param g geometr?a a guardar.
335
         *
336
         * @throws DriverIOException
337
         * @throws IOException
338
         */
339
        public void doAddGeometry(IGeometry g) throws DriverIOException, IOException {
340
                int virtualIndex = ofa.getGeometryCount() + numAdd;
341
                int pos = expansionFile.addGeometry(g);
342
                relations.put(new Integer(virtualIndex), new Integer(pos));
343
                numAdd++;
344
        
345
                Rectangle2D r = g.getBounds2D();
346
                index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(),
347
                                r.getY() + r.getHeight()), new Integer(virtualIndex));
348
        
349
                //                System.err.println(this.index.size());
350
        }
351

    
352
        /**
353
         * Elimina una geometria. Si es una geometr?a original de la capa en
354
         * edici?n se marca como eliminada (haya sido modificada o no). Si es una
355
         * geometr?a a?adida posteriormente se invalida en el fichero de
356
         * expansi?n, para que una futura compactaci?n termine con ella.
357
         *
358
         * @param index ?ndice de la geometr?a.
359
         *
360
         * @throws DriverIOException
361
         * @throws IOException
362
         */
363
        public void doRemoveGeometry(int index) throws DriverIOException, IOException {
364
                Integer integer = new Integer(index);
365
        
366
                IGeometry g = null;
367
        
368
                if (!relations.containsKey(integer)) {
369
                        delgeometries.set(index, true);
370
                        g = ofa.getGeometry(index);
371
                } else {
372
                        int num = ((Integer) relations.get(integer)).intValue();
373
                        g = expansionFile.getGeometry(num);
374
                        expansionFile.invalidateGeometry(num);
375
                }
376
        
377
                Rectangle2D r = g.getBounds2D();
378
                this.index.remove(new Envelope(r.getX(), r.getX() + r.getWidth(),
379
                                r.getY(), r.getY() + r.getHeight()), new Integer(index));
380
        
381
                //                System.err.println(this.index.size());
382
        }
383

    
384
        /**
385
         * Si se intenta modificar una geometr?a original de la capa en edici?n se
386
         * a?ade al fichero de expansi?n y se registra la posici?n en la que se
387
         * a?adi?. Si se intenta modificar una geometria que se encuentra en el
388
         * fichero de expansi?n (por ser nueva o original pero modificada) se
389
         * invoca el m?todo modifyGeometry y se actualiza el ?ndice de la
390
         * geometria en el fichero.
391
         *
392
         * @param index DOCUMENT ME!
393
         * @param g DOCUMENT ME!
394
         *
395
         * @throws IOException
396
         * @throws DriverIOException
397
         */
398
        public void doModifyGeometry(int index, IGeometry g)
399
                throws IOException, DriverIOException {
400
                Integer integer = new Integer(index);
401
        
402
                IGeometry gAnt = null;
403
        
404
                if (!relations.containsKey(integer)) {
405
                        int expansionIndex = expansionFile.addGeometry(g);
406
                        relations.put(integer, new Integer(expansionIndex));
407
        
408
                        //Se actualiza el ?ndice espacial
409
                        gAnt = ofa.getGeometry(index);
410
        
411
                        Rectangle2D rAnt = gAnt.getBounds2D();
412
                        Rectangle2D r = g.getBounds2D();
413
                        this.index.remove(new Envelope(rAnt.getX(),
414
                                        rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
415
                                        rAnt.getY() + rAnt.getHeight()), new Integer(index));
416
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
417
                                        r.getY(), r.getY() + r.getHeight()), new Integer(index));
418
                } else {
419
                        int num = ((Integer) relations.get(integer)).intValue();
420
                        gAnt = expansionFile.getGeometry(num);
421
                        num = expansionFile.modifyGeometry(num, g);
422
                        relations.put(integer, new Integer(num));
423
        
424
                        //Se modifica el ?ndice espacial
425
                        Rectangle2D rAnt = gAnt.getBounds2D();
426
                        Rectangle2D r = g.getBounds2D();
427
                        this.index.remove(new Envelope(rAnt.getX(),
428
                                        rAnt.getX() + rAnt.getWidth(), rAnt.getY(),
429
                                        rAnt.getY() + rAnt.getHeight()), new Integer(index));
430
                        this.index.insert(new Envelope(r.getX(), r.getX() + r.getWidth(),
431
                                        r.getY(), r.getY() + r.getHeight()), new Integer(index));
432
                }
433
        
434
                //                System.err.println(this.index.size());
435
        }
436
}