-
Notifications
You must be signed in to change notification settings - Fork 13
Use bands and sub features
Neither a raster coverage nor a feature coverage need to be simple 2D objects with only X and Y coordinates to worry about. A raster may have a third dimension, referred to as the Z
dimension but that is not (mostly not) a Z
in vertical meters (though it could be). Features may have even more "dimensions" ( see Feature(s)).
The Z
dimension must have a type, a unit to be properly defined. In Ilwis terms we use a domain there. Furthermore we must have set of valid values for this dimension.
ITimeDomain dom;
dom.prepare();
dom->range(new Ilwis::TimeInterval("20090101", "20110101"));
std::vector<QString> times = {"20090101","20090131","20090602", \
"20090703", "20100109","20110101"};
raster->attributeDefinitionsRef().setSubDefinition(dom,times);
In this example we create a time domain ranging between first of January 2009 and the same date two years later. Then we add a range of valid dates on this range for which we have data. Those two pieces of information are combines and form the subdefintion which defines the Z
dimension. It is then possible to request
PixelIterator band2 = raster->band("20090131");
to request the raster band of 31st of January.
The same is possible with numeric information e.g.
raster->attributeDefinitionsRef().setSubDefinition(IDomain("value"),{100,200,500,1500,300});
if one has for example coverages of temperature for different heights above the ground.
PixelIterator band3 = raster->band(500);
will then retrieve the band (containing temperature values) on 500m height.
By default the Z
dimension will be a simple integer scalar that counts from 0 to infinity.
The situation for features is quite similar. Feature may have associated other features. For example a classified land use area which shape changes during the course of a year, or a stationary sensor with measurements over time (where the actual geometry stays the same but attributes changes).
If we define for example a the sensor example we get something that is very similar to the raster case
ITimeDomain dom;
dom.prepare();
dom->range(new Ilwis::TimeInterval("20090101", "20110101"));
std::vector<QString> times = {"20090101","200900201",\
"200900301",..., "20101201"};
featurecoverage->attributeDefinitionsRef().setSubDefinition(dom,times);
Accessing this data is of course different then the raster case as we have to this per feature. For this we have overloaded the []
operator so that this will work
SPFeatureI subfeature = somefeature["20090301"];
which will retrieve the subfeature for the 1st of March 2009. Adding sub features is done as follows
SPFeatureI newfeature = feature1->createSubFeature("20090401", somegeom);
It automatically adds the new feature as subfeature to feature1 with a geometry. The geometry may be 0
if none is needed (yet), or the geometry will stay the same (take the in situ sensor example).
Attributes are a different matter. There are attributes on general coverage level and attributes that are defined on the sub level. At coverage level we use
FeatureAttributeDefinition def = featureCoverage->attributeDefinitionsRef();
def.addColumn("sensorid", "count");
to add attribute types. On sub level we use
auto *attrdef = new Ilwis::FeatureAttributeDefinition();
attrdef->addColumn("temperature", "value");
featureCoverage->attributeDefinitionsRef().featureAttributeDefinition(attrdef);
note that the FeatureAttributeDefinition
has to be added only once when creating the first attribute at sub level. You can always retrieve an existing one of the feature coverage by for example
FeatureAttributeDefinition& defintion = featurecoverage->attributeDefinitionsRef().featureAttributeDefinitionRef();
After this attribute values can retrieved by the overloaded ()
operator. For example
// setting sub feature attribute
feature1["20090101"]("temperature", 26.5);
// getting sub feature attribute
double v = feature1["20090101"]("temperature").toDouble();
// setting coverage level (constant over the subfeatures) attribute
feature1("sensorid",349);
// getting coverage level attribute
int id = feature1("sensorid");