Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions folium/plugins/timestamped_geo_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ class TimestampedGeoJson(JSCSSMixin, MacroElement):
Used to construct the array of available times starting
from the first available time. Format: ISO8601 Duration
ex: 'P1M' 1/month, 'P1D' 1/day, 'PT1H' 1/hour, and 'PT1M' 1/minute
show_path: bool, default True
Whether to draw animated LineString paths. Set to False to animate
only the last-point markers when add_last_point=True. The source paths
are still used to determine timestamps and marker positions.
duration: str, default None
Period of time which the features will be shown on the map after their
time has passed. If None, all previous times will be shown.
Expand Down Expand Up @@ -131,6 +135,14 @@ class TimestampedGeoJson(JSCSSMixin, MacroElement):
}
})

{% if not this.show_path %}
// Keep full source features for time indexing, but skip recreating
// their polylines in the animated frame layers.
geoJsonLayer.options.filter = function (feature) {
return feature.geometry.type !== "LineString";
};
{% endif %}

var {{this.get_name()}} = L.timeDimension.layer.geoJson(
geoJsonLayer,
{
Expand Down Expand Up @@ -191,6 +203,7 @@ def __init__(
time_slider_drag_update=False,
duration=None,
speed_slider=True,
show_path=True,
):
super().__init__()
self._name = "TimestampedGeoJson"
Expand All @@ -205,6 +218,7 @@ def __init__(
self.embed = False
self.data = data
self.add_last_point = bool(add_last_point)
self.show_path = bool(show_path)
self.period = period
self.date_options = date_options
self.duration = "undefined" if duration is None else '"' + duration + '"'
Expand Down
41 changes: 41 additions & 0 deletions tests/plugins/test_timestamped_geo_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,44 @@ def test_timestamped_geo_json():

bounds = m.get_bounds()
assert bounds == [[-53.0, -158.0], [50.0, 158.0]], bounds


def test_timestamped_geo_json_can_animate_markers_without_paths():
data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {"type": "LineString", "coordinates": [[1, 2], [3, 4]]},
"properties": {
"times": [1435708800000, 1435795200000],
"icon": "marker",
},
}
],
}

map_with_paths = folium.Map(location=[2, 1])
plugins.TimestampedGeoJson(data).add_to(map_with_paths)
original = map_with_paths.get_root().render()
assert "geoJsonLayer.options.filter" not in original

map_with_markers = folium.Map(location=[2, 1])
plugin = plugins.TimestampedGeoJson(
data,
show_path=False,
add_last_point=True,
).add_to(map_with_markers)
html = map_with_markers.get_root().render()

# Initial GeoJSON must receive every LineString so it can index all times.
# The frame-layer filter is installed only afterwards, and suppresses
# creating a polyline while allowing the generated last-point marker.
initial_layer = html.index("var geoJsonLayer = L.geoJson(")
frame_filter = html.index("geoJsonLayer.options.filter = function")
animated_layer = html.index("L.timeDimension.layer.geoJson(")
assert initial_layer < frame_filter < animated_layer
assert 'feature.geometry.type !== "LineString"' in html
assert "addlastPoint: true" in html
assert '"coordinates": [[1, 2], [3, 4]]' in html
assert plugin.show_path is False