Statistics
| Revision:

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

History | View | Annotate | Download (13.6 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.hardcode.driverManager.Driver;
13
import com.iver.cit.gvsig.fmap.DriverException;
14
import com.iver.cit.gvsig.fmap.DriverIOExceptionType;
15
import com.iver.cit.gvsig.fmap.core.IFeature;
16
import com.iver.cit.gvsig.fmap.core.IRow;
17
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
18
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
19
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
20
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
21
import com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver;
22
import com.iver.cit.gvsig.fmap.layers.ISpatialDB;
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
        private int maxIndex=0;
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 IVectorialDatabaseDriver 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 = (IVectorialDatabaseDriver) getOriginalDriver();
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
                                        // Iteramos hasta que encontremos alguno no borrado.
76
                                        // Aqu? suponemos que el orden es el original. Si no, no funcionar?.
77
                                        if (delRows.get(originalIndex)) // Si est? borrado
78
                                        {
79
                                                feat = null;
80
                                                boolean bFound = false;
81
                                                while (featIt.hasNext())
82
                                                {
83
                                                        feat = featIt.next();
84
                                                        originalIndex = dbDriver.getRowIndexByFID(feat);
85
                                                        // calculatedIndex = getCalculatedIndex(originalIndex);
86
                                                        if (delRows.get(originalIndex) == false) // Si NO est? borrado
87
                                                        {
88
                                                                bFound = true;
89
                                                                break;
90
                                                        }
91
                                                }
92
                                                if (bFound == false) // Todos los ?ltimos est?n borrados.
93
                                                {
94
                                                        bOriginalCursorOpened = false; // para que busque en el fichero de expansi?n
95
                                                        feat = null;
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
                                                                DriverIOExceptionType type =
116
                                                                        new DriverIOExceptionType();
117
                                                                type.setDriverName(getDriver().getName());
118
                                                                throw new DriverException(e, type);
119
                                                        }
120

    
121

    
122

    
123

    
124

    
125
                                                } // else
126
                                        } // if tercer bOriginalCursorOpened
127
                                } // if segundo bOriginalCursorOpened
128
                        } // if primer bOriginalCursorOpened
129
                        if (!bOriginalCursorOpened) {
130
                                // Si ya no hay m?s de las originales, todav?a tenemos
131
                                // que revisar las a?adidas que hay en el fichero
132
                                // de expansi?n
133
                                try {
134
                                        while ((idFromExpansion < expansionFile.getSize()) && (feat == null))
135
                                        {
136
                                                IRowEdited rowEd = expansionFile.getRow(idFromExpansion);
137
                                                IFeature aux = (IFeature) rowEd.getLinkedRow();
138
                                                Integer calculated = (Integer) mapFID2index.get(aux.getID());
139
                                                calculatedIndex = calculated.intValue();
140
                                                System.out.println("El elemento idFromExpansion = " + idFromExpansion + " es " + aux.getID());
141

    
142
                                                // Revisamos los borrados
143
                                                if (delRows.get(calculatedIndex) == true)
144
                                                {
145
                                                        boolean bFound = false;
146
                                                        while ((!bFound) && (idFromExpansion < expansionFile.getSize()-1))
147
                                                        {
148
                                                                // calculatedIndex++;
149
                                                                idFromExpansion++;
150
                                                                rowEd = expansionFile.getRow(idFromExpansion);
151
                                                                aux = (IFeature) rowEd.getLinkedRow();
152

    
153

    
154

    
155
                                                                Integer auxCalculated = (Integer) mapFID2index.get(aux.getID());
156
                                                                calculatedIndex = auxCalculated.intValue();
157
                                                                // Si no est? borrado y es una entidad v?lida, que est? siendo usada (no es algo que est? en el expansionFile sin usarse)
158
                                                                if ((delRows.get(calculatedIndex) == false) && (relations.containsKey(auxCalculated)))
159
                                                                {
160
                                                                        bFound = true;
161
                                                                        calculated = auxCalculated;
162
                                                                        break;
163
                                                                }
164
                                                                else
165
                                                                {
166
                                                                        System.out.println("El elemento idFromExpansion = " + idFromExpansion + " est? borrado");
167
                                                                }
168
                                                        }
169
                                                        if (bFound)
170
                                                        {
171
                                                                calculated = new Integer(calculatedIndex);
172
                                                                rowEd = expansionFile.getRow(idFromExpansion);
173
                                                                aux = (IFeature) rowEd.getLinkedRow();
174
                                                        }
175
                                                        else
176
                                                        {
177
                                                                return false; // El resto est?n borrados
178
                                                        }
179
                                                } // if primer borrado
180
                                                if (relations.containsKey(calculated))
181
                                                {
182
                                                        Integer realExpansionIndex = (Integer) relations.get(calculated);
183
                                                        if (realExpansionIndex.intValue() == idFromExpansion)
184
                                                        {
185
                                                                feat = (IFeature) aux.cloneRow();
186
                                                        }
187
                                                }
188
                                                idFromExpansion++;
189
                                        }
190
                                } catch (IOException e) {
191
                                        throw new DriverException(e);
192
                                }
193
                        }
