Statistics
| Revision:

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

History | View | Annotate | Download (8.06 KB)

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

    
3
import java.awt.geom.Rectangle2D;
4
import java.io.File;
5
import java.io.FileInputStream;
6
import java.io.IOException;
7
import java.io.RandomAccessFile;
8
import java.nio.channels.FileChannel;
9
import java.nio.channels.WritableByteChannel;
10
import java.sql.Types;
11

    
12
import com.iver.cit.gvsig.fmap.DriverException;
13
import com.iver.cit.gvsig.fmap.core.FShape;
14
import com.iver.cit.gvsig.fmap.core.IFeature;
15
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
16
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
17
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileHeaderNIO;
18
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileWriterNIO;
19
import com.iver.cit.gvsig.fmap.drivers.shp.write.SHPFileWrite;
20
import com.iver.cit.gvsig.fmap.drivers.shp.write.ShapefileException;
21
import com.iver.cit.gvsig.fmap.edition.EditionException;
22
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
23
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter;
24
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
25
import com.iver.cit.gvsig.fmap.edition.writers.AbstractWriter;
26
import com.iver.cit.gvsig.fmap.layers.FBitSet;
27
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
28
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
29
import com.iver.cit.gvsig.fmap.layers.VectorialFileAdapter;
30
import com.iver.utiles.bigfile.BigByteBuffer2;
31

    
32
public class ShpWriter extends AbstractWriter implements ISpatialWriter {
33
        private String shpPath;
34
        private String shxPath;
35
        private String dbfPath;
36
        
37
        private File shpFile;
38

    
39
        private SHPFileWrite shpWrite;
40
        private DbaseFileWriterNIO dbfWrite;
41

    
42
        private DbaseFileHeaderNIO myHeader;
43

    
44
        private int shapeType;
45
        private int numRows;
46
        private int fileSize;
47
        private Rectangle2D fullExtent;
48
        private Object[] record;
49

    
50
        // private FLyrVect lyrVect;
51
        private FBitSet selection = null;
52

    
53
        public void setFile(File f)
54
        {
55
                shpPath = f.getAbsolutePath();
56

    
57
                String strFichshx = f.getAbsolutePath().replaceAll("\\.shp", ".shx");
58
                shxPath = strFichshx.replaceAll("\\.SHP", ".SHX");
59

    
60
                String strFichDbf = f.getAbsolutePath().replaceAll("\\.shp", ".dbf");
61
                dbfPath = strFichDbf.replaceAll("\\.SHP", ".DBF");
62
                
63
                shpFile = f;
64
        }
65

    
66
        private WritableByteChannel getWriteChannel(String path)
67
                                throws IOException
68
        {
69
                WritableByteChannel channel;
70

    
71
                File f = new File(path);
72

    
73
                if (!f.exists()) {
74
                        System.out.println("Creando fichero " + f.getAbsolutePath());
75

    
76
                        if (!f.createNewFile()) {
77
                                System.err.print("Error al crear el fichero " +
78
                                        f.getAbsolutePath());
79
                                throw new IOException("Cannot create file " + f);
80
                        }
81
                }
82

    
83
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
84
                channel = raf.getChannel();
85

    
86
                return channel;
87
        }
88

    
89
        /**
90
         * Util para crear un fichero .shp desde cero.
91
         * @param shpFile
92
         * @param lyrDef
93
         * @throws IOException
94
         * @throws DriverException
95
         */
96
        /*public ShpWriter(File shpFile, LayerDefinition lyrDef) throws IOException, DriverException
97
        {
98
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(lyrDef.getFieldsDesc());
99
                initialize(shpFile, lyrDef.getShapeType());
100
        }
101

102
        public ShpWriter(File shpFile, FLyrVect lyrVect) throws IOException, DriverException
103
        {
104
                SelectableDataSource sds = lyrVect.getRecordset();
105
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(sds);
106

107
                initialize(shpFile, lyrVect.getShapeType());
108
        }
109
        */
110
        public void initialize(File shpFile, FLyrVect lyrVect) throws IOException, DriverException{
111
                SelectableDataSource sds = lyrVect.getRecordset();
112
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(sds);
113

    
114
                initialize(shpFile, lyrVect.getShapeType());
115
        }
116
        public void initialize(File shpFile, LayerDefinition lyrDef) throws IOException, DriverException
117
        {
118
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(lyrDef.getFieldsDesc());
119
                initialize(shpFile, lyrDef.getShapeType());
120
        }
121
        
122
        /**
123
         * To be used when you need to write to another existing shp file.
124
         * It is used inside IndexedShpDriver.
125
         * @param shpFile
126
         * @throws IOException 
127
         * @throws IOException
128
         * @throws DriverException
129
         */
130
        public void initialize(VectorialEditableAdapter vea) throws EditionException
131
        {
132
                try {
133
                        SelectableDataSource sds = vea.getRecordset();
134
                        myHeader = DbaseFileHeaderNIO.createDbaseHeader(sds);
135
                        initialize(shpFile, vea.getShapeType());
136
                } catch (IOException e) {
137
                        e.printStackTrace();
138
                        throw new EditionException(e);
139
                } catch (DriverIOException e) {
140
                        e.printStackTrace();
141
                        throw new EditionException(e);
142
                }
143
                
144
                
145
        } 
146
        
147
        /* public ShpWriter(File shpFile, FLyrVect lyrVect, FBitSet selection) throws IOException, DriverException
148
        {
149
                SelectableDataSource sds = lyrVect.getRecordset();
150
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(sds);
151

152
                initialize(shpFile, lyrVect, selection);
153
        } */
154

    
155
        private void initialize(File shpFile, int typeFShape) throws IOException //, FLyrVect lyrVect, FBitSet selection) throws IOException, DriverException
156
        {
157
                // this.lyrVect = lyrVect;
158
                // this.selection = selection;
159
                setFile(shpFile);
160

    
161

    
162
                shpWrite = new SHPFileWrite((FileChannel) getWriteChannel(shpPath),
163
                                (FileChannel) getWriteChannel(shxPath));
164
                shapeType = shpWrite.getShapeType(typeFShape);
165
        }
166

    
167
        public void preProcess() throws EditionException {
168
                // Por ahora solo escribimos los primeros bytes
169
                // de las cabeceras. Luego en el postprocess los escribiremos
170
                // correctamente, con el fullExtent y el numero de
171
                // registros que tocan.
172
                if (selection == null)
173
                {
174

    
175
                        try {
176
                                shpWrite.writeHeaders(new Rectangle2D.Double(),
177
                                                shapeType, 0, 0);
178

    
179
                                myHeader.setNumRecords(0);
180
                                dbfWrite = new DbaseFileWriterNIO(myHeader,
181
                                                (FileChannel) getWriteChannel(dbfPath));
182
                                record = new Object[myHeader.getNumFields()];
183
                                numRows = 0;
184
                                fullExtent = null;
185

    
186
                        } catch (IOException e) {
187
                                e.printStackTrace();
188
                                throw new EditionException(e);
189
                        }
190
                }
191

    
192

    
193
        }
194

    
195
        public void process(IRowEdited row) throws EditionException {
196
                IFeature feat = (IFeature) row.getLinkedRow();
197

    
198
                try {
199
                        /* System.out.println("Intento escribir el registro " +
200
                                        numRows + " de la capa " + lyrVect.getName()); */
201
                        fileSize = shpWrite.writeIGeometry(feat.getGeometry());
202
                        Rectangle2D boundsShp = feat.getGeometry().getBounds2D();
203

    
204
                        if (fullExtent == null) {
205
                                fullExtent = boundsShp;
206
                        } else {
207
                                fullExtent.add(boundsShp);
208
                        }
209

    
210
                        for (int i=0; i < record.length; i++)
211
                                record[i] = feat.getAttribute(i);
212
                        dbfWrite.write(record);
213
                        numRows++;
214

    
215
                } catch (IOException e) {
216
                        e.printStackTrace();
217
                        throw new EditionException(e);
218
                } catch (ShapefileException e) {
219
                        e.printStackTrace();
220
                        throw new EditionException(e);
221
                }
222

    
223
        }
224

    
225
        public void postProcess() throws EditionException {
226
                try {
227
                        myHeader.setNumRecords(numRows);
228
                        if (fullExtent == null)
229
                                fullExtent = new Rectangle2D.Double();
230
                        shpWrite.writeHeaders(fullExtent,
231
                                        shapeType, numRows, fileSize);
232

    
233
                        dbfWrite = new DbaseFileWriterNIO(myHeader,
234
                                        (FileChannel) getWriteChannel(dbfPath));
235
                } catch (IOException e) {
236
                        e.printStackTrace();
237
                        throw new EditionException(e);
238
                }
239

    
240

    
241
        }
242
        /**
243
         * Devuelve el path del fichero Shp.
244
         *
245
         * @author azabala
246
         * @return shp path
247
         */
248
        public String getShpPath(){
249
                //Lo necesito para que el ShpSchemaManager sepa
250
                //como "construir" el esquema del fichero SHP/DBF
251
                //adem?s del ShpLayerDefinition
252
                //TODO hacer que ShpWriter implemente ISchemaManager
253
                return this.shpPath;
254
        }
255

    
256
        public String getName() {
257
                return "Shape Writer";
258
        }
259
        public boolean canWriteGeometry(int gvSIGgeometryType) {
260
                switch (gvSIGgeometryType)
261
                {
262
                case FShape.POINT:
263
                        return true;
264
                case FShape.LINE:
265
                        return true;
266
                case FShape.POLYGON:
267
                        return true;
268
                case FShape.ARC:
269
                        return false;
270
                case FShape.ELLIPSE:
271
                        return false;                        
272
                case FShape.MULTIPOINT:
273
                        return true;                        
274
                case FShape.TEXT:
275
                        return false;                                                
276
                }
277
                return false;
278
        }
279

    
280
        public boolean canWriteAttribute(int sqlType) {
281
                switch (sqlType)
282
                {
283
                case Types.DOUBLE:
284
                case Types.FLOAT: 
285
                case Types.INTEGER:
286
                case Types.BIGINT:
287
                        return true;
288
                case Types.DATE:
289
                        return true;
290
                case Types.BIT:
291
                case Types.BOOLEAN:
292
                        return true;                        
293
                case Types.VARCHAR:
294
                case Types.CHAR: 
295
                case Types.LONGVARCHAR:
296
                        return true; // TODO: Revisar esto, porque no creo que admita campos muy grandes
297

    
298
                }
299
                
300
                return false;
301
        }
302

    
303
}