1 |
mojays |
321 |
/* |
2 |
|
|
* GeoTools - OpenSource mapping toolkit |
3 |
|
|
* http://geotools.org |
4 |
|
|
* (C) 2005-2006, GeoTools Project Managment Committee (PMC) |
5 |
|
|
* |
6 |
|
|
* This library is free software; you can redistribute it and/or |
7 |
|
|
* modify it under the terms of the GNU Lesser General Public |
8 |
|
|
* License as published by the Free Software Foundation; |
9 |
|
|
* version 2.1 of the License. |
10 |
|
|
* |
11 |
|
|
* This library 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 GNU |
14 |
|
|
* Lesser General Public License for more details. |
15 |
|
|
*/ |
16 |
|
|
package org.geotools.feature.collection; |
17 |
|
|
|
18 |
|
|
import java.io.IOException; |
19 |
|
|
import java.util.Iterator; |
20 |
|
|
|
21 |
|
|
import org.apache.batik.svggen.font.table.FeatureList; |
22 |
|
|
import org.geotools.data.FeatureReader; |
23 |
|
|
import org.geotools.data.collection.DelegateFeatureReader; |
24 |
|
|
import org.geotools.factory.CommonFactoryFinder; |
25 |
|
|
import org.geotools.feature.CollectionListener; |
26 |
|
|
import org.geotools.feature.FeatureCollection; |
27 |
|
|
import org.geotools.feature.FeatureIterator; |
28 |
|
|
import org.geotools.feature.IllegalAttributeException; |
29 |
|
|
import org.geotools.feature.SimpleFeature; |
30 |
|
|
import org.geotools.feature.SimpleFeatureType; |
31 |
|
|
import org.geotools.feature.visitor.FeatureVisitor; |
32 |
|
|
import org.geotools.geometry.jts.ReferencedEnvelope; |
33 |
|
|
import org.opengis.util.ProgressListener; |
34 |
|
|
import org.opengis.filter.Filter; |
35 |
|
|
import org.opengis.filter.FilterFactory; |
36 |
|
|
import org.opengis.filter.sort.SortBy; |
37 |
|
|
|
38 |
|
|
import com.vividsolutions.jts.geom.Geometry; |
39 |
|
|
|
40 |
|
|
/** |
41 |
|
|
* <b>Xulu:<br> |
42 |
|
|
* Code taken from gt-2.4.2 to optimize the {@link #size()} method! |
43 |
|
|
* The original variant always iterates ALL features at every call!.</b><br><br> |
44 |
|
|
* |
45 |
|
|
* Used as a reasonable default implementation for subCollection. |
46 |
|
|
* <p> |
47 |
|
|
* Note: to implementors, this is not optimal, please do your own |
48 |
|
|
* thing - your users will thank you. |
49 |
|
|
* </p> |
50 |
|
|
* |
51 |
|
|
* @author Jody Garnett, Refractions Research, Inc. |
52 |
|
|
* |
53 |
|
|
* @source $URL: http://svn.geotools.org/geotools/tags/2.4.2/modules/library/main/src/main/java/org/geotools/feature/collection/SubFeatureCollection.java $ |
54 |
|
|
*/ |
55 |
|
|
public class SubFeatureCollection extends AbstractResourceCollection implements FeatureCollection { |
56 |
|
|
// Xulu-01.sn |
57 |
|
|
private int size = -1; |
58 |
|
|
// Xulu-01.en |
59 |
|
|
|
60 |
|
|
/** Filter */ |
61 |
|
|
protected Filter filter; |
62 |
|
|
|
63 |
|
|
/** Origional Collection */ |
64 |
|
|
protected FeatureCollection collection; |
65 |
|
|
protected FeatureState state; |
66 |
|
|
protected FilterFactory ff = CommonFactoryFinder.getFilterFactory( null ); |
67 |
|
|
|
68 |
|
|
public SubFeatureCollection(FeatureCollection collection ) { |
69 |
|
|
this( collection, Filter.INCLUDE ); |
70 |
|
|
} |
71 |
|
|
public SubFeatureCollection(FeatureCollection collection, Filter subfilter ){ |
72 |
|
|
if (subfilter == null ) subfilter = Filter.INCLUDE; |
73 |
|
|
if (subfilter.equals(Filter.EXCLUDE)) { |
74 |
|
|
throw new IllegalArgumentException("A subcollection with Filter.EXCLUDE is a null operation"); |
75 |
|
|
} |
76 |
|
|
|
77 |
|
|
if( collection instanceof SubFeatureCollection){ |
78 |
|
|
SubFeatureCollection filtered = (SubFeatureCollection) collection; |
79 |
|
|
if( subfilter.equals(Filter.INCLUDE)){ |
80 |
|
|
this.collection = filtered.collection; |
81 |
|
|
this.filter = filtered.filter(); |
82 |
|
|
} |
83 |
|
|
else { |
84 |
|
|
this.collection = filtered.collection; |
85 |
|
|
this.filter = ff.and( filtered.filter(), subfilter ); |
86 |
|
|
} |
87 |
|
|
} else { |
88 |
|
|
this.collection = collection; |
89 |
|
|
this.filter = subfilter; |
90 |
|
|
} |
91 |
|
|
state = new SubFeatureState( this.collection, this ); |
92 |
|
|
} |
93 |
|
|
|
94 |
|
|
protected Filter filter(){ |
95 |
|
|
if( filter == null ){ |
96 |
|
|
filter = createFilter(); |
97 |
|
|
} |
98 |
|
|
return filter; |
99 |
|
|
} |
100 |
|
|
/** Override to implement subsetting */ |
101 |
|
|
protected Filter createFilter(){ |
102 |
|
|
return Filter.INCLUDE; |
103 |
|
|
} |
104 |
|
|
|
105 |
|
|
public SimpleFeatureType getFeatureType() { |
106 |
|
|
return state.getFeatureType(); |
107 |
|
|
} |
108 |
|
|
|
109 |
|
|
public FeatureIterator features() { |
110 |
|
|
return new DelegateFeatureIterator( this, iterator() ); |
111 |
|
|
} |
112 |
|
|
|
113 |
|
|
public void closeIterator(Iterator iterator) { |
114 |
|
|
if( iterator == null ) return; |
115 |
|
|
|
116 |
|
|
if( iterator instanceof FilteredIterator){ |
117 |
|
|
FilteredIterator filtered = (FilteredIterator) iterator; |
118 |
|
|
filtered.close(); |
119 |
|
|
} |
120 |
|
|
} |
121 |
|
|
public void close(FeatureIterator close) { |
122 |
|
|
if( close != null ) close.close(); |
123 |
|
|
} |
124 |
|
|
|
125 |
|
|
// |
126 |
|
|
// SimpleFeature methods |
127 |
|
|
// |
128 |
|
|
public String getID() { |
129 |
|
|
return state.getId(); |
130 |
|
|
} |
131 |
|
|
|
132 |
|
|
public ReferencedEnvelope getBounds(){ |
133 |
|
|
return ReferencedEnvelope.reference(state.getBounds()); |
134 |
|
|
} |
135 |
|
|
|
136 |
|
|
public Geometry getDefaultGeometry() { |
137 |
|
|
return state.getDefaultGeometry(); |
138 |
|
|
} |
139 |
|
|
|
140 |
|
|
public void setDefaultGeometry(Geometry g) throws IllegalAttributeException { |
141 |
|
|
state.setDefaultGeometry( g ); |
142 |
|
|
} |
143 |
|
|
|
144 |
|
|
public void addListener(CollectionListener listener) throws NullPointerException { |
145 |
|
|
state.addListener( listener ); |
146 |
|
|
} |
147 |
|
|
|
148 |
|
|
public void removeListener(CollectionListener listener) throws NullPointerException { |
149 |
|
|
state.removeListener( listener ); |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
public FeatureCollection getParent() { |
153 |
|
|
return state.getParent(); |
154 |
|
|
} |
155 |
|
|
|
156 |
|
|
public void setParent(FeatureCollection collection) { |
157 |
|
|
state.setParent( collection ); |
158 |
|
|
} |
159 |
|
|
|
160 |
|
|
public Object[] getAttributes(Object[] attributes) { |
161 |
|
|
return state.getAttributes( attributes ); |
162 |
|
|
} |
163 |
|
|
|
164 |
|
|
public Object getAttribute(String xPath) { |
165 |
|
|
return state.getAttribute( xPath ); |
166 |
|
|
} |
167 |
|
|
|
168 |
|
|
public Object getAttribute(int index) { |
169 |
|
|
return state.getAttribute( index ); |
170 |
|
|
} |
171 |
|
|
|
172 |
|
|
public void setAttribute(int position, Object val) throws IllegalAttributeException, ArrayIndexOutOfBoundsException { |
173 |
|
|
state.setAttribute( position, val ); |
174 |
|
|
} |
175 |
|
|
public int getNumberOfAttributes() { |
176 |
|
|
return state.getNumberOfAttributes(); |
177 |
|
|
} |
178 |
|
|
|
179 |
|
|
public void setAttribute(String xPath, Object attribute) throws IllegalAttributeException { |
180 |
|
|
state.setAttribute( xPath, attribute ); |
181 |
|
|
} |
182 |
|
|
|
183 |
|
|
// |
184 |
|
|
// |
185 |
|
|
// |
186 |
|
|
public FeatureCollection subCollection(Filter filter) { |
187 |
|
|
if (filter.equals(Filter.INCLUDE)) { |
188 |
|
|
return this; |
189 |
|
|
} |
190 |
|
|
if (filter.equals(Filter.EXCLUDE)) { |
191 |
|
|
// TODO implement EmptyFeatureCollection( schema ) |
192 |
|
|
} |
193 |
|
|
return new SubFeatureCollection(this, filter); |
194 |
|
|
} |
195 |
|
|
|
196 |
|
|
public int size() { |
197 |
|
|
//Xulu-01.sn |
198 |
|
|
if ( this.size >= 0 ) |
199 |
|
|
return this.size; |
200 |
|
|
//Xulu-01.en |
201 |
|
|
int count = 0; |
202 |
|
|
Iterator i = null; |
203 |
|
|
try { |
204 |
|
|
for( i = iterator(); i.hasNext(); count++) i.next(); |
205 |
|
|
} |
206 |
|
|
finally { |
207 |
|
|
close( i ); |
208 |
|
|
} |
209 |
|
|
//Xulu-01.sn |
210 |
|
|
this.size = count; |
211 |
|
|
//Xulu-01.en |
212 |
|
|
return count; |
213 |
|
|
} |
214 |
|
|
|
215 |
|
|
public boolean isEmpty() { |
216 |
|
|
Iterator iterator = iterator(); |
217 |
|
|
try { |
218 |
|
|
return !iterator.hasNext(); |
219 |
|
|
} |
220 |
|
|
finally { |
221 |
|
|
close( iterator ); |
222 |
|
|
} |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
public Iterator openIterator() { |
226 |
|
|
return new FilteredIterator( collection, filter() ); |
227 |
|
|
} |
228 |
|
|
|
229 |
|
|
|
230 |
|
|
public SimpleFeatureType getSchema() { |
231 |
|
|
return collection.getSchema(); |
232 |
|
|
} |
233 |
|
|
|
234 |
|
|
/** |
235 |
|
|
* Accepts a visitor, which then visits each feature in the collection. |
236 |
|
|
* @throws IOException |
237 |
|
|
*/ |
238 |
|
|
public void accepts(FeatureVisitor visitor, ProgressListener progress ) throws IOException { |
239 |
|
|
Iterator iterator = null; |
240 |
|
|
// if( progress == null ) progress = new NullProgressListener(); |
241 |
|
|
try{ |
242 |
|
|
float size = size(); |
243 |
|
|
float position = 0; |
244 |
|
|
progress.started(); |
245 |
|
|
for( iterator = iterator(); !progress.isCanceled() && iterator.hasNext(); progress.progress( position++/size )){ |
246 |
|
|
try { |
247 |
|
|
SimpleFeature feature = (SimpleFeature) iterator.next(); |
248 |
|
|
visitor.visit(feature); |
249 |
|
|
} |
250 |
|
|
catch( Exception erp ){ |
251 |
|
|
progress.exceptionOccurred( erp ); |
252 |
|
|
} |
253 |
|
|
} |
254 |
|
|
} |
255 |
|
|
finally { |
256 |
|
|
progress.complete(); |
257 |
|
|
close( iterator ); |
258 |
|
|
} |
259 |
|
|
} |
260 |
|
|
|
261 |
|
|
public FeatureReader reader() throws IOException { |
262 |
|
|
return new DelegateFeatureReader( getSchema(), features() ); |
263 |
|
|
} |
264 |
|
|
|
265 |
|
|
public int getCount() throws IOException { |
266 |
|
|
return size(); |
267 |
|
|
} |
268 |
|
|
|
269 |
|
|
public FeatureCollection collection() throws IOException { |
270 |
|
|
return this; |
271 |
|
|
} |
272 |
|
|
|
273 |
|
|
public FeatureList sort(SortBy order) { |
274 |
|
|
return null; |
275 |
|
|
} |
276 |
|
|
|
277 |
|
|
public void purge() { |
278 |
|
|
collection.purge(); |
279 |
|
|
} |
280 |
|
|
} |