/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * 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; * version 2.1 of the License. * * 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. */ package org.geotools.feature; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.resources.Utilities; import org.opengis.feature.GeometryAttribute; import org.opengis.feature.type.AttributeDescriptor; import org.opengis.feature.type.GeometryDescriptor; import org.opengis.feature.type.GeometryType; import org.opengis.filter.identity.Identifier; import org.opengis.geometry.BoundingBox; import org.opengis.referencing.crs.CoordinateReferenceSystem; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; /** * TODO: rename to GeometricAttribute Provides ...TODO summary sentence * <p> * TODO Description * </p> * <p> * </p> * <p> * Example Use: * * <pre><code> * GeometryAttributeType x = new GeometryAttributeType( ... ); * TODO code example * </code></pre> * * </p> * * @author Leprosy * @since 0.3 TODO: test wkt geometry parse. * * @source $URL$ */ public class GeometryAttributeImpl extends AttributeImpl implements GeometryAttribute { /** * bounds, derived */ protected BoundingBox bounds; public GeometryAttributeImpl( Object content, GeometryDescriptor descriptor, Identifier id ) { super(content, descriptor, id); } public GeometryType getType() { return (GeometryType) super.getType(); } public GeometryDescriptor getDescriptor() { return (GeometryDescriptor) super.getDescriptor(); } public Geometry getValue() { return (Geometry) super.getValue(); } public void setValue(Object newValue) throws IllegalArgumentException, IllegalStateException { setValue( (Geometry) newValue ); } public void setValue(Geometry geometry) { super.setValue(geometry); } /** * Set the bounds for the contained geometry. */ public synchronized void setBounds( BoundingBox bbox ){ bounds = bbox; } /** * Returns the non null envelope of this attribute. If the attribute's * geometry is <code>null</code> the returned Envelope * <code>isNull()</code> is true. * * @return */ public synchronized BoundingBox getBounds() { if( bounds == null ){ ReferencedEnvelope bbox = new ReferencedEnvelope(getType().getCoordinateReferenceSystem()); Geometry geom = (Geometry) getValue(); if (geom != null) { bbox.expandToInclude(geom.getEnvelopeInternal()); } else { bbox.setToNull(); } bounds = bbox; } return bounds; } public boolean equals(Object o) { if ( this == o ) { return true; } if (!(o instanceof GeometryAttributeImpl)) { return false; } GeometryAttributeImpl att = (GeometryAttributeImpl) o; //JD: since Geometry does not implement equals(Object) "properly",( ie // if you dont call equals(Geomtery) two geometries which are equal // will not be equal) we dont call super.equals() if (!Utilities.equals(descriptor, att.descriptor)) return false; if (!Utilities.equals(id, att.id)) return false; if ( value != null && att.value != null ) { //another lovley jts thing... comparing geometry collections that // arent multi point/line/poly throws an exception, so we nee dto // that comparison if ( att.value instanceof GeometryCollection && !(att.value instanceof MultiPoint) && !(att.value instanceof MultiLineString) && !(att.value instanceof MultiPolygon) ) { if ( value instanceof GeometryCollection ) { //compare the two collections GeometryCollection c1 = (GeometryCollection) value; GeometryCollection c2 = (GeometryCollection) att.value; if ( c1.getNumGeometries() != c2.getNumGeometries() ) { return false; } for ( int i = 0; i < c1.getNumGeometries(); i++ ) { Geometry g1 = c1.getGeometryN(i); Geometry g2 = c2.getGeometryN(i); if ( !g1.equals(g2) ) { return false; } } return true; } else { return false; } } if ( !((Geometry)value).equals((Geometry)att.value)) { return false; } } else { return Utilities.deepEquals(value, this.value); } return true; } public int hashCode() { int hash = descriptor.hashCode(); if ( id != null ) { hash += 37 * id.hashCode(); } return hash; } public String toString() { StringBuffer sb = new StringBuffer(getClass().getSimpleName()).append(":"); sb.append(getDescriptor().getName().getLocalPart()); CoordinateReferenceSystem crs = getDescriptor().getType().getCoordinateReferenceSystem(); if(!getDescriptor().getName().getLocalPart().equals(getDescriptor().getType().getName().getLocalPart()) || id != null || crs != null){ sb.append("<"); sb.append(getDescriptor().getType().getName().getLocalPart()); if( id != null ){ sb.append( " id="); sb.append( id ); } if( crs != null ){ sb.append( " crs="); sb.append( crs ); } if( id != null ){ sb.append( " id="); sb.append( id ); } sb.append(">"); } sb.append("="); sb.append(value); return sb.toString(); } }