130 lines
4.2 KiB
Python
130 lines
4.2 KiB
Python
from jinja2 import Template
|
|
|
|
from folium.elements import JSCSSMixin
|
|
from folium.map import Layer
|
|
|
|
|
|
class VectorGridProtobuf(JSCSSMixin, Layer):
|
|
"""
|
|
Add vector tile layers based on https://github.com/Leaflet/Leaflet.VectorGrid.
|
|
|
|
Parameters
|
|
----------
|
|
url: url to tile provider
|
|
e.g. https://free-{s}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf?token={token}
|
|
layer_name: string, default "VectorGridLayer"
|
|
name of the layer
|
|
options: dict or str, VectorGrid.protobuf options
|
|
|
|
For convenience you can pass VectorGrid.protobuf options as python dictionary or string.
|
|
Strings allow plain JavaScript to be passed, therefore allow for conditional styling (see examples).
|
|
|
|
Additionally the url might contain any string literals like {token}, or {key}
|
|
that can be passed as attribute to the options dict and will be substituted.
|
|
|
|
Every layer inside the tile layer has to be styled separately.
|
|
|
|
Examples
|
|
--------
|
|
|
|
Options as dict:
|
|
|
|
>>> m = folium.Map()
|
|
>>> url = "https://free-{s}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf?token={token}"
|
|
>>> options = {
|
|
... "subdomain": "tilehosting",
|
|
... "token": "af6P2G9dztAt1F75x7KYt0Hx2DJR052G",
|
|
... "vectorTileLayerStyles": {
|
|
... "layer_name_one": {
|
|
... "fill": True,
|
|
... "weight": 1,
|
|
... "fillColor": "green",
|
|
... "color": "black",
|
|
... "fillOpacity": 0.6,
|
|
... "opacity": 0.6,
|
|
... },
|
|
... "layer_name_two": {
|
|
... "fill": True,
|
|
... "weight": 1,
|
|
... "fillColor": "red",
|
|
... "color": "black",
|
|
... "fillOpacity": 0.6,
|
|
... "opacity": 0.6,
|
|
... },
|
|
... },
|
|
... }
|
|
|
|
>>> VectorGridProtobuf(url, "layer_name", options).add_to(m)
|
|
|
|
Options as string allows to pass functions
|
|
|
|
>>> m = folium.Map()
|
|
>>> url = "https://free-{s}.tilehosting.com/data/v3/{z}/{x}/{y}.pbf?token={token}"
|
|
>>> options = '''{
|
|
... "subdomain": "tilehosting",
|
|
... "token": "af6P2G9dztAt1F75x7KYt0Hx2DJR052G",
|
|
... "vectorTileLayerStyles": {
|
|
... all: function(f) {
|
|
... if (f.type === 'parks') {
|
|
... return {
|
|
... "fill": true,
|
|
... "weight": 1,
|
|
... "fillColor": 'green',
|
|
... "color": 'black',
|
|
... "fillOpacity":0.6,
|
|
... "opacity":0.6
|
|
... };
|
|
... }
|
|
... if (f.type === 'water') {
|
|
... return {
|
|
... "fill": true,
|
|
... "weight": 1,
|
|
... "fillColor": 'purple',
|
|
... "color": 'black',
|
|
... "fillOpacity":0.6,
|
|
... "opacity":0.6
|
|
... };
|
|
... }
|
|
... }
|
|
... }
|
|
... }'''
|
|
|
|
>>> VectorGridProtobuf(url, "layer_name", options).add_to(m)
|
|
|
|
|
|
For more info, see: https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html#styling-vectorgrids.
|
|
"""
|
|
|
|
_template = Template(
|
|
"""
|
|
{% macro script(this, kwargs) -%}
|
|
var {{ this.get_name() }} = L.vectorGrid.protobuf(
|
|
'{{ this.url }}',
|
|
{% if this.options is defined %}
|
|
{{ this.options if this.options is string else this.options|tojson }})
|
|
.addTo({{ this._parent.get_name() }});
|
|
{% else %}
|
|
{{ this.options }}).addTo({{ this._parent.get_name() }});
|
|
{% endif %}
|
|
{%- endmacro %}
|
|
"""
|
|
)
|
|
|
|
default_js = [
|
|
(
|
|
"vectorGrid",
|
|
"https://unpkg.com/leaflet.vectorgrid@latest/dist/Leaflet.VectorGrid.bundled.js",
|
|
)
|
|
]
|
|
|
|
def __init__(self, url, layer_name, options=None):
|
|
self.layer_name = layer_name if layer_name else "VectorGridProtobufLayer"
|
|
|
|
super().__init__(name=self.layer_name)
|
|
|
|
self.url = url
|
|
self._name = "VectorGridProtobuf"
|
|
|
|
if options is not None:
|
|
self.options = options
|