diff --git a/.github/workflows/pypi.yml b/.github/workflows/pypi.yml index cf6e29adca..9f07789f56 100644 --- a/.github/workflows/pypi.yml +++ b/.github/workflows/pypi.yml @@ -46,7 +46,7 @@ jobs: - name: Publish a Python distribution to PyPI if: success() && github.event_name == 'release' - uses: pypa/gh-action-pypi-publish@v1.12.3 + uses: pypa/gh-action-pypi-publish@v1.12.4 with: user: __token__ password: ${{ secrets.PYPI_PASSWORD }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c2974beda8..f1829174a4 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,12 +15,12 @@ repos: files: requirements-dev.txt - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.1 + rev: v0.9.4 hooks: - id: ruff - repo: https://github.com/psf/black - rev: 24.10.0 + rev: 25.1.0 hooks: - id: black language_version: python3 @@ -31,7 +31,7 @@ repos: - id: blackdoc - repo: https://github.com/codespell-project/codespell - rev: v2.3.0 + rev: v2.4.1 hooks: - id: codespell args: diff --git a/LICENSE.txt b/LICENSE.txt index fcc3efae40..b08ad7fc29 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,4 +1,6 @@ -Copyright (C) 2013, Rob Story +Copyright (C) 2013-, Folium developers +See https://github.com/python-visualization/folium/graphs/contributors for a +full list of contributors. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in @@ -16,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. diff --git a/docs/_static/flask_example.py b/docs/_static/flask_example.py index 47d4273cf6..548ddf5ffe 100644 --- a/docs/_static/flask_example.py +++ b/docs/_static/flask_example.py @@ -1,16 +1,16 @@ -""" flask_example.py +"""flask_example.py - Required packages: - - flask - - folium +Required packages: +- flask +- folium - Usage: +Usage: - Start the flask server by running: +Start the flask server by running: - $ python flask_example.py + $ python flask_example.py - And then head to http://127.0.0.1:5000/ in your browser to see the map displayed +And then head to http://127.0.0.1:5000/ in your browser to see the map displayed """ diff --git a/docs/_static/switcher.json b/docs/_static/switcher.json index ce0e1189bb..b60ab36e86 100644 --- a/docs/_static/switcher.json +++ b/docs/_static/switcher.json @@ -4,10 +4,14 @@ "url": "https://python-visualization.github.io/folium/dev/" }, { - "name": "latest (0.19.3)", - "version": "0.19.3", + "name": "latest (0.19.4)", + "version": "0.19.4", "url": "https://python-visualization.github.io/folium/latest/" }, + { + "version": "0.19.3", + "url": "https://python-visualization.github.io/folium/v0.19.3/" + }, { "version": "0.19.2", "url": "https://python-visualization.github.io/folium/v0.19.2/" diff --git a/docs/user_guide/raster_layers/tiles.md b/docs/user_guide/raster_layers/tiles.md index cf7998590c..5a1de3ede5 100644 --- a/docs/user_guide/raster_layers/tiles.md +++ b/docs/user_guide/raster_layers/tiles.md @@ -26,6 +26,13 @@ folium.Map(location=[lat, lon], tiles="Cartodb dark_matter", zoom_start=zoom_sta ### Custom tiles +You can also provide a url template to load tiles from, for example if you use a paid API. +You also have to provide an attribution in that case. For information how that +url template should look like see the Leaflet documentation: +https://leafletjs.com/reference.html#tilelayer. + +Below is an example, note the literal `{z}`, `{x}` and `{y}` in the url template. + ```{code-cell} ipython3 attr = ( '© OpenStreetMap ' diff --git a/folium/elements.py b/folium/elements.py index 3dbbc82ff1..56b3ba9040 100644 --- a/folium/elements.py +++ b/folium/elements.py @@ -1,12 +1,18 @@ from typing import List, Tuple -from branca.element import CssLink, Element, Figure, JavascriptLink, MacroElement +from branca.element import ( + CssLink, + Element, # NoQA: F401 needed as a reexport + Figure, + JavascriptLink, + MacroElement, +) from folium.template import Template from folium.utilities import JsCode -class JSCSSMixin(Element): +class JSCSSMixin(MacroElement): """Render links to external Javascript and CSS resources.""" default_js: List[Tuple[str, str]] = [] diff --git a/folium/features.py b/folium/features.py index 83a7b7fa47..dc9349ef01 100644 --- a/folium/features.py +++ b/folium/features.py @@ -111,7 +111,7 @@ def __init__( ) -class Vega(JSCSSMixin, Element): +class Vega(JSCSSMixin): """ Creates a Vega chart element. @@ -234,7 +234,7 @@ def render(self, **kwargs): ) -class VegaLite(Element): +class VegaLite(MacroElement): """ Creates a Vega-Lite chart element. diff --git a/folium/map.py b/folium/map.py index 36c4655945..e922906713 100644 --- a/folium/map.py +++ b/folium/map.py @@ -275,7 +275,6 @@ class Icon(MacroElement): var {{ this.get_name() }} = L.AwesomeMarkers.icon( {{ this.options|tojavascript }} ); - {{ this._parent.get_name() }}.setIcon({{ this.get_name() }}); {% endmacro %} """ ) @@ -341,7 +340,7 @@ class Marker(MacroElement): folium.Popup or a folium.Popup instance. tooltip: str or folium.Tooltip, default None Display a text when hovering over the object. - icon: Icon plugin + icon: Icon, CustomIcon or DivIcon, optional the Icon plugin to use to render the marker. draggable: bool, default False Set to True to be able to drag the marker around the map. @@ -372,6 +371,23 @@ class Marker(MacroElement): """ ) + class SetIcon(MacroElement): + """Set the icon of a marker after both are created.""" + + _template = Template( + """ + {% macro script(this, kwargs) %} + {{ this.marker.get_name() }}.setIcon({{ this.icon.get_name() }}); + {% endmacro %} + """ + ) + + def __init__(self, marker: "Marker", icon: "Icon"): + super().__init__() + self._name = "SetIcon" + self.marker = marker + self.icon = icon + def __init__( self, location: Optional[Sequence[float]] = None, @@ -387,6 +403,8 @@ def __init__( self.options = remove_empty( draggable=draggable or None, autoPan=draggable or None, **kwargs ) + # this attribute is not used by Marker, but by GeoJson + self.icon = None if icon is not None: self.add_child(icon) self.icon = icon @@ -410,10 +428,12 @@ def render(self): raise ValueError( f"{self._name} location must be assigned when added directly to map." ) + if self.icon: + self.add_child(self.SetIcon(marker=self, icon=self.icon)) super().render() -class Popup(Element): +class Popup(MacroElement): """Create a Popup instance that can be linked to a Layer. Parameters diff --git a/folium/vector_layers.py b/folium/vector_layers.py index 850c889493..066efd6ac2 100644 --- a/folium/vector_layers.py +++ b/folium/vector_layers.py @@ -103,6 +103,9 @@ def path_options( if kwargs.get("tags"): extra_options["tags"] = kwargs.pop("tags") + if kwargs.get("className"): + extra_options["className"] = kwargs.pop("className") + default = { "stroke": kwargs.pop("stroke", True), "color": color, diff --git a/tests/test_features.py b/tests/test_features.py index 1f1e64f1ae..af43144c76 100644 --- a/tests/test_features.py +++ b/tests/test_features.py @@ -1,4 +1,4 @@ -"""" +""" " Folium Features Tests --------------------- diff --git a/tests/test_repr.py b/tests/test_repr.py index d597747406..2ce215c332 100644 --- a/tests/test_repr.py +++ b/tests/test_repr.py @@ -1,4 +1,4 @@ -"""" +""" " Folium _repr_*_ Tests --------------------- diff --git a/tests/test_vector_layers.py b/tests/test_vector_layers.py index d887f25547..0cb8ba2183 100644 --- a/tests/test_vector_layers.py +++ b/tests/test_vector_layers.py @@ -1,4 +1,4 @@ -"""" +""" " Test Vector Layers ------------------