Revision 47199
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.spi/src/main/java/org/gvsig/fmap/dal/feature/spi/AbstractFeatureSetProvider.java | ||
---|---|---|
24 | 24 |
package org.gvsig.fmap.dal.feature.spi; |
25 | 25 |
|
26 | 26 |
import java.util.Iterator; |
27 |
import java.util.Objects; |
|
27 | 28 |
import org.apache.commons.lang3.builder.ToStringBuilder; |
29 |
import org.apache.commons.lang3.mutable.MutableObject; |
|
30 |
import org.gvsig.expressionevaluator.Code; |
|
31 |
import org.gvsig.expressionevaluator.Expression; |
|
32 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
|
33 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
|
34 |
import org.gvsig.expressionevaluator.Interpreter; |
|
35 |
import org.gvsig.expressionevaluator.MutableSymbolTable; |
|
36 |
import org.gvsig.expressionevaluator.SymbolTable; |
|
28 | 37 |
|
29 | 38 |
import org.gvsig.fmap.dal.exception.DataException; |
39 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
|
30 | 40 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
31 | 41 |
import org.gvsig.fmap.dal.feature.FeatureType; |
42 |
import org.gvsig.fmap.geom.Geometry; |
|
43 |
import org.gvsig.fmap.geom.SpatialIndex; |
|
44 |
import org.gvsig.fmap.geom.primitive.Envelope; |
|
32 | 45 |
import org.gvsig.tools.dispose.DisposableIterator; |
33 | 46 |
import org.gvsig.tools.dispose.impl.AbstractDisposable; |
47 |
import org.gvsig.tools.exception.BaseException; |
|
48 |
import org.gvsig.tools.visitor.VisitCanceledException; |
|
49 |
import org.gvsig.tools.visitor.Visitor; |
|
34 | 50 |
import org.slf4j.Logger; |
35 | 51 |
import org.slf4j.LoggerFactory; |
36 | 52 |
|
... | ... | |
173 | 189 |
return super.toString(); |
174 | 190 |
} |
175 | 191 |
} |
192 |
|
|
193 |
|
|
194 |
@SuppressWarnings("Convert2Lambda") |
|
195 |
protected Iterator createSpatialIterator(FeatureType featureType, FeatureQuery query, SpatialIndex spatialIndex) { |
|
196 |
if( featureType==null || spatialIndex == null || query == null || query.getFilter()==null) { |
|
197 |
return null; |
|
198 |
} |
|
199 |
FeatureAttributeDescriptor geomdesc = featureType.getDefaultGeometryAttribute(); |
|
200 |
if( geomdesc == null ) { |
|
201 |
return null; |
|
202 |
} |
|
203 |
ExpressionEvaluatorManager expmanager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager(); |
|
204 |
Code filterCode = null; |
|
205 |
try { |
|
206 |
SymbolTable filterSymbolTable = null; |
|
207 |
Expression filterExp = query.getExpressionFilter(); |
|
208 |
if( filterExp == null ) { |
|
209 |
String sql = query.getFilter().getSQL(); |
|
210 |
if( sql == null ) { |
|
211 |
return null; |
|
212 |
} |
|
213 |
filterCode = expmanager.compile(sql); |
|
214 |
} else { |
|
215 |
filterCode = filterExp.getCode(); |
|
216 |
filterSymbolTable = filterExp.getSymbolTable(); |
|
217 |
} |
|
218 |
MutableObject<Code> spatialQuery = new MutableObject<>(); |
|
219 |
try { |
|
220 |
filterCode.accept(new Visitor() { |
|
221 |
@Override |
|
222 |
public void visit(Object obj) throws VisitCanceledException, BaseException { |
|
223 |
if( Code.isFunction((Code) obj, "ST_INTERSECTS") || Code.isFunction((Code) obj, "ST_CONTAINS")) { |
|
224 |
Code.Callable intersects = (Code.Callable)obj; |
|
225 |
Code p1 = intersects.parameters().get(0); |
|
226 |
Code p2 = intersects.parameters().get(1); |
|
227 |
Code sq = null; |
|
228 |
if( Code.isIdentifier(p1, geomdesc.getName()) ) { |
|
229 |
sq = p2; |
|
230 |
} else if( Code.isIdentifier(p2, geomdesc.getName()) ) { |
|
231 |
sq = p1; |
|
232 |
} |
|
233 |
if( sq != null ) { |
|
234 |
spatialQuery.setValue(sq); |
|
235 |
throw new VisitCanceledException(); |
|
236 |
} |
|
237 |
} |
|
238 |
} |
|
239 |
}); |
|
240 |
} catch(VisitCanceledException ex) { |
|
241 |
|
|
242 |
} |
|
243 |
if( spatialQuery.getValue()!=null ) { |
|
244 |
Interpreter interpreter = expmanager.createInterpreter(); |
|
245 |
MutableSymbolTable symbolTable; |
|
246 |
if( filterSymbolTable instanceof MutableSymbolTable ) { |
|
247 |
interpreter.setSymbolTable(filterSymbolTable); |
|
248 |
} else { |
|
249 |
symbolTable = expmanager.createSymbolTable(); |
|
250 |
if( filterSymbolTable != null ) { |
|
251 |
symbolTable.addSymbolTable(filterSymbolTable); |
|
252 |
} |
|
253 |
interpreter.setSymbolTable(symbolTable); |
|
254 |
} |
|
255 |
Envelope envelope = null; |
|
256 |
Object value = interpreter.runCode(spatialQuery.getValue()); |
|
257 |
if( value instanceof Geometry ) { |
|
258 |
envelope = ((Geometry)value).getEnvelope(); |
|
259 |
} else if( value instanceof Envelope ) { |
|
260 |
envelope = (Envelope) value; |
|
261 |
} |
|
262 |
if( envelope!=null ) { |
|
263 |
return spatialIndex.query(envelope, Long.MAX_VALUE); |
|
264 |
} |
|
265 |
} |
|
266 |
} catch (Exception ex) { |
|
267 |
LOGGER.warn("Can't use spatial index for query '"+Objects.toString(filterCode)+"'.",ex); |
|
268 |
} |
|
269 |
return null; |
|
270 |
} |
|
271 |
|
|
176 | 272 |
} |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.file/org.gvsig.fmap.dal.file.csv/src/main/java/org/gvsig/fmap/dal/store/csv/CSVFeatureWriter.java | ||
---|---|---|
7 | 7 |
|
8 | 8 |
import java.io.File; |
9 | 9 |
import java.io.FileOutputStream; |
10 |
import java.io.FileWriter; |
|
11 | 10 |
import java.io.IOException; |
12 | 11 |
import java.io.OutputStreamWriter; |
13 | 12 |
import java.io.Writer; |
... | ... | |
24 | 23 |
import org.gvsig.fmap.geom.Geometry; |
25 | 24 |
import org.gvsig.fmap.geom.GeometryLocator; |
26 | 25 |
import org.gvsig.fmap.geom.GeometryManager; |
26 |
import org.gvsig.fmap.geom.SpatialIndex; |
|
27 | 27 |
import org.gvsig.fmap.geom.operation.GeometryOperationException; |
28 | 28 |
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException; |
29 | 29 |
import org.gvsig.fmap.geom.primitive.Envelope; |
... | ... | |
63 | 63 |
private boolean includeMetadataInHeader; |
64 | 64 |
private Locale locale; |
65 | 65 |
private GeometryManager geometryManager; |
66 |
private SpatialIndex spatialIndex; |
|
66 | 67 |
|
67 |
public void initialize(CSVStoreParameters storeParameters, File file, FeatureType ftype, CsvPreference csvpreferences) { |
|
68 |
public void initialize( |
|
69 |
CSVStoreParameters storeParameters, |
|
70 |
File file, |
|
71 |
FeatureType ftype, |
|
72 |
CsvPreference csvpreferences |
|
73 |
) { |
|
74 |
this.initialize(storeParameters, file, ftype, csvpreferences, null); |
|
75 |
} |
|
76 |
|
|
77 |
public void initialize( |
|
78 |
CSVStoreParameters storeParameters, |
|
79 |
File file, |
|
80 |
FeatureType ftype, |
|
81 |
CsvPreference csvpreferences, |
|
82 |
SpatialIndex spatialIndex |
|
83 |
) { |
|
68 | 84 |
this.file = file; |
69 | 85 |
this.ftype = ftype; |
70 | 86 |
this.storeParameters = storeParameters; |
... | ... | |
87 | 103 |
this.includeMetadataInHeader = CSVStoreParameters.getIncludeMetadataInHeader(storeParameters); |
88 | 104 |
this.locale = CSVStoreParameters.getLocale(storeParameters); |
89 | 105 |
this.geometryManager = GeometryLocator.getGeometryManager(); |
106 |
this.spatialIndex = spatialIndex; |
|
107 |
if( spatialIndex != null ) { |
|
108 |
spatialIndex.removeAll(); |
|
90 | 109 |
} |
91 | 110 |
|
111 |
} |
|
112 |
|
|
92 | 113 |
public void beginAppend() { |
93 | 114 |
try { |
94 | 115 |
FileOutputStream fos = new FileOutputStream(file, true); |
... | ... | |
108 | 129 |
} |
109 | 130 |
this.values = new String[n]; |
110 | 131 |
} |
111 |
|
|
112 | 132 |
} catch (IOException e) { |
113 | 133 |
LOGGER.warn("Can't open file for write (" + file.getAbsolutePath() + ").", e); |
114 | 134 |
throw new RuntimeException(e); |
... | ... | |
183 | 203 |
} |
184 | 204 |
} |
185 | 205 |
} |
206 |
if( spatialIndex!=null ) { |
|
207 |
Geometry geom = feature.getDefaultGeometry(); |
|
208 |
this.spatialIndex.insert(geom, feature.getOID()); |
|
209 |
} |
|
186 | 210 |
|
187 | 211 |
for (int i = 0; i < descriptors.length; i++) { |
188 | 212 |
FeatureAttributeDescriptor descriptor = descriptors[i]; |
... | ... | |
260 | 284 |
} catch (Exception ex){ |
261 | 285 |
LOGGER.warn("Can't delete index file '"+(indexFile == null?"null":indexFile.getAbsolutePath())+"'", ex); |
262 | 286 |
} |
287 |
if( spatialIndex!=null ) { |
|
288 |
spatialIndex.flush(); |
|
289 |
} |
|
263 | 290 |
} |
264 | 291 |
|
265 | 292 |
public Envelope getEnvelope() { |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.file/org.gvsig.fmap.dal.file.csv/src/main/java/org/gvsig/fmap/dal/store/csv/AbstractFeatureProviderLoadedOnDemand.java | ||
---|---|---|
23 | 23 |
*/ |
24 | 24 |
package org.gvsig.fmap.dal.store.csv; |
25 | 25 |
|
26 |
import org.gvsig.fmap.dal.exception.ReadRuntimeException;
|
|
26 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
|
|
27 | 27 |
import org.gvsig.fmap.dal.feature.FeatureType; |
28 | 28 |
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider; |
29 | 29 |
import org.gvsig.fmap.dal.feature.spi.FeatureProvider; |
... | ... | |
34 | 34 |
|
35 | 35 |
protected boolean loading; |
36 | 36 |
protected boolean loaded; |
37 |
protected String geomName; |
|
37 | 38 |
|
38 | 39 |
public AbstractFeatureProviderLoadedOnDemand(FeatureType type) { |
39 | 40 |
super(type); |
40 | 41 |
loading = false; |
41 | 42 |
loaded = false; |
43 |
FeatureAttributeDescriptor geomdesc = type.getDefaultGeometryAttribute(); |
|
44 |
if( geomdesc!=null ) { |
|
45 |
geomName = geomdesc.getName(); |
|
46 |
} |
|
42 | 47 |
} |
43 | 48 |
|
44 | 49 |
protected void load() { |
... | ... | |
83 | 88 |
|
84 | 89 |
@Override |
85 | 90 |
public Geometry getDefaultGeometry() { |
86 |
return null; |
|
91 |
if( geomName == null ) { |
|
92 |
return null; |
|
93 |
} |
|
94 |
return (Geometry) this.get(geomName); |
|
87 | 95 |
} |
88 | 96 |
|
89 | 97 |
@Override |
90 | 98 |
public Envelope getDefaultEnvelope() { |
91 |
return null; |
|
99 |
Geometry geom = this.getDefaultGeometry(); |
|
100 |
if( geom==null ) { |
|
101 |
return null; |
|
102 |
} |
|
103 |
try { |
|
104 |
return geom.getEnvelope(); |
|
105 |
} catch(Exception ex) { |
|
106 |
// En ocasiones con geometrias incorrectas getEnvelop falla. |
|
107 |
return null; |
|
108 |
} |
|
92 | 109 |
} |
93 | 110 |
|
94 | 111 |
@Override |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.file/org.gvsig.fmap.dal.file.csv/src/main/java/org/gvsig/fmap/dal/store/csv/CSVSetProvider.java | ||
---|---|---|
23 | 23 |
*/ |
24 | 24 |
package org.gvsig.fmap.dal.store.csv; |
25 | 25 |
|
26 |
import java.util.Iterator; |
|
26 | 27 |
import java.util.List; |
27 | 28 |
import java.util.NoSuchElementException; |
28 | 29 |
|
... | ... | |
85 | 86 |
protected long index; |
86 | 87 |
protected FeatureType type; |
87 | 88 |
protected long count; |
89 |
protected final FeatureQuery query; |
|
90 |
protected Iterator spatialIndexIt; |
|
88 | 91 |
|
89 |
public CSVIterator(CSVStoreProvider store, FeatureType type, |
|
92 |
public CSVIterator(CSVStoreProvider store, FeatureQuery query, FeatureType type,
|
|
90 | 93 |
long startOn) throws DataException { |
91 | 94 |
super(store); |
92 | 95 |
this.index = startOn; |
93 | 96 |
this.type = type; |
97 |
this.query = query; |
|
94 | 98 |
this.count = store.getFeatureCount(); |
99 |
if( this.query!=null ) { |
|
100 |
this.spatialIndexIt = createSpatialIterator( |
|
101 |
store.getFeatureStore().getDefaultFeatureTypeQuietly(), |
|
102 |
query, |
|
103 |
store.getSpatialIndex() |
|
104 |
); |
|
105 |
} |
|
95 | 106 |
} |
96 | 107 |
|
97 | 108 |
@Override |
109 |
protected CSVStoreProvider getFeatureStoreProvider() { |
|
110 |
return (CSVStoreProvider) super.getFeatureStoreProvider(); |
|
111 |
} |
|
112 |
|
|
113 |
@Override |
|
98 | 114 |
protected boolean internalHasNext() { |
115 |
if( this.spatialIndexIt != null ) { |
|
116 |
return this.spatialIndexIt.hasNext(); |
|
117 |
} |
|
99 | 118 |
return this.count > index; |
100 | 119 |
} |
101 | 120 |
|
102 | 121 |
@Override |
103 | 122 |
protected FeatureProvider internalNext() { |
104 |
if (index >= this.count) { |
|
105 |
throw new NoSuchElementException(); |
|
106 |
} |
|
107 | 123 |
CSVFeatureProvider data = new CSVFeatureProvider(getStore(), type); |
108 |
data.setOID(index++); |
|
124 |
if( this.spatialIndexIt != null ) { |
|
125 |
Object oid = this.spatialIndexIt.next(); |
|
126 |
data.setOID(oid); |
|
127 |
} else { |
|
128 |
if (index >= this.count) { |
|
129 |
throw new NoSuchElementException(); |
|
130 |
} |
|
131 |
data.setOID(index++); |
|
132 |
} |
|
109 | 133 |
return data; |
110 | 134 |
} |
111 | 135 |
|
... | ... | |
128 | 152 |
|
129 | 153 |
protected FeatureProvider data; |
130 | 154 |
|
131 |
public FastCSVIterator(CSVStoreProvider store, FeatureType type, |
|
155 |
public FastCSVIterator(CSVStoreProvider store, FeatureQuery query, FeatureType type,
|
|
132 | 156 |
long startOn) throws DataException { |
133 |
super(store, type, startOn); |
|
157 |
super(store, query, type, startOn);
|
|
134 | 158 |
this.data = new CSVFeatureProvider(store, type); |
135 | 159 |
} |
136 | 160 |
|
137 | 161 |
@Override |
138 | 162 |
protected FeatureProvider internalNext() { |
139 |
if (index >= this.count) { |
|
140 |
throw new NoSuchElementException(); |
|
141 |
} |
|
142 |
data.setOID(index++); |
|
143 |
return this.data; |
|
163 |
if( this.spatialIndexIt != null ) { |
|
164 |
Object oid = this.spatialIndexIt.next(); |
|
165 |
data.setOID(oid); |
|
166 |
} else { |
|
167 |
if (index >= this.count) { |
|
168 |
throw new NoSuchElementException(); |
|
169 |
} |
|
170 |
data.setOID(index++); |
|
171 |
} |
|
172 |
return data; |
|
144 | 173 |
} |
145 | 174 |
|
146 | 175 |
@Override |
... | ... | |
203 | 232 |
throws DataException { |
204 | 233 |
return new CSVIterator( |
205 | 234 |
getStore(), |
235 |
getQuery(), |
|
206 | 236 |
getFeatureType(), |
207 | 237 |
index |
208 | 238 |
); |
... | ... | |
213 | 243 |
throws DataException { |
214 | 244 |
return new FastCSVIterator( |
215 | 245 |
getStore(), |
246 |
getQuery(), |
|
216 | 247 |
getFeatureType(), |
217 | 248 |
index |
218 | 249 |
); |
trunk/org.gvsig.desktop/org.gvsig.desktop.compat.cdc/org.gvsig.fmap.dal/org.gvsig.fmap.dal.file/org.gvsig.fmap.dal.file.csv/src/main/java/org/gvsig/fmap/dal/store/csv/CSVStoreProvider.java | ||
---|---|---|
28 | 28 |
import java.io.InputStreamReader; |
29 | 29 |
import java.net.URI; |
30 | 30 |
import java.net.URL; |
31 |
import java.nio.charset.StandardCharsets; |
|
31 | 32 |
import java.util.ArrayList; |
32 | 33 |
import java.util.HashMap; |
33 | 34 |
import java.util.Iterator; |
34 | 35 |
import java.util.List; |
35 |
import java.util.logging.Level;
|
|
36 |
import java.util.Objects;
|
|
36 | 37 |
import org.apache.commons.io.FileUtils; |
37 | 38 |
|
38 | 39 |
import org.apache.commons.io.FilenameUtils; |
... | ... | |
78 | 79 |
import org.gvsig.fmap.geom.Geometry; |
79 | 80 |
import org.gvsig.fmap.geom.GeometryLocator; |
80 | 81 |
import org.gvsig.fmap.geom.GeometryManager; |
82 |
import org.gvsig.fmap.geom.SpatialIndex; |
|
83 |
import org.gvsig.fmap.geom.SpatialIndexFactory; |
|
81 | 84 |
import org.gvsig.fmap.geom.primitive.Envelope; |
82 | 85 |
import org.gvsig.fmap.geom.primitive.Point; |
83 | 86 |
import org.gvsig.tools.ToolsLocator; |
... | ... | |
99 | 102 |
import org.slf4j.LoggerFactory; |
100 | 103 |
import org.supercsv.prefs.CsvPreference; |
101 | 104 |
import org.gvsig.tools.dataTypes.CoercionContext; |
105 |
import org.gvsig.tools.dispose.DisposeUtils; |
|
106 |
import org.gvsig.tools.dynobject.DynObject; |
|
102 | 107 |
import org.gvsig.tools.i18n.I18nManager; |
103 | 108 |
import org.gvsig.tools.util.GetItemWithSize64; |
104 | 109 |
|
... | ... | |
123 | 128 |
private FeatureType featureType; |
124 | 129 |
private GetItemWithSize64<List<String>> virtualrows; |
125 | 130 |
private RowToFeatureTranslator rowToFeatureTranslator; |
126 |
|
|
131 |
private SpatialIndex spatialIndex; |
|
132 |
|
|
127 | 133 |
@SuppressWarnings({"OverridableMethodCallInConstructor", "LeakingThisInConstructor"}) |
128 |
public CSVStoreProvider(CSVStoreParameters parameters, |
|
129 |
DataStoreProviderServices storeServices) throws InitializeException { |
|
134 |
public CSVStoreProvider( |
|
135 |
CSVStoreParameters parameters, |
|
136 |
DataStoreProviderServices storeServices |
|
137 |
) throws InitializeException { |
|
130 | 138 |
super( |
131 | 139 |
parameters, |
132 | 140 |
storeServices, |
... | ... | |
249 | 257 |
} |
250 | 258 |
data = newdata; |
251 | 259 |
if (writer.getEnvelope() != null) { |
252 |
envelope = writer.getEnvelope().getGeometry().getEnvelope(); |
|
260 |
envelope = writer.getEnvelope(); |
|
261 |
} else { |
|
262 |
envelope = null; |
|
253 | 263 |
} |
254 | 264 |
resource.notifyChanges(); |
255 | 265 |
writer.end(); |
256 |
|
|
266 |
bboxFileSave(envelope); |
|
257 | 267 |
} else { |
258 | 268 |
|
259 | 269 |
CSVStoreParameters csvParams = getCSVParameters(); |
... | ... | |
264 | 274 |
tmpParams.setFile(tmpFile); |
265 | 275 |
|
266 | 276 |
FeatureType ftype = getStoreServices().getDefaultFeatureType(); |
267 |
writer.initialize(tmpParams, tmpFile, ftype, getCSVPreferences()); |
|
277 |
writer.initialize(tmpParams, tmpFile, ftype, getCSVPreferences(),spatialIndex);
|
|
268 | 278 |
writer.begin(); |
269 | 279 |
it = features.fastIterator(); |
270 | 280 |
taskStatus.setIndeterminate(); |
... | ... | |
285 | 295 |
} |
286 | 296 |
} |
287 | 297 |
if (writer.getEnvelope() != null) { |
288 |
envelope = writer.getEnvelope().getGeometry().getEnvelope(); |
|
298 |
envelope = writer.getEnvelope(); |
|
299 |
} else { |
|
300 |
envelope = null; |
|
289 | 301 |
} |
290 | 302 |
resource.notifyChanges(); |
291 | 303 |
writer.end(); |
... | ... | |
302 | 314 |
FileUtils.moveFile(tmpParams.getFile(), csvFile); |
303 | 315 |
FileUtils.delete(new File(FilenameUtils.removeExtension(csvFile.getAbsolutePath())+".idx")); |
304 | 316 |
|
317 |
bboxFileSave(envelope); |
|
318 |
|
|
305 | 319 |
loadFeatures(); |
306 | 320 |
} |
307 | 321 |
} |
... | ... | |
390 | 404 |
return null; |
391 | 405 |
} |
392 | 406 |
}); |
407 |
if (writer.getEnvelope() != null) { |
|
408 |
envelope = writer.getEnvelope(); |
|
409 |
} else { |
|
410 |
envelope = null; |
|
411 |
} |
|
393 | 412 |
writer.end(); |
394 | 413 |
this.close(); |
414 |
bboxFileSave(envelope); |
|
415 |
|
|
395 | 416 |
} catch (Exception ex) { |
396 | 417 |
LOGGER.warn("Not been able to end append '" + this.getFullName() + "'.", ex); |
397 | 418 |
} |
... | ... | |
425 | 446 |
if (this.envelope != null) { |
426 | 447 |
return this.envelope; |
427 | 448 |
} |
449 |
this.envelope = bboxFileLoad(); |
|
450 |
if (this.envelope != null) { |
|
451 |
return this.envelope; |
|
452 |
} |
|
428 | 453 |
if (!this.need_calculate_envelope) { |
429 | 454 |
return null; |
430 | 455 |
} |
... | ... | |
448 | 473 |
Feature f = (Feature) obj; |
449 | 474 |
Geometry geom = f.getDefaultGeometry(); |
450 | 475 |
if (geom != null) { |
451 |
envelope.add(geom.getEnvelope()); |
|
476 |
try { |
|
477 |
Envelope env = geom.getEnvelope(); |
|
478 |
envelope.add(env); |
|
479 |
} catch(Exception ex) { |
|
480 |
LOGGER.warn("Can't calculate envelop of geometry in feature '"+Objects.toString(f.getReference())+"'.",ex); |
|
481 |
} |
|
452 | 482 |
} |
453 | 483 |
} |
454 | 484 |
}); |
485 |
bboxFileSave(envelope); |
|
455 | 486 |
taskStatus.terminate(); |
456 | 487 |
} catch (VisitCanceledException e) { |
457 | 488 |
return null; |
... | ... | |
731 | 762 |
// haber cambiado. |
732 | 763 |
ftype = edftype.getNotEditableCopy(); |
733 | 764 |
this.setFeatureType(ftype); |
765 |
} else { |
|
766 |
this.loadOrCreateSpatialIndex(); |
|
734 | 767 |
} |
735 | 768 |
if( taskStatus.isRunning() ) { |
736 | 769 |
taskStatus.terminate(); |
... | ... | |
760 | 793 |
} |
761 | 794 |
// in = null; |
762 | 795 |
} |
796 |
taskStatus.remove(); |
|
763 | 797 |
} |
764 | 798 |
} |
765 | 799 |
|
... | ... | |
825 | 859 |
@Override |
826 | 860 |
public FeatureSetProvider createSet(FeatureQuery query, FeatureType featureType) |
827 | 861 |
throws DataException { |
862 |
this.open(); |
|
828 | 863 |
if (this.virtualrows == null) { |
829 | 864 |
return super.createSet(query, featureType); |
830 | 865 |
} |
... | ... | |
832 | 867 |
} |
833 | 868 |
|
834 | 869 |
public List<String> getRowByIndex(long index) { |
870 |
try { |
|
871 |
this.open(); |
|
872 |
} catch(Exception ex) { |
|
873 |
throw new RuntimeException("Can't get row by index", ex); |
|
874 |
} |
|
835 | 875 |
if (this.virtualrows == null) { |
836 | 876 |
return null; |
837 | 877 |
} |
... | ... | |
856 | 896 |
|
857 | 897 |
@Override |
858 | 898 |
public long getFeatureCount() throws DataException { |
899 |
this.open(); |
|
859 | 900 |
if (this.virtualrows == null) { |
860 | 901 |
return super.getFeatureCount(); |
861 | 902 |
} |
... | ... | |
864 | 905 |
|
865 | 906 |
@Override |
866 | 907 |
public long getDataSize() throws DataException { |
908 |
this.open(); |
|
867 | 909 |
if (this.virtualrows == null) { |
868 | 910 |
return super.getDataSize(); |
869 | 911 |
} |
... | ... | |
873 | 915 |
@Override |
874 | 916 |
protected FeatureProvider internalGetFeatureProviderByReference( |
875 | 917 |
FeatureReferenceProviderServices reference) throws DataException { |
918 |
this.open(); |
|
876 | 919 |
if (this.virtualrows == null) { |
877 | 920 |
return super.internalGetFeatureProviderByReference(reference); |
878 | 921 |
} |
... | ... | |
896 | 939 |
} |
897 | 940 |
} |
898 | 941 |
|
942 |
@Override |
|
899 | 943 |
public void refresh() throws OpenException { |
900 | 944 |
try { |
901 | 945 |
this.close(); |
... | ... | |
912 | 956 |
if(this.virtualrows != null && this.virtualrows instanceof Closeable){ |
913 | 957 |
IOUtils.closeQuietly((Closeable) this.virtualrows); |
914 | 958 |
this.virtualrows = null; |
959 |
this.envelope = null; |
|
960 |
this.spatialIndex = null; |
|
915 | 961 |
} |
916 | 962 |
|
917 | 963 |
} |
918 | 964 |
|
919 | 965 |
|
920 |
|
|
966 |
private void loadOrCreateSpatialIndex() { |
|
967 |
FeatureSetProvider set = null; |
|
968 |
DisposableIterator<FeatureProvider> it = null; |
|
969 |
try { |
|
970 |
if( this.virtualrows == null ) { |
|
971 |
return; |
|
972 |
} |
|
973 |
FeatureAttributeDescriptor geomdesc = this.featureType.getDefaultGeometryAttribute(); |
|
974 |
if( geomdesc == null ) { |
|
975 |
return; |
|
976 |
} |
|
977 |
// String indexTypeName = "MVRTree"; |
|
978 |
// String extname = "mvtree"; |
|
979 |
String indexTypeName = GeometryManager.SPATIALINDEX_DEFAULT_QUADTREE; |
|
980 |
String extname = "qtree"; |
|
981 |
|
|
982 |
this.envelope = bboxFileLoad(); |
|
983 |
File indexfile = this.getAuxFile(extname); |
|
984 |
boolean createIndex = !indexfile.exists(); |
|
921 | 985 |
|
986 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
987 |
SpatialIndexFactory indexfactory = geomManager.getSpatialIndexFactory(indexTypeName); |
|
988 |
DynObject params = indexfactory.createParameters(); |
|
989 |
params.setDynValue("file", indexfile); |
|
990 |
SpatialIndex index = geomManager.createSpatialIndex(indexTypeName, params); |
|
991 |
if( createIndex ) { |
|
992 |
I18nManager i18n = ToolsLocator.getI18nManager(); |
|
993 |
this.taskStatus.add(); |
|
994 |
taskStatus.message(i18n.getTranslation("_Creating_spatial_index")); |
|
995 |
taskStatus.setRangeOfValues(0, this.virtualrows.size64()); |
|
996 |
taskStatus.setCurValue(0); |
|
997 |
Envelope theEnvelope = geomManager.createEnvelope(Geometry.SUBTYPES.GEOM2D); |
|
998 |
set = this.createSet(null, featureType); |
|
999 |
it = set.fastIterator(); |
|
1000 |
while( it.hasNext() ) { |
|
1001 |
taskStatus.incrementCurrentValue(); |
|
1002 |
if( taskStatus.isCancellationRequested() ) { |
|
1003 |
taskStatus.cancel(); |
|
1004 |
LOGGER.info("CSV spatial index creation canceled ("+getFullFileName()+")"); |
|
1005 |
break; |
|
1006 |
} |
|
1007 |
FeatureProvider f = it.next(); |
|
1008 |
if( f == null ) { |
|
1009 |
continue; |
|
1010 |
} |
|
1011 |
Object oid = null; |
|
1012 |
try { |
|
1013 |
oid = f.getOID(); |
|
1014 |
Geometry geom = (Geometry) f.get(geomdesc.getName()); |
|
1015 |
index.insert(geom, oid); |
|
1016 |
theEnvelope.add(geom); |
|
1017 |
} catch(Exception ex) { |
|
1018 |
LOGGER.debug("Can't insert feature '"+Objects.toString(oid)+"' in spatial index.",ex); |
|
1019 |
} |
|
1020 |
} |
|
1021 |
taskStatus.message(i18n.getTranslation("_Saving_spatial_index")); |
|
1022 |
taskStatus.setIndeterminate(); |
|
1023 |
index.flush(); |
|
1024 |
bboxFileSave(theEnvelope); |
|
1025 |
taskStatus.terminate(); |
|
1026 |
this.envelope = theEnvelope; |
|
1027 |
} |
|
1028 |
this.spatialIndex = index; |
|
1029 |
} catch (Exception ex) { |
|
1030 |
taskStatus.abort(); |
|
1031 |
LOGGER.warn("Can't create spatial index.",ex); |
|
1032 |
} finally { |
|
1033 |
DisposeUtils.disposeQuietly(it); |
|
1034 |
DisposeUtils.disposeQuietly(set); |
|
1035 |
taskStatus.remove(); |
|
1036 |
} |
|
1037 |
} |
|
1038 |
|
|
1039 |
public File getAuxFile(String extension) { |
|
1040 |
File data_file = CSVStoreParameters.getFile(this.getCSVParameters()); |
|
1041 |
if (data_file == null){ |
|
1042 |
return null; |
|
1043 |
} |
|
1044 |
File index_file = new File(FilenameUtils.removeExtension(data_file.getAbsolutePath()) + "." + extension); |
|
1045 |
return index_file; |
|
1046 |
} |
|
1047 |
|
|
1048 |
public SpatialIndex getSpatialIndex() { |
|
1049 |
return spatialIndex; |
|
1050 |
} |
|
1051 |
|
|
1052 |
private void bboxFileSave(Envelope envelope) { |
|
1053 |
File bboxfile = this.getAuxFile("bbox"); |
|
1054 |
bboxFileSave(bboxfile, envelope); |
|
1055 |
} |
|
1056 |
|
|
1057 |
private void bboxFileSave(File bboxfile, Envelope envelope) { |
|
1058 |
if( envelope == null ) { |
|
1059 |
bboxfile.delete(); |
|
1060 |
return; |
|
1061 |
} |
|
1062 |
try { |
|
1063 |
FileUtils.write( |
|
1064 |
bboxfile, |
|
1065 |
envelope.getBox2D().convertToWKTQuietly(), |
|
1066 |
StandardCharsets.UTF_8 |
|
1067 |
); |
|
1068 |
} catch(Exception ex) { |
|
1069 |
LOGGER.warn("Can't write bbox file '"+Objects.toString(bboxfile)+"'.",ex); |
|
1070 |
} |
|
1071 |
} |
|
1072 |
|
|
1073 |
private Envelope bboxFileLoad() { |
|
1074 |
File bboxfile = this.getAuxFile("bbox"); |
|
1075 |
return bboxFileLoad(bboxfile); |
|
1076 |
} |
|
1077 |
|
|
1078 |
private Envelope bboxFileLoad(File bboxfile) { |
|
1079 |
try { |
|
1080 |
if( bboxfile.exists() ) { |
|
1081 |
GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
|
1082 |
String wkt = FileUtils.readFileToString(bboxfile, StandardCharsets.UTF_8); |
|
1083 |
Geometry geom = geomManager.createFrom(wkt); |
|
1084 |
if( geom!=null ) { |
|
1085 |
return geom.getEnvelope(); |
|
1086 |
} |
|
1087 |
} |
|
1088 |
} catch(Exception ex) { |
|
1089 |
LOGGER.warn("Can't load bbox file",ex); |
|
1090 |
} |
|
1091 |
return null; |
|
1092 |
} |
|
1093 |
|
|
922 | 1094 |
} |
Also available in: Unified diff