Move buffer dissolve to worker
This commit is contained in:
+17
-2
@@ -8,11 +8,14 @@ import {
|
||||
tagsToHTML
|
||||
} from './overpass.ts';
|
||||
import { Circle, FeatureGroup, Polygon } from 'leaflet';
|
||||
// @ts-ignore
|
||||
import { buffer, truncate } from '@turf/turf';
|
||||
|
||||
export class ExclusionCircle extends FeatureGroup<Polygon | Circle> {
|
||||
readonly id: string;
|
||||
readonly element: NWRElement;
|
||||
readonly reason: BannedArea;
|
||||
readonly buffer: ReturnType<buffer> | null = null;
|
||||
|
||||
constructor(e: NWRElement) {
|
||||
super();
|
||||
@@ -36,7 +39,9 @@ export class ExclusionCircle extends FeatureGroup<Polygon | Circle> {
|
||||
if (isWay(m)) {
|
||||
m.geometry.length > 3
|
||||
? this.addLayer(this.getPolygon(m.geometry, color))
|
||||
: this.addLayer(this.getCircle(m.geometry[0], color));
|
||||
: m.geometry.forEach((g) =>
|
||||
this.addLayer(this.getCircle(g, color))
|
||||
);
|
||||
} else if (isNode(m)) {
|
||||
this.addLayer(this.getCircle(m, color));
|
||||
}
|
||||
@@ -47,7 +52,17 @@ export class ExclusionCircle extends FeatureGroup<Polygon | Circle> {
|
||||
this.id = e.id;
|
||||
this.element = e;
|
||||
this.reason = reason;
|
||||
|
||||
try {
|
||||
this.buffer = truncate(
|
||||
buffer(this.toGeoJSON(), 100, { units: 'meters' })
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`Buffer calc for id=${e.id}, type=${e.type} failed`,
|
||||
e,
|
||||
err
|
||||
);
|
||||
}
|
||||
this.bindPopup(
|
||||
`<div class="whitespace-pre-wrap flex flex-col gap-3">${tagsToHTML({ reason, ...e.tags })}<a href="https://www.openstreetmap.org/${e.type}/${e.id}" target="_blank">↗ Auf OpenStreetMap öffnen</a></div>`,
|
||||
{ maxWidth: 500 }
|
||||
|
||||
+20
-37
@@ -6,21 +6,20 @@ import {
|
||||
FeatureGroup,
|
||||
GeoJSON,
|
||||
Map as LMap,
|
||||
Polygon,
|
||||
Popup,
|
||||
TileLayer
|
||||
} from 'leaflet';
|
||||
import 'leaflet-easybutton';
|
||||
import { BannedArea, BannedAreas, NWRElement } from './overpass.ts';
|
||||
import { colorMap, ExclusionCircle } from './ExclusionCircle.ts';
|
||||
import {
|
||||
buffer,
|
||||
dissolve,
|
||||
featureCollection,
|
||||
FeatureCollection,
|
||||
truncate
|
||||
} from '@turf/turf';
|
||||
// @ts-ignore
|
||||
import { FeatureCollection, truncate } from '@turf/turf';
|
||||
// @ts-ignore
|
||||
import type { Feature } from '@turf/helpers';
|
||||
import workerUrl from './worker/worker.ts?worker&url';
|
||||
|
||||
const worker = new Worker(workerUrl, { type: 'module' });
|
||||
|
||||
const m_mono = new TileLayer(
|
||||
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
@@ -70,8 +69,18 @@ map.on('moveend', async () => {
|
||||
});
|
||||
let loading = false;
|
||||
|
||||
worker.addEventListener(
|
||||
'message',
|
||||
(b: MessageEvent<FeatureCollection<Polygon>>) => {
|
||||
exclusionZone.clearLayers();
|
||||
const zone = new GeoJSON(b.data, {
|
||||
style: { color: 'red', fillOpacity: 0.1, weight: 1 }
|
||||
});
|
||||
exclusionZone.addLayer(zone);
|
||||
exclusionZone.bringToBack();
|
||||
}
|
||||
);
|
||||
function showBuffer() {
|
||||
console.time('prepare');
|
||||
map.attributionControl.setPrefix('Berechne Zone');
|
||||
const fs = Object.entries(buffers)
|
||||
.filter(([k]) => map.hasLayer(features[k as keyof typeof features]))
|
||||
@@ -83,22 +92,7 @@ function showBuffer() {
|
||||
});
|
||||
|
||||
if (fs.length > 0) {
|
||||
exclusionZone.clearLayers();
|
||||
console.timeEnd('prepare');
|
||||
try {
|
||||
console.time('dissolve');
|
||||
const b = dissolve(featureCollection(fs));
|
||||
const zone = new GeoJSON(b, {
|
||||
style: { color: 'red', fillOpacity: 0.1, weight: 1 }
|
||||
});
|
||||
console.timeEnd('dissolve');
|
||||
console.time('render');
|
||||
exclusionZone.addLayer(zone);
|
||||
console.timeEnd('render');
|
||||
exclusionZone.bringToBack();
|
||||
} catch (err) {
|
||||
console.error('dissolve', err);
|
||||
}
|
||||
worker.postMessage(fs);
|
||||
}
|
||||
map.attributionControl.setPrefix('');
|
||||
}
|
||||
@@ -145,7 +139,6 @@ out geom;`;
|
||||
.then((r) => r.elements as NWRElement[]);
|
||||
|
||||
loading = false;
|
||||
console.time('parse');
|
||||
map.attributionControl.setPrefix('Berechne Orte...');
|
||||
const ids = elements.map((e) => e.id);
|
||||
const exclude: ExclusionCircle[] = [];
|
||||
@@ -168,20 +161,10 @@ out geom;`;
|
||||
}
|
||||
|
||||
features[marker.reason].addLayer(marker);
|
||||
try {
|
||||
const b = buffer(marker.toGeoJSON(), 100, { units: 'meters' });
|
||||
|
||||
// new GeoJSON(b).addTo(map);
|
||||
buffers[marker.reason].push(truncate(b));
|
||||
} catch (err) {
|
||||
console.error(
|
||||
`Buffer calc for id=${e.id}, type=${e.type} failed`,
|
||||
e,
|
||||
err
|
||||
);
|
||||
if (marker.buffer) {
|
||||
buffers[marker.reason].push(marker.buffer);
|
||||
}
|
||||
});
|
||||
console.timeEnd('parse');
|
||||
|
||||
queueMicrotask(showBuffer);
|
||||
map.attributionControl.setPrefix('');
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// @ts-ignore
|
||||
import { Feature } from '@turf/helpers';
|
||||
// @ts-ignore
|
||||
import { dissolve, featureCollection } from '@turf/turf';
|
||||
|
||||
self.onmessage = function (e: MessageEvent<Feature[]>) {
|
||||
try {
|
||||
const b = dissolve(featureCollection(e.data));
|
||||
self.postMessage(b);
|
||||
} catch (err) {
|
||||
console.error('dissolve', err);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user