public class TLcdNetCDFFilteredModel extends TLcd2DBoundsIndexedModel implements ILcdTimeBounded, ILcdMultiDimensionalModel, ILcdLockDependent
This model wrapper around a NetCDF model makes it possible to filter NetCDF data. This model is suited for
visualization: it can be visualized by default by the raster painting code, and it makes sure that only one
image is painted at the same time. The image that will be painted can be selected using the applyDimensionFilter
method. All the dimensions and possible filter values can be obtained using the getDimensions()
method. The unfiltered (wrapped) NetCDF model can be retrieved using the
getUnfilteredModel()
method.
This model contains domain objects (typically one) that implements ILcdDataObject
and contains an image in one of its properties. This
property can be retrieved by inspecting the TLcdHasGeometryAnnotation
of the data type.
The domain objects also contain properties that describe their time and vertical position. See
TLcdNetCDFFilteredModelDataTypes
.
ILcdMultiDimensionalModel
,
Serialized FormILcdModel.Query
fModelEventSupport
FIRE_LATER, FIRE_NOW, NO_EVENT
Constructor and Description |
---|
TLcdNetCDFFilteredModel(ILcdModel aModel)
Creates a new model wrapper around an unfiltered (multidimensional) model.
|
Modifier and Type | Method and Description |
---|---|
void |
applyDimensionFilter(TLcdDimensionFilter aFilter,
int aEventMode)
Applies a given dimensional filter and fires an event accordingly.
|
void |
dispose()
Disposes of this model and allows it to release any system resources that it is holding.
|
List<Object> |
getDependentObjects()
Returns the objects that must be locked along with this object.
|
<T> ILcdDimension<T> |
getDimension(TLcdDimensionAxis<T> aAxis)
Returns the data ranges for which data is available.
|
Collection<TLcdDimensionAxis<?>> |
getDimensionAxes()
Deprecated.
use
getDimensions() instead. |
TLcdDimensionFilter |
getDimensionFilter()
Gets the current dimensional filter, possibly empty but never
null . |
List<TLcdDimension<?>> |
getDimensions()
Gets a list of dimensions, for example time or height, over which this multi-dimensional object is defined.
|
TLcdDimensionInterval<?> |
getFilterParameter(TLcdDimensionAxis<?> aAxis)
Deprecated.
use
getDimensionFilter() instead. |
ILcdTimeBounds |
getTimeBounds()
Returns the
ILcdTimeBounds by which this object is bounded. |
ILcdModel |
getUnfilteredModel()
Returns the unfiltered model that is wrapped by this filtered model instance.
|
<T> TLcdDimensionAxis<T> |
retrieveDimensionAxis(Class<T> aType,
ILcdISO19103UnitOfMeasure aUnit)
Deprecated.
use
getDimensions() instead |
void |
setFilterParameter(TLcdDimensionAxis<?> aAxis,
TLcdDimensionInterval<?> aInterval,
int aEventMode)
Deprecated.
use
applyDimensionFilter(TLcdDimensionFilter, int) instead. |
addElement, allElementsChanged, applyOnInteract2DBounds, applyOnInteract2DBounds, canAddElement, canRemoveElement, contains, elementAt, elementChanged, elements, elementsChanged, getAddElementFilter, getBounds, getRemoveElementFilter, indexOf, isSynchronized, removeAllElements, removeElement, setAddElementFilter, setRemoveElementFilter, setSynchronized, size
addElements, addModelListener, allElementsRemoved, elementAdded, elementRemoved, elementsAdded, elementsRemoved, fireCollectedModelChanges, getModelDescriptor, getModelEncoder, getModelMetadata, getModelReference, initializeTransientValues, isClassTraceOn, isTraceOn, removeElements, removeModelListener, setClassTraceOn, setModelDescriptor, setModelDisposer, setModelEncoder, setModelMetadataFunction, setModelReference, setTraceOn
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
addElement, addElements, addModelListener, all, canAddElement, canRemoveElement, elementChanged, elements, elementsChanged, filter, fireCollectedModelChanges, getModelDescriptor, getModelEncoder, getModelMetadata, getModelReference, query, removeAllElements, removeElement, removeElements, removeModelListener
close
query
public TLcdNetCDFFilteredModel(ILcdModel aModel)
aModel
- an unfiltered NetCDF model.IllegalArgumentException
- when the given model is not an unfiltered NetCDF model.public ILcdModel getUnfilteredModel()
Returns the unfiltered model that is wrapped by this filtered model instance. The unfiltered model contains
domain objects (typically one) that implement the ILcdMultiDimensional
interface. It can be used to retrieve the possible axes and dimension intervals for
which data is available. Note that the data (i.e. the ALcdImage
objects) itself can only be retrieved
using the filtered model.
public void setFilterParameter(TLcdDimensionAxis<?> aAxis, TLcdDimensionInterval<?> aInterval, int aEventMode)
applyDimensionFilter(TLcdDimensionFilter, int)
instead.Sets one of the filter parameters. Filter parameters are for example a time or depth. This method
can for example be used to select one image that represents temperature at a specific time or depth.
The possible axes and dimension intervals to use can be retrieved from the getDimensionAxes
method. Note that these axes don't include spatial (i.e. lon/lat) axes.
Calling this method can modify the model elements contained in this model. Please refer to
ILcdModel
's Changing data for threading and locking policies. After this method is called,
the geometry property of the domain object (which implements ILcdDataObject
) is modified. Note that it is possible that the model elements contained in this model are
not modified after calling this method.
aAxis
- the dimension axis on which to filteraInterval
- the interval defined on the given axis used for filtering.aEventMode
- the mode for sending out the model change event. This can be one of
FIRE_NOW
, FIRE_LATER
or NO_EVENT
.getFilterParameter(com.luciad.multidimensional.TLcdDimensionAxis)
public TLcdDimensionInterval<?> getFilterParameter(TLcdDimensionAxis<?> aAxis)
getDimensionFilter()
instead.aAxis
- the axis for which to retrieve the filter parameter.applyDimensionFilter(TLcdDimensionFilter, int)
public Collection<TLcdDimensionAxis<?>> getDimensionAxes()
getDimensions()
instead.Returns the axes for which data is available. See applyDimensionFilter(com.luciad.multidimensional.TLcdDimensionFilter, int)
setFilter}. Note that the
returned collection is unmodifiable. Axes can for example represent time or depth. This means that it is possible
to retrieve different images for different times or depths. Note that the returned axes don't include spatial
(i.e. lon/lat) axes or axes for the actual data (e.g. temperature), only the axes using which can be filtered.
The axes returned in this method contain either Date
or
TLcdISO19103Measure
intervals.
public void applyDimensionFilter(TLcdDimensionFilter aFilter, int aEventMode)
ILcdMultiDimensionalModel
Filtering behavior
In practice, filtering behavior and the default filter depend on the type of the model:
ALcdImage
instances, every one of which is valid within a certain interval. An implementation of this
interface needs to make sure that
ALcdImage.fromDomainObject(java.lang.Object)
.
We advise to use the 'has-an-image' paradigm to expose this image, because it allows for faster updates
in a Lightspeed view.
Filter matching
Matching intervals happens based on TLcdDimensionInterval.overlaps(com.luciad.multidimensional.TLcdDimensionInterval<T>, com.luciad.multidimensional.TLcdDimensionInterval<T>)
.
The rationale for this is the following:
Locking
This method should typically be called from within a write lock:
try (TLcdLockUtil.Lock lock = TLcdLockUtil.writeLock(model) {
...
model.applyDimensionFilter(filter, ILcdModel.FIRE_LATER);
...
} finally {
model.fireCollectedModelChanges();
}
The most common exception to this rule is when you're creating a model initially and no-one has a reference to it
yet: in that case, it's safe to not lock at all and use ILcdModel.NO_EVENT
.
No snapping
Implementations should not 'snap' to the intervals defined by the filter in case no elements match.
There shall be no snapping to nearest, previous or next.
Instead, the result must be 'empty' (or 'image is null
' in case of raster models).
If you need to snap a filter interval to an actual interval the model has to offer, you should use
TLcdDimensionFilter.createSnappingFilter(com.luciad.multidimensional.ILcdMultiDimensionalModel, com.luciad.multidimensional.TLcdDimensionFilter.SnapMode)
to create a snapped filter.
Differences with createSnappingFilter
As its name suggests, the primary purpose of the utility method createSnappingFilter
is to create a
filter which 'snaps' to filter intervals so that there is always at least one match.
But the method does more than just that.
Here is a list of differences between using and not using createSnappingFilter
:
Behavior | applyDimensionFilter | createSnappingFilter->applyDimensionFilter |
---|---|---|
Snapping | Never, possibly resulting in no matches | Snaps to intervals defined by the model if needed, such that there is always at least one match |
Supported snap modes | None | Nearest, previous, next, or none (null ) |
Filter has less axes than supported by model | Reset to default for those axes | Keep the last current filter value for those axes, so that there are minimal model changes |
Empty filter | Reset to default filter | Keep current filter, so that there are no model changes |
ILcdModel which is not ILcdMultiDimensionalModel |
Not supported | Checks instance of ILcdMultiDimensionalModel , leaves others alone |
applyDimensionFilter
in interface ILcdMultiDimensionalModel
aFilter
- The dimensional filter, possibly empty but never null
.aEventMode
- The mode of the event that should be triggered when the value of the filter parameters changes.TLcdDimensionInterval.overlaps(com.luciad.multidimensional.TLcdDimensionInterval<T>, com.luciad.multidimensional.TLcdDimensionInterval<T>)
,
TLcdDimensionFilter.createSnappingFilter(com.luciad.multidimensional.ILcdMultiDimensionalModel, com.luciad.multidimensional.TLcdDimensionFilter.SnapMode)
public TLcdDimensionFilter getDimensionFilter()
ILcdMultiDimensionalModel
null
.
The current dimensional filter is the last one that was set on this model using
ILcdMultiDimensionalModel.applyDimensionFilter(TLcdDimensionFilter, int)
.
It may contain more or less dimensions than this model supports, and it may be empty
(TLcdDimensionFilter.EMPTY_FILTER
), but it must never be null
.
The filter intervals may but does not have to be one of the intervals given by getDimensions().getValues()
.
When no dimensional filter has been set on this model yet, this method returns the default dimensional filter. The default dimensional filter depends on the implementation. Typical implementations:
The default filter is not necessarily constant. It may change as elements are added to or removed from the model, because the default filter is often computed from the dimensional information of the elements.
getDimensionFilter
in interface ILcdMultiDimensionalModel
TLcdDimensionFilter.EMPTY_FILTER
but never null
.public List<TLcdDimension<?>> getDimensions()
If this model is an interpolated one, the returned dimensions from this method consist of regular (=non-single-value) intervals between all values for which data is available. Otherwise the returned dimensions consist of multiple single-value intervals, one for each piece of data.
getDimensions
in interface ILcdMultiDimensional
null
.ILcdMultiDimensionalModel
public <T> ILcdDimension<T> getDimension(TLcdDimensionAxis<T> aAxis)
Returns the data ranges for which data is available. These contain the possible intervals that can be used for
filtering. See applyDimensionFilter(TLcdDimensionFilter, int)
applyDimensionFilter}. Note that the
returned collection is unmodifiable. Axes can for example represent time or depth. This means that it is possible
to retrieve different images for different times or depths. Note that the returned axes don't include spatial
(i.e. lon/lat) axes or axes for the actual data (e.g. temperature), only the axes using which can be filtered.
If this model is an interpolated one, the returned dimension from this method consists of regular (=non-single-value) intervals between all values for which data is available. Otherwise the returned dimension consists of multiple single-value intervals, one for each piece of data.
The ranges returned in this method contain either Date
or
TLcdISO19103Measure
intervals.
public <T> TLcdDimensionAxis<T> retrieveDimensionAxis(Class<T> aType, ILcdISO19103UnitOfMeasure aUnit)
getDimensions()
insteadnull
is returned. If more than one axis corresponds to the given type and unit, the first one is returned.aType
- the type.aUnit
- the (optional) unit.null
if no axis can
be found.public ILcdTimeBounds getTimeBounds()
ILcdTimeBounded
ILcdTimeBounds
by which this object is bounded.getTimeBounds
in interface ILcdTimeBounded
ILcdTimeBounds
by which this object is bounded.public List<Object> getDependentObjects()
ILcdLockDependent
TLcdLockUtil
first locks all objects
returned by this method before locking this object.getDependentObjects
in interface ILcdLockDependent
public void dispose()
ALcdModel
finalize
) on this model subsequent to a call to
this method is undefined.
When a model disposer has been provided it is called, otherwise this method does nothing.
When overriding this method it is recommended to call super.dispose()
.
dispose
in interface ILcdModel
dispose
in interface ILcdDisposable
dispose
in class ALcdModel
ALcdModel.setModelDisposer(Consumer)