001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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 }