Saltar a contenido

Recursos open data

Ver presentación OpenData (pptx)

Ver presentación OpenData (pdf)

El MetaMapa: Ejemplo de mapificación de resultados de Sócrata

Buscaremos mapas en formato geojson con la api discovery de Sócrata https://api.us.socrata.com/api/catalog/v1?q=chicago%20crime&only=maps

  • Para ir de la API Global hasta el recurso local debemos realizar 3 peticiones

  • Peticion 1 API Global : https://api.us.socrata.com/api/catalog/v1?q=chicago%20crime&only=maps

  • Peticion 2 obtener url recurso https://{dominio/api/views.json?method=getByResourceName&name={id recurso}

  • Petición 3 obterner el recurso https://{dminio}/api/geospatial/{recurso}?method=export&format=GeoJSON

Paso 1 crear archivo metamapa

  • Creamos un archivo con el nombre de metamapa.html en /geoweb.

  • Creamos un archivo con el nombre de socrata.js. dentro de /geoweb/js

  • Abrimos el archivo metamapa.html con VSCode y copiamos el siguiente código.

<html>
<head>
    <meta charset='utf-8' />
    <title>MetaMapa</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />

    <link href='css/estilobase.css' rel='stylesheet' />
    <script src='js/socrata.js'></script>
    <script>
        var map;
        function init() {
            mapboxgl.accessToken = 'pk.eyJ1IjoiZ2lzbWFzdGVybTIiLCJhIjoiY2plZHhubTQxMTNoYzMza3Rqa3kxYTdrOCJ9.53B1E6mKD_EQOVb2Y0-SsA';
            map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/mapbox/dark-v10',
                center: [9.746, 40.473],
                zoom: 5.5,
                hash: true,
                pitch: 45,
                attributionControl: false
            });
            map.addControl(new mapboxgl.AttributionControl({
                compact: true
            }));
            map.addControl(new mapboxgl.NavigationControl());
        }
    </script>
</head>
<body onload="init()">
    <div id='map'></div>
</body>
</html>

Paso 2 reutilizamos código y opciones html

<html>
<head>
    <meta charset='utf-8' />
    <title>MetaMapa</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <link href='css/estilobase.css' rel='stylesheet' />
    <script src='js/utils.js'></script>
    <script src='js/socrata.js'></script>
    <style>
        #results {
            width: 100%;
            background-color: #f2f2f2;
            margin: 5px;
        }
        #mygrid {
            height: 340px;
            overflow: auto
        }
        #panelContainer {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 350px;
            background-color: white;
            height: 95%;
            opacity: 0.9;
        }
        #num_results_socrata {
            width: 70px !important;
        }
    </style>
    <script>
        var map;
        function init() {
            mapboxgl.accessToken = 'pk.eyJ1IjoiZ2lzbWFzdGVybTIiLCJhIjoiY2plZHhubTQxMTNoYzMza3Rqa3kxYTdrOCJ9.53B1E6mKD_EQOVb2Y0-SsA';
            map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/mapbox/dark-v10',
                center: [9.746, 40.473],
                zoom: 5.5,
                hash: true,
                pitch: 45,
                attributionControl: false
            });
            map.addControl(new mapboxgl.AttributionControl({
                compact: true
            }));
            map.addControl(new mapboxgl.NavigationControl());
        }
    </script>
</head>
<body onload="init()">
    <div id='map'></div>
    <div id="panelContainer">
        <div class="col-md-12">
            <h4>MetaMapa </h4>
            <p>Discovery API <br>
                <a target="_blank"
                    href="https://docs.socratadiscovery.apiary.io">https://docs.socratadiscovery.apiary.io</a>
            </p>
            <div class="form-group">
                <div class="radio">
                    <label>
                        <input type="radio" name="optionsRadios" id="optionsRadios1"
                            value="https://api.eu.socrata.com/api/catalog/v1?" checked>
                        EU API Discovery
                    </label>
                </div>
                <div class="radio">
                    <label>
                        <input type="radio" name="optionsRadios" id="optionsRadios2"
                            value="https://api.us.socrata.com/api/catalog/v1?">
                        US API Discovery
                    </label>
                </div>
            </div>
            <div class="form-group">
                <label for="text_filter_socrata"> Buscar {q=} <u></u></label>
                <input type="text" class="form-control" id="text_filter_socrata" value="" placeholder="Entrar cerca">
            </div>
            <div class="form-group">
                <label for="num_results_socrata">Num results:{limit=}</label>
                <input type="number" class="form-control" id="num_results_socrata" value="100">
            </div>
            <div class="form-group">
                <button id="bt_send" type="button" class="btn btn-default btn-success">Enviar</button>
            </div>
            <hr>
            <div id="results"></div>
            <div id="mygrid"></div>
        </div>
    </div>
