2019-01-16 14:03:18 +00:00
|
|
|
let tableData_global = []; // fetched date
|
|
|
|
let flags;
|
2019-01-09 11:25:28 +00:00
|
|
|
|
2019-01-11 11:31:36 +00:00
|
|
|
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();
|
|
|
|
};
|
|
|
|
|
2019-01-16 11:00:42 +00:00
|
|
|
// mappa
|
2019-01-11 11:31:36 +00:00
|
|
|
const options = {
|
|
|
|
lat: 0,
|
|
|
|
lng: 0,
|
|
|
|
zoom: 4,
|
2019-01-16 11:00:42 +00:00
|
|
|
style: 'mapbox://styles/mapbox/traffic-night-v2',
|
|
|
|
pitch: 50,
|
2019-01-11 11:31:36 +00:00
|
|
|
}
|
2019-01-09 11:25:28 +00:00
|
|
|
|
2019-01-16 16:03:15 +00:00
|
|
|
let WIDTH;
|
|
|
|
let HEIGHT;
|
|
|
|
|
2019-01-16 11:00:42 +00:00
|
|
|
const key = 'pk.eyJ1IjoicmljYXJkb2xhbmduZXIiLCJhIjoiY2pxano2enh2MG1qazN4bm5lajIzeDl3eiJ9.wK0MtuxLgJxDcGUksKMeKg';
|
|
|
|
let mappa;
|
|
|
|
let myMap;
|
|
|
|
let canvas;
|
|
|
|
|
|
|
|
// three
|
|
|
|
let scene;
|
|
|
|
let camera;
|
|
|
|
let renderer;
|
2019-01-16 16:03:15 +00:00
|
|
|
var light;
|
2019-01-16 14:03:18 +00:00
|
|
|
|
2019-01-17 14:59:57 +00:00
|
|
|
function setup_flags() {
|
2019-01-16 14:03:18 +00:00
|
|
|
flags = [
|
2019-01-19 10:53:48 +00:00
|
|
|
{ id: "birth_rate_per_1000", name: "Birth Rate / 100", enabled: true, color: 0xff0000, scale: 0.1 },
|
|
|
|
{ id: "cell_phones_per_100", name: "Cell Phones / 100", enabled: false, color: 0xFFAA00, scale: 0.05 },
|
|
|
|
{ id: "children_per_woman", name: "Children / Woman", enabled: false, color: 0xAAFF00, scale: 1.0 },
|
|
|
|
{ id: "electricity_consumption_per_capita", name: "Electricity Consumption / Capita", enabled: false, color: 0x005AFF, scale: 0.00004 },
|
|
|
|
{ id: "gdp_per_capita", name: "GDP / Capita", enabled: false, color: 0xFFFF00, scale: 0.0001 },
|
|
|
|
{ id: "gdp_per_capita_growth", name: "GDP / Capita Growth", enabled: false, color: 0xE700FF, scale: 0.5 },
|
|
|
|
{ id: "inflation_annual", name: "Inflation Annual", enabled: false, color: 0x00F9FF, scale: 0.2 },
|
|
|
|
{ id: "internet_user_per_100", name: "Internet User / 100", enabled: false, color: 0xFF009A, scale: 0.05 },
|
|
|
|
{ id: "life_expectancy", name: "Life Expectancy", enabled: false, color: 0x00FF10, scale: 0.05 },
|
|
|
|
{ id: "military_expenditure_percent_of_gdp", name: "Military Expenditure % of GDP", enabled: false, color: 0x0027FF, scale: 1.0 },
|
2019-01-16 14:03:18 +00:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2019-01-17 14:59:57 +00:00
|
|
|
function setup_checkboxes() {
|
|
|
|
let checkboxes = "<table>";
|
|
|
|
|
|
|
|
for (let i = 0; i < flags.length; i++) {
|
|
|
|
let flag = flags[i];
|
|
|
|
|
|
|
|
checkboxes += "<tr><td>";
|
|
|
|
checkboxes += "<input type=\"checkbox\"";
|
2019-01-19 10:53:48 +00:00
|
|
|
checkboxes += " id=\"" + flag.id + "\"";
|
|
|
|
checkboxes += " onclick=\"checkbox_clicked('" + flag.id + "')\"";
|
2019-01-17 14:59:57 +00:00
|
|
|
|
|
|
|
if (flag.enabled) {
|
|
|
|
checkboxes += " checked";
|
|
|
|
}
|
|
|
|
|
|
|
|
checkboxes += ">" + flag.name + "</input>";
|
|
|
|
|
|
|
|
checkboxes += "</td></tr>";
|
|
|
|
checkboxes += "\n";
|
|
|
|
}
|
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
checkboxes += "</table>";
|
2019-01-17 14:59:57 +00:00
|
|
|
|
|
|
|
let overlay = document.getElementById("overlay");
|
|
|
|
|
|
|
|
if (overlay != null) {
|
|
|
|
overlay.innerHTML = checkboxes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
function checkbox_clicked(id) {
|
|
|
|
let checkbox = document.getElementById(id);
|
|
|
|
|
|
|
|
if (checkbox == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let i = 0; i < flags.length; i++) {
|
|
|
|
let flag = flags[i];
|
|
|
|
|
|
|
|
if (flag.id == id) {
|
|
|
|
flag.enabled = checkbox.checked;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
update();
|
|
|
|
}
|
2019-01-16 11:00:42 +00:00
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
function set_window_extents() {
|
2019-01-16 16:03:15 +00:00
|
|
|
WIDTH = window.innerWidth;
|
|
|
|
HEIGHT = window.innerHeight;
|
2019-01-16 14:03:18 +00:00
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
canvas.width = WIDTH;
|
|
|
|
canvas.height = HEIGHT;
|
|
|
|
|
|
|
|
renderer.setSize(WIDTH, HEIGHT);
|
|
|
|
|
2019-01-16 16:03:15 +00:00
|
|
|
camera = new THREE.PerspectiveCamera(75, WIDTH / HEIGHT, 0.1, 1000);
|
2019-01-16 14:03:18 +00:00
|
|
|
camera.up = new THREE.Vector3(0, 0, 1);
|
2019-01-19 10:53:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function setup() {
|
|
|
|
mappa = new Mappa('MapboxGL', key);
|
|
|
|
myMap = mappa.tileMap(options);
|
|
|
|
canvas = document.getElementById("mapa");
|
2019-01-16 14:03:18 +00:00
|
|
|
|
|
|
|
scene = new THREE.Scene();
|
2019-01-16 11:00:42 +00:00
|
|
|
renderer = new THREE.WebGLRenderer({ alpha: true, canvas: canvas });
|
|
|
|
|
2019-01-16 16:03:15 +00:00
|
|
|
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;
|
|
|
|
|
2019-01-16 11:00:42 +00:00
|
|
|
document.body.appendChild(renderer.domElement);
|
|
|
|
|
2019-01-09 11:25:28 +00:00
|
|
|
myMap.overlay(canvas);
|
2019-01-16 16:03:15 +00:00
|
|
|
myMap.onChange(update);
|
2019-01-16 11:00:42 +00:00
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
set_window_extents();
|
2019-01-17 14:59:57 +00:00
|
|
|
setup_flags();
|
|
|
|
setup_checkboxes();
|
2019-01-16 16:03:15 +00:00
|
|
|
|
|
|
|
update();
|
2019-01-16 14:03:18 +00:00
|
|
|
}
|
|
|
|
|
2019-01-16 16:03:15 +00:00
|
|
|
function setup_objects() {
|
|
|
|
scene.remove.apply(scene, scene.children);
|
|
|
|
scene.add(light);
|
2019-01-16 14:03:18 +00:00
|
|
|
|
|
|
|
for (let i = 0; i < tableData_global.length; i++) {
|
|
|
|
let long = tableData_global[i]["gps_long"];
|
|
|
|
let lat = tableData_global[i]["gps_lat"];
|
2019-01-16 16:03:15 +00:00
|
|
|
let enabled = 0;
|
2019-01-16 14:03:18 +00:00
|
|
|
|
|
|
|
for (let j = 0; j < flags.length; j++) {
|
|
|
|
let flag = flags[j];
|
|
|
|
|
|
|
|
if (flag.enabled) {
|
|
|
|
let value = tableData_global[i][flag.id];
|
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
let height = value * flag.scale;
|
2019-01-16 16:03:15 +00:00
|
|
|
let geometry = new THREE.BoxGeometry(1, 1, height);
|
|
|
|
let material = new THREE.MeshBasicMaterial({ color: flag.color });
|
2019-01-16 14:03:18 +00:00
|
|
|
let cube = new THREE.Mesh(geometry, material);
|
2019-01-16 16:03:15 +00:00
|
|
|
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);
|
|
|
|
|
2019-01-16 14:03:18 +00:00
|
|
|
scene.add(cube);
|
2019-01-16 16:03:15 +00:00
|
|
|
|
|
|
|
enabled++;
|
2019-01-16 14:03:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2019-01-09 11:25:28 +00:00
|
|
|
}
|
2019-01-11 11:31:36 +00:00
|
|
|
|
2019-01-16 11:00:42 +00:00
|
|
|
function draw() { }
|
2019-01-11 11:31:36 +00:00
|
|
|
|
2019-01-16 16:03:15 +00:00
|
|
|
function update() {
|
|
|
|
setup_objects();
|
|
|
|
|
2019-01-19 10:53:48 +00:00
|
|
|
let pos = myMap.pixelToLatLng(WIDTH / 2, HEIGHT / 2);
|
2019-01-17 14:59:57 +00:00
|
|
|
|
|
|
|
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)));
|
|
|
|
}
|
2019-01-16 14:03:18 +00:00
|
|
|
|
2019-01-17 14:59:57 +00:00
|
|
|
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);
|
2019-01-16 14:03:18 +00:00
|
|
|
|
2019-01-16 11:00:42 +00:00
|
|
|
renderer.render(scene, camera);
|
2019-01-19 10:53:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function on_resize() {
|
|
|
|
set_window_extents();
|
|
|
|
update();
|
2019-01-11 11:31:36 +00:00
|
|
|
}
|