Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 159 additions & 11 deletions dev.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import {
} from './build/ol';
import 'ol/ol.css';
import { toLonLat, transformExtent } from 'ol/proj';
import { Icon, Style, Circle, Fill, Stroke } from 'ol/style';
import { Point } from 'ol/geom';
import { radiansToDegrees } from '@turf/helpers';
import { NEXT_CACHE_TAG_MAX_LENGTH } from 'next/dist/lib/constants';

window.apiKey = '5cc87b12d7c5370001c1d6554840ecb89d2743d2b0aad0588b8ba7eb';

Expand Down Expand Up @@ -42,17 +46,112 @@ const realtimeLayer = new RealtimeLayer({
url: 'wss://api.geops.io/tracker-ws/v1/', // prod
// url: 'wss://api.geops.io/realtime-ws/v1/', // sbm
styleOptions: {
showHeading: true,
// useHeadingStyle: true,
// useDelayStyle: true,
},
// style: realtimeByMotStyle,
// tenant: 'sbm',
// tenant: 'trenord',
tenant: 'trenord',
// bboxParameters: {
// line_tags: 'RVF',
// },
});

const getPointOnLine = (angleDeg, distance, originX = 0, originY = 0) => {
// 1. Convert angle from degrees to radians
const angleRad = (angleDeg + 90) * (Math.PI / 180);

// 2. Calculate the offset from the origin using Cosine (X) and Sine (Y)
const deltaX = Math.cos(angleRad) * distance;
const deltaY = Math.sin(angleRad) * distance;

// 3. Add the offset to the origin coordinates
const x = originX + deltaX;
const y = originY - deltaY;

return [
Math.floor(x), // Rounded for better readability
Math.floor(y),
];
};

const cacheFirtsAnchor = [];
let cacheFirstRotation = 0;
let featuresHighlightedIds = [];
const realtimeLayerHover = new VectorLayer({
source: new VectorSource(),
minZoom: 14,
style: (feature) => {
// const canvas =
// realtimeLayer.engine.renderState?.styleCacheByTrajectoryId?.[
// feature.get('train_id')
// ];
const canvas = realtimeLayer.style(
{
type: 'Feature',
properties: feature.getProperties(),
geometry: {
type: 'LineString',
coordinates: feature.getGeometry()?.getCoordinates() || [],
},
},
realtimeLayer.renderedViewState,
{
...realtimeLayer.styleOptions,
showDelayText: false,
showDelayBg: true,
hoverVehicleId: feature.get('train_id'),
},
);
const index = featuresHighlightedIds?.indexOf(feature.get('train_id'));
console.log('index', index, feature.get('train_id'));
if (index === 0) {
cacheFirstRotation = feature.get('rotation') || 0;
}

if (canvas) {
return new Style({
image: new Icon({
img: canvas,
imgSize: [canvas.width, canvas.height],
scale: 1,
anchor: getPointOnLine(
radiansToDegrees(cacheFirstRotation),
(index * canvas.height) / 2,
canvas.width / 2,
canvas.height / 2,
),
anchorXUnits: 'pixels',
anchorYUnits: 'pixels',
}),
geometry: (feature) => {
const coords = feature.get('coordinate');
if (coords) {
return new Point(coords);
}
return feature.getGeometry();
},
});
}
return new Style({
image: new Circle({
radius: 50,
fill: new Fill({ color: 'rgba(255, 0, 0, 0.5)' }),
stroke: new Stroke({ color: 'red', width: 2 }),
}),
stroke: new Stroke({ color: 'blue', width: 20 }),
geometry: (feature) => {
const coords = feature.get('coordinate');
if (coords) {
return new Point(coords);
}
return feature.getGeometry();
},
});
},
});

const mocoLayer = new MocoLayer({
apiKey: window.apiKey,
// tenant: 'rvf',
Expand All @@ -64,9 +163,10 @@ const mocoLayer = new MocoLayer({
const map = new Map({
layers: [
baseLayer,
// realtimeLayer,
realtimeLayer,
realtimeLayerHover,
// mocoLayer,
mapsetLayer,
// mapsetLayer,
],
target: 'map',
view: new View({
Expand All @@ -83,16 +183,56 @@ map.on('pointermove', (evt) => {
return;
}
const pixel = map.getEventPixel(evt.originalEvent);
const [feature] = map.getFeaturesAtPixel(pixel, {
hitTolerance: 10,
const features = map.getFeaturesAtPixel(pixel, {
hitTolerance: 15,
layerFilter: (l) => l === realtimeLayer,
});

// realtimeLayer.hoverVehicleId = feature?.get('train_id');
const featuresHovered = map.getFeaturesAtPixel(pixel, {
layerFilter: (l) => l === realtimeLayerHover,
});
console.log(features.map((f) => f.get('train_id')));

const featuresIds = features.map((f) => f.get('train_id'));
const featuresHoveredIds = featuresHovered.map((f) => f.get('train_id'));
const noFeaturesHovered =
!featuresHovered.length && !featuresHoveredIds.length;

if ((map.getView().getZoom() || 0) >= realtimeLayerHover.getMinZoom()) {
realtimeLayer.filter = (feature) => {
return !featuresHighlightedIds?.includes(feature.properties.train_id);
};
} else {
realtimeLayer.filter = null;
}

console.log(
'BEFORE features',
featuresHovered.length,
features.length,
featuresHighlightedIds.length,
);

realtimeLayer.highlight(feature);
console.log(feature?.getProperties());
map.getTargetElement().style.cursor = feature ? 'pointer' : '';
if (!featuresHovered.length && !features.length) {
console.log('CLEAR features', featuresHovered.length, features.length);
realtimeLayerHover.getSource().clear(true);
featuresHighlightedIds = [];
} else if (features.length > 1 && !featuresHighlightedIds.length) {
console.log(
'ADD features',
featuresHoveredIds,
featuresHovered.length,
features.length,
featuresIds,
);
realtimeLayerHover.getSource().addFeatures(features);
featuresHighlightedIds = featuresIds;
} else if (!featuresHovered.length && features.length === 1) {
realtimeLayer.highlight(features[0]);
}

map.getTargetElement().style.cursor =
features.length || featuresHovered.length ? 'pointer' : '';
});

map.on('singleclick', (evt) => {
Expand All @@ -101,12 +241,20 @@ map.on('singleclick', (evt) => {
}
const pixel = map.getEventPixel(evt.originalEvent);
const [feature] = map.getFeaturesAtPixel(pixel, {
hitTolerance: 10,
hitTolerance: 15,
layerFilter: (l) => l === realtimeLayer,
});
const [featureHover] = map.getFeaturesAtPixel(pixel, {
hitTolerance: 15,
layerFilter: (l) => l === realtimeLayerHover,
});

realtimeLayer.select([feature]);
realtimeLayer.select(featureHover || feature);
realtimeLayerHover.getSource().clear();
realtimeLayerHover.changed();
realtimeLayer.filter = null;
});

map.on('moveend', () => {
const zoom = map.getView().getZoom();
console.log('Current zoom level:', zoom);
Expand Down
Loading
Loading