| org.geotools.feature.FeatureType
All known Subclasses: org.geotools.data.wfs.WFSFeatureType, org.geotools.data.feature.adapter.GTComlexFeatureTypeAdapter, org.geotools.feature.DefaultFeatureType, org.geotools.data.feature.adapter.GTFeatureTypeAdapter, org.geotools.data.vpf.VPFFeatureType, org.geotools.data.DummyFeatureType, org.geotools.data.vpf.file.VPFFile, org.geotools.data.vpf.VPFFeatureClass,
FeatureType | public interface FeatureType (Code) | | A metadata template for a Feature of arbitrary complexity.
Notes:
- that this documentation should be read in conjunction with the
Feature API.
- the attributes described by this FeatureType and its ancestors define the complete
schema for a Feature
This interface answers the question: How do we represent features within GeoTools? Of course, the
most general answer would be: features can be any Java object. However, this is also the least
useful solution because it means that users of features have essentially no way to find out about
the meaning of features other than using Java introspection/reflection. This is too cumbersome
and is insufficient for the goal of creating a simple framework for manipulating and accessing
generic geographic data. The opposite approach might be to define a very constrained set of
possible attributes (that, for example, mirrored Java primitives and OGC simple geometries) and
only allow features of this type.
This interface takes a different approach: it defines a minimal ontology for representing a
feature and serves as a consistent framework for defining more constrained (and, therefore, often
more meaningful) feature types. A FeatureType represents features as an object
that contains zero or more attribute objects, one of which will generally be a geometry, but no
geometry and multiple geometries are allowed, according to implementation. Note that instances of
implementations of this class are henceforth referred to as schemas.
With oneexceptions, the type of an attribute is considered to be its cannonical definition by the
FeatureType. For example, an attribute type might be a javax.sound.midi.Sequence
object, which contains a float public field called PPQ. The fact that this
attribute exists is not known by the FeatureType itself. If a caller asks this
FeatureType for all of its attributes, the
FeatureType will tell
the caller that it has an attribute of type javax.sound.midi.Sequence , but not
that this attribute has a sub-attribute (field) called PPQ. It is the responsibility of the
callers to understand the objects it is asking for and manipulate them appropriately.
The exceptions is for:
- if the type stored in the
FeatureType is a
org.geotools.datasource.Feature type.
In this case, all information about sub-attributes are stored and passed to calling classes upon
request. The style of reference (XPath) is defined in and mediated by FeatureType
implementations.
Question: how does one determine the schema for the attribute defined as a FeatureType? I suspect
that FeatureType may be a valid AttributeType? (One needs this schema information before xpath
can be used to query the Feature value.
It is the responsibility of the implementing class to ensure that the FeatureType
is always in a valid state. This means that each attribute tuple must be fully initialized and
valid. The minimum valid FeatureType is one with nulls for namespace, type, and
attributes; this is clearly a trivial case, since it is so constrained that it would not allow
for any feature construction. There are a few conventions of which implementers of this interface
must be aware in order to successfully manage a FeatureType :
- Immutability
FeatureTypes must be implemented as immutable objects! All setting methods have been
removed from this interface, that functionality is now available in the mutable
FeatureTypeFactory
- Default Geometries
Note that the FeatureType contains a special methods for handling geometries. The primary
geometry retrieval methods are in Feature because they may change over the life of
the feature, while the schema may not. In cases where there are more than one geometries it is up
to the implementor to determine which is the default geometry. getDefaultGeometry
may return null if there are no geometries in the FeatureType, but if there is one
or more geometry then the method must return one of them, null is never an
acceptable return value.
- XPath
XPath is the standard used to access all attributes (flat, nested, and multiple), via a single,
unified string. Using XPath to access attributes has the convenient side-benefit of making them
appear to be non-nested and non-multiple to callers with no awareness of XPath. This greatly
simplifies accessing and manipulating data. However, it does put extra burden on the implementers
of FeatureType to understand and correctly implement XPath pointers. Note that the
Feature object does not understand XPath at all and relies on implementors of this
interface to interpret XPath references. Fortunately, XPath is quite simple and has a clearly
written specification .
- Feature Creation
FeatureType also must provide methods for the creation of Features, as specified in
FeatureFactory. The creating FeatureType should check to see if the passed in objects validate
against its AttributeTypes, and if it does should return a new Feature.
Redesign Notes (feature-exp2)
The main design goal of this is to have FeatureType extend AttributeType. This allows us to
nesting of features much more nicely. We already are going in this direction, with the
FeatureAttributeType buried in DefaultAttribute. This is just making it explicit, so it works
with the complex objects GML can return a lot more sensible. So much of the work in this class is
figuring out what concepts are the same. Some stuff may need to be rethought a bit, as there are
a few subtle assumptions that we are working with flat files. We will revisit this when we
implement choice and multiplicity.
- got rid of deprecated getNamespace() method that returned a string, replaced it with a URI
return. This has been deprecated for a bit, and was done out of a desire to keep backwards
compatibility with 2.0, but that mission failed, so we're just moving on. This change will break
a few things, but is a good one, people just need to update their client code a bit.
- Deprecated getTypeName() to be getName(). They are the same thing, would be nice to get rid
of getTypeName, but it's used super extensively. Though perhaps we could consider keeping it as a
convenience, a bit more explicit, but it seems like overkill.
- Updated comments of the AttributeType operations that are inhierited to say what they mean
in the context of a FeatureType.
Redesign Notes (factory-hints)
The factory-hints design is finally coming through on the promiss of the great geotools factory
design. This design is actualy placing the factory system under application (rather than
'default') control, as such it is really showing every last place where we did not follow our
architecture.
Use Cases:
- Custom Feature:
Application spedcifies the use of a custom feature implementation. This is used so an application
interface is supported by each and every feature created.
- optiomized coordinate storage
LiteRenderer2 wants Shape2d specific CoordinateSequenceFactory used for all Geometry creation.
The point is to allow only the xy information to be retrieved, and in a format suitable for rapid
reprojection and coversion to a Java2D Shape. Any OpenGL (or Java3D) based renderer would also
run into this need.
The second use case is interesting in that LiteRenderer2 will be using the Datastore at the same
time as other threads that want the normal coordinate sequence. So this is a per Query hint.
Consequence: Since FeatureType is immutable, and CoordianteSequence is specified by the
GeometryFactory of the DefaultGeometryAttribute this implys that we have a per Query SchemaType.
It strikes me that this is a bad separation of concerns the "schema" should be exactly the same,
it is just the GeometryFactory that controls construction that is in the wrong spot. It should be
a hint, not attached to GeomtryAttributeType.
author: Rob Hranac, VFNY author: Chris Holmes, TOPP author: David Zwiers, Refractions author: Jody Garnett, Refractions version: $Id: FeatureType.java 27002 2007-09-17 03:01:53Z jdeolive $ See Also: org.geotools.feature.Feature See Also: org.geotools.feature.FeatureTypeFactory See Also: org.geotools.feature.type.NestedAttributeType See Also: org.geotools.feature.DefaultFeatureType |
Method Summary | |
Feature | create(Object[] attributes) Creates a new feature, with a generated unique featureID. | Feature | create(Object[] attributes, String featureID) Scheduled for removal in Geotools 2.2, please use FeatureFactory.
Creates a new feature, with the indicated featureID.
Parameters: attributes - the array of attribute values. Parameters: featureID - the feature ID. | Feature | duplicate(Feature feature) Create a duplicate of the provided feature, must delegate to an appropriate FeatureFactory
create method. | public boolean | equals(Object arg0) FeatureType check based on namespace, typeName, attributes and ancestors.
Conceptually FeatureType equality is supped to indicate an exact match based AttributeType
and Ancestors. | int | find(AttributeType type) Find the position of a given AttributeType.
Match is based on attribute type name, the resulting index
may be used with getAttributeType( index ).
Parameters: type - The type to search for. | int | find(String attName) Find the position of an AttributeType which matches the given String. | FeatureType[] | getAncestors() Obtain an array of this FeatureType's direct ancestors. | int | getAttributeCount() The number of attribues defined by this schema. | AttributeType | getAttributeType(String xPath) Gets the attributeType at this xPath, if the specified attributeType does
not exist then null is returned.
Question: it is unclear how this interacts with the complete schema defined by this
FeatureType and its ancestors (in which a given xpath may refer to several AttributeTypes as
restrictions are applied.
Perhaps this method should be restricted to a FlatFeatureType? Or should have the option of
returning an array of matching AttributeType in order of inheiritence?
Parameters: xPath - XPath pointer to attribute type. | AttributeType | getAttributeType(int position) Gets the schema attributeType at the specified index. | AttributeType[] | getAttributeTypes() AttributeTypes for this FeatureType, all attributes defined by this FeatureType
and its super types define schema for feature instances. | GeometryAttributeType | getDefaultGeometry() Gets the default geometry AttributeType.
If the FeatureType has more one geometry it is up to the implementor to determine which
geometry is the default. | URI | getNamespace() Gets the global schema namespace.
This is often used to record the schema prefix (not the URI) required when writing out this
Feature using GML. | String | getTypeName() Gets the type name for this schema. | boolean | hasAttributeType(String xPath) This is only used twice in the whole geotools code base, and one of those is for a test, so
we're removing it from the interface. | public int | hashCode() Hascode based on namespace, typeName, attributes and ancestors. | boolean | isAbstract() Is this FeatureType an abstract type?
When true is returned instances of this Feature cannot be created, instead a child
FeatureType must use this FeatureType as its ancestor. | boolean | isDescendedFrom(URI nsURI, String typeName) Test to determine whether this FeatureType is descended from the given FeatureType. | boolean | isDescendedFrom(FeatureType type) A convenience method for calling
FeatureType f1;
FeatureType f2;
f1.isDescendedFrom(f2.getNamespace(), f2.getName());
Question: this method duplicates the information provided by getAncestors().
Parameters: type - The type to compare to. |
create | Feature create(Object[] attributes) throws IllegalAttributeException(Code) | | Creates a new feature, with a generated unique featureID.
Generating a FeatureID is less than ideal, as a FeatureID should be something
special about the "real world object" being modeled as a feature.
As an example: the "Effiel Tower" is a great feature id (there is only one) and we can
use that Feature ID in serveral systems:
- In a tour guide FeatureTypes one which records (NAME, LOCATION, COST); and
- In a historical reference (NAME, LOCATION, HIEGHT, DATE, HISTORY)
Explicitly a FeatureID should be persistant over time, and between systems.
The FeatureIDs "generated" by this method are generally created by a datasource.
This method is more for testing that doesn't need featureID.
Warning: This class does not follow the geotools guidelines of sepearting out
Interface from Factory, in geotools 2.3 there will be a formal FeatureFactory
allowing you to provide application specific FeatureImplementations as an orthogonal
concern to definition of type.
Parameters: attributes - the array of attribute values The created feature throws: IllegalAttributeException - if the FeatureType does not validate the attributes. |
create | Feature create(Object[] attributes, String featureID) throws IllegalAttributeException(Code) | | Scheduled for removal in Geotools 2.2, please use FeatureFactory.
Creates a new feature, with the indicated featureID.
Parameters: attributes - the array of attribute values. Parameters: featureID - the feature ID. the created feature. throws: IllegalAttributeException - if the FeatureType does not validate the attributes. |
duplicate | Feature duplicate(Feature feature) throws IllegalAttributeException(Code) | | Create a duplicate of the provided feature, must delegate to an appropriate FeatureFactory
create method.
The implementation is assumed to make use of AttributeType duplicate as required for a deep
copy.
//@deprecated This method will be removed in 2.2, please use FeatureFactory obtained from FactoryFinder
Parameters: feature - a deep copy of feature throws: IllegalAttributeException - |
equals | public boolean equals(Object arg0)(Code) | | FeatureType check based on namespace, typeName, attributes and ancestors.
Conceptually FeatureType equality is supped to indicate an exact match based AttributeType
and Ancestors. The geotools models includes additional information of namespace
and typename.
As far as the geotools data model is concerned any FeatureType implementation should be able
to be subsituted for another. (An actually application may provided an implementation that
provdes tracking of metadata such as creation history, or support for additional interfaces).
Required implementation:
A sample implementation is provided in FeatureTypes.equals( FeatureType, FeatureType ).
Questions:
Q: You may wonder why namespace and typeName are not enought?
A: Geotools often returns a "limitied" schema in response to a query where only a subset
of the attributes are requested.
Q: Doesn't that still indicate the same schema?
A: Yes it kind of should, a GML application (such as GeoServer) has to actually follow the
application schema and include attributes required by the schema (but not request by the query).
This library is more lax in its treatment, and expects you to uses isDecendedFrom as required.
|
find | int find(AttributeType type)(Code) | | Find the position of a given AttributeType.
Match is based on attribute type name, the resulting index
may be used with getAttributeType( index ).
Parameters: type - The type to search for. -1 if not found, a zero-based index if found. |
find | int find(String attName)(Code) | | Find the position of an AttributeType which matches the given String.
This index may be used with getAttributeType( index ), the search space is the entire schema
defined by this FeatureType and its ancestors.
Parameters: attName - the name to look for -1 if not found, zero-based index otherwise |
getAncestors | FeatureType[] getAncestors()(Code) | | Obtain an array of this FeatureType's direct ancestors.
Implementors should return a non-null array (may be of length 0).
- length 0 - a root FeatureType
- length 1 - singe inhieratance
- length 1+ - multiple inheiratance, order is not significant
GetAncestors() indicates *just* the direct parents of this FeatureType.
It capures the inheirtance relationship from the OGC overview document.
Example Code:
public FeatureType getAncestors()}
return new FeatureType[]{ getSuper(), };
}
An array of ancestors. |
getAttributeCount | int getAttributeCount()(Code) | | The number of attribues defined by this schema.
This method to allows access to the complete schema as defined by this
FeatureType and its ancestors.
Notes:
-
- for FeatureType with no super type this count value is the the
same as getAttributeTypes().length.
number of distinct attributeTypes available, taking ancestors and taking overridesinto account.
|
getAttributeType | AttributeType getAttributeType(String xPath)(Code) | | Gets the attributeType at this xPath, if the specified attributeType does
not exist then null is returned.
Question: it is unclear how this interacts with the complete schema defined by this
FeatureType and its ancestors (in which a given xpath may refer to several AttributeTypes as
restrictions are applied.
Perhaps this method should be restricted to a FlatFeatureType? Or should have the option of
returning an array of matching AttributeType in order of inheiritence?
Parameters: xPath - XPath pointer to attribute type. AttributeType, or null if unavaialble |
getAttributeType | AttributeType getAttributeType(int position)(Code) | | Gets the schema attributeType at the specified index.
The index is specified with respect to the entire Schema (as defined by this FeatureType and
it's ancestors).
The index value should not be used with either:
- FeatureType.getAttributeTypes()[index] - as it defines only attributes contributed by
this FeatureType
- Feature.getAttribute( index ) - as attributes order may or may not be in sequence
Parameters: position - a integer index into the complete schema represented bythis FeatureType and its ancestors the attribute type at the specified position |
getAttributeTypes | AttributeType[] getAttributeTypes()(Code) | | AttributeTypes for this FeatureType, all attributes defined by this FeatureType
and its super types define schema for feature instances.
The provided array of AttributeTypes should be considered as adding to (or overriding) the
the AttribtueTypes defined by this FeatureTypes ancestors.
Note Well: Client code should not consider the index provided by the find( attName ) method
as a valid index into the returned array.
Array of AttributeType describing this schema, array may be length 0, but shouldnot be null |
getDefaultGeometry | GeometryAttributeType getDefaultGeometry()(Code) | | Gets the default geometry AttributeType.
If the FeatureType has more one geometry it is up to the implementor to determine which
geometry is the default. If working with multiple geometries it is best to get the
attributeTypes and iterate through them, checking for instances of GeometryAttribtueType.
This should just be used a convenience method when it is known that the features do not have
multiple geometries.
The attribute type of the default geometry, which will contain the position. |
getNamespace | URI getNamespace()(Code) | | Gets the global schema namespace.
This is often used to record the schema prefix (not the URI) required when writing out this
Feature using GML. The supporting application will need to be able to start the GMLWriter off
with the correct URI information so everything makes sense.
The Registry interface provided by the data module provides an example of how to store
associate FeatureType and namespace information. Please note that you may not have duplicate
typeNames in the same Namespace.
Namespace of schema |
getTypeName | String getTypeName()(Code) | | Gets the type name for this schema.
In GML this must be the element name of the Feature.
The name of this feature type. |
hasAttributeType | boolean hasAttributeType(String xPath)(Code) | | This is only used twice in the whole geotools code base, and one of those is for a test, so
we're removing it from the interface. If getAttributeType does not have the AttributeType it
will just return null. Gets the number of occurrences of this attribute.
Question: the comment says we are removing this, but it is not depricated? And how the heck
can the number of occurances out of a boolean.
Parameters: xPath - XPath pointer to attribute type. Number of occurrences. |
hashCode | public int hashCode()(Code) | | Hascode based on namespace, typeName, attributes and ancestors.
Hascode is always a matched set with an equals implementation, please see the javadocs
for equals for a detailed discussion.
See Also: java.lang.Object.hashCode |
isAbstract | boolean isAbstract()(Code) | | Is this FeatureType an abstract type?
When true is returned instances of this Feature cannot be created, instead a child
FeatureType must use this FeatureType as its ancestor.
true if abstract, false otherwise. |
isDescendedFrom | boolean isDescendedFrom(URI nsURI, String typeName)(Code) | | Test to determine whether this FeatureType is descended from the given FeatureType. Think of
this relationship likes the "extends" relationship in java.
Parameters: nsURI - The namespace URI to use. Parameters: typeName - The typeName. true if descendant, false otherwise. |
isDescendedFrom | boolean isDescendedFrom(FeatureType type)(Code) | | A convenience method for calling
FeatureType f1;
FeatureType f2;
f1.isDescendedFrom(f2.getNamespace(), f2.getName());
Question: this method duplicates the information provided by getAncestors().
Parameters: type - The type to compare to. true if descendant, false otherwise. |
|
|