{
    "cells": [
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "[![image](https://studiolab.sagemaker.aws/studiolab.svg)](https://studiolab.sagemaker.aws/import/github/giswqs/mapwidget/blob/master/docs/examples/esm.ipynb)\n",
                "[![image](https://img.shields.io/badge/Open-Planetary%20Computer-black?style=flat&logo=microsoft)](https://pccompute.westeurope.cloudapp.azure.com/compute/hub/user-redirect/git-pull?repo=https://github.com/giswqs/mapwidget&urlpath=lab/tree/mapwidget/docs/examples/esm.ipynb&branch=master)\n",
                "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/giswqs/mapwidget/blob/master/docs/examples/esm.ipynb)"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "# %pip install mapwidget"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "import os\n",
                "import anywidget\n",
                "import traitlets"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Leaflet"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "class MapWidget(anywidget.AnyWidget):\n",
                "    _esm = \"\"\"\n",
                "    import * as L from \"https://esm.sh/leaflet@1.9.3\";\n",
                "    export function render(view) {\n",
                "    \n",
                "            let center = view.model.get(\"center\");\n",
                "            let zoom = view.model.get(\"zoom\");\n",
                "            let width = view.model.get(\"width\");\n",
                "            let height = view.model.get(\"height\");\n",
                "            \n",
                "            const container = document.createElement(\"div\");     \n",
                "            container.style.width = width;       \n",
                "            container.style.height = height;\n",
                "            \n",
                "            const map = L.map(container).setView(center, zoom);\n",
                "            L.tileLayer(\"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png\", {\n",
                "                attribution: 'Map data &copy; <a href=\"https://www.openstreetmap.org/\">OpenStreetMap</a> contributors',\n",
                "                maxZoom: 24,\n",
                "            }).addTo(map);\n",
                "            \n",
                "            view.el.appendChild(container);\n",
                "        }\n",
                "    \"\"\"\n",
                "\n",
                "    _css = \"https://unpkg.com/leaflet@1.9.3/dist/leaflet.css\"\n",
                "\n",
                "    center = traitlets.List([20, 0]).tag(sync=True, o=True)\n",
                "    zoom = traitlets.Int(2).tag(sync=True, o=True)\n",
                "    width = traitlets.Unicode(\"100%\").tag(sync=True, o=True)\n",
                "    height = traitlets.Unicode(\"600px\").tag(sync=True, o=True)\n",
                "\n",
                "\n",
                "m = MapWidget(center=[20, 0], zoom=2, height='600px')\n",
                "m"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Maplibre"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "class MapWidget(anywidget.AnyWidget):\n",
                "    _esm = \"\"\"\n",
                "    import maplibregl from \"https://esm.sh/maplibre-gl@2.4.0\";\n",
                "\n",
                "    export function render(view) {\n",
                "    \n",
                "        let center = view.model.get(\"center\");\n",
                "        center.reverse();\n",
                "        let zoom = view.model.get(\"zoom\");\n",
                "        let width = view.model.get(\"width\");\n",
                "        let height = view.model.get(\"height\");\n",
                "\n",
                "        const div = document.createElement(\"div\");\n",
                "        div.style.width = width;\n",
                "        div.style.height = height;\n",
                "\n",
                "        const map = new maplibregl.Map({\n",
                "          container: div,\n",
                "          style: 'https://demotiles.maplibre.org/style.json', // stylesheet location\n",
                "          center: center, // starting position [lng, lat]\n",
                "          zoom: zoom // starting zoom\n",
                "        });\n",
                "        view.el.appendChild(div);\n",
                "    }\n",
                "    \"\"\"\n",
                "    _css = \"https://esm.sh/maplibre-gl@2.4.0?css\"\n",
                "\n",
                "    center = traitlets.List([20, 0]).tag(sync=True, o=True)\n",
                "    zoom = traitlets.Int(2).tag(sync=True, o=True)\n",
                "    width = traitlets.Unicode(\"100%\").tag(sync=True, o=True)\n",
                "    height = traitlets.Unicode(\"600px\").tag(sync=True, o=True)\n",
                "\n",
                "\n",
                "m = MapWidget(center=[20, 0], zoom=2)\n",
                "m"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Mapbox"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "class MapWidget(anywidget.AnyWidget):\n",
                "    _esm = \"\"\"\n",
                "    import mapboxgl from \"https://esm.sh/mapbox-gl@2.13.0\";\n",
                "\n",
                "    export function render(view) {\n",
                "        let center = view.model.get(\"center\");\n",
                "        center.reverse();\n",
                "        let zoom = view.model.get(\"zoom\");\n",
                "        let width = view.model.get(\"width\");\n",
                "        let height = view.model.get(\"height\");\n",
                "\n",
                "        const div = document.createElement(\"div\");\n",
                "        div.style.width = width;\n",
                "        div.style.height = height;\n",
                "\n",
                "        let token = view.model.get(\"token\");\n",
                "\n",
                "        mapboxgl.accessToken = token;\n",
                "        const map = new mapboxgl.Map({\n",
                "            container: div,\n",
                "            style: \"mapbox://styles/mapbox/streets-v12\",\n",
                "            center: center,\n",
                "            zoom: zoom,\n",
                "        });\n",
                "        view.el.appendChild(div);\n",
                "    }\n",
                "\n",
                "    \"\"\"\n",
                "    _css = \"https://esm.sh/mapbox-gl@2.13.0?css\"\n",
                "\n",
                "    default_token = os.environ.get('MAPBOX_TOKEN')\n",
                "    token = traitlets.Unicode(default_token).tag(sync=True)\n",
                "    center = traitlets.List([20, 0]).tag(sync=True, o=True)\n",
                "    zoom = traitlets.Int(2).tag(sync=True, o=True)\n",
                "    width = traitlets.Unicode('100%').tag(sync=True, o=True)\n",
                "    height = traitlets.Unicode('600px').tag(sync=True, o=True)\n",
                "\n",
                "\n",
                "m = MapWidget(center=[20, 0], zoom=2)\n",
                "m"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## Cesium"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "class MapWidget(anywidget.AnyWidget):\n",
                "    _esm = \"\"\"\n",
                "    function loadScript(src) {\n",
                "      return new Promise((resolve, reject) => {\n",
                "        let script = Object.assign(document.createElement(\"script\"), {\n",
                "          type: \"text/javascript\",\n",
                "          async: true,\n",
                "          src: src,\n",
                "        });\n",
                "        script.addEventListener(\"load\", resolve);\n",
                "        script.addEventListener(\"error\", reject);\n",
                "        document.body.appendChild(script);\n",
                "      });\n",
                "    };\n",
                "    \n",
                "    await loadScript(\"https://cesium.com/downloads/cesiumjs/releases/1.103/Build/Cesium/Cesium.js\");\n",
                "    \n",
                "    export function render(view) {\n",
                "    \n",
                "      let width = view.model.get(\"width\");\n",
                "      let height = view.model.get(\"height\");\n",
                "        \n",
                "      const div = document.createElement(\"div\");\n",
                "      div.style.width = width;\n",
                "      div.style.height = height;\n",
                "      \n",
                "      Cesium.Ion.defaultAccessToken = view.model.get(\"token\");\n",
                "\n",
                "      const viewer = new Cesium.Viewer(div, {\n",
                "        terrainProvider: Cesium.createWorldTerrain()\n",
                "      });    \n",
                "\n",
                "      const buildingTileset = viewer.scene.primitives.add(Cesium.createOsmBuildings());   \n",
                "\n",
                "      viewer.camera.flyTo({\n",
                "        destination : Cesium.Cartesian3.fromDegrees(-122.4175, 37.655, 400),\n",
                "        orientation : {\n",
                "          heading : Cesium.Math.toRadians(0.0),\n",
                "          pitch : Cesium.Math.toRadians(-15.0),\n",
                "        }\n",
                "      });\n",
                "      \n",
                "      view.el.appendChild(div);\n",
                "    }\n",
                "    \"\"\"\n",
                "    # make sure to include styles\n",
                "    _css = \"https://cesium.com/downloads/cesiumjs/releases/1.103/Build/Cesium/Widgets/widgets.css\"\n",
                "    default_token = os.environ.get('CESIUM_TOKEN')\n",
                "    token = traitlets.Unicode(default_token).tag(sync=True)\n",
                "    width = traitlets.Unicode('100%').tag(sync=True, o=True)\n",
                "    height = traitlets.Unicode('600px').tag(sync=True, o=True)\n",
                "\n",
                "\n",
                "m = MapWidget()\n",
                "m"
            ]
        },
        {
            "attachments": {},
            "cell_type": "markdown",
            "metadata": {},
            "source": [
                "## OpenLayers"
            ]
        },
        {
            "cell_type": "code",
            "execution_count": null,
            "metadata": {},
            "outputs": [],
            "source": [
                "class MapWidget(anywidget.AnyWidget):\n",
                "    _esm = \"\"\"\n",
                "    function loadScript(src) {\n",
                "      return new Promise((resolve, reject) => {\n",
                "        let script = Object.assign(document.createElement(\"script\"), {\n",
                "          type: \"text/javascript\",\n",
                "          async: true,\n",
                "          src: src,\n",
                "        });\n",
                "        script.addEventListener(\"load\", resolve);\n",
                "        script.addEventListener(\"error\", reject);\n",
                "        document.body.appendChild(script);\n",
                "      });\n",
                "    };\n",
                "    \n",
                "    await loadScript(\"https://cdn.jsdelivr.net/npm/ol@v7.3.0/dist/ol.js\");\n",
                "    \n",
                "    export function render(view) {\n",
                "    \n",
                "      let center = view.model.get(\"center\");\n",
                "      center.reverse();\n",
                "      let zoom = view.model.get(\"zoom\");\n",
                "      let width = view.model.get(\"width\");\n",
                "      let height = view.model.get(\"height\");\n",
                "\n",
                "      const div = document.createElement(\"div\");\n",
                "      div.style.width = width;\n",
                "      div.style.height = height;\n",
                "      \n",
                "        var map = new ol.Map({\n",
                "            target: div,\n",
                "            layers: [\n",
                "                new ol.layer.Tile({\n",
                "                    source: new ol.source.OSM()\n",
                "                })\n",
                "            ],\n",
                "            view: new ol.View({\n",
                "                center: ol.proj.fromLonLat(center),\n",
                "                zoom: zoom\n",
                "            })\n",
                "        });\n",
                "      view.el.appendChild(div);\n",
                "    }\n",
                "    \"\"\"\n",
                "    # make sure to include styles\n",
                "    _css = \"https://cdn.jsdelivr.net/npm/ol@v7.3.0/ol.css\"\n",
                "    center = traitlets.List([20, 0]).tag(sync=True, o=True)\n",
                "    zoom = traitlets.Int(2).tag(sync=True, o=True)\n",
                "    width = traitlets.Unicode('100%').tag(sync=True, o=True)\n",
                "    height = traitlets.Unicode('600px').tag(sync=True, o=True)\n",
                "\n",
                "\n",
                "m = MapWidget(center=[20, 0], zoom=2)\n",
                "m"
            ]
        }
    ],
    "metadata": {
        "kernelspec": {
            "display_name": "geo",
            "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.10.8"
        },
        "orig_nbformat": 4
    },
    "nbformat": 4,
    "nbformat_minor": 2
}