VR-Forces 4.8 Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
15.6 - Accessing Features through the API

Table of Contents

Features are usually accessed using the following process:

  1. Get a set of features from the DtTerrainInterface.
  2. Create a DtQuery object and filter the feature set.
  3. Iterate over the features using the forEachFeature() function on the filtered feature set. Within the function passed into forEachFeature(), do some kind of processing on an individual feature, such as using its geometry or attributes.

The following example shows the entire process. It prints the attributes on each point building feature within a given area. Each step is discussed in greater detail in subsequent sections.

using namespace MAKVRinTerra;
struct FeaturePrinter
{
void printAttribute(const DtFeature::Key & key, DtFeature::Attribute attr)
{
DtWarn << "\t" << key << " = " << attr << std::endl;
}
void operator()(const DtFeature& feature)
{
DtWarn << "Printing a feature:" << std::endl;
feature.forEachAttribute(boost::bind(&FeaturePrinter::printAttribute, this, _1, _2));
}
};
void printFeaturesInArea(DtTerrainInterface* terrainInterface,
std::vector<DtVector> points)
{
std::auto_ptr<MAKVRinTerra::DtObstacleFeatureSet> buildings =
terrainInterface->obstacles("MAK_BUILDING");
DtProj::CPtr localProj = terrainInterface->localProj();
DtQuery intersectQuery = DtGeometryIntersects::Create(area);
DtQuery finalQuery = DtAndQuery::Create(pointTypeQuery, intersectQuery);
std::auto_ptr<DtObstacleFeatureSet> buildingsInArea(buildings->filter(finalQuery, LOAD));
FeaturePrinter printer;
buildingsInArea->forEachFeature(boost::ref(printer), DO_NOT_BLOCK);
}

15.6.1 Accessing Feature Sets through the Terrain Interface

Feature data is accessed in the API through the DtTerrainInterface object. The DtTerrainInterface allows feature sets to be accessed using the following functions:

virtual std::auto_ptr<MAKVRinTerra::DtObstacleFeatureSet> obstacles(const std::string& type) const;
virtual std::auto_ptr<MAKVRinTerra::DtPathFeatureSet> paths(const std::string& type) const;
virtual std::auto_ptr<MAKVRinTerra::DtFeatureSet> allFeatures() const;

These functions return sets of features, using the "type" string to determine what type of features should be included - for example "MAK_ROAD" or "MAK_OBSTACLE". See ./appData/settings/featureconfig.txt for the available feature type strings.

Once a feature set has been acquired, it can be filtered using DtQuery objects, with which the user can cause matching features to be loaded.

15.6.1.1 The obstacles() Function

This function returns a set of obstacle features - features that have been configured to be obstacle objects. All obstacle features have a "footprint" geometry - an areal geometry representing the 2-dimensional footprint of the feature. This is either taken directly from the original feature geometry or, if the feature is a point feature, it is generated from the feature's length, width, and rotation.

15.6.1.2 The paths() Function

This function returns a set of path features, or linear features that can be used for path planning.

15.6.1.3 The allFeatures() Function

This function returns the set of all features, which can then be filtered with specific queries.

15.6.2 Filtering and DtQuery Objects

Once a feature set has been acquired, you can filter it using a DtQuery object. DtQuery objects can be constructed through code like this (taken from the addSensorPropagator example):

// In this example, the final query object losQuery represents the query "GeometryType Area
// AND intersects targetPoint"
DtQuery areaTypeQuery = DtHasGeometry::Create(DtFeatureGeometry::AreaType);
DtQuery geometryQuery = DtGeometryIntersects::Create(targetPoint);
DtQuery losQuery = DtAndQuery::Create(areaTypeQuery, geometryQuery);

Once the query object is created, it can be applied to the feature set using the filter function:

// LOAD will cause features to be loaded asynchronously - instead of just returning matching
// features that are already loaded
std::auto_ptr<DtObstacleFeatureSet> obstacles(losFeatures->filter(losQuery, LOAD));

15.6.3 Iterating Over Features Using forEachFeature()

To iterate over the features in a feature set, use the forEachFeature() function. forEachFeature() can be called using any bound function, or using a functor:

// ClosestPointOnedgeFinder is a functor
ClosestPointOnEdgeFinder finder(point);
// uses boost::ref because the functor will be copied internally.
// using DO_NOT_BLOCK means to iterate over whatever features are currently loaded,
// instead of blocking until all are loaded
intersectedObstacles->forEachFeature(boost::ref(finder), DO_NOT_BLOCK);
// Example that uses a member function - this could also be a non-member function
// featuresInCell is a DtPathFeatureSet
// this is a DtPathFinder object
// BLOCK means to block until all features in the feature set have been loaded, then run
// forEachFeature
featuresInCell->forEachFeature(
boost::bind(&DtPathFinder::addFeatureToGraph, this, _1), BLOCK);

15.6.4 Feature Attributes and forEachAttribute()

Features are composed of 1 or more geometries, along with 1 or more attributes. Attributes are looked up by name, and will have integer, double, or string values. Individual feature attributes can be accessed using the attributeAs() function:

//MAK_WIDTH is a "Transform Attribute" defined in appData/settings/featureconfig.txt
//feature is a DtFeature::CPtr
boost::optional<double> featureWidth = feature->attributeAs<double>("MAK_WIDTH");
double width = featureWidth ? *featureWidth : 0;

To iterate over all attributes, use the forEachAttribute() function, as follows. This example is a simple object that takes a feature and prints out its attributes:

class FeatureWrapper
{
FeatureWrapper(const DtFeature & f)
{
//_1 and _2 are the key and attribute value respectively
f.forEachAttribute(boost::bind(&DtSimpleFeature::printAttribute, this, _1, _2));
}
void printAttribute(const Key & k, Attribute attr)
{
DtWarn << key << " = " << attr << std::endl;
}
};

15.6.5 DtFeatureGeometry Objects and DtProj Objects

Each feature will contain at least one DtFeatureGeometry object, accessed via the geometry() function. The DtFeatureGeometry object contains the point(s) that make up the geometry, the projection the geometry is in, as well as various utility functions for relating geometries.

DtFeatureGeometry objects can be created using static functions in the DtFeatureGeometry class, most of which require a DtProj object, a VR-Forces wrapper for the proj library. This object is integrated with the existing VR-Forces Coordinate System classes, in that a DtProj object can be accessed from any Coordinate_System object, and new DtProj objects can be created using Coordinate_System objects. Here is an example that tests whether a feature's geometry intersects the geodetic origin:

DtProj::CPtr geodProj = DtProj::Make(new DtGeodeticCS);
DtPoint geodPoint(0.0, 0.0, 0.0);
DtFeatureGeometry::Point geodGeometry = DtFeatureGeometry::Point::Make(geodPoint, geodProj);
bool intersects = geodGeometry.intersects(feature.geometry());

The sim's current "Local" projection can be acquired from the DtTerrainInterface:

DtProj::CPtr localProj = terrainInterface->localProj();

[<< Terrain Implementations] [Home] [Top of Page] [Dynamic Terrain Network Interface >>]


Document ID: Generated on Thu Aug 27 10:56:05 EDT 2020 from SVN revision 217100
Copyright © 2005-2020 MAK Technologies. All Rights Reserved (www.mak.com)