# Calculate motion statistics

Calculate Motion Statistics calculates movement statistics and descriptors for time-enabled points that represent one or more moving entities. The input DataFrame must be point geometries with an instant timestamp.

## Usage notes

TermDescription
GeodesicA line drawn on a sphere. A geodesic line drawn on the globe represents the curvature of the earth's geoid.
PlanarA straight-line distance as measured on a flat surface (that is, a Cartesian plane). This is also referred to as Euclidean distance.
InstantA single moment in time represented by a start time and no end time.
SegmentThe path between two sequential observations in a track.
TrackA sequence of point observations that are time enabled with time type instant. Rows are determined to be in the sequence by a track identifier field and are ordered by time. For example, a city can have a fleet of snow plow trucks that record their location every 10 minutes. The vehicle ID can represent the distinct tracks.
• Specify one or more fields to identify unique entities, also known as tracks. Tracks are represented by the unique combination of one or more track fields. For example, if the `flightID` and `Destination` fields are used as track identifiers, the records `ID007`, `Solden` and `ID007`, `Tokyo` would be in different tracks since they have different values for the `Destination` field.

• By default, all supported statistics will be calculated for each input point if possible. Alternatively, you can choose one or more groups of statistics to calculate using `setMotionStatistics()`.

• Minimum, maximum, average and total statistics are calculated using the current observation and a number of previous observations defined by `setTrackHistoryWindow()`. Other statistics are always calculated using only the current and previous observation and do not consider the track history window value. For example, if you set a track history window value of 5 and specify Speed as the value for `setMotionStatistics()`, the current observation and the previous four observations will be used to calculate MinSpeed, MaxSpeed, and AvgSpeed fields at each observation, while the Speed field will be calculated using only the current and previous observations at each point. The value specified for `setTrackHistoryWindow()` must be greater than 1. The default is 3.

• If there are fewer observations in a track's history than the value specified using `setTrackHistoryWindow()`, statistics starting with `Min`, `Max`, `Avg`, or `Tot` will be calculated using all observations in the track history.

• Statistics will not be calculated for the first record in each track. Statistics in the acceleration group will not be calculated for the first two records in each track.

• The result values will be in the units specified using `setStatisticUnits()`.

• When calculating statistics on large tracks, you can use `setTimeBoundarySplit()` to split the large tracks into smaller tracks to improve performance.

• See the Results section below for a list of the calculated statistic fields.

## Limitations

• The input DataFrame must be points that have a timestamp representing an instant in time. Any records that do not have time or geometry are not included in the result.

## Results

The result of Calculate Motion Statistics is a copy of the input DataFrame with a new field for each calculated statistic.

The following statistic fields will be calculated for the distance group:

FieldDescription
`Distance`Distance traveled from the previous observation to the current.
`TotDistance`Sum of distances traveled between observations in the track history window.
`MinDistance`Minimum of distances traveled between observations in the track history window.
`MaxDistance`Maximum of distances traveled between observations in the track history window.

The following statistic fields will be calculated for the speed group:

FieldDescription
`Speed`Speed of travel from the previous observation to the current.
`MinSpeed`Minimum speed between observations in the track history window.
`MaxSpeed`Maximum speed between observations in the track history window.
`AvgSpeed`The sum of distances between observations in the track history window divided by the sum of durations between observations in the track history window.

The following statistics fields will be calculated for the acceleration group:

FieldDescription
`Acceleration`The difference between the current speed and previous speed divided by the current duration.
`MinAcceleration`Minimum acceleration calculated in the track history window.
`MaxAcceleration`Maximum acceleration calculated in the track history window.
`AvgAcceleration`The difference between the current and first speeds in the track history window divided by the sum of durations between observations in the track history window.

The following statistic fields will be calculated for the duration group:

FieldDescription
`Duration`The elapsed time since the previous observation.
`TotDuration`Sum of durations in the track history window.
`MinDuration`Minimum duration in the track history window.
`MaxDuration`Maximum duration in the track history window.
`AvgDuration`Sum of durations in the track history window divided by the number of points.

