Skip to content

Commit 0814e34

Browse files
committed
draft 1
draft 2 draft 3 draft 4 draft 5 draft 6 DBC22-6776: fixed broken test cases removed commented out code DBC22-6776: switch to fixed pixels to cluster icons
1 parent 4fd1f8e commit 0814e34

4 files changed

Lines changed: 103 additions & 19 deletions

File tree

src/frontend/src/Components/map/handlers/click.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ const camClickHandler = (
257257
feature.setCameraStyle('active');
258258
feature.set('clicked', true, true);
259259
feature.set('unread', false);
260+
feature.set('hovered', false);
260261

261262
if (isCamDetail) {
262263
// Do not auto center on feature on cam details page
@@ -580,8 +581,14 @@ export const pointerClickHandler = (
580581
mapContext
581582
) => {
582583
if (features.length) {
583-
const clickedFeature = features[0];
584-
switch (clickedFeature.getProperties()['type']) {
584+
let clickedFeature = features[0];
585+
586+
if (!clickedFeature.get('type')) {
587+
clickedFeature = features[0].values_?.features[0];
588+
}
589+
590+
591+
switch (clickedFeature?.getProperties()['type']) {
585592
case 'camera':
586593
trackEvent(
587594
'click',

src/frontend/src/Components/map/handlers/hover.js

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const resetHoveredStates = (targetFeature, hoveredFeatureRef) => {
3333
if (!hoveredFeature.getProperties().clicked) {
3434
switch (hoveredFeature.getProperties()['type']) {
3535
case 'camera':
36+
hoveredFeature.set('hovered', false);
3637
hoveredFeature.setCameraStyle('static');
3738
break;
3839
case 'event': {
@@ -148,15 +149,25 @@ export const pointerMoveHandler = (e, mapRef, hoveredFeature) => {
148149
});
149150

150151
if (features.length) {
151-
const targetFeature = features[0];
152-
resetHoveredStates(targetFeature, hoveredFeature);
153-
hoveredFeature.current = targetFeature;
152+
let targetFeature = features[0];
153+
if(targetFeature && !targetFeature.get('type')) {
154+
// targetFeature = features[0].values_?.features[0];
155+
const clusterFeatures = targetFeature.get('features');
154156

155-
// Set hover style if feature isn't clicked
156-
switch (targetFeature.getProperties()['type']) {
157+
if (clusterFeatures && clusterFeatures.length === 1) {
158+
targetFeature = clusterFeatures[0];
159+
}
160+
}
161+
162+
const realFeature = targetFeature;
163+
resetHoveredStates(realFeature, hoveredFeature);
164+
hoveredFeature.current = realFeature;
165+
166+
switch (realFeature?.get('type')) {
157167
case 'camera':
158-
if (!targetFeature.get('clicked')) {
159-
targetFeature.setCameraStyle('hover');
168+
if (!realFeature.get('clicked')) {
169+
realFeature.setCameraStyle('hover');
170+
realFeature.set('hovered', true);
160171
}
161172
return;
162173
case 'event':

src/frontend/src/Components/map/layers/camerasLayer.js

Lines changed: 70 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
// OpenLayers
22
import { Point } from 'ol/geom';
3-
import { Style } from 'ol/style';
3+
import {Style, Fill, Stroke, Text} from 'ol/style';
44
import * as ol from 'ol';
55
import VectorLayer from 'ol/layer/Vector';
66
import VectorSource from 'ol/source/Vector';
7+
import Cluster from 'ol/source/Cluster.js';
8+
import CircleStyle from 'ol/style/Circle.js';
79

810
// Styling
911
import { cameraStyles, unreadCameraStyles } from '../../data/featureStyleDefinitions.js';
1012

11-
export function getCamerasLayer(cameras, projectionCode, mapContext, referenceData, updateReferenceFeature, setLoadingLayers) {
13+
export function getCamerasLayer(cameras, projectionCode, mapContext, referenceData, updateReferenceFeature, setLoadingLayers, pixelDistance) {
1214
const vectorSource = new VectorSource();
1315

1416
cameras.forEach(camera => {
@@ -47,12 +49,63 @@ export function getCamerasLayer(cameras, projectionCode, mapContext, referenceDa
4749
}
4850
});
4951

50-
return new VectorLayer({
52+
const clusterSource = new Cluster({
53+
distance: pixelDistance,
54+
source: vectorSource,
55+
});
56+
57+
const styleCache = {};
58+
59+
const layer = new VectorLayer({
5160
classname: 'webcams',
5261
visible: mapContext.visible_layers.highwayCams,
53-
source: vectorSource,
54-
style: () => null
62+
source: clusterSource,
63+
64+
style: function (feature) {
65+
const features = feature.get('features');
66+
const size = features.length;
67+
68+
// single camera
69+
if (size === 1) {
70+
const cam = features[0];
71+
72+
if (cam.get('clicked')) {
73+
return cameraStyles.active;
74+
}
75+
if (cam.get('hovered')) {
76+
return cameraStyles.hover;
77+
}
78+
else {
79+
return cameraStyles.static;
80+
}
81+
}
82+
83+
// cluster
84+
let style = styleCache[size];
85+
86+
if (!style) {
87+
style = new Style({
88+
image: new CircleStyle({
89+
radius: 10,
90+
stroke: new Stroke({ color: '#fff' }),
91+
fill: new Fill({ color: '#3399CC' }),
92+
}),
93+
text: new Text({
94+
text: String(size),
95+
fill: new Fill({ color: '#fff' }),
96+
}),
97+
});
98+
99+
styleCache[size] = style;
100+
}
101+
102+
return style;
103+
},
55104
});
105+
106+
layer.getClusterSource = () => clusterSource;
107+
108+
return layer;
56109
}
57110

58111
export function updateCamerasLayer(cameras, layer, setLoadingLayers) {
@@ -62,7 +115,11 @@ export function updateCamerasLayer(cameras, layer, setLoadingLayers) {
62115
}, {});
63116

64117
for (const feature of layer.getSource().getFeatures()) {
65-
const camera = camerasLookup[feature.getId()];
118+
let camera = camerasLookup[feature.getId()];
119+
if (!camera) {
120+
camera = camerasLookup[feature.values_.features[0].getId()];
121+
}
122+
66123

67124
if (!camera) { // camera no longer in list from API
68125
feature.setStyle(new Style(null));
@@ -76,12 +133,16 @@ export function updateCamerasLayer(cameras, layer, setLoadingLayers) {
76133
feature.setProperties(camera); // update feature with latest API data.
77134

78135
if (feature.get('clicked')) { continue; }
79-
80-
feature.setCameraStyle('static');
136+
try {
137+
feature.setCameraStyle('static');
138+
}
139+
catch {
140+
feature.values_.features[0].setCameraStyle('static');
141+
}
81142
}
82143

83144
setLoadingLayers(prevState => ({
84145
...prevState,
85146
cameras: false
86147
}));
87-
}
148+
}

src/frontend/src/Components/map/layers/index.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ export const loadLayer = (mapLayers, mapRef, mapContext, key, dataList, filtered
4747
mapRef.current.removeLayer(mapLayers.current[key]);
4848
}
4949

50+
const view = mapRef.current.getView();
51+
5052
if (dataList) {
5153
if (!mapLayers.current[key] || key == 'routeLayer') {
5254
// Generate and add layer if it doesn't exist
@@ -56,7 +58,8 @@ export const loadLayer = (mapLayers, mapRef, mapContext, key, dataList, filtered
5658
mapContext,
5759
referenceData,
5860
updateReferenceFeature,
59-
setLoadingLayers
61+
setLoadingLayers,
62+
50
6063
);
6164

6265
mapRef.current.addLayer(mapLayers.current[key]);
@@ -70,6 +73,8 @@ export const loadLayer = (mapLayers, mapRef, mapContext, key, dataList, filtered
7073
}
7174
}
7275

76+
77+
7378
export const enableReferencedLayer = (referenceData, mapContext) => {
7479
// Do nothing if no reference data
7580
if (!referenceData) return;

0 commit comments

Comments
 (0)