View temporal data

Some layers store temporal data, which is information about the changing state of a dataset over time. These layers are called time-aware layers. Time-aware layers allow you to step through periods of time, revealing patterns and trends in your data. For example, you can accomplish the following using time-aware layers:

  • Track hurricane paths and other meteorological events.
  • Explore historic patterns in data through time, such as population or land-use changes.
  • Monitor changes in well production or status.
  • Map the progression of a wildfire or flood.
  • Visualize the spread of disease over time.

In the ArcGIS Runtime SDK for Java, time-aware layers are those layers which implement the TimeAwareLayer interface. A hierarchy of this interface and its implementing layer classes is shown below:

TimeAwareLayer UML

All time-aware layers have a time extent property that defines a time range that is a start date and end date. There are also time field properties that indicate at which time(s) the feature applies. Time-aware layers can have additional properties such as the time step interval (or tick) and whether or not the data is cumulative. The time step interval indicates the frequency at which the data progression should be viewed; for example, data can be viewed for each day or for each year.

All time-aware layers display features for the time extent defined by the map. The time extent property on time-aware layers cannot be set explicitly, since it's defined by the map, feature, or image service. After publishing a map service, feature service, or image service containing time-aware layers, you can work with the ArcGISDynamicMapServiceLayer, ArcGISFeatureLayer, or ArcGISImageServiceLayer classes, respectively, to view changes in data over time.

Note:

At 10.2, the FeatureLayer class was added to view and work with features online and offline. However this class does not yet support time-aware services and displaying time-aware data. Please use ArcGISFeatureLayer instead to work with time-aware feature services.

You add time-aware layers to the map in exactly the same way as you add non time-aware layers to the map: by adding a layer to the JMap's layer list using map.getLayers().add(layer). The simplest way to work with time-aware layers is to use the time slider control in the toolkit, because it handles the process of updating the map's time extent for you. Alternatively, you can use the API to build applications that perform temporal queries, filter layers using time definitions, and set the map's time extent.

Work with the toolkit

The ArcGIS Runtime SDK for Java provides a JTimeSlider control in the toolkit that simplifies the process of visualizing temporal data. Using the time slider, you can filter the map to display cumulative data up to a point in time, a single point in time, or data that falls within a time range. The benefits of using the time slider are that it filters time-aware layers to only display data for the current time extent and can play back changes over time.

You should not use the time slider with feature layers in the ON DEMAND mode because it can result in too many requests to the server. If you're not working with a large amount of data, you can use an ArcGISFeatureLayer in SNAPSHOT mode. If your dataset is large, consider using an ArcGISDynamicMapServiceLayer instead.

Follow these steps to use a JTimeSlider to display temporal data in your map application:

  1. Create the time slider component, and add it to the user interface of your application:
    JTimeSlider jTimeSlider = new JTimeSlider();
    // add the time slider for example in the SOUTH (bottom) part of a JComponent with a BorderLayout
    jComponent.add(jTimeSlider, BorderLayout.SOUTH);
  2. Create the time-aware layer. In the following code example, a feature layer represents a feature service that contains earthquakes at a specific time and location:
    ArcGISFeatureLayer earthquakesLayer = new ArcGISFeatureLayer(
      "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/" + 
      "Earthquakes/Since_1970/MapServer/0");
  3. Set up the time slider using one of the following two options:
    1. Set up the time slider from a layer. Any time-aware layer can be used to set up the time slider; the time extent, interval and other properties from the layer are honored by the time slider.
      earthquakesLayer.addLayerInitializeCompleteListener(
        new LayerInitializeCompleteListener() {
      
        @Override
        public void layerInitializeComplete(LayerInitializeCompleteEvent event) {
          jTimeSlider.setupFromLayer((TimeAwareLayer) event.getLayer());
          jTimeSlider.setTitle("Earthquakes");
        }
      });
    2. Set up the time slider using its properties. This option is useful when you have more than one time-aware layer with different time extents or if setting up the time slider from a layer does not give you the time extent or tick that you want. Time-aware layers can be added to the slider before they are initialized.
      jTimeSlider.setTitle("Earthquakes");
      jTimeSlider.addLayer(layer);				
      jTimeSlider.setTimeExtent(new TimeExtent(
        new GregorianCalendar(1960, 1, 1), 
        new GregorianCalendar(2019, 1, 1)), 
        10, 
        Units.Years));
  4. Add the time-aware layer to your map:
    jMap.getLayers().add(earthquakesLayer);
    // Note: a baselayer has already been added to the map
    // The time-aware layer displays above the baselayer in this case
  5. Optionally, control the time slider's playback:
    jTimeSlider.setTimeMode(TimeMode.CumulativeFromStart);
    // tick every two seconds:
    jTimeSlider.setPlaybackRate(2000);
    // start the playback:
    jTimeSlider.play();
  6. Use the time slider in an application.
    View and interact with the Time slider and Time-aware dynamic layer samples in the ArcGIS Runtime SDK for Java sample application to experiment with the time slider. Slider thumbs denote a location on the slider and are specified with JTimeSlider's setTimeMode method. The valid time mode values are CumulativeFromStart, TimeInstant, and TimeExtent. By default (TimeExtent mode), the time slider contains two thumbs the user can drag to represent a time range. One thumb (in the TimeInstant mode) enables the user to define a specific time by which to filter the data. The CumulativeFromStart mode has one thumb locked to the start of the time slider and one thumb that is moveable. A set of buttons on the time slider also enables you to automate the display of time extents by iterating through a sequence of ranges or intervals. The control contains a play button to automatically step through the sequence, and forward and back buttons to move the thumbs.

Work with the API

When time-aware layers are present in a map, the map's time extent must be set in order to visualize any of the data in the layers. The map's time extent defines the time period for which the layers' data is displayed in the map; so it acts as a filter for time-aware layers. Each time the map's time extent is changed, all time-aware layers update to reflect the new extent when the map is panned or zoomed.

In the following code example, the map's time extent is set, and only data that meets the input time range appears:

JMap jMap = new JMap();
TimeExtent timeExtent = new TimeExtent(
  new GregorianCalendar(2009, 6, 2), 
  new GregorianCalendar(2010, 6, 30));

//the time interval can be set at any point in the life of the map
jMap.setTimeInterval(timeExtent);

Disabling time-awareness for a layer means that all features from a layer, regardless of their time extent, will be displayed. Disable time-awareness of a layer after the layer has initialized as shown in the following code:

ArcGISDynamicMapServiceLayer layer = new ArcGISDynamicMapServiceLayer(
  "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/" + 
  "Hurricanes/NOAA_Tracks_1851_2007/MapServer");
layer.addLayerInitializeCompleteListener(new LayerInitializeCompleteListener() {
  @Override
  public void layerInitializeComplete(LayerInitializeCompleteEvent event) {
    LayerTimeOptions options = layer.getTimeOptions().get(0);
    options.getTimeOptions().setUseTime(false);
  }
});