Overview
Readers that are spatially enabled have a value of "Always" or "Optional"
in the Spatial Index entry of their Quick Facts table. For readers with a
value of Optional, you can use IUniversalReader::getProperties() to
determine whether a spatial index is available for a particular dataset.
Spatially enabled readers are often used to access datasets with millions
of features. For this reason, FME Objects users are discouraged from
creating a reader cache for spatially enabled readers because caching
this much data is not practical. Also, these types of readers usually
have optimized query capabilities that FME should take advantage of.
Developers of all spatially enabled readers must therefore implement the
following three public reader methods:
- spatialEnabled() which must return FME_TRUE.
- getProperties() which identifies which setConstraints() types are
supported by returning an attributed feature.
- setConstraints() which must pass the correct corresponding queries to
the database based on the provided constraint type. Constraints are
specified as attributes on an IFMEFeature object, the constraint feature,
which is passed to setConstraints as an input parameter. The name of the
attribute used to specify the type of constraint to be used is
fme_search_type. The following table describes the different values
supported for fme_search_type:
fme_all_features
Retrieve features based on specific attribute value or feature
type value
fme_envelope_intersects
Retrieve features whose bounding box intersects a rectangular
selection area
fme_envelope_ids
Retrieve the IDs for features whose bounding box intersects a
rectangular selection area
fme_nonspatial_ids
Retrieve the IDs for non-spatial features
fme_feature_type_ids
Retrieve the IDs for all features, by feature type. This can be
used along with the specified-feature constraints to retrieve
only features from certain feature types.
fme_closest
Retrieve the feature that is closest to a selection point, within
a maximum distance threshold
fme_specified_feature
Retrieve a specific feature by index
fme_specified_feature_list
Retrieve a list of specific features by index
fme_specified_feature_range
Retrieve a range of features based on a start and end index
fme_execute_sql
Retrieve result features from executing the provided custom
SQL statement
fme_schema_from_query
Retrieve schema features as described by provided custom
database query
fme_db_join
Retrieve attribute only features for the specified Relate call
defined by attributes on the constraint feature
fme_metadata
Retrieve metadata about specified feature types in a dataset
fme_get_version_list
Retrieve data about all the versions that a user has access to
fme_get_historical_version_list
Retrieve data about all the versions that a user has access to
fme_spatial_interaction
Retrieve features which satisfy a given spatial interaction
There are three special constraint primitives that are supported across
several of these search types:
- The fme_where attribute is used to pass a WHERE clause directly to
the database.
- The fme_feature_type list attribute is used to retrieve only
features with specific feature types. If this is not present, then
database readers should return no features while file readers should
return features from all feature types.
- It has been common for formats (see dll_fme_ado) to support both
lists and plain fme_feature_type attributes when only lists are
officially supported. This is discouraged going forward.
- Some formats require fme_feature_type when they really
shouldn't. For example, dll_fme_ado will not process constraints
unless an fme_feature_type is provided. Any setConstraints client
that operates on arbitrary formats should pass a placeholder
fme_feature_type to ALL setConstraints calls.
- The fme_type list attribute is used to retrieve only features with
specific fme types. If this is not present, all fme types should be
returned. These should be the style of fme type, not fme geometry,
and not the format specific type, like "fme_line", "fme_text",
"fme_point", and "fme_area". Example: fme_type{0} = fme_line,
fme_type{1} = fme_area - Non-list fme_type attributes (such as those
set when query geometry is specified) must be ignored Note: The
syntax of the WHERE clause is specific to the spatially enabled
reader.
Sometimes there is an overlap between what the setConstraints
specification can express and what reader-specific directives and DEF
lines can express. For example, the MSSQL_ADO reader has a WHERE_CLAUSE
directive and the constraint feature has an fme_where attribute. There
are many other examples. If setConstraints() is called, the reader is
essentially reset and the constraint feature takes precedence for all
such settings.
- The constraint feature takes precedence irrespective of whether
setConstraints() is called before or after open(). The order of the
setConstraints() and open() calls does not effect semantics.
- The constraint feature always takes precedence even for attributes
that aren't set. For example, if the reader has a WHERE_CLAUSE
directive and setConstraints() is called, the reader-level
WHERE_CLAUSE is not used even if the constraint feature doesn't have
an fme_where attribute. Also, a constraint feature without
fme_feature_types always returns nothing (for database formats; see
above).
- If setConstraints() is called, it overrides all other settings that
relate to constraints. For example, if there is a feature-type-level
where clause on a DEF line, setConstraints() overrides it. Also, if
there is a feature-type-level custom SQL statement, setConstraints()
overrides it. This means that you can't specify feature type FOO as
"select * from BAR" and then do an envelope query (or any other
constraint) on feature type FOO.
- If setConstraints() is called multiple times, each invocation must
replace or remove the constraints set by previous invocations.
Sometimes it is desirable to use the UniversalReader's implementation of
setConstraints() instead of the native reader's implementation, especially
if a cache file is used.
- If the constraint feature contains an attribute named
fme_disable_native_constraints_support, then setConstraints() will
not be called on the reader. Instead, constraints will only be
applied by the UniversalReader.
- The value of the fme_disable_native_constraints_support attribute
is ignored.
fme_all_features
The fme_all_features search type supports the fme_where, fme_type{} and
fme_feature_type{} primitives. Additionally, filtering the set of
attributes returned can be done using either fme_attribute_list{} when
formats can return columns by name, or fme_start_attribute_index and
fme_end_attribute_index for sequential column formats such as CSV or
Excel. Both attributes expect a numeric, zero indexed value and are
honored inclusively. Similar values can be used to limit the features
returned as well; fme_start_feature_index and fme_end_feature_index. For
example, the following constraint feature:
Intent:
fme_search_type = fme_all_features (required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
fme_where = 'Direction = "North"' (optional)
fme_start_attribute_index = 0 (optional)
fme_end_attribute_index = 4 (optional)
fme_start_feature_index = 11 (optional)
fme_end_feature_index = 20 (optional)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
fmeFeature->setAttribute("fme_search_type", "fme_all_features");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeFeature->setAttribute("fme_where", "Direction = 'North'");
fmeFeature->setAttribute("fme_start_attribute_index", 0);
fmeFeature->setAttribute("fme_end_attribute_index", 4);
fmeFeature->setAttribute("fme_start_feature_index", 11);
fmeFeature->setAttribute("fme_end_feature_index", 20);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_feature_type{1}' has value `Railroad'
Attribute(string): `fme_search_type' has value `fme_all_features'
Attribute(string): `fme_where' has value `Direction = 'North
Attribute(32 bit integer): `fme_start_attribute_index' has value `0'
Attribute(32 bit integer): `fme_end_attribute_index' has value `4'
Attribute(32 bit integer): `fme_start_feature_index' has value `11'
Attribute(32 bit integer): `fme_end_feature_index' has value `20'
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Geometry Type: Unknown (0)
===========================================================================
retrieves the 11th to 20th feature, inclusive, from the Roads and
Railroad feature types, for which the attribute "Direction" has a value
of "North", but only retrieves the first 5 attributes.
If fme_feature_type{} is not present, and the format is NOT a database
format, all feature types are implied. If fme_feature_type{} is not
present and the format is a database format, then no feature types are
returned.
The feature types specified override the IDs originally specified when
opening the reader (i.e. no intersection with the original IDs or
anything like that).
If fme_where is not present, all features from the requested feature
types are selected. fme_where is compatible with fme_start_feature_index,
fme_end_feature_index fme_start_attribute_index and
fme_end_attribute_index. The where clause will be applied first, if
supported, then the filtered results will be limited by the supplied
indexes.
If fme_attribute_list{} is present then the resultant feature will be
only return the provided attributes. This acts as an attribute filter.
This filter is optional and otherwise all attributes will be returned.
This should be used for arbitrary column filtering by name. This is not
compatible with the fme_start_attribute_index and fme_end_attribute_index
filters.
If a format uses ordered, sequential columns such as CSV or Excel,
fme_start_attribute_index and fme_end_attribute_index can be used to
limit the attributes returned. Both values are numeric, zero indexed and
are inclusive. These filters will be applied after the other filters such
as fme_where are applied. This is not compatible with the
fme_attribute_list{} filter. These filters can also be used individually
to limit only the start attribute or end attribute column if desired.
If a fme_start_feature_index and fme_end_feature_index are specified they
can be used to limit the features returned by feature index. Both values
are numeric, zero indexed and are inclusive. These filters will be
applied after the other filters such as fme_where are applied. These
filters can also be used individually to limit only the start feature or
end feature if desired.
fme_all_schemas
The fme_all_schemas search type supports the fme_feature_type{}
primitive. For example, the following constraint feature:
Intent:
fme_search_type = fme_all_schemas(required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
fmeFeature->setAttribute("fme_search_type", "fme_all_schemas");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_feature_type{1}' has value `Railroad'
Attribute(string): `fme_search_type' has value `fme_all_schemas'
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Geometry Type: Unknown (0)
===========================================================================
retrieves the schema features for the Roads and Railroad feature types.
If fme_feature_type{} is not present, and the format is NOT a database
format, all feature types are implied. If fme_feature_type{} is not
present and the format is a database format, then no feature types are
returned.
The feature types specified override the IDs originally specified when
opening the reader (i.e. no intersection with the original IDs or
anything like that).
Schema features returned are the same as if the user had called
readSchema directly but allow for the reuse of the same instance of the
reader.
fme_envelope_intersects
If getProperties() claims support for fme_envelope_intersects, it will be
assumed by FME that the format also has native search envelope support in
terms of the settings box.
The fme_envelope_intersects search type supports the fme_where,
fme_type{} and fme_feature_type{} primitives. If there is an
fme_envelope_order_results attribute on the constraint feature with a
value of "YES", retrieved features must be ordered according to their
distance from the query envelope centroid. Requests for ordered results
are honored only if 200 or fewer features intersect the query envelope.
The fme_envelope_intersects search type also allows for
fme_envelope_width_in_pixels and fme_envelope_height_in_pixels primitives
specified as integer attributes on the constraint feature. These are used
by the Data Inspector to help formats determine resolutions or zoom
levels by contrasting the envelope geometry of the constraint feature to
the pixel size attributes above. These are both optionally specified and
optionally honored. Currently Stamen, MapBox and ArcGIS Online readers
should honor these constraint primitives. The values are in screen pixels
and may be buffered based on the graphics view window in the Data
Inspector.
Readers are expected to take the bounding box of the constraint geometry
(which could be as simple a single point) to create an envelope (which
might have no length on one or more axes).
Readers that support reading from multiple geometry sources (eg columns)
should apply envelopes in an OR fashion: A feature matches an envelope if
any component geometry matches the envelope, and all geometry will be
returned if any component matches the envelope.
For example, the following constraint retrieves the features from the
Roads and Railroad feature types, for which the attribute "Direction" has
a value of "South", and whose linear or polygon geometry intersects with
the envelope area defined by (x=0, y=0), (x=100, y=100).
Intent:
fme_search_type = fme_envelope_intersects (required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
fme_where = "Direction = 'South'" (optional)
fme_type = {"fme_line", "fme_polygon"} (optional)
geometry = {(x=0, y=0), (x=100, y=100)} (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
IFMEStringArray *fmeGeometryTypes = fmeSession->createStringArray();
fmeGeometryTypes->append("fme_line");
fmeGeometryTypes->append("fme_polygon");
fmeFeature->setAttribute("fme_search_type", "fme_envelope_intersects");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeFeature->setAttribute("fme_where", "Direction = 'South'");
fmeFeature->setAttribute("fme_type", *fmeGeometryTypes);
fmeFeature->addCoordinate(0,0);
fmeFeature->addCoordinate(100,100);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeGeometryTypes);
fmeGeometryTypes = NULL;
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_feature_type{1}' has value `Railroad'
Attribute(string): `fme_search_type' has value `fme_envelope_intersects'
Attribute(string): `fme_type{0}' has value `fme_line'
Attribute(string): `fme_type{1}' has value `fme_polygon'
Attribute(string): `fme_where' has value `Direction = 'South
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Attribute: `fme_type{0}' is sequenced
Attribute: `fme_type{1}' is sequenced
Geometry Type: Unknown (0)
Number of Coordinates: 2 -- Coordinate Dimension: 2 -- Coordinate System: `'
(0,0) (100,100)
===========================================================================
fme_envelope_ids
The fme_envelope_ids search type does not return a subset of regular
reader features. Most other search types pare down the results set
returned, offering anything from all features, to envelopes of features,
to features given a specific query or where clause. fme_envelope_ids is
used to provide a non-regular reader feature that has been formatted
specifically to hold a set of matching feature IDs for the dataset or a
specific set of feature types. The envelope ids constraint feature and
returned features are described below.
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader. This step is a post process that uses the IDs of the
features returned from the underlying "fme_envelope_intersects" to
efficiently allow the Universal Reader to return a list of IDs for future
use without building and returning the features themselves. The
fme_envelope_id_list is populated as a space delimited list of ids on the
output feature. Incremental consecutive IDs are compressed using '-' to improve efficiency,
for instance, "1 2 3 4 5 6 7 9" would be represented as "1-7 9". One feature will be returned
for each feature type.
The fme_envelope_ids search type supports the fme_where, fme_type{} and
fme_feature_type{} primitives.
Readers that support reading from multiple geometry sources (eg columns)
should apply envelopes in an OR fashion: A feature matches an envelope if
any component geometry matches the envelope, and all geometry will be
returned if any component matches the envelope.
For example, the following constraint retrieves the features from the
Roads and Railroad feature types, for which the attribute "Direction" has
a value of "South", and whose linear or polygon geometry intersects with
the envelope area defined by (x=0, y=0), (x=100, y=100).
The primary use of this is to improve the performance for the Data
Inspector.
Intent:
fme_search_type = fme_envelope_ids (required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
fme_where = "Direction = 'South'" (optional)
fme_type = {"fme_line", "fme_polygon"} (optional)
geometry = {(x=0, y=0), (x=100, y=100)} (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
IFMEStringArray *fmeGeometryTypes = fmeSession->createStringArray();
fmeGeometryTypes->append("fme_line");
fmeGeometryTypes->append("fme_polygon");
fmeFeature->setAttribute("fme_search_type", "fme_envelope_ids");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeFeature->setAttribute("fme_where", "Direction = 'South'");
fmeFeature->setAttribute("fme_type", *fmeGeometryTypes);
fmeFeature->addCoordinate(0,0);
fmeFeature->addCoordinate(100,100);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeGeometryTypes);
fmeGeometryTypes = NULL;
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_feature_type{1}' has value `Railroad'
Attribute(string): `fme_search_type' has value `fme_envelope_ids'
Attribute(string): `fme_type{0}' has value `fme_line'
Attribute(string): `fme_type{1}' has value `fme_polygon'
Attribute(string): `fme_where' has value `Direction = 'South
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Attribute: `fme_type{0}' is sequenced
Attribute: `fme_type{1}' is sequenced
Geometry Type: Unknown (0)
Number of Coordinates: 2 -- Coordinate Dimension: 2 -- Coordinate System: `'
(0,0) (100,100)
===========================================================================
Envelope IDs feature returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Road'
Attribute(string) : `fme_envelope_id_list' has value `10 9 8 7 6 5'
Attribute(string) : `fme_geometry' has value `fme_undefined'
Attribute(string) : `fme_type' has value `fme_no_geom'
Coordinate System: `LL-WGS84'
Geometry Type: IFMENull
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Railroad'
Attribute(string) : `fme_envelope_id_list' has value `1-6 8 10'
Attribute(string) : `fme_geometry' has value `fme_undefined'
Attribute(string) : `fme_type' has value `fme_no_geom'
Coordinate System: `LL-WGS84'
Geometry Type: IFMENull
===========================================================================
fme_nonspatial_ids
The fme_nonspatial_ids search type does not return a subset of regular
reader features. Most other search types pare down the results set
returned, offering anything from all features, to envelopes of features,
to features given a specific query or where clause. fme_nonspatial_ids is
used to provide a non-regular reader feature that has been formatted
specifically to hold a set of matching feature IDs for the dataset or a
specific set of feature types. The non-spatial ids constraint feature and
returned features are described below.
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader. This step is a post process that uses the IDs of the
features to efficiently allow the Universal Reader to return a list
of IDs for future use without building and returning the features
themselves. The fme_nonspatial_id_list is populated as a space delimited
list of ids on the output feature. One feature will be returned for
each feature type.
For example, the following constraint retrieves the features from the
Roads and Railroad feature types.
The primary use of this is to improve the performance for the Data
Inspector.
Intent:
fme_search_type = fme_nonspatial_ids (required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
fmeFeature->setAttribute("fme_search_type", "fme_nonspatial_ids");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_feature_type{1}' has value `Railroad'
Attribute(string): `fme_search_type' has value `fme_nonspatial_ids'
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Geometry Type: Unknown (0)
===========================================================================
Non-spatial IDs feature returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Road'
Attribute(string): `fme_geometry' has value `fme_undefined'
Attribute(string): `fme_nonspatial_id_list' has value `0 1'
Attribute(string): `fme_type' has value `fme_no_geom'
Coordinate System: `LL-WGS84'
Geometry Type: IFMENull
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Railroad'
Attribute(string): `fme_geometry' has value `fme_undefined'
Attribute(string): `fme_nonspatial_id_list' has value `3 6 9'
Attribute(string): `fme_type' has value `fme_no_geom'
Coordinate System: `LL-WGS84'
Geometry Type: IFMENull
===========================================================================
fme_feature_type_ids
The fme_feature_type_ids search type does not return a subset of regular
reader features. Most other search types pare down the results set
returned, offering anything from all features, to envelopes of features,
to features given a specific query or where clause. fme_feature_type_ids is
used to provide a non-regular reader feature that has been formatted
specifically to hold a set of matching feature IDs for the dataset or a
specific set of feature types.
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader. This step is a post process that uses the IDs of the
features to efficiently allow the Universal Reader to return a list
of IDs for future use without building and returning the features
themselves. The fme_feature_type_ids is populated as a space delimited
list of ids on the output feature. One feature will be returned for
each feature type.
For example, the following constraint retrieves the features from the
Roads and Railroad feature types.
The primary use of this is to improve the performance for the Data
Inspector.
Intent:
fme_search_type = fme_feature_type_ids (required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
fmeFeature->setAttribute("fme_search_type", "fme_feature_type_ids");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_feature_type{1}' has value `Railroad'
Attribute(string): `fme_search_type' has value `fme_feature_type_ids'
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Geometry Type: Unknown (0)
===========================================================================
Feature Type IDs feature returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Road'
Attribute(string): `fme_geometry' has value `fme_undefined'
Attribute(string): `fme_feature_type_id_list' has value `0 1'
Attribute(string): `fme_type' has value `fme_no_geom'
Coordinate System: `LL-WGS84'
Geometry Type: IFMENull
===========================================================================
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Railroad'
Attribute(string): `fme_geometry' has value `fme_undefined'
Attribute(string): `fme_feature_type_id_list' has value `3 6 9'
Attribute(string): `fme_type' has value `fme_no_geom'
Coordinate System: `LL-WGS84'
Geometry Type: IFMENull
===========================================================================
fme_closest
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader.
The fme_closest search type supports the fme_where, fme_type{} and
fme_feature_type{} primitive constraints. If the constraint feature
geometry has only one coordinate, that coordinate is used as the query
point; otherwise the centroid of the constraint feature's bounding box is
used as the query point. When a maximum distance threshold is specified
using the fme_max_distance attribute, only the closest feature will only
be retrieved if the distance between it and the query point is less than
fme_max_distance; otherwise no feature is retrieved.
For example, the following constraint retrieves the feature from the
Roads and Railroad feature types that is the closest point to the point
(x=10, y=10), only if its "Direction" attribute has a value of "North",
and it is within 100.0 ground coordinates; otherwise no feature is
retrieved.
Intent:
fme_search_type = fme_closest (required)
fme_feature_type = {"Road","Railroad"} (recommended 1..M)
fme_where = "Direction = 'North'" (optional)
fme_type = {"fme_point"} (optional)
fme_max_distance = 100.0; (recommended)
geometry = {(x=10, y=10)} (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeatureTypes->append("Railroad");
IFMEStringArray *fmeGeometryTypes = fmeSession->createStringArray();
fmeGeometryTypes->append("fme_point");
FME_Real64 maxDistance = 100.0;
fmeFeature->setAttribute("fme_search_type", "fme_closest");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeFeature->setAttribute("fme_where", "Direction = 'North'");
fmeFeature->setAttribute("fme_type", *fmeGeometryTypes);
fmeFeature->setAttribute("fme_max_distance", maxDistance);
fmeFeature->addCoordinate(10,10);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeGeometryTypes);
fmeGeometryTypes = NULL;
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string) : `fme_feature_type{0}' has value `Road'
Attribute(string) : `fme_feature_type{1}' has value `Railroad'
Attribute(64 bit real): `fme_max_distance' has value `100.0'
Attribute(string) : `fme_search_type' has value `fme_closest'
Attribute(string) : `fme_type{0}' has value `fme_point'
Attribute(string) : `fme_where' has value `Direction = 'North
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_feature_type{1}' is sequenced
Attribute: `fme_type{0}' is sequenced
Geometry Type: Unknown (0)
Number of Coordinates: 1 -- Coordinate Dimension: 1 -- Coordinate System: `'
(10,10)
===========================================================================
fme_specified_feature
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader.
For example the following constraint retrieves the 10th feature of the
dataset:
Intent:
fme_search_type = fme_specified_feature (required)
fme_index = 10 (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
FME_Int32 index = 10;
fmeFeature->setAttribute("fme_search_type", "fme_specified_feature");
fmeFeature->setAttribute("fme_index", index);
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string) : `fme_feature_type' has value `Road'
Attribute(32 bit integer): `fme_index' has value `10'
Attribute(string) : `fme_search_type' has value `fme_specified_feature'
Geometry Type: Unknown (0)
===========================================================================
fme_specified_feature_list
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader.
For example the following constraint retrieves a list of features from
the dataset:
Intent:
fme_search_type = fme_specified_feature_list (required)
fme_index_list = "2 34 78 21 95" (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
FMEObsoleteStringImp indexList = "2 34 78 21 95";
fmeFeature->setAttribute("fme_search_type", "fme_specified_feature_list");
fmeFeature->setAttribute("fme_index_list", indexList);
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string) : `fme_feature_type' has value `Road'
Attribute(string) : `fme_index_list' has value `2 34 78 21 95'
Attribute(string) : `fme_search_type' has value `fme_specified_feature_list'
Geometry Type: Unknown (0)
===========================================================================
fme_specified_feature_range
Implemented entirely by the Universal Reader, and will never be passed to
an IFMEReader.
For example the following constraint retrieves features 10-20 from the
dataset:
Intent:
fme_search_type = fme_specified_feature_range (required)
fme_start_index = 10 (required)
fme_end_index = 20 (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
FME_Int32 startIndex = 10;
FME_Int32 endIndex = 20;
fmeFeature->setAttribute("fme_search_type", "fme_specified_feature_range");
fmeFeature->setAttribute("fme_start_index", startIndex);
fmeFeature->setAttribute("fme_end_index", endIndex);
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string) : `fme_feature_type' has value `Road'
Attribute(32 bit integer): `fme_start_index' has value `10'
Attribute(32 bit integer): `fme_end_index' has value `20'
Attribute(string) : `fme_search_type' has value `fme_specified_feature_range'
Geometry Type: Unknown (0)
===========================================================================
fme_execute_sql
fme_execute_sql is the setConstraints fme_search_type used to support
arbitrary SQL statement execution such as those passed by the SqlExecutor
and SqlCreator transformers in FME. Since there is no specific list of
tables to be queried, but rather the SQL statement itself, this search
type does not support fme_feature_type in the same way that other search
types do. The SQL query is free form SQL, and specific function
implementation depends on the underlying reader and format. The special
attribute used on fme_execute_sql type constraint features to specify the
SQL statement is called fme_sql_statement.
For example, the following constraint feature:
Intent:
fme_feature_type = placeholder_value (optional for well behaved formats)
fme_search_type = fme_execute_sql (required)
fme_sql_statement = select * from mytable where id < 10 (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setAttribute("fme_feature_type", "placeholder_value");
fmeFeature->setAttribute("fme_search_type", "fme_execute_sql");
fmeFeature->setAttribute("fme_sql_statement", "select * from mytable where id < 10");
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `'
Attribute(string): `fme_feature_type' has value `placeholder_value'
Attribute(string): `fme_search_type' has value `fme_execute_sql'
Attribute(string): `fme_sql_statement' has value `select * from mytable where id < 10'
Geometry Type: Unknown (0)
===========================================================================
The constraint feature instructs the reader to return one feature per row
in the result set (database) or record (file). SQL commands can also be
run but do not return a result set. In this case a call to reader.read()
is still required to execute the SQL statement but the feature returned
(if any) can be discarded.
Transaction Control
fme_execute_sql statements should not be committed until either the
setConstraints client sends a COMMIT statement (not be interpreted by
the reader, but passed on to the database), a non- fme_execute_sql
setConstraints is requested, or the reader is closed. For example:
1. fme_execute_sql1 INSERT ...
2. fme_all_features <commit for changing modes>
3. fme_execute_sql2 INSERT ...
4. fme_execute_sql3 COMMIT <client requested commit>
5. fme_execute_sql4 INSERT ...
6. <commit on reader close>
We should be autocommitting in all non-fme_execute_sql modes, to avoid
holding locks on tables. The importance of this depends greatly on the
locking behavior of the underlying database (it's a big deal if no one
can write if read locks are present).
fme_schema_from_query
fme_schema_from_query is the setConstraints fme_search_type used to support
getting result schema from arbitrary database queries, for example those
passed by the SqlExecutor and SqlCreator transformers in FME. This will not
execute the query, but rather describe the schema of the query's result set.
Since there is no specific list of tables to be queried, but rather the
query statement itself, this search type does not support fme_feature_type
in the same way that other search types do. The query is free form, and
specific function implementation depends on the underlying reader and
format. To specify the query, a special attribute called fme_sql_statement
is used on fme_schema_from_query type constraint features.
For example, the following constraint feature:
Intent:
fme_feature_type = placeholder_value (optional for well behaved formats)
fme_search_type = fme_schema_from_query (required)
fme_sql_statement = select first_name, last_name, id from mytable where id < 10 (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setAttribute("fme_feature_type", "placeholder_value");
fmeFeature->setAttribute("fme_search_type", "fme_schema_from_query");
fmeFeature->setAttribute("fme_sql_statement", "select first_name, last_name, id from mytable where id < 10");
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `'
Attribute(string): `fme_feature_type' has value `placeholder_value'
Attribute(string): `fme_search_type' has value `fme_schema_from_query'
Attribute(string): `fme_sql_statement' has value `select first_name, last_name, id from mytable where id < 10'
Geometry Type: Unknown (0)
===========================================================================
Schema Feature Returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `placeholder_value'
Attribute(string): `first_name' has value `varchar2(50)'
Attribute(string): `last_name' has value `varchar2(50)'
Attribute(string): `id' has value `integer'
Attribute: `first_name' is sequenced
Attribute: `last_name' is sequenced
Attribute: `id' is sequenced
Geometry Type: Unknown (0)
===========================================================================
The constraint feature instructs the reader to return one schema feature
describing the result set (database) or record (file). The returned schema
feature's attribute names correspond to column names as described by the
result set, and the attribute values describe the corresponding column's
data type. The attributes are sequenced in the same order as columns
described by the result set.
Some SQL commands (eg. DDL) do not return a result set, and so do not have a schema. In
this case a call to reader.read() will return a feature with no schema
information.
fme_db_join
The fme_db_join is the setConstraints fme_search_type used to support the
Joiner transformer. This search type supports fme_feature_type{}
primitive but only uses the first entry. The transfer columns, key
columns, and key values parameters are passed on the constraint feature
using string arrays named fme_select_columns{}, fme_key_columns{} and
fme_key_values{} respectively.
Even though it only makes sense to supply one feature type name in the
fme_feature_type{} for this constraint type it is still exposed as a list
attribute for consistency. If more than one feature type is specified
then only the first is used.
It is possible that a table column's values contains trailing spaces,
which would likely cause the join to fail if the key does not contain the
same trailing spaces. Supplying fme_trim_keys with a value of yes tells
supported readers to perform trimming of the column values so that the
values will match the corresponding rows of the table.
For example, the following constraint:
Intent:
fme_search_type = fme_db_join (required)
fme_feature_type = {"Road"} (required)
fme_select_columns = "id" "name" "numlanes" (required)
fme_key_columns = "id" "name" (required)
fme_key_values = "23" "straight" (required)
fme_trim_keys = "yes" (optional)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
IFMEStringArray *fmeSelectColumns = fmeSession->createStringArray();
fmeSelectColumns->append("id");
fmeSelectColumns->append("name");
fmeSelectColumns->append("numlanes");
IFMEStringArray *fmeKeyColumns = fmeSession->createStringArray();
fmeKeyColumns->append("id");
fmeKeyColumns->append("name");
IFMEStringArray *fmeKeyValues = fmeSession->createStringArray();
fmeKeyValues->append("23");
fmeKeyValues->append("straight");
fmeFeature->setAttribute("fme_search_type", "fme_db_join");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeFeature->setListAttribute("fme_select_columns", *fmeSelectColumns);
fmeFeature->setListAttribute("fme_key_columns", *fmeKeyColumns);
fmeFeature->setListAttribute("fme_key_values", *fmeKeyValues);
fmeFeature->setAttribute("fme_trim_keys", "yes");
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeKeyValues);
fmeKeyValues = NULL;
fmeSession->destroyStringArray(fmeKeyColumns);
fmeKeyColumns = NULL;
fmeSession->destroyStringArray(fmeSelectColumns);
fmeSelectColumns = NULL;
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_key_columns{0}' has value `id'
Attribute(string): `fme_key_columns{1}' has value `name'
Attribute(string): `fme_key_values{0}' has value `23'
Attribute(string): `fme_key_values{1}' has value `straight'
Attribute(string): `fme_search_type' has value `fme_db_join'
Attribute(string): `fme_select_columns{0}' has value `id'
Attribute(string): `fme_select_columns{1}' has value `name'
Attribute(string): `fme_select_columns{2}' has value `numlanes'
Attribute(string): `fme_trim_keys' has value `yes'
Attribute: `fme_feature_type{0}' is sequenced
Attribute: `fme_key_columns{0}' is sequenced
Attribute: `fme_key_columns{1}' is sequenced
Attribute: `fme_key_values{0}' is sequenced
Attribute: `fme_key_values{1}' is sequenced
Attribute: `fme_select_columns{0}' is sequenced
Attribute: `fme_select_columns{1}' is sequenced
Attribute: `fme_select_columns{2}' is sequenced
Geometry Type: Unknown (0)
===========================================================================
The constraint feature above results in the attributes id, name and
numlanes being placed on the feature where the id = 23 the name =
"straight". One feature is returned per matching row in the database. Any
trailing spaces on the "name" column values of the database table are not
considered significant when comparing with the given value ("straight").
fme_metadata
The fme_metadata search type does not return a subset of regular reader
features. Most other search types pare down the results set returned,
offering anything from all features, to envelopes of features, to
features given a specific query or where clause. fme_metadata is used to
provide a non-regular reader feature that has been formatted specifically
to hold well-defined metadata attributes about a given feature type. The
metadata constraint feature and returned metadata feature are described
below.
The fme_metadata search type supports fme_feature_type{} primitive and
will return one metadata feature per feature type specified. If the
fme_feature_type{} primitive is not specified, then one metadata feature
will be returned per feature type on the dataset.
If the only attributes specified on the query feature are fme_search_type
and fme_feature_type{} (or just fme_search_type), then all the metadata
attributes are returned. Otherwise, only the specific information
requested is returned on the metadata feature. To request that a metadata
feature contain a certain attribute, set the attribute on the query
feature. It doesn't matter what value is given to the attribute, or even
if a value is given at all. For example, the following constraint:
Intent:
fme_search_type = fme_metadata (required)
fme_feature_type = {"Road"} (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeature->setAttribute("fme_search_type", "fme_metadata");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_feature_type{0}' has value `Road'
Attribute(string): `fme_search_type' has value `fme_metadata'
Attribute: `fme_feature_type{0}' is sequenced
Geometry Type: Unknown (0)
===========================================================================
Metadata feature returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `Road'
Attribute(string) : `fme_contains_spatial_column' has value `yes'
Attribute(string) : `fme_coordinate_system{0}' has value `LL-83'
Attribute(string) : `fme_dimension' has value `2'
Attribute(string) : `fme_feature_identifier' has value `oid'
Attribute(string) : `fme_cache_file_name' has value `c:\temp\temp.ffs'
Attribute(string) : `fme_geometry' has value `fme_polygon'
Attribute(string) : `fme_geometry{0}' has value `fme_point'
Attribute(string) : `fme_geometry{1}' has value `fme_line'
Attribute(64 bit unsigned integer): `fme_geometry_class' has value `32'
Attribute(64 bit real) : `fme_max_x' has value `100.0'
Attribute(64 bit real) : `fme_max_y' has value `100.0'
Attribute(64 bit real) : `fme_min_x' has value `0.0'
Attribute(64 bit real) : `fme_min_y' has value `0.0'
Attribute(32 bit unsigned integer): `fme_num_entries' has value `324'
Attribute(string) : `fme_type' has value `fme_area'
Geometry Type: Polygon (4)
Number of Coordinates: 5 -- Coordinate Dimension: 2 -- Coordinate System: `LL-83'
(0.0,0.0) (0.0,100.0) (100.0,100.0) (100.0,0.0) (0.0,0.0)
===========================================================================
However, if all that one wanted returned on a metadata feature were the
extents, coordinate system, and the number of features for that feature
type, then the code would look like:
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("Road");
fmeFeature->setAttribute("fme_search_type", "fme_metadata");
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes);
fmeFeature->setAttribute("fme_extents");
fmeFeature->setAttribute("fme_coordinate_system");
fmeFeature->setAttribute("fme_num_entries");
fmeReader->setConstraints(*fmeFeature);
fmeSession->destroyStringArray(fmeFeatureTypes);
fmeFeatureTypes = NULL;
- The feature type of the returned metadata feature specifies the
feature type for which the metadata applies.
- fme_contains_spatial_column indicates whether the feature type
contains a geometry column. For example in a database it may be a BLOB
or Long Binary column. If one wants only a subset of metadata
attributes returned and this attribute is part of that subset, then
fme_contains_spatial_column should be on the query feature.
- fme_dimension is the dimension of the feature type - either 2 or 3.
If the format does not restrict the dimension of the feature in a
feature type, this should be set to 3D. If the feature type is simply
tabular data, then this attribute should not be set on the feature. If
one wants only a subset of metadata attributes returned and this
attribute is part of that subset, then fme_dimension should be on the
query feature.
- fme_geometry is the string array list of possible geometries in the
feature type. They may not all exist. For some formats this is only
one entry. The elements in this list should be fme_types, not the
format specific geometry and not fme_geometry values - yes, the name
is misleading. The possible fme_types are as follows: "fme_point"
(kFME_point constant), "fme_arc" (kFME_arc constant), "fme_ellipse"
(kFME_ellipse constant), "fme_text" (kFME_text constant), "fme_line"
(kFME_line constant), "fme_area" (kFME_area constant), "fme_raster"
(kFME_raster constant), "fme_collection" (kFME_collection constant),
"fme_surface" (kFME_surface constant), "fme_solid" (kFME_solid
constant), and "fme_no_geom" (kFME_no_geom constant). The constants
are found in FME_HOME/fmeobjects/cpp/fmereaderconstants.h. If one
wants only a subset of metadata attributes returned and this attribute
is part of that subset, then fme_geometry should be on the query
feature (it doesn't matter if it's a list attribute or a regular
attribute).
Note that readSchema() expects fme_geometry to be populated with format_
types, not fme_ types. Unclear how this confusing discrepancy came about,
although the setConstraints() choice seems stronger.
- fme_num_entries is the number of features in the feature type. If
one wants only a subset of metadata attributes returned and this
attribute is part of that subset, then fme_num_entries should be on
the query feature. Even if this is an expensive call, this should be
implemented. If one do not want this attribute returned, then one
should be specific in which attributes one wants returned.
- fme_feature_identifier is a column which may act as a unique index for
the feature type. The column must:
* Contain unique 32 bit (or less) unsigned integers
* Most formats will return signed columns with the assumption
that they will not contain numbers below zero. PR#19555
* Not contain nulls
* Most formats implement this by returning a column with a
non-nullable constraint.
* PostgreSQL based formats scan the column to ensure no nulls
exist. This is arguably better because it increases the number
of candidate columns, or worse because the data could change
underneath, invalidating the choice.
* Be reference-able without quoting
* "WHERE myidcol = x" must be valid.
* PR#58632: Many formats are not following this rule,
resulting in a poor column being chosen and no
data being returned for each feature in ArcCatalog
Tabular Preview.
* PR#58633: If DataInterop moves to preferring fme_db_join
queries over fme_all_features + fme_where, we
will be able to work around this limitation on a
format by format basis (by implementing
fme_db_join).
* Support fast queries
* Most formats will return an indexed column. This is not
necessary for formats that support massively parallel row
scans.
This attribute should not be set if such a column does not exist. If
one wants only a subset of metadata attributes returned and this
attribute is part of that subset, then fme_feature_identifier should be
on the query feature. This is unrelated to the fme_specified_feature
search type; callers typically use the returned value with generated
fme_where clauses.
- fme_coordinate_system is the coordinate system string containing the
FME coordinate system name of the current feature type. User defined
coordinate system values will be returned if FME does not have a
predefined coordinate system. E.g. sometimes we get the name as
'_fme_01' for the coordinate system from the coordinate system
manager. If the feature type does not have a coordinate system
associated with it, then the coordinate system should not be set. The
fme_coordinate_system value may be returned as a string or a string
array list of FME coordinate system name(s). If one wants only a
subset of metadata attributes returned and the coordinate system is
part of that subset, then the attribute fme_coordinate_system should
be on the query feature.
- fme_geometry_class is a single bit mask representing the geometries
of the current feature type. The representation of each geometry
is defined in the FME_GeometryTypeMask enum found in
FME_HOME/fmeobjects/cpp/fmereaderconstants.h. If one wants only a
subset of metadata attributes returned and this attribute is part
of that subset, then fme_geometry_class should be on the query feature
(it doesn't matter if it's a list attribute or a regular attribute).
- The extents of the feature type are specified as five points, and
are returned on the feature as min and max attributes and as the
feature's geometry, expressed as a polygon (see the example feature
above). Note that in some readers the bounds (which is the smallest
polygon that can completely encompass all the features) rather than
the extents are returned. If the feature type is 2D then no z values
should be set.
Point 1: minx, miny, minz
Point 2: minx, maxy, minz
Point 3: maxx, maxy, maxz
Point 4: maxx, miny, maxz
Point 5: minx, miny, minz
- Degenerate bounding box cases are handled exactly the same, i.e the
bounding box is a point or a line (minx = maxx).
- The extents and the min/max attributes should not be set when:
1. the reader returns the bounds rather than the extents, and:
1. the feature type doesn't contain any features but allows
storage of spatial features
2. the feature type allows spatial features and contains
features, but none of the features have geometry
- for example, one has a database table that contains a
spatial column and contains records in the table; however,
all the records have set the spatial column to NULL
2. the feature type doesn't allow storage of spatial features.
- fme_cache_file_name is the cached FFS file name used by the reader,
if cached in FME Objects, which stores the cached version of the
features for this feature type. Note that a single FFS file may
contain multiple feature types. This attribute should not be set if
there is no cache, which may occur if the reader is spatially enabled
or supports the metadata constraint and all requested subconstraints.
If one wants only a subset of metadata attributes returned and this
attribute is part of that subset, then fme_cache_file_name should be
on the query feature. Currently implemented by the Universal Reader
only and does not make sense for other native readers and should not
be set by an IFMEReader.
- If one wants only a subset of metadata attributes returned and the
extents are part of that subset, then fme_extents should be on the
query feature. Specifying fme_extents on the query feature will result
in the returned metadata feature containing the extents as the
feature's geometry, in addition to the extents being set using the min
and max attributes.
- If one wants only a subset of metadata attributes returned and some
set of min/max x,y,z are part of that subset, then the appropriate
min/max attributes should be on the query feature. Specifying min/max
attributes on the query feature will mean only the requested min/max
attributes will be returned on the metadata feature; the metadata
feature will not have any geometry on it as it would if the attribute
fme_extents was present on the query feature.
fme_get_version_list
The fme_get_version_list is used to received a list of all possible
versions that the current user can access. Additional information may be
provided about the version including when it was created, a description
of the version, and the name of its parent version. This search type is
only applicable to databases supporting versioning (e.g. ArcSDE). The
constraint feature and returned version info feature are described below.
Unlike other search types, the fme_get_version_list search type does not
support any primitives. Each feature returned will represent a single
version.
The following would be an example of a constraint feature:
Intent:
fme_search_type = fme_get_version_list (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
fmeFeature->setAttribute("fme_search_type", "fme_get_version_list");
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_search_type' has value `fme_metadata'
Geometry Type: Unknown (0)
=====================================================================
Metadata feature returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `VersionInfo'
Attribute(string): `fme_type' has value `fme_no_geom'
Attribute(string): `fme_version_access' has value `public'
Attribute(string): `fme_version_creation_time' has value `20041019091455'
Attribute(string): `fme_version_description' has value `child of SDE.DEFAULT'
Attribute(string): `fme_version_name' has value `DEV.left-branch'
Attribute(string): `fme_version_parent_name' has value `SDE.DEFAULT'
Geometry Type: Unknown (0)
===========================================================================
The feature type of the returned version feature is always VersionInfo.
fme_get_historical_version_list
The fme_get_historical_version_list is used to retrieve a list of all
possible historical markers (versions) that the current user can access.
Additional information may be provided about the version including its
name and the timestamp it was created with. This search type is only
applicable to databases supporting historical versioning (e.g. ArcSDE
Geodatabase). The constraint feature and returned version info feature
are described below.
Unlike other search types, the fme_get_historical_version_list search
type does not support any primitives. Each feature returned will
represent a single version.
The following would be an example of a constraint feature:
Intent:
fme_search_type = fme_get_historical_version_list (required)
Code:
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
fmeFeature->setAttribute("fme_search_type", "fme_get_historical_version_list");
fmeReader->setConstraints(*fmeFeature);
Constraint Feature:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `MY_CONSTRAINT_FEATURE'
Attribute(string): `fme_search_type' has value `fme_get_historical_version_list'
Geometry Type: Unknown (0)
===========================================================================
Metadata feature returned:
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Feature Type: `VersionInfo'
Attribute(string): `fme_type' has value `fme_no_geom'
Attribute(string): `fme_version_name' has value `New Marker'
Attribute(string): `fme_historical_version_timestamp' has value `1/1/2006 12:00:01 AM'
Geometry Type: Unknown (0)
===========================================================================
The feature type of the returned version feature is always VersionInfo.
fme_spatial_interaction (DRAFT - This is search type is still being
developed)
The fme_spatial_interaction search type supports the fme_interaction,
fme_where, fme_type{} and fme_feature_type{} primitives.
With this search type, the geometry of the constraint feature is used as
the search feature.
The search feature is used along with the specified spatial interaction
to query the database. All features which satisfy the are spatial
interaction are returned.
Given the argument "fme_interaction", getProperties() must return a list
of spatial interactions supported by the format. This list can include
OGC defined interactions, format specific spatial interactions, DE-9IM
strings, or "DE9IM:ALL" to indicate that the format supports arbitrary
DE-9IM strings. In order to differentiate between format specific
interactions and OGC defined interactions, any format specific
interactions must be prefixed with a format identifier (e.g. the short
format name) and a colon.
- Unless clearly indicated by the name, interactions are expected to
be applied "query geom <interaction> table geom", e.g. query geom
CONTAINS table geom
Readers that support reading from multiple geometry sources (eg columns)
should apply spatial interactions in an OR fashion: A feature satisfies
an interaction if any component geometry satisfies the interaction, and
all geometry will be returned if any component satisfies the interaction.
Code:
FME_Boolean getProperties(const char* propertyCategory , IFMEStringArray &values)
{
FME_Boolean allProps = FME_FALSE;
ObsoleteString category = propertyCategory;
if(category == kFME_ReaderPropAll) //"*"
{
allProps = FME_TRUE;
}
values.clear();
if(category == "fme_spatial_interaction" || allProps )
{
values.append( "fme_spatial_interaction" );
values.append( "fme_interaction" ); //Allow spatial interaction queries.
}
else if(category == "fme_interaction" || allProps )
{
values.append("fme_interaction");
values.append("CONTAINS"); //Allow OGC named predicates.
values.append("fme_interaction");
values.append("ORACLE:CONTAINS"); //Allow format specific named predicates.
values.append("fme_interaction");
values.append("TT*F*F**T"); //Allow specific DE-9IM strings.
values.append("fme_interaction");
values.append("DE9IM:ALL"); //Allow arbitrary DE-9IM strings.
}
if(values.entries() > 0)
{
return FME_TRUE;
}
return FME_FALSE;
}
Possible fme_interaction Values
OGC defined interactions
EQUALS, DISJOINT, TOUCHES, CROSSES, WITHIN, OVERLAPS, CONTAINS, INTERSECTS
These eight spatial relationships are defined in
OGC 06-103r3 and do not require any prefix.
The spatial interactions are the same as the predicates
used in the SpatialFilterFactory and
SpatialRelationshipFactory.
Only formats that are OGC compliant should use these
predicates, otherwise they should use the format specific
relationship.
Format specific interactions
ORACLE:COVEREDBY, MYSQL:INTERSECTS
Formats that support interactions outside of those define
by the OGC, or formats that are not OGC compliant should
indicate this with a prefix consisting of an identifier and
a colon.
DE-9IM strings
T*FFF*TTT
DE-9IM strings must be of the form (T|F|0|1|2|\*){9}.
Code:
IFMEStringArray *fmeFeatureTypes = fmeSession->createStringArray();
fmeFeatureTypes->append("fun_shapes");
fmeFeatureTypes->append("boring_shapes");
IFMEStringArray *fmeTypes = fmeSession->createStringArray();
fmeTypes->append("fme_line");
fmeTypes->append("fme_polygon");
IFMEStringArray *spatialInteractions = fmeSession->createStringArray();
spatialInteractions ->append("ORACLE:ANYINTERACT");
spatialInteractions ->append("ORACLE:COVERS");
fmeFeature->resetFeature();
fmeFeature->setFeatureType("MY_CONSTRAINT_FEATURE");
fmeFeature->setAttribute("fme_search_type", "fme_spatial_interaction"); //Required constraint type.
fmeFeature->setListAttribute("fme_interaction", *spatialInteractions); //Required interactions list.
fmeFeature->setAttribute("fme_where", "Colour = 'Blue'"); //Optional WHERE clause
fmeFeature->setListAttribute("fme_feature_type", *fmeFeatureTypes); //Recommended feature types list.
fmeFeautre->setListAttribute("fme_type", *fmeTypes); //Optional FME types list.
fmeReader->setConstraints(*fmeFeature);
Notable setConstraints Clients (DRAFT)
Authors of readers should use this as a guide to determine which
constraints are most interesting to implement. Constraints that are
implemented by UniversalReader are not listed here.
Reader Settings Box Envelope
Passes envelope parameters to reader only when getProperties advertises
support for fme_envelope_intersects.
Transformers
FeatureReader
Will use the most appropriate search type given the filtering that
was requested. Filtering not natively supported will be emulated in
the most efficient way possible (note that fme_where cannot be
emulated).
fme_envelope_intersects
fme_feature_type
fme_where
fme_all_features
fme_feature_type
fme_where
fme_spatial_interaction (pending PR#67524)
fme_feature_type
fme_interaction
fme_where
Joiner
fme_db_join
SqlCreator/Executor
fme_execute_sql
fme_schema_from_query
ArcGIS Data Interoperability
note: Data Interoperability Extension (and FME Extension) for ArcGIS
Desktop are not being actively updated. Also, the new ArcGIS Pro does not
use setConstraints. As such, new formats won't need to satisfy these
setConstraints calls.
fme_metadata
fme_feature_type
fme_feature_identifier
fme_geometry
fme_all_features
fme_feature_type
fme_where (PR#58633 proposes preferring fme_db_join)
fme_envelope_intersects
fme_feature_type
FME Data Inspector (see internal "FME Data Inspector - Development Notes")
fme_metadata
fme_feature_type
fme_extents
fme_all_features
fme_feature_type
fme_envelope_intersects
fme_feature_type
fme_envelope_width_in_pixels
fme_envelope_height_in_pixels