</body>
</html>

Paso 3 Función peticionUnoApiGlobal()

  • Añadimos dentro de js/socrata.js la funcion peticionUnoApiGlobal()

Para enviar la primera petición a la API global de Sócrata

https://api.eu.socrata.com/api/catalog/v1?q=wifi&limit=1&only=map

function peticionUnoApiGlobal() {

    var options = document.getElementsByName("optionsRadios");
    var url_servidor;
    for (var i = 0; i < options.length; i++) {
        if (options[i].checked) {
            url_servidor = options[i].value;
        }
    }
    var textoBuscar = document.getElementById("text_filter_socrata").value; //encodeURI()
    var limiteResultados = document.getElementById("num_results_socrata").value;
    var peticion1 = url_servidor + "q=" + textoBuscar + "&limit=" + limiteResultados + "&only=map";
    // console.log(peticion1);

    enviarPeticion(peticion1).then(function (respuestaSocrata) {

        if (respuestaSocrata) {
            // console.info(respuestaSocrata);
            document.getElementById("results").innerHTML = "Resultados encontrados:<b>" + respuestaSocrata.resultSetSize + "</b>";
            //$('#mygrid').html('');

            var resultadosHTML;

            if (respuestaSocrata.resultSetSize >= 1) {
                resultadosHTML = "<ul>";
                for (var i = 0; i < respuestaSocrata.results.length; i++) {

                    resultadosHTML = resultadosHTML + '<li class="li"><b>' + respuestaSocrata.results[i].resource.name + ': <b>' +
                        '<a target="_blank" title="' + respuestaSocrata.results[i].resource.attribution + '" href="' + respuestaSocrata.results[i].link + '"> Link </a> ' +
                        '<a class="btn btn-success btn-xs btmapa"  onClick="buscaPintaDatos(this.id)" title="' + respuestaSocrata.results[i].resource.attribution + '" href="#" id="' + respuestaSocrata.results[i].resource.id + '#' + respuestaSocrata.results[i].metadata.domain + '">Ver mapa</a>';

                }
                resultadosHTML = resultadosHTML + "</ul>";
                document.getElementById("mygrid").innerHTML = resultadosHTML;


            } else {

                document.getElementById("results").innerHTML = "No hay resultados";
            }
        }
    });//fin peticion



} // fin funcion
  • Llamamos a la funcion peticionUnoApiGlobal() desde metamapa.html
<html>
<head>
    <meta charset='utf-8' />
    <title>MetaMapa</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
    <link href='css/estilobase.css' rel='stylesheet' />
    <script src='js/utils.js'></script>
    <script src='js/socrata.js'></script>
    <style>
        #results {
            width: 100%;
            background-color: #f2f2f2;
            margin: 5px;
        }
        #mygrid {
            height: 340px;
            overflow: auto
        }
        #panelContainer {
            position: absolute;
            top: 0px;
            left: 0px;
            width: 350px;
            background-color: white;
            height: 95%;
            opacity: 0.9;
        }
        #num_results_socrata {
            width: 70px !important;
        }
    </style>
    <script>
        var map;
        function init() {
            mapboxgl.accessToken = 'pk.eyJ1IjoiZ2lzbWFzdGVybTIiLCJhIjoiY2plZHhubTQxMTNoYzMza3Rqa3kxYTdrOCJ9.53B1E6mKD_EQOVb2Y0-SsA';
            map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/mapbox/dark-v10',
                center: [9.746, 40.473],
                zoom: 5.5,
                hash: true,
                pitch: 45,
                attributionControl: false
            });
            map.addControl(new mapboxgl.AttributionControl({
                compact: true
            }));
            map.addControl(new mapboxgl.NavigationControl());
        }
    </script>
