/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2006 by: EXSE, Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53115 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.graphics; import java.util.ArrayList; import org.deegree.model.crs.CoordinateSystem; import org.deegree.model.crs.GeoTransformer; import org.deegree.model.crs.IGeoTransformer; import org.deegree.model.feature.Feature; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.feature.FeatureFactory; import org.deegree.model.feature.FeatureProperty; import org.deegree.model.spatialschema.Envelope; import org.deegree.model.spatialschema.Geometry; import org.deegree.model.spatialschema.GeometryFactory; import org.deegree.model.spatialschema.Point; import org.deegree.model.spatialschema.Position; /** * A Layer is a collection of <tt>Feature</tt>s building a thematic 'unit' waterways or country * borders for example. <tt>Feature</tt>s can be added or removed from the layer. A * <tt>Feature</tt> can e changed by a modul of the application using the layer because only * references to <tt>Feature</tt>s are stored within a layer. * * <p> * ------------------------------------------------------------------------ * </p> * * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @version $Revision: 1.21 $ $Date: 2006/11/27 09:07:52 $ */ public class FeatureLayer extends AbstractLayer { private FeatureCollection fc = null; /** * creates a layer with EPSG:4326 as default coordinate system */ FeatureLayer( String name ) throws Exception { super( name ); fc = FeatureFactory.createFeatureCollection( name, 50 ); init( fc ); } /** * Creates a new FeatureLayer object. * * @param name * @param crs * * @throws Exception */ FeatureLayer( String name, CoordinateSystem crs ) throws Exception { super( name, crs ); fc = FeatureFactory.createFeatureCollection( name, 50 ); init( fc ); } /** * Creates a new AbstractLayer object. * * @param name * @param crs * @param fc * * @throws Exception */ FeatureLayer( String name, CoordinateSystem crs, FeatureCollection fc ) throws Exception { super( name, crs ); init( fc ); } /** * initializes serveral parameters of the layer and homogenizes the coordinate reference systems * of the features */ private void init( FeatureCollection feature ) throws Exception { this.fc = FeatureFactory.createFeatureCollection( feature.getId(), feature.size() ); // create object for coordinate transformation IGeoTransformer gt = new GeoTransformer( cs ); double minx = 9E99; double maxx = -9E99; double miny = 9E99; double maxy = -9E99; String s1 = cs.getName(); for (int i = 0; i < feature.size(); i++) { Feature feat = feature.getFeature( i ); FeatureProperty[] prop = feat.getProperties(); FeatureProperty[] propN = new FeatureProperty[prop.length]; boolean changed = false; for (int k = 0; k < prop.length; k++) { Object value = prop[k].getValue(); propN[k] = prop[k]; if ( value instanceof Geometry ) { CoordinateSystem _cs_ = ( (Geometry) value ).getCoordinateSystem(); String s2 = null; if ( _cs_ != null ) { s2 = _cs_.getName(); } else { // default reference system s2 = "EPSG:4326"; } if ( !s1.equalsIgnoreCase( s2 ) ) { Geometry transformedGeometry = gt.transform( (Geometry) value ); propN[k] = FeatureFactory.createFeatureProperty( prop[k].getName(), transformedGeometry ); changed = true; value = transformedGeometry; } if ( value instanceof Point ) { Position pos = ( (Point) value ).getPosition(); if ( pos.getX() > maxx ) { maxx = pos.getX(); } if ( pos.getX() < minx ) { minx = pos.getX(); } if ( pos.getY() > maxy ) { maxy = pos.getY(); } if ( pos.getY() < miny ) { miny = pos.getY(); } } else { Envelope en = ( (Geometry) value ).getEnvelope(); if ( en.getMax().getX() > maxx ) { maxx = en.getMax().getX(); } if ( en.getMin().getX() < minx ) { minx = en.getMin().getX(); } if ( en.getMax().getY() > maxy ) { maxy = en.getMax().getY(); } if ( en.getMin().getY() < miny ) { miny = en.getMin().getY(); } } } } if ( changed ) { FeatureProperty[] fp = new FeatureProperty[propN.length]; for (int j = 0; j < fp.length; j++) { fp[j] = FeatureFactory.createFeatureProperty( propN[j].getName(), propN[j].getValue() ); } feat = FeatureFactory.createFeature( feat.getId(), feat.getFeatureType(), fp ); } fc.add( feat ); } boundingbox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, null ); } private void recalculateBoundingbox() { double minx = 9E99; double maxx = -9E99; double miny = 9E99; double maxy = -9E99; for (int i = 0; i < fc.size(); i++) { Geometry[] prop = fc.getFeature( i ).getGeometryPropertyValues(); for (int k = 0; k < prop.length; k++) { if ( prop[k] instanceof Point ) { Position pos = ( (Point) prop[k] ).getPosition(); if ( pos.getX() > maxx ) { maxx = pos.getX(); } if ( pos.getX() < minx ) { minx = pos.getX(); } if ( pos.getY() > maxy ) { maxy = pos.getY(); } if ( pos.getY() < miny ) { miny = pos.getY(); } } else { Envelope en = ( prop[k] ).getEnvelope(); if ( en.getMax().getX() > maxx ) { maxx = en.getMax().getX(); } if ( en.getMin().getX() < minx ) { minx = en.getMin().getX(); } if ( en.getMax().getY() > maxy ) { maxy = en.getMax().getY(); } if ( en.getMin().getY() < miny ) { miny = en.getMin().getY(); } } } } boundingbox = GeometryFactory.createEnvelope( minx, miny, maxx, maxy, null ); } /** * returns the feature that matches the submitted id */ public Feature getFeatureById( String id ) { return fc.getFeature( id ); } /** * returns the feature that matches the submitted id */ public Feature[] getFeaturesById( String[] ids ) { ArrayList list = new ArrayList(); Feature feature = null; for (int i = 0; i < fc.size(); i++) { feature = fc.getFeature( i ); for (int k = 0; k < ids.length; k++) { if ( feature.getId().equals( ids[k] ) ) { list.add( feature ); break; } } } return (Feature[]) list.toArray( new Feature[list.size()] ); } /** * returns the feature that matches the submitted index */ public Feature getFeature( int index ) { Feature feature = fc.getFeature( index ); return feature; } /** * returns all features */ public Feature[] getAllFeatures() { return fc.toArray(); } /** * adds a feature to the layer */ public void addFeature( Feature feature ) throws Exception { fc.add( feature ); recalculateBoundingbox(); } /** * adds a feature collection to the layer */ public void addFeatureCollection( FeatureCollection featureCollection ) throws Exception { fc.add( featureCollection ); recalculateBoundingbox(); } /** * removes a display Element from the layer */ public void removeFeature( Feature feature ) throws Exception { fc.remove( feature ); recalculateBoundingbox(); } /** * removes the display Element from the layer that matches the submitted id */ public void removeFeature( int id ) throws Exception { removeFeature( getFeature( id ) ); } /** * returns the amount of features within the layer. */ public int getSize() { return fc.size(); } /** * sets the coordinate reference system of the MapView. If a new crs is set all geometries of * GeometryFeatures will be transformed to the new coordinate reference system. */ public void setCoordinatesSystem( CoordinateSystem crs ) throws Exception { if ( !cs.equals( crs ) ) { this.cs = crs; init( fc ); } } }/* ******************************************************************** Changes to this class. What the people have been up to: $Log: FeatureLayer.java,v $ Revision 1.21 2006/11/27 09:07:52 poth JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code. Revision 1.20 2006/11/21 13:13:11 poth bug fix - calculating bbox for point layers Revision 1.19 2006/08/29 14:38:15 poth bug fix - recreating feature if geometry/CRS has been transformed; check for CRS being equal Revision 1.18 2006/07/29 08:51:12 poth references to deprecated classes removed Revision 1.17 2006/07/12 14:46:18 poth comment footer added ********************************************************************** */