Creando mapas con Notion y Github

"Notion es un software de gestión de proyectos y para tomar notas"

Continuando con la "serie" de post sobre Notion y aprovechando que un amigo ha publicado un componente web para crear maps usando LeafLet de forma realmente fácil voy a contar en este post cómo podemos usar Notion como backend para geolocalizar puntos y hacer que Github publique un mapa con ellos

En este post no voy a volver a contar cómo crearse cuenta o cómo crear una integración. Para ello te remito a los otros post del blog donde (espero) se explica. Así que para este post partimos de que tenemos una cuenta free en Notion y que hemos creado una integración

INFO

Al final del post pongo un enlace al proyecto ejemplo que te puedes clonar para no tener que picarte el código

Aprovechando las capacidades de Notion de que cada página es una "base de datos" vamos a crear una donde vamos a crear las siguientes columnas:

Name

String

Presentación

String

GoogleMap

URL

y vamos a añadir algunas entradas:

Madrid

1969

Donde todo empezó

https://www.google.com/maps/place/C.+Pescara,+28032+Madrid/@40.4253096,-3.6319141,14z/data=!4m5!3m4!1s0xd4225809d6376ef:0xbd6238a7e387bba!8m2!3d40.4152972!4d-3.6246032

Costa Rica

1999

Primer viaje al extranjero

https://www.google.com/maps/place/Tortuguero,+Lim%C3%B3n+Province,+Costa+Rica/@10.5445739,-83.5075092,16z/data=!3m1!4b1!4m5!3m4!1s0x8fa7560928a2e741:0x7b7e58e66658b6eb!8m2!3d10.5424838!4d-83.5023552

Nepal

2004

Nepal y Tibet, un viaje a otro universo

https://www.google.com/maps/place/Kathmandu+44600,+Nepal/@27.7090319,85.2911134,13z/data=!3m1!4b1!4m13!1m7!3m6!1s0x3995e8c77d2e68cf:0x34a29abcd0cc86de!2sNepal!3b1!8m2!3d28.394857!4d84.124008!3m4!1s0x39eb198a307baabf:0xb5137c1bf18db1ea!8m2!3d27.7169653!4d85.3239441

INFO

Como puedes ver la idea es añadir tantos lugares como queramos, poner una descripcion y una url copiada directamente desde GoogleMaps la cual parsearemos para extraer las coordenadas. Esta es una de las gracias de este script, facilitar el añadir entradas sin tener que estar buscando las posiciones, sino usar una url donde aparezcan

Como ya expliqué en los post relativos a Notion, esta base de datos tiene un identificador que puedes ver en la propia URL de Notion y que usaremos para extraer la información desde Github

Github

Vamos a usar un repositorio de Github para ejecutar un script que extraerá la información desde Notion y generará una página HTML+JS con un mapa mundi. Aprovecharemos la funcionalidad de Github pages para publicarlo en Internet.

  • Crearemos un repositorio, por ejemplo, "mis-andanzas"

  • En settings añadiremos dos secrets:

    • DATABASE, con el ID de nuestra página de Notion

    • NOTION_TOKEN, con el token que nos proporció Notion a la hora de crear nuestra integration

  • En settings configuraremos "Pages" indicando que el source será un Github Actions (no lo crees, ya te paso el código yo)

Con esto tenemos preparado el repositorio Github (recuerda que al final del post te paso un enlace para que te lo clones si no quieres hacerlo desde cero)

Script

El script en sí es muy sencillo. Simplemente usará las librerías JS de notion para conectarse a la página de Notion y volcar en un fichero ".js" las filas como si fueran puntos de un mapa usando el formato GeoJSON. Como ya he comentado, la gracia del script es que parsea las URLs de GoogleMap para hacerlo más cómodo.

notion2map.js
const {
    Client
} = require("@notionhq/client");

const {
    env
} = require('process');

require('dotenv').config();

// Initializing a client
const notion = new Client({
    auth: process.env.NOTION_TOKEN,
})
const myPage = await notion.databases.query({
        database_id: process.env.DATABASE
    });
...
 myPage.results.forEach(i => {
...
        const title = i.properties['Name'];
        if (title.title.length == 0)
            return;

        const name = title.title[0].plain_text;
        const url = i.properties['GoogleMap'].url;
        const presentation = i.properties['Presentation'].rich_text.map(m => m.plain_text).join(' ');
        const coordinates = googlemapExpr.exec(url);
        const lat = coordinates[1];
        const lng = coordinates[2];
...
        fs.appendFileSync(GEO_FILE, `{
            type: "Feature",
            geometry: {
                type: "Point", coordinates: [${lng}, ${lat}]
...

Simplemente generamos un fichero Javascript "creado al vuelo" que contiene un array con los puntos

Web Component

Miguel Pagola, https://github.com/migupl, se ha creado un componente web para generar mapas de forma muy simple, https://github.com/migupl/vanilla-js-web-component-leaflet-geojson, y muy bien documentado así que lo vamos a usarlo como "plantilla" para nuestro mapa, en lugar de complicarnos con los objetos de LeafLeft

<html>
<head>
...
    <script type="module" src="https://migupl.github.io/vanilla-js-web-component-leaflet-geojson/components/leaflet-map-component/leaflet-map.js"></script>
    <script src="data.js"></script>
...
<body>
    <header>
        <div class="container">
            <h1>Mis Andanzas</h1>
        </div>
    </header>
    <section id="setting-up">
        <leaflet-map id="notion-map" fitToBounds="true" flyToBounds="true"></leaflet-map>
    </section>
</body>
<script>
    window.onload = (event) => {
        const map = document.getElementById('notion-map');

        const eventBus = map.eventBus;

        eventBus.dispatch('x-leaflet-map-geojson-add', {
            leafletMap: map,
            geojson: features
        });
    }
</script>

Simplemente cargamos su javascript junto con el generado por el script y una vez que se carga la página, le indicamos que nos muestre los puntos.

No te tienes que preocupar por centrar el mapa, indicar zoom por defecto, ni nada parecido!!!

Github Action

Para terminar crearemos un github action ("static.yml" en mi proyecto) que ejecute el script y genere las páginas.

Para publicarlas usaremos un action disponible al que le dices la ruta que quieres publicar y Github las publica

jobs:
  # Single deploy job since we're just deploying
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    env:
      NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
      DATABASE: ${{ secrets.DATABASE }}
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Pages
        uses: actions/configure-pages@v3
      - name: Use Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 14.21.3
      - run: npm install
      - run: npm run generate
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          # Upload entire repository
          path: 'docs'
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1
WARNING

Recuerda NO usar los tokens en claro en tus actions, sino usar secrets

Una vez ejecutado el pipeline Github publicará una página accesible desde Internet como

TODO!!!

Queda pendiente para próximas versiones algunas ideas que me han planteado/surgido:

  • Añadir imágenes en el tooltip

  • Poder crear rutas en lugar de puntos sueltos

  • …​

Proyecto

El proyecto está publicado en https://github.com/jagedn/mis-andanzas y te lo puedes "forkear" o clonar y modificar a tu gusto. Si te fijas, los tokens y secretos están ocultos con lo que tu información está protegida

Follow comments at Telegram group Or subscribe to the Channel Telegram channel

2019 - 2024 | Mixed with Bootstrap | Baked with JBake v2.6.7