Skip to content

Commit

Permalink
add-north-arrow-flexibility (#43)
Browse files Browse the repository at this point in the history
Co-authored-by: mdevz-22 <giuliana.castellini@nimblegravity.com>
Co-authored-by: Eric Gitonga <gitonga@gmail.com>
  • Loading branch information
3 people authored Jan 9, 2024
1 parent 19c068a commit 4c26a80
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 44 deletions.
69 changes: 65 additions & 4 deletions ecoscope/mapping/map.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import urllib
import warnings


import ee
import folium
import geopandas as gpd
Expand Down Expand Up @@ -108,24 +109,31 @@ def add_legend(self, *args, **kwargs):

return super().add_legend(*args, **kwargs)

def add_north_arrow(self, position="topright", scale=1.0):
def add_north_arrow(self, imagePath="", position="topright", angle=0, scale=1.0):
"""
Parameters
----------
imagePath : str
Path to the image file for the north arrow. If not provided, default SVG image is uploaded.
position : str
Possible values are 'topleft', 'topright', 'bottomleft' or 'bottomright'.
angle : int
Angle for the north arrow to be rotated.
scale : float
Scale dimensions of north arrow.
"""

self.add_child(
ControlElement(
f"""\
NorthArrowElement(
html=f"""\
<svg width="{100*scale}px" height="{100*scale}px" version="1.1" viewBox="0 0 773 798" xmlns="http://www.w3.org/2000/svg">
<path transform="translate(0 798) scale(1 -1)" d="m674 403-161 48q-17 48-66 70l-46 166-46-167q-22-9-38-25t-29-45l-159-47 159-49q15-44 67-68l46-164 48 164q39 17 64 69zm-163 0q0-49-32-81-33-34-78-34-46 0-77 34-31 31-31 81 0 46 31 80t77 34q45 0 78-34 32-34 32-80zm-12 1q-5 7-7.5 17.5t-4 21.5-4.5 21-9 16q-7 6-17 9.5t-20.5 6-20 6-15.5 9.5v-107h98zm-98-108v108h-99l3-3 23-75q6-6 16.5-9.5t21-5.5 20-5.5 15.5-9.5zm-280 152h-26v-2q5 0 6-1 3-3 3-6 0-2-0.5-4t-1.5-7l-18-48-16 47q-3 9-3 12 0 7 7 7h2v2h-34v-2q2 0 3-1l3-3q2 0 2-2 2-1 4-5l5-15-12-42-17 50q-3 9-3 11 0 7 6 7h2v2h-33v-2q8 0 10-6 1-2 3-9l27-74h5l15 53 19-53h2l27 71q2 10 3 11 5 7 10 7v2zm325 350h-29v-3q7 0 10-4 1-1 1-11v-35l-42 53h-32v-3q7-2 12-6l2-3v-62q0-13-12-13v-2h29v2h-2q-4 0-7 2.5t-3 10.5v55l58-72h3v73q0 9 1 10.5t8 3.5l3 1v3zm207-395h-130q0 16-6 42zm-212-119-40-141v135q9 0 19 1t21 5zm-154 78-137 41h130q0-10 2-19.5t5-21.5zm114 168q-25 0-39-8l39 142v-134zm372-148h-3q-3-4-5-7.5t-4-5.5q-5-5-17-5h-19q-3 0-3 5v35h20q8 0 10-6 1-1 1-3 0-3 1-4h3v30h-3q-2-9-4-11t-8-2h-20v35h24q7 0 8-1 4-1 9-14h3l-1 20h-69v-2h3q7 0 8-4 2-2 2-9v-58q0-11-4-12-1-1-6-1h-3v-3h68zm-340-358q0 9-5.5 14.5t-20.5 14.5q-9 5-13 9l-5 5q-3 10-3 7 0 14 14 14 18 0 24-26h2v31h-2q-2-6-5-6-4 0-5 1-8 5-15 5-11 0-17.5-7t-6.5-17q0-13 9-19 6-4 16.5-10.5t12.5-8.5q8-7 8-13 0-14-18-14-13 0-18 5.5t-7 20.5h-2v-30h2q0 5 3 5l16-5h8q12 0 20 7t8 17z"/>
</svg>""", # noqa
imagePath=imagePath,
position=position,
angle=angle,
scale=scale,
)
)

Expand Down Expand Up @@ -249,7 +257,7 @@ def to_html(self, outfile, **kwargs):
with open(outfile, "w") as file:
file.write(self._repr_html_(**kwargs))

def to_png(self, outfile, sleep_time=10, **kwargs):
def to_png(self, outfile, sleep_time=5, **kwargs):
"""
Parameters
----------
Expand Down Expand Up @@ -529,6 +537,59 @@ def __init__(self, html, position="bottomright"):
)


class NorthArrowElement(ControlElement):
"""
Class to wrap arbitrary HTML or PNG as Leaflet Control.
Parameters
----------
html : str
HTML to render an element from.
imagePath: str
Path to the image file for the north arrow. If not provided, default SVG image is uploaded.
position : str
Possible values are 'topleft', 'topright', 'bottomleft' or 'bottomright'.
angle : int
Angle for the north arrow to be rotated.
scale : float
Scale dimensions of north arrow.
"""

_template = Template(
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.Control.extend({
onAdd: function(map) {
var control;
if (this.options.imagePath){
var img = document.createElement('img');
img.src=this.options.imagePath;
img.style.width = (this.options.scale * 100) + 'px';
img.style.height = (this.options.scale * 100) + 'px';
control=img;
} else {
var template = document.createElement('template');
template.innerHTML = `{{ this.html }}`.trim();
control = template.content.firstChild
}
control.style.transform = 'rotate({{ this.angle }}deg)';
return control;
}
});
(new {{ this.get_name() }}({{ this.options|tojson }})).addTo({{this._parent.get_name()}});
{% endmacro %}
"""
)

def __init__(self, html, imagePath="", position="bottomright", angle="", scale=""):
super().__init__(html=html, position=position)
self.angle = angle
self.options = folium.utilities.parse_options(imagePath=imagePath, scale=scale, position=position)


class FloatElement(MacroElement):
"""
Class to wrap arbitrary HTML as a floating Element.
Expand Down
2 changes: 1 addition & 1 deletion ecoscope/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "1.5.0"
__version__ = "1.5.1"
4 changes: 2 additions & 2 deletions notebooks/01. IO/Landscape Dynamics Data.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"metadata": {},
"outputs": [],
"source": [
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -225,7 +225,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -745,7 +745,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
4 changes: 2 additions & 2 deletions notebooks/03. Home Range & Movescape/EcoGraph.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -591,7 +591,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -333,7 +333,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
4 changes: 2 additions & 2 deletions notebooks/03. Home Range & Movescape/Reduce Regions.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -149,7 +149,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
25 changes: 12 additions & 13 deletions notebooks/04. EcoMap & EcoPlot/EcoMap.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"%pip install ecoscope &> /dev/null"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand All @@ -47,6 +47,7 @@
"import shapely\n",
"\n",
"import ecoscope\n",
"from ecoscope.contrib import geemap\n",
"\n",
"ecoscope.init(selenium=True, silent=True)"
]
Expand Down Expand Up @@ -94,13 +95,13 @@
" EE_ACCOUNT = os.getenv(\"EE_ACCOUNT\")\n",
" EE_PRIVATE_KEY_DATA = os.getenv(\"EE_PRIVATE_KEY_DATA\")\n",
" if EE_ACCOUNT and EE_PRIVATE_KEY_DATA:\n",
" ee.Initialize(credentials=ee.ServiceAccountCredentials(EE_ACCOUNT, key_data=EE_PRIVATE_KEY_DATA))\n",
" geemap.ee_initialize(credentials=ee.ServiceAccountCredentials(EE_ACCOUNT, key_data=EE_PRIVATE_KEY_DATA))\n",
" else:\n",
" ee.Initialize()\n",
" geemap.ee_initialize()\n",
"\n",
"except ee.EEException:\n",
" ee.Authenticate()\n",
" ee.Initialize()"
" geemap.ee_initialize()"
]
},
{
Expand Down Expand Up @@ -297,10 +298,8 @@
"# Add title\n",
"m.add_title(title=\"Elephant Sighting Map\", align=\"center\", font_size=\"18px\")\n",
"\n",
"# Add north-arrow\n",
"m.add_north_arrow(\n",
" position=\"top-left\",\n",
")\n",
"# Add north-arrow. Positions are: topright, topleft, bottomright, bottomleft\n",
"m.add_north_arrow(position=\"topright\", scale=1, angle=0)\n",
"\n",
"# Add legend\n",
"m.add_legend(legend_dict={\"KDB025Z_Tracks\": \"468af7\", \"Elephant_Sighting_Events\": \"f746ad\"})\n",
Expand Down Expand Up @@ -366,7 +365,7 @@
"m.zoom_to_gdf(movbank_relocations_gdf)\n",
"\n",
"m.add_legend(title=\"Is Night\", legend_dict={True: \"292965\", False: \"e7a553\"})\n",
"m.add_north_arrow(position=\"topright\")\n",
"m.add_north_arrow(position=\"topright\", scale=1, angle=0)\n",
"m.add_title(title=\"Day-Night Relocation Map\", align=\"center\", font_size=\"18px\")\n",
"\n",
"m"
Expand Down Expand Up @@ -411,7 +410,7 @@
"m.zoom_to_gdf(movbank_trajectory_gdf)\n",
"\n",
"m.add_legend(title=\"Is Night\", legend_dict={True: \"292965\", False: \"e7a553\"})\n",
"m.add_north_arrow(position=\"topright\")\n",
"m.add_north_arrow(position=\"topright\", scale=1, angle=0)\n",
"m.add_title(title=\"Day-Night Trajectory Map\", align=\"center\", font_size=\"18px\")\n",
"\n",
"m"
Expand All @@ -432,7 +431,7 @@
"source": [
"m = ecoscope.mapping.EcoMap()\n",
"m.add_speedmap(trajectory=movbank_trajectory_gdf, classification_method=\"equal_interval\", num_classes=6, bins=None)\n",
"m.add_north_arrow(position=\"topright\")\n",
"m.add_north_arrow(position=\"topright\", scale=1, angle=0)\n",
"m.add_title(title=\"Elephant Speed Map\", align=\"center\", font_size=\"18px\")\n",
"m.zoom_to_gdf(movbank_trajectory_gdf)\n",
"\n",
Expand Down Expand Up @@ -497,7 +496,7 @@
"m.zoom_to_gdf(percentile_areas)\n",
"\n",
"m.add_title(title=\"Salif ETD Range\", align=\"center\", font_size=\"18px\")\n",
"m.add_north_arrow(position=\"topleft\")\n",
"m.add_north_arrow(position=\"topleft\", scale=1, angle=0)\n",
"\n",
"m"
]
Expand Down Expand Up @@ -558,7 +557,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
4 changes: 2 additions & 2 deletions notebooks/04. EcoMap & EcoPlot/EcoPlot.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -146,7 +146,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
4 changes: 2 additions & 2 deletions notebooks/05. Environmental Analyses/Landscape Grid.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand Down Expand Up @@ -249,7 +249,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"source": [
"ECOSCOPE_RAW = \"https://raw.githubusercontent.com/wildlife-dynamics/ecoscope/master\"\n",
"\n",
"# !pip install ecoscope"
"!pip install ecoscope &> /dev/null"
]
},
{
Expand All @@ -46,6 +46,7 @@
"import pandas as pd\n",
"\n",
"import ecoscope\n",
"from ecoscope.contrib import geemap\n",
"\n",
"ecoscope.init()"
]
Expand Down Expand Up @@ -93,13 +94,13 @@
" EE_ACCOUNT = os.getenv(\"EE_ACCOUNT\")\n",
" EE_PRIVATE_KEY_DATA = os.getenv(\"EE_PRIVATE_KEY_DATA\")\n",
" if EE_ACCOUNT and EE_PRIVATE_KEY_DATA:\n",
" ee.Initialize(credentials=ee.ServiceAccountCredentials(EE_ACCOUNT, key_data=EE_PRIVATE_KEY_DATA))\n",
" geemap.ee_initialize(credentials=ee.ServiceAccountCredentials(EE_ACCOUNT, key_data=EE_PRIVATE_KEY_DATA))\n",
" else:\n",
" ee.Initialize()\n",
" geemap.ee_initialize()\n",
"\n",
"except ee.EEException:\n",
" ee.Authenticate()\n",
" ee.Initialize()"
" geemap.ee_initialize()"
]
},
{
Expand Down Expand Up @@ -239,7 +240,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.12"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
Loading

0 comments on commit 4c26a80

Please sign in to comment.