Statistics
| Revision:

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

History | View | Annotate | Download (16 KB)

1
/**
2
 * 
3
 */
4
package com.iver.cit.gvsig.fmap.edition;
5

    
6
import java.awt.geom.Rectangle2D;
7
import java.io.IOException;
8
import java.util.ArrayList;
9
import java.util.Hashtable;
10
import java.util.List;
11

    
12
import com.iver.cit.gvsig.fmap.DriverException;
13
import com.iver.cit.gvsig.fmap.core.IFeature;
14
import com.iver.cit.gvsig.fmap.core.IGeometry;
15
import com.iver.cit.gvsig.fmap.core.IRow;
16
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
17
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
18
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
19
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
20
import com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver;
21
import com.iver.cit.gvsig.fmap.layers.ISpatialDB;
22
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
23
import com.iver.cit.gvsig.fmap.layers.VectorialDBAdapter;
24
import com.vividsolutions.jts.geom.Envelope;
25
import com.vividsolutions.jts.index.quadtree.Quadtree;
26

    
27
/**
28
 * @author fjp
29
 * 
30
 */
31
public class VectorialEditableDBAdapter extends VectorialEditableAdapter
32
                implements ISpatialDB {
33

    
34
        private class MyIterator implements IFeatureIterator {
35
                private Rectangle2D extent = null;
36

    
37
                private VectorialDBAdapter orig;
38

    
39
                private IFeature feat;
40

    
41
                private IFeatureIterator featIt;
42

    
43
                private String epsg;
44

    
45
                private VectorialDatabaseDriver dbDriver;
46

    
47
                Hashtable alreadyDone = new Hashtable();
48

    
49
                private int idFromExpansion = 0;
50

    
51
                private List listFromExpansion;
52

    
53
                private boolean bOriginalCursorOpened = true;
54

    
55
                public MyIterator(Rectangle2D r, String strEPSG) throws DriverException {
56
                        extent = r;
57
                        epsg = strEPSG;
58
                        orig = (VectorialDBAdapter) ova;
59
                        featIt = orig.getFeatureIterator(extent, epsg);
60
                        dbDriver = (VectorialDatabaseDriver) getDriver();
61
                        getFeaturesFromExpansionFile();
62
                }
63

    
64
                public boolean hasNext() throws DriverException {
65
                        feat = null;
66
                        int calculatedIndex = -1;
67
                        if (bOriginalCursorOpened) // Si hay originales (Es porque si se ha
68
                                                                                // llegado al final, se cierra el
69
                                                                                // iterador y salta un fallo
70
                        {
71
                                bOriginalCursorOpened = featIt.hasNext();
72
                                if (bOriginalCursorOpened) {
73
                                        feat = featIt.next();
74
                                        int originalIndex = dbDriver.getRowIndexByFID(feat);
75
                                        
76
                                        // Iteramos hasta que encontremos alguno no borrado.
77
                                        // Aqu? suponemos que el orden es el original. Si no, no funcionar?.
78
                                        if (delRows.get(originalIndex)) // Si est? borrado
79
                                        {
80
                                                feat = null;
81
                                                boolean bFound = false;
82
                                                while (featIt.hasNext())
83
                                                {
84
                                                        feat = featIt.next();
85
                                                        originalIndex = dbDriver.getRowIndexByFID(feat);
86
                                                        // calculatedIndex = getCalculatedIndex(originalIndex);
87
                                                        if (delRows.get(originalIndex) == false) // Si NO est? borrado
88
                                                        {
89
                                                                bFound = true;
90
                                                                break;
91
                                                        }
92
                                                }
93
                                                if (bFound == false) // Todos los ?ltimos est?n borrados.
94
                                                {
95
                                                        bOriginalCursorOpened = false; // para que busque en el fichero de expansi?n
96
                                                }
97
                                        } // if delRows
98
                                        if (bOriginalCursorOpened) // Si todav?a quedan features por leer, y no est?n borradas
99
                                        {
100
                                                calculatedIndex = originalIndex; //getCalculatedIndex(originalIndex);
101
                                                Integer integer = new Integer(calculatedIndex);
102
                                                if (!relations.containsKey(integer)) { // Si no est? en el
103
                                                                                                                                // fichero de
104
                                                                                                                                // expansi?n
105
                                                        alreadyDone.put(integer, feat);
106
                                                } else { // Si est? en el fichero de expansi?n
107
                                                        int num = ((Integer) relations.get(integer)).intValue();
108
                                                        IRowEdited auxR;
109
                                                        try {
110
                                                                auxR = expansionFile.getRow(num);
111
                                                                feat = (IFeature) auxR.getLinkedRow().cloneRow();
112
                                                                // feat = (IFeature) auxR.getLinkedRow();
113
                                                                alreadyDone.put(integer, feat);
114
                                                        } catch (IOException e) {
115
                                                                e.printStackTrace();
116
                                                                throw new DriverException(e);
117
                                                        }
118
                                                } // else
119
                                        } // if tercer bOriginalCursorOpened
120
                                } // if segundo bOriginalCursorOpened
121
                        } // if primer bOriginalCursorOpened
122
                        if (!bOriginalCursorOpened) {
123
                                // Si ya no hay m?s de las originales, todav?a tenemos
124
                                // que revisar las a?adidas que hay en el fichero
125
                                // de expansi?n
126
                                try {
127
                                        while ((idFromExpansion < expansionFile.getSize()) && (feat == null))
128
                                        {
129
                                                IRowEdited rowEd = expansionFile.getRow(idFromExpansion);
130
                                                IFeature aux = (IFeature) rowEd.getLinkedRow();
131
                                                Integer calculated = (Integer) mapFID2index.get(aux.getID());
132
                                                calculatedIndex = calculated.intValue();
133
                                                System.out.println("El elemento idFromExpansion = " + idFromExpansion + " es " + aux.getID());
134
                                                
135
                                                // Revisamos los borrados
136
                                                if (delRows.get(calculatedIndex) == true)
137
                                                {
138
                                                        boolean bFound = false;
139
                                                        while ((!bFound) && (idFromExpansion < expansionFile.getSize()-1))
140
                                                        {
141
                                                                // calculatedIndex++;
142
                                                                idFromExpansion++;
143
                                                                rowEd = expansionFile.getRow(idFromExpansion);
144
                                                                aux = (IFeature) rowEd.getLinkedRow();
145
                                                                
146
                                                                
147
                                                                
148
                                                                Integer auxCalculated = (Integer) mapFID2index.get(aux.getID());
149
                                                                calculatedIndex = auxCalculated.intValue();
150
                                                                // Si no est? borrado y es una entidad v?lida, que est? siendo usada (no es algo que est? en el expansionFile sin usarse)
151
                                                                if ((delRows.get(calculatedIndex) == false) && (relations.containsKey(auxCalculated)))
152
                                                                {
153
                                                                        bFound = true;
154
                                                                        calculated = auxCalculated;
155
                                                                        break;
156
                                                                }
157
                                                                else
158
                                                                {
159
                                                                        System.out.println("El elemento idFromExpansion = " + idFromExpansion + " est? borrado");                                                                        
160
                                                                }
161
                                                        }
162
                                                        if (bFound)
163
                                                        {
164
                                                                calculated = new Integer(calculatedIndex);
165
                                                                rowEd = expansionFile.getRow(idFromExpansion);
166
                                                                aux = (IFeature) rowEd.getLinkedRow();                                                        
167
                                                        }
168
                                                        else
169
                                                        {
170
                                                                return false; // El resto est?n borrados
171
                                                        }
172
                                                } // if primer borrado
173
                                                if (relations.containsKey(calculated))
174
                                                {
175
                                                        Integer realExpansionIndex = (Integer) relations.get(calculated);
176
                                                        if (realExpansionIndex.intValue() == idFromExpansion)
177
                                                        {
178
                                                                feat = (IFeature) aux.cloneRow();
179
                                                        }
180
                                                }
181
                                                idFromExpansion++;
182
                                        }
183
                                } catch (IOException e) {
184
                                        throw new DriverException(e);
185
                                }
186
                        }
187

    
188
                        if (calculatedIndex == -1)
189
                                return false;
190
                        else {
191
                                if (feat == null)
192
                                {
193
                                        if (idFromExpansion == expansionFile.getSize())
194
                                                return false;
195
                                        else
196
                                                System.err.println("ERROR DE ENTREGA DE FEATURE EN hasNext del Iterador");
197
                                }
198
                                /* if (delRows.get(calculatedIndex))
199
                                        feat = null; */
200
                                return true;
201
                        }
202

    
203
                }
204

    
205
                public IFeature next() throws DriverException {
206
                        return feat;
207
                }
208

    
209
                public void closeIterator() throws DriverException {
210
                        // TODO Auto-generated method stub
211

    
212
                }
213

    
214
                private void getFeaturesFromExpansionFile() {
215
                        Envelope e = FConverter.convertRectangle2DtoEnvelope(extent);
216
                        listFromExpansion = index.query(e);
217
                }
218
        }
219

    
220
        
221
        private Hashtable mapFID2index = new Hashtable();
222
        private Hashtable mapIndex2FID = new Hashtable();
223
        /**
224
         * 
225
         */
226
        public VectorialEditableDBAdapter() {
227
                super();
228
                // TODO Auto-generated constructor stub
229
        }
230

    
231
        /*
232
         * (non-Javadoc)
233
         * 
234
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getFeatures(java.awt.geom.Rectangle2D,
235
         *      java.lang.String)
236
         */
237
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG)
238
                        throws DriverException {
239
                ArrayList aux = new ArrayList();
240
                IFeatureIterator featIt = getFeatureIterator(r, strEPSG, null);
241
                int numEntities = 0;
242
                while (featIt.hasNext()) {
243
                        IFeature feat = featIt.next();
244
                        // TODO:
245
                        assert(feat !=null);
246
                        int index = getRowIndexByFID(feat);
247
                        IRowEdited edRow = new DefaultRowEdited(feat, IRowEdited.STATUS_ORIGINAL, index);
248
                        aux.add(edRow);
249
                        numEntities++;
250
                }
251

    
252
                return (IRowEdited[]) aux.toArray(new IRowEdited[0]);
253
                // return (IFeature[]) aux.toArray(new IFeature[0]);
254

    
255
        }
