Statistics
| Revision:

svn-gvsig-desktop / tags / J2ME_compat_v1_2_Build_1209 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / VectorialEditableDBAdapter.java @ 19509

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.util.ArrayList;
8
import java.util.Hashtable;
9
import java.util.List;
10

    
11
import org.cresques.cts.IProjection;
12

    
13
import com.hardcode.driverManager.Driver;
14
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
15
import com.iver.cit.gvsig.exceptions.commands.EditionCommandException;
16
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
17
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileWriteException;
18
import com.iver.cit.gvsig.exceptions.layers.CancelEditingLayerException;
19
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
20
import com.iver.cit.gvsig.exceptions.visitors.StopWriterVisitorException;
21
import com.iver.cit.gvsig.fmap.core.IFeature;
22
import com.iver.cit.gvsig.fmap.core.IRow;
23
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
24
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
25
import com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver;
26
import com.iver.cit.gvsig.fmap.drivers.featureiterators.AttrQueryFeatureIterator;
27
import com.iver.cit.gvsig.fmap.layers.ISpatialDB;
28
import com.iver.cit.gvsig.fmap.layers.VectorialDBAdapter;
29
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
30

    
31
/**
32
 * @author fjp
33
 *
34
 */
35
public class VectorialEditableDBAdapter extends VectorialEditableAdapter
36
                implements ISpatialDB {
37
        private class MyIterator implements IFeatureIterator {
38
                private Rectangle2D extent = null;
39

    
40
                private VectorialDBAdapter orig;
41

    
42
                private IFeature feat;
43

    
44
                private IFeatureIterator featIt;
45

    
46
                private String epsg;
47

    
48
                private IVectorialDatabaseDriver dbDriver;
49

    
50
                Hashtable alreadyDone = new Hashtable();
51

    
52
                private int idFromExpansion = 0;
53

    
54
                private List listFromExpansion;
55

    
56
                private boolean bOriginalCursorOpened = true;
57

    
58
                public MyIterator(Rectangle2D r, String strEPSG) throws ReadDriverException {
59
                        extent = r;
60
                        epsg = strEPSG;
61
                        orig = (VectorialDBAdapter) ova;
62
                        featIt = orig.getFeatureIterator(extent, epsg);
63
                        dbDriver = (IVectorialDatabaseDriver) getOriginalDriver();
64
                        getFeaturesFromExpansionFile();
65
                }
66

    
67

    
68
                /*
69
                 * azo: these new constructors must be tested
70
                 * */
71

    
72
                public MyIterator(String[] fields, IProjection newProjection) throws ReadDriverException{
73
                        epsg = newProjection.getAbrev();
74
                        orig = (VectorialDBAdapter) ova;
75
                        featIt = orig.getFeatureIterator(fields, newProjection);
76
                        dbDriver = (IVectorialDatabaseDriver) getOriginalDriver();
77
                        getFeaturesFromExpansionFile();
78
                }
79

    
80
                public MyIterator(String sql, IProjection newProjection) throws ReadDriverException{
81
                        epsg = newProjection.getAbrev();
82
                        orig = (VectorialDBAdapter) ova;
83
                        featIt = orig.getFeatureIterator(sql, newProjection);
84
                        dbDriver = (IVectorialDatabaseDriver) getOriginalDriver();
85
                        getFeaturesFromExpansionFile();
86
                }
87

    
88
                public MyIterator(Rectangle2D rect, String[] fields, IProjection newProjection) throws ReadDriverException{
89
                        extent = rect;
90
                        epsg = newProjection.getAbrev();
91
                        orig = (VectorialDBAdapter) ova;
92
                        featIt = orig.getFeatureIterator(extent, fields, newProjection, true);
93
                        dbDriver = (IVectorialDatabaseDriver) getOriginalDriver();
94
                        getFeaturesFromExpansionFile();
95
                }
96

    
97

    
98

    
99
                public boolean hasNext() throws ReadDriverException {
100
                        feat = null;
101
                        int calculatedIndex = -1;
102
                        if (bOriginalCursorOpened) // Si hay originales (Es porque si se ha
103
                                                                                // llegado al final, se cierra el
104
                                                                                // iterador y salta un fallo
105
                        {
106
                                bOriginalCursorOpened = featIt.hasNext();
107
                                if (bOriginalCursorOpened) {
108
                                        feat = featIt.next();
109
                                        int originalIndex = dbDriver.getRowIndexByFID(feat);
110

    
111
                                        // Iteramos hasta que encontremos alguno no borrado.
112
                                        // Aqu? suponemos que el orden es el original. Si no, no funcionar?.
113
                                        if (delRows.get(originalIndex)) // Si est? borrado
114
                                        {
115
                                                feat = null;
116
                                                boolean bFound = false;
117
                                                while (featIt.hasNext())
118
                                                {
119
                                                        feat = featIt.next();
120
                                                        originalIndex = dbDriver.getRowIndexByFID(feat);
121
                                                        // calculatedIndex = getCalculatedIndex(originalIndex);
122
                                                        if (delRows.get(originalIndex) == false) // Si NO est? borrado
123
                                                        {
124
                                                                bFound = true;
125
                                                                break;
126
                                                        }
127
                                                }
128
                                                if (bFound == false) // Todos los ?ltimos est?n borrados.
129
                                                {
130
                                                        bOriginalCursorOpened = false; // para que busque en el fichero de expansi?n
131
                                                        feat = null;
132
                                                }
133
                                        } // if delRows
134
                                        if (bOriginalCursorOpened) // Si todav?a quedan features por leer, y no est?n borradas
135
                                        {
136
                                                calculatedIndex = originalIndex; //getCalculatedIndex(originalIndex);
137
                                                Integer integer = new Integer(calculatedIndex);
138
                                                if (!relations.containsKey(integer)) { // Si no est? en el
139
                                                                                                                                // fichero de
140
                                                                                                                                // expansi?n
141
                                                        alreadyDone.put(integer, feat);
142
                                                } else { // Si est? en el fichero de expansi?n
143
                                                        int num = ((Integer) relations.get(integer)).intValue();
144
                                                        IRowEdited auxR = null;
145
                                                        try {
146
                                                                auxR = expansionFile.getRow(num);
147
                                                        } catch (ExpansionFileReadException e) {
148
                                                                // TODO Auto-generated catch block
149
                                                                e.printStackTrace();
150
                                                        }
151
                                                        feat = (IFeature) auxR.getLinkedRow().cloneRow();
152
                                                        // feat = (IFeature) auxR.getLinkedRow();
153
                                                        alreadyDone.put(integer, feat);
154
                                                } // else
155
                                        } // if tercer bOriginalCursorOpened
156
                                } // if segundo bOriginalCursorOpened
157
                        } // if primer bOriginalCursorOpened
158
                        if (!bOriginalCursorOpened) {
159
                                // Si ya no hay m?s de las originales, todav?a tenemos
160
                                // que revisar las a?adidas que hay en el fichero
161
                                // de expansi?n
162
                                        while ((idFromExpansion < expansionFile.getSize()) && (feat == null))
163
                                        {
164
                                                IRowEdited rowEd = expansionFile.getRow(idFromExpansion);
165
                                                IFeature aux = (IFeature) rowEd.getLinkedRow();
166
                                                Integer calculated = (Integer) mapFID2index.get(aux.getID());
167
                                                calculatedIndex = calculated.intValue();
168
                                                System.out.println("El elemento idFromExpansion = " + idFromExpansion + " es " + aux.getID());
169

    
170
                                                // Revisamos los borrados
171
                                                if (delRows.get(calculatedIndex) == true)
172
                                                {
173
                                                        boolean bFound = false;
174
                                                        while ((!bFound) && (idFromExpansion < expansionFile.getSize()-1))
175
                                                        {
176
                                                                // calculatedIndex++;
177
                                                                idFromExpansion++;
178
                                                                rowEd = expansionFile.getRow(idFromExpansion);
179
                                                                aux = (IFeature) rowEd.getLinkedRow();
180

    
181

    
182

    
183
                                                                Integer auxCalculated = (Integer) mapFID2index.get(aux.getID());
184
                                                                calculatedIndex = auxCalculated.intValue();
185
                                                                // Si no est? borrado y es una entidad v?lida, que est? siendo usada (no es algo que est? en el expansionFile sin usarse)
186
                                                                if ((delRows.get(calculatedIndex) == false) && (relations.containsKey(auxCalculated)))
187
                                                                {
188
                                                                        bFound = true;
189
                                                                        calculated = auxCalculated;
190
                                                                        break;
191
                                                                }
192
                                                                else
193
                                                                {
194
                                                                        System.out.println("El elemento idFromExpansion = " + idFromExpansion + " est? borrado");
195
                                                                }
196
                                                        }
197
                                                        if (bFound)
198
                                                        {
199
                                                                calculated = new Integer(calculatedIndex);
200
                                                                rowEd = expansionFile.getRow(idFromExpansion);
201
                                                                aux = (IFeature) rowEd.getLinkedRow();
202
                                                        }
203
                                                        else
204
                                                        {
205
                                                                return false; // El resto est?n borrados
206
                                                        }
207
                                                } // if primer borrado
208
                                                if (relations.containsKey(calculated))
209
                                                {
210
                                                        Integer realExpansionIndex = (Integer) relations.get(calculated);
211
                                                        if (realExpansionIndex.intValue() == idFromExpansion)
212
                                                        {
213
                                                                feat = (IFeature) aux.cloneRow();
214
                                                        }
215
                                                }
216
                                                idFromExpansion++;
217
                                        }
218
                        }
219

    
220
                        if (calculatedIndex == -1)
221
                                return false;
222
                        else {
223
                                if (feat == null)
224
                                {
225
                                        if (idFromExpansion == expansionFile.getSize())
226
                                                return false;
227
                                        else
228
                                                System.err.println("ERROR DE ENTREGA DE FEATURE EN hasNext del Iterador");
229
                                }
230
                                /* if (delRows.get(calculatedIndex))
231
                                        feat = null; */
232
                                return true;
233
                        }
234

    
235
                }
236

    
237
                public IFeature next() {
238
                        return feat;
239
                }
240

    
241
                public void closeIterator() throws ReadDriverException {
242
                        // TODO Auto-generated method stub
243

    
244
                }
245

    
246
                private void getFeaturesFromExpansionFile() {
247
//                        Envelope e = FConverter.convertRectangle2DtoEnvelope(extent);
248
                        listFromExpansion = fmapSpatialIndex.query(extent);
249
                }
250
        }
251

    
252

    
253
        private Hashtable mapFID2index = new Hashtable();
254
//        private Hashtable mapIndex2FID = new Hashtable();
255
        /**
256
         *
257
         */
258
        public VectorialEditableDBAdapter() {
259
                super();
260
        }
261

    
262
        /*
263
         * (non-Javadoc)
264
         *
265
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#getFeatures(java.awt.geom.Rectangle2D,
266
         *      java.lang.String)
267
         */
268
        public IRowEdited[] getFeatures(Rectangle2D r, String strEPSG) throws ReadDriverException, ExpansionFileReadException {
269
                ArrayList aux = new ArrayList();
270
                IFeatureIterator featIt = getFeatureIterator(r, strEPSG, null);
271
                int numEntities = 0;
272
                while (featIt.hasNext()) {
273
                        IFeature feat = featIt.next();
274
                        // TODO:
275
                        //assert(feat !=null);
276
                        int index = getRowIndexByFID(feat);
277
                        IRowEdited edRow = new DefaultRowEdited(feat, IRowEdited.STATUS_ORIGINAL, index);
278
                        aux.add(edRow);
279
                        numEntities++;
280
                }
281

    
282
                return (IRowEdited[]) aux.toArray(new IRowEdited[0]);
283
                // return (IFeature[]) aux.toArray(new IFeature[0]);
284

    
285
        }
286

    
287
        /*
288
         * (non-Javadoc)
289
         *
290
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#startEdition()
291
         */
292
        public void startEdition(int sourceType) throws StartWriterVisitorException {
293
                isEditing = true;
294
                Driver drv = ova.getDriver();
295
                if (drv instanceof IWriteable)
296
                {
297
                        setWriter(((IWriteable) drv).getWriter());
298
                }
299

    
300
                try {
301
                        expansionFile.open();
302

    
303
                        // TODO: Si la capa dispone de un ?ndice espacial, hacer
304
                        // algo aqu? para que se use ese ?ndice espacial.
305
//                        index = new Quadtree();
306
                        fmapSpatialIndex = new QuadtreeJts();
307
                        // No metemos ninguna entidad de las originales dentro
308
                        // de la base de datos porque esa consulta ya la
309
                        // hace getFeatures sin tener en cuenta el ?ndice local.
310
                         for (int i = 0; i < ova.getShapeCount(); i++)
311
                         {
312
                                 IFeature feat = ova.getFeature(i);
313
                                 Integer calculatedIndex = new Integer(i);
314
                                 mapFID2index.put(feat.getID(), calculatedIndex);
315
//                                 mapIndex2FID.put(calculatedIndex, feat.getID());
316
                         }
317

    
318
                        /*
319
                         * for (int i = 0; i < ova.getShapeCount(); i++) { IGeometry g=null;
320
                         * try { g = ((DefaultFeature) ova.getFeature(i)).getGeometry(); }
321
                         * catch (DriverException e1) { // TODO Auto-generated catch block
322
                         * e1.printStackTrace(); }
323
                         *
324
                         * if (g == null) { continue; }
325
                         *
326
                         * Rectangle2D r = g.getBounds2D(); Envelope e = new
327
                         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
328
                         * r.getHeight()); index.insert(e, new Integer(i)); } } catch
329
                         * (DriverIOException e) { throw new EditionException(e);
330
                         */
331
                } catch (ReadDriverException e) {
332
                        throw new StartWriterVisitorException(writer.getName(),e);
333
                }
334

    
335
//                System.err.println("Se han metido en el ?ndice "
336
//                                + index.queryAll().size() + " geometr?as");
337

    
338
        }
339

    
340
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
341
                        throws ReadDriverException {
342
                return new MyIterator(r, strEPSG);
343
        }
344

    
345
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
346
                        String[] alphaNumericFieldsNeeded) throws ReadDriverException {
347
                return new MyIterator(r, strEPSG);
348
        }
