Skip To Content

View temporal data

In this topic

Geographic data is sometimes temporal in nature. Temporal data represents the state of an entity under observation at a particular time instant, or over a time period. For example, the progression of a hurricane, changes in sea temperature, destruction of wildlife habitat, or the spread of disease. By viewing and analyzing these changes in temporal sequence, you can identify trends and spot patterns in the data that would have otherwise not been noticed.

Learn more about temporal data.

A map allows you to visualize temporal data and filter out data that does not belong to a specific time period. When used in conjunction with a temporal renderer, you can symbolize changes that take place over time.

Time-aware layers

The map must contain at least one time-aware layer to be able to display temporal data. The following types of layers can be time-aware:

A layer is time aware if the service it is using contains time-enabled data.

Learn more about enabling time on your data.

You can determine if a service contains time-enabled data by using the ArcGIS Services Directory. If the TimeInfo property is listed, it means the data is time-enabled.

Time Info in services directory
Time information in ArcGIS Services Directory for a time-enabled service

You can also programmatically verify a layer is time-aware or not by inspecting its timeAware property.

Time extent

Once you have at least one time-aware layer in the map, you can adjust the map's time extent to visualize the temporal data. The time extent defines the time period for which time-aware layers display their data. Setting the map's time extent is similar to setting the spatial extent. While the spatial extent specifies the geographic area to display, the time extent specifies the time period from which the data displays. When the map's time extent changes, all time-aware layers update to reflect the new extent. There is no change to layers that are not time aware.

View data for a time period

The map allows you to display data that belongs to a time period. For example, displaying earthquakes that occurred between December 3, 2001 and March 17, 2002. To accomplish this, create AGSTimeExtent specifying the starting and ending points in time, then set it as the map's time extent as follows:

NSDate* dec3 = ...;
NSDate* mar17 = ...;
AGSTimeExtent* extent = [[AGSTimeExtent alloc] initWithStart:dec3 end:mar17];
map.timeExtent = extent;

If you want to display data starting from a particular time to the end, specify the starting time and leave the ending time as nil. The following extent represent a time period from March 17, 2002 and onwards:

NSDate* mar17 = ...;
AGSTimeExtent* mar17_onwards = [[AGSTimeExtent alloc] initWithStart:mar17 end:nil];

Conversely, if you want to display data starting from the beginning to a particular time, specify the ending time and leave the starting time as nil. The following time extent represents a time period to Dec 3, 2001:

NSDate* dec3 = ...;
AGSTimeExtent* till_dec3 = [[AGSTimeExtent alloc] initWithStart:nil end:dec3];
Note:

The starting and ending times on the map extent are both inclusive.

View data for a time instant

The map also allows you to display data that belongs to a specific time instant. For example, displaying the location of hurricane Katrina on August 25, 2005 at 6:30 a.m. (EST). To display data belonging to a time instant, create AGSTimeExtent using the same starting and ending point in time, then set it as the map's time extent as follows:

NSDate* aug25_630AM = ...;
AGSTimeExtent* instant = [[AGSTimeExtent alloc] initWithStart:aug25_630AM end:aug25_630AM];

Layer time options

The following sections discuss layer time options.

Time offset

If you have two or more time-aware layers in the map, it is possible that they could be using data belonging to different time zones, or different time periods. For example, one layer could contain hourly traffic data for California in Pacific Standard Time, and the other for New York in Eastern Standard Time. One layer may contain monthly data for the Arctic ice sheet in 2001 and the other for 2011. Even when you have such data, you may want to visualize them on a map simultaneously to compare and contrast trends. For instance, you may want to compare the rush hour traffic at 5:00 p.m. (PST) in California with the traffic at 5:00 p.m. (EST) in New York, or the condition of the ice sheet in June 2001 with the condition in June 2011.

To accomplish this, adjust one of the layer's time options by specifying an offset. Suppose you specify an offset of +10 years to the layer containing data for the ice sheet in 2001. This enables the layer to treat its data as belonging to 2011 instead of 2001. The actual data is not changed and the offset is applied on-the-fly. Now, when you set the map's time extent to June 2011, both layers draw their data. The layer for the 2011 data draws its June data as normal. However, the layer for the 2001 data first applies an offset of +10 years to its data and consequently draws its June 2001 data as if it were June 2011. You can visualize the data from both layers simultaneously even though the data belonged to different time periods.