256

    
257
        /*
258
         * (non-Javadoc)
259
         * 
260
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#startEdition()
261
         */
262
        public void startEdition() throws EditionException {
263
                isEditing = true;
264
                try {
265
                        expansionFile.open();
266

    
267
                        // TODO: Si la capa dispone de un ?ndice espacial, hacer
268
                        // algo aqu? para que se use ese ?ndice espacial.
269
                        index = new Quadtree();
270
                        // No metemos ninguna entidad de las originales dentro
271
                        // de la base de datos porque esa consulta ya la
272
                        // hace getFeatures sin tener en cuenta el ?ndice local.
273
                         for (int i = 0; i < ova.getShapeCount(); i++)
274
                         {
275
                                 IFeature feat = ova.getFeature(i);
276
                                 Integer calculatedIndex = new Integer(i);
277
                                 mapFID2index.put(feat.getID(), calculatedIndex);
278
                                 mapIndex2FID.put(calculatedIndex, feat.getID());
279
                         }
280

    
281
                        /*
282
                         * for (int i = 0; i < ova.getShapeCount(); i++) { IGeometry g=null;
283
                         * try { g = ((DefaultFeature) ova.getFeature(i)).getGeometry(); }
284
                         * catch (DriverException e1) { // TODO Auto-generated catch block
285
                         * e1.printStackTrace(); }
286
                         * 
287
                         * if (g == null) { continue; }
288
                         * 
289
                         * Rectangle2D r = g.getBounds2D(); Envelope e = new
290
                         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
291
                         * r.getHeight()); index.insert(e, new Integer(i)); } } catch
292
                         * (DriverIOException e) { throw new EditionException(e);
293
                         */
294
                } catch (IOException e) {
295
                        throw new EditionException(e);
296
                } catch (DriverIOException e) {
297
                        throw new EditionException(e);
298
                } catch (DriverException e) {
299
                        throw new EditionException(e);
300
                }
301

    
302
                System.err.println("Se han metido en el ?ndice "
303
                                + index.queryAll().size() + " geometr?as");
304

    
305
        }