The following statistics fields will be calculated for the elevation group:

FieldDescription
`Elevation`Current elevation of the observation.
`ElevChange`Difference between the current and the previous elevation.
`TotElevChange`Sum of elevation changes between the points in the track history window. This can be a negative value.
`MinElevation`Minimum elevation in the track history window.
`MaxElevation`Maximum elevation in the track history window.
`AvgElevation`Sum of elevations in the track history window divided by the number of points.

The following statistics fields will be calculated for the slope group:

FieldDescription
`Slope`Ratio of elevation change to distance between the current and previous observations.
`MinSlope`Minimum slope in the track history window.
`MaxSlope`Maximum slope in the track history window.
`AvgSlope`Sum of slopes in the track history window divided by the number of points.

The following statistics fields will be calculated for the idle group:

FieldDescription
`Idling`Returns `true` if the distance between the current observation and the previous is less than the `distance_tolerance` value specified using `setIdleTolerance()`, and the duration between the current observation and the previous is at least the `time_tolerance` value specified using `setIdleTolerance()`. Returns `false` if one or both of those conditions are not met.
`TotIdleTime`Sum of duration in the track history window that meet idling criteria.
`PctIdleTime`Percentage of time for which idling was detected.

The following statistics field will be calculated for the bearing group:

FieldDescription
`Bearing`Angle of travel from the previous observation to the current observation.

## Performance notes

Improve the performance of Calculate Motion Statistics by doing one or more of the following:

• Only analyze the records in your area of interest. You can pick the records of interest by using one of the following SQL functions:

• ST_Intersection—Clip to an area of interest represented by a polygon. This will modify your input records.
• ST_BboxIntersects—Select records that intersect an envelope.
• ST_EnvIntersects—Select records having an evelope that intersects the envelope of another geometry.
• ST_Intersects—Select records that intersect another dataset or area of intersect represented by a polygon.
• Decrease the track history window size using `setTrackHistoryWindow()`.
• Specify a value for `setTimeBoundarySplit()` to break up large tracks at a defined time interval.

## Similar capabilities

The following tools perform similar capabilities:

## How Calculate Motion Statistics works

The diagram below shows a track with six sequential points. The statistics are calculated based on each row's elevation, distance, and time.

The following table summarizes the statistics calculations for the diagram above. All calculations are evaluated at point 5 and the track history window is 3. An observation is considered idling if it has moved less than 32 meters in 1 minute.

StatisticsFormulaExample
Distance35 m
Total Distance80 + 30 + 35 = 145 m
SpeedDistance / Duration35 / 60 = 0.58 m/s
Average SpeedTotal Distance / Total Duration145 / 180 m/s
Acceleration(0.58 -- 0.5) / 60 = 0.001 m/s2
Average Acceleration(Speed(last) - Speed(first)) / (Total Duration)(0.58 -- 1.33) / 60 = -0.01 m/s2
Duration60s
Total Duration60 + 60 + 60 = 180 s
Elevation5 m
Elevation Change5 - 4 = 1 m
Total Elevation Change5 - 0 = 5 m
SlopeElevation Change /Distance1 / 35
Average SlopeTotal Elevation Change/ Total Distance5 / 145
IdlingFalse
Total Idle Time60 s
Percentage Idle Time.5
Bearing0

## Syntax

For more details, go to the GeoAnalytics Engine API reference for calculate motion statistics.

