text: Title: Add support for PMTiles
  Body: The source code is adapted from [folium-pmtiles](https://github.com/jtmiclat/folium-pmtiles). For now, it only supports folium. It would be great to support ipyleaflet as well. 
  
  ```python
  import folium
  from folium.elements import JSCSSMixin
  from folium.map import Layer
  from jinja2 import Template
  
  class PMTilesMapLibreLayer(JSCSSMixin, Layer):
      """Based of
      https://github.com/python-visualization/folium/blob/56d3665fdc9e7280eae1df1262450e53ec4f5a60/folium/plugins/vectorgrid_protobuf.py
      """
  
      _template = Template(
          """
              {% macro script(this, kwargs) -%}
              let protocol = new pmtiles.Protocol();
              maplibregl.addProtocol("pmtiles", protocol.tile);
  
             {{ this._parent.get_name() }}.createPane('overlay');
             {{ this._parent.get_name() }}.getPane('overlay').style.zIndex = 650;
             {{ this._parent.get_name() }}.getPane('overlay').style.pointerEvents = 'none';
  
              var {{ this.get_name() }} = L.maplibreGL({
              pane: 'overlay',
              style: {{ this.style|tojson}}
              }).addTo({{ this._parent.get_name() }});
  
              {%- endmacro %}
              """
      )
      default_css = [
          ("maplibre_css", "https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css")
      ]
  
      default_js = [
          ("pmtiles", "https://unpkg.com/pmtiles@2.7.1/dist/index.js"),
          ("maplibre-lib", "https://unpkg.com/maplibre-gl@2.2.1/dist/maplibre-gl.js"),
          (
              "maplibre-leaflet",
              "https://unpkg.com/@maplibre/maplibre-gl-leaflet@0.0.19/leaflet-maplibre-gl.js",
          ),
      ]
  
      def __init__(self, url, layer_name=None, style=None, **kwargs):
          self.layer_name = layer_name if layer_name else "PMTilesVector"
  
          super().__init__(name=self.layer_name, **kwargs)
  
          self.url = url
          self._name = "PMTilesVector"
  
          if style is not None:
              self.style = style
          else:
              self.style = {}
  
  
  m = folium.Map(location=[43.7798, 11.24148], zoom_start=13)
  pmtiles_url = "https://open.gishub.org/data/pmtiles/protomaps_firenze.pmtiles"
  pmtiles_layer = PMTilesMapLibreLayer(
      "folium_layer_name",
      overlay=True,
      style={
          "version": 8,
          "sources": {
              "example_source": {
                  "type": "vector",
                  "url": "pmtiles://" + pmtiles_url,
                  "attribution": '<a href="https://protomaps.com">Protomaps</a> © <a href="https://openstreetmap.org/copyright">OpenStreetMap</a>',
              }
          },
          "layers": [
              {
                  "id": "buildings",
                  "source": "example_source",
                  "source-layer": "landuse",
                  "type": "fill",
                  "paint": {"fill-color": "steelblue"},
              },
              {
                  "id": "roads",
                  "source": "example_source",
                  "source-layer": "roads",
                  "type": "line",
                  "paint": {"line-color": "black"},
              },
          ],
      },
  )
  m.add_child(pmtiles_layer)
  folium.LayerControl().add_to(m)
  m
  ```
  ![image](https://github.com/opengeos/leafmap/assets/5016453/b688540f-6e05-448c-bbb3-c2edba0b8f50)
  ****
  