</head>
<body onload="init()">
    <div id='map'></div>
    <div id="panelContainer">
        <div class="col-md-12">
            <h4>MetaMapa </h4>
            <p>Discovery API <br>
                <a target="_blank"
                    href="https://docs.socratadiscovery.apiary.io">https://docs.socratadiscovery.apiary.io</a>
            </p>
            <div class="form-group">
                <div class="radio">
                    <label>
                        <input type="radio" name="optionsRadios" id="optionsRadios1"
                            value="https://api.eu.socrata.com/api/catalog/v1?" checked>
                        EU API Discovery
                    </label>
                </div>
                <div class="radio">
                    <label>
                        <input type="radio" name="optionsRadios" id="optionsRadios2"
                            value="https://api.us.socrata.com/api/catalog/v1?">
                        US API Discovery
                    </label>
                </div>
            </div>
            <div class="form-group">
                <label for="text_filter_socrata"> Buscar {q=} <u></u></label>
                <input type="text" class="form-control" id="text_filter_socrata" value="" placeholder="Entrar cerca">
            </div>
            <div class="form-group">
                <label for="num_results_socrata">Num results:{limit=}</label>
                <input type="number" class="form-control" id="num_results_socrata" value="100">
            </div>
            <div class="form-group">
                <button id="bt_send" onclick="peticionUnoApiGlobal()" type="button" class="btn btn-default btn-success">Enviar</button>
            </div>
            <hr>
            <div id="results"></div>
            <div id="mygrid"></div>
        </div>
    </div>
</body>
</html>

Otra forma de hacerlo más profesional seria

        const boton = document.getElementById("bt_send");
        const texto = document.getElementById("text_filter_socrata");

        texto.addEventListener("keypress", function (event) {
            console.info(event);
            if (event.which == 13 || event.keyCode == 13) {
                peticionUnoApiGlobal();
                return false;
            }
        });

        boton.addEventListener("click", function (event) {
            peticionUnoApiGlobal();

        });

Realizamos algunas búsquedas

Ejemplo "wifi" o "crime"

Paso 4: Petición 2 localizar y obtener el recurso

  • Añadimos a socrata.js la funcion asíncrona peticionDosObtenerRecurso()
 async function peticionDosObtenerRecurso(data) {

    var params = data.split("#");
    var peticion2 = 'https://' + params[1] + '/api/views.json?method=getByResourceName&name=' + params[0];

  return await  enviarPeticion(peticion2).then(function (respuestaNodoSocrata) {
        var urlRecurso;
        var isGeojson;
        var bbox;
        console.info(respuestaNodoSocrata);

        if (respuestaNodoSocrata.metadata && respuestaNodoSocrata.metadata.geo) { //es geo

            urlRecurso = 'https://' + params[1] + '/api/geospatial/' + respuestaNodoSocrata.childViews[0] + '?method=export&format=GeoJSON';
            isGeojson = true;
            bbox = respuestaNodoSocrata.metadata.geo.bbox;
        } else { // es una tabla

            urlRecurso = 'https://' + params[1] + '/resource/' + params[0] + '.json?$limit=1000';
            isGeojson = false;
            bbox = null;

        }

       var respuesta = {url:urlRecurso,bbox: bbox,isGeojson: isGeojson};

        return respuesta;;

    });// fin peticion 2 

} //finfuncion

observamos la función aún no creada buscaPintaDatos

