Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into fix-test-issues
Browse files Browse the repository at this point in the history
  • Loading branch information
Conengmo committed Oct 19, 2024
2 parents 6343237 + d9e1e9a commit 70a01c0
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 17 deletions.
49 changes: 42 additions & 7 deletions folium/plugins/draw.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@


class Draw(JSCSSMixin, MacroElement):
"""
'''
Vector drawing and editing plugin for Leaflet.
Parameters
----------
export : bool, default False
Add a small button that exports the drawn shapes as a geojson file.
feature_group : FeatureGroup, optional
The FeatureGroup object that will hold the editable figures. This can
be used to initialize the Draw plugin with predefined Layer objects.
filename : string, default 'data.geojson'
Name of geojson file
position : {'topleft', 'toprigth', 'bottomleft', 'bottomright'}
Expand All @@ -25,22 +28,35 @@ class Draw(JSCSSMixin, MacroElement):
edit_options : dict, optional
The options used to configure the edit toolbar. See
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html#editpolyoptions
on : dict, optional
Event handlers to attach to the created layer. Pass a mapping from the
names of the events to their `JsCode` handlers.
Examples
--------
>>> m = folium.Map()
>>> Draw(
... export=True,
... filename="my_data.geojson",
... show_geometry_on_click=False,
... position="topleft",
... draw_options={"polyline": {"allowIntersection": False}},
... edit_options={"poly": {"allowIntersection": False}},
... on={
... "click": JsCode(
... """
... function(event) {
... alert(JSON.stringify(this.toGeoJSON()));
... }
... """
... )
... },
... ).add_to(m)
For more info please check
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html
"""
'''

_template = Template(
"""
Expand All @@ -50,10 +66,17 @@ class Draw(JSCSSMixin, MacroElement):
draw: {{ this.draw_options|tojson }},
edit: {{ this.edit_options|tojson }},
}
// FeatureGroup is to store editable layers.
var drawnItems_{{ this.get_name() }} = new L.featureGroup().addTo(
{{ this._parent.get_name() }}
);
{%- if this.feature_group %}
var drawnItems_{{ this.get_name() }} =
{{ this.feature_group.get_name() }};
{%- else %}
// FeatureGroup is to store editable layers.
var drawnItems_{{ this.get_name() }} =
new L.featureGroup().addTo(
{{ this._parent.get_name() }}
);
{%- endif %}
options.edit.featureGroup = drawnItems_{{ this.get_name() }};
var {{ this.get_name() }} = new L.Control.Draw(
options
Expand All @@ -68,11 +91,19 @@ class Draw(JSCSSMixin, MacroElement):
console.log(coords);
});
{%- endif %}
{%- for event, handler in this.on.items() %}
layer.on(
"{{event}}",
{{handler}}
);
{%- endfor %}
drawnItems_{{ this.get_name() }}.addLayer(layer);
});
});
{{ this._parent.get_name() }}.on('draw:created', function(e) {
drawnItems_{{ this.get_name() }}.addLayer(e.layer);
});
{% if this.export %}
document.getElementById('export').onclick = function(e) {
var data = drawnItems_{{ this.get_name() }}.toGeoJSON();
Expand Down Expand Up @@ -106,20 +137,24 @@ class Draw(JSCSSMixin, MacroElement):
def __init__(
self,
export=False,
feature_group=None,
filename="data.geojson",
position="topleft",
show_geometry_on_click=True,
draw_options=None,
edit_options=None,
on=None,
):
super().__init__()
self._name = "DrawControl"
self.export = export
self.feature_group = feature_group
self.filename = filename
self.position = position
self.show_geometry_on_click = show_geometry_on_click
self.draw_options = draw_options or {}
self.edit_options = edit_options or {}
self.on = on or {}

def render(self, **kwargs):
super().render(**kwargs)
Expand Down
4 changes: 2 additions & 2 deletions folium/plugins/heat_map_withtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class HeatMapWithTime(JSCSSMixin, Layer):
speedStep: {{this.speed_step}},
styleNS: "{{this.style_NS}}",
timeSlider: {{this.time_slider}},
timeSliderDrapUpdate: {{this.time_slider_drap_update}},
timeSliderDragUpdate: {{this.time_slider_drag_update}},
timeSteps: {{this.index_steps}}
})
.addTo({{this._parent.get_name()}});
Expand Down Expand Up @@ -199,7 +199,7 @@ def __init__(
self.time_slider = "true"
self.play_button = "true"
self.play_reverse_button = "true"
self.time_slider_drap_update = "false"
self.time_slider_drag_update = "false"
self.style_NS = "leaflet-control-timecontrol"

def render(self, **kwargs):
Expand Down
28 changes: 21 additions & 7 deletions folium/plugins/time_slider_choropleth.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class TimeSliderChoropleth(JSCSSMixin, Layer):
styledict: dict
A dictionary where the keys are the geojson feature ids and the values are
dicts of `{time: style_options_dict}`
date_options: str, default "ddd MMM DD YYYY"
A format string to render the currently active time in the control.
highlight: bool, default False
Whether to show a visual effect on mouse hover and click.
name : string, default None
Expand All @@ -44,6 +46,11 @@ class TimeSliderChoropleth(JSCSSMixin, Layer):
let styledict = {{ this.styledict|tojson }};
let current_timestamp = timestamps[{{ this.init_timestamp }}];
function formatDate(date) {
var newdate = new moment(date);
return newdate.format({{this.date_format|tojson}});
}
let slider_body = d3.select("body").insert("div", "div.folium-map")
.attr("id", "slider_{{ this.get_name() }}");
$("#slider_{{ this.get_name() }}").hide();
Expand All @@ -64,7 +71,7 @@ class TimeSliderChoropleth(JSCSSMixin, Layer):
.attr("step", "1")
.style('align', 'center');
let datestring = new Date(parseInt(current_timestamp)*1000).toDateString();
let datestring = formatDate(parseInt(current_timestamp)*1000);
d3.select("#slider_{{ this.get_name() }} > output").text(datestring);
let fill_map = function(){
Expand All @@ -84,7 +91,7 @@ class TimeSliderChoropleth(JSCSSMixin, Layer):
d3.select("#slider_{{ this.get_name() }} > input").on("input", function() {
current_timestamp = timestamps[this.value];
var datestring = new Date(parseInt(current_timestamp)*1000).toDateString();
let datestring = formatDate(parseInt(current_timestamp)*1000);
d3.select("#slider_{{ this.get_name() }} > output").text(datestring);
fill_map();
});
Expand Down Expand Up @@ -155,12 +162,19 @@ class TimeSliderChoropleth(JSCSSMixin, Layer):
"""
)

default_js = [("d3v4", "https://d3js.org/d3.v4.min.js")]
default_js = [
("d3v4", "https://d3js.org/d3.v4.min.js"),
(
"moment",
"https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js",
),
]

def __init__(
self,
data,
styledict,
date_options: str = "ddd MMM DD YYYY",
highlight: bool = False,
name=None,
overlay=True,
Expand All @@ -173,21 +187,21 @@ def __init__(
):
super().__init__(name=name, overlay=overlay, control=control, show=show)
self.data = GeoJson.process_data(GeoJson({}), data)
self.date_format = date_options
self.highlight = highlight

self.stroke_opacity = stroke_opacity
self.stroke_width = stroke_width
self.stroke_color = stroke_color

if not isinstance(styledict, dict):
raise ValueError(
f"styledict must be a dictionary, got {styledict!r}"
) # noqa
raise ValueError(f"styledict must be a dictionary, got {styledict!r}")

for val in styledict.values():
if not isinstance(val, dict):
raise ValueError(
f"Each item in styledict must be a dictionary, got {val!r}"
) # noqa
)

# Make set of timestamps.
timestamps_set = set()
Expand Down
2 changes: 1 addition & 1 deletion tests/plugins/test_heat_map_withtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def test_heat_map_with_time():
speedStep: {{this.speed_step}},
styleNS: "{{this.style_NS}}",
timeSlider: {{this.time_slider}},
timeSliderDrapUpdate: {{this.time_slider_drap_update}},
timeSliderDragUpdate: {{this.time_slider_drag_update}},
timeSteps: {{this.index_steps}}
})
.addTo({{this._parent.get_name()}});
Expand Down

0 comments on commit 70a01c0

Please sign in to comment.