{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "[](https://demo.leafmap.org/lab/index.html?path=maplibre/pmtiles.ipynb)\n", "[](https://colab.research.google.com/github/opengeos/leafmap/blob/master/docs/maplibre/pmtiles.ipynb)\n", "[](https://mybinder.org/v2/gh/opengeos/leafmap/HEAD)\n", "\n", "**PMTiles source and protocol**\n", "\n", "This source code of this example is adapted from the MapLibre GL JS example - [mPMTiles source and protocol](https://maplibre.org/maplibre-gl-js/docs/examples/pmtiles/).\n", "\n", "Uncomment the following line to install [leafmap](https://leafmap.org) if needed." ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": {}, "outputs": [], "source": [ "# %pip install -U \"leafmap[maplibre]\"" ] }, { "cell_type": "code", "execution_count": null, "id": "2", "metadata": {}, "outputs": [], "source": [ "import leafmap.maplibregl as leafmap" ] }, { "cell_type": "markdown", "id": "3", "metadata": {}, "source": [ "## Remote PMTiles\n", "\n", "### Protomaps sample data" ] }, { "cell_type": "code", "execution_count": null, "id": "4", "metadata": {}, "outputs": [], "source": [ "url = \"https://open.gishub.org/data/pmtiles/protomaps_firenze.pmtiles\"\n", "metadata = leafmap.pmtiles_metadata(url)\n", "print(f\"layer names: {metadata['layer_names']}\")\n", "print(f\"bounds: {metadata['bounds']}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "\n", "style = {\n", " \"version\": 8,\n", " \"sources\": {\n", " \"example_source\": {\n", " \"type\": \"vector\",\n", " \"url\": \"pmtiles://\" + url,\n", " \"attribution\": \"PMTiles\",\n", " }\n", " },\n", " \"layers\": [\n", " {\n", " \"id\": \"buildings\",\n", " \"source\": \"example_source\",\n", " \"source-layer\": \"landuse\",\n", " \"type\": \"fill\",\n", " \"paint\": {\"fill-color\": \"steelblue\"},\n", " },\n", " {\n", " \"id\": \"roads\",\n", " \"source\": \"example_source\",\n", " \"source-layer\": \"roads\",\n", " \"type\": \"line\",\n", " \"paint\": {\"line-color\": \"black\"},\n", " },\n", " ],\n", "}\n", "\n", "# style = leafmap.pmtiles_style(url) # Use default style\n", "\n", "m.add_pmtiles(\n", " url,\n", " style=style,\n", " visible=True,\n", " opacity=1.0,\n", " tooltip=True,\n", ")\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "6", "metadata": {}, "outputs": [], "source": [ "m.layer_interact()" ] }, { "cell_type": "markdown", "id": "7", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "### Source Cooperative\n", "\n", "[Google-Microsoft Open Buildings - combined by VIDA](https://beta.source.coop/repositories/vida/google-microsoft-open-buildings/description)" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "url = \"https://data.source.coop/vida/google-microsoft-open-buildings/pmtiles/go_ms_building_footprints.pmtiles\"\n", "metadata = leafmap.pmtiles_metadata(url)\n", "print(f\"layer names: {metadata['layer_names']}\")\n", "print(f\"bounds: {metadata['bounds']}\")" ] }, { "cell_type": "code", "execution_count": null, "id": "10", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map(center=[0, 20], zoom=2, height=\"600px\")\n", "m.add_basemap(\"Google Hybrid\", visible=False)\n", "\n", "style = {\n", " \"version\": 8,\n", " \"sources\": {\n", " \"example_source\": {\n", " \"type\": \"vector\",\n", " \"url\": \"pmtiles://\" + url,\n", " \"attribution\": \"PMTiles\",\n", " }\n", " },\n", " \"layers\": [\n", " {\n", " \"id\": \"buildings\",\n", " \"source\": \"example_source\",\n", " \"source-layer\": \"building_footprints\",\n", " \"type\": \"fill\",\n", " \"paint\": {\"fill-color\": \"#3388ff\", \"fill-opacity\": 0.5},\n", " },\n", " ],\n", "}\n", "\n", "# style = leafmap.pmtiles_style(url) # Use default style\n", "\n", "m.add_pmtiles(\n", " url,\n", " style=style,\n", " visible=True,\n", " opacity=1.0,\n", " tooltip=True,\n", ")\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "11", "metadata": {}, "outputs": [], "source": [ "m.layer_interact()" ] }, { "cell_type": "markdown", "id": "12", "metadata": {}, "source": [ "" ] }, { "cell_type": "markdown", "id": "13", "metadata": {}, "source": [ "## Local PMTiles\n", "\n", "tippecanoe is required to convert vector data to pmtiles. Install it with `conda install -c conda-forge tippecanoe`.\n", "\n", "Download [building footprints](https://github.com/opengeos/open-data/blob/main/datasets/libya/Derna_buildings.geojson) of Derna, Libya." ] }, { "cell_type": "code", "execution_count": null, "id": "14", "metadata": {}, "outputs": [], "source": [ "url = \"https://raw.githubusercontent.com/opengeos/open-data/main/datasets/libya/Derna_buildings.geojson\"\n", "leafmap.download_file(url, \"buildings.geojson\")" ] }, { "cell_type": "markdown", "id": "15", "metadata": {}, "source": [ "Convert vector to PMTiles." ] }, { "cell_type": "code", "execution_count": null, "id": "16", "metadata": {}, "outputs": [], "source": [ "pmtiles = \"buildings.pmtiles\"\n", "leafmap.geojson_to_pmtiles(\n", " \"buildings.geojson\", pmtiles, layer_name=\"buildings\", overwrite=True, quiet=True\n", ")" ] }, { "cell_type": "markdown", "id": "17", "metadata": {}, "source": [ "Start a HTTP Sever" ] }, { "cell_type": "code", "execution_count": null, "id": "18", "metadata": {}, "outputs": [], "source": [ "leafmap.start_server(port=8000)" ] }, { "cell_type": "code", "execution_count": null, "id": "19", "metadata": {}, "outputs": [], "source": [ "url = f\"http://127.0.0.1:8000/{pmtiles}\"\n", "# leafmap.pmtiles_metadata(url)" ] }, { "cell_type": "markdown", "id": "20", "metadata": {}, "source": [ "Display the PMTiles on the map." ] }, { "cell_type": "code", "execution_count": null, "id": "21", "metadata": {}, "outputs": [], "source": [ "m = leafmap.Map()\n", "m.add_basemap(\"Google Hybrid\")\n", "style = {\n", " \"version\": 8,\n", " \"sources\": {\n", " \"example_source\": {\n", " \"type\": \"vector\",\n", " \"url\": \"pmtiles://\" + url,\n", " \"attribution\": \"PMTiles\",\n", " }\n", " },\n", " \"layers\": [\n", " {\n", " \"id\": \"buildings\",\n", " \"source\": \"example_source\",\n", " \"source-layer\": \"buildings\",\n", " \"type\": \"fill\",\n", " \"paint\": {\"fill-color\": \"#3388ff\", \"fill-opacity\": 0.5},\n", " },\n", " ],\n", "}\n", "\n", "# style = leafmap.pmtiles_style(url) # Use default style\n", "\n", "m.add_pmtiles(\n", " url,\n", " style=style,\n", " visible=True,\n", " opacity=0.8,\n", " tooltip=True,\n", ")\n", "m" ] }, { "cell_type": "code", "execution_count": null, "id": "22", "metadata": {}, "outputs": [], "source": [ "m.layer_interact()" ] }, { "cell_type": "markdown", "id": "23", "metadata": {}, "source": [ "" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.11.9" } }, "nbformat": 4, "nbformat_minor": 5 }