<html>
        <head>
            <meta charset='utf-8' />
            <title>Vector-Tiles Sagrada Familia 3d ICGC</title>
            <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
            <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/98/three.min.js"></script>
            <script src="vendors/js/GLTFLoader.js"></script>
            <link href='https://cdn.skypack.dev/maplibre-gl/dist/mapbox-gl.css' rel='stylesheet' />
            <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
            <style>
                body {
                    margin: 0;
                    padding: 0;
                }
                #map {
                    position: absolute;
                    top: 0;
                    bottom: 0;
                    width: 100%;
                    height: 100%
                }
                #menu {
                    position: absolute;
                    z-index: 1000;
                    background: #fff;
                    padding: 10px;
                    font-family: 'Open Sans', sans-serif;
                    top: 5px;
                    left: 5px;
                    border-radius: 7px;
                    -webkit-box-shadow: 5px 5px 5px -5px rgba(0, 0, 0, 0.75);
                    -moz-box-shadow: 5px 5px 5px -5px rgba(0, 0, 0, 0.75);
                    box-shadow: 5px 5px 5px -5px rgba(0, 0, 0, 0.75);
                }
                #div_pitch {
                    position: absolute;
                    right: 10px;
                    top: 142px;
                    width: 30px;
                    z-index: 100;
                }
                .sliderClass {
                    position: absolute;
                    left: 10px;
                    top: 79px;
                    width: 130px;
                    z-index: 100;
                    display: none;
                    background-color: white;
                    padding: 10px;
                    border-radius: 4px;
                    font-size: 0.85em;
                    opacity: 0.9;
                }
            </style>
        </head>
        <body>
            <div id='menu'>
                <input id='icgc' type='radio' name='rtoggle' value='icgc' checked='checked'>
                <label for='icgc'>icgc</label>
                <input id='osm-bright' type='radio' name='rtoggle' value='osm-bright'>
                <label for='osm-bright'>osm-bright</label>
                <input id='positron' type='radio' name='rtoggle' value='positron'>
                <label for='positron'>positron</label>
                <input id='fulldark' type='radio' name='rtoggle' value='fulldark'>
                <label for='fulldark'>fulldark</label>
                <input id='night' type='radio' name='rtoggle' value='night'>
                <label for='night'>night</label>
                <input id='hibrid' type='radio' name='rtoggle' value='hibrid'>
                <label for='hibrid'>hibrid</label>
            </div>
            <div id='div_pitch' class="mapboxgl-ctrl-group mapboxgl-ctrl">
                <button id="bt_pitch" title="Perspectiva" class="mapboxgl-ctrl-icon glyphicon glyphicon-road"></button>
            </div>
            <div id="map"></div>
             <script type="module">
               import {Map, NavigationControl,GeolocateControl,AttributionControl} from 'https://cdn.skypack.dev/maplibre-gl';     
                const THREE = window.THREE;
                const loader = new THREE.GLTFLoader();
                let _gltf;
                let  currentTO;
               let  isRotating = false;
                const map = new Map({
                    container: 'map',
                    style: 'https://geoserveis.icgc.cat/contextmaps/icgc.json',
                    center: [2.174689, 41.403806],
                    zoom: 15.93,
                    maxZoom: 18,
                    hash: true,
                    bearing: -131.2,
                    pitch: 45
                });
                map.on('load', function () {
                    map.addControl(new NavigationControl());
                    map.addControl(new GeolocateControl({
                        positionOptions: {
                            enableHighAccuracy: true,
                            watchPosition: true
                        }
                    }));
                    loader.load(
                        // resource URL
                        'models/sf_0.01625.glb',
                        // called when the resource is loaded
                        function (gltf) {
                            _gltf = gltf;
                            add3DModel();
                            currentTO = setTimeout(startRotation, 2000);
                        },
                        // called while loading is progressing
                        function (xhr) {
                            console.log((xhr.loaded / xhr.total * 100) + '% loaded');
                        },
                        // called when loading has errors
                        function (error) {
                            console.log('An error happened', error);
                        }
                    );
                    map.on('styledata', function () {
                        setTimeout(function () {
                            if (map.isStyleLoaded()) {
                                add3DModel();
                            }
                        }, 2000);
                    });
                    map.on('zoomend', function (e) {
                        if (map.getZoom() >= 13) {
                            map.easeTo({
                                'pitch': 50
                            });
                        } else {
                            map.easeTo({
                                'pitch': 20
                            });
                        }
                    });
                });
                class ThreeICGCMODEL {
                    constructor() {
                        this.id = 'sagradaFamilia';
                        this.type = 'custom';
                        this.renderingMode = '3d';
                        this.translate = fromLL(2.174546, 41.403564);
                        this.scale = 0.000000037;
                        this.camera = new THREE.Camera();
                        this.scene = _gltf.scene;
                        this.scene.remove(this.scene.getObjectByName("Ambient"));
                        const directionalLight = new THREE.AmbientLight(0xffffff, 1.5);
                        directionalLight.name = "Ambient";
                        this.scene.add(directionalLight);
                    }
                    onAdd(map, gl) {
                        this.map = map;
                        this.renderer = new THREE.WebGLRenderer({
                            canvas: map.getCanvas(),
                            context: gl
                        });
                        this.renderer.autoClear = false;
                    }
                    render(gl, matrix) {
                        const m = new THREE.Matrix4().fromArray(matrix);
                        const l = new THREE.Matrix4()
                            .makeTranslation(this.translate[0], this.translate[1], this.translate[2])
                            .scale(new THREE.Vector3(this.scale, -this.scale, this.scale));
                        this.camera.projectionMatrix.elements = matrix;
                        this.camera.projectionMatrix = m.multiply(l);
                        this.renderer.state.reset();
                        // this.renderer.context.disable(this.renderer.context.DEPTH_TEST);
                        this.renderer.render(this.scene, this.camera);
                        this.map.triggerRepaint();
                    }
                }
                //Thank you!!!
                //https://bl.ocks.org/andrewharvey/7b61e9bdb4165e8832b7495c2a4f17f7
                const fromLL = function (lon, lat) {
                    // derived from https://gist.github.com/springmeyer/871897
                    const extent = 20037508.34;
                    const x = lon * extent / 180;
                    let y = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
                    y = y * extent / 180;
                    return [(x + extent) / (2 * extent), 1 - ((y + extent) / (2 * extent)), 0.000001];
                }
                const layerList = document.getElementById('menu');
                const inputs = layerList.getElementsByTagName('input');
                const button = document.getElementById('bt_pitch');
                function switchLayer(layer) {
                    const layerId = layer.target.id;
                    map.setStyle('https://geoserveis.icgc.cat/contextmaps/' + layerId + '.json');
                }
                function canviaPerspectiva() {
                    const pitch = parseInt(map.getPitch());
                    pitch == 60 ? pitch = 0 : pitch = pitch + 30;
                    map.easeTo({
                        'pitch': pitch
                    })
                };
                function add3DModel() {
                    if (!map.getLayer('sagradaFamilia')) {
                        map.addLayer(new ThreeICGCMODEL());
                    }
                }
                function startRotation() {
                    isRotating = true;
                    window.requestAnimationFrame(rotate);
                }
                map.on('mousemove', function () {
                    isRotating = false;
                    clearTimeout(currentTO);
                    currentTO = setTimeout(startRotation, 2000);
                });
                function rotate() {
                    if (isRotating) {
                        map.setBearing(map.getBearing() + 0.1);
                    }
                    window.requestAnimationFrame(rotate);
                }
                for (let  i = 0; i < inputs.length; i++) {
                    inputs[i].onclick = switchLayer;
                }
                button.onclick = canviaPerspectiva;
            </script>
        </body>
        </html>