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 |
} |