001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/src/org/deegree/graphics/FeatureLayer.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.graphics;
037
038 import java.util.ArrayList;
039 import java.util.List;
040
041 import org.deegree.model.crs.CoordinateSystem;
042 import org.deegree.model.crs.GeoTransformer;
043 import org.deegree.model.feature.Feature;
044 import org.deegree.model.feature.FeatureCollection;
045 import org.deegree.model.feature.FeatureFactory;
046 import org.deegree.model.feature.FeatureProperty;
047 import org.deegree.model.spatialschema.Envelope;
048 import org.deegree.model.spatialschema.Geometry;
049 import org.deegree.model.spatialschema.GeometryFactory;
050 import org.deegree.model.spatialschema.Point;
051 import org.deegree.model.spatialschema.Position;
052
053 /**
054 * A Layer is a collection of <tt>Feature</tt>s building a thematic 'unit' waterways or country
055 * borders for example. <tt>Feature</tt>s can be added or removed from the layer. A
056 * <tt>Feature</tt> can e changed by a modul of the application using the layer because only
057 * references to <tt>Feature</tt>s are stored within a layer.
058 *
059 *
060 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
061 * @version $Revision: 19454 $ $Date: 2009-09-01 14:27:33 +0200 (Di, 01. Sep 2009) $
062 */
063
064 public class FeatureLayer extends AbstractLayer {
065
066 protected FeatureCollection fc = null;
067
068 /**
069 * creates a layer with EPSG:4326 as default coordinate system
070 * @param name of the feature
071 * @throws Exception
072 */
073 protected FeatureLayer( String name ) throws Exception {
074 super( name );
075
076 fc = FeatureFactory.createFeatureCollection( name, 50 );
077
078 init( fc );
079 }
080
081 /**
082 * Creates a new FeatureLayer object.
083 *
084 * @param name
085 * @param crs
086 *
087 * @throws Exception
088 */
089 protected FeatureLayer( String name, CoordinateSystem crs ) throws Exception {
090 super( name, crs );
091
092 fc = FeatureFactory.createFeatureCollection( name, 50 );
093
094 init( fc );
095 }
096
097 /**
098 * Creates a new AbstractLayer object.
099 *
100 * @param name
101 * @param crs
102 * @param fc
103 *
104 * @throws Exception
105 */
106 protected FeatureLayer( String name, CoordinateSystem crs, FeatureCollection fc ) throws Exception {
107 super( name, crs );
108 init( fc );
109 }
110
111 /**
112 * initializes several parameters of the layer and homogenizes the coordinate reference systems
113 * of the features
114 *
115 * @param feature
116 * @throws Exception
117 */
118 private void init( FeatureCollection feature )
119 throws Exception {
120
121 this.fc = FeatureFactory.createFeatureCollection( feature.getId(), feature.size() );
122 // create object for coordinate transformation
123 GeoTransformer gt = new GeoTransformer( cs );
124 double minx = 9E99;
125 double maxx = -9E99;
126 double miny = 9E99;
127 double maxy = -9E99;
128 String s1 = cs.getIdentifier();
129 for ( int i = 0; i < feature.size(); i++ ) {
130 Feature feat = feature.getFeature( i );
131 FeatureProperty[] prop = feat.getProperties();
132 FeatureProperty[] propN = new FeatureProperty[prop.length];
133 boolean changed = false;
134 for ( int k = 0; k < prop.length; k++ ) {
135
136 Object value = prop[k].getValue();
137 propN[k] = prop[k];
138 if ( value instanceof Geometry ) {
139
140 CoordinateSystem _cs_ = ( (Geometry) value ).getCoordinateSystem();
141 String s2 = null;
142 if ( _cs_ != null ) {
143 s2 = _cs_.getIdentifier();
144 } else {
145 // default reference system
146 s2 = "EPSG:4326";
147 }
148
149 if ( !s1.equalsIgnoreCase( s2 ) ) {
150 Geometry transformedGeometry = gt.transform( (Geometry) value );
151 propN[k] = FeatureFactory.createFeatureProperty( prop[k].getName(), transformedGeometry );
152 changed = true;
153 value = transformedGeometry;
154 }
155 if ( value instanceof Point ) {
156 Position pos = ( (Point) value ).getPosition();
157 if ( pos.getX() > maxx ) {
158 maxx = pos.getX();
159 }
160 if ( pos.getX() < minx ) {
161 minx = pos.getX();
162 }
163 if ( pos.getY() > maxy ) {
164 maxy = pos.getY();
165 }
166 if ( pos.getY() < miny ) {
167 miny = pos.getY();
168 }
169 } else {
170 Envelope en = ( (Geometry) value ).getEnvelope();
171 if ( en.getMax().getX() > maxx ) {
172 maxx = en.getMax().getX();
173 }
174 if ( en.getMin().getX() < minx ) {
175 minx = en.getMin().getX();
176 }
177 if ( en.getMax().getY() > maxy ) {
178 maxy = en.getMax().getY();
179 }
180 if ( en.getMin().getY() < miny ) {
181 miny = en.getMin().getY();
182 }
183 }
184 }
185 }
186 if ( changed ) {
187 FeatureProperty[] fp = new FeatureProperty[propN.length];
188 for ( int j = 0; j < fp.length; j++ ) {
189 fp[j] = FeatureFactory.createFeatureProperty( propN[j].getName(), propN[j].getValue() );
190 }
191 feat = FeatureFactory.createFeature( feat.getId(), feat.getFeatureType(), fp );
192 }
193 fc.add( feat );
194 }
195
196 boundingbox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, null );
197
198 }
199
200 /**
201 *
202 *
203 */
204 private void recalculateBoundingbox() {
205
206 double minx = 9E99;
207 double maxx = -9E99;
208 double miny = 9E99;
209 double maxy = -9E99;
210
211 for ( int i = 0; i < fc.size(); i++ ) {
212 Geometry[] prop = fc.getFeature( i ).getGeometryPropertyValues();
213 for ( int k = 0; k < prop.length; k++ ) {
214 if ( prop[k] instanceof Point ) {
215 Position pos = ( (Point) prop[k] ).getPosition();
216 if ( pos.getX() > maxx ) {
217 maxx = pos.getX();
218 }
219 if ( pos.getX() < minx ) {
220 minx = pos.getX();
221 }
222 if ( pos.getY() > maxy ) {
223 maxy = pos.getY();
224 }
225 if ( pos.getY() < miny ) {
226 miny = pos.getY();
227 }
228 } else {
229 Envelope en = ( prop[k] ).getEnvelope();
230 if ( en.getMax().getX() > maxx ) {
231 maxx = en.getMax().getX();
232 }
233 if ( en.getMin().getX() < minx ) {
234 minx = en.getMin().getX();
235 }
236 if ( en.getMax().getY() > maxy ) {
237 maxy = en.getMax().getY();
238 }
239 if ( en.getMin().getY() < miny ) {
240 miny = en.getMin().getY();
241 }
242 }
243 }
244 }
245
246 boundingbox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, null );
247
248 }
249
250 /**
251 * returns the feature that matches the submitted id
252 *
253 * @param id
254 * @return feature identified by its id
255 */
256 public Feature getFeatureById( String id ) {
257 return fc.getFeature( id );
258 }
259
260 /**
261 * returns the feature that matches the submitted id
262 *
263 * @param ids
264 * @return features identified by their id
265 */
266 public Feature[] getFeaturesById( String[] ids ) {
267
268 List<Feature> list = new ArrayList<Feature>();
269
270 Feature feature = null;
271
272 for ( int i = 0; i < fc.size(); i++ ) {
273 feature = fc.getFeature( i );
274
275 for ( int k = 0; k < ids.length; k++ ) {
276 if ( feature.getId().equals( ids[k] ) ) {
277 list.add( feature );
278 break;
279 }
280 }
281 }
282
283 return list.toArray( new Feature[list.size()] );
284 }
285
286 /**
287 * returns the feature that matches the submitted index
288 *
289 * @param index
290 * @return a feature
291 */
292 public Feature getFeature( int index ) {
293 Feature feature = fc.getFeature( index );
294 return feature;
295 }
296
297 /**
298 * returns all features
299 *
300 * @return all features as array
301 */
302 public Feature[] getAllFeatures() {
303 return fc.toArray();
304 }
305
306 /**
307 * adds a feature to the layer
308 *
309 * @param feature
310 * @throws Exception
311 */
312 public void addFeature( Feature feature )
313 throws Exception {
314 fc.add( feature );
315 recalculateBoundingbox();
316 }
317
318 /**
319 * adds a feature collection to the layer
320 *
321 * @param featureCollection
322 * @throws Exception
323 */
324 public void addFeatureCollection( FeatureCollection featureCollection )
325 throws Exception {
326 fc.add( featureCollection );
327 recalculateBoundingbox();
328 }
329
330 /**
331 * removes a display Element from the layer
332 *
333 * @param feature
334 * @throws Exception
335 */
336 public void removeFeature( Feature feature )
337 throws Exception {
338 fc.remove( feature );
339 recalculateBoundingbox();
340 }
341
342 /**
343 * removes the display Element from the layer that matches the submitted id
344 *
345 * @param id
346 * @throws Exception
347 */
348 public void removeFeature( int id )
349 throws Exception {
350 removeFeature( getFeature( id ) );
351 }
352
353 /**
354 * returns the amount of features within the layer.
355 *
356 * @return number of contained features
357 */
358 public int getSize() {
359 return fc.size();
360 }
361
362 /**
363 * sets the coordinate reference system of the MapView. If a new crs is set all geometries of
364 * GeometryFeatures will be transformed to the new coordinate reference system.
365 *
366 * @param crs
367 * @throws Exception
368 */
369 public void setCoordinatesSystem( CoordinateSystem crs )
370 throws Exception {
371 if ( !cs.equals( crs ) ) {
372 this.cs = crs;
373 init( fc );
374 }
375 }
376 }