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