org.geotools.feature
Interface Feature

All Known Subinterfaces:
FeatureCollection, FeatureDocument, FeatureList, IndexedFeatureCollection, RandomFeatureAccess, SimpleFeature
All Known Implementing Classes:
AbstractFeatureCollection, AbstractFeatureCollection, AbstractFeatureList, DataFeatureCollection, DefaultFeature, DefaultFeatureCollection, MemoryFeatureCollection, SubFeatureCollection, SubFeatureList

public interface Feature

Represents a feature of arbitrary complexity. This interface answers the question: How do we access feature attributes? The most generic approach would be to pass all feature attributes as objects and use Java variable and method references to access them. However, this is also the most useless approach because it establishes no unified methods for getting attribute information (since it is totally Object dependent), without elaborate reflection/introspection, which is inconvenient to use. Unlike its FeatureType counterpart, this interface does not attempt to serve as a typing framework. Rather, multiple implementations of this interface should generally be for performance reasons.

This interface serves two important purposes. Most obviously, it gives users of features a unified, consistent framework for accessing and manipulating feature data. Perhaps more importantly, the FeatureType and Feature interfaces also work together to give implementers a framework for constraining and enforcing constraints (respectively) on allowed feature types. As such, this interface is as general as possible in terms of the types of objects to which it provides access. Keep in mind that creating new features is relatively difficult and should only be done to optimize performance for highly constrained schema types. For the vast majority of schemas, the generic feature implementation will work fine.

Notes for Feature Clients:
Clients should always use feature accessor methods (getAttribute and setAttribute) to modify the state of internal attribute objects. It is possible that some feature implementations will allow object state changes by clients outside of the class, but this is strongly discouraged. In general, feature implementations will make defensive copies of objects passed to clients and it is therefore not guaranteed that client state changes that take place outside of the feature will be reflected in the internal state of the feature object! For this reason, clients should always use the set methods to change feature attribute object states!

Notes for Feature Implementers:
It is the responsibility of the implementing class to ensure that the Feature attributes stay synchronized with its FeatureType definition. Features should never get out of synch with their declared schemas and should never alter their schemas! There are four conventions of which implementers of this interface must be aware in order to successfully manage a Feature:

  1. FeatureType Reference
    Features must always hold a single (immutable: see FeatureType) schema reference and this reference should not be altered after a feature has been created. To ensure this, is is strongly recommended that features take a valid reference to an existing immutable schema in its constructor and declare that reference final.
  2. Default Geometry
    Each feature must have a default geometry, but this primary geometry may be null. This means that a feature may contain no geometries, but it must always have a method for accessing a geometry object (even if it is null). It also means that a feature with multiple geometries must pick one as its default geometry. Note that the designation of the default geometry is stored as part of the FeatureType and is therefore immmutable.
  3. Attributes
    All features contain zero or more attributes, which can have one or more occurrences inside the feature. Attributes may be any valid Java object. If attributes are instances of Feature, they are handled specially by the Feature methods, in that their attributes may be accessed directly by their containing feature. All other object variables and methods must be accessed through the objects themselves. It is up to implementers of Feature to make sure that each attribute value conforms to its internal schema. A feature should never reach a state where its attributes (or sub-attributes) do not conform to their FeatureType definitions. There are three ways to implement this. The first is to simply make features immutable; however, given the ubiquity and required flexibility of features, this is likely not possible. The second (and second easiest), is to make all feature attributes immutable. For most cases, this is probably the best way to handle this issue. The third way, is to never give out a reference that would allow a client to change an attribute object's class (most obviously, an array reference). Generally speaking, features should attempt to minimize external object references by attempting to clone incoming attributes before adding them and outgoing attributes before sending them. For features with non-cloneable attributes, of course, this is not possible, so this is left to the discretion of the implementor.
  4. Constructors
    Constructors should take arguments with enough information to create a valid representation of the feature. They should also always include a valid schema that can be used to check the proposed attributes. This is necessary to ensure that the feature is always in a valid state, relative to its schema.
  5. hashCode() and equals(Object other)
    Determining equality and equivalence for Feature instances is of utmost importance. This must be done in a constistent manner, as many other areas of geotools will rely on these relations. See java.lang.Object for details.

Version:
$Id: Feature.java 17702 2006-01-23 00:08:55Z desruisseaux $
Author:
James Macgill, CCG, Rob Hranac, TOPP, Ian Schneider, USDA-ARS, dzwiers
See Also:
FeatureType, DefaultFeature

Nested Class Summary
static class Feature.NULL
          Not straight forward, this is a "null" object to represent the value null for a given attribute which is nullable.
 
Method Summary
 java.lang.Object getAttribute(int index)
          Gets an attribute by the given zero-based index.
 java.lang.Object getAttribute(java.lang.String xPath)
          Gets an attribute for this feature at the location specified by xPath.
 java.lang.Object[] getAttributes(java.lang.Object[] attributes)
          Copy all the attributes of this Feature into the given array.
 com.vividsolutions.jts.geom.Envelope getBounds()
          Get the total bounds of this feature which is calculated by doing a union of the bounds of each geometry this feature is associated with.
 com.vividsolutions.jts.geom.Geometry getDefaultGeometry()
          Gets the default geometry for this feature.
 FeatureType getFeatureType()
          Gets a reference to the schema for this feature.
 java.lang.String getID()
          Gets the unique feature ID for this feature.
 int getNumberOfAttributes()
          Get the number of attributes this feature has.
 FeatureCollection getParent()
          Deprecated. Please don't use, a Feature can be in more then one collection
 void setAttribute(int position, java.lang.Object val)
          Sets an attribute by the given zero-based index.
 void setAttribute(java.lang.String xPath, java.lang.Object attribute)
          Sets a single attribute for this feature, passed as a complex object.
 void setDefaultGeometry(com.vividsolutions.jts.geom.Geometry geometry)
          Sets the default geometry for this feature.
 void setParent(FeatureCollection collection)
          Sets the parent collection this feature is stored in, if it is not already set.
 

