Overview
Point Feature Datasets (also known as Discrete Sampling Geometry (DSG) datasets) are collections of Point Features. Point Feature Datasets contain one or more DsgFeatureCollections:
public interface ucar.nc2.ft.FeatureDatasetPoint extends ucar.nc2.ft.FeatureDataset {
List<DsgFeatureCollection> getPointFeatureCollectionList();
}
public interface DsgFeatureCollection {
String getName();
ucar.nc2.constants.FeatureType getCollectionFeatureType();
CalendarDateUnit getTimeUnit();
String getAltUnits();
CalendarDateRange getCalendarDateRange();
ucar.unidata.geoloc.LatLonRect getBoundingBox();
int size();
}
Point feature types are arrangements of collections of Point Features (a set of measurements at the same point in space and time), distinguished by the geometry and topology of the collections.
The Point Feature Types
that are implemented are:
- Point feature : one or more parameters measured at one point in time and space.
- Station time series feature : a time-series of data points all at the same location, with varying time.
- Profile feature : a set of data points along a vertical line.
- Station Profile feature : a time-series of profile features at a named location.
- Trajectory feature : a set of data points along a 1D curve in time and space.
- Trajectory Profile feature : a collection of profile features which originate along a trajectory. Also known as a Section.
Related documents:
Point Features
A PointFeature
is a collection of data taken at a single time and a single place:
public interface PointFeature {
DsgFeatureCollection getFeatureCollection();
ucar.unidata.geoloc.EarthLocation getLocation();
double getObservationTime();
CalendarDate getObservationTimeAsCalendarDate();
double getNominalTime();
CalendarDate getNominalTimeAsCalendarDate();
CalendarDateUnit getTimeUnit();
ucar.ma2.StructureData getDataAll() throws java.io.IOException;
ucar.ma2.StructureData getFeatureData() throws java.io.IOException;
}
The time can be retrieved as a CalendarDate
or as a double in units of getFeatureCollection().getTimeUnit()
.
The actual time of the data sample is the observation time, and is always present.
Some observational systems bin data into standard intervals, in which case there is also a nominal time.
When the nominal time is not given in the data, it is usually set to the observational time.
Conversion between time as a double
and as a CalendarDate
is done by getFeatureCollection().getTimeUnits()
.
When a PointFeature
is part of nested features, getDataAll()
will return the data with all of the parent data in a single StructureData
object, while getFeatureData()
will return the data at just the innermost feature.
See examples below.
The location
is returned as:
public interface ucar.unidata.geoloc.EarthLocation {
double getLatitude();
double getLongitude();
double getAltitude();
ucar.unidata.geoloc.LatLonPoint getLatLon();
}
The latitude
and longitude
are required, while the altitude
may be missing and if so, is set to Double.NaN
.
The altitude
units
(if they exist) can be found from getFeatureCollection().getAltUnits()
.
The actual data of the observation is contained in a ucar.ma2.StructureData
, which has a collection of StructureMembers
which describe the individual data members, along with many convenience routines for extracting the data.
PointFeatureCollection
A PointFeatureCollection
is a collection of PointFeatures
:
public interface PointFeatureCollection extends DsgFeatureCollection, Iterable<PointFeature> {
PointFeatureCollection subset(LatLonRect boundingBox, CalendarDateRange dateRange) throws IOException;
}
A PointFeatureCollection
inherits from DsgFeatureCollection
, and so has a name
, featureType
, and timeUnit
.
The size
, boundingBox
, and dateRange
may not be known until after iterating through the collection, that is, actually reading the data.
You can force the discovery of these by calling ucar.nc2.ft.point.DsgCollectionHelper.calcBounds()
.
A PointFeatureCollection
implements Iterable<PointFeature>
, so can be used in a foreach block:
for (PointFeature pf : pointFeatureCollection) {
...
}
You may subset a PointFeatureCollection
with a lat/lon bounding box, and/or a dateRange
, for example:
CalendarDateRange dateRange = CalendarDateRange.of(start, end);
LatLonRect horizSubset = new LatLonRect(40,-105,10.0,20.0);
// get all the points in that subset
PointFeatureCollection subset = original.subset(horizSubset, dateRange);
for (PointFeature pf : subset) {
...
}
Profile Features
A ProfileFeature
is a collection of PointFeatures along a vertical line.
public interface ProfileFeature extends PointFeatureCollection, Iterable<PointFeature> {
LatLonPoint getLatLon();
CalendarDate getTime(); // nominal
StructureData getFeatureData() throws IOException;
}
ProfileFeature
extends PointFeatureCollection
and DsgFeatureCollection
, so has a name
, altUnit
, etc.
The iterator will return PointFeatures
that all belong to the same profile, with the same lat/lon point and varying heights.
Each profile will have a nominal time, but there may also be a time associated with each point in the profile that varies.
Since a profile is a PointFeatureCollection
, it implements Iterable<PointFeature>
, so you get its data using:
for (PointFeature pf : profile) {
...
}
ProfileFeatureCollection
A collection of ProfileFeatures
is a ProfileFeatureCollection
:
public interface ProfileFeatureCollection extends PointFeatureCC, Iterable<ProfileFeature> {
ProfileFeatureCollection subset(LatLonRect boundingBox) throws IOException;
ProfileFeatureCollection subset(LatLonRect boundingBox, CalendarDateRange dateRange) throws IOException;
}
To read all the data, iterate through each ProfileFeature
in the collection, then through each PointFeature
of the ProfileFeature
:
for (ProfileFeature profile : profileFeatureCollection) {
StructureData profileData = profile.getFeatureData();
for (PointFeature obs : profile) {
StructureData obsData = obs.getFeatureData();
...
}
}
Data associated with the entire profile will be found in profile.getFeatureData()
, while the data along the z axis will be in obs.getFeatureData()
.
You may subset a ProfileFeatureCollection
with a lat/lon bounding box, getting back another ProfileFeatureCollection
.
Typically this is a logical subset, and no data is read until you iterate over the subset:
LatLonRect wantBB = new LatLonRect("-60,120,12,20");
ProfileFeatureCollection subset = profileFeatureCollection.subset(wantBB);
// get all the profiles in the specified bounding box
for (ProfileFeature profile : subset) {
LatLonPoint profileLocation = profile.getLatlon();
...
}
Station Time Series Features
A StationTimeSeriesFeature
is a time series of PointFeatures
at a single, named location called a Station
:
public interface StationTimeSeriesFeature extends StationFeature, PointFeatureCollection {
String getName();
String getDescription();
String getWmoId();
double getLatitude();
double getLongitude();
double getAltitude();
LatLonPoint getLatLon();
StructureData getFeatureData() throws IOException;
StationTimeSeriesFeature subset(CalendarDateRange dateRange) throws IOException;
}
StationTimeSeriesFeature
extends PointFeatureCollection
and DsgFeatureCollection
, so has a name
, altUnit
, timeUnits
, etc.
It also extends Station
and EarthLocation
and so has a description
, lat
, lon
, altitude
and so on.
An iterator will return PointFeatures
that all belong to the same station.
These may or may not be time-ordered.
One can also subset on dateRange
:
CalendarDateRange dateRange = CalendarDateRange.of(start, end);
PointFeatureCollection subset = stationTimeSeriesCollection.subset(dateRange);
for (PointFeature pointFeature : subset) {
StructureData allData = pointFeature.getDataAll();
...
}
The example also shows getting a single StructureData
that will include the data from both the station and the observation.
StationTimeSeriesFeatureCollection
A StationTimeSeriesFeatureCollection
is a collection of stations with time series data at each:
public interface StationTimeSeriesFeatureCollection extends PointFeatureCC, Iterable<StationTimeSeriesFeature> {
List<StationFeature> getStationFeatures() throws IOException;
List<StationFeature> getStationFeatures( List<String> stnNames) throws IOException;
List<StationFeature> getStationFeatures( ucar.unidata.geoloc.LatLonRect boundingBox) throws IOException;
StationFeature findStationFeature(String name);
StationTimeSeriesFeature getStationTimeSeriesFeature(StationFeature s) throws IOException;
// subsetting
StationTimeSeriesFeatureCollection subset(List<StationFeature> stations) throws IOException;
StationTimeSeriesFeatureCollection subset(ucar.unidata.geoloc.LatLonRect boundingBox) throws IOException;
StationTimeSeriesFeatureCollection subset(List<StationFeature> stns, CalendarDateRange dateRange) throws IOException;
StationTimeSeriesFeatureCollection subset(LatLonRect boundingBox, CalendarDateRange dateRange) throws IOException;
PointFeatureCollection flatten(List<String> stations, CalendarDateRange dateRange, List<VariableSimpleIF> varList) throws IOException;
PointFeatureCollection flatten(LatLonRect llbbox, CalendarDateRange dateRange) throws IOException;
}
A StationTimeSeriesFeatureCollection
is a collection of stations, from which you can get the list of available stations, a bounding box, etc.
You may subset the station collection by passing in a list of station names or a lat/lon bounding box.
You may subset the timeseries collection by passing in a list of stations, a lat/lon bounding box, or a date range.
You may flatten the timeseries collection, making it into a collection of PointFeatures
.
The flattening may include subsetting by lat/lon bounding box, and/or a dateRange.
Flattening can sometimes improve performance.
To access the data, get a StationTimeSeriesFeature
for a specified Station, or iterate over all StationTimeSeriesFeatures
in the collection:
for (StationTimeSeriesFeature timeSeries : stationCollection) {
StructureData stnData = timeSeries.getFeatureData();
for (ucar.nc2.ft.PointFeature pointFeature : timeSeries) {
StructureData obsData = pointFeature.getFeatureData();
...
}
}
To get a time series at a particular station:
Station stn = stationTimeSeriesCollection.getStation("FXOW");
StationTimeSeriesFeature timeSeries = stationTimeSeriesCollection.getStationFeature(stn);
for (ucar.nc2.ft.PointFeature pointFeature : timeSeries) {
...
}
To get all PointFeatures in a specific area and time range, it can help performance sometimes to flatten the StationTimeSeriesCollection
, so that the points can be returned in the order they are stored, instead of sorting by Station.
One can still retrieve the associated station by calling stationCollection.getStationFeature(pointFeature)
:
LatLonRect bb = new LatLonRect( LatLonPoint.create(40.0, -105.0),
LatLonPoint.create(42.0, -100.0));
CalendarDateRange dateRange = CalendarDateRange.of(start, end);
PointFeatureCollection points = stnCollection.flatten(bb,dateRange);
for (PointFeature pointFeature : points) {
StationFeature stationFeature = stnCollection.getStationFeature(pointFeature);
String stationName = stationFeature.getName();
...
}
Station Profile Features
A StationProfileFeature
is a time series of ProfileFeatures
at a single, named location.
public interface StationProfileFeature extends StationFeature, PointFeatureCC, Iterable<ProfileFeature> {
String getName();
String getDescription();
String getWmoId();
double getLatitude();
double getLongitude();
double getAltitude();
StructureData getFeatureData() throws IOException;
List<CalendarDate> getTimes() throws IOException;
ProfileFeature getProfileByDate(CalendarDate date) throws IOException;
StationProfileFeature subset(CalendarDateRange dateRange) throws IOException;
}
A StationProfileFeature
is a time series of profiles at a named location.
It extends StationFeature
, and so has name
, description
, etc.
Each profile has a nominal time value, and you can get a list of these, or find a specific profile by time.
You can iterate over the ProfileFeatures
in the collection, then through all PointFeatures
of the ProfileFeature
:
for (ucar.nc2.ft.ProfileFeature profile : stationProfileFeature) {
StructureData profileData = profile.getFeatureData();
for (ucar.nc2.ft.PointFeature pointFeature : profile) {
...
}
}
StationProfileFeatureCollection
A StationProfileFeatureCollection
is a collection of StationProfileFeature
, i.e. multiple stations, each of which has time series of profiles.
public interface StationProfileFeatureCollection extends PointFeatureCCC, Iterable<StationProfileFeature> {
List<StationFeature> getStationFeatures() throws IOException;
List<StationFeature> getStationFeatures( List<String> stnNames) throws IOException;
List<StationFeature> getStationFeatures( ucar.unidata.geoloc.LatLonRect boundingBox) throws IOException;
StationFeature findStationFeature(String name);
StationProfileFeature getStationProfileFeature(StationFeature s) throws IOException;
// subsetting
StationProfileFeatureCollection subset(List<StationFeature> stations) throws IOException;
StationProfileFeatureCollection subset(ucar.unidata.geoloc.LatLonRect boundingBox) throws IOException;
StationProfileFeatureCollection subset(List<StationFeature> stns, CalendarDateRange dateRange) throws IOException;
StationProfileFeatureCollection subset(LatLonRect boundingBox, CalendarDateRange dateRange) throws IOException;
}
A StationProfileFeatureCollection
looks much like a StationTimeSeriesFeatureCollection
, except you have profiles instead of point features.
To run through all the data, iterate through each StationProfileFeature
in the collection, then through each ProfileFeature
in the StationProfileFeature
, then through each PointFeature
of the ProfileFeatures
:
for (StationProfileFeature stationProfile : stationProfileFeatureCollection) {
StructureData stnData = stationProfile.getFeatureData();
for (ProfileFeature profile : stationProfile) {
StructureData profileData = profile.getFeatureData();
for (PointFeature pointFeature : profile) {
StructureData obsData = pointFeature.getFeatureData();
...
}
}
}
Trajectory Features
A TrajectoryFeature
is a connected collection of PointFeatures
along a line in space and time.
public interface TrajectoryFeature extends PointFeatureCollection, Iterable<PointFeature> {
int size();
CalendarDateRange getCalendarDateRange();
ucar.unidata.geoloc.LatLonRect getBoundingBox();
StructureData getFeatureData() throws IOException;
}
TrajectoryFeature
extends PointFeatureCollection
and DsgFeatureCollection
, so has a name
, altUnit
, etc.
The iteration will return PointFeatures
that all belong to the same trajectory.
Since a trajectory is a PointFeatureCollection
, it implements Iterable<PointFeature>
, so you get its data using:
for (PointFeature pf : trajectory) {
...
}
TrajectoryFeatureCollection
A collection of TrajectoryFeatures
is a TrajectoryFeatureCollection
:
public interface TrajectoryFeatureCollection extends PointFeatureCC, Iterable<TrajectoryFeature> {
TrajectoryFeatureCollection subset(LatLonRect boundingBox) throws IOException;
}
To read all the data, iterate through each TrajectoryFeature
in the collection, then through each PointFeature
:
for (TrajectoryFeature traj : trajectoryFeatureCollection) {
StructureData trajData = traj.getFeatureData();
for (PointFeature obs : traj) {
StructureData obsData = obs.getFeatureData();
...
}
}
Data associated with the entire trajectory will be found in traj.getFeatureData()
, while the data along the trajectory will be in obs.getFeatureData()
.
You may subset a TrajectoryFeatureCollection
with a lat/lon bounding box, getting back another TrajectoryFeatureCollection
.
Typically this is a logical subset, and no data is read until you iterate over the subset:
LatLonRect wantBB = new LatLonRect("-60,120,12,20");
TrajectoryFeatureCollection subset = trajectoryFeatureCollection.subset(wantBB);
// get all the profiles in the specified bounding box
for (TrajectoryFeature traj : subset) {
...
}
TrajectoryProfileFeature Features
A TrajectoryProfileFeature
is a time series of profiles along a line is space and time, ie a trajectory.
public interface TrajectoryProfileFeature extends PointFeatureCC, Iterable<ProfileFeature> {
StructureData getFeatureData() throws IOException;
}
You can iterate over the ProfileFeatures
in the collection, then through all PointFeatures
of the ProfileFeature
:
for (ucar.nc2.ft.ProfileFeature profile : trajProfileFeature) {
StructureData profileData = profile.getFeatureData();
for (ucar.nc2.ft.PointFeature pointFeature : profile) {
...
}
}
TrajectoryProfileFeatureCollection
A TrajectoryProfileFeatureCollection
is a collection of TrajectoryProfileFeatures
, i.e. multiple trajectories, each of which has a time series of profiles.
public interface TrajectoryProfileFeatureCollection extends PointFeatureCCC, Iterable<StationProfileFeature> {}
To run through all the data, iterate through each TrajectoryProfileFeatureCollection
in the collection, then through each ProfileFeature
in the StationProfileFeature
, then through each PointFeature
of the ProfileFeatures
:
for (TrajectoryProfileFeature trajProfile : trajProfileFeatureCollection) {
StructureData trajData = trajProfile.getFeatureData();
for (ProfileFeature profile : trajProfile) {
StructureData profileData = profile.getFeatureData();
for (PointFeature pointFeature : profile) {
StructureData obsData = pointFeature.getFeatureData();
...
}
}
}