LuciadCPillar 2026.1.01
Loading...
Searching...
No Matches
luciad::Feature Class Referencefinal

A Feature is a (partial) copy of a domain object. More...

#include <luciad/models/features/Feature.h>

Classes

class  Builder
 Allows the incremental creation of a Feature object. More...

Public Member Functions

Builder asBuilder () const
 Returns this Feature as a Feature::Builder.
std::shared_ptr< Geometry > findGeometry () const
 Tries to find a geometry for this feature.
const DataType & getDataType () const
 Returns the data type describing the feature properties.
FeatureId getId () const
 Returns the id of this feature.
std::optional< size_t > getListSize (const DataPropertyPath &propertyPath) const
 Returns the element count of a list-typed property.
std::optional< size_t > getListSize (const std::string &propertyName) const
 Convenience overload of getListSize that resolves the property by name on this feature's data type.
template<typename T>
std::optional< T > getValue (const DataPropertyPath &propertyPath) const
 Accesses the value for the given property.
template<typename T>
std::optional< T > getValue (const std::string &propertyName) const
 Convenience overload of getValue that resolves the property by name on this feature's data type.
bool hasId () const
 Returns if this Feature has an id.
bool operator!= (const Feature &other) const
bool operator== (const Feature &other) const

Static Public Member Functions

static Builder newBuilder ()
 Returns a new Feature Builder.

Detailed Description

A Feature is a (partial) copy of a domain object.

It allows the rest of the API to easily access the domain object's properties, including any geometry. If you do a query on the model, and retrieve a Feature from it, the caller of the query receives ownership of the Feature. I.e. the caller can decide what to do with it, and when to dispose it.

This means that the Map and Layer APIs are allowed to keep references to a Feature and have unrestricted lock-less access to its properties. The caller of the IFeatureModel::query method is responsible for managing the lifetime of a Feature.

To make Feature instances easy to use in a multi-threaded environment, they are

  • immutable
  • thread safe for reading

See article for more details on this class.

Member Function Documentation

◆ asBuilder()

Builder luciad::Feature::asBuilder ( ) const

Returns this Feature as a Feature::Builder.

This makes it possible to copy a Feature, and modify values. Note that when using this builder, it is not possible to change the datatype. Only the values and the id of the Feature. Otherwise a LogicException will be thrown.

Returns
this Feature as a Feature::Builder.
Since
2020.1

◆ findGeometry()

std::shared_ptr< Geometry > luciad::Feature::findGeometry ( ) const

Tries to find a geometry for this feature.

If this feature's data type is annotated with GeometryDataAnnotation, the value of the corresponding property is returned. Otherwise, the result will be nullptr.

Returns
the annotated geometry, if any, else nullptr.
See also
GeometryDataAnnotation::getPropertyPath

◆ getDataType()

const DataType & luciad::Feature::getDataType ( ) const

Returns the data type describing the feature properties.

Returns
the data type describing the feature properties.

◆ getId()

FeatureId luciad::Feature::getId ( ) const

Returns the id of this feature.

A feature id should be unique across a model.

When no id is set, this method will throw an exception.

Returns
the id of this feature.
Exceptions
LogicExceptionwhen the feature has no id.

◆ getListSize() [1/2]

std::optional< size_t > luciad::Feature::getListSize ( const DataPropertyPath & propertyPath) const

Returns the element count of a list-typed property.

Example

std::optional<size_t> size = feature.getListSize(timePath); // 3
std::optional<int64_t> first = feature.getValue<int64_t>(firstTimePath); // 150
Parameters
propertyPaththe path to the list-typed property (DataCollectionKind::List).
Returns
no value if the list is unset for this feature, or the element count otherwise (0 for an empty list).
Exceptions
InvalidArgumentExceptionif the path's origin type does not match this Feature's data type, or the path does not point to a list, such as for a scalar property or a list element.
Since
2026.1

◆ getListSize() [2/2]

std::optional< size_t > luciad::Feature::getListSize ( const std::string & propertyName) const

Convenience overload of getListSize that resolves the property by name on this feature's data type.

Equivalent to calling getListSize with a DataPropertyPath built from getDataType() and propertyName.

Performance note: this overload resolves the name on every call. To read the same property from many features in a tight loop, build a DataPropertyPath once and use the DataPropertyPath overload, which prevents the repeated lookup.