Paso 5: Obtener y pintar datos

  • Creamos la funcion peticionTresObtenerDato dentro de socrata.js para obtener y/o tranformar los datos a GeoJson

  • Creamos la funcions pintarMapa dentro de socrata.js para añadir los datos al mapa

 function peticionTresObtenerDato(urlRecurso, bbox, isGeojson) {

    enviarPeticion(urlRecurso).then(function (respuestaRecurso) {

        if (isGeojson) {

            pintarMapa(respuestaRecurso, bbox);

        } else {

            var geoJSON = {
                "type": "FeatureCollection",
                "features": []
            };



            for (var i = 0; i < respuestaRecurso.length; i++) {

                if (respuestaRecurso[i].location_1) {
                    geoJSON.features.push(
                        {
                            "type": "Feature",
                            "properties": respuestaRecurso[i].location_1,
                            "geometry": {
                                "type": "Point",
                                "coordinates": [
                                    respuestaRecurso[i].location_1.longitud,
                                    respuestaRecurso[i].location_1.latitude
                                ]
                            }
                        }
                    );


                } else if (respuestaRecurso[i].location) {
                    geoJSON.features.push(
                        {
                            "type": "Feature",
                            "properties": respuestaRecurso[i].location,
                            "geometry": {
                                "type": "Point",
                                "coordinates": [
                                    respuestaRecurso[i].location.longitude,
                                    respuestaRecurso[i].location.latitude
                                ]
                            }
                        }
                    );


                } else {
                    geoJSON.features.push(
                        {
                            "type": "Feature",
                            "properties": {},
                            "geometry": {
                                "type": "Point",
                                "coordinates": [
                                    0,
                                    0
                                ]
                            }
                        }
                    );
                }


            } //fin for


            var newBBOx = geoJSON.features[0].geometry.coordinates[0] + "," +
                geoJSON.features[0].geometry.coordinates[1] + "," +
                geoJSON.features[geoJSON.features.length - 1].geometry.coordinates[0] + "," +
                geoJSON.features[geoJSON.features.length - 1].geometry.coordinates[1];

            pintarMapa(geoJSON, newBBOx);

        } //fin else

    }) //fin peticion
}
function pintarMapa(geoJSON, bbox) {

    var tipoGeometria = geoJSON.features[0].geometry.type;

    if (!map.getSource("datossocrata_source")) {

        map.addSource("datossocrata_source", {
            type: "geojson",
            data: geoJSON
        });

    } else {

        map.getSource("datossocrata_source").setData(geoJSON);

        map.removeLayer("socrata");

    }

    if (tipoGeometria.indexOf("Line") != -1) { //es tipo linea

        map.addLayer({
            'id': 'socrata',
            'type': 'line',
            'source': 'datossocrata_source',
            'layout': {
                'line-join': 'round',
                'line-cap': 'round'
            },
            'paint': {
                'line-color': '#ff0000',
                'line-width': 3
            }
        });


    } else if (tipoGeometria.indexOf("Polygon") != -1) { //es tipo linea

        map.addLayer({
            'id': 'socrata',
            'type': 'fill',
            'source': 'datossocrata_source',
            'paint': {
                'fill-color': '#ff0000',
                'fill-outline-color': '#ffffff',
                'fill-opacity': 0.5
            }
        });


    } else {
        map.addLayer({
            'id': 'socrata',
            'type': 'circle',
            'source': 'datossocrata_source',
            'paint': {
                'circle-color': '#ff0000',
                'circle-radius': 10
            }
        });

    }


    var bounds = bbox.split(",")

    map.fitBounds([[bounds[0], bounds[1]], [bounds[2], bounds[3]]]);



}

Paso 6: Ejecutar i pintar datos

  • Creamos la funcion buscaPintaDatos dentro de socrata.js para llamar a las funciones 2 y 3
function buscaPintaDatos(data){

    peticionDosObtenerRecurso(data).then(function(respuesta){

        peticionTresObtenerDato(respuesta.url, respuesta.bbox, respuesta.isGeojson)


    })

}

Buscamos datos

Podrímos aprovecha la funció de info addPopupToMap("socrata")

 map.on("load", function(){

    addPopupToMap("socrata");
});

alt text

¿Subimos el ejemplo al GitHub?

        git pull
        git add .
        git commit -m "socrata"
        git push

Saber más... Ejemplos avanzados con MapBox GL JS

Vamos a ver algunos ejemplos más avanzados y complejos

¿Para que nos puede servir?

  • Como base para nuestra práctica final

  • Para ver la potencialidad de los estilos de mapbox

  • Para aprender nuevos métodos y funcionalidades de Mapbox GL JS

  • Para connectarnos y utlizar servicios externos

  • Para observar formas de programar y solucionar problemas

  • Para aprender a reutilizar código

Animación y rotación del mapa

Ejemplo rotación de camara com mapa_rutas3d.html

  • Añadimos funciones de rotación a rutas.js
        var animacion;
        function rotarCamara(timestamp) {

            rotacion =timestamp /100 ==360 ?0 : timestamp /100;
            map.rotateTo(rotacion, { duration: 0 });

            animacion = requestAnimationFrame(rotarCamara);
        }


        function finalRotarCamara() {

            cancelAnimationFrame(animacion);
        }   
  • LLamamos y controlamos funciones de rotacion en mapa-rutas3d.html
