@geops/rvf-mobility-web-component 0.1.40 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/index.js +153 -277
- package/package.json +1 -1
- package/src/NotificationLayer/NotificationLayer.tsx +1 -0
- package/src/NotificationLayer/notificationUtils.ts +234 -160
- package/src/RvfFeatureDetails/RvfLineNetworkDetails/RvfLineNetworkDetails.tsx +172 -131
- package/src/RvfFeatureDetails/RvfNotificationDetails/RvfNotificationDetails.tsx +200 -42
- package/src/icons/disruption-type-banner.xcf +0 -0
- package/src/icons/sbb_add_stop.png +0 -0
- package/src/icons/sbb_add_stop.svg +6 -0
- package/src/icons/sbb_alternative.png +0 -0
- package/src/icons/sbb_alternative.svg +6 -0
- package/src/icons/sbb_cancellation.png +0 -0
- package/src/icons/sbb_cancellation.svg +7 -0
- package/src/icons/sbb_construction.png +0 -0
- package/src/icons/sbb_construction.svg +6 -0
- package/src/icons/sbb_construction_banner.png +0 -0
- package/src/icons/sbb_delay.png +0 -0
- package/src/icons/sbb_delay.svg +6 -0
- package/src/icons/sbb_disruption.png +0 -0
- package/src/icons/sbb_disruption.svg +6 -0
- package/src/icons/sbb_disruption_banner.png +0 -0
- package/src/icons/sbb_info.png +0 -0
- package/src/icons/sbb_info.svg +6 -0
- package/src/icons/sbb_missed_connection.png +0 -0
- package/src/icons/sbb_missed_connection.svg +6 -0
- package/src/icons/sbb_missed_connection_banner.png +0 -0
- package/src/icons/sbb_platform_change.png +0 -0
- package/src/icons/sbb_platform_change.svg +7 -0
- package/src/icons/sbb_replacementbus.png +0 -0
- package/src/icons/sbb_replacementbus.svg +6 -0
- package/src/icons/sbb_replacementbus_banner.png +0 -0
- package/src/icons/sbb_reroute.png +0 -0
- package/src/icons/sbb_reroute.svg +7 -0
- package/src/icons/warning-banner.xcf +0 -0
- package/src/utils/addSourceAndLayers.ts +51 -5
- package/src/utils/{getFeatureInformationTitle.ts → getFeatureInformationTitle.tsx} +14 -2
- package/src/utils/i18n.ts +6 -5
- package/src/utils/sharingGraphqlUtils.ts +16 -9
- package/src/utils/translations.ts +16 -0
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@geops/rvf-mobility-web-component",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
4
|
"description": "Web components for rvf in the domains of mobility and logistics.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.42",
|
|
6
6
|
"homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "index.js",
|
|
@@ -92,6 +92,7 @@ const useNotifications = (): FeatureCollection => {
|
|
|
92
92
|
abortCtrl = new AbortController();
|
|
93
93
|
const response = await fetch(url, { signal: abortCtrl.signal });
|
|
94
94
|
const data = await response.json();
|
|
95
|
+
|
|
95
96
|
const notifications = getNotificationsWithStatus(data, now);
|
|
96
97
|
setNotifications(notifications);
|
|
97
98
|
setShouldAddPreviewNotifications(true);
|
|
@@ -12,6 +12,89 @@ export const getTime = (str) => {
|
|
|
12
12
|
return parseInt(str?.substr(0, 8).replace(/:/g, ""), 10);
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
+
export const isNotificationNotOutOfDate = (notification, now) => {
|
|
16
|
+
// TODO: The backend should be responsible to returns only good notifications.
|
|
17
|
+
let notOutOfDate = notification.properties.affected_time_intervals.some(
|
|
18
|
+
(ati) => {
|
|
19
|
+
return now < new Date(ati.end);
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
if (!notOutOfDate) {
|
|
23
|
+
notOutOfDate = notification.properties.publications.some((publication) => {
|
|
24
|
+
return (
|
|
25
|
+
now >= new Date(publication.visible_from) &&
|
|
26
|
+
now <= new Date(publication.visible_until)
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
return notOutOfDate;
|
|
31
|
+
};
|
|
32
|
+
export const isNotificationPublished = (notification, now) => {
|
|
33
|
+
if (!notification?.properties?.publications?.length) {
|
|
34
|
+
// If there is no piblications date, use the time intervals
|
|
35
|
+
return isNotificationActive(notification, now);
|
|
36
|
+
}
|
|
37
|
+
return notification.properties.publications.some((publication) => {
|
|
38
|
+
return (
|
|
39
|
+
now >= new Date(publication.visible_from) &&
|
|
40
|
+
now <= new Date(publication.visible_until)
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const isNotificationActive = (notification, now: Date) => {
|
|
46
|
+
return notification.properties.affected_time_intervals.some(
|
|
47
|
+
(affectedTimeInterval) => {
|
|
48
|
+
const {
|
|
49
|
+
end,
|
|
50
|
+
start,
|
|
51
|
+
time_of_day_end: dayTimeEnd,
|
|
52
|
+
time_of_day_start: dayTimeStart,
|
|
53
|
+
} = affectedTimeInterval;
|
|
54
|
+
const nowTime = getTime(now.toTimeString());
|
|
55
|
+
const startTime = getTime(dayTimeStart);
|
|
56
|
+
const endTime = getTime(dayTimeEnd);
|
|
57
|
+
const inRange = new Date(start) <= now && now <= new Date(end);
|
|
58
|
+
return startTime && endTime
|
|
59
|
+
? inRange && startTime <= nowTime && nowTime <= endTime
|
|
60
|
+
: inRange;
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
const getStartsString = (notification, now) => {
|
|
66
|
+
const next = notification.properties.affected_time_intervals.reduce(
|
|
67
|
+
(a, b) => {
|
|
68
|
+
const aEnd = new Date(a.end);
|
|
69
|
+
const aStart = new Date(a.start);
|
|
70
|
+
const bStart = new Date(b.start);
|
|
71
|
+
return now < aEnd && aStart < bStart ? a : b;
|
|
72
|
+
},
|
|
73
|
+
[],
|
|
74
|
+
);
|
|
75
|
+
const nextStartDate = new Date(next.start);
|
|
76
|
+
let starts;
|
|
77
|
+
if (
|
|
78
|
+
now.toDateString() === nextStartDate.toDateString() ||
|
|
79
|
+
now.getTime() - nextStartDate.getTime() > 0
|
|
80
|
+
) {
|
|
81
|
+
if (next.time_of_day_start) {
|
|
82
|
+
starts = `ab ${next.time_of_day_start.substr(0, 5)}`;
|
|
83
|
+
} else {
|
|
84
|
+
starts = `ab ${nextStartDate.toLocaleTimeString(["de"], {
|
|
85
|
+
hour: "2-digit",
|
|
86
|
+
hour12: false,
|
|
87
|
+
minute: "2-digit",
|
|
88
|
+
})}`;
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
starts = `ab ${nextStartDate.toLocaleDateString(["de-DE"], {
|
|
92
|
+
day: "numeric",
|
|
93
|
+
month: "short",
|
|
94
|
+
})}`;
|
|
95
|
+
}
|
|
96
|
+
return starts;
|
|
97
|
+
};
|
|
15
98
|
/**
|
|
16
99
|
*
|
|
17
100
|
* @param {Array.<Object>} notifications Raw notifications
|
|
@@ -20,124 +103,86 @@ export const getTime = (str) => {
|
|
|
20
103
|
*/
|
|
21
104
|
const getNotificationsWithStatus = (notifications, now) => {
|
|
22
105
|
return notifications
|
|
23
|
-
.filter(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
notOutOfDate = notification.properties.publications.some(
|
|
32
|
-
(publication) => {
|
|
33
|
-
return (
|
|
34
|
-
now >= new Date(publication.visible_from) &&
|
|
35
|
-
now <= new Date(publication.visible_until)
|
|
36
|
-
);
|
|
37
|
-
},
|
|
38
|
-
);
|
|
39
|
-
}
|
|
40
|
-
return notOutOfDate;
|
|
41
|
-
})
|
|
42
|
-
.map((n) => {
|
|
43
|
-
const isPublished = n.properties.publications.some((publication) => {
|
|
44
|
-
return (
|
|
45
|
-
now >= new Date(publication.visible_from) &&
|
|
46
|
-
now <= new Date(publication.visible_until)
|
|
47
|
-
);
|
|
48
|
-
});
|
|
49
|
-
const isActive = n.properties.affected_time_intervals.some((ati) => {
|
|
50
|
-
const {
|
|
51
|
-
end,
|
|
52
|
-
start,
|
|
53
|
-
time_of_day_end: dayTimeEnd,
|
|
54
|
-
time_of_day_start: dayTimeStart,
|
|
55
|
-
} = ati;
|
|
56
|
-
const nowTime = getTime(now.toTimeString());
|
|
57
|
-
const startTime = getTime(dayTimeStart);
|
|
58
|
-
const endTime = getTime(dayTimeEnd);
|
|
59
|
-
const inRange = new Date(start) <= now && now <= new Date(end);
|
|
60
|
-
return startTime && endTime
|
|
61
|
-
? inRange && startTime <= nowTime && nowTime <= endTime
|
|
62
|
-
: inRange;
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
const next = n.properties.affected_time_intervals.reduce((a, b) => {
|
|
66
|
-
const aEnd = new Date(a.end);
|
|
67
|
-
const aStart = new Date(a.start);
|
|
68
|
-
const bStart = new Date(b.start);
|
|
69
|
-
return now < aEnd && aStart < bStart ? a : b;
|
|
70
|
-
}, []);
|
|
71
|
-
const nextStartDate = new Date(next.start);
|
|
72
|
-
let starts;
|
|
73
|
-
if (
|
|
74
|
-
now.toDateString() === nextStartDate.toDateString() ||
|
|
75
|
-
now.getTime() - nextStartDate.getTime() > 0
|
|
76
|
-
) {
|
|
77
|
-
if (next.time_of_day_start) {
|
|
78
|
-
starts = `ab ${next.time_of_day_start.substr(0, 5)}`;
|
|
79
|
-
} else {
|
|
80
|
-
starts = `ab ${nextStartDate.toLocaleTimeString(["de"], {
|
|
81
|
-
hour: "2-digit",
|
|
82
|
-
hour12: false,
|
|
83
|
-
minute: "2-digit",
|
|
84
|
-
})}`;
|
|
85
|
-
}
|
|
86
|
-
} else {
|
|
87
|
-
starts = `ab ${nextStartDate.toLocaleDateString(["de-DE"], {
|
|
88
|
-
day: "numeric",
|
|
89
|
-
month: "short",
|
|
90
|
-
})}`;
|
|
91
|
-
}
|
|
106
|
+
.filter(isNotificationNotOutOfDate)
|
|
107
|
+
.map((notification) => {
|
|
108
|
+
// For information:
|
|
109
|
+
// A notification here is a FeatureCollection representing a publication of a situation,
|
|
110
|
+
// containing properties about the situation and a list of features representing affecetdLines and affectedStops of this publication.
|
|
111
|
+
// AffectedStops are not currently represented in the map.
|
|
112
|
+
// AffectedLines are represented as linestrings in the map(the display of line is currently disabled) and, if is_icon_ref=true, as an icon .
|
|
113
|
+
// The representation of the icon depends of the disruption_type property of the publication.
|
|
92
114
|
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
});
|
|
97
|
-
if (iconRef) {
|
|
98
|
-
const iconRefFeature = format.readFeature(iconRef, {
|
|
99
|
-
dataProjection: "EPSG:4326",
|
|
100
|
-
featureProjection: "EPSG:3857",
|
|
101
|
-
}) as Feature;
|
|
102
|
-
const center = getCenter(iconRefFeature.getGeometry().getExtent());
|
|
103
|
-
iconRefPoint = iconRefFeature.getGeometry().getClosestPoint(center);
|
|
104
|
-
}
|
|
115
|
+
const isPublished = isNotificationPublished(notification, now);
|
|
116
|
+
const isActive = isNotificationActive(notification, now);
|
|
117
|
+
const starts = getStartsString(notification, now);
|
|
105
118
|
|
|
106
|
-
const
|
|
107
|
-
...
|
|
108
|
-
iconRefPoint,
|
|
119
|
+
const commonProperties = {
|
|
120
|
+
...notification.properties,
|
|
109
121
|
isActive,
|
|
110
122
|
isPublished,
|
|
111
123
|
starts,
|
|
112
124
|
};
|
|
113
125
|
|
|
114
|
-
|
|
126
|
+
// We append all the common properties to all the features.
|
|
127
|
+
const features = notification.features.map((f) => {
|
|
115
128
|
return {
|
|
116
129
|
...f,
|
|
117
|
-
properties: { ...
|
|
130
|
+
properties: { ...commonProperties, ...f.properties },
|
|
118
131
|
};
|
|
119
132
|
});
|
|
120
133
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
// We search for is_icon_ref=true features (lines) and create a point feature for each of them.
|
|
135
|
+
const iconRefFeatures = notification.features
|
|
136
|
+
.filter((f) => {
|
|
137
|
+
return f.properties.is_icon_ref || f.geometry.type === "Point";
|
|
138
|
+
})
|
|
139
|
+
.map((affectedLine) => {
|
|
140
|
+
const affectedLineFeature = format.readFeature(affectedLine, {
|
|
141
|
+
dataProjection: "EPSG:4326",
|
|
142
|
+
featureProjection: "EPSG:3857",
|
|
143
|
+
}) as Feature;
|
|
144
|
+
const center = getCenter(
|
|
145
|
+
affectedLineFeature.getGeometry().getExtent(),
|
|
146
|
+
);
|
|
147
|
+
const iconRefPoint = affectedLineFeature
|
|
148
|
+
.getGeometry()
|
|
149
|
+
.getClosestPoint(center);
|
|
150
|
+
|
|
151
|
+
const iconRefFeatureProperties = {
|
|
152
|
+
...commonProperties,
|
|
153
|
+
...affectedLine.properties,
|
|
131
154
|
isIconRefPoint: true,
|
|
132
|
-
}
|
|
133
|
-
|
|
155
|
+
};
|
|
156
|
+
if (!iconRefFeatureProperties.disruption_type) {
|
|
157
|
+
iconRefFeatureProperties.disruption_type = "OTHER";
|
|
158
|
+
}
|
|
159
|
+
// Set Banner image
|
|
160
|
+
if (iconRefFeatureProperties.disruption_type) {
|
|
161
|
+
iconRefFeatureProperties.disruption_type_banner =
|
|
162
|
+
iconRefFeatureProperties.disruption_type + "_BANNER";
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (iconRefPoint) {
|
|
166
|
+
const iconRefFeature = {
|
|
167
|
+
geometry: {
|
|
168
|
+
coordinates: toLonLat(iconRefPoint),
|
|
169
|
+
type: "Point",
|
|
170
|
+
},
|
|
171
|
+
id: Math.random() + "",
|
|
172
|
+
properties: iconRefFeatureProperties,
|
|
173
|
+
type: "Feature",
|
|
174
|
+
};
|
|
175
|
+
return iconRefFeature;
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
.filter((f) => {
|
|
179
|
+
return !!f;
|
|
134
180
|
});
|
|
135
|
-
}
|
|
136
181
|
|
|
137
182
|
return {
|
|
138
|
-
...
|
|
139
|
-
features,
|
|
140
|
-
properties,
|
|
183
|
+
...notification,
|
|
184
|
+
features: [...features, ...iconRefFeatures],
|
|
185
|
+
properties: commonProperties,
|
|
141
186
|
};
|
|
142
187
|
});
|
|
143
188
|
};
|
|
@@ -188,6 +233,7 @@ const addNotificationsLayers = (
|
|
|
188
233
|
sourceId: string,
|
|
189
234
|
sourceData: FeatureCollection,
|
|
190
235
|
beforeLayerId: string,
|
|
236
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
191
237
|
graph: number,
|
|
192
238
|
) => {
|
|
193
239
|
if (!mapboxLayer) {
|
|
@@ -217,26 +263,26 @@ const addNotificationsLayers = (
|
|
|
217
263
|
// source: "notifications",
|
|
218
264
|
// type: "line",
|
|
219
265
|
// },
|
|
220
|
-
{
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
},
|
|
266
|
+
// {
|
|
267
|
+
// filter: [
|
|
268
|
+
// "all",
|
|
269
|
+
// ["==", ["get", "isActive"], true],
|
|
270
|
+
// ["==", ["get", "graph"], graph],
|
|
271
|
+
// ["==", ["get", "disruption_type"], "DISRUPTION"],
|
|
272
|
+
// ],
|
|
273
|
+
// id: "notificationsActive",
|
|
274
|
+
// layout: { visibility: "visible" },
|
|
275
|
+
// metadata: {
|
|
276
|
+
// "general.filter": "notifications",
|
|
277
|
+
// },
|
|
278
|
+
// paint: {
|
|
279
|
+
// "line-color": "rgba(255,0,0,0.5)",
|
|
280
|
+
// "line-dasharray": [2, 2],
|
|
281
|
+
// "line-width": 5,
|
|
282
|
+
// },
|
|
283
|
+
// source: "notifications",
|
|
284
|
+
// type: "line",
|
|
285
|
+
// },
|
|
240
286
|
// {
|
|
241
287
|
// filter: [
|
|
242
288
|
// "all",
|
|
@@ -256,61 +302,78 @@ const addNotificationsLayers = (
|
|
|
256
302
|
// source: "notifications",
|
|
257
303
|
// type: "line",
|
|
258
304
|
// },
|
|
259
|
-
{
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
},
|
|
276
|
-
{
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
},
|
|
305
|
+
// {
|
|
306
|
+
// filter: [
|
|
307
|
+
// "all",
|
|
308
|
+
// ["==", ["get", "isActive"], true],
|
|
309
|
+
// ["==", ["get", "disruption_type"], "DEVIATION"],
|
|
310
|
+
// ],
|
|
311
|
+
// id: "notificationsActiveDeviation",
|
|
312
|
+
// layout: { visibility: "visible" },
|
|
313
|
+
// paint: {
|
|
314
|
+
// "line-color": "#000000",
|
|
315
|
+
// "line-dasharray": [2, 2],
|
|
316
|
+
// "line-opacity": 0.5,
|
|
317
|
+
// "line-width": 5,
|
|
318
|
+
// },
|
|
319
|
+
// source: "notifications",
|
|
320
|
+
// type: "line",
|
|
321
|
+
// },
|
|
322
|
+
// {
|
|
323
|
+
// filter: [
|
|
324
|
+
// "all",
|
|
325
|
+
// ["==", ["get", "isIconRefPoint"], true],
|
|
326
|
+
// // ["==", ["get", "isActive"], true],
|
|
327
|
+
// ],
|
|
328
|
+
// id: "notificationsIconRefPointActive",
|
|
329
|
+
// layout: { visibility: "visible" },
|
|
330
|
+
// metadata: {
|
|
331
|
+
// "general.filter": "notifications",
|
|
332
|
+
// },
|
|
333
|
+
// paint: {
|
|
334
|
+
// "circle-color": "#ff0000",
|
|
335
|
+
// "circle-radius": 10,
|
|
336
|
+
// },
|
|
337
|
+
// source: "notifications",
|
|
338
|
+
// type: "circle",
|
|
339
|
+
// },
|
|
294
340
|
|
|
341
|
+
// Display an icon
|
|
295
342
|
{
|
|
296
343
|
filter: [
|
|
297
344
|
"all",
|
|
298
345
|
["==", ["get", "isIconRefPoint"], true],
|
|
346
|
+
["==", ["get", "isPublished"], true],
|
|
299
347
|
["==", ["get", "isActive"], true],
|
|
300
348
|
],
|
|
301
349
|
id: "notificationsIconRefPointActive",
|
|
302
350
|
layout: {
|
|
303
|
-
"icon-
|
|
304
|
-
"icon-
|
|
351
|
+
"icon-allow-overlap": true,
|
|
352
|
+
// "icon-image": "warning"
|
|
353
|
+
"icon-image": [
|
|
354
|
+
"coalesce",
|
|
355
|
+
// ["image", "warning"],
|
|
356
|
+
["image", ["get", "disruption_type"]],
|
|
357
|
+
// If no image with the name above exists, show the
|
|
358
|
+
// "rocket" image instead.
|
|
359
|
+
["image", "warning"],
|
|
360
|
+
],
|
|
361
|
+
"icon-size": 0.6,
|
|
362
|
+
|
|
363
|
+
// "icon-size": ["interpolate", ["linear"], ["zoom"], 11, 0, 11, 0.6],
|
|
305
364
|
visibility: "visible",
|
|
306
365
|
},
|
|
366
|
+
|
|
307
367
|
metadata: {
|
|
308
368
|
"general.filter": "notifications",
|
|
309
369
|
},
|
|
370
|
+
minzoom: 11,
|
|
310
371
|
paint: {},
|
|
311
372
|
source: "notifications",
|
|
312
373
|
type: "symbol",
|
|
313
374
|
},
|
|
375
|
+
|
|
376
|
+
// Display a banner with the start date
|
|
314
377
|
{
|
|
315
378
|
filter: [
|
|
316
379
|
"all",
|
|
@@ -320,8 +383,18 @@ const addNotificationsLayers = (
|
|
|
320
383
|
],
|
|
321
384
|
id: "notificationsIconRefPointNonActive",
|
|
322
385
|
layout: {
|
|
323
|
-
"icon-
|
|
386
|
+
"icon-allow-overlap": true,
|
|
387
|
+
// "icon-image": "warningBanner",
|
|
388
|
+
"icon-image": [
|
|
389
|
+
"coalesce",
|
|
390
|
+
// ["image", "warning"],
|
|
391
|
+
["image", ["get", "disruption_type_banner"]],
|
|
392
|
+
// If no image with the name above exists, show the
|
|
393
|
+
// "rocket" image instead.
|
|
394
|
+
["image", "warningBanner"],
|
|
395
|
+
],
|
|
324
396
|
"icon-size": 0.15,
|
|
397
|
+
// "icon-size": ["interpolate", ["linear"], ["zoom"], 11, 0, 11, 0.15],
|
|
325
398
|
"text-field": ["get", "starts"],
|
|
326
399
|
"text-offset": [1.5, 0],
|
|
327
400
|
"text-size": 8,
|
|
@@ -330,6 +403,7 @@ const addNotificationsLayers = (
|
|
|
330
403
|
metadata: {
|
|
331
404
|
"general.filter": "notifications",
|
|
332
405
|
},
|
|
406
|
+
minzoom: 11,
|
|
333
407
|
paint: {},
|
|
334
408
|
source: "notifications",
|
|
335
409
|
type: "symbol",
|