Parameters
propertyNamethe name of a list-typed property (DataCollectionKind::List) in this feature's data type.
Returns
no value if the list is unset for this feature, or the element count otherwise (0 for an empty list).
Exceptions
InvalidArgumentExceptionwhen no property with that name exists, or it does not point to a list, such as for a scalar property.
Since
2026.1

◆ getValue() [1/2]

template<typename T>
std::optional< T > luciad::Feature::getValue ( const DataPropertyPath & propertyPath) const

Accesses the value for the given property.

The type parameter T depends on the type of value this property contains:

  • Scalar property: T is the element type (bool, int32_t, int64_t, float, double, std::string, or a Geometry, or one of its subtypes).
  • Composite property (value type is a non-primitive DataType): T is luciad::DataObject, and the nested composite value is returned.
  • List property: T is the list type, and the list is returned, or no value when the list is unset. Individual elements may be unset as well.
  • List element (path with a terminal index step): T is the element type (luciad::DataObject for a composite element), and the single element is returned.

Example

auto optBool = feature.getValue<bool>(boolPropertyPath);
auto optInt = feature.getValue<int32_t>(intPropertyPath);
auto optLong = feature.getValue<int64_t>(longPropertyPath);
auto optFloat = feature.getValue<float>(floatPropertyPath);
auto optDouble = feature.getValue<double>(doublePropertyPath);
auto optString = feature.getValue<std::string>(stringPropertyPath);
auto optGeometry = feature.getValue<std::shared_ptr<Geometry>>(geometryPropertyPath);
auto unsetValue = feature.getValue<std::string>(unsetPropertyPath); // Unset property -> empty optional

Reading a composite value and navigating to one of its leaves:

// Read the whole composite, then descend to one of its leaves.
std::optional<DataObject> retrieved = person.getValue<DataObject>(addressPath);
std::optional<std::string> street = retrieved->getValue<std::string>(streetPath);

Reading the elements of a list of composite values:

// A list of composites: bulk-set the list, then navigate from an element to its inner leaf.
auto addressesPath = DataPropertyPath::newBuilder().originType(teamType).property("addresses").build();
auto mainSt = DataObject::newBuilder().dataType(addressType).value<std::string>(streetPath, "Main St").build();
auto highSt = DataObject::newBuilder().dataType(addressType).value<std::string>(streetPath, "High St").build();
std::vector<std::optional<DataObject>> addresses = {mainSt, highSt};
auto team = Feature::newBuilder().id(2).dataType(teamType).value<std::vector<std::optional<DataObject>>>(addressesPath, addresses).build();
auto secondPath = DataPropertyPath::newBuilder().originType(teamType).property("addresses").index(1).build();
std::optional<std::string> secondStreet = team.getValue<DataObject>(secondPath)->getValue<std::string>(streetPath);
Template Parameters
Tthe value type, chosen by property shape (see above).
Parameters
propertyPaththe property for which to return a value.
Returns
the value, or no value if the property exists in the DataType but is not set for this feature. For an indexed path, no value means the element at that index is explicitly unset.
Exceptions
InvalidArgumentExceptionwhen the property does not exist in the DataType, T does not match the path's leaf type (for example the value is a Point geometry but ArcBand was requested), or the list is unset or the index is out of bounds for an indexed path.

◆ getValue() [2/2]

template<typename T>
std::optional< T > luciad::Feature::getValue ( const std::string & propertyName) const

Convenience overload of getValue that resolves the property by name on this feature's data type.

Equivalent to calling getValue with a DataPropertyPath built from getDataType() and propertyName.

Performance note: this overload resolves the name on every call. To read the same property from many features in a tight loop, build a DataPropertyPath once and use the DataPropertyPath overload, which avoids the repeated lookup.

Template Parameters
Tthe value type, chosen by the property's shape (see the DataPropertyPath overload).
Parameters
propertyNamethe name of a property in this feature's data type.
Returns
the value, or no value if the property exists but is not set for this feature.
Exceptions
InvalidArgumentExceptionwhen no property with that name exists, or T does not match its type.
Since
2026.1

◆ hasId()

bool luciad::Feature::hasId ( ) const

Returns if this Feature has an id.

If this method returns false, it is not allowed to call Feature::getId.

Returns
if this Feature has an id.
See also
Feature::Builder::id

◆ newBuilder()

Builder luciad::Feature::newBuilder ( )
static

Returns a new Feature Builder.

Returns
a new Feature Builder.

◆ operator!=()

bool luciad::Feature::operator!= ( const Feature & other) const

◆ operator==()

bool luciad::Feature::operator== ( const Feature & other) const