Fix: stabilize rendering of linelayers

This commit is contained in:
Pieter Vander Vennet 2023-09-29 11:11:27 +02:00
parent 8f93b0d398
commit 055e5a801b

View file

@ -1,21 +1,21 @@
import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource";
import type { Map as MlMap } from "maplibre-gl" import type { Map as MlMap } from "maplibre-gl";
import { GeoJSONSource, Marker } from "maplibre-gl" import { GeoJSONSource, Marker } from "maplibre-gl";
import { ShowDataLayerOptions } from "./ShowDataLayerOptions" import { ShowDataLayerOptions } from "./ShowDataLayerOptions";
import { GeoOperations } from "../../Logic/GeoOperations" import { GeoOperations } from "../../Logic/GeoOperations";
import LayerConfig from "../../Models/ThemeConfig/LayerConfig" import LayerConfig from "../../Models/ThemeConfig/LayerConfig";
import PointRenderingConfig from "../../Models/ThemeConfig/PointRenderingConfig" import PointRenderingConfig from "../../Models/ThemeConfig/PointRenderingConfig";
import { OsmTags } from "../../Models/OsmFeature" import { OsmTags } from "../../Models/OsmFeature";
import { FeatureSource, FeatureSourceForLayer } from "../../Logic/FeatureSource/FeatureSource" import { FeatureSource, FeatureSourceForLayer } from "../../Logic/FeatureSource/FeatureSource";
import { BBox } from "../../Logic/BBox" import { BBox } from "../../Logic/BBox";
import { Feature, Point } from "geojson" import { Feature, Point } from "geojson";
import LineRenderingConfig from "../../Models/ThemeConfig/LineRenderingConfig" import LineRenderingConfig from "../../Models/ThemeConfig/LineRenderingConfig";
import { Utils } from "../../Utils" import { Utils } from "../../Utils";
import * as range_layer from "../../../assets/layers/range/range.json" import * as range_layer from "../../../assets/layers/range/range.json";
import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson" import { LayerConfigJson } from "../../Models/ThemeConfig/Json/LayerConfigJson";
import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFeatureSourceSplitter" import PerLayerFeatureSourceSplitter from "../../Logic/FeatureSource/PerLayerFeatureSourceSplitter";
import FilteredLayer from "../../Models/FilteredLayer" import FilteredLayer from "../../Models/FilteredLayer";
import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource" import SimpleFeatureSource from "../../Logic/FeatureSource/Sources/SimpleFeatureSource";
class PointRenderingLayer { class PointRenderingLayer {
private readonly _config: PointRenderingConfig private readonly _config: PointRenderingConfig
@ -284,18 +284,18 @@ class LineRenderingLayer {
// Already up to date // Already up to date
return return
} }
{// Add source to the map or update the features
if (src === undefined) { if (src === undefined) {
this.currentSourceData = features this.currentSourceData = features;
map.addSource(this._layername, { map.addSource(this._layername, {
type: "geojson", type: "geojson",
data: { data: {
type: "FeatureCollection", type: "FeatureCollection",
features, features
}, },
promoteId: "id", promoteId: "id"
}) });
// @ts-ignore const linelayer = this._layername + "_line";
const linelayer = this._layername + "_line"
map.addLayer({ map.addLayer({
source: this._layername, source: this._layername,
id: linelayer, id: linelayer,
@ -304,19 +304,26 @@ class LineRenderingLayer {
"line-color": ["feature-state", "color"], "line-color": ["feature-state", "color"],
"line-opacity": ["feature-state", "color-opacity"], "line-opacity": ["feature-state", "color-opacity"],
"line-width": ["feature-state", "width"], "line-width": ["feature-state", "width"],
"line-offset": ["feature-state", "offset"], "line-offset": ["feature-state", "offset"]
}, },
layout: { layout: {
"line-cap": "round", "line-cap": "round"
}, }
}) });
for (const feature of features) {
map.setFeatureState(
{ source: this._layername, id: feature.properties.id },
this.calculatePropsFor(feature.properties)
)
}
map.on("click", linelayer, (e) => { map.on("click", linelayer, (e) => {
// line-layer-listener // line-layer-listener
e.originalEvent["consumed"] = true e.originalEvent["consumed"] = true;
this._onClick(e.features[0]) this._onClick(e.features[0]);
}) });
const polylayer = this._layername + "_polygon" const polylayer = this._layername + "_polygon";
map.addLayer({ map.addLayer({
source: this._layername, source: this._layername,
@ -326,44 +333,45 @@ class LineRenderingLayer {
layout: {}, layout: {},
paint: { paint: {
"fill-color": ["feature-state", "fillColor"], "fill-color": ["feature-state", "fillColor"],
"fill-opacity": ["feature-state", "fillColor-opacity"], "fill-opacity": ["feature-state", "fillColor-opacity"]
}, }
}) });
if (this._onClick) { if (this._onClick) {
map.on("click", polylayer, (e) => { map.on("click", polylayer, (e) => {
// polygon-layer-listener // polygon-layer-listener
if (e.originalEvent["consumed"]) { if (e.originalEvent["consumed"]) {
// This is a polygon beneath a marker, we can ignore it // This is a polygon beneath a marker, we can ignore it
return return;
} }
e.originalEvent["consumed"] = true e.originalEvent["consumed"] = true;
console.log("Got features:", e.features, e) console.log("Got features:", e.features, e);
this._onClick(e.features[0]) this._onClick(e.features[0]);
}) });
} }
this._visibility?.addCallbackAndRunD((visible) => { this._visibility?.addCallbackAndRunD((visible) => {
try { try {
map.setLayoutProperty(linelayer, "visibility", visible ? "visible" : "none") map.setLayoutProperty(linelayer, "visibility", visible ? "visible" : "none");
map.setLayoutProperty(polylayer, "visibility", visible ? "visible" : "none") map.setLayoutProperty(polylayer, "visibility", visible ? "visible" : "none");
} catch (e) { } catch (e) {
console.warn( console.warn(
"Error while setting visibility of layers ", "Error while setting visibility of layers ",
linelayer, linelayer,
polylayer, polylayer,
e e
) );
} }
}) });
} else { } else {
this.currentSourceData = features this.currentSourceData = features;
src.setData({ src.setData({
type: "FeatureCollection", type: "FeatureCollection",
features: this.currentSourceData, features: this.currentSourceData
}) });
}
} }
for (let i = 0; i < features.length; i++) { for (let i = 0; i < features.length; i++) {
// Installs a listener on the 'Tags' of every individual feature to update the rendering
const feature = features[i] const feature = features[i]
const id = feature.properties.id ?? feature.id const id = feature.properties.id ?? feature.id
if (id === undefined) { if (id === undefined) {
@ -392,6 +400,9 @@ class LineRenderingLayer {
const tags = this._fetchStore(id) const tags = this._fetchStore(id)
this._listenerInstalledOn.add(id) this._listenerInstalledOn.add(id)
tags.addCallbackAndRunD((properties) => { tags.addCallbackAndRunD((properties) => {
if(!map.getLayer(this._layername)){
return
}
map.setFeatureState( map.setFeatureState(
{ source: this._layername, id }, { source: this._layername, id },
this.calculatePropsFor(properties) this.calculatePropsFor(properties)