SetterDescriptionRequired
`run(dataframe)`Runs the Calculate Motion Statistics tool using the provided DataFrame.Yes
`setDistanceMethod(distance_method)`Sets the method used to calculate distances between track observations. There are two methods to choose from: `'Planar'` or `'Geodesic'` (default).No
`setIdleTolerance(distance_tolerance, distance_tolerance_unit, time_tolerance, time_tolerance_unit)`Sets the tolerances to use to decide if an entity is idling. An entity is idling when it hasn’t moved more than the distance tolerance in at least the time tolerance.Yes, if idle statistics are calculated.
`setMotionStatistics(*motion_statistics)`Sets the statistic groups that will be calculated. By default all statistics will be calculated.No
`setStatisticUnits(distance_unit='Meters', duration_unit='Seconds', speed_unit='MetersPerSecond', acceleration_unit='MetersPerSecondSquared', elevation_unit='Meters')`Sets the output units for each statistic group.No
`setTimeBoundarySplit(time_boundary_split, time_boundary_split_unit, time_boundary_reference=None)`Sets boundaries to limit calculations to defined spans of time.No
`setTrackFields(*track_fields)`Sets one or more fields used to identify distinct tracks.Yes
`setTrackHistoryWindow(track_history_window)`Sets the number of observations (including the current observation) that will be used when calculating summary statistics that are not instantaneous. This includes minimum, maximum, average, and total statistics. The default is 3.No

## Examples

### Run Calculate Motion Statistics

Python
Use dark colors for code blocksCopy
``````# Log in
import geoanalytics

# Imports
from geoanalytics.tools import CalculateMotionStatistics
from geoanalytics.sql import functions as ST

# Path to the Seattle example tracks data
data_path = r"https://services1.arcgis.com/36PP9fe9l4BSnArw/arcgis/rest" \
"/services/seattle_example_tracks/FeatureServer/0"

# Create a DataFrame from the Seattle example tracks data

# Calculate Motion Statistics to enhance your data with speed and idling statistics
result = CalculateMotionStatistics() \
.setTrackFields("user_id") \
.setTrackHistoryWindow(track_history_window=5) \
.setMotionStatistics("Speed", "idle") \
.setIdleTolerance(distance_tolerance=100,
distance_tolerance_unit="Feet",
time_tolerance=5,
time_tolerance_unit="Minutes") \
.setDistanceMethod(distance_method="Planar") \
.setStatisticUnits(speed_unit="FeetPerSecond") \
.run(dataframe=df)

# Show a selection of columns for the first 5 records in the result DataFrame
result.filter(result["user_id"] == 'user1') \
.select("user_id", "Speed", "MinSpeed", "MaxSpeed","AvgSpeed", "Idling", "TotIdleTime") \
.sort("AvgSpeed", ascending=False) \
.show(5)
``````
Result
Use dark colors for code blocksCopy
``````+-------+------------------+------------------+-----------------+------------------+------+-----------+
|user_id|             Speed|          MinSpeed|         MaxSpeed|          AvgSpeed|Idling|TotIdleTime|
+-------+------------------+------------------+-----------------+------------------+------+-----------+
|  user1|5.2204847202976685|5.2204847202976685|6.892290697309563|5.7618999711114105| false|        0.0|
|  user1| 5.526445079215372| 5.164426033535724|6.892290697309563|5.7478852994209255| false|        0.0|
|  user1| 6.278522175413303| 4.358639317727936|6.452378996093401| 5.644197059655965| false|        0.0|
|  user1| 5.408379387623038| 4.638848823449657|6.892290697309563| 5.525986235479496| false|        0.0|
|  user1| 4.575716510069646| 4.451734493505993|6.881149550040065|  5.47720959430053| false|        0.0|
+-------+------------------+------------------+-----------------+------------------+------+-----------+
only showing top 5 rows``````

### Plotting results

Python
Use dark colors for code blocksCopy
``````# Plot the enhanced results and show the average speed of user6
result_plot = result.where("user_id = 'user6'").st.plot(cmap_values="AvgSpeed",
cmap="plasma",
legend=True,
figsize=(14,8),
aspect="auto",
basemap="light")
result_plot.set_title("Average speed in feet per second for user6")
result_plot.set_xlabel("X (US Survey Feet)")
result_plot.set_ylabel("Y (US Survey Feet)");``````

ReleaseNotes

1.0.0

Tool introduced