Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap / src / org / gvsig / fmap / drivers / writing / PruebaVicenteExpansionFile2.java @ 20989

History | View | Annotate | Download (28 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.fmap.drivers.writing;
42

    
43
import java.awt.geom.Point2D;
44
import java.io.File;
45
import java.io.FileInputStream;
46
import java.io.FileNotFoundException;
47
import java.io.IOException;
48
import java.io.RandomAccessFile;
49
import java.io.UnsupportedEncodingException;
50
import java.nio.ByteBuffer;
51
import java.nio.ByteOrder;
52
import java.nio.channels.FileChannel;
53
import java.nio.channels.WritableByteChannel;
54
import java.nio.channels.FileChannel.MapMode;
55
import java.nio.charset.Charset;
56
import java.sql.Types;
57
import java.text.DateFormat;
58
import java.text.ParseException;
59
import java.util.ArrayList;
60
import java.util.Date;
61
import java.util.HashMap;
62
import java.util.Locale;
63

    
64
import org.gvsig.fmap.core.features.DefaultFeature;
65
import org.gvsig.fmap.core.features.DefaultRowEdited;
66
import org.gvsig.fmap.core.features.IFeature;
67
import org.gvsig.fmap.core.features.IRow;
68
import org.gvsig.fmap.core.features.IRowEdited;
69
import org.gvsig.fmap.core.geometries.IGeometry;
70
import org.gvsig.fmap.core.geometries.utils.FConstant;
71
import org.gvsig.fmap.core.shapes.FShape;
72
import org.gvsig.fmap.core.shapes.GeneralPathX;
73
import org.gvsig.fmap.core.shapes.ShapeFactory;
74
import org.gvsig.fmap.drivers.exceptions.CloseExpansionFileException;
75
import org.gvsig.fmap.drivers.exceptions.ExpansionFileReadException;
76
import org.gvsig.fmap.drivers.exceptions.ExpansionFileWriteException;
77
import org.gvsig.fmap.drivers.exceptions.OpenExpansionFileException;
78
import org.gvsig.fmap.drivers.formats.shp.reading.DbaseFileWriterNIO;
79
import org.gvsig.fmap.drivers.formats.shp.reading.SHP;
80
import org.gvsig.fmap.drivers.formats.shp.reading.write.SHPShape;
81
import org.gvsig.fmap.drivers.formats.shp.reading.write.ShapefileException;
82
import org.gvsig.fmap.drivers.reading.FieldDescription;
83
import org.gvsig.fmap.drivers.writing.adapters.EditableAdapter;
84

    
85
import com.hardcode.gdbms.engine.data.driver.DriverException;
86
import com.hardcode.gdbms.engine.values.BooleanValue;
87
import com.hardcode.gdbms.engine.values.DateValue;
88
import com.hardcode.gdbms.engine.values.NullValue;
89
import com.hardcode.gdbms.engine.values.NumericValue;
90
import com.hardcode.gdbms.engine.values.StringValue;
91
import com.hardcode.gdbms.engine.values.Value;
92
import com.hardcode.gdbms.engine.values.ValueFactory;
93
import com.iver.utiles.bigfile.BigByteBuffer2;
94

    
95

    
96
/**
97
 * Implementaci?n en memoria de ExpansionFile.
98
 *
99
 * @author Vicente Caballero Navarro
100
 */
101
public class PruebaVicenteExpansionFile2 implements ExpansionFile {
102
        //ArrayList rows = new ArrayList();
103
        private static Locale ukLocale = new Locale("en", "UK"); // English, UK version
104
        private EditableAdapter edAdapter;
105
        private Charset charset = Charset.forName("ISO-8859-1");
106
        private DbaseFileWriterNIO.FieldFormatter formatter = new DbaseFileWriterNIO.FieldFormatter();
107

    
108
        private final Number NULL_NUMBER = new Integer(0);
109
        private final String NULL_STRING = "";
110
        private final String NULL_DATE = "        ";
111

    
112
        //private WritableByteChannel dbfchannelWriter;
113
        //private WritableByteChannel shxchannelWriter;
114

    
115

    
116
        private SHPShape m_shape = null;
117

    
118
        private FileChannel readChannel;
119
        private FileChannel shpChannelWriter;
120
        private FileChannel shxChannelWriter;
121
        private FileChannel dbfChannelWriter;
122

    
123
        private int m_pos = 0;
124
        private int m_offset;
125
        private int m_cnt;
126
        private ArrayList indexControl=new ArrayList();
127

    
128
        private BigByteBuffer2 bbRead;
129
        private BigByteBuffer2 bbShxRead;
130
        private BigByteBuffer2 bbDbfRead;
131
        private ByteBuffer bbWriter = null;
132
        private ByteBuffer bbShxWriter = null;
133

    
134
        private FileChannel readChannelShx;
135
        private ByteBuffer cachedRecordRead = null;
136

    
137
        private int posActual = -1;
138
        private int recordOffset;
139
        private byte[] bytesCachedRecord = null;
140
        private Charset chars;
141
        private RandomAccessFile raf;
142
        private MapMode mode;
143
        private FileInputStream finShx;
144
        private ByteBuffer dbfBuffer;
145

    
146

    
147
        private class Index{
148
                private int internalIndex;
149
                private int position;
150
                private int status;
151
                private int type;
152
                public Index(int type,int indexInternalFields, int pos,int status) {
153
                        this.type=type;
154
                        internalIndex=indexInternalFields;
155
                        position=pos;
156
                        this.status=status;
157
                }
158
                public int getInternalIndex() {
159
                        return internalIndex;
160
                }
161
                public void setInternalIndex(int internalIndex) {
162
                        this.internalIndex = internalIndex;
163
                }
164
                public int getPosition() {
165
                        return position;
166
                }
167
                public void setPosition(int position) {
168
                        this.position = position;
169
                }
170
                public int getStatus() {
171
                        return status;
172
                }
173
                public void setStatus(int status) {
174
                        this.status = status;
175
                }
176
                public int getType() {
177
                        return type;
178
                }
179
                public void setType(int type) {
180
                        this.type = type;
181
                }
182
        }
183

    
184
        private class InternalRow
185
        {
186
                private IRowEdited row;
187
                private int indexInternalFields;
188
                public InternalRow(IRowEdited row, int indexInternalFields)
189
                {
190
                        this.row = row;
191
                        this.indexInternalFields = indexInternalFields;
192
                }
193
                public int getIndexInternalFields() {
194
                        return indexInternalFields;
195
                }
196
                public IRowEdited getRow() {
197
                        return row;
198
                }
199
        }
200

    
201
        public PruebaVicenteExpansionFile2(EditableAdapter edAdapter){
202
                this.edAdapter = edAdapter;
203
        }
204

    
205
        //BitSet invalidRows = new BitSet();
206
        /**
207
         * @see org.gvsig.fmap.drivers.writing.ExpansionFile#addRow(IRow, int)
208
         */
209
        public int addRow(IRow row, int status, int indexInternalFields) throws ExpansionFileWriteException {
210
                int newIndex = indexControl.size();
211
                IRowEdited edRow = new DefaultRowEdited(row,
212
                                status, newIndex);
213
                //InternalRow iRow = new InternalRow(edRow, indexInternalFields);
214
                Value[] values=edRow.getAttributes();
215
                IGeometry geometry=((IFeature)edRow.getLinkedRow()).getGeometry();
216
                int pos=doAddRow(values,geometry);
217
                indexControl.add(new Index(geometry.getGeometryType(),indexInternalFields,pos,status));
218
                return newIndex;
219
        }
220

    
221
        /**
222
         * Devuelve la geometria a partir de un ?ndice.
223
         *
224
         * @param index DOCUMENT ME!
225
         *
226
         * @return DOCUMENT ME!
227
         *
228
         * @throws IOException DOCUMENT ME!
229
         */
230
        public synchronized IGeometry getShape(int position,int index,int type) {
231
                Point2D.Double p = new Point2D.Double();
232
                int numParts;
233
                int numPoints;
234
                int i;
235
                int j;
236
                /* int numReg;
237
                int numeroPuntos;
238
                int hasta;
239
                int desde; */
240
                int shapeType;
241

    
242
                //Rectangle2D.Double BoundingBox;
243
        // if (m_posShapes[index] == 0)
244

    
245
                // bb.position(m_posShapes[index]);
246
        bbRead.position(getPositionForRecord(index));
247
                bbRead.order(ByteOrder.LITTLE_ENDIAN);
248

    
249
                ///bb.position(bb.position()+4);
250
                shapeType = bbRead.getInt();
251
                System.err.println("type= "+shapeType);
252
                //el shape tal con tema tal y n?mro tal es null
253
                if (shapeType==SHP.NULL){
254
                        return null;
255
                }
256

    
257
                // retrieve that shape.
258
                // tempRecord.setShape(readShape(tempShapeType, tempContentLength, in));
259
                switch (type) {
260
                        case (SHP.POINT2D):
261
                                p = readPoint(bbRead);
262
                        System.err.println("Point= "+p.getX()+", "+p.getY());
263
                                return ShapeFactory.createPoint2D(p.getX(), p.getY());
264

    
265
                        case (SHP.POLYLINE2D):
266

    
267
                                //BoundingBox = readRectangle(bb);
268
                                //bb.getDouble();
269
                                //bb.getDouble();
270
                                //bb.getDouble();
271
                                //bb.getDouble();
272
                                bbRead.position(bbRead.position() + 32);
273
                                numParts = bbRead.getInt();
274
                                numPoints = bbRead.getInt();
275

    
276
                                // part indexes.
277
                                // Geometry geom = GeometryFactory.toGeometryArray();
278
                                GeneralPathX elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD,
279
                                                numPoints);
280

    
281
                                int[] tempParts = new int[numParts];
282

    
283
                                for (i = 0; i < numParts; i++) {
284
                                        tempParts[i] = bbRead.getInt();
285
                                }
286

    
287
                                j = 0;
288

    
289
                                for (i = 0; i < numPoints; i++) {
290
                                        p = readPoint(bbRead);
291

    
292
                                        if (i == tempParts[j]) {
293
                                                elShape.moveTo(p.x, p.y);
294

    
295
                                                if (j < (numParts - 1)) {
296
                                                        j++;
297
                                                }
298
                                        } else {
299
                                                elShape.lineTo(p.x, p.y);
300
                                        }
301
                                }
302

    
303
                                return ShapeFactory.createPolyline2D(elShape);
304

    
305
                        case (SHP.POLYGON2D):
306

    
307
                                //                            BoundingBox = readRectangle(bb);
308
                                bbRead.getDouble();
309
                                bbRead.getDouble();
310
                                bbRead.getDouble();
311
                                bbRead.getDouble();
312

    
313
                                numParts = bbRead.getInt();
314

    
315
                                numPoints = bbRead.getInt();
316

    
317
                                // part indexes.
318
                                // Geometry geom = GeometryFactory.toGeometryArray();
319
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
320

    
321
                                tempParts = new int[numParts];
322

    
323
                                for (i = 0; i < numParts; i++) {
324
                                        tempParts[i] = bbRead.getInt();
325
                                }
326

    
327
                                j = 0;
328

    
329
                                for (i = 0; i < numPoints; i++) {
330
                                        p = readPoint(bbRead);
331

    
332
                                        if (i == tempParts[j]) {
333
                                                elShape.moveTo(p.x, p.y);
334

    
335
                                                if (j < (numParts - 1)) {
336
                                                        j++;
337
                                                }
338
                                        } else {
339
                                                elShape.lineTo(p.x, p.y);
340
                                        }
341
                                }
342

    
343
                                return ShapeFactory.createPolygon2D(elShape);
344

    
345
                        case (SHP.POINT3D):
346

    
347
                                double x = bbRead.getDouble();
348
                                double y = bbRead.getDouble();
349
                                double z = bbRead.getDouble();
350

    
351
                                return ShapeFactory.createPoint3D(x, y, z);
352

    
353
                        case (SHP.POLYLINE3D):
354
                                bbRead.position(bbRead.position() + 32);
355
                                numParts = bbRead.getInt();
356
                                numPoints = bbRead.getInt();
357
                                elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
358
                                tempParts = new int[numParts];
359

    
360
                                for (i = 0; i < numParts; i++) {
361
                                        tempParts[i] = bbRead.getInt();
362
                                }
363

    
364
                                j = 0;
365

    
366
                                for (i = 0; i < numPoints; i++) {
367
                                        p = readPoint(bbRead);
368

    
369
                                        if (i == tempParts[j]) {
370
                                                elShape.moveTo(p.x, p.y);
371

    
372
                                                if (j < (numParts - 1)) {
373
                                                        j++;
374
                                                }
375
                                        } else {
376
                                                elShape.lineTo(p.x, p.y);
377
                                        }
378
                                }
379

    
380
                                double[] boxZ = new double[2];
381
                                boxZ[0] = bbRead.getDouble();
382
                                boxZ[1] = bbRead.getDouble();
383

    
384
                                double[] pZ = new double[numPoints];
385

    
386
                                for (i = 0; i < numPoints; i++) {
387
                                        pZ[i] = bbRead.getDouble();
388
                                }
389

    
390
                                return ShapeFactory.createPolyline3D(elShape, pZ);
391
                        case (SHP.POLYGON3D):
392
                        bbRead.position(bbRead.position() + 32);
393
                        numParts = bbRead.getInt();
394
                        numPoints = bbRead.getInt();
395
                        elShape = new GeneralPathX(GeneralPathX.WIND_EVEN_ODD, numPoints);
396
                        tempParts = new int[numParts];
397

    
398
                        for (i = 0; i < numParts; i++) {
399
                                tempParts[i] = bbRead.getInt();
400
                        }
401

    
402
                        j = 0;
403

    
404
                        for (i = 0; i < numPoints; i++) {
405
                                p = readPoint(bbRead);
406

    
407
                                if (i == tempParts[j]) {
408
                                        elShape.moveTo(p.x, p.y);
409

    
410
                                        if (j < (numParts - 1)) {
411
                                                j++;
412
                                        }
413
                                } else {
414
                                        elShape.lineTo(p.x, p.y);
415
                                }
416
                        }
417

    
418
                        double[] boxpoZ = new double[2];
419
                        boxpoZ[0] = bbRead.getDouble();
420
                        boxpoZ[1] = bbRead.getDouble();
421

    
422
                        double[] poZ = new double[numPoints];
423

    
424
                        for (i = 0; i < numPoints; i++) {
425
                                poZ[i] = bbRead.getDouble();
426
                        }
427

    
428
                        return ShapeFactory.createPolygon3D(elShape, poZ);
429

    
430
                        case (SHP.MULTIPOINT2D):
431
                                bbRead.position(bbRead.position() + 32);
432
                                numPoints = bbRead.getInt();
433

    
434
                                double[] tempX = new double[numPoints];
435
                                double[] tempY = new double[numPoints];
436

    
437
                                for (i = 0; i < numPoints; i++) {
438
                                        tempX[i] = bbRead.getDouble();
439
                                        tempY[i] = bbRead.getDouble();
440
                                }
441

    
442
                                return ShapeFactory.createMultipoint2D(tempX, tempY);
443

    
444
                        case (SHP.MULTIPOINT3D):
445
                                bbRead.position(bbRead.position() + 32);
446
                                numPoints = bbRead.getInt();
447

    
448
                                double[] temX = new double[numPoints];
449
                                double[] temY = new double[numPoints];
450
                                double[] temZ = new double[numPoints];
451

    
452
                                for (i = 0; i < numPoints; i++) {
453
                                        temX[i] = bbRead.getDouble();
454
                                        temY[i] = bbRead.getDouble();
455
                                        //temZ[i] = bb.getDouble();
456
                                }
457

    
458
                                for (i = 0; i < numPoints; i++) {
459
                                        temZ[i] = bbRead.getDouble();
460
                                }
461
                                return ShapeFactory.createMultipoint3D(temX, temY, temZ);
462
                }
463

    
464
                return null;
465
        }
466

    
467
        private int doAddRow(Value[] values,IGeometry geometry) {
468
                try {
469
                        write(values);
470
                        return writeIGeometry(geometry);
471
                } catch (IOException e) {
472
                        e.printStackTrace();
473
                } catch (ShapefileException e) {
474
                        e.printStackTrace();
475
                }
476
                return -1;
477
        }
478

    
479
        public int modifyRow(int index, IRow row, int indexInternalFields) throws ExpansionFileWriteException {
480
//                  InternalRow iOldRow = (InternalRow) rows.get(index);
481
//                  IRowEdited edRow = new DefaultRowEdited(row,
482
//                    iOldRow.getRow().getStatus(), index);
483
//
484
//                  InternalRow iRow = new InternalRow(edRow, indexInternalFields);
485
//                  rows.add(iRow);
486
//
487
//
488
//                  return rows.size() - 1;
489
                return -1;
490
                 }
491

    
492
        /**
493
         * @see org.gvsig.fmap.drivers.writing.ExpansionFile#getRow(int)
494
         */
495
        public IRowEdited getRow(int index) throws ExpansionFileReadException {
496
                //Index indexControl=(Index)this.index.get(index);
497
                IRowEdited row=doGetRow(index);
498
                return row;
499
//                InternalRow iRow = (InternalRow) rows.get(index);
500
//                int indexInternalFields = indexControl.getInternalIndex();
501
//                return edAdapter.createExternalRow(iRow.getRow(), indexInternalFields);
502
//                 return iRow.getRow();
503

    
504
        }
505
        private IRowEdited doGetRow(int index) {
506
                Index indexControl=(Index)this.indexControl.get(index);
507
                IGeometry geometry=getShape(indexControl.getPosition(),indexControl.getInternalIndex(),indexControl.getType());
508
                FieldDescription[] fds=edAdapter.getFieldsDescription();
509
                int length=fds.length;
510
                Value[] values=new Value[length];
511
                int lengthRow=0;
512
                for (int i=0;i<fds.length;i++) {
513
                        lengthRow+=fds[i].getFieldLength();
514
                }
515
                for (int i=0;i<length;i++) {
516
                        try {
517
                                values[i]=getFieldValue(indexControl.getInternalIndex(),i,lengthRow);
518
                        } catch (DriverException e) {
519
                                e.printStackTrace();
520
                        }
521
                }
522
                DefaultFeature fea = new DefaultFeature(geometry,values);
523
                IRowEdited edRow = new DefaultRowEdited(fea,
524
                            indexControl.getStatus(), index);
525
                return edRow;
526
        }
527
        /**
528
         * @see com.iver.cit.gvsig.fmap.edition.ExpansionFile#invalidateRow(int)
529
         */
530
        /*public void invalidateRow(int index) {
531
                invalidRows.set(index, true);
532
        }
533
*/
534
        /**
535
         * @see org.gvsig.fmap.drivers.writing.ExpansionFile#compact()
536
         */
537
        public void compact(HashMap relations) {
538
        /*        ArrayList geoAux = new ArrayList();
539
                Iterator iter = relations.keySet().iterator();
540
                HashMap aux = new HashMap();
541
                int n = 0;
542

543
                while (iter.hasNext()) {
544
                        Integer virtualIndex = (Integer) iter.next();
545
                        Integer expansionIndex = (Integer) relations.get(virtualIndex);
546

547
                        if (!invalidRows.get(expansionIndex.intValue())){
548
                                geoAux.add(rows.get(expansionIndex.intValue()));
549
                                aux.put(new Integer(n), new Integer(geoAux.size()-1));
550
                                n++;
551
                        }
552
                }
553

554
                invalidRows.clear();
555
                rows = geoAux;
556
                relations.clear();
557
                relations.putAll(aux);
558
*/
559

    
560
        }
561

    
562
        /**
563
         * @see org.gvsig.fmap.drivers.writing.ExpansionFile#getRowCount()
564
         */
565
        /*public int getRowCount() {
566
                return rows.size() - invalidRows.cardinality();
567
        }
568
*/
569
        public void deleteLastRow() {
570
//                rows.remove(rows.size()-1);
571
        }
572

    
573
        public void open() throws OpenExpansionFileException {
574
                initDBFBuffer();
575
                try {
576
                        shpChannelWriter=(FileChannel) getWriteChannel("c:/pruebaVicente.shp");
577

    
578
                dbfChannelWriter=(FileChannel)getWriteChannel("c:/pruebaVicente.dbf");
579
                shxChannelWriter=(FileChannel)getWriteChannel("c:/pruebaVicente.shx");
580
                File file=new File("c:/pruebaVicente.dbf");
581
                if (file.canWrite()) {
582
                        try {
583
                                raf = new RandomAccessFile(file, "rw");
584
                                mode = FileChannel.MapMode.READ_WRITE;
585
                        } catch (FileNotFoundException e) {
586
                                raf = new RandomAccessFile(file, "r");
587
                                mode = FileChannel.MapMode.READ_ONLY;
588
                        }
589
                } else {
590
                        raf = new RandomAccessFile(file, "r");
591
                        mode = FileChannel.MapMode.READ_ONLY;
592
                }
593
                readChannel = raf.getChannel();
594

    
595
                bbRead = new BigByteBuffer2(readChannel, FileChannel.MapMode.READ_ONLY);
596
                finShx = new FileInputStream(getShxFile(file));
597
                bbDbfRead = new BigByteBuffer2(readChannel, mode);
598
        // Open the file and then get a channel from the stream
599
        readChannelShx = finShx.getChannel();
600
                bbShxRead = new BigByteBuffer2(readChannelShx, FileChannel.MapMode.READ_ONLY);
601
            bbShxRead.order(ByteOrder.BIG_ENDIAN);
602

    
603
            chars = Charset.forName("ISO-8859-1");
604
                } catch (IOException e1) {
605
                        throw new OpenExpansionFileException("",e1);
606
                }
607
        }
608
        public File getShxFile(File f) {
609
        String str = f.getAbsolutePath();
610

    
611
        return new File(str.substring(0, str.length() - 3) + "shx");
612
    }
613

    
614
        public void close() throws CloseExpansionFileException {
615
                try {
616
                        bbDbfRead = null;
617
                        dbfBuffer=null;
618
                        dbfChannelWriter.close();
619
                        m_shape = null;
620
                        bbShxWriter = null;
621
                        shpChannelWriter.close();
622
                        shxChannelWriter.close();
623
                        shpChannelWriter = null;
624
                        shxChannelWriter = null;
625
                        indexControl.clear();
626
                        readChannel.close();
627
                        readChannelShx.close();
628
                } catch (IOException e) {
629
                        throw new CloseExpansionFileException("",e);
630
                }
631
                        //rows.clear();
632
                        System.gc();
633
        }
634

    
635
        public int getSize() {
636
                return indexControl.size();
637
        }
638
        public void write(Object[] record) throws IOException{
639
                FieldDescription[] fds=edAdapter.getFieldsDescription();
640
                dbfBuffer.position(0);
641

    
642
                    // put the 'not-deleted' marker
643
                    dbfBuffer.put( (byte) ' ');
644

    
645
                    for (int i = 0; i < fds.length; i++) {
646
                      String fieldString = fieldString(record[i], i);
647
//                      if ( header.getFieldLength(i) != fieldString.getBytes().length) {
648
//                          System.out.println(i + " : " + header.getFieldName(i));
649
//                      }
650

    
651

    
652
                      dbfBuffer.put(fieldString.getBytes(charset.name()));
653

    
654
                    }
655

    
656

    
657
                    write();
658
                  }
659

    
660
         private void write() throws IOException {
661
                    dbfBuffer.position(0);
662
                    int r = dbfBuffer.remaining();
663
                    while ( (r -= dbfChannelWriter.write(dbfBuffer)) > 0) {
664
                      ; // do nothing
665
                    }
666
                  }
667
         private void initDBFBuffer() {
668
                 FieldDescription[] fds=edAdapter.getFieldsDescription();
669
                 int tempLength =-1;
670
                 for (int i = 0; i < fds.length; i++) {
671
                         tempLength += fds[i].getFieldLength()+1;
672
                }
673
                 dbfBuffer = ByteBuffer.allocateDirect(tempLength);
674
                 bytesCachedRecord = new byte[tempLength];
675
         }
676
         private String fieldString(Object obj,final int col) {
677
                 FieldDescription[] fds=edAdapter.getFieldsDescription();
678
                 String o;
679
                    final int fieldLen = fds[col].getFieldLength();
680
                    switch (fds[col].getFieldType()) {
681
                      case Types.VARCHAR:
682
                        o = formatter.getFieldString(
683
                          fieldLen,
684
                          (obj instanceof NullValue)? NULL_STRING : ((StringValue) obj).getValue()
685
                        );
686
                        break;
687
                      case Types.BOOLEAN:
688
                        o = (obj instanceof NullValue) ? "F" : ((BooleanValue)obj).getValue() == true ? "T" : "F";
689
                        break;
690
                      case Types.DOUBLE:
691
                      case Types.INTEGER:
692
                      case Types.FLOAT:
693
                              Number number = null;
694
                            if(obj instanceof NullValue){
695
                                    number = NULL_NUMBER;
696
                            }else{
697
                                    NumericValue gVal = (NumericValue) obj;
698
                                    number = new Double(gVal.doubleValue());
699
                            }
700
                        o = formatter.getFieldString(fieldLen,
701
                                        fds[col].getFieldDecimalCount(),
702
                                                number);
703
                        break;
704
                      case Types.DATE:
705
                          if (obj instanceof NullValue)
706
                              o = NULL_DATE;
707
                          else
708
                              o = formatter.getFieldString(((DateValue)obj).getValue());
709
                        break;
710
                      default:
711
                        throw new RuntimeException("Unknown type " + fds[col].getFieldType());
712
                    }
713

    
714
                    return o;
715
                  }
716
         private WritableByteChannel getWriteChannel(String path)
717
     throws IOException {
718
     WritableByteChannel channel;
719

    
720
     File f = new File(path);
721

    
722
     if (!f.exists()) {
723
         System.out.println("Creando fichero " + f.getAbsolutePath());
724

    
725
         if (!f.createNewFile()) {
726
             throw new IOException("Cannot create file " + f);
727
         }
728
     }
729

    
730
     RandomAccessFile raf = new RandomAccessFile(f, "rw");
731
     channel = raf.getChannel();
732

    
733
     return channel;
734
 }
735

    
736

    
737

    
738

    
739
         public int writeIGeometry(IGeometry g) throws IOException, ShapefileException
740
                {
741
                        int shapeType = getShapeType(g.getGeometryType());
742
                        m_shape = SHP.create(shapeType);
743
//                        m_shape.setFlatness(flatness);
744
                        return writeGeometry(g,shapeType);
745
                }
746
         public synchronized int writeGeometry(IGeometry g,int type) throws IOException {
747
                        if (bbWriter == null) {
748
                                allocateBuffers();
749
                                m_offset =50;
750
                                m_cnt = 0;
751

    
752
                                shpChannelWriter.position(0);
753
                                shxChannelWriter.position(0);
754

    
755
                                // throw new IOException("Must write headers first");
756
                        }
757

    
758
                        int posInit=m_offset;
759
                        m_pos = bbWriter.position();
760
                        m_shape.obtainsPoints(g);
761
                        int length = m_shape.getLength(g);
762

    
763
                        // must allocate enough for shape + header (2 ints)
764
                        checkShapeBuffer(length + 8);
765

    
766
                        length /= 2;
767

    
768
                        bbWriter.order(ByteOrder.BIG_ENDIAN);
769
                        bbWriter.putInt(++m_cnt);
770
                        bbWriter.putInt(length);
771
                        bbWriter.order(ByteOrder.LITTLE_ENDIAN);
772
                        bbWriter.putInt(type);
773
                        m_shape.write(bbWriter, g);
774

    
775
                        ///assert (length * 2 == (m_bb.position() - m_pos) - 8);
776
                        m_pos = bbWriter.position();
777

    
778
                        // write to the shx
779
                        bbShxWriter.putInt(m_offset);
780
                        bbShxWriter.putInt(length);
781
                        m_offset += (length + 4);
782
                        drain();
783
                        ///assert(m_bb.position() == 0);
784
                        return posInit; // Devolvemos hasta donde hemos escrito
785
                }
786
         private void allocateBuffers() {
787
                        bbWriter = ByteBuffer.allocateDirect(16 * 1024);
788
                        bbShxWriter = ByteBuffer.allocateDirect(100);
789
                }
790
         /**
791
                 * Returns a shapeType compatible with shapeFile constants from a gvSIG's IGeometry type
792
                 * @param geometryType
793
                 * @return a shapeType compatible with shapeFile constants from a gvSIG's IGeometry type
794
                 */
795
                public int getShapeType(int geometryType) {
796
                        if (geometryType>=FShape.Z){
797
                                switch (geometryType - FShape.Z) {
798
                                case (FShape.POINT):
799
                                        return FConstant.SHAPE_TYPE_POINTZ;
800

    
801
                                case (FShape.LINE):
802
                                        return FConstant.SHAPE_TYPE_POLYLINEZ;
803

    
804
                                case FShape.POLYGON:
805
                                        return FConstant.SHAPE_TYPE_POLYGONZ;
806

    
807
                                case FShape.MULTIPOINT:
808
                                        return FConstant.SHAPE_TYPE_MULTIPOINTZ; //TODO falta aclarar cosas aqu?.
809
                        }
810

    
811
                        }else{
812
                                switch (geometryType) {
813
                                        case FShape.POINT:
814
                                                return FConstant.SHAPE_TYPE_POINT;
815

    
816
                                        case FShape.LINE:
817
                                        case FShape.ELLIPSE:
818
                                        case FShape.CIRCLE:
819
                                        case FShape.ARC:
820
                                                return FConstant.SHAPE_TYPE_POLYLINE;
821

    
822
                                        case FShape.POLYGON:
823
                                                return FConstant.SHAPE_TYPE_POLYGON;
824

    
825
                                        case FShape.MULTIPOINT:
826
                                                return FConstant.SHAPE_TYPE_MULTIPOINT; //TODO falta aclarar cosas aqu?.
827
                                }
828
                        }
829
                                return FConstant.SHAPE_TYPE_NULL;
830
                        }
831

    
832

    
833
                /**
834
                 * Make sure our buffer is of size.
835
                 *
836
                 * @param size DOCUMENT ME!
837
                 */
838
                private void checkShapeBuffer(int size) {
839
                        if (bbWriter.capacity() < size) {
840
                                bbWriter = ByteBuffer.allocateDirect(size);
841
                        }
842
                }
843

    
844
                /**
845
                 * Drain internal buffers into underlying channels.
846
                 *
847
                 * @throws IOException DOCUMENT ME!
848
                 */
849
                private void drain() throws IOException {
850
                        bbWriter.flip();
851
                        bbShxWriter.flip();
852

    
853
                        while (bbWriter.remaining() > 0)
854
                                shpChannelWriter.write(bbWriter);
855

    
856
                        while (bbShxWriter.remaining() > 0)
857
                                shxChannelWriter.write(bbShxWriter);
858

    
859
                        bbWriter.flip().limit(bbWriter.capacity());
860
                        bbShxWriter.flip().limit(bbShxWriter.capacity());
861
                }
862
                /**
863
                 * Reads the Point from the shape file.
864
                 *
865
                 * @param in ByteBuffer.
866
                 *
867
                 * @return Point2D.
868
                 */
869
                private synchronized Point2D.Double readPoint(BigByteBuffer2 in) {
870
                // create a new point
871
                Point2D.Double tempPoint = new Point2D.Double();
872

    
873
                // bytes 1 to 4 are the type and have already been read.
874
                // bytes 4 to 12 are the X coordinate
875
                in.order(ByteOrder.LITTLE_ENDIAN);
876
                tempPoint.setLocation(in.getDouble(), in.getDouble());
877

    
878
                return tempPoint;
879
        }
880

    
881
        private synchronized long getPositionForRecord(int numRec) {
882
                // shx file has a 100 bytes header, then, records
883
                // 8 bytes length, one for each entity.
884
                // first 4 bytes are the offset
885
                // next 4 bytes are length
886

    
887
                int posIndex = 100 + (numRec * 8);
888
                // bbShx.position(posIndex);
889
                long pos = 8 + 2 * bbShxRead.getInt(posIndex);
890

    
891
                return pos;
892
        }
893

    
894
        public Value getFieldValue(long rowIndex, int fieldId, int position)
895
                        throws DriverException {
896
                FieldDescription[] fds=edAdapter.getFieldsDescription();
897
                position*=rowIndex;
898
                for (int i=0;i<fieldId;i++) {
899
                        position+=fds[i].getFieldLength();
900
                }
901
                int fieldType=fds[fieldId].getFieldType();
902
                // Field Type (C  or M)
903
                //char fieldType = fieldTypes[fieldId];
904

    
905
                if (fieldType == Types.BOOLEAN) {
906
                        return ValueFactory.createValue(getBooleanFieldValue(
907
                                        (int) rowIndex, fieldId));
908

    
909
                        /*                }else if (fieldType == 'N'){
910
                         String strValue = dbf.getStringFieldValue(rowIndex, fieldId);
911
                         long value = Long.parseLong(strValue);
912
                         if ((value > Integer.MIN_VALUE) && (value < Integer.MAX_VALUE)){
913
                         return new IntValue((int) value);
914
                         }else{
915
                         return new LongValue(value);
916
                         }
917
                         */
918
                } else if ((fieldType == Types.DOUBLE) || (fieldType == Types.FLOAT)) {
919
                        String strValue;
920
                        try {
921
                                strValue = getStringFieldValue((int) rowIndex, fieldId,position)
922
                                                .trim();
923
                        } catch (UnsupportedEncodingException e1) {
924
                                e1.printStackTrace();
925
                                throw new DriverException(e1);
926
                        }
927

    
928
                        if (strValue.length() == 0) {
929
                                return null;
930
                        }
931
                        double value = 0;
932
                        try {
933
                                value = Double.parseDouble(strValue);
934
                        } catch (Exception e) {
935
                                return ValueFactory.createValue(0D);
936
                        }
937
                        return ValueFactory.createValue(value);
938
                } else if (fieldType == Types.VARCHAR) {
939
                        try {
940
                                return ValueFactory.createValue(getStringFieldValue(
941
                                                (int) rowIndex, fieldId,position).trim());
942
                        } catch (UnsupportedEncodingException e) {
943
                                throw new DriverException(e);
944
                        }
945
                } else if (fieldType == Types.DATE) {
946
                        String date;
947
                        try {
948
                                date = getStringFieldValue((int) rowIndex, fieldId,position).trim();
949
                        } catch (UnsupportedEncodingException e1) {
950
                                throw new DriverException(e1);
951
                        }
952
                        // System.out.println(rowIndex + " data=" + date);
953
                        if (date.length() == 0) {
954
                                return null;
955
                        }
956

    
957
                        String year = date.substring(0, 4);
958
                        String month = date.substring(4, 6);
959
                        String day = date.substring(6, 8);
960
                        DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT,
961
                                        ukLocale);
962
                        /* Calendar c = Calendar.getInstance();
963
                         c.clear();
964
                         c.set(Integer.parseInt(year), Integer.parseInt(month),
965
                         Integer.parseInt(day));
966
                         c.set(Calendar.MILLISECOND, 0); */
967
                        String strAux = month + "/" + day + "/" + year;
968
                        Date dat;
969
                        try {
970
                                dat = df.parse(strAux);
971
                        } catch (ParseException e) {
972
                                throw new DriverException("Bad Date Format");
973
                        }
974

    
975
                        // System.out.println("numReg = " + rowIndex + " date:" + dat.getTime());
976

    
977
                        return ValueFactory.createValue(dat);
978
                } else {
979
                        throw new DriverException("Unknown field type");
980
                }
981
        }