<html>
    <head>
    <meta charset='utf-8' />
    <title>Mapa rutas 3D</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />
    <link href='css/estilobase.css' rel='stylesheet' />

    <script src='js/3d.js'></script>
    <script src='js/rutas.js'></script>
    <script>
        //Añadir vuestor token!!
        var map;
        function init() {
            mapboxgl.accessToken =
                'pk.eyJ1IjoiZ2lzbWFzdGVybTIiLCJhIjoiY2plZHhubTQxMTNoYzMza3Rqa3kxYTdrOCJ9.53B1E6mKD_EQOVb2Y0-SsA';
             map = new mapboxgl.Map({
                container: 'map',
                style: 'mapbox://styles/mapbox/satellite-streets-v10',
                center: [1.77878, 41.60044],
                zoom: 14,
                attributionControl: false,
                pitch: 45,
                hash: true
            });

            map.addControl(new mapboxgl.AttributionControl({ compact: true }));
            map.addControl(new mapboxgl.NavigationControl());

            map.on('load', function () {
             add3D('mapbox-dem');
             addRutas();
            rotarCamara(0);

            }); //fin onload      

            map.on("click",function(e){
                finalRotarCamara()

                });
            map.on("zoomstart",function(e){
                finalRotarCamara()

                });  

            map.on("zoomend",function(e){
                rotarCamara(0);

            });          

        } // final init
    </script>
    </head>

    <body onload="init()">
        <div class="panelTopIzquierda">
            <select onChange="zoomToRutas(this.value)">
                <option selected value="14/41.60044/1.77878">Ruta 1</option>
                <option value="12.96/41.76589/2.30274">Ruta 2</option>
                <option value="13.04/42.31892/3.26054">Ruta 3</option>
            </select>
         </div>
        <div id="map"></div>
    </body>

    </html>

Servicios WMS y plugins

Ejemplo comparar Ortos del año 1945-46 (Vuelo Americano B) y Orto actual

WMS Ortos Históricas https://www.icgc.cat/es/Administracion-y-empresa/Servicios/Servicios-en-linea-Geoservicios/WMS-Ortoimatges/WMS-Ortofotos

  • Creamos página mapbox-compare.html
<html>

<head>
    <meta charset='utf-8' />
    <title>Comparador</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />
    <script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-compare/v0.4.0/mapbox-gl-compare.js"></script>
    <link rel="stylesheet"
        href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-compare/v0.4.0/mapbox-gl-compare.css"
        type="text/css" />
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }

        .map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    </style>
    <script>
        //Añadir vuestor token!!
        var map;
        function init() {
            mapboxgl.accessToken =
                'pk.eyJ1IjoiZ2lzbWFzdGVybTIiLCJhIjoiY2plZHhubTQxMTNoYzMza3Rqa3kxYTdrOCJ9.53B1E6mKD_EQOVb2Y0-SsA';


            var mapa1 = new mapboxgl.Map({
                container: 'mapa1',
                style: 'mapbox://styles/mapbox/satellite-v9',
                center: [2.16859, 41.3954],
                zoom: 13,
                attributionControl: false,
            });

            var mapa2 = new mapboxgl.Map({
                container: 'mapa2',
                style: 'mapbox://styles/mapbox/light-v10',
                center: [2.16859, 41.3954],
                zoom: 13,
                attributionControl: false,
            });

            /* ejemplos capas
            ortofoto_blanc_i_negre_1945,
            ortofoto_blanc_i_negre_1956,
            ortofoto_blanc_i_negre_1970-1977
            */
            mapa2.on('load', function () {
                mapa2.addSource("orto1945", {
                    type: "raster",
                    tiles: [ 
                        "https://geoserveis.icgc.cat/servei/catalunya/orto-territorial/wms?layers=ortofoto_blanc_i_negre_1945&bbox={bbox-epsg-3857}&format=image/png&styles=&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=512&height=512",
                    ],
                    tileSize: 512,
                    maxzoom: 19,
                    minZoom: 7.5,
                });
                //  ovab5m
                mapa2.addLayer({
                    id: "orto1945",
                    source: "orto1945",
                    type: "raster",
                    maxzoom: 18

                });
            })


            var map = new mapboxgl.Compare(mapa1, mapa2, "#comparador");

        } // final init
    </script>