306

    
307
        /*
308
         * (non-Javadoc)
309
         * 
310
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#stopEdition(com.iver.cit.gvsig.fmap.edition.IWriter)
311
         */
312
        public void stopEdition(IWriter writer) throws EditionException {
313
                // TODO Auto-generated method stub
314
                super.stopEdition(writer);
315
        }
316

    
317
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
318
                        throws DriverException {
319
                return new MyIterator(r, strEPSG);
320
        }
321

    
322
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
323
                        String[] alphaNumericFieldsNeeded) throws DriverException {
324
                return new MyIterator(r, strEPSG);
325
        }
326

    
327
        public String[] getFields() {
328
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
329
                return orig.getFields();
330
        }
331

    
332
        public String getWhereClause() {
333
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
334
                return orig.getWhereClause();
335
        }
336

    
337
        public String getTableName() {
338
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
339
                return orig.getTableName();
340
        }
341

    
342
        public DBLayerDefinition getLyrDef() {
343
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
344
                return orig.getLyrDef();
345
        }
346

    
347
        public int getRowIndexByFID(IFeature feat) {
348
                /* int resul;
349
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
350
                resul = orig.getRowIndexByFID(feat);
351
                int externalIndex = -1; 
352
                if (resul == -1)
353
                {
354
                        // No est? en los originales. Si no est? borrado, 
355
                        // estar? en el fichero de expansi?n.
356
                        Integer integer = (Integer) hashFIDtoExpansionFile.get(feat.getID());
357
                        resul = integer.intValue();
358
                        IRowEdited rowEd;
359
                        try {
360
                                rowEd = expansionFile.getRow(resul);
361
                                externalIndex = rowEd.getIndex();
362
                        } catch (IOException e) {
363
                                // TODO Auto-generated catch block
364
                                e.printStackTrace();
365
                        }
366
                                
367
                        
368
                }
369
                else
370
                {
371
                        externalIndex = getInversedIndex(resul); 
372
                } */
373
                Integer calculatedIndex = (Integer) mapFID2index.get(feat.getID());
374
                return getInversedIndex(calculatedIndex.intValue());
375
        }