982
        /**
983
         * DOCUMENT ME!
984
         *
985
         * @param rowIndex
986
         *            DOCUMENT ME!
987
         * @param fieldId
988
         *            DOCUMENT ME!
989
         *
990
         * @return DOCUMENT ME!
991
         */
992
        public boolean getBooleanFieldValue(int rowIndex, int fieldId) {
993
                FieldDescription[] fds=edAdapter.getFieldsDescription();
994
                int recordOffset = (fds.length * rowIndex)
995
                                + 0;
996

    
997
                // Se calcula el offset del campo
998
                int fieldOffset = 0;
999

    
1000
                for (int i = 0; i < (fieldId - 1); i++) {
1001
                        fieldOffset += fds[i].getFieldLength();
1002
                }
1003

    
1004
                bbDbfRead.position(recordOffset + fieldOffset);
1005

    
1006
                char bool = (char) bbDbfRead.get();
1007

    
1008
                return ((bool == 't') || (bool == 'T') || (bool == 'Y') || (bool == 'y'));
1009
        }
1010
        public String getStringFieldValue(int rowIndex, int fieldId, int position)
1011
                        throws UnsupportedEncodingException {
1012
                FieldDescription[] fds=edAdapter.getFieldsDescription();
1013
                int fieldOffset = position;
1014
                byte[] data = new byte[fds[fieldId].getFieldLength()];
1015
                if (rowIndex != posActual) {
1016
                        recordOffset = (fds.length * rowIndex)
1017
                                        + 0;
1018

    
1019
                        /*
1020
                         * System.err.println("getStringFieldValue: rowIndex = " +
1021
                         * rowIndex); System.err.println("recordOffset = " + recordOffset + "
1022
                         * fieldOffset=" + fieldOffset);
1023
                         */
1024
                        bbDbfRead.position(recordOffset);
1025
                        bbDbfRead.get(bytesCachedRecord);
1026
                        cachedRecordRead = ByteBuffer.wrap(bytesCachedRecord);
1027
                        posActual = rowIndex;
1028

    
1029
                }
1030
                cachedRecordRead.position(fieldOffset);
1031
                cachedRecordRead.get(data);
1032

    
1033
                return new String(data, chars.name());
1034

    
1035
        }
1036
}