Statistics
| Revision:

gvsig-projects-pool / org.gvsig.lidar.prov / org.gvsig.lidar.prov.common / src / main / java / org / gvsig / lidar / prov / LASDataStoreProvider.java @ 281

History | View | Annotate | Download (12 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2016 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 2
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
package org.gvsig.lidar.prov;
25

    
26
import java.io.File;
27
import java.util.Iterator;
28

    
29
import org.apache.commons.io.FileUtils;
30
import org.gvsig.fmap.dal.DataStore;
31
import org.gvsig.fmap.dal.DataStoreParameters;
32
import org.gvsig.fmap.dal.DataTypes;
33
import org.gvsig.fmap.dal.exception.CloseException;
34
import org.gvsig.fmap.dal.exception.DataException;
35
import org.gvsig.fmap.dal.exception.InitializeException;
36
import org.gvsig.fmap.dal.exception.OpenException;
37
import org.gvsig.fmap.dal.exception.ReadRuntimeException;
38
import org.gvsig.fmap.dal.feature.FeatureQuery;
39
import org.gvsig.fmap.dal.feature.FeatureSet;
40
import org.gvsig.fmap.dal.feature.FeatureStore;
41
import org.gvsig.fmap.dal.feature.FeatureType;
42
import org.gvsig.fmap.dal.feature.exception.PerformEditingException;
43
import org.gvsig.fmap.dal.feature.spi.AbstractFeatureStoreProvider;
44
import org.gvsig.fmap.dal.feature.spi.FeatureProvider;
45
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices;
46
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider;
47
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider;
48
import org.gvsig.fmap.dal.resource.ResourceAction;
49
import org.gvsig.fmap.dal.resource.exception.ResourceException;
50
import org.gvsig.fmap.dal.resource.exception.ResourceExecuteException;
51
import org.gvsig.fmap.dal.resource.file.FileResource;
52
import org.gvsig.fmap.dal.resource.spi.ResourceConsumer;
53
import org.gvsig.fmap.dal.resource.spi.ResourceProvider;
54
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
55
import org.gvsig.fmap.geom.GeometryLocator;
56
import org.gvsig.fmap.geom.GeometryManager;
57
import org.gvsig.fmap.geom.primitive.Envelope;
58
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
59
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
60
import org.gvsig.tools.dispose.DisposableIterator;
61
import org.gvsig.tools.dynobject.DynObject;
62
import org.gvsig.tools.exception.BaseException;
63
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65

    
66
/**
67
 * 
68
 * @author <a href="mailto:cmartinez@scolab.es">Cesar Martinez Izquierdo</a>
69
 *
70
 */
71
public abstract class LASDataStoreProvider extends AbstractFeatureStoreProvider implements
72
    FeatureStoreProvider, ResourceConsumer {
73

    
74
    private static final Logger LOG = LoggerFactory.getLogger(LASDataStoreProvider.class);
75
    
76
    public static final String GEOM_FIELD="GEOM";
77
    public static final String CLASS_FIELD="CLASSIFICATION";
78
    public static final String POINTX_FIELD="POINTX";
79
    public static final String POINTY_FIELD="POINTY";
80
    public static final String POINTZ_FIELD="POINTZ";
81
    public static final String TIME_FIELD="TIME";
82
    public static final String WEEKTIME_FIELD="WEEKTIME";
83
    public static final String COLOR_FIELD="COLOR";
84
    public static final String INTENSITY_FIELD="INTENSITY";
85
    public static final String RETURNNUM_FIELD="RETURNNUM";
86
    public static final String NUMRETURNS_FIELD="NUMRETURNS";
87

    
88
    protected File file;
89

    
90
    protected Envelope envelope = null;
91

    
92
    protected ResourceProvider resourceProvider;
93

    
94
    protected boolean opened = false;
95
    protected long counterNewsOIDs = -1;
96
    
97
    protected  GeometryManager gm;
98
    
99
    protected double decimation = 1.0d;
100
    protected double resolution = 0.0d;
101
 
102
    protected LASDataStoreProvider(DataStoreParameters dataParameters,
103
        DataStoreProviderServices storeServices, DynObject metadata) throws InitializeException {
104
        super(dataParameters, storeServices, metadata);
105

    
106
        // Set CRS parameter to metadata
107
        this.setDynValue(DataStore.METADATA_CRS, dataParameters.getDynValue(DataStore.METADATA_CRS));
108
        file = (File) dataParameters.getDynValue(LASDataStoreParameters.FILE_PARAMETER_NAME);
109
        
110
        if (dataParameters instanceof LASDataStoreParameters) {
111
                LASDataStoreParameters lasParameters = (LASDataStoreParameters) dataParameters;
112
                decimation = (double) lasParameters.getDecimation();
113
                if (decimation<1) {
114
                        decimation = 1;
115
                }
116
                resolution = lasParameters.getResolution();
117
        }
118

    
119
        getResource().addConsumer(this);
120
        this.gm = GeometryLocator.getGeometryManager();
121
        try {
122
            this.open();
123
        } catch (OpenException e) {
124
            throw new InitializeException(getProviderName(), e);
125
        }
126
    }
127
    
128
    /*
129
    public FeatureProvider createFeatureProvider(FeatureType type) throws DataException {
130
        return new DBFFeatureProvider(this, type);
131
    }*/
132

    
133
    @Override
134
    public String getFullName() {
135
            return getName();
136
    }
137

    
138
    @Override
139
    public String getName() {
140
        return getLASParameters().getFile().getName();
141
    }
142

    
143
    @Override
144
    public boolean allowWrite() {
145
            return false;
146
    }
147

    
148
    @Override
149
    public ResourceProvider getResource() {
150
        if (this.resourceProvider == null) {
151
            try {
152
                this.resourceProvider =
153
                    this.createResource(FileResource.NAME, new Object[] { getLASParameters()
154
                        .getFile().getAbsolutePath() });
155
            } catch (InitializeException e) {
156
                throw new ReadRuntimeException(String.format(
157
                    "Can not create file resource with %1s path", getLASParameters().getFile()
158
                        .getAbsolutePath()), e);
159
            }
160
        }
161

    
162
        return resourceProvider;
163
    }
164

    
165
    @Override
166
    public Object getSourceId() {
167
        return this.getLASParameters().getFile();
168
    }
169

    
170
    @Override
171
    public void open() throws OpenException {
172
            // FIXME: should this method be synchronized?
173
        if (opened == false) {
174
            try {
175
                    this.opened = loadFeatureType();
176
                updateDecimationFromResolution();
177
            } catch (BaseException e) {
178
                LOG.error("Can not load feature type", e);
179
                throw new OpenException(getFullName(), e);
180
            }
181
        }
182
    }
183
    
184
    protected void updateDecimationFromResolution() {
185
            if (resolution>0.0d) {
186
                    try {
187
                                double width = getEnvelope().getLength(0);
188
                                double height = getEnvelope().getLength(1);
189
                                long count = getFeatureCount();
190
                                double origResolution = ((count/width)/height); // divide twice instead of multiply denominator to avoid overflow of the product
191
                                double calculatedDecimation = origResolution/resolution;
192
                                if (calculatedDecimation>1) {
193
                                        decimation = calculatedDecimation;
194
                                }
195
                                else {
196
                                        decimation = 1;
197
                                }
198
                        } catch (DataException e) {
199
                                // TODO Auto-generated catch block
200
                                e.printStackTrace();
201
                        }
202
                    
203
            }
204
                    
205
    }
206

    
207
    protected abstract boolean loadFeatureType() throws LASUnsupportedFormatException,
208
        GeometryTypeNotSupportedException, GeometryTypeNotValidException, DataException;
209
    
210
    
211
    @SuppressWarnings("rawtypes")
212
    @Override
213
    public void performChanges(Iterator deleteds, Iterator inserteds,
214
            Iterator updateds, Iterator originalFeatureTypesUpdated)
215
            throws PerformEditingException {
216

    
217
        try {
218
            final FeatureStore store
219
                    = this.getStoreServices().getFeatureStore();
220
            getResource().closeRequest();
221
            getResource().execute(new ResourceAction() {
222

    
223
                public Object run() throws Exception {
224
                    FeatureSet set = null;
225
                    DisposableIterator iter = null;
226
                    try {
227
                        set = store.getFeatureSet();
228
                        LASDataStoreParameters params = (LASDataStoreParameters) getParameters();
229
                        LASDataStoreParameters tmpParams
230
                                = (LASDataStoreParameters) params.getCopy();
231

    
232
                        File tmp_file = File.createTempFile(
233
                                "tmp_" + System.currentTimeMillis(), ".las");
234
                        tmp_file.deleteOnExit();
235

    
236
                        tmpParams.setFile(tmp_file);
237
                        /*
238
                        writer.begin(tmpParams, store.getDefaultFeatureType(),
239
                                set.getSize());
240

241
                        iter = set.fastIterator();
242
                        while (iter.hasNext()) {
243
                            Feature feature = (Feature) iter.next();
244
                            writer.append(feature);
245
                        }
246

247
                        writer.end();
248
                                                */
249
                        try {
250
                            close();
251
                        } catch (CloseException e1) {
252
                            throw new PerformEditingException(getProviderName(), e1);
253
                        }
254
                        params.getFile().delete();
255

    
256
                        File target_file = params.getFile();
257
                        if (target_file.exists()) {
258
                            target_file.delete();
259
                        }
260
                        tmp_file.renameTo(target_file);
261

    
262
                        if (tmp_file.exists() && !target_file.exists()) {
263
                            // Renaming failed, let's simply copy.
264
                            // We assume we cannot delete it, but we
265
                            // used deleteOnExit and it's
266
                            // temporary, so no problem
267
                            LOG.info("Warning: copying tmp file instead of renaming: "
268
                                    + target_file.getName());
269
                            FileUtils.copyFile(tmp_file, target_file);
270
                        }
271
                        
272
                        getResource().notifyChanges();
273
                        loadFeatureType();
274
                    } finally {
275
                        if (set != null) {
276
                            set.dispose();
277
                        }
278
                        if (iter != null) {
279
                            iter.dispose();
280
                        }
281
                    }
282
                    return null;
283
                }
284
            });
285
        } catch (ResourceExecuteException | ResourceException e) {
286
            throw new PerformEditingException(this.getProviderName(), e);
287
        }
288

    
289
        this.counterNewsOIDs = -1;
290
    }
291

    
292
    @Override
293
    public Object createNewOID() {
294
        if (this.counterNewsOIDs < 0) {
295
            try {
296
                this.counterNewsOIDs = this.getFeatureCount();
297
            } catch (DataException e) {
298
                e.printStackTrace();
299
            }
300

    
301
        } else {
302
            this.counterNewsOIDs++;
303
        }
304
        return new Long(counterNewsOIDs);
305
    }
306

    
307
    @Override
308
    public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType)
309
        throws DataException {
310
        open();
311
        return new LASFetureSetProvider(this, query, featureType);
312
    }
313

    
314
    @Override
315
    public int getOIDType() {
316
        return DataTypes.LONG;
317
    }
318

    
319
    @Override
320
    protected FeatureProvider internalGetFeatureProviderByReference(
321
        FeatureReferenceProviderServices reference, FeatureType featureType)
322
        throws DataException {
323

    
324
            return internalGetFeatureProviderByIndex(((Long) reference.getOID()).longValue(), featureType);
325
    }
326
    
327
    public abstract FeatureProvider internalGetFeatureProviderByIndex(
328
                    long index, FeatureType featureType)
329
                                    throws DataException;
330

    
331
    protected LASDataStoreParameters getLASParameters() {
332
        return (LASDataStoreParameters) this.getParameters();
333
    }
334
}