349

    
350
        public IFeatureIterator getFeatureIterator(String[] fields, IProjection newProjection)
351
        throws ReadDriverException{
352
                //TODO make tests with these (unit test of vectorialeditableadapter)
353
                return new MyIterator(fields, newProjection);
354
//                return new DefaultFeatureIterator(this, projection, newProjection, fields);
355
        }
356

    
357
        //TODO test this (azo)
358
        public IFeatureIterator getFeatureIterator(Rectangle2D rect, String[] fields,
359
                        IProjection newProjection,
360
                        boolean fastIteration) throws ReadDriverException{
361
                return getFeatureIterator(rect, newProjection.getAbrev(), fields);
362
        }
363

    
364
        /**
365
        * Return a feature iterator from a given sql statement.
366
        * <br>
367
        * In this case, the statement will have the "projection" operator
368
        * (select campo1, campo2, ...etc) and the "selection" operator (where ....)
369
        * @param sql statement which define a filter
370
        * @return feature iterator
371
        * */
372
        public IFeatureIterator getFeatureIterator(String sql,
373
                                                                IProjection newProjection) throws ReadDriverException{
374

    
375
                return new AttrQueryFeatureIterator(this, projection, newProjection, sql);
376
        }
377

    
378
        public DBLayerDefinition getLyrDef() {
379
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
380
                return orig.getLyrDef();
381
        }
382

    
383
        public int getRowIndexByFID(IFeature feat) {
384
                Integer calculatedIndex = (Integer) mapFID2index.get(feat.getID());
385
                return getInversedIndex(calculatedIndex.intValue());
386
        }
387

    
388
        /* (non-Javadoc)
389
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doAddRow(com.iver.cit.gvsig.fmap.core.IRow)
390
         */
391
        public int doAddRow(IRow feat, int sourceType) throws ReadDriverException, ExpansionFileWriteException {
392
                int calculatedIndex = super.doAddRow(feat, sourceType);
393
                // Integer posInExpansionFile = (Integer) relations.get(new Integer(calculatedIndex));
394
                Integer virtual = new Integer(calculatedIndex); // calculatedIndex es igual al numero de shapes originales + el numero de entidades a?adidas.
395
                                        // es decir, virtual es el calculatedIndex (no tiene en cuenta los borrados)
396
                                        // calculatedIndex = indiceExterno + borrados hasta ese punto.
397
                mapFID2index.put(feat.getID(), virtual);
398
//                mapIndex2FID.put(virtual, feat.getID());
399
                return calculatedIndex;
400

    
401
        }
402

    
403
        /* (non-Javadoc)
404
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doModifyRow(int, com.iver.cit.gvsig.fmap.core.IRow)
405
         */