194

    
195
                        if (calculatedIndex == -1)
196
                                return false;
197
                        else {
198
                                if (feat == null)
199
                                {
200
                                        if (idFromExpansion == expansionFile.getSize())
201
                                                return false;
202
                                        else
203
                                                System.err.println("ERROR DE ENTREGA DE FEATURE EN hasNext del Iterador");
204
                                }
205
                                /* if (delRows.get(calculatedIndex))
206
                                        feat = null; */
207
                                return true;
208
                        }
209

    
210
                }
211

    
212
                public IFeature next() throws DriverException {
213
                        return feat;
214
                }
215

    
216
                public void closeIterator() throws DriverException {
217
                        // TODO Auto-generated method stub
218

    
219
                }
220

    
221
                private void getFeaturesFromExpansionFile() {
222
                        Envelope e = FConverter.convertRectangle2DtoEnvelope(extent);
223
                        listFromExpansion = index.query(e);
224
                }
225
        }
226

    
227

    
228
        private Hashtable mapFID2index = new Hashtable();
229
        private Hashtable mapIndex2FID = new Hashtable();
230
        /**
231
         *
232
         */
233
        public VectorialEditableDBAdapter() {
234
                super();
235
        }
236

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

    
258
                return (IRowEdited[]) aux.toArray(new IRowEdited[0]);
259
                // return (IFeature[]) aux.toArray(new IFeature[0]);
260

    
261
        }
262

    
263
        /*
264
         * (non-Javadoc)
265
         *
266
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#startEdition()
267
         */
268
        public void startEdition(int sourceType) throws EditionException {
269
                isEditing = true;
270
                Driver drv = ova.getDriver();
271
                if (drv instanceof IWriteable)
272
                {
273
                        setWriter(((IWriteable) drv).getWriter());
274
                }
275

    
276
                try {
277
                        expansionFile.open();
278

    
279
                        // TODO: Si la capa dispone de un ?ndice espacial, hacer
280
                        // algo aqu? para que se use ese ?ndice espacial.
281
                        index = new Quadtree();
282
                        // No metemos ninguna entidad de las originales dentro
283
                        // de la base de datos porque esa consulta ya la
284
                        // hace getFeatures sin tener en cuenta el ?ndice local.
285

    
286
                        // TODO: URGENTE !!!!!
287
                        // PONER ALGO EN LAS DRIVERS DE BASE DE DATOS PARA QUE
288
                        // ESTO SEA R?PIDO!!! No podemos pedir TOOOOOODAS las features
289
                        // para hacer un ?ndice que YA EXISTE dentro del VectorialDriver!!.
290

    
291
                         for (int i = 0; i < ova.getShapeCount(); i++)
292
                         {
293
                                 IFeature feat = ova.getFeature(i);
294
                                 Integer calculatedIndex = new Integer(i);
295
                                 mapFID2index.put(feat.getID(), calculatedIndex);
296
                                 int featInt=Integer.parseInt(feat.getID());
297
                                 if (maxIndex<featInt){
298
                                         maxIndex=featInt;
299
                                 }
300
                                 mapIndex2FID.put(calculatedIndex, feat.getID());
301
                         }
302

    
303
                        /*
304
                         * for (int i = 0; i < ova.getShapeCount(); i++) { IGeometry g=null;
305
                         * try { g = ((DefaultFeature) ova.getFeature(i)).getGeometry(); }
306
                         * catch (DriverException e1) { // TODO Auto-generated catch block
307
                         * e1.printStackTrace(); }
308
                         *
309
                         * if (g == null) { continue; }
310
                         *
311
                         * Rectangle2D r = g.getBounds2D(); Envelope e = new
312
                         * Envelope(r.getX(), r.getX() + r.getWidth(), r.getY(), r.getY() +
313
                         * r.getHeight()); index.insert(e, new Integer(i)); } } catch
314
                         * (DriverIOException e) { throw new EditionException(e);
315
                         */
316
                } catch (IOException e) {
317
                        throw new EditionException(e);
318
                } catch (DriverIOException e) {
319
                        throw new EditionException(e);
320
                } catch (DriverException e) {
321
                        throw new EditionException(e);
322
                }
323

    
324
                System.err.println("Se han metido en el ?ndice "
325
                                + index.queryAll().size() + " geometr?as");
326

    
327
        }
328

    
329
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG)
330
                        throws DriverException {
331
                return new MyIterator(r, strEPSG);
332
        }