Method Detail

getParent

public FeatureCollection getParent()
Deprecated. Please don't use, a Feature can be in more then one collection

Gets the feature collection this feature is stored in.

Returns:
The collection that is the parent of this feature.

setParent

public void setParent(FeatureCollection collection)
Sets the parent collection this feature is stored in, if it is not already set. If it is set then this method does nothing.

Parameters:
collection - the collection to be set as parent.

getFeatureType

public FeatureType getFeatureType()
Gets a reference to the schema for this feature.

Returns:
A reference to this feature's schema.

getID

public java.lang.String getID()
Gets the unique feature ID for this feature.

Returns:
Unique identifier for this feature.

getAttributes

public java.lang.Object[] getAttributes(java.lang.Object[] attributes)
Copy all the attributes of this Feature into the given array. If the argument array is null, a new one will be created. Gets all attributes from this feature, returned as a complex object array. This array comes with no metadata, so to interpret this collection the caller class should ask for the schema as well. This array may have multiple entries for each AttributeType depending on the AttributeType's multiplicity.

Parameters:
attributes - An array to copy attributes into. May be null.
Returns:
The array passed in, or a new one if null.

getAttribute

public java.lang.Object getAttribute(java.lang.String xPath)
Gets an attribute for this feature at the location specified by xPath. Due to the complex nature of xpath, a List of all valid values will be returned when an attribute is requested. These values can range from complete Feature Collections to single primative attribute values. When a particular instance of the Attribute is requested, then the Object will be returned. Simply put, in the general case we are assuming the existance of multiplicity, so specify which instance you want or you get them all. Example of getting a list: ./road returns the List of road attribute instances Example of getting an Object: ./road[0] returns the first road

Parameters:
xPath - XPath representation of attribute location.
Returns:
A List of copies of the requested attribute, null if the requested xpath is not found, or NULL_ATTRIBUTE.

getAttribute

public java.lang.Object getAttribute(int index)
Gets an attribute by the given zero-based index. This index is based on the values within the Feature as opposed to the AttributeType declaration. To get the values for the 5th attributeType, use the schema to determine the xPath and class the getAttribute(xPath) method.

Parameters:
index - The requested index. Must be 0 <= idx < getNumberOfAttributes().
Returns:
A copy of the requested attribute, or NULL_ATTRIBUTE.
See Also:
getAttribute(String)

setAttribute

public void setAttribute(int position,
                         java.lang.Object val)
                  throws IllegalAttributeException,
                         java.lang.ArrayIndexOutOfBoundsException
Sets an attribute by the given zero-based index. This index is based on the values within the Feature as opposed to the AttributeType declaration. To get the values for the 5th attributeType, use the schema to determine the xPath and class the setAttribute(xPath,val) method.

Parameters:
position - The requested index. Must be 0 <= idx < getNumberOfAttributes()
val - An object representing the attribute being set
Throws:
IllegalAttributeException - if the passed in val does not validate against the AttributeType at that position.
java.lang.ArrayIndexOutOfBoundsException - if an invalid position is given
See Also:
setAttribute(String, Object)

getNumberOfAttributes

public int getNumberOfAttributes()
Get the number of attributes this feature has. This is NOT simply a convenience method for calling getFeatureType().getNumberOfAttributes(). This is the same as calling getAttributes(null).length. This represents the number of actual attribute values in the feature, and may differ from the number of AttributeTypes defined in the FeatureType based on the multiplicity of the AttributeTypes.

Returns:
The total number of attributes this Feature contains.

setAttribute

public void setAttribute(java.lang.String xPath,
                         java.lang.Object attribute)
                  throws IllegalAttributeException
Sets a single attribute for this feature, passed as a complex object. If the attribute does not exist or the object does not conform to the internal schema, an exception is thrown. Checking this is, of course, left to the feature to do internally. Well behaved features should always fully check the passed attributes against thire schema before adding them. NOTE: The xPath may contain instance information about multiplicity, for example: ./road[3] which is the third road attribute in this feature.

Parameters:
xPath - XPath representation of attribute location.
attribute - Feature attribute to set.
Throws:
IllegalAttributeException - If the attribute is illegal for the path specified.

getDefaultGeometry

public com.vividsolutions.jts.geom.Geometry getDefaultGeometry()
Gets the default geometry for this feature.

This method will return null if no DefaultGeometry has been defined by the schema.

Returns:
Default geometry for this feature, or null

setDefaultGeometry

public void setDefaultGeometry(com.vividsolutions.jts.geom.Geometry geometry)
                        throws IllegalAttributeException
Sets the default geometry for this feature.

Parameters:
geometry - The geometry to set.
Throws:
IllegalAttributeException - If the AttributeType is not a geometry, or is invalid for some other reason.

getBounds

public com.vividsolutions.jts.geom.Envelope getBounds()
Get the total bounds of this feature which is calculated by doing a union of the bounds of each geometry this feature is associated with.

This method will return an empty Envelope if the feature contains no geometry information.

Returns:
An Envelope containing the total bounds of this Feature.


Copyright © GeoTools. All Rights Reserved.