Improve icon-sprite-webgl example code

Should load slightly faster now by adding the source only after all
features are available, this avoids dispatching the addfeature event
for each of the 80000 features.
Use webgl tile layer for the background so the canvas can be shared
between both layers.
This commit is contained in:
Maximilian Krög
2022-05-26 18:05:47 +02:00
parent 03f3e619f2
commit 8d8f4fd961

View File

@@ -1,11 +1,11 @@
import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js';
import Point from '../src/ol/geom/Point.js';
import TileLayer from '../src/ol/layer/Tile.js';
import TileLayer from '../src/ol/layer/WebGLTile.js';
import VectorSource from '../src/ol/source/Vector.js';
import View from '../src/ol/View.js';
import WebGLPointsLayer from '../src/ol/layer/WebGLPoints.js';
import XYZ from '../src/ol/source/XYZ.js';
import {Vector} from '../src/ol/source.js';
import {fromLonLat} from '../src/ol/proj.js';
const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB';
@@ -31,11 +31,6 @@ const map = new Map({
}),
});
const vectorSource = new Vector({
features: [],
attributions: 'National UFO Reporting Center',
});
const oldColor = [255, 160, 110];
const newColor = [180, 255, 200];
const size = 16;
@@ -45,10 +40,9 @@ const style = {
filterShape: 'all',
},
filter: [
'case',
['!=', ['var', 'filterShape'], 'all'],
['==', ['get', 'shape'], ['var', 'filterShape']],
true,
'any',
['==', ['var', 'filterShape'], 'all'],
['==', ['var', 'filterShape'], ['get', 'shape']],
],
symbol: {
symbolType: 'image',
@@ -87,24 +81,22 @@ const style = {
},
};
// key is shape name, value is sightings count
const shapeTypes = {
all: 0,
};
const shapeSelect = document.getElementById('shape-filter');
shapeSelect.addEventListener('input', function () {
style.variables.filterShape =
shapeSelect.options[shapeSelect.selectedIndex].value;
style.variables.filterShape = shapeSelect.value;
map.render();
});
function fillShapeSelect() {
function fillShapeSelect(shapeTypes) {
Object.keys(shapeTypes)
.sort(function (a, b) {
return shapeTypes[b] - shapeTypes[a];
})
.forEach(function (shape) {
const option = document.createElement('option');
option.text = `${shape} (${shapeTypes[shape]} sightings)`;
const sightings = shapeTypes[shape];
option.text = `${shape} (${sightings} sighting${
sightings === 1 ? '' : 's'
})`;
option.value = shape;
shapeSelect.appendChild(option);
});
@@ -112,62 +104,56 @@ function fillShapeSelect() {
const client = new XMLHttpRequest();
client.open('GET', 'data/csv/ufo_sighting_data.csv');
client.onload = function () {
client.addEventListener('load', function () {
const csv = client.responseText;
// key is shape name, value is sightings count
const shapeTypes = {};
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(',');
while ((curIndex = csv.indexOf('\n', prevIndex)) !== -1) {
const line = csv.substring(prevIndex, curIndex).split(',');
prevIndex = curIndex + 1;
const coords = fromLonLat([parseFloat(line[5]), parseFloat(line[4])]);
const coords = [parseFloat(line[5]), parseFloat(line[4])];
const shape = line[2];
shapeTypes[shape] = (shapeTypes[shape] ? shapeTypes[shape] : 0) + 1;
shapeTypes['all']++;
shapeTypes[shape] = (shapeTypes[shape] || 0) + 1;
features.push(
new Feature({
datetime: line[0],
year: parseInt(/[0-9]{4}/.exec(line[0])[0]), // extract the year as int
year: parseInt(/[0-9]{4}/.exec(line[0])[0], 10), // extract the year as int
shape: shape,
duration: line[3],
geometry: new Point(coords),
geometry: new Point(fromLonLat(coords)),
})
);
}
vectorSource.addFeatures(features);
fillShapeSelect();
};
client.send();
shapeTypes['all'] = features.length;
map.addLayer(
new WebGLPointsLayer({
source: vectorSource,
source: new VectorSource({
features: features,
attributions: 'National UFO Reporting Center',
}),
style: style,
})
);
fillShapeSelect(shapeTypes);
});
client.send();
const info = document.getElementById('info');
map.on('pointermove', function (evt) {
if (map.getView().getInteracting() || map.getView().getAnimating()) {
return;
}
const pixel = evt.pixel;
info.innerText = '';
map.forEachFeatureAtPixel(pixel, function (feature) {
const text = map.forEachFeatureAtPixel(evt.pixel, function (feature) {
const datetime = feature.get('datetime');
const duration = feature.get('duration');
const shape = feature.get('shape');
info.innerText =
'On ' +
datetime +
', lasted ' +
duration +
' seconds and had a "' +
shape +
'" shape.';
return `On ${datetime}, lasted ${duration} seconds and had a "${shape}" shape.`;
});
info.innerText = text || '';
});