Repository: movingpandas/movingpandas

Issue:
Improve docstring formatting
Try to have a proper list or at least add a full stop, e.g. https://movingpandas.readthedocs.io/en/main/trajectory.html#movingpandas.Trajectory.add_distance 
![image](https://github.com/movingpandas/movingpandas/assets/590385/2471c7c6-efa8-46e0-8df6-792613e02f17)

Discussion:
codecov-commenter: ## [Codecov](https://app.codecov.io/gh/movingpandas/movingpandas/pull/356?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) Report
All modified and coverable lines are covered by tests :white_check_mark:

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

| [Files](https://app.codecov.io/gh/movingpandas/movingpandas/pull/356?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None) | Coverage Δ | |
|---|---|---|
| [movingpandas/tests/test\_trajectory\_collection.py](https://app.codecov.io/gh/movingpandas/movingpandas/pull/356?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-bW92aW5ncGFuZGFzL3Rlc3RzL3Rlc3RfdHJhamVjdG9yeV9jb2xsZWN0aW9uLnB5) | `94.73% <100.00%> (-5.27%)` | :arrow_down: |
| [movingpandas/trajectory.py](https://app.codecov.io/gh/movingpandas/movingpandas/pull/356?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-bW92aW5ncGFuZGFzL3RyYWplY3RvcnkucHk=) | `88.05% <ø> (-0.94%)` | :arrow_down: |
| [movingpandas/trajectory\_collection.py](https://app.codecov.io/gh/movingpandas/movingpandas/pull/356?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None#diff-bW92aW5ncGFuZGFzL3RyYWplY3RvcnlfY29sbGVjdGlvbi5weQ==) | `87.37% <100.00%> (+0.87%)` | :arrow_up: |

... and [5 files with indirect coverage changes](https://app.codecov.io/gh/movingpandas/movingpandas/pull/356/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None)


:loudspeaker: Thoughts on this report? [Let us know!](https://about.codecov.io/pull-request-comment-report/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=None).


Patch:
diff --git a/movingpandas/trajectory.py b/movingpandas/trajectory.py
index 9d2684f..52c5e2f 100644
--- a/movingpandas/trajectory.py
+++ b/movingpandas/trajectory.py
@@ -852,16 +852,17 @@ class Trajectory:
         Return the length of the trajectory.
 
         Length is calculated using CRS units, except if the CRS is geographic
-        (e.g. EPSG:4326 WGS84) then length is calculated in metres.
+        (e.g. EPSG:4326 WGS84) then length is calculated in meters.
 
         If units have been declared:
-            For geographic projections, in declared units
-            For known CRS units, in declared units
-            For unknown CRS units, in declared units as if CRS is in meters
+
+        - For geographic projections, in declared units
+        - For known CRS units, in declared units
+        - For unknown CRS units, in declared units as if CRS is in meters
 
         Parameters
         ----------
-        units : str
+        units : tuple(str)
             Units in which to calculate length values (default: CRS units)
             For more info, check the list of supported units at
             https://movingpandas.org/units
@@ -983,6 +984,8 @@ class Trajectory:
         ----------
         overwrite : bool
             Whether to overwrite existing direction values (default: False)
+        name : str
+            Name of the direction column (default: "direction")
         """
         self.direction_col_name = name
         if self.direction_col_name in self.df.columns and not overwrite:
@@ -1038,20 +1041,25 @@ class Trajectory:
         """
         Add distance column and values to the trajectory's DataFrame.
 
-        Adds a column with the distance to each point from the previous:
-            If no units have been declared:
-                For geographic projections (e.g. EPSG:4326 WGS84), in meters
-                For other projections, in CRS units
-            If units have been declared:
-                For geographic projections, in declared units
-                For known CRS units, in declared units
-                For unknown CRS units, in declared units as if CRS is in meters
+        Distance values are computed between the current point and the previous:
+
+        If no units have been declared:
+
+        - For geographic projections (e.g. EPSG:4326 WGS84), in meters
+        - For other projections, in CRS units
+
+        If units have been declared:
+
+        - For geographic projections, in declared units
+        - For known CRS units, in declared units
+        - For unknown CRS units, in declared units as if CRS is in meters
 
         Parameters
         ----------
         overwrite : bool
             Whether to overwrite existing distance values (default: False)
-
+        name : str
+            Name of the distance column (default: "distance")
         units : str
             Units in which to calculate distance values (default: CRS units)
             For more info, check the list of supported units at
@@ -1095,15 +1103,19 @@ class Trajectory:
         """
         Add speed column and values to the trajectory's DataFrame.
 
-        Adds a column with the speed to each point from the previous:
-             If no units have been declared:
-                 For geographic projections, in meters per second
-                 For other projections, in CRS units per second
-             If units have been declared:
-                 For geographic projections, in declared units
-                 For known CRS units, in declared units
-                 For unknown CRS units, in declared units as if CRS distance
-                 units are meters
+        Speed values are computed between the current point and the previous:
+
+        If no units have been declared:
+
+        - For geographic projections, in meters per second
+        - For other projections, in CRS units per second
+
+        If units have been declared:
+
+        - For geographic projections, in declared units
+        - For known CRS units, in declared units
+        - For unknown CRS units, in declared units as if CRS distance
+          units are meters
 
         Parameters
         ----------
@@ -1111,7 +1123,7 @@ class Trajectory:
             Whether to overwrite existing speed values (default: False)
         name : str
             Name of the speed column (default: "speed")
-        units : tuple
+        units : tuple(str)
             Units in which to calculate speed
 
             distance : str
@@ -1163,19 +1175,23 @@ class Trajectory:
         """
         Add acceleration column and values to the trajectory's DataFrame.
 
-        Adds a column with the acceleration to each point from the previous:
-             If no units have been declared:
-                 For geographic projections, in meters per second squared
-                 For other projections, in CRS units per second squared
-             If units have been declared:
-                 For geographic projections, using declared units
-                 For known CRS units, using declared units
-                 For unknown CRS units, using declared units as if CRS distance
-                 units are meters
-                 If only distance units are declared, returns
-                     distance per second squared
-                 If distance and one time unit declared, returns
-                     distance/time per second
+        Acceleration values are computed between the current point and the previous:
+
+        If no units have been declared:
+
+        - For geographic projections, in meters per second squared
+        - For other projections, in CRS units per second squared
+
+        If units have been declared:
+
+        - For geographic projections, using declared units
+        - For known CRS units, using declared units
+        - For unknown CRS units, using declared units as if CRS distance
+          units are meters
+        - If only distance units are declared, returns
+          distance per second squared
+        - If distance and one time unit declared, returns
+          distance/time per second
 
         Parameters
         ----------
@@ -1183,7 +1199,7 @@ class Trajectory:
             Whether to overwrite existing speed values (default: False)
         name : str
             Name of the acceleration column (default: "acceleration")
-        units : tuple
+        units : tuple(str)
             Units in which to calculate acceleration
 
             distance : str
@@ -1321,9 +1337,10 @@ class Trajectory:
         https://shapely.readthedocs.io/en/stable/manual.html#object.distance).
 
         If units have been declared:
-            For geographic projections, in declared units
-            For known CRS units, in declared units
-            For unknown CRS units, in declared units as if CRS is in meters
+
+        - For geographic projections, in declared units
+        - For known CRS units, in declared units
+        - For unknown CRS units, in declared units as if CRS is in meters
 
         Parameters
         ----------
@@ -1361,9 +1378,10 @@ class Trajectory:
         the other geometry.
 
         If units have been declared:
-            For geographic projections, in declared units
-            For known CRS units, in declared units
-            For unknown CRS units, in declared units as if CRS is in meters
+
+        - For geographic projections, in declared units
+        - For known CRS units, in declared units
+        - For unknown CRS units, in declared units as if CRS is in meters
 
         Parameters
         ----------
diff --git a/movingpandas/trajectory_collection.py b/movingpandas/trajectory_collection.py
index e895ba0..ee25425 100644
--- a/movingpandas/trajectory_collection.py
+++ b/movingpandas/trajectory_collection.py
@@ -3,7 +3,15 @@
 from pandas import concat
 from copy import copy
 from geopandas import GeoDataFrame
-from .trajectory import Trajectory, SPEED_COL_NAME, DIRECTION_COL_NAME
+from .trajectory import (
+    Trajectory,
+    SPEED_COL_NAME,
+    DIRECTION_COL_NAME,
+    DISTANCE_COL_NAME,
+    ACCELERATION_COL_NAME,
+    ANGULAR_DIFFERENCE_COL_NAME,
+    TIMEDELTA_COL_NAME,
+)
 from .trajectory_plotter import _TrajectoryPlotter
 from .unit_utils import UNITS
 
@@ -486,7 +494,7 @@ class TrajectoryCollection:
         overwrite : bool
             Whether to overwrite existing speed values (default: False)
 
-        units : tuple
+        units : tuple(str)
             Units in which to calculate speed
 
             distance : str
@@ -500,9 +508,9 @@ class TrajectoryCollection:
 
         """
         for traj in self:
-            traj.add_speed(overwrite, name, units)
+            traj.add_speed(overwrite=overwrite, name=name, units=units)
 
-    def add_direction(self, name=DIRECTION_COL_NAME, overwrite=False):
+    def add_direction(self, overwrite=False, name=DIRECTION_COL_NAME):
         """
         Add direction column and values to the trajectories.
 
@@ -515,11 +523,15 @@ class TrajectoryCollection:
             Whether to overwrite existing direction values (default: False)
         """
         for traj in self:
-            traj.add_direction(overwrite)
+            traj.add_direction(overwrite=overwrite, name=name)
 
-    def add_angular_difference(self, overwrite=False):
+    def add_angular_difference(
+        self,
+        overwrite=False,
+        name=ANGULAR_DIFFERENCE_COL_NAME,
+    ):
         """
-        Add angular difference to the trajectories.
+        Add angular difference to the trajectory's DataFrame.
 
         Angular difference is calculated as the absolute smaller angle
         between direction for points along the trajectory.
@@ -531,9 +543,11 @@ class TrajectoryCollection:
             Whether to overwrite existing angular difference values (default: False)
         """
         for traj in self:
-            traj.add_angular_difference(overwrite)
+            traj.add_angular_difference(overwrite=overwrite, name=name)
 
-    def add_acceleration(self, overwrite=False):
+    def add_acceleration(
+        self, overwrite=False, name=ACCELERATION_COL_NAME, units=UNITS()
+    ):
         """
         Add acceleration column and values to the trajectories.
 
@@ -545,9 +559,59 @@ class TrajectoryCollection:
         ----------
         overwrite : bool
             Whether to overwrite existing acceleration values (default: False)
+        name : str
+            Name of the acceleration column (default: "acceleration")
+        units : tuple(str)
+            Units in which to calculate acceleration
+
+            distance : str
+                Abbreviation for the distance unit
+                (default: CRS units, or metres if geographic)
+            time : str
+                Abbreviation for the time unit (default: seconds)
+            time2 : str
+                Abbreviation for the second time unit (default: seconds)
+
+            For more info, check the list of supported units at
+            https://movingpandas.org/units
+        """
+        for traj in self:
+            traj.add_acceleration(overwrite=overwrite, name=name, units=units)
+
+    def add_distance(self, overwrite=False, name=DISTANCE_COL_NAME, units=None):
+        """
+        Add distance column and values to the trajectories.
+
+        Parameters
+        ----------
+        overwrite : bool
+            Whether to overwrite existing distance values (default: False)
+        name : str
+            Name of the distance column (default: "distance")
+        units : str
+            Units in which to calculate distance values (default: CRS units)
+            For more info, check the list of supported units at
+            https://movingpandas.org/units
+        """
+        for traj in self:
+            traj.add_distance(overwrite=overwrite, name=name, units=units)
+
+    def add_timedelta(self, overwrite=False, name=TIMEDELTA_COL_NAME):
+        """
+        Add timedelta column and values to the trajectories.
+
+        Timedelta is calculated as the time difference between the current
+        and the previous row. Values are instances of datetime.timedelta.
+
+        Parameters
+        ----------
+        overwrite : bool
+            Whether to overwrite existing timedelta values (default: False)
+        name : str
+            Name of the timedelta column (default: "timedelta")
         """
         for traj in self:
-            traj.add_acceleration(overwrite)
+            traj.add_timedelta(overwrite=overwrite, name=name)
 
     def add_traj_id(self, overwrite=False):
         """


Test patch:
diff --git a/movingpandas/tests/test_trajectory_collection.py b/movingpandas/tests/test_trajectory_collection.py
index a5e718c..0f554e5 100644
--- a/movingpandas/tests/test_trajectory_collection.py
+++ b/movingpandas/tests/test_trajectory_collection.py
@@ -12,7 +12,15 @@ from pandas import Timestamp
 from pandas.testing import assert_frame_equal
 from shapely.geometry import LineString, Point, Polygon
 
-from movingpandas.trajectory import TRAJ_ID_COL_NAME
+from movingpandas.trajectory import (
+    TRAJ_ID_COL_NAME,
+    SPEED_COL_NAME,
+    DIRECTION_COL_NAME,
+    DISTANCE_COL_NAME,
+    ACCELERATION_COL_NAME,
+    ANGULAR_DIFFERENCE_COL_NAME,
+    TIMEDELTA_COL_NAME,
+)
 from movingpandas.trajectory_collection import TrajectoryCollection
 from . import requires_holoviews
 
@@ -265,6 +273,38 @@ class TestTrajectoryCollection:
         with pytest.raises(RuntimeError):
             collection.add_traj_id()
 
+    def test_add_speed(self):
+        self.collection.add_speed()
+        result1 = self.collection.trajectories[0].df[SPEED_COL_NAME].tolist()
+        assert len(result1) == 4
+
+    def test_add_acceleration(self):
+        self.collection.add_acceleration()
+        result1 = self.collection.trajectories[0].df[ACCELERATION_COL_NAME].tolist()
+        assert len(result1) == 4
+
+    def test_add_direction(self):
+        self.collection.add_direction()
+        result1 = self.collection.trajectories[0].df[DIRECTION_COL_NAME].tolist()
+        assert len(result1) == 4
+
+    def test_add_distance(self):
+        self.collection.add_distance()
+        result1 = self.collection.trajectories[0].df[DISTANCE_COL_NAME].tolist()
+        assert len(result1) == 4
+
+    def test_add_angular_difference(self):
+        self.collection.add_angular_difference()
+        result1 = (
+            self.collection.trajectories[0].df[ANGULAR_DIFFERENCE_COL_NAME].tolist()
+        )
+        assert len(result1) == 4
+
+    def test_add_timedelta(self):
+        self.collection.add_timedelta()
+        result1 = self.collection.trajectories[0].df[TIMEDELTA_COL_NAME].tolist()
+        assert len(result1) == 4
+
     def test_to_point_gdf(self):
         point_gdf = self.collection.to_point_gdf()
         point_gdf.to_file("temp.gpkg", layer="points", driver="GPKG")