let tableData_global = []; // fetched date let flags; const doFetchCountries = () => { $.ajax({ url: "/items" }).done((data) => { if (data instanceof Array) tableData_global = data; else { tableData_global = []; tableData_global.push(data); } }); }; window.onload = () => { doFetchCountries(); setup(); }; // mappa const options = { lat: 0, lng: 0, zoom: 4, style: 'mapbox://styles/mapbox/traffic-night-v2', pitch: 50, } let WIDTH; let HEIGHT; const key = 'pk.eyJ1IjoicmljYXJkb2xhbmduZXIiLCJhIjoiY2pxano2enh2MG1qazN4bm5lajIzeDl3eiJ9.wK0MtuxLgJxDcGUksKMeKg'; let mappa; let myMap; let canvas; // three let scene; let camera; let renderer; var light; function setup_flags() { flags = [ { id: "birth_rate_per_1000", name: "Birth Rate / 100", enabled: true, color: 0xff0000 }, { id: "cell_phones_per_100", name: "Cell Phones / 100", enabled: false, color: 0x0ff000 }, { id: "children_per_woman", name: "Children / Woman", enabled: false, color: 0x00ff00 }, { id: "electricity_consumption_per_capita", name: "Electricity Consumption / Capita", enabled: false, color: 0x000ff0 }, { id: "gdp_per_capita", name: "GDP / Capita", enabled: false, color: 0x0000ff }, { id: "gdp_per_capita_growth", name: "GDP / Capita Growth", enabled: false, color: 0xf0000f }, { id: "inflation_annual", name: "Inflation Annual", enabled: false, color: 0xf000f0 }, { id: "internet_user_per_100", name: "Internet User / 100", enabled: false, color: 0x00f00f }, { id: "life_expectancy", name: "Life Expectancy", enabled: false, color: 0xf00f00 }, { id: "military_expenditure_percent_of_gdp", name: "Military Expenditure % of GDP", enabled: false, color: 0x0f00f0 }, ]; } function setup_checkboxes() { let checkboxes = ""; for (let i = 0; i < flags.length; i++) { let flag = flags[i]; checkboxes += ""; checkboxes += "\n"; } checkboxes = "
"; checkboxes += ""; checkboxes += "
"; let overlay = document.getElementById("overlay"); if (overlay != null) { overlay.innerHTML = checkboxes; } } function setup() { mappa = new Mappa('MapboxGL', key); myMap = mappa.tileMap(options); canvas = document.getElementById("mapa"); canvas.width = window.innerWidth; canvas.height = window.innerHeight; WIDTH = window.innerWidth; HEIGHT = window.innerHeight; camera = new THREE.PerspectiveCamera(75, WIDTH / HEIGHT, 0.1, 1000); camera.up = new THREE.Vector3(0, 0, 1); scene = new THREE.Scene(); renderer = new THREE.WebGLRenderer({ alpha: true, canvas: canvas }); light = new THREE.PointLight(0xffffff, 1, 1000); light.position.set(-50, -50, 100); light.castShadow = true; light.shadow.mapSize.width = 512; light.shadow.mapSize.height = 512; light.shadow.camera.near = 0.5; light.shadow.camera.far = 1000; renderer.setSize(WIDTH, HEIGHT); document.body.appendChild(renderer.domElement); myMap.overlay(canvas); myMap.onChange(update); setup_flags(); setup_checkboxes(); update(); } function setup_objects() { scene.remove.apply(scene, scene.children); scene.add(light); for (let i = 0; i < tableData_global.length; i++) { let long = tableData_global[i]["gps_long"]; let lat = tableData_global[i]["gps_lat"]; let enabled = 0; for (let j = 0; j < flags.length; j++) { let flag = flags[j]; if (flag.enabled) { let value = tableData_global[i][flag.id]; let height = value / 20.0; let geometry = new THREE.BoxGeometry(1, 1, height); let material = new THREE.MeshBasicMaterial({ color: flag.color }); let cube = new THREE.Mesh(geometry, material); cube.castShadow = true; cube.receiveShadow = true; const pos = myMap.latLngToPixel(lat, long); const vector = new THREE.Vector3(); vector.set((pos.x / WIDTH) * 2 - 1, -(pos.y / HEIGHT) * 2 + 1, 0.5); vector.unproject(camera); const dir = vector.sub(camera.position).normalize(); const distance = -camera.position.z / dir.z; const newPos = camera.position.clone().add(dir.multiplyScalar(distance)); cube.position.set(newPos.x + enabled, newPos.y, newPos.z + height / 2); scene.add(cube); enabled++; } } } } function draw() { } function update() { setup_objects(); let pos = myMap.pixelToLatLng(window.innerWidth / 2, window.innerHeight / 2); let zoom = myMap.zoom(); let view; if (zoom == 0) { view = new THREE.Vector3(0, -10.0, 30.0); } else { view = new THREE.Vector3(0, -10 + (2.5 * (4 - zoom)), 30 + (7.5 * (4 - zoom))); } let center = new THREE.Vector3(pos.x, pos.y, 0); camera.position.set(view.x + center.x, view.y + center.y, view.z + center.z); camera.lookAt(center); renderer.render(scene, camera); }