</head>

<body onload="init()">
    <div id="comparador">
        <div id="mapa1" class="map"></div>
        <div id="mapa2" class="map"></div>
    </div>
</body>

</html>

Si quisieramos que fuera un estilo propio

    var miestilo= {
        version: 8,
        center: [1.537786, 41.837539],
        zoom: 12,
        bearing: 0,
        pitch: 0,
        sources: {
            orto1945: {
                type: "raster",
                tiles: [
                     "https://geoserveis.icgc.cat/servei/catalunya/orto-territorial/wms?layers=ortofoto_blanc_i_negre_1945&bbox={bbox-epsg-3857}&format=image/png&styles=&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=512&height=512",
                ],
                tileSize: 512,
                maxzoom: 19,
                minZoom: 7.5,
            },

        },
        sprite: "https://tilemaps.icgc.cat/tileserver/sprites/geologic/sprite",
        glyphs:
            "https://tilemaps.icgc.cat/tileserver/glyphs/{fontstack}/{range}.pbf",
        layers: [
            {
                id: "orto1945",
                source: "orto1945",
                type: "raster",
                maxzoom: 18

            },

        ],
    };
  • Creamos página mapbox-compare2.html y tendria este aspecto
<html>
<head>
    <meta charset='utf-8' />
    <title>Comparador 2</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.js'></script>
    <link href='https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapbox-gl.css' rel='stylesheet' />
    <script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-compare/v0.4.0/mapbox-gl-compare.js"></script>
    <link rel="stylesheet"
        href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-compare/v0.4.0/mapbox-gl-compare.css"
        type="text/css" />
    <style>
        body {
            margin: 0;
            padding: 0;
            overflow: hidden
        }
        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
        .map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
        }
    </style>
    <script>
        var map;
        var miestilo = {
            version: 8,
            center: [1.537786, 41.837539],
            zoom: 12,
            bearing: 0,
            pitch: 0,
            sources: {
                orto1945: {
                    type: "raster",
                    tiles: [
                        "https://geoserveis.icgc.cat/servei/catalunya/orto-territorial/wms?layers=ortofoto_blanc_i_negre_1945&bbox={bbox-epsg-3857}&format=image/png&styles=&service=WMS&version=1.1.1&request=GetMap&srs=EPSG:3857&transparent=true&width=512&height=512",
                    ],
                    tileSize: 512,
                    maxzoom: 19,
                    minZoom: 7.5,
                },
            },
            sprite: "https://tilemaps.icgc.cat/tileserver/sprites/geologic/sprite",
            glyphs:
                "https://tilemaps.icgc.cat/tileserver/glyphs/{fontstack}/{range}.pbf",
            layers: [
                {
                    id: "orto1945",
                    source: "orto1945",
                    type: "raster",
                    maxzoom: 18
                },
            ],
        };
        function init() {
            //Añadir vuestor token!!
            mapboxgl.accessToken =
                'pk.eyJ1IjoiZ2lzbWFzdGVybTIiLCJhIjoiY2plZHhubTQxMTNoYzMza3Rqa3kxYTdrOCJ9.53B1E6mKD_EQOVb2Y0-SsA';
            var mapa1 = new mapboxgl.Map({
                container: 'mapa1',
                style: 'mapbox://styles/mapbox/satellite-v9',
                center: [2.16859, 41.3954],
                zoom: 13,
                attributionControl: false,
            });
            var mapa2 = new mapboxgl.Map({
                container: 'mapa2',
                style: miestilo,
                center: [2.16859, 41.3954],
                zoom: 13,
                attributionControl: false,
            });
            var map = new mapboxgl.Compare(mapa1, mapa2, "#comparador");
        } // final init
    </script>
</head>
<body onload="init()">
    <div id="comparador">
        <div id="mapa1" class="map"></div>
        <div id="mapa2" class="map"></div>
    </div>
</body>
</html>

¿Subimos el ejemplo al GitHub?

    git pull
    git add .
    git commit -m "ejemplos"
    git push