Class TLcdNetCDFFilteredModel
- All Implemented Interfaces:
ILcd2DBoundsIndexedModel
,ILcd2DBoundsInteractable
,ILcdIntegerIndexedModel
,ILcdModel
,ILcdMultiDimensional
,ILcdMultiDimensionalModel
,ILcdBounded
,ILcdTimeBounded
,ILcdLockDependent
,ILcdDisposable
,Serializable
,AutoCloseable
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
.
- Since:
- 2015.0
- See Also:
-
Nested Class Summary
Nested classes/interfaces inherited from interface com.luciad.model.ILcdModel
ILcdModel.Query
-
Field Summary
Fields inherited from class com.luciad.model.ALcdModel
fModelEventSupport
Fields inherited from interface com.luciad.model.ILcdModel
FIRE_LATER, FIRE_NOW, NO_EVENT
-
Constructor Summary
ConstructorDescriptionTLcdNetCDFFilteredModel
(ILcdModel aModel) Creates a new model wrapper around an unfiltered (multidimensional) model. -
Method Summary
Modifier and TypeMethodDescriptionvoid
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.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.Deprecated.Gets the current dimensional filter, possibly empty but nevernull
.List
<TLcdDimension<?>> Gets a list of dimensions, for example time or height, over which this multi-dimensional object is defined.getFilterParameter
(TLcdDimensionAxis<?> aAxis) Deprecated.usegetDimensionFilter()
instead.Returns theILcdTimeBounds
by which this object is bounded.Returns the unfiltered model that is wrapped by this filtered model instance.<T> TLcdDimensionAxis
<T> retrieveDimensionAxis
(Class<T> aType, ILcdISO19103UnitOfMeasure aUnit) Deprecated.usegetDimensions()
insteadvoid
setFilterParameter
(TLcdDimensionAxis<?> aAxis, TLcdDimensionInterval<?> aInterval, int aEventMode) Deprecated.useapplyDimensionFilter(TLcdDimensionFilter, int)
instead.Methods inherited from class com.luciad.model.TLcd2DBoundsIndexedModel
addElement, allElementsChanged, applyOnInteract2DBounds, applyOnInteract2DBounds, canAddElement, canRemoveElement, contains, elementAt, elementChanged, elements, elementsChanged, getAddElementFilter, getBounds, getRemoveElementFilter, indexOf, isSynchronized, removeAllElements, removeElement, setAddElementFilter, setRemoveElementFilter, setSynchronized, size
Methods inherited from class com.luciad.model.ALcdModel
addElements, addModelListener, allElementsRemoved, elementAdded, elementRemoved, elementsAdded, elementsRemoved, fireCollectedModelChanges, getModelDescriptor, getModelEncoder, getModelMetadata, getModelReference, initializeTransientValues, isClassTraceOn, isTraceOn, removeElements, removeModelListener, setClassTraceOn, setModelDescriptor, setModelDisposer, setModelEncoder, setModelMetadataFunction, setModelReference, setTraceOn
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
Methods inherited from interface com.luciad.model.ILcd2DBoundsIndexedModel
query
Methods inherited from interface com.luciad.util.ILcdDisposable
close
Methods inherited from interface com.luciad.model.ILcdModel
addElement, addElements, addModelListener, canAddElement, canRemoveElement, elementChanged, elements, elementsChanged, fireCollectedModelChanges, getModelDescriptor, getModelEncoder, getModelMetadata, getModelReference, removeAllElements, removeElement, removeElements, removeModelListener
-
Constructor Details
-
TLcdNetCDFFilteredModel
Creates a new model wrapper around an unfiltered (multidimensional) model.- Parameters:
aModel
- an unfiltered NetCDF model.- Throws:
IllegalArgumentException
- when the given model is not an unfiltered NetCDF model.
-
-
Method Details
-
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. theALcdImage
objects) itself can only be retrieved using the filtered model.- Returns:
- the unfiltered model that is wrapped by this filtered model instance.
-
setFilterParameter
public void setFilterParameter(TLcdDimensionAxis<?> aAxis, TLcdDimensionInterval<?> aInterval, int aEventMode) Deprecated.useapplyDimensionFilter(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 implementsILcdDataObject
) is modified. Note that it is possible that the model elements contained in this model are not modified after calling this method.- Parameters:
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 ofFIRE_NOW
,FIRE_LATER
orNO_EVENT
.- See Also:
-
getFilterParameter
Deprecated.usegetDimensionFilter()
instead.Returns the currently used filter parameter that corresponds to the given axis.- Parameters:
aAxis
- the axis for which to retrieve the filter parameter.- Returns:
- the currently used filter parameter that corresponds to the given axis.
- See Also:
-
getDimensionAxes
Deprecated.usegetDimensions()
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
orTLcdISO19103Measure
intervals.- Returns:
- the axes for which data is available.
-
applyDimensionFilter
Description copied from interface:ILcdMultiDimensionalModel
Applies a given dimensional filter and fires an event accordingly. The given filter may specify one interval per axis. The filter may contain more or less axes than the model supports.- If the filter contains more axes than the model supports, the model should ignore those axes.
- If the filter contains less axes than the model supports, the model should reset to its default for those axes.
Filtering behavior
In practice, filtering behavior and the default filter depend on the type of the model:- Vector models, such as NVG or ASTERIX, have multiple elements, where every element is a domain object. Each element has a validity defined by an interval, for example a temporal interval on a time axis. The filtered model will only contain the elements that match the filter. When a new filter is applied, events will be fired as elements are removed or added based on the new filter. The default filter in this case is 'no filter', which means that all elements match the filter and the model behaves as if unfiltered. In case no elements match the filter, the model will be empty.
-
Raster models, such as NetCDF, have a single or a couple of model elements, where every model
element corresponds with exactly one image. Internally, each element is possibly backed up by multiple
ALcdImage
instances, every one of which is valid within a certain interval. An implementation of this interface needs to make sure that- a model element only corresponds with exactly one of these images, based on the currently configured filter.
- the model element's image is available through
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. - changes in filtering are correctly applied. When a filter is changed, it must either replace the element with a new element, or when the 'has-an-image' paradigm is used, it must replace the image that is exposed by the model element. When a filter doesn't match anything, it must make sure that there is no element present in the model. Using 'has-an-image' with a null image is not a valid way to express this.
Filter matching
Matching intervals happens based onTLcdDimensionInterval.overlaps(com.luciad.multidimensional.TLcdDimensionInterval<T>, com.luciad.multidimensional.TLcdDimensionInterval<T>)
. The rationale for this is the following:- Each element has a validity defined by an interval, for example on a time axis.
- Using the filter, you're asking the model to "match everything which is valid in the filter interval(s)", which corresponds to the meaning of overlap.
Locking
This method should typically be called from within a write lock:
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 usetry (TLcdLockUtil.Lock lock = TLcdLockUtil.writeLock(model) { ... model.applyDimensionFilter(filter, ILcdModel.FIRE_LATER); ... } finally { model.fireCollectedModelChanges(); }
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 isnull
' in case of raster models). If you need to snap a filter interval to an actual interval the model has to offer, you should useTLcdDimensionFilter.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 methodcreateSnappingFilter
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 usingcreateSnappingFilter
: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 notILcdMultiDimensionalModel
Not supported Checks instance of ILcdMultiDimensionalModel
, leaves others alone- Specified by:
applyDimensionFilter
in interfaceILcdMultiDimensionalModel
- Parameters:
aFilter
- The dimensional filter, possibly empty but nevernull
.aEventMode
- The mode of the event that should be triggered when the value of the filter parameters changes.- See Also:
-
getDimensionFilter
Description copied from interface:ILcdMultiDimensionalModel
Gets the current dimensional filter, possibly empty but nevernull
. The current dimensional filter is the last one that was set on this model usingILcdMultiDimensionalModel.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 benull
. The filter intervals may but does not have to be one of the intervals given bygetDimensions().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:
- Multi-dimensional raster models, such as NetCDF, typically define a default filter which matches exactly one combination of dimensional values, often the first combination. The reason for this is that the rasters are typically mutually exclusive: only one can be included in the filtered result. Intuitively, this corresponds to a "match any" or "match first" filter.
- Multi-dimensional object models, such as NVG, typically define an unbounded default filter which matches all objects. The reason for this is that the objects are are not mutually exclusive: they can all be included in the filtered result. Intuitively, this corresponds to "no filter".
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.
- Specified by:
getDimensionFilter
in interfaceILcdMultiDimensionalModel
- Returns:
- The current dimensional filter, possibly the
TLcdDimensionFilter.EMPTY_FILTER
but nevernull
.
-
getDimensions
Gets a list of dimensions, for example time or height, over which this multi-dimensional object is defined. Each dimension defines an axis, its possible values, and the range of possible values. The values of the dimension axes are all the possible values this multi-dimensional object can be filtered on. An empty list means that the instance is not dimensionally filterable.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.
- Specified by:
getDimensions
in interfaceILcdMultiDimensional
- Returns:
- a list dimensions (axes and their possible values) over which this multi-dimensional object is defined,
possibly empty but never
null
. - See Also:
-
getDimension
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
orTLcdISO19103Measure
intervals.- Returns:
- the data ranges for which data is available.
-
retrieveDimensionAxis
public <T> TLcdDimensionAxis<T> retrieveDimensionAxis(Class<T> aType, ILcdISO19103UnitOfMeasure aUnit) Deprecated.usegetDimensions()
insteadReturns the axis that corresponds to the given type and (optional) unit. If no axis can be found,null
is returned. If more than one axis corresponds to the given type and unit, the first one is returned.- Parameters:
aType
- the type.aUnit
- the (optional) unit.- Returns:
- the axis that corresponds to the given type and (optional) unit. Can be
null
if no axis can be found.
-
getTimeBounds
Description copied from interface:ILcdTimeBounded
Returns theILcdTimeBounds
by which this object is bounded.- Specified by:
getTimeBounds
in interfaceILcdTimeBounded
- Returns:
- the
ILcdTimeBounds
by which this object is bounded.
-
getDependentObjects
Description copied from interface:ILcdLockDependent
Returns the objects that must be locked along with this object.TLcdLockUtil
first locks all objects returned by this method before locking this object.- Specified by:
getDependentObjects
in interfaceILcdLockDependent
- Returns:
- the objects that must be locked along with this object.
-
dispose
public void dispose()Description copied from class:ALcdModel
Disposes of this model and allows it to release any system resources that it is holding. The result of calling any other method (other thanfinalize
) 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()
.
-
getDimensions()
instead.