Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.shp / src / main / java / org / gvsig / fmap / dal / store / shp / SHPFeatureWriter.java @ 47732

History | View | Annotate | Download (8.53 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.fmap.dal.store.shp;
26

    
27
import java.io.File;
28
import java.io.IOException;
29
import java.nio.channels.FileChannel;
30

    
31
import org.slf4j.Logger;
32
import org.slf4j.LoggerFactory;
33

    
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.exception.WriteException;
36
import org.gvsig.fmap.dal.feature.EditableFeatureType;
37
import org.gvsig.fmap.dal.feature.Feature;
38
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
39
import org.gvsig.fmap.dal.feature.FeatureType;
40
import org.gvsig.fmap.dal.store.dbf.DBFFeatureWriter;
41
import org.gvsig.fmap.dal.store.dbf.DBFStoreParameters;
42
import org.gvsig.fmap.dal.store.shp.utils.SHPFileWrite;
43
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
45
import org.gvsig.fmap.geom.GeometryLocator;
46
import org.gvsig.fmap.geom.GeometryManager;
47
import org.gvsig.fmap.geom.GeometryUtils;
48
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
49
import org.gvsig.fmap.geom.primitive.Envelope;
50
import org.gvsig.fmap.geom.type.GeometryType;
51

    
52
public class SHPFeatureWriter extends DBFFeatureWriter {
53

    
54
    private static final GeometryManager GEOM_MANAGER = GeometryLocator.getGeometryManager();
55
    private static final Logger LOGGER = LoggerFactory.getLogger(SHPFeatureWriter.class);
56

    
57
    private SHPFileWrite shpWrite;
58
    private Envelope envelope = null;
59
    private int[] supportedGeometryTypes;
60
    private int fileSize;
61
    private FeatureType shpFeatureType;
62

    
63
    protected SHPFeatureWriter(String name) {
64
        super(name);
65
    }
66

    
67
    public void begin(DBFStoreParameters dbfParameters, FeatureType featureType, long numRows)
68
        throws DataException {
69
        SHPStoreParameters shpParameters = (SHPStoreParameters) dbfParameters;
70
        File shpFile = shpParameters.getSHPFile();
71
        File shxFile = shpParameters.getSHXFile();
72

    
73
        FileChannel shpChannel = null;
74
        FileChannel shxChannel = null;
75

    
76
        try {
77
            shpChannel =
78
                (FileChannel) getWriteChannel(shpFile.getAbsolutePath());
79
            shxChannel =
80
                (FileChannel) getWriteChannel(shxFile.getAbsolutePath());
81
        } catch (IOException e) {
82
            throw new WriteException(this.name, e);
83
        }
84

    
85
        shpWrite = new SHPFileWrite(shpChannel, shxChannel);
86
        int shapeType = getShapeTypeAndSetSupportedGeometries(featureType);
87
        try {
88
            shpWrite.writeHeaders(
89
                GEOM_MANAGER.createEnvelope(0, 0, 0, 0, featureType.getDefaultGeometryAttribute().getGeomType().getSubType()),
90
                shapeType, 0, 0);
91
        } catch (CreateEnvelopeException e) {
92
            LOGGER.warn("Error creating the envelope", e);
93
        }
94

    
95
        this.shpFeatureType = featureType;
96

    
97
        EditableFeatureType efType = featureType.getEditable();
98
        efType.remove(efType.getDefaultGeometryAttributeIndex());
99
        efType.setDefaultGeometryAttributeName(null);
100
        super.begin(dbfParameters, efType, numRows);
101

    
102
    }
103

    
104
    private int getShapeTypeAndSetSupportedGeometries(FeatureType featureType) {
105

    
106
        FeatureAttributeDescriptor geometryAttr = featureType.getAttributeDescriptor(
107
                featureType.getDefaultGeometryAttributeIndex()
108
        );
109
        int gvSIG_geometryType;
110
        int gvSIG_geometrySubType;
111
        try {
112
            GeometryType geomType = geometryAttr.getGeomType();
113
            gvSIG_geometryType = geomType.getType();
114
            gvSIG_geometrySubType = geomType.getSubType();
115
        } catch(Exception e){
116
            gvSIG_geometryType = geometryAttr.getGeometryType();
117
            gvSIG_geometrySubType = geometryAttr.getGeometrySubType();
118
        }
119
        this.setSupportedGeometryTypes(gvSIG_geometryType);
120
        int shapeType = 0;
121
        shapeType =
122
            shpWrite.getShapeType(gvSIG_geometryType, gvSIG_geometrySubType);
123
        return shapeType;
124
    }
125

    
126
    public void dispose() {
127
        super.dispose();
128
        this.envelope = null;
129
        this.shpWrite = null;
130
    }
131

    
132
    public void end() throws DataException {
133
        try {
134
            if (envelope == null) {
135
                try {
136
                    envelope
137
                        = GEOM_MANAGER.createEnvelope(0, 0, 0, 0, SUBTYPES.GEOM2D);
138
                } catch (CreateEnvelopeException e) {
139
                    LOGGER.error("Error creating the envelope", e);
140
                }
141
            }
142
            int shapeType = getShapeTypeAndSetSupportedGeometries(shpFeatureType);
143
            shpWrite.writeHeaders(envelope, shapeType, super.getRowCount(),
144
                shpWrite.size());
145
            super.end();
146
            shpWrite.close();
147
        } catch (IOException e) {
148
            throw new RuntimeException("Can't write SHP file.", e);
149
        }
150
    }
151

    
152
    public void append(Feature feature) throws DataException {
153

    
154
        Geometry theGeom = feature.getDefaultGeometry();
155
        if (theGeom != null) {
156
            if (!canWriteGeometry(theGeom.getType())) {
157
                throw new WriteException(this.name, // FIXME Excepcion correcta
158
                    new RuntimeException("UnsupportedGeometryType: "
159
                        + theGeom.getGeometryType().getName()));
160
            }
161
            super.append(feature);
162
            fileSize = shpWrite.writeIGeometry(theGeom);
163
            Envelope envelope = theGeom.getEnvelope();
164
            if (envelope != null) {
165
                if (this.envelope != null) {
166
                    this.envelope.add(envelope);
167
                } else {
168
                    this.envelope = envelope;
169
                }
170
            }
171
        } else {
172
            super.append(feature);
173
            fileSize = shpWrite.writeIGeometry(theGeom);
174
        }
175
    }
176

    
177
    private void setSupportedGeometryTypes(int gvSIG_geometryType) {
178
        if( GeometryUtils.isSubtype(Geometry.TYPES.POINT, gvSIG_geometryType) ) {
179
            supportedGeometryTypes =
180
                new int[] { Geometry.TYPES.POINT, Geometry.TYPES.NULL };
181
            return;
182
        }
183
        if( GeometryUtils.isSubtype(Geometry.TYPES.MULTIPOINT, gvSIG_geometryType) ) {
184
            supportedGeometryTypes =
185
                new int[] { Geometry.TYPES.MULTIPOINT, Geometry.TYPES.NULL };
186
            return;
187
        }
188
        if( GeometryUtils.isSubtype(Geometry.TYPES.CURVE, gvSIG_geometryType) ) {
189
            supportedGeometryTypes =
190
                new int[] { Geometry.TYPES.MULTICURVE, Geometry.TYPES.CURVE, Geometry.TYPES.NULL };
191
            return;
192
        }
193
        if( GeometryUtils.isSubtype(Geometry.TYPES.MULTICURVE, gvSIG_geometryType) ) {
194
            supportedGeometryTypes =
195
                new int[] { Geometry.TYPES.MULTICURVE, Geometry.TYPES.CURVE, Geometry.TYPES.NULL };
196
            return;
197
        }
198
        if( GeometryUtils.isSubtype(Geometry.TYPES.SURFACE, gvSIG_geometryType) ) {
199
            supportedGeometryTypes =
200
                new int[] { Geometry.TYPES.MULTISURFACE, Geometry.TYPES.SURFACE, Geometry.TYPES.NULL };
201
            return;
202
        }
203
        if( GeometryUtils.isSubtype(Geometry.TYPES.MULTISURFACE, gvSIG_geometryType) ) {
204
            supportedGeometryTypes =
205
                new int[] { Geometry.TYPES.MULTISURFACE, Geometry.TYPES.SURFACE, Geometry.TYPES.NULL };
206
            return;
207
        }
208
        supportedGeometryTypes = new int[] {};
209
    }
210

    
211
    public boolean canWriteGeometry(int gvSIGgeometryType) {
212
        for (int i = 0; i < supportedGeometryTypes.length; i++) {
213
            if( GeometryUtils.isSubtype(supportedGeometryTypes[i], gvSIGgeometryType)) {
214
                return true;
215
            }
216
        }
217
        return false;
218
    }
219

    
220
//    public void begin(DBFStoreParameters storeParameters,
221
//        FeatureType featureType, long numRows) throws DataException {
222
//        throw new UnsupportedOperationException();
223
//    }
224

    
225
}