Having hit detection enabled has an overhead as it means continously generating additional render instructions and rendering to an offscreen canvas
142 lines
3.4 KiB
JavaScript
142 lines
3.4 KiB
JavaScript
import Map from '../src/ol/Map.js';
|
|
import View from '../src/ol/View.js';
|
|
import TileLayer from '../src/ol/layer/Tile.js';
|
|
import Feature from '../src/ol/Feature.js';
|
|
import Point from '../src/ol/geom/Point.js';
|
|
import {Vector} from '../src/ol/source.js';
|
|
import {fromLonLat} from '../src/ol/proj.js';
|
|
import Stamen from '../src/ol/source/Stamen.js';
|
|
import WebGLPointsLayer from '../src/ol/layer/WebGLPoints.js';
|
|
|
|
const vectorSource = new Vector({
|
|
attributions: 'NASA'
|
|
});
|
|
|
|
const oldColor = 'rgba(242,56,22,0.61)';
|
|
const newColor = '#ffe52c';
|
|
const period = 12; // animation period in seconds
|
|
const animRatio =
|
|
['^',
|
|
['/',
|
|
['mod',
|
|
['+',
|
|
['time'],
|
|
[
|
|
'interpolate',
|
|
['linear'],
|
|
['get', 'year'],
|
|
1850, 0,
|
|
2015, period
|
|
]
|
|
],
|
|
period
|
|
],
|
|
period
|
|
],
|
|
0.5
|
|
];
|
|
|
|
const style = {
|
|
variables: {
|
|
minYear: 1850,
|
|
maxYear: 2015
|
|
},
|
|
filter: ['between', ['get', 'year'], ['var', 'minYear'], ['var', 'maxYear']],
|
|
symbol: {
|
|
symbolType: 'circle',
|
|
size: ['*',
|
|
['interpolate', ['linear'], ['get', 'mass'], 0, 8, 200000, 26],
|
|
['-', 1.75, ['*', animRatio, 0.75]]
|
|
],
|
|
color: ['interpolate',
|
|
['linear'],
|
|
animRatio,
|
|
0, newColor,
|
|
1, oldColor
|
|
],
|
|
opacity: ['-', 1.0, ['*', animRatio, 0.75]]
|
|
}
|
|
};
|
|
|
|
// handle input values & events
|
|
const minYearInput = document.getElementById('min-year');
|
|
const maxYearInput = document.getElementById('max-year');
|
|
|
|
function updateMinYear() {
|
|
style.variables.minYear = parseInt(minYearInput.value);
|
|
updateStatusText();
|
|
}
|
|
function updateMaxYear() {
|
|
style.variables.maxYear = parseInt(maxYearInput.value);
|
|
updateStatusText();
|
|
}
|
|
function updateStatusText() {
|
|
const div = document.getElementById('status');
|
|
div.querySelector('span.min-year').textContent = minYearInput.value;
|
|
div.querySelector('span.max-year').textContent = maxYearInput.value;
|
|
}
|
|
|
|
minYearInput.addEventListener('input', updateMinYear);
|
|
minYearInput.addEventListener('change', updateMinYear);
|
|
maxYearInput.addEventListener('input', updateMaxYear);
|
|
maxYearInput.addEventListener('change', updateMaxYear);
|
|
updateStatusText();
|
|
|
|
// load data
|
|
const client = new XMLHttpRequest();
|
|
client.open('GET', 'data/csv/meteorite_landings.csv');
|
|
client.onload = function() {
|
|
const csv = client.responseText;
|
|
const features = [];
|
|
|
|
let prevIndex = csv.indexOf('\n') + 1; // scan past the header line
|
|
|
|
let curIndex;
|
|
while ((curIndex = csv.indexOf('\n', prevIndex)) != -1) {
|
|
const line = csv.substr(prevIndex, curIndex - prevIndex).split(',');
|
|
prevIndex = curIndex + 1;
|
|
|
|
const coords = fromLonLat([parseFloat(line[4]), parseFloat(line[3])]);
|
|
if (isNaN(coords[0]) || isNaN(coords[1])) {
|
|
// guard against bad data
|
|
continue;
|
|
}
|
|
|
|
features.push(new Feature({
|
|
mass: parseFloat(line[1]) || 0,
|
|
year: parseInt(line[2]) || 0,
|
|
geometry: new Point(coords)
|
|
}));
|
|
}
|
|
|
|
vectorSource.addFeatures(features);
|
|
};
|
|
client.send();
|
|
|
|
const map = new Map({
|
|
layers: [
|
|
new TileLayer({
|
|
source: new Stamen({
|
|
layer: 'toner'
|
|
})
|
|
}),
|
|
new WebGLPointsLayer({
|
|
style: style,
|
|
source: vectorSource,
|
|
disableHitDetection: true
|
|
})
|
|
],
|
|
target: document.getElementById('map'),
|
|
view: new View({
|
|
center: [0, 0],
|
|
zoom: 2
|
|
})
|
|
});
|
|
|
|
// animate the map
|
|
function animate() {
|
|
map.render();
|
|
window.requestAnimationFrame(animate);
|
|
}
|
|
animate();
|