gvsig-projects-pool / org.gvsig.topology / trunk / org.gvsig.topology / org.gvsig.topology.lib / org.gvsig.topology.lib.impl / src / main / java / org / gvsig / topology / lib / impl / DefaultTopologyDataSet.java @ 2067
History | View | Annotate | Download (19.6 KB)
1 | 688 | jjdelcerro | /**
|
---|---|---|---|
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 | package org.gvsig.topology.lib.impl; |
||
25 | |||
26 | 725 | jjdelcerro | import java.util.Iterator; |
27 | 721 | jjdelcerro | import java.util.Map; |
28 | 725 | jjdelcerro | import org.apache.commons.collections.IteratorUtils; |
29 | 688 | jjdelcerro | import org.apache.commons.lang3.StringUtils; |
30 | 725 | jjdelcerro | import org.apache.commons.lang3.mutable.MutableObject; |
31 | import org.gvsig.expressionevaluator.Expression; |
||
32 | 2067 | jolivas | import org.gvsig.expressionevaluator.ExpressionBuilder; |
33 | import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
||
34 | import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
||
35 | 1284 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionUtils; |
36 | import org.gvsig.expressionevaluator.GeometryExpressionBuilder; |
||
37 | import org.gvsig.expressionevaluator.GeometryExpressionUtils; |
||
38 | 727 | jjdelcerro | import org.gvsig.fmap.dal.DataStore; |
39 | 688 | jjdelcerro | import org.gvsig.fmap.dal.EditingNotification; |
40 | import org.gvsig.fmap.dal.EditingNotificationManager; |
||
41 | import org.gvsig.fmap.dal.exception.DataException; |
||
42 | import org.gvsig.fmap.dal.feature.EditableFeature; |
||
43 | import org.gvsig.fmap.dal.feature.Feature; |
||
44 | import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
||
45 | import org.gvsig.fmap.dal.feature.FeatureReference; |
||
46 | 894 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureSet; |
47 | 688 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureStore; |
48 | 725 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureStoreProviderFactory; |
49 | 688 | jjdelcerro | import org.gvsig.fmap.dal.feature.FeatureType; |
50 | import org.gvsig.fmap.dal.swing.DALSwingLocator; |
||
51 | import org.gvsig.fmap.geom.Geometry; |
||
52 | 725 | jjdelcerro | import org.gvsig.fmap.geom.GeometryLocator; |
53 | import org.gvsig.fmap.geom.GeometryManager; |
||
54 | 894 | jjdelcerro | import org.gvsig.fmap.geom.GeometryUtils; |
55 | 725 | jjdelcerro | import org.gvsig.fmap.geom.SpatialIndex; |
56 | 688 | jjdelcerro | import org.gvsig.fmap.geom.type.GeometryType; |
57 | 894 | jjdelcerro | import org.gvsig.tools.dispose.DisposableIterator; |
58 | 688 | jjdelcerro | import org.gvsig.tools.exception.BaseException; |
59 | 721 | jjdelcerro | import org.gvsig.tools.util.PropertiesSupportHelper; |
60 | 722 | jjdelcerro | import org.gvsig.tools.visitor.VisitCanceledException; |
61 | 688 | jjdelcerro | import org.gvsig.tools.visitor.Visitor; |
62 | import org.gvsig.topology.lib.api.CancelOperationException; |
||
63 | import org.gvsig.topology.lib.api.PerformOperationException; |
||
64 | import org.gvsig.topology.lib.api.TopologyDataSet; |
||
65 | import org.gvsig.topology.lib.api.TopologyLocator; |
||
66 | import org.gvsig.topology.lib.api.TopologyManager; |
||
67 | import org.json.JSONObject; |
||
68 | import org.gvsig.topology.lib.api.TopologyServices; |
||
69 | 725 | jjdelcerro | import org.slf4j.Logger; |
70 | import org.slf4j.LoggerFactory; |
||
71 | 688 | jjdelcerro | |
72 | /**
|
||
73 | *
|
||
74 | * @author jjdelcerro
|
||
75 | */
|
||
76 | @SuppressWarnings({"EqualsAndHashcode","UseSpecificCatch"}) |
||
77 | public class DefaultTopologyDataSet implements TopologyDataSet { |
||
78 | |||
79 | 725 | jjdelcerro | private final static Logger LOGGER = LoggerFactory.getLogger(DefaultTopologyDataSet.class); |
80 | |||
81 | 688 | jjdelcerro | private TopologyServices services;
|
82 | private String name; |
||
83 | 727 | jjdelcerro | private DataStore store;
|
84 | 688 | jjdelcerro | private boolean needFinishEditing; |
85 | private String fullName; |
||
86 | 721 | jjdelcerro | private PropertiesSupportHelper propertiesHelper;
|
87 | 725 | jjdelcerro | private MutableObject<SpatialIndex> spatialIndex = null; |
88 | |||
89 | 688 | jjdelcerro | public DefaultTopologyDataSet() {
|
90 | this.services = null; |
||
91 | this.name = null; |
||
92 | this.store = null; |
||
93 | this.needFinishEditing = false; |
||
94 | this.fullName = null; |
||
95 | 721 | jjdelcerro | this.propertiesHelper = new PropertiesSupportHelper(); |
96 | 688 | jjdelcerro | } |
97 | |||
98 | 727 | jjdelcerro | public DefaultTopologyDataSet(TopologyServices services, String name, DataStore store) { |
99 | 688 | jjdelcerro | this.services = services;
|
100 | this.name = name;
|
||
101 | this.store = store;
|
||
102 | this.needFinishEditing = false; |
||
103 | if( store!=null ) { |
||
104 | this.fullName = store.getFullName();
|
||
105 | } |
||
106 | } |
||
107 | |||
108 | 894 | jjdelcerro | @Override
|
109 | 726 | jjdelcerro | public void restart() { |
110 | this.store = null; |
||
111 | this.spatialIndex = null; |
||
112 | } |
||
113 | |||
114 | 688 | jjdelcerro | @Override
|
115 | public boolean equals(Object obj) { |
||
116 | if( !(obj instanceof DefaultTopologyDataSet) ) { |
||
117 | return false; |
||
118 | } |
||
119 | DefaultTopologyDataSet other = (DefaultTopologyDataSet)obj; |
||
120 | if( this.store != other.store ) { |
||
121 | return false; |
||
122 | } |
||
123 | if( !StringUtils.equals(this.getName(), other.getName()) ) { |
||
124 | return false; |
||
125 | } |
||
126 | return true; |
||
127 | } |
||
128 | |||
129 | @Override
|
||
130 | public String getName() { |
||
131 | return this.name; |
||
132 | } |
||
133 | |||
134 | @Override
|
||
135 | public void setName(String name) { |
||
136 | this.name = name;
|
||
137 | } |
||
138 | |||
139 | @Override
|
||
140 | public String toString() { |
||
141 | try {
|
||
142 | 727 | jjdelcerro | FeatureAttributeDescriptor attr = this.getFeatureStore().getDefaultFeatureType().getDefaultGeometryAttribute();
|
143 | 688 | jjdelcerro | String geomType = attr.getGeomType().getName();
|
144 | return this.name + " ("+ geomType + ")"; |
||
145 | } catch(Exception ex) { |
||
146 | return this.name ; |
||
147 | } |
||
148 | } |
||
149 | |||
150 | @Override
|
||
151 | 727 | jjdelcerro | public DataStore getStore() {
|
152 | 688 | jjdelcerro | if (this.store == null) { |
153 | this.store = this.services.getFeatureStore(this); |
||
154 | } |
||
155 | return this.store; |
||
156 | } |
||
157 | |||
158 | @Override
|
||
159 | 727 | jjdelcerro | public FeatureStore getFeatureStore() {
|
160 | if (this.store == null) { |
||
161 | this.store = this.services.getFeatureStore(this); |
||
162 | } |
||
163 | return (FeatureStore) this.store; |
||
164 | } |
||
165 | |||
166 | @Override
|
||
167 | 688 | jjdelcerro | public long getSize() { |
168 | try {
|
||
169 | 727 | jjdelcerro | long size = this.getFeatureStore().getFeatureCount(); |
170 | 688 | jjdelcerro | return size;
|
171 | } catch (DataException ex) {
|
||
172 | // TODO: mensage al log
|
||
173 | return 0; |
||
174 | } |
||
175 | } |
||
176 | |||
177 | @Override
|
||
178 | public boolean isThisStore(FeatureStore store) { |
||
179 | if( store == null ) { |
||
180 | return false; |
||
181 | } |
||
182 | return StringUtils.equals(this.fullName, store.getFullName()); |
||
183 | } |
||
184 | |||
185 | @Override
|
||
186 | public int getGeometryType() { |
||
187 | try {
|
||
188 | 727 | jjdelcerro | FeatureStore theStore = this.getFeatureStore();
|
189 | 688 | jjdelcerro | FeatureType featureType = theStore.getDefaultFeatureType(); |
190 | FeatureAttributeDescriptor attr = featureType.getDefaultGeometryAttribute(); |
||
191 | GeometryType geomType = attr.getGeomType(); |
||
192 | return geomType.getType();
|
||
193 | } catch (Exception ex) { |
||
194 | return Geometry.TYPES.GEOMETRY;
|
||
195 | } |
||
196 | } |
||
197 | |||
198 | @Override
|
||
199 | 722 | jjdelcerro | public void accept(Visitor visitor) throws VisitCanceledException { |
200 | 727 | jjdelcerro | FeatureStore st = this.getFeatureStore();
|
201 | 688 | jjdelcerro | try {
|
202 | st.accept(visitor); |
||
203 | 722 | jjdelcerro | } catch(VisitCanceledException ex) {
|
204 | throw ex;
|
||
205 | } catch(BaseException ex) {
|
||
206 | 688 | jjdelcerro | throw new RuntimeException(ex); |
207 | } |
||
208 | } |
||
209 | |||
210 | @Override
|
||
211 | public void edit() throws DataException { |
||
212 | 727 | jjdelcerro | FeatureStore theStore = this.getFeatureStore();
|
213 | 688 | jjdelcerro | if (!theStore.isEditing()) {
|
214 | theStore.edit(); |
||
215 | this.needFinishEditing = true; |
||
216 | } |
||
217 | } |
||
218 | |||
219 | @Override
|
||
220 | public void finishEditing() throws DataException { |
||
221 | if (this.needFinishEditing) { |
||
222 | 727 | jjdelcerro | this.getFeatureStore().finishEditing();
|
223 | 688 | jjdelcerro | } |
224 | } |
||
225 | |||
226 | @Override
|
||
227 | public EditableFeature createNewFeature() throws DataException { |
||
228 | 727 | jjdelcerro | EditableFeature f = this.getFeatureStore().createNewFeature();
|
229 | 688 | jjdelcerro | return f;
|
230 | } |
||
231 | |||
232 | public void perform( |
||
233 | String operation,
|
||
234 | Feature feature |
||
235 | ) throws DataException {
|
||
236 | this.edit();
|
||
237 | |||
238 | EditingNotificationManager editingNotificationManager |
||
239 | = DALSwingLocator.getEditingNotificationManager(); |
||
240 | 727 | jjdelcerro | FeatureStore theStore = this.getFeatureStore();
|
241 | 688 | jjdelcerro | |
242 | EditingNotification notification |
||
243 | = editingNotificationManager.notifyObservers(this, // source |
||
244 | operation, // type
|
||
245 | null,// document |
||
246 | null,// layer |
||
247 | theStore,// store
|
||
248 | feature// feature
|
||
249 | ); |
||
250 | |||
251 | if (notification.isCanceled()) {
|
||
252 | String msg = String.format( |
||
253 | "Can't insert feature into %1$s, canceled by some observer.",
|
||
254 | this.getName());
|
||
255 | throw new CancelOperationException(msg); |
||
256 | } |
||
257 | |||
258 | String after = null; |
||
259 | if( operation.equalsIgnoreCase(EditingNotification.BEFORE_REMOVE_FEATURE) ) {
|
||
260 | theStore.delete(feature); |
||
261 | after = EditingNotification.AFTER_REMOVE_FEATURE; |
||
262 | |||
263 | } else {
|
||
264 | if (notification.shouldValidateTheFeature()) {
|
||
265 | if (!editingNotificationManager.validateFeature(feature)) {
|
||
266 | String msg = String.format("%1$s is not valid", feature.toString()); |
||
267 | throw new PerformOperationException(msg); |
||
268 | } |
||
269 | } |
||
270 | switch(operation) {
|
||
271 | case EditingNotification.BEFORE_UPDATE_FEATURE:
|
||
272 | theStore.update((EditableFeature) feature); |
||
273 | after = EditingNotification.AFTER_UPDATE_FEATURE; |
||
274 | break;
|
||
275 | |||
276 | case EditingNotification.BEFORE_INSERT_FEATURE:
|
||
277 | theStore.insert((EditableFeature) feature); |
||
278 | after = EditingNotification.AFTER_INSERT_FEATURE; |
||
279 | break;
|
||
280 | } |
||
281 | } |
||
282 | |||
283 | editingNotificationManager.notifyObservers(this,
|
||
284 | after, null, null, |
||
285 | theStore, feature); |
||
286 | |||
287 | } |
||
288 | |||
289 | @Override
|
||
290 | public void insert(final EditableFeature feature) throws DataException { |
||
291 | perform( |
||
292 | EditingNotification.BEFORE_INSERT_FEATURE, |
||
293 | feature |
||
294 | ); |
||
295 | } |
||
296 | |||
297 | @Override
|
||
298 | public void update(final EditableFeature feature) throws DataException { |
||
299 | perform( |
||
300 | EditingNotification.BEFORE_UPDATE_FEATURE, |
||
301 | feature |
||
302 | ); |
||
303 | } |
||
304 | |||
305 | @Override
|
||
306 | public void delete(final Feature feature) throws DataException { |
||
307 | perform( |
||
308 | EditingNotification.BEFORE_REMOVE_FEATURE, |
||
309 | feature |
||
310 | ); |
||
311 | } |
||
312 | |||
313 | @Override
|
||
314 | public void delete(final FeatureReference feature) throws DataException { |
||
315 | perform( |
||
316 | EditingNotification.BEFORE_REMOVE_FEATURE, |
||
317 | feature.getFeature() |
||
318 | ); |
||
319 | } |
||
320 | |||
321 | @Override
|
||
322 | public JSONObject toJSON() {
|
||
323 | JSONObject jsonDataSet = new JSONObject();
|
||
324 | jsonDataSet.put("name", this.name); |
||
325 | jsonDataSet.put("fullName", this.fullName); |
||
326 | |||
327 | return jsonDataSet;
|
||
328 | } |
||
329 | |||
330 | @Override
|
||
331 | public void fromJSON(String json) { |
||
332 | this.fromJSON(new JSONObject(json)); |
||
333 | } |
||
334 | |||
335 | @Override
|
||
336 | public void fromJSON(JSONObject json) { |
||
337 | TopologyManager manager = TopologyLocator.getTopologyManager(); |
||
338 | this.name = json.getString("name"); |
||
339 | this.fullName = null; |
||
340 | if( json.has("fullName") ) { |
||
341 | this.fullName = json.getString("fullName"); |
||
342 | } |
||
343 | this.store = null; |
||
344 | this.needFinishEditing = false; |
||
345 | this.services = manager.getDefaultServices();
|
||
346 | } |
||
347 | |||
348 | 721 | jjdelcerro | @Override
|
349 | public Object getProperty(String string) { |
||
350 | return this.propertiesHelper.getProperty(name); |
||
351 | } |
||
352 | |||
353 | @Override
|
||
354 | public void setProperty(String string, Object o) { |
||
355 | this.propertiesHelper.setProperty(name, o);
|
||
356 | } |
||
357 | |||
358 | @Override
|
||
359 | public Map<String, Object> getProperties() { |
||
360 | return this.propertiesHelper.getProperties(); |
||
361 | } |
||
362 | |||
363 | 894 | jjdelcerro | @Override
|
364 | 725 | jjdelcerro | public SpatialIndex getSpatialIndex() {
|
365 | if( this.spatialIndex == null ) { |
||
366 | this.spatialIndex = new MutableObject<>(); |
||
367 | 727 | jjdelcerro | FeatureStore theStore = this.getFeatureStore();
|
368 | 725 | jjdelcerro | FeatureStoreProviderFactory storeFactory = (FeatureStoreProviderFactory) theStore.getProviderFactory(); |
369 | if( storeFactory.useLocalIndexesCanImprovePerformance()==FeatureStoreProviderFactory.YES ) {
|
||
370 | try {
|
||
371 | GeometryManager geomManager = GeometryLocator.getGeometryManager(); |
||
372 | final SpatialIndex geomIndex = geomManager.createSpatialIndex(
|
||
373 | GeometryManager.SPATIALINDEX_DEFAULT_QUADTREE, |
||
374 | null
|
||
375 | ); |
||
376 | final SpatialIndex dataIndex = theStore.wrapSpatialIndex(geomIndex);
|
||
377 | try {
|
||
378 | 2067 | jolivas | store.accept(new Visitor() {
|
379 | @Override
|
||
380 | public void visit(Object o) throws VisitCanceledException, BaseException { |
||
381 | Feature f = (Feature) o; |
||
382 | Geometry geom = f.getDefaultGeometry(); |
||
383 | if (geom != null) { |
||
384 | dataIndex.insert(geom, f); |
||
385 | } |
||
386 | 725 | jjdelcerro | } |
387 | }); |
||
388 | } catch (VisitCanceledException ex) {
|
||
389 | } |
||
390 | this.spatialIndex.setValue(dataIndex);
|
||
391 | } catch (Exception ex) { |
||
392 | LOGGER.warn("Can't create spatial index", ex);
|
||
393 | } |
||
394 | } |
||
395 | } |
||
396 | return this.spatialIndex.getValue(); |
||
397 | } |
||
398 | |||
399 | 894 | jjdelcerro | @Override
|
400 | 725 | jjdelcerro | public Iterable<FeatureReference> query(Geometry geom) { |
401 | 894 | jjdelcerro | return this.queryReferences(geom); |
402 | } |
||
403 | |||
404 | @Override
|
||
405 | public Iterable<FeatureReference> queryReferences(Geometry geom) { |
||
406 | 725 | jjdelcerro | SpatialIndex index = this.getSpatialIndex();
|
407 | if( index == null ) { |
||
408 | 894 | jjdelcerro | try {
|
409 | FeatureStore theStore = (FeatureStore) this.getStore();
|
||
410 | 1284 | jjdelcerro | Expression expression = ExpressionUtils.createExpression();
|
411 | GeometryExpressionBuilder expressionBuilder = GeometryExpressionUtils.createExpressionBuilder(); |
||
412 | 894 | jjdelcerro | String geomName = theStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
|
413 | if( GeometryUtils.isSubtype(Geometry.TYPES.POINT, geom.getType()) ) {
|
||
414 | expression.setPhrase( |
||
415 | expressionBuilder.ifnull( |
||
416 | expressionBuilder.column(geomName), |
||
417 | expressionBuilder.constant(false),
|
||
418 | expressionBuilder.ST_Intersects( |
||
419 | expressionBuilder.column(geomName), |
||
420 | expressionBuilder.geometry(geom) |
||
421 | ) |
||
422 | ).toString() |
||
423 | ); |
||
424 | } else {
|
||
425 | expression.setPhrase( |
||
426 | expressionBuilder.ifnull( |
||
427 | expressionBuilder.column(geomName), |
||
428 | expressionBuilder.constant(false),
|
||
429 | expressionBuilder.ST_Overlaps( |
||
430 | expressionBuilder.column(geomName), |
||
431 | expressionBuilder.envelope(geom.getEnvelope()) |
||
432 | ) |
||
433 | ).toString() |
||
434 | ); |
||
435 | } |
||
436 | FeatureSet set = theStore.getFeatureSet(expression); |
||
437 | final DisposableIterator it = set.fastIterator();
|
||
438 | 2067 | jolivas | return new Iterable<FeatureReference>() { |
439 | 894 | jjdelcerro | @Override
|
440 | 2067 | jolivas | public Iterator<FeatureReference> iterator() { |
441 | return new Iterator<FeatureReference>() { |
||
442 | @Override
|
||
443 | public boolean hasNext() { |
||
444 | return it.hasNext();
|
||
445 | } |
||
446 | |||
447 | @Override
|
||
448 | public FeatureReference next() {
|
||
449 | Feature f = (Feature) it.next(); |
||
450 | return f.getReference();
|
||
451 | } |
||
452 | }; |
||
453 | 894 | jjdelcerro | } |
454 | }; |
||
455 | |||
456 | } catch(Exception ex) { |
||
457 | return (Iterable<FeatureReference>) IteratorUtils.EMPTY_ITERATOR; |
||
458 | } |
||
459 | 725 | jjdelcerro | } |
460 | final Iterator it = index.query(geom); |
||
461 | if( it == null ) { |
||
462 | return (Iterable<FeatureReference>) IteratorUtils.EMPTY_ITERATOR; |
||
463 | } |
||
464 | 2067 | jolivas | return new Iterable<FeatureReference>() { |
465 | @Override
|
||
466 | public Iterator<FeatureReference> iterator() { |
||
467 | return it;
|
||
468 | } |
||
469 | }; |
||
470 | 725 | jjdelcerro | } |
471 | |||
472 | @Override
|
||
473 | 894 | jjdelcerro | public Iterable<Feature> queryFeatures(Geometry geom) { |
474 | SpatialIndex index = this.getSpatialIndex();
|
||
475 | if( index == null ) { |
||
476 | try {
|
||
477 | FeatureStore theStore = (FeatureStore) this.getStore();
|
||
478 | 1284 | jjdelcerro | Expression expression = ExpressionUtils.createExpression();
|
479 | GeometryExpressionBuilder expressionBuilder = GeometryExpressionUtils.createExpressionBuilder(); |
||
480 | 894 | jjdelcerro | String geomName = theStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
|
481 | if( GeometryUtils.isSubtype(Geometry.TYPES.POINT, geom.getType()) ) {
|
||
482 | expression.setPhrase( |
||
483 | expressionBuilder.ifnull( |
||
484 | expressionBuilder.column(geomName), |
||
485 | expressionBuilder.constant(false),
|
||
486 | expressionBuilder.ST_Intersects( |
||
487 | expressionBuilder.column(geomName), |
||
488 | expressionBuilder.geometry(geom) |
||
489 | ) |
||
490 | ).toString() |
||
491 | ); |
||
492 | } else {
|
||
493 | expression.setPhrase( |
||
494 | expressionBuilder.ifnull( |
||
495 | expressionBuilder.column(geomName), |
||
496 | expressionBuilder.constant(false),
|
||
497 | expressionBuilder.ST_Overlaps( |
||
498 | expressionBuilder.column(geomName), |
||
499 | expressionBuilder.envelope(geom.getEnvelope()) |
||
500 | ) |
||
501 | ).toString() |
||
502 | ); |
||
503 | } |
||
504 | FeatureSet set = theStore.getFeatureSet(expression); |
||
505 | final DisposableIterator it = set.fastIterator();
|
||
506 | 2067 | jolivas | return new Iterable<Feature>() { |
507 | @Override
|
||
508 | public Iterator<Feature> iterator() { |
||
509 | return it;
|
||
510 | } |
||
511 | }; |
||
512 | 894 | jjdelcerro | |
513 | } catch(Exception ex) { |
||
514 | return (Iterable<Feature>) IteratorUtils.EMPTY_ITERATOR; |
||
515 | } |
||
516 | } |
||
517 | final Iterator it = index.query(geom); |
||
518 | if( it == null ) { |
||
519 | return (Iterable<Feature>) IteratorUtils.EMPTY_ITERATOR; |
||
520 | } |
||
521 | 2067 | jolivas | return new Iterable<Feature>() { |
522 | 894 | jjdelcerro | @Override
|
523 | 2067 | jolivas | public Iterator<Feature> iterator() { |
524 | return new Iterator<Feature>() { |
||
525 | @Override
|
||
526 | public boolean hasNext() { |
||
527 | return it.hasNext();
|
||
528 | } |
||
529 | |||
530 | @Override
|
||
531 | public Feature next() {
|
||
532 | FeatureReference ref = (FeatureReference) it.next(); |
||
533 | try {
|
||
534 | return ref.getFeature();
|
||
535 | } catch (DataException ex) {
|
||
536 | return null; |
||
537 | } |
||
538 | } |
||
539 | }; |
||
540 | 894 | jjdelcerro | } |
541 | }; |
||
542 | } |
||
543 | |||
544 | @Override
|
||
545 | 725 | jjdelcerro | public Feature findFirst(Expression filter) { |
546 | try {
|
||
547 | 727 | jjdelcerro | return this.getFeatureStore().findFirst(filter); |
548 | 725 | jjdelcerro | } catch (Exception ex) { |
549 | return null; |
||
550 | } |
||
551 | } |
||
552 | |||
553 | 688 | jjdelcerro | } |