406
        public int doModifyRow(int calculatedIndex, IRow feat,int sourceType) throws ReadDriverException, ExpansionFileWriteException, ExpansionFileReadException{
407
                int posAnteriorInExpansionFile = super.doModifyRow(calculatedIndex, feat, sourceType); // devolver? -1 si es original
408
                // No hacemos nada con las modificaciones sobre los ?ndices.
409
                // Suponiendo que feat tenga la misma ID que la que hab?a antes.
410
                Integer virtual = new Integer(calculatedIndex);
411
//                String theIDoriginal = (String) mapIndex2FID.get(virtual);
412
//                if (!theIDoriginal.equals(feat.getID()))
413
//                {
414
//                        //assertionError err = new //assertionError("Fallo al modificar la fila. ID viejo=" + theIDoriginal + " ID nuevo = " + feat.getID());
415
//                        err.printStackTrace();
416
//                }
417
                // hashFIDtoExpansionFile.put(feat.getID(), new Integer(posInExpansionFile));
418
                mapFID2index.put(feat.getID(), virtual);
419
//                mapIndex2FID.put(virtual, feat.getID());
420
                return posAnteriorInExpansionFile;
421
        }
422

    
423
        /* (non-Javadoc)
424
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doRemoveRow(int)
425
         */
426
        public IRow doRemoveRow(int index,int sourceType) throws ReadDriverException, ExpansionFileReadException {
427
                // Le entra un calculatedIndex, as? que delRows tiene guardados
428
                // los ?ndices internos, no los externos.
429
                IFeature deletedFeat = (IFeature) super.doRemoveRow(index, sourceType);
430
                // Lo borramos de hashFIDtoExpansionFile
431
                // hashFIDtoExpansionFile.remove(deletedFeat.getID());
432
                return deletedFeat;
433
        }
434

    
435
        /* (non-Javadoc)
436
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#undoAddRow(int)
437
         */
438
        public void undoAddRow(int calculatedIndex, int sourceType) throws EditionCommandException {
439
                // TODO Auto-generated method stub
440
                super.undoAddRow(calculatedIndex,sourceType);
441
                Integer calculated = new Integer(calculatedIndex);
442
//                String theID = (String) mapIndex2FID.get(calculated);
443
                mapFID2index.remove(calculated);
444
//                mapIndex2FID.remove(theID);
445

    
446
        }
447
        public void cancelEdition(int sourceType) throws CancelEditingLayerException {
448
                super.cancelEdition(sourceType);
449
                mapFID2index.clear();
450
//                mapIndex2FID.clear();
451
        }
452

    
453
        public void stopEdition(IWriter writer, int sourceType) throws StopWriterVisitorException{
454
                super.stopEdition(writer, sourceType);
455
                mapFID2index.clear();
456
//                mapIndex2FID.clear();
457
        }
458
}