root / branches / v2_0_0_prep / libraries / org.gvsig.fmap.dal.cache / src / main / java / org / gvsig / fmap / dal / cache / AbstractFeatureCacheProvider.java @ 32646
History | View | Annotate | Download (17.1 KB)
1 |
/* gvSIG. Geographic Information System of the Valencian Government
|
---|---|
2 |
*
|
3 |
* Copyright (C) 2007-2008 Infrastructures and Transports Department
|
4 |
* of the Valencian Government (CIT)
|
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 |
*/
|
22 |
|
23 |
/*
|
24 |
* AUTHORS (In addition to CIT):
|
25 |
* 2009 {Iver T.I.} {Task}
|
26 |
*/
|
27 |
|
28 |
package org.gvsig.fmap.dal.cache; |
29 |
|
30 |
import java.util.HashMap; |
31 |
import java.util.Iterator; |
32 |
|
33 |
import org.cresques.cts.IProjection; |
34 |
import org.gvsig.fmap.dal.DALLocator; |
35 |
import org.gvsig.fmap.dal.DataManager; |
36 |
import org.gvsig.fmap.dal.DataServerExplorer; |
37 |
import org.gvsig.fmap.dal.DataServerExplorerParameters; |
38 |
import org.gvsig.fmap.dal.cache.CacheFeatureSet.CacheFeatureSetIterator; |
39 |
import org.gvsig.fmap.dal.cache.envelope.DefaultEnvelopeManager; |
40 |
import org.gvsig.fmap.dal.cache.envelope.EnvelopeManager; |
41 |
import org.gvsig.fmap.dal.exception.CloseException; |
42 |
import org.gvsig.fmap.dal.exception.CreateException; |
43 |
import org.gvsig.fmap.dal.exception.DataException; |
44 |
import org.gvsig.fmap.dal.exception.InitializeException; |
45 |
import org.gvsig.fmap.dal.exception.OpenException; |
46 |
import org.gvsig.fmap.dal.exception.ReadException; |
47 |
import org.gvsig.fmap.dal.exception.ValidateDataParametersException; |
48 |
import org.gvsig.fmap.dal.feature.DisposableIterator; |
49 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
50 |
import org.gvsig.fmap.dal.feature.Feature; |
51 |
import org.gvsig.fmap.dal.feature.FeatureLocks; |
52 |
import org.gvsig.fmap.dal.feature.FeatureQuery; |
53 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
54 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
55 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
56 |
import org.gvsig.fmap.dal.feature.FeatureType; |
57 |
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException; |
58 |
import org.gvsig.fmap.dal.feature.impl.DefaultFeatureReference; |
59 |
import org.gvsig.fmap.dal.feature.spi.DefaultFeatureProvider; |
60 |
import org.gvsig.fmap.dal.feature.spi.FeatureProvider; |
61 |
import org.gvsig.fmap.dal.feature.spi.FeatureReferenceProviderServices; |
62 |
import org.gvsig.fmap.dal.feature.spi.FeatureSetProvider; |
63 |
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProvider; |
64 |
import org.gvsig.fmap.dal.feature.spi.FeatureStoreProviderServices; |
65 |
import org.gvsig.fmap.dal.feature.spi.cache.FeatureCacheProvider; |
66 |
import org.gvsig.fmap.dal.resource.spi.ResourceProvider; |
67 |
import org.gvsig.fmap.geom.Geometry; |
68 |
import org.gvsig.fmap.geom.GeometryLocator; |
69 |
import org.gvsig.fmap.geom.Geometry.SUBTYPES; |
70 |
import org.gvsig.fmap.geom.primitive.Envelope; |
71 |
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsEnvelopeEvaluator; |
72 |
import org.gvsig.fmap.mapcontext.layers.vectorial.IntersectsGeometryEvaluator; |
73 |
import org.gvsig.tools.dynobject.DynClass; |
74 |
import org.gvsig.tools.dynobject.DynObject; |
75 |
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException; |
76 |
import org.gvsig.tools.dynobject.exception.DynMethodException; |
77 |
import org.gvsig.tools.evaluator.Evaluator; |
78 |
import org.gvsig.tools.evaluator.EvaluatorFieldValue; |
79 |
import org.gvsig.tools.evaluator.EvaluatorFieldValueMatch; |
80 |
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo; |
81 |
import org.gvsig.tools.locator.LocatorException; |
82 |
|
83 |
/**
|
84 |
* @author <a href="mailto:jpiera@gvsig.org">Jorge Piera</a>
|
85 |
*/
|
86 |
public abstract class AbstractFeatureCacheProvider implements FeatureCacheProvider{ |
87 |
protected DataServerExplorer dataServerExplorer = null; |
88 |
protected static final DataManager dataManager = DALLocator.getDataManager(); |
89 |
protected FeatureStoreProviderServices featureStoreProviderServices = null; |
90 |
protected FeatureStoreProvider featureStoreProvider = null; |
91 |
private Envelope fullenvelope = null; |
92 |
|
93 |
protected IProjection sourceProjection = null; |
94 |
protected FeatureType sourceFeatureType = null; |
95 |
|
96 |
//A list of FeatureStores indexed by scale
|
97 |
protected HashMap featureStores = null; |
98 |
|
99 |
//A list of EnvelopeManager indexed by scale
|
100 |
protected HashMap envelopeManagers = null; |
101 |
|
102 |
public AbstractFeatureCacheProvider() {
|
103 |
super();
|
104 |
this.featureStores = new HashMap(); |
105 |
this.envelopeManagers = new HashMap(); |
106 |
} |
107 |
|
108 |
public void apply( |
109 |
FeatureStoreProviderServices featureStoreProviderServices, |
110 |
FeatureStoreProvider featureStoreProvider) throws DataException {
|
111 |
this.featureStoreProvider = featureStoreProvider;
|
112 |
this.featureStoreProviderServices = featureStoreProviderServices;
|
113 |
|
114 |
this.sourceFeatureType = featureStoreProviderServices.getDefaultFeatureType();
|
115 |
this.sourceProjection = sourceFeatureType.getDefaultGeometryAttribute().getSRS();
|
116 |
fullenvelope=featureStoreProvider.getEnvelope(); |
117 |
|
118 |
// Evaluator evaluator = new IntersectsEnvelopeEvaluator(fullenvelope,
|
119 |
// sourceProjection, sourceFeatureType,
|
120 |
// sourceFeatureType.getDefaultGeometryAttributeName());
|
121 |
// FeatureQuery newFeatureQuery = featureStoreProviderServices.getFeatureStore().createFeatureQuery();
|
122 |
// newFeatureQuery.setFilter(evaluator);
|
123 |
|
124 |
|
125 |
|
126 |
// try {
|
127 |
// if(this.sourceProjection.isProjected()){
|
128 |
// fullenvelope = GeometryLocator.getGeometryManager().createEnvelope(-10000000, -10000000,
|
129 |
// 10000000, 10000000, SUBTYPES.GEOM2D);
|
130 |
// }
|
131 |
// else{
|
132 |
// fullenvelope = GeometryLocator.getGeometryManager().createEnvelope(-180, -90,
|
133 |
// 180, 90, SUBTYPES.GEOM2D);
|
134 |
// }
|
135 |
// } catch (Exception e) {
|
136 |
// throw new CreateGeometryException(e);
|
137 |
// }
|
138 |
|
139 |
// FeatureStore featureStore = featureStoreProviderServices.getFeatureStore();
|
140 |
// addAllFeatures(featureStore.getFeatureSet(), featureStore.getEnvelope(), 0);
|
141 |
} |
142 |
|
143 |
public void initialize(DataServerExplorerParameters parameters) throws DataException { |
144 |
try{
|
145 |
dataServerExplorer = dataManager.createServerExplorer(parameters); |
146 |
if (!dataServerExplorer.canAdd()){
|
147 |
throw new CreateException("The server explorer doesn't allow to add data stores", null); |
148 |
} |
149 |
} catch (Exception e) { |
150 |
throw new CreateException("Error creating the server explorer", e); |
151 |
} |
152 |
} |
153 |
|
154 |
/**
|
155 |
* Gets an envelope manager by scale.
|
156 |
* @param scale
|
157 |
* @return
|
158 |
*/
|
159 |
private EnvelopeManager getEnvelopeManager(double scale){ |
160 |
Double iScale = new Double(0); |
161 |
if (envelopeManagers.containsKey(iScale)){
|
162 |
return (EnvelopeManager)envelopeManagers.get(iScale);
|
163 |
} |
164 |
EnvelopeManager envelopeManager = new DefaultEnvelopeManager();
|
165 |
envelopeManagers.put(iScale, envelopeManager); |
166 |
return envelopeManager;
|
167 |
} |
168 |
|
169 |
/**
|
170 |
* Gets a feature store by scale. If it not exists, it creates
|
171 |
* one using the {@link FeatureStoreProvider}.
|
172 |
* @param scale
|
173 |
* @return
|
174 |
* @throws ValidateDataParametersException
|
175 |
* @throws LocatorException
|
176 |
* @throws DataException
|
177 |
*/
|
178 |
public FeatureStore getFeatureStore(double scale) throws DataException{ |
179 |
Double iScale = new Double(scale); |
180 |
if (featureStores.containsKey(iScale)){
|
181 |
return (FeatureStore)featureStores.get(iScale);
|
182 |
} |
183 |
FeatureStore featureStore = createDataStore(scale); |
184 |
featureStores.put(iScale, featureStore); |
185 |
return featureStore;
|
186 |
} |
187 |
|
188 |
public boolean allowAutomaticValues() { |
189 |
return false; |
190 |
} |
191 |
|
192 |
public boolean allowWrite() { |
193 |
return false; |
194 |
} |
195 |
|
196 |
public void append(FeatureProvider featureProvider) throws DataException { |
197 |
// TODO Auto-generated method stub
|
198 |
|
199 |
} |
200 |
|
201 |
public void beginAppend() throws DataException { |
202 |
// TODO Auto-generated method stub
|
203 |
|
204 |
} |
205 |
|
206 |
public boolean canWriteGeometry(int geometryType, int geometrySubType) |
207 |
throws DataException {
|
208 |
return false; |
209 |
} |
210 |
|
211 |
public FeatureLocks createFeatureLocks() throws DataException { |
212 |
return null; |
213 |
} |
214 |
|
215 |
public FeatureProvider createFeatureProvider(FeatureType type)
|
216 |
throws DataException {
|
217 |
// TODO Auto-generated method stub
|
218 |
return null; |
219 |
} |
220 |
|
221 |
public FeatureSelection createFeatureSelection() throws DataException { |
222 |
return getFeatureStore(0).createFeatureSelection(); |
223 |
} |
224 |
|
225 |
public Object createNewOID() { |
226 |
return null; |
227 |
} |
228 |
|
229 |
public FeatureSetProvider createSet(FeatureQuery query,
|
230 |
FeatureType featureType) throws DataException {
|
231 |
//If there is not a filter returns the original set of data
|
232 |
if ((query == null) || (query.getFilter() == null)){ |
233 |
Evaluator evaluator = new IntersectsEnvelopeEvaluator(fullenvelope,
|
234 |
sourceProjection, sourceFeatureType, |
235 |
sourceFeatureType.getDefaultGeometryAttributeName()); |
236 |
FeatureQuery newFeatureQuery = featureStoreProviderServices.getFeatureStore().createFeatureQuery(); |
237 |
newFeatureQuery.setFilter(evaluator); |
238 |
query=newFeatureQuery; |
239 |
// return featureStoreProvider.createSet(query, featureType);
|
240 |
} |
241 |
double scale = 0;//query.getScale(); |
242 |
FeatureStore featureStore =getFeatureStore(scale); |
243 |
EnvelopeManager envelopeManager = getEnvelopeManager(scale); |
244 |
|
245 |
Envelope envelope = null;
|
246 |
|
247 |
EvaluatorFieldsInfo fieldsInfo = query.getFilter().getFieldsInfo(); |
248 |
String[] fields = fieldsInfo.getFieldNames(); |
249 |
for (int i=0 ; i<fields.length ; i++){ |
250 |
EvaluatorFieldValue[] evaluatorFieldValues = fieldsInfo.getFieldValues(fields[i]);
|
251 |
for (int j=0 ; j<evaluatorFieldValues.length ; j++){ |
252 |
if (EvaluatorFieldValue.MATCH == evaluatorFieldValues[j].getType()){
|
253 |
EvaluatorFieldValueMatch evaluatorFieldValueMatch = (EvaluatorFieldValueMatch)evaluatorFieldValues[j]; |
254 |
Object area = evaluatorFieldValueMatch.getValue();
|
255 |
if (area instanceof Envelope){ |
256 |
envelope = (Envelope)area; |
257 |
}else if (area instanceof Geometry){ |
258 |
envelope = ((Geometry)area).getEnvelope(); |
259 |
} |
260 |
} |
261 |
} |
262 |
} |
263 |
|
264 |
//If there is not an envelope returns the original set of data
|
265 |
if (envelope == null){ |
266 |
return featureStoreProvider.createSet(query, featureType);
|
267 |
} |
268 |
|
269 |
if (!envelopeManager.contains(envelope)){
|
270 |
//Create a query by geometry
|
271 |
Geometry geometry = envelopeManager.difference(envelope); |
272 |
Evaluator evaluator = new IntersectsGeomAndNotInCacheEvaluator(geometry,
|
273 |
sourceProjection, sourceFeatureType, |
274 |
sourceFeatureType.getDefaultGeometryAttributeName(),featureStore); |
275 |
FeatureQuery newFeatureQuery = featureStoreProviderServices.getFeatureStore().createFeatureQuery(); |
276 |
newFeatureQuery.setFilter(evaluator); |
277 |
|
278 |
//Retrieve the features from the source
|
279 |
FeatureSetProvider featureSetProvider = featureStoreProvider.createSet(newFeatureQuery, featureType); |
280 |
|
281 |
// DisposableIterator iter=featureSetProvider.fastIterator();
|
282 |
// while (iter.hasNext()) {
|
283 |
// DefaultFeatureProvider object = (DefaultFeatureProvider) iter.next();
|
284 |
// System.err.println("feature = "+object.toString());
|
285 |
// }
|
286 |
|
287 |
|
288 |
//Update the cache
|
289 |
addAllFeatures(new CacheFeatureSet(featureStore, featureSetProvider), envelope, scale);
|
290 |
|
291 |
//Update the envelope manager
|
292 |
// envelopeManager.addEnvelope(envelope);
|
293 |
} |
294 |
return new CacheSetProvider(getFeatureSet(envelope, scale)); |
295 |
} |
296 |
|
297 |
/* (non-Javadoc)
|
298 |
* @see org.gvsig.fmap.dal.feature.FeatureCache#getFeatures(org.gvsig.fmap.geom.primitive.Envelope, double)
|
299 |
*/
|
300 |
public FeatureSet getFeatureSet(Envelope envelope, double scale) throws DataException { |
301 |
FeatureStore store = getFeatureStore(scale); |
302 |
FeatureType ft=store.getDefaultFeatureType(); |
303 |
Evaluator evaluator = new IntersectsEnvelopeEvaluator(envelope,
|
304 |
sourceProjection, ft, |
305 |
ft.getDefaultGeometryAttributeName()); |
306 |
|
307 |
FeatureQuery featureQuery = store.createFeatureQuery(); |
308 |
featureQuery.setFilter(evaluator); |
309 |
|
310 |
// FeatureSet setAll=store.getFeatureSet();
|
311 |
// DisposableIterator itAll=setAll.iterator();
|
312 |
// int i=0;
|
313 |
// while (itAll.hasNext()) {
|
314 |
// Feature f = (Feature) itAll.next();
|
315 |
// i++;
|
316 |
// System.err.println("All i:"+i+" : "+f.getReference().toString());
|
317 |
// }
|
318 |
// return setAll;
|
319 |
FeatureSet set=store.getFeatureSet(featureQuery); |
320 |
DisposableIterator it=set.iterator(); |
321 |
int i=0; |
322 |
while (it.hasNext()) {
|
323 |
Feature f = (Feature) it.next(); |
324 |
i++; |
325 |
System.err.println("Query i:"+i+" : "+f.getReference().toString()); |
326 |
|
327 |
} |
328 |
it.dispose(); |
329 |
return set;
|
330 |
} |
331 |
|
332 |
public void endAppend() throws DataException { |
333 |
// TODO Auto-generated method stub
|
334 |
|
335 |
} |
336 |
|
337 |
public Envelope getEnvelope() throws DataException { |
338 |
return fullenvelope;
|
339 |
} |
340 |
|
341 |
public long getFeatureCount() throws DataException { |
342 |
if (featureStores.size() == 0){ |
343 |
return 0; |
344 |
} |
345 |
//TODO feature count by scale
|
346 |
Iterator it = featureStores.keySet().iterator();
|
347 |
long featureNumber = 0; |
348 |
while (it.hasNext()){
|
349 |
FeatureStore store = (FeatureStore)featureStores.get(it.next()); |
350 |
featureNumber = featureNumber + store.getFeatureCount(); |
351 |
} |
352 |
return featureNumber;
|
353 |
} |
354 |
|
355 |
public FeatureProvider getFeatureProviderByReference(
|
356 |
FeatureReferenceProviderServices reference) throws DataException {
|
357 |
// TODO Auto-generated method stub
|
358 |
return null; |
359 |
} |
360 |
|
361 |
public FeatureProvider getFeatureProviderByReference(
|
362 |
FeatureReferenceProviderServices reference, FeatureType featureType) |
363 |
throws DataException {
|
364 |
// TODO Auto-generated method stub
|
365 |
return null; |
366 |
} |
367 |
|
368 |
public String getName() { |
369 |
return null; |
370 |
} |
371 |
|
372 |
public int getOIDType() { |
373 |
// TODO Auto-generated method stub
|
374 |
return 0; |
375 |
} |
376 |
|
377 |
public FeatureStoreProviderServices getStoreServices() {
|
378 |
// TODO Auto-generated method stub
|
379 |
return null; |
380 |
} |
381 |
|
382 |
public boolean isLocksSupported() { |
383 |
// TODO Auto-generated method stub
|
384 |
return false; |
385 |
} |
386 |
|
387 |
public void performChanges(Iterator deleteds, Iterator inserteds, |
388 |
Iterator updateds, Iterator featureTypesChanged) |
389 |
throws DataException {
|
390 |
// TODO Auto-generated method stub
|
391 |
|
392 |
} |
393 |
|
394 |
public boolean supportsAppendMode() { |
395 |
// TODO Auto-generated method stub
|
396 |
return false; |
397 |
} |
398 |
|
399 |
public void close() throws CloseException { |
400 |
// TODO Auto-generated method stub
|
401 |
|
402 |
} |
403 |
|
404 |
public void dispose() { |
405 |
// TODO Auto-generated method stub
|
406 |
|
407 |
} |
408 |
|
409 |
public Iterator getChilds() { |
410 |
// TODO Auto-generated method stub
|
411 |
return null; |
412 |
} |
413 |
|
414 |
public DataServerExplorer getExplorer() throws ReadException, |
415 |
ValidateDataParametersException { |
416 |
// TODO Auto-generated method stub
|
417 |
return null; |
418 |
} |
419 |
|
420 |
public Object getSourceId() { |
421 |
// TODO Auto-generated method stub
|
422 |
return null; |
423 |
} |
424 |
|
425 |
public void open() throws OpenException { |
426 |
// TODO Auto-generated method stub
|
427 |
|
428 |
} |
429 |
|
430 |
public void refresh() throws OpenException, InitializeException { |
431 |
// TODO Auto-generated method stub
|
432 |
|
433 |
} |
434 |
|
435 |
public void delegate(DynObject dynObject) { |
436 |
// TODO Auto-generated method stub
|
437 |
|
438 |
} |
439 |
|
440 |
public DynClass getDynClass() {
|
441 |
// TODO Auto-generated method stub
|
442 |
return null; |
443 |
} |
444 |
|
445 |
public Object getDynValue(String name) throws DynFieldNotFoundException { |
446 |
// TODO Auto-generated method stub
|
447 |
return null; |
448 |
} |
449 |
|
450 |
public boolean hasDynValue(String name) { |
451 |
// TODO Auto-generated method stub
|
452 |
return false; |
453 |
} |
454 |
|
455 |
public void implement(DynClass dynClass) { |
456 |
// TODO Auto-generated method stub
|
457 |
|
458 |
} |
459 |
|
460 |
public Object invokeDynMethod(String name, DynObject context) |
461 |
throws DynMethodException {
|
462 |
// TODO Auto-generated method stub
|
463 |
return null; |
464 |
} |
465 |
|
466 |
public Object invokeDynMethod(int code, DynObject context) |
467 |
throws DynMethodException {
|
468 |
// TODO Auto-generated method stub
|
469 |
return null; |
470 |
} |
471 |
|
472 |
public void setDynValue(String name, Object value) |
473 |
throws DynFieldNotFoundException {
|
474 |
// TODO Auto-generated method stub
|
475 |
|
476 |
} |
477 |
|
478 |
public void delete(double scale) throws DataException{ |
479 |
FeatureStore featureStore = getFeatureStore(scale); |
480 |
FeatureSet featureSet = featureStore.getFeatureSet(); |
481 |
featureStore.edit(); |
482 |
DisposableIterator it = featureSet.fastIterator(); |
483 |
while (it.hasNext()){
|
484 |
Feature feature = (Feature)it.next(); |
485 |
featureStore.delete(feature); |
486 |
} |
487 |
it.dispose(); |
488 |
featureStore.finishEditing(); |
489 |
//Update the envelope manager
|
490 |
EnvelopeManager envelopeManager = getEnvelopeManager(scale); |
491 |
envelopeManager.delete(); |
492 |
} |
493 |
|
494 |
public void deleteAll() throws DataException { |
495 |
Iterator it = featureStores.keySet().iterator();
|
496 |
while (it.hasNext()){
|
497 |
Integer scale = (Integer)it.next(); |
498 |
delete(scale.intValue()); |
499 |
} |
500 |
} |
501 |
|
502 |
public void addAllFeatures(FeatureSet featureSet, Envelope envelope, |
503 |
double scale) throws DataException { |
504 |
FeatureStore featureStore = getFeatureStore(scale); |
505 |
featureStore.edit(); |
506 |
DisposableIterator it = featureSet.fastIterator(); |
507 |
while (it.hasNext()){
|
508 |
Feature feature = (Feature)it.next(); |
509 |
System.err.println("Reference= "+((DefaultFeatureReference)feature.getReference()).getOID().toString()); |
510 |
EditableFeature editableFeature = featureStore.createNewFeature(); |
511 |
copyFeature(editableFeature, feature); |
512 |
featureStore.insert(editableFeature); |
513 |
} |
514 |
it.dispose(); |
515 |
featureStore.finishEditing(); |
516 |
//Update the envelope manager
|
517 |
EnvelopeManager envelopeManager = getEnvelopeManager(scale); |
518 |
envelopeManager.addEnvelope(envelope); |
519 |
} |
520 |
|
521 |
/**
|
522 |
* This method has to be overrided if the cache provider cannot mantain
|
523 |
* the source {@link FeatureType}
|
524 |
* @param feature
|
525 |
* @return
|
526 |
*/
|
527 |
protected void copyFeature(EditableFeature editableFeature, Feature sourceFeature){ |
528 |
editableFeature.copyFrom(sourceFeature); |
529 |
} |
530 |
|
531 |
public ResourceProvider getResource() {
|
532 |
// TODO Auto-generated method stub
|
533 |
return null; |
534 |
} |
535 |
|
536 |
public void clear() { |
537 |
featureStoreProvider.clear(); |
538 |
} |
539 |
|
540 |
} |
541 |
|