//Layer using the service that contains the ice sheet data from 2001
AGSDynamicMapServiceLayer* june2001Layer = ...;

AGSLayerTimeOptions* op = [[[AGSLayerTimeOptions alloc] init] autorelease];
op.layerId = 1; //ID of the sub-layer containing the actual data
op.timeOffset = 10;
op.timeOffsetUnits = AGSTimeIntervalUnitsYears;

NSMutableArray* options = [[[NSMutableArray alloc] init] autorelease];
[options addObject:op];

//Set the layer time options
june2001Layer.layerTimeOptions = options;
//Tell the layer some properties were changed
[june2001Layer dataChanged]

Cumulative time

As described earlier, you can use a time extent containing only an ending time to display temporal data cumulatively to the ending point of the time extent. However, there may be cases when you have more than one time-aware layer in the map, but you only want to display temporal data cumulatively for some of them. In such cases, it wouldn't be feasible to use a cumulative time extent with the map as it forces all time-aware layers to display data cumulatively.

To handle such cases, modify the time options of individual layers to always display temporal data cumulatively. This allows you to use time extents that have well defined starting and ending points, but the chosen layers still display temporal data cumulatively to and including the specified time extent.

AGSLayerTimeOptions* op = [[[AGSLayerTimeOptions alloc] init] autorelease];
op.layerId = 1; //ID of the sub-layer containing the actual data
op.timeDataCumulative = TRUE;

Disable time

You can also temporarily exclude time-aware layers from honoring the map's time extent by disabling their time option. These layers will then behave as if they were not time aware and display all their data.

AGSLayerTimeOptions* op = [[[AGSLayerTimeOptions alloc] init] autorelease];
op.layerId = 1; //ID of the sub-layer containing the actual data
op.useTime = FALSE;

Create NSDate objects

When querying or viewing with temporal data, you will often have to create NSDate objects to specify a time extent. When you create NSDate objects, they use the time zone of the application by default. On a computer, the time zone can be set manually, through Settings or automatically, when connected to a network. If the time zone used by the application is different from the time zone used by the service's data, this can result in errors.

To illustrate this situation, suppose that a service contained temporal data tracking the historic progression of hurricanes on an hourly basis. Also suppose that the data is stored in GMT. You want to display the location of active hurricanes at a particular time, for example, 1 Jan 2000, 12:00 a.m. (GMT); therefore, you create AGSTimeExtent with the corresponding NSDate objects.

//Covert from string to data using formatter
NSDateFormatter* inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:@"M/d/yyyy h:mm a"];

//You want 12 AM GMT, but this will return 12 AM in the application's time zone
NSDate* date = [inputFormatter dateFromString:@"1/1/2001 12:00 AM"];

AGSTimeExtent* extent = [[AGSTimeExtent alloc] initWithStart:date end:date];

If the application was using a different time zone by default, for example, Pacific Standard Time, you would actually end up with NSDate representing 1 Jan 2000, 12:00 a.m. (PST) instead of 12:00 a.m. (GMT). As a result, the layer displays active hurricanes for 1 Jan 2000, 12:00 a.m. (PST), which is equivalent to 1 Jan 2000, 8:00 a.m. (GMT), even though you originally set out display features of 12:00 a.m. (GMT).

To solve this, specify a time zone for the time values you use. The OS X platform automatically adjusts the time values, if needed, to create an equivalent NSDate object using your application's default time zone. The following example specifies a value of 12:00 a.m. and indicates the value belongs to GMT :

NSDateFormatter* inputFormatter = [[NSDateFormatter alloc] init];
[inputFormatter setDateFormat:@"M/d/yyyy h:mm a"];

//specify the time zone that the value belongs to
[inputFormatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];

NSDate* date = [inputFormatter dateFromString:@"1/1/2001 12:00 AM"];