LuciadCPillar 2023.1.04
luciad::IFeatureModel Class Referenceabstract

A feature model allows to uniformly access vector data. More...

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

Inheritance diagram for luciad::IFeatureModel:
luciad::Model

Public Member Functions

 ~IFeatureModel () override=default
 
virtual void addObserver (std::shared_ptr< IFeatureModelObserver > modelObserver)=0
 Adds an observer that allows to receive change events from this feature model. More...
 
virtual FeatureModelMetadata getFeatureModelMetadata () const =0
 
virtual std::shared_ptr< FeatureModelPersistenceManagergetPersistenceManager ()=0
 The luciad::FeatureModelPersistenceManager is used to persist in-memory changes made through luciad::IFeatureModelUpdater. More...
 
virtual std::shared_ptr< IFeatureModelUpdatergetUpdater ()=0
 The IFeatureModelUpdater is used to make changes to the model. More...
 
virtual void query (const FeatureQuery &query, IFeatureQueryCallback &callback) const =0
 Queries the model, and passes the result to the given callback. More...
 
virtual void removeObserver (const std::shared_ptr< IFeatureModelObserver > &modelObserver)=0
 Removes the given observer. More...
 
- Public Member Functions inherited from luciad::Model
virtual ~Model ()=default
 
virtual ModelMetadata getModelMetadata () const =0
 Returns the meta data for this model. More...
 
virtual std::shared_ptr< BoundsqueryBounds () const =0
 Returns the bounds of this model, if available. More...
 

Detailed Description

A feature model allows to uniformly access vector data.

See article for more details on how to use and how to implement this class.

Using a model

A user of a model:

  • Can use the query method on any thread
  • Can expect model change events on any thread. This means that the user of a model is responsible for creating a thread-safe observer implementation, and for possible rescheduling of the model events on a different thread if needed.

Implementing a model

The model implementation has multiple responsibilities.

  • Access the data uniformly. I.e. translate data storage entries into Feature instances.
  • Filter the data. When a user of the model queries the model, he can specify a filter. The model implementation must make sure that data is correctly filtered, as efficiently as possible.
  • All model implementations must be thread safe for reading, to allow multiples queries in parallel.
  • Make sure dynamic data (i.e. data that changes over time) is updated in a thread-safe way.
  • Make sure that notifications are sent when dynamic data changes.
  • Make sure that the data is presented in a consistent way. That is, after the model sends out a change event for a Feature, the query() method must also reflect that change. This can be guaranteed by making sure that model updates (internal updates + firing model change notifications) and calls to the query method are never executed simultaneously. Notifications must not be sent while the query() method is executing.

Persisting changes

Feature models can add support for persisting model changes. See this article for more information.

Performance considerations

In order to optimize feature loading, it is recommended to follow these rules when creating a model:

  • The model should have bounds.
  • The features should contain a property whose value is a geometry.
  • Feature data types should have a GeometryDataAnnotation.
  • The reference used should not be geocentric.

Constructor & Destructor Documentation

◆ ~IFeatureModel()

luciad::IFeatureModel::~IFeatureModel ( )
overridedefault

Member Function Documentation

◆ addObserver()

virtual void luciad::IFeatureModel::addObserver ( std::shared_ptr< IFeatureModelObserver modelObserver)
pure virtual

Adds an observer that allows to receive change events from this feature model.

Adding the same observer twice is forbidden, and will cause an exception to be thrown.

Parameters
modelObserveran observer
Exceptions
InvalidArgumentExceptionwhen the observer was already added.

◆ getFeatureModelMetadata()

virtual FeatureModelMetadata luciad::IFeatureModel::getFeatureModelMetadata ( ) const
pure virtual
Returns
the feature model meta data. It provides information about the types of features one can expect within the model.

◆ getPersistenceManager()

virtual std::shared_ptr< FeatureModelPersistenceManager > luciad::IFeatureModel::getPersistenceManager ( )
pure virtual

The luciad::FeatureModelPersistenceManager is used to persist in-memory changes made through luciad::IFeatureModelUpdater.

If persisting changes is not supported by the model, or if it is not needed because luciad::IFeatureModelUpdater already automatically persists its changes, this method must return nullptr.

Returns
the FeatureModelPersistenceManager that can be used for this model. When a model doesn't support (or doesn't need) saving functionality, nullptr must be returned.
Since
2023.1

◆ getUpdater()

virtual std::shared_ptr< IFeatureModelUpdater > luciad::IFeatureModel::getUpdater ( )
pure virtual

The IFeatureModelUpdater is used to make changes to the model.

Typically, IFeatureModel implementations implement these changes as in-memory changes. FeatureModelPersistenceManager can then be used to persist those changes (if persisting changes is supported). An IFeatureModel can however choose to immediately persist any of these changes immediately, if persisting changes doesn't imply a large performance overhead for example. In that case a FeatureModelPersistenceManager is not needed, and getPersistenceManager must return nullptr.

Returns
the updater that can be used for this model. When a model can't be updated, nullptr must be returned.
Since
2020.1

◆ query()

virtual void luciad::IFeatureModel::query ( const FeatureQuery query,
IFeatureQueryCallback callback 
) const
pure virtual

Queries the model, and passes the result to the given callback.

The callback can return false to indicate that the query can stop. This method passes Feature instances to the given callback. These instances contain a copy of the original data (structured according to the DataModel of this model). The ownership of these features is passed to the caller of this method (through the callback). This means that the model is not allowed to modify/deleted these Feature instances, once they are passed to the callback function.

This method is thread-safe, and can be called on any thread.

This method is synchronous and blocking. In other words, as soon as this function returns

  • the given callback must have been called for each resulting feature
  • no more calls to the callback can be done anymore

Implementations of this method have the responsibilities described in the class documentation.

When implementing this method you may want to use the existing evaluation support which you can find in FeatureExpressionEvaluator and FeatureExpressionEvaluatorFactory.

Example to query the model for a Feature with a specific id.

auto callback = IFeatureQueryCallback::create([](const Feature& feature) {
std::cout << "Selected => " << feature.getId() << std::endl;
return false;
});
model->query(query, *callback);
A Feature is a (partial) copy of a domain object.
Definition: Feature.h:34
FeatureId getId() const
Returns the id of this feature.
Builder & featureIds(std::vector< FeatureId > featureIds)
Sets the feature ids to select.
A query specifies which objects you are interested in.
Definition: FeatureQuery.h:34
static Builder newBuilder()
Returns the builder class for creation of the feature query.
virtual void query(const FeatureQuery &query, IFeatureQueryCallback &callback) const =0
Queries the model, and passes the result to the given callback.
static std::shared_ptr< IFeatureQueryCallback > create(std::function< bool(Feature)> function)
Creates a default IFeatureQueryCallback instance that delegates the IFeatureQueryCallback::handleFeat...
Parameters
querythe query
callbacka callback which can handle the result of the query operation

◆ removeObserver()

virtual void luciad::IFeatureModel::removeObserver ( const std::shared_ptr< IFeatureModelObserver > &  modelObserver)
pure virtual

Removes the given observer.

If the given observer was never added, an exception is thrown.

Parameters
modelObserveran observer
Exceptions
InvalidArgumentExceptionwhen the observer is not known.