Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

- Update leaflet to 1.3.4 (ocefpaf #939)
- More options (tms, opacity, kwargs) in TileLayer (mpickering #948)
- Add MousePosition plugin (btozer #916)


0.6.0
Expand Down
99 changes: 99 additions & 0 deletions examples/plugin-MousePosition.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import folium\n",
"from folium.plugins import MousePosition"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgPHN0eWxlPiNtYXBfNDg5ODFhZDE1Njk4NDc0ZmFiNDIwMWFiODI5MWE3MDAgewogICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgICB3aWR0aDogMTAwLjAlOwogICAgICAgIGhlaWdodDogMTAwLjAlOwogICAgICAgIGxlZnQ6IDAuMCU7CiAgICAgICAgdG9wOiAwLjAlOwogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG4ucmF3Z2l0LmNvbS9hcmRoaS9MZWFmbGV0Lk1vdXNlUG9zaXRpb24vYzMyZjFjODQvc3JjL0wuQ29udHJvbC5Nb3VzZVBvc2l0aW9uLmpzIj48L3NjcmlwdD4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9jZG4ucmF3Z2l0LmNvbS9hcmRoaS9MZWFmbGV0Lk1vdXNlUG9zaXRpb24vYzMyZjFjODQvc3JjL0wuQ29udHJvbC5Nb3VzZVBvc2l0aW9uLmNzcyIvPgo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgPGRpdiBjbGFzcz0iZm9saXVtLW1hcCIgaWQ9Im1hcF80ODk4MWFkMTU2OTg0NzRmYWI0MjAxYWI4MjkxYTcwMCIgPjwvZGl2Pgo8L2JvZHk+CjxzY3JpcHQ+ICAgIAogICAgCiAgICAKICAgICAgICB2YXIgYm91bmRzID0gbnVsbDsKICAgIAoKICAgIHZhciBtYXBfNDg5ODFhZDE1Njk4NDc0ZmFiNDIwMWFiODI5MWE3MDAgPSBMLm1hcCgKICAgICAgICAnbWFwXzQ4OTgxYWQxNTY5ODQ3NGZhYjQyMDFhYjgyOTFhNzAwJywgewogICAgICAgIGNlbnRlcjogWzAsIDBdLAogICAgICAgIHpvb206IDEsCiAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgbGF5ZXJzOiBbXSwKICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICBjcnM6IEwuQ1JTLkVQU0czODU3LAogICAgICAgIHpvb21Db250cm9sOiB0cnVlLAogICAgICAgIH0pOwoKICAgIAogICAgCiAgICB2YXIgdGlsZV9sYXllcl81YTgyY2U1ZWI4OWU0NjNkYjI1N2JhZmU4MjZjNzA2ZCA9IEwudGlsZUxheWVyKAogICAgICAgICdodHRwczovL3tzfS50aWxlLm9wZW5zdHJlZXRtYXAub3JnL3t6fS97eH0ve3l9LnBuZycsCiAgICAgICAgewogICAgICAgICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgICAgICAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICAgICAgICJtYXhOYXRpdmVab29tIjogMTgsCiAgICAgICAgIm1heFpvb20iOiAxOCwKICAgICAgICAibWluWm9vbSI6IDAsCiAgICAgICAgIm5vV3JhcCI6IGZhbHNlLAogICAgICAgICJzdWJkb21haW5zIjogImFiYyIKfSkuYWRkVG8obWFwXzQ4OTgxYWQxNTY5ODQ3NGZhYjQyMDFhYjgyOTFhNzAwKTsKICAgIAoKICAgICAgICB2YXIgbW91c2VfcG9zaXRpb25fNTBhZDM4ODcxMmU5NGJkMGEwOTdjYzk0MzI2Zjg5OGIgPSBuZXcgTC5Db250cm9sLk1vdXNlUG9zaXRpb24oCiAgICAgICAgICAgIHsKICAiZW1wdHlTdHJpbmciOiAiVW5hdmFpbGFibGUiLAogICJsbmdGaXJzdCI6IGZhbHNlLAogICJudW1EaWdpdHMiOiA1LAogICJwb3NpdGlvbiI6ICJib3R0b21yaWdodCIsCiAgInByZWZpeCI6ICIiLAogICJzZXBhcmF0b3IiOiAiIDogIgp9KTsKICAgICAgICBtb3VzZV9wb3NpdGlvbl81MGFkMzg4NzEyZTk0YmQwYTA5N2NjOTQzMjZmODk4Yi5vcHRpb25zWyJsYXRGb3JtYXR0ZXIiXSA9IHVuZGVmaW5lZDsKICAgICAgICBtb3VzZV9wb3NpdGlvbl81MGFkMzg4NzEyZTk0YmQwYTA5N2NjOTQzMjZmODk4Yi5vcHRpb25zWyJsbmdGb3JtYXR0ZXIiXSA9IHVuZGVmaW5lZDsKICAgICAgICBtYXBfNDg5ODFhZDE1Njk4NDc0ZmFiNDIwMWFiODI5MWE3MDAuYWRkQ29udHJvbChtb3VzZV9wb3NpdGlvbl81MGFkMzg4NzEyZTk0YmQwYTA5N2NjOTQzMjZmODk4Yik7CgogICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x1ae35394b70>"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Create a folium map\n",
"m = folium.Map()\n",
"\n",
"# Add a mouse position plugin with default parameters\n",
"m.add_child(MousePosition())"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div style=\"width:100%;\"><div style=\"position:relative;width:100%;height:0;padding-bottom:60%;\"><iframe src=\"data:text/html;charset=utf-8;base64,PCFET0NUWVBFIGh0bWw+CjxoZWFkPiAgICAKICAgIDxtZXRhIGh0dHAtZXF1aXY9ImNvbnRlbnQtdHlwZSIgY29udGVudD0idGV4dC9odG1sOyBjaGFyc2V0PVVURi04IiAvPgogICAgPHNjcmlwdD5MX1BSRUZFUl9DQU5WQVM9ZmFsc2U7IExfTk9fVE9VQ0g9ZmFsc2U7IExfRElTQUJMRV8zRD1mYWxzZTs8L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmpzIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2FqYXguZ29vZ2xlYXBpcy5jb20vYWpheC9saWJzL2pxdWVyeS8xLjExLjEvanF1ZXJ5Lm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvanMvYm9vdHN0cmFwLm1pbi5qcyI+PC9zY3JpcHQ+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG5qcy5jbG91ZGZsYXJlLmNvbS9hamF4L2xpYnMvTGVhZmxldC5hd2Vzb21lLW1hcmtlcnMvMi4wLjIvbGVhZmxldC5hd2Vzb21lLW1hcmtlcnMuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2xlYWZsZXRAMS4yLjAvZGlzdC9sZWFmbGV0LmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL21heGNkbi5ib290c3RyYXBjZG4uY29tL2Jvb3RzdHJhcC8zLjIuMC9jc3MvYm9vdHN0cmFwLm1pbi5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9tYXhjZG4uYm9vdHN0cmFwY2RuLmNvbS9ib290c3RyYXAvMy4yLjAvY3NzL2Jvb3RzdHJhcC10aGVtZS5taW4uY3NzIi8+CiAgICA8bGluayByZWw9InN0eWxlc2hlZXQiIGhyZWY9Imh0dHBzOi8vbWF4Y2RuLmJvb3RzdHJhcGNkbi5jb20vZm9udC1hd2Vzb21lLzQuNi4zL2Nzcy9mb250LWF3ZXNvbWUubWluLmNzcyIvPgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJodHRwczovL2NkbmpzLmNsb3VkZmxhcmUuY29tL2FqYXgvbGlicy9MZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy8yLjAuMi9sZWFmbGV0LmF3ZXNvbWUtbWFya2Vycy5jc3MiLz4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9yYXdnaXQuY29tL3B5dGhvbi12aXN1YWxpemF0aW9uL2ZvbGl1bS9tYXN0ZXIvZm9saXVtL3RlbXBsYXRlcy9sZWFmbGV0LmF3ZXNvbWUucm90YXRlLmNzcyIvPgogICAgPHN0eWxlPmh0bWwsIGJvZHkge3dpZHRoOiAxMDAlO2hlaWdodDogMTAwJTttYXJnaW46IDA7cGFkZGluZzogMDt9PC9zdHlsZT4KICAgIDxzdHlsZT4jbWFwIHtwb3NpdGlvbjphYnNvbHV0ZTt0b3A6MDtib3R0b206MDtyaWdodDowO2xlZnQ6MDt9PC9zdHlsZT4KICAgIAogICAgPHN0eWxlPiNtYXBfOTNlZjlmMDA5MjM1NDc3OThjZmM3OTBiMDRhMjk3ODMgewogICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTsKICAgICAgICB3aWR0aDogMTAwLjAlOwogICAgICAgIGhlaWdodDogMTAwLjAlOwogICAgICAgIGxlZnQ6IDAuMCU7CiAgICAgICAgdG9wOiAwLjAlOwogICAgICAgIH0KICAgIDwvc3R5bGU+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG4ucmF3Z2l0LmNvbS9hcmRoaS9MZWFmbGV0Lk1vdXNlUG9zaXRpb24vYzMyZjFjODQvc3JjL0wuQ29udHJvbC5Nb3VzZVBvc2l0aW9uLmpzIj48L3NjcmlwdD4KICAgIDxsaW5rIHJlbD0ic3R5bGVzaGVldCIgaHJlZj0iaHR0cHM6Ly9jZG4ucmF3Z2l0LmNvbS9hcmRoaS9MZWFmbGV0Lk1vdXNlUG9zaXRpb24vYzMyZjFjODQvc3JjL0wuQ29udHJvbC5Nb3VzZVBvc2l0aW9uLmNzcyIvPgo8L2hlYWQ+Cjxib2R5PiAgICAKICAgIAogICAgPGRpdiBjbGFzcz0iZm9saXVtLW1hcCIgaWQ9Im1hcF85M2VmOWYwMDkyMzU0Nzc5OGNmYzc5MGIwNGEyOTc4MyIgPjwvZGl2Pgo8L2JvZHk+CjxzY3JpcHQ+ICAgIAogICAgCiAgICAKICAgICAgICB2YXIgYm91bmRzID0gbnVsbDsKICAgIAoKICAgIHZhciBtYXBfOTNlZjlmMDA5MjM1NDc3OThjZmM3OTBiMDRhMjk3ODMgPSBMLm1hcCgKICAgICAgICAnbWFwXzkzZWY5ZjAwOTIzNTQ3Nzk4Y2ZjNzkwYjA0YTI5NzgzJywgewogICAgICAgIGNlbnRlcjogWzAsIDBdLAogICAgICAgIHpvb206IDEsCiAgICAgICAgbWF4Qm91bmRzOiBib3VuZHMsCiAgICAgICAgbGF5ZXJzOiBbXSwKICAgICAgICB3b3JsZENvcHlKdW1wOiBmYWxzZSwKICAgICAgICBjcnM6IEwuQ1JTLkVQU0czODU3LAogICAgICAgIHpvb21Db250cm9sOiB0cnVlLAogICAgICAgIH0pOwoKICAgIAogICAgCiAgICB2YXIgdGlsZV9sYXllcl9mZmY1Y2ExNDU0NWQ0OTBkOTJiYWEyNTFmY2FiN2E2YSA9IEwudGlsZUxheWVyKAogICAgICAgICdodHRwczovL3tzfS50aWxlLm9wZW5zdHJlZXRtYXAub3JnL3t6fS97eH0ve3l9LnBuZycsCiAgICAgICAgewogICAgICAgICJhdHRyaWJ1dGlvbiI6IG51bGwsCiAgICAgICAgImRldGVjdFJldGluYSI6IGZhbHNlLAogICAgICAgICJtYXhOYXRpdmVab29tIjogMTgsCiAgICAgICAgIm1heFpvb20iOiAxOCwKICAgICAgICAibWluWm9vbSI6IDAsCiAgICAgICAgIm5vV3JhcCI6IGZhbHNlLAogICAgICAgICJzdWJkb21haW5zIjogImFiYyIKfSkuYWRkVG8obWFwXzkzZWY5ZjAwOTIzNTQ3Nzk4Y2ZjNzkwYjA0YTI5NzgzKTsKICAgIAoKICAgICAgICB2YXIgbW91c2VfcG9zaXRpb25fMGFkOWI5YWY4NTUxNDk0YmJmM2RlODJlYTA0YTVmMWMgPSBuZXcgTC5Db250cm9sLk1vdXNlUG9zaXRpb24oCiAgICAgICAgICAgIHsKICAiZW1wdHlTdHJpbmciOiAiTmFOIiwKICAibG5nRmlyc3QiOiB0cnVlLAogICJudW1EaWdpdHMiOiAyMCwKICAicG9zaXRpb24iOiAidG9wcmlnaHQiLAogICJwcmVmaXgiOiAiQ29vcmRpbmF0ZXM6IiwKICAic2VwYXJhdG9yIjogIiB8ICIKfSk7CiAgICAgICAgbW91c2VfcG9zaXRpb25fMGFkOWI5YWY4NTUxNDk0YmJmM2RlODJlYTA0YTVmMWMub3B0aW9uc1sibGF0Rm9ybWF0dGVyIl0gPSBmdW5jdGlvbihudW0pIHtyZXR1cm4gTC5VdGlsLmZvcm1hdE51bShudW0sIDMpICsgJyDCuiAnO307OwogICAgICAgIG1vdXNlX3Bvc2l0aW9uXzBhZDliOWFmODU1MTQ5NGJiZjNkZTgyZWEwNGE1ZjFjLm9wdGlvbnNbImxuZ0Zvcm1hdHRlciJdID0gZnVuY3Rpb24obnVtKSB7cmV0dXJuIEwuVXRpbC5mb3JtYXROdW0obnVtLCAzKSArICcgwrogJzt9OzsKICAgICAgICBtYXBfOTNlZjlmMDA5MjM1NDc3OThjZmM3OTBiMDRhMjk3ODMuYWRkQ29udHJvbChtb3VzZV9wb3NpdGlvbl8wYWQ5YjlhZjg1NTE0OTRiYmYzZGU4MmVhMDRhNWYxYyk7CgogICAgICAgIAo8L3NjcmlwdD4=\" style=\"position:absolute;width:100%;height:100%;left:0;top:0;border:none !important;\" allowfullscreen webkitallowfullscreen mozallowfullscreen></iframe></div></div>"
],
"text/plain": [
"<folium.folium.Map at 0x1ae35359908>"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Create another folium map\n",
"m = folium.Map()\n",
"\n",
"# Define a Javascript function that formats the coordinate value\n",
"# that is passed to it.\n",
"formatter = \"function(num) {return L.Util.formatNum(num, 3) + ' º ';};\"\n",
"\n",
"# Add a mouse position plugin with custom parameters\n",
"m.add_child(MousePosition(position='topright', separator=' | ',\n",
" empty_string='NaN', lng_first=True,\n",
" num_digits=20, prefix=\"Coordinates:\",\n",
" lat_formatter=formatter,\n",
" lng_formatter=formatter))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
2 changes: 2 additions & 0 deletions folium/plugins/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from folium.plugins.heat_map_withtime import HeatMapWithTime
from folium.plugins.marker_cluster import MarkerCluster
from folium.plugins.measure_control import MeasureControl
from folium.plugins.mouse_position import MousePosition
from folium.plugins.polyline_text_path import PolyLineTextPath
from folium.plugins.scroll_zoom_toggler import ScrollZoomToggler
from folium.plugins.terminator import Terminator
Expand All @@ -41,6 +42,7 @@
'HeatMapWithTime',
'MarkerCluster',
'MeasureControl',
'MousePosition',
'PolyLineTextPath',
'ScrollZoomToggler',
'Terminator',
Expand Down
86 changes: 86 additions & 0 deletions folium/plugins/mouse_position.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# -*- coding: utf-8 -*-

from __future__ import (absolute_import, division, print_function)

import json

from branca.element import CssLink, Figure, JavascriptLink, MacroElement

from jinja2 import Template


class MousePosition(MacroElement):
"""Add a field that shows the coordinates of the mouse position.

Uses the Leaflet plugin by Ardhi Lukianto under MIT license.
https://github.com/ardhi/Leaflet.MousePosition

Parameters
----------
position : str, default 'bottomright'
The standard Control position parameter for the widget.
separator : str, default ' : '
Character used to separate latitude and longitude values.
empty_string : str, default 'Unavailable'
Initial text to display.
lng_first : bool, default False
Whether to put the longitude first or not.
Set as True to display longitude before latitude.
num_digits : int, default '5'
Number of decimal places included in the displayed
longitude and latitude decimal degree values.
prefix : str, default ''
A string to be prepended to the coordinates.
lat_formatter : str, default None
Custom Javascript function to format the latitude value.
lng_formatter : str, default None
Custom Javascript function to format the longitude value.

Examples
--------
>>> fmtr = "function(num) {return L.Util.formatNum(num, 3) + ' º ';};"
>>> MousePosition(position='topright', separator=' | ', prefix="Mouse:",
... lat_formatter=fmtr, lng_formatter=fmtr)

"""
_template = Template("""
{% macro script(this, kwargs) %}

var {{ this.get_name() }} = new L.Control.MousePosition(
{{ this.options }});
{{ this.get_name() }}.options["latFormatter"] = {{ this.lat_formatter }};
{{ this.get_name() }}.options["lngFormatter"] = {{ this.lng_formatter }};
{{ this._parent.get_name() }}.addControl({{ this.get_name() }});

{% endmacro %}
""") # noqa

def __init__(self, position='bottomright', separator=' : ',
empty_string='Unavailable', lng_first=False, num_digits=5,
prefix='', lat_formatter=None, lng_formatter=None):

super(MousePosition, self).__init__()
self._name = 'MousePosition'

options = {
'position': position,
'separator': separator,
'emptyString': empty_string,
'lngFirst': lng_first,
'numDigits': num_digits,
'prefix': prefix,
}
self.options = json.dumps(options, sort_keys=True, indent=2)
self.lat_formatter = lat_formatter or 'undefined'
self.lng_formatter = lng_formatter or 'undefined'

def render(self, **kwargs):
super(MousePosition, self).render()

figure = self.get_root()
assert isinstance(figure, Figure), ('You cannot render this Element '
'if it is not in a Figure.')

figure.header.add_child(JavascriptLink('https://cdn.rawgit.com/ardhi/Leaflet.MousePosition/c32f1c84/src/L.Control.MousePosition.js')) # noqa

figure.header.add_child(CssLink('https://cdn.rawgit.com/ardhi/Leaflet.MousePosition/c32f1c84/src/L.Control.MousePosition.css')) # noqa