376

    
377
        /* (non-Javadoc)
378
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doAddRow(com.iver.cit.gvsig.fmap.core.IRow)
379
         */
380
        public int doAddRow(IRow feat) throws DriverIOException, IOException {
381
                int calculatedIndex = super.doAddRow(feat);
382
                Integer posInExpansionFile = (Integer) relations.get(new Integer(calculatedIndex));
383
                Integer virtual = new Integer(calculatedIndex); // calculatedIndex es igual al numero de shapes originales + el numero de entidades a?adidas.
384
                                        // es decir, virtual es el calculatedIndex (no tiene en cuenta los borrados)
385
                                        // calculatedIndex = indiceExterno + borrados hasta ese punto.
386
                mapFID2index.put(feat.getID(), virtual);
387
                mapIndex2FID.put(virtual, feat.getID());
388
                return calculatedIndex;
389
                
390
        }
391

    
392
        /* (non-Javadoc)
393
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doModifyRow(int, com.iver.cit.gvsig.fmap.core.IRow)
394
         */
395
        public int doModifyRow(int calculatedIndex, IRow feat) throws IOException, DriverIOException {
396
                int posAnteriorInExpansionFile = super.doModifyRow(calculatedIndex, feat); // devolver? -1 si es original
397
                // No hacemos nada con las modificaciones sobre los ?ndices.
398
                // Suponiendo que feat tenga la misma ID que la que hab?a antes.
399
                Integer virtual = new Integer(calculatedIndex);
400
                String theIDoriginal = (String) mapIndex2FID.get(virtual);
401
                if (!theIDoriginal.equals(feat.getID()))
402
                {
403
                        AssertionError err = new AssertionError("Fallo al modificar la fila. ID viejo=" + theIDoriginal + " ID nuevo = " + feat.getID());
404
                        err.printStackTrace();
405
                }
406
                // hashFIDtoExpansionFile.put(feat.getID(), new Integer(posInExpansionFile));
407
                mapFID2index.put(feat.getID(), virtual);
408
                mapIndex2FID.put(virtual, feat.getID());                
409
                return posAnteriorInExpansionFile;
410
        }