333

    
334
        public IFeatureIterator getFeatureIterator(Rectangle2D r, String strEPSG,
335
                        String[] alphaNumericFieldsNeeded) throws DriverException {
336
                return new MyIterator(r, strEPSG);
337
        }
338

    
339
        public DBLayerDefinition getLyrDef() {
340
                VectorialDBAdapter orig = (VectorialDBAdapter) ova;
341
                return orig.getLyrDef();
342
        }
343

    
344
        public int getRowIndexByFID(IFeature feat) {
345
                Integer calculatedIndex = (Integer) mapFID2index.get(feat.getID());
346
                return getInversedIndex(calculatedIndex.intValue());
347
        }
348

    
349
        /* (non-Javadoc)
350
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doAddRow(com.iver.cit.gvsig.fmap.core.IRow)
351
         */
352
        public int doAddRow(IRow feat, int sourceType) throws DriverIOException, IOException {
353
                int calculatedIndex = super.doAddRow(feat, sourceType);
354
                // Integer posInExpansionFile = (Integer) relations.get(new Integer(calculatedIndex));
355
                Integer virtual = new Integer(calculatedIndex); // calculatedIndex es igual al numero de shapes originales + el numero de entidades a?adidas.
356
                                        // es decir, virtual es el calculatedIndex (no tiene en cuenta los borrados)
357
                                        // calculatedIndex = indiceExterno + borrados hasta ese punto.
358
                mapFID2index.put(feat.getID(), virtual);
359
                mapIndex2FID.put(virtual, feat.getID());
360
                return calculatedIndex;
361

    
362
        }
363

    
364
        /* (non-Javadoc)
365
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doModifyRow(int, com.iver.cit.gvsig.fmap.core.IRow)
366
         */
367
        public int doModifyRow(int calculatedIndex, IRow feat,int sourceType) throws IOException, DriverIOException {
368
                int posAnteriorInExpansionFile = super.doModifyRow(calculatedIndex, feat, sourceType); // devolver? -1 si es original
369
                // No hacemos nada con las modificaciones sobre los ?ndices.
370
                // Suponiendo que feat tenga la misma ID que la que hab?a antes.
371
                Integer virtual = new Integer(calculatedIndex);
372
                String theIDoriginal = (String) mapIndex2FID.get(virtual);
373
                if (!theIDoriginal.equals(feat.getID()))
374
                {
375
                        AssertionError err = new AssertionError("Fallo al modificar la fila. ID viejo=" + theIDoriginal + " ID nuevo = " + feat.getID());
376
                        err.printStackTrace();
377
                }
378
                // hashFIDtoExpansionFile.put(feat.getID(), new Integer(posInExpansionFile));
379
                mapFID2index.put(feat.getID(), virtual);
380
                mapIndex2FID.put(virtual, feat.getID());
381
                return posAnteriorInExpansionFile;
382
        }
383

    
384
        /* (non-Javadoc)
385
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#doRemoveRow(int)
386
         */
387
        public IRow doRemoveRow(int index,int sourceType) throws DriverIOException, IOException {
388
                // Le entra un calculatedIndex, as? que delRows tiene guardados
389
                // los ?ndices internos, no los externos.
390
                IFeature deletedFeat = (IFeature) super.doRemoveRow(index, sourceType);
391
                // Lo borramos de hashFIDtoExpansionFile
392
                // hashFIDtoExpansionFile.remove(deletedFeat.getID());
393
                return deletedFeat;
394
        }
395

    
396
        /* (non-Javadoc)
397
         * @see com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter#undoAddRow(int)
398
         */
399
        public void undoAddRow(int calculatedIndex, int sourceType) throws DriverIOException, IOException {
400
                // TODO Auto-generated method stub
401
                super.undoAddRow(calculatedIndex,sourceType);
402
                Integer calculated = new Integer(calculatedIndex);
403
                String theID = (String) mapIndex2FID.get(calculated);
404
                mapFID2index.remove(calculated);
405
                mapIndex2FID.remove(theID);
406

    
407
        }
408

    
409
        public void cancelEdition(int sourceType) throws IOException {
410
                super.cancelEdition(sourceType);
411
                mapFID2index.clear();
412
                mapIndex2FID.clear();
413
        }
414

    
415
        public void stopEdition(IWriter writer, int sourceType) throws EditionException {
416
                super.stopEdition(writer, sourceType);
417
                mapFID2index.clear();
418
                mapIndex2FID.clear();
419
        }
420

    
421
        public int getNewIndex() throws com.hardcode.gdbms.engine.data.driver.DriverException {
422
                int index = maxIndex+1;
423
                while(mapFID2index.containsKey(String.valueOf(index))){
424
                        index++;
425
                }
426
                return index;
427
        }
428

    
429

    
430
}