411

    
412
        /* (non-Javadoc)
413
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doRemoveRow(int)
414
         */
415
        public IRow doRemoveRow(int index) throws DriverIOException, IOException {
416
                // Le entra un calculatedIndex, as? que delRows tiene guardados
417
                // los ?ndices internos, no los externos.
418
                IFeature deletedFeat = (IFeature) super.doRemoveRow(index);
419
                // Lo borramos de hashFIDtoExpansionFile
420
                // hashFIDtoExpansionFile.remove(deletedFeat.getID());
421
                return deletedFeat;
422
        }
423

    
424
        /* (non-Javadoc)
425
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getFeature(int)
426
         */
427
        public IFeature getFeature(int numReg) throws DriverException {
428
                // TODO Auto-generated method stub
429
                return super.getFeature(numReg);
430
        }
431

    
432
        /* (non-Javadoc)
433
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getRow(int)
434
         */
435
        public IRowEdited getRow(int index) throws DriverIOException, IOException {
436
                // TODO Auto-generated method stub
437
                return super.getRow(index);
438
        }
439

    
440
        /* (non-Javadoc)
441
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getShape(int)
442
         */
443
        public IGeometry getShape(int rowIndex) throws DriverIOException {
444
                // TODO Auto-generated method stub
445
                return super.getShape(rowIndex);
446
        }
447

    
448
        /* (non-Javadoc)
449
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getShapeBounds(int)
450
         */
451
        public Rectangle2D getShapeBounds(int index) throws IOException {
452
                // TODO Auto-generated method stub
453
                return super.getShapeBounds(index);
454
        }
455

    
456
        /* (non-Javadoc)
457
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getShapeType(int)
458
         */
459
        public int getShapeType(int index) {
460
                // TODO Auto-generated method stub
461
                return super.getShapeType(index);
462
        }
463

    
464
        /* (non-Javadoc)
465
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#setOriginalVectorialAdapter(com.iver.cit.gvsig.fmap.layers.ReadableVectorial)
466
         */
467
        public void setOriginalVectorialAdapter(ReadableVectorial rv) {
468
                // El ?ndice espacial se est? calcualndo en el startEdition, pero
469
                // OJO: No se hace con un while, sino con un getRow().
470
                // Si va lento, habr? que reescribirlo.
471
                super.setOriginalVectorialAdapter(rv);
472
        }
473

    
474
        /* (non-Javadoc)
475
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#undoAddRow(int)
476
         */
477
        public void undoAddRow(int calculatedIndex) throws DriverIOException, IOException {
478
                // TODO Auto-generated method stub
479
                super.undoAddRow(calculatedIndex);
480
                Integer calculated = new Integer(calculatedIndex);
481
                String theID = (String) mapIndex2FID.get(calculated);
482
                mapFID2index.remove(calculated);
483
                mapIndex2FID.remove(theID);
484
                
485
        }
486

    
487
        /* (non-Javadoc)
488
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#undoModifyRow(int, int)
489
         */
490
        public void undoModifyRow(int geometryIndex, int previousExpansionFileIndex) throws IOException, DriverIOException {
491
                // TODO Auto-generated method stub
492
                super.undoModifyRow(geometryIndex, previousExpansionFileIndex);
493
        }
494

    
495
        /* (non-Javadoc)
496
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#undoRemoveRow(int)
497
         */
498
        public void undoRemoveRow(int index) throws IOException, DriverIOException {
499
                // TODO Auto-generated method stub
500
                super.undoRemoveRow(index);
501
        }
502

    
503
}