@geops/rvf-mobility-web-component 0.1.8
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/.fixpackrc +21 -0
- package/.husky/commit-msg +1 -0
- package/.husky/post-checkout +1 -0
- package/.husky/post-merge +1 -0
- package/.husky/post-rebase +1 -0
- package/.husky/pre-commit +1 -0
- package/.lintstagedrc.js +12 -0
- package/.nvmrc +1 -0
- package/.prettierrc.js +1 -0
- package/CHANGELOG.md +183 -0
- package/Logo.svg +10 -0
- package/README.md +179 -0
- package/__mocks__/dataurl.js +11 -0
- package/__mocks__/mapbox-gl.js +19 -0
- package/commitlint.config.cjs +1 -0
- package/doc/.eslintrc.json +3 -0
- package/doc/.fixpackrc +21 -0
- package/doc/.prettierrc +1 -0
- package/doc/README.md +14 -0
- package/doc/declarations.d.ts +6 -0
- package/doc/next.config.mjs +4 -0
- package/doc/package.json +43 -0
- package/doc/postcss.config.mjs +8 -0
- package/doc/public/README.md +1 -0
- package/doc/src/app/components/GeopsAPIKeyLink.tsx +6 -0
- package/doc/src/app/components/GeopsAPIsLink.tsx +6 -0
- package/doc/src/app/components/GeopsMapsAPILink.tsx +8 -0
- package/doc/src/app/components/GeopsMobility.tsx +9 -0
- package/doc/src/app/components/GeopsMobilityDoc.tsx +231 -0
- package/doc/src/app/components/GeopsMobilitySearch.tsx +10 -0
- package/doc/src/app/components/GeopsMobilitySearchDoc.tsx +129 -0
- package/doc/src/app/components/GeopsRealtimeAPILink.tsx +10 -0
- package/doc/src/app/components/GeopsStopsAPILink.tsx +8 -0
- package/doc/src/app/components/Link.tsx +9 -0
- package/doc/src/app/components/WebComponentDoc.tsx +296 -0
- package/doc/src/app/favicon.ico +0 -0
- package/doc/src/app/geops-mobility/page.tsx +6 -0
- package/doc/src/app/geops-mobility-search/page.tsx +7 -0
- package/doc/src/app/globals.css +38 -0
- package/doc/src/app/hooks/useAttrFromUrlParams.ts +21 -0
- package/doc/src/app/hooks/useIsFullScreen.ts +14 -0
- package/doc/src/app/hooks/usePublicKey.ts +21 -0
- package/doc/src/app/layout.tsx +51 -0
- package/doc/src/app/page.tsx +86 -0
- package/doc/src/geops-ui.ts +3 -0
- package/doc/tailwind.config.ts +20 -0
- package/doc/tsconfig.json +40 -0
- package/eslint.config.mjs +40 -0
- package/favicon.ico +0 -0
- package/global.d.ts +4 -0
- package/iframe.html +34 -0
- package/index.html +276 -0
- package/index.js +2162 -0
- package/input.css +34 -0
- package/jest-setup.js +4 -0
- package/jest.config.js +17 -0
- package/package.json +80 -0
- package/scripts/build.mjs +16 -0
- package/scripts/dev.mjs +26 -0
- package/search.html +144 -0
- package/src/BaseLayer/BaseLayer.tsx +36 -0
- package/src/BaseLayer/index.tsx +1 -0
- package/src/Copyright/Copyright.tsx +54 -0
- package/src/Copyright/index.css +3 -0
- package/src/Copyright/index.tsx +1 -0
- package/src/DebugDeparture/DebugDeparture.tsx +116 -0
- package/src/DebugDeparture/index.tsx +1 -0
- package/src/DebugStop/DebugStop.tsx +47 -0
- package/src/DebugStop/index.tsx +1 -0
- package/src/Departure/Departure.tsx +55 -0
- package/src/Departure/index.tsx +1 -0
- package/src/GeolocationButton/GeolocationButton.tsx +81 -0
- package/src/GeolocationButton/index.tsx +1 -0
- package/src/Map/Map.tsx +89 -0
- package/src/Map/index.tsx +1 -0
- package/src/MobilityMap/MobilityMap.tsx +259 -0
- package/src/MobilityMap/index.css +13 -0
- package/src/MobilityMap/index.tsx +1 -0
- package/src/NotificationLayer/NotificationLayer.tsx +156 -0
- package/src/NotificationLayer/index.tsx +1 -0
- package/src/NotificationLayer/notificationUtils.ts +191 -0
- package/src/Overlay/Overlay.tsx +57 -0
- package/src/Overlay/index.tsx +1 -0
- package/src/RealtimeLayer/RealtimeLayer.tsx +230 -0
- package/src/RealtimeLayer/index.tsx +1 -0
- package/src/RouteDestination/RouteDestination.test.tsx +13 -0
- package/src/RouteDestination/RouteDestination.tsx +15 -0
- package/src/RouteDestination/index.tsx +1 -0
- package/src/RouteIcon/RouteIcon.tsx +66 -0
- package/src/RouteIcon/index.tsx +1 -0
- package/src/RouteIdentifier/RouteIdentifer.tsx +35 -0
- package/src/RouteIdentifier/index.tsx +1 -0
- package/src/RouteInfos/RouteInfos.tsx +22 -0
- package/src/RouteInfos/index.tsx +1 -0
- package/src/RouteSchedule/RouteSchedule.tsx +69 -0
- package/src/RouteSchedule/firstStation.png +0 -0
- package/src/RouteSchedule/index.tsx +1 -0
- package/src/RouteSchedule/lastStation.png +0 -0
- package/src/RouteSchedule/line.png +0 -0
- package/src/RouteSchedule/station.png +0 -0
- package/src/RouteScheduleFooter/RouteScheduleFooter.tsx +44 -0
- package/src/RouteScheduleFooter/index.tsx +1 -0
- package/src/RouteScheduleHeader/RouteScheduleHeader.tsx +58 -0
- package/src/RouteScheduleHeader/index.tsx +1 -0
- package/src/RouteStop/RouteStop.tsx +121 -0
- package/src/RouteStop/index.tsx +1 -0
- package/src/RouteStopDelay/RouteStopDelay.tsx +36 -0
- package/src/RouteStopDelay/index.tsx +1 -0
- package/src/RouteStopName/RouteStopName.tsx +24 -0
- package/src/RouteStopName/index.tsx +1 -0
- package/src/RouteStopPlatform/RouteStopPlatform.tsx +29 -0
- package/src/RouteStopPlatform/index.tsx +1 -0
- package/src/RouteStopProgress/RouteStopProgress.tsx +101 -0
- package/src/RouteStopProgress/index.tsx +1 -0
- package/src/RouteStopServices/RouteStopServices.tsx +26 -0
- package/src/RouteStopServices/index.tsx +1 -0
- package/src/RouteStopStation/RouteStopStation.tsx +32 -0
- package/src/RouteStopStation/index.tsx +1 -0
- package/src/RouteStopTime/RouteStopTime.tsx +34 -0
- package/src/RouteStopTime/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +245 -0
- package/src/RvfMobilityMap/index.css +13 -0
- package/src/RvfMobilityMap/index.tsx +1 -0
- package/src/ScaleLine/ScaleLine.tsx +51 -0
- package/src/ScaleLine/index.css +6 -0
- package/src/ScaleLine/index.tsx +1 -0
- package/src/ScrollableHandler/ScrollableHandler.tsx +65 -0
- package/src/ScrollableHandler/index.tsx +1 -0
- package/src/Search/Search.tsx +18 -0
- package/src/Search/index.tsx +1 -0
- package/src/SingleClickListener/SingleClickListener.tsx +103 -0
- package/src/SingleClickListener/index.tsx +1 -0
- package/src/Station/Station.tsx +68 -0
- package/src/Station/index.tsx +1 -0
- package/src/StationHeader/StationHeader.tsx +32 -0
- package/src/StationHeader/index.tsx +1 -0
- package/src/StationName/StationName.tsx +21 -0
- package/src/StationName/index.tsx +1 -0
- package/src/StationServices/StationServices.tsx +80 -0
- package/src/StationServices/index.tsx +1 -0
- package/src/StationsLayer/StationsLayer.tsx +41 -0
- package/src/StationsLayer/index.tsx +1 -0
- package/src/StopsSearch/StopsSearch.tsx +254 -0
- package/src/StopsSearch/index.tsx +1 -0
- package/src/icons/Airport/Airport.tsx +17 -0
- package/src/icons/Airport/airport-14-svgrepo-com.svg +41 -0
- package/src/icons/Airport/index.tsx +1 -0
- package/src/icons/BarAndRestaurants/BarAndRestaurants.tsx +17 -0
- package/src/icons/BarAndRestaurants/food-restaurant-svgrepo-com.svg +12 -0
- package/src/icons/BarAndRestaurants/index.tsx +1 -0
- package/src/icons/Bathroom/Bathroom.tsx +59 -0
- package/src/icons/Bathroom/bathroom-restroom-svgrepo-com.svg +38 -0
- package/src/icons/Bathroom/index.tsx +1 -0
- package/src/icons/BikeStorage/BikeStorage.tsx +17 -0
- package/src/icons/BikeStorage/index.tsx +1 -0
- package/src/icons/BikeStorage/parking-bicycle-14-svgrepo-com.svg +41 -0
- package/src/icons/Elevator/Elevator.tsx +16 -0
- package/src/icons/Elevator/elevator-svgrepo-com.svg +2 -0
- package/src/icons/Elevator/index.tsx +1 -0
- package/src/icons/Police/Police.tsx +20 -0
- package/src/icons/Police/index.tsx +1 -0
- package/src/icons/Police/polizia.png +0 -0
- package/src/icons/README.md +52 -0
- package/src/icons/WaitingAreas/WaitingAreas.tsx +16 -0
- package/src/icons/WaitingAreas/highway-rest-area-svgrepo-com.svg +5 -0
- package/src/icons/WaitingAreas/index.tsx +1 -0
- package/src/icons/WaitingAreas/wheelchair-svgrepo-com.svg +2 -0
- package/src/icons/WheelChair/WheelChair.tsx +16 -0
- package/src/icons/WheelChair/disabili.png +0 -0
- package/src/icons/WheelChair/index.tsx +1 -0
- package/src/icons/WheelChair/wheelchair-svgrepo-com.svg +2 -0
- package/src/index.tsx +50 -0
- package/src/utils/MobilityEvent.ts +21 -0
- package/src/utils/addSourceAndLayers.ts +62 -0
- package/src/utils/centerOnStation.ts +17 -0
- package/src/utils/centerOnVehicle.ts +50 -0
- package/src/utils/getBgColor.ts +3 -0
- package/src/utils/getDelayColor.test.ts +20 -0
- package/src/utils/getDelayColor.ts +23 -0
- package/src/utils/getDelayColorForVehicle.test.ts +28 -0
- package/src/utils/getDelayColorForVehicle.ts +25 -0
- package/src/utils/getDelayFontForVehicle.test.ts +7 -0
- package/src/utils/getDelayFontForVehicle.tsx +8 -0
- package/src/utils/getDelayString.test.ts +22 -0
- package/src/utils/getDelayString.ts +28 -0
- package/src/utils/getDelayTextForVehicle.test.ts +28 -0
- package/src/utils/getDelayTextForVehicle.ts +21 -0
- package/src/utils/getFullTrajectoryAndFit.ts +40 -0
- package/src/utils/getHoursAndMinutes.test.ts +14 -0
- package/src/utils/getHoursAndMinutes.ts +22 -0
- package/src/utils/getMainColorForVehicle.test.ts +27 -0
- package/src/utils/getMainColorForVehicle.ts +46 -0
- package/src/utils/getStopStatus.test.ts +104 -0
- package/src/utils/getStopStatus.ts +171 -0
- package/src/utils/getTextFontForVehicle.test.ts +7 -0
- package/src/utils/getTextFontForVehicle.tsx +9 -0
- package/src/utils/getTextForVehicle.test.ts +17 -0
- package/src/utils/getTextForVehicle.ts +19 -0
- package/src/utils/hooks/useDebug.tsx +11 -0
- package/src/utils/hooks/useDeparture.tsx +23 -0
- package/src/utils/hooks/useI18n.tsx +20 -0
- package/src/utils/hooks/useMapContext.tsx +74 -0
- package/src/utils/hooks/useParams.ts +5 -0
- package/src/utils/hooks/useRouteStop.tsx +33 -0
- package/src/utils/hooks/useStation.tsx +21 -0
- package/src/utils/hooks/useUpdatePermalink.tsx +33 -0
- package/src/utils/hooks/useZoom.tsx +32 -0
- package/src/utils/i18n.ts +16 -0
- package/src/utils/translations.ts +31 -0
- package/tailwind.config.mjs +56 -0
- package/testNotification.json +50653 -0
- package/tsconfig.json +12 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function Police({ ...props }) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
fill="currentColor"
|
|
5
|
+
width="24px"
|
|
6
|
+
height="24px"
|
|
7
|
+
viewBox="0 0 15 15"
|
|
8
|
+
version="1.1"
|
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
10
|
+
{...props}
|
|
11
|
+
>
|
|
12
|
+
<path
|
|
13
|
+
id="rect4718"
|
|
14
|
+
d="M5.5,1L6,2h5l0.5-1H5.5z M6,2.5v1.25c0,0,0,2.75,2.5,2.75S11,3.75,11,3.75V2.5H6z M1.9844,3.9863
	C1.4329,3.9949,0.9924,4.4485,1,5v4c-0.0001,0.6398,0.5922,1.1152,1.2168,0.9766L5,9.3574V14l5.8789-6.9297
	C10.7391,7.0294,10.5947,7,10.4414,7H6.5L3,7.7539V5C3.0077,4.4362,2.5481,3.9775,1.9844,3.9863z M11.748,7.7109L6.4121,14H12
	V8.5586C12,8.2451,11.9061,7.9548,11.748,7.7109z"
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export default Police;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./Police";
|
|
Binary file
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Icons
|
|
2
|
+
|
|
3
|
+
This folder contains icons used inside the web component.
|
|
4
|
+
Icons are preact components that display an SVG. No raster data (PNGs,JPEGs...).
|
|
5
|
+
Until we decide otherwise, we don't want to use automatic transformation from SVG to component like using SVGR.
|
|
6
|
+
So you must create and clean your component manually.
|
|
7
|
+
|
|
8
|
+
Icon must have their color defines with currentColor
|
|
9
|
+
|
|
10
|
+
You can let the original svg file in the corrsponding folder to keep track of them.
|
|
11
|
+
|
|
12
|
+
## Guidelines
|
|
13
|
+
|
|
14
|
+
- Structure of folders follows the same rules as in normal components.
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
MyIcon/index.tsx // only export the component
|
|
18
|
+
/MyIcon.tsx // the component containing the SVG
|
|
19
|
+
/icon.svg // the original SVG file
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
- Set the width and height attribute to 24 pixels
|
|
23
|
+
|
|
24
|
+
- Propagate all the component props
|
|
25
|
+
|
|
26
|
+
- Set the fill attribute to `currentcColor`
|
|
27
|
+
|
|
28
|
+
- Clean all useless properties.
|
|
29
|
+
|
|
30
|
+
Here an example how it should look like:
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
function MyIcon({ ...props }) {
|
|
34
|
+
return (
|
|
35
|
+
<svg
|
|
36
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
37
|
+
version="1.1"
|
|
38
|
+
width="24"
|
|
39
|
+
height="24"
|
|
40
|
+
fill="currentColor"
|
|
41
|
+
viewBox="0 0 14 14"
|
|
42
|
+
{...props}
|
|
43
|
+
>
|
|
44
|
+
</svg>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Where to find icons
|
|
51
|
+
|
|
52
|
+
For now, if you need new icon, use <https://www.svgrepo.com/> and select only icons you are allowed to use and modify.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function WaitingAreas({ ...props }) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
fill="currentColor"
|
|
5
|
+
width="24px"
|
|
6
|
+
height="24px"
|
|
7
|
+
viewBox="0 0 15 15"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
{...props}
|
|
10
|
+
>
|
|
11
|
+
<path d="M13.5,13h-3V9h3a.5.5,0,0,0,.4092-.7871L11.66,5h.84a.5.5,0,0,0,.3838-.82l-2.5-3a.5155.5155,0,0,0-.7676,0l-2.5,3A.5.5,0,0,0,7.5,5h.84L6.0908,8.2129A.5.5,0,0,0,6.5,9h3v4H4V11H5.5a.5.5,0,0,0,0-1h-4a.5.5,0,0,0,0,1H3v2H1.5a.5.5,0,0,0,0,1h12a.5.5,0,0,0,0-1Z" />
|
|
12
|
+
</svg>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default WaitingAreas;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
3
|
+
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 15 15" xmlns="http://www.w3.org/2000/svg" id="highway-rest-area">
|
|
4
|
+
<path d="M13.5,13h-3V9h3a.5.5,0,0,0,.4092-.7871L11.66,5h.84a.5.5,0,0,0,.3838-.82l-2.5-3a.5155.5155,0,0,0-.7676,0l-2.5,3A.5.5,0,0,0,7.5,5h.84L6.0908,8.2129A.5.5,0,0,0,6.5,9h3v4H4V11H5.5a.5.5,0,0,0,0-1h-4a.5.5,0,0,0,0,1H3v2H1.5a.5.5,0,0,0,0,1h12a.5.5,0,0,0,0-1Z"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./WaitingAreas";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg fill="inheritColor" width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1"><path d="M12,6.5a2,2,0,1,0-2-2A2,2,0,0,0,12,6.5Zm7.5,14h-1v-5a1,1,0,0,0-1-1h-5v-2h5a1,1,0,0,0,0-2h-5v-2a1,1,0,0,0-2,0v7a1,1,0,0,0,1,1h5v5a1,1,0,0,0,1,1h2a1,1,0,0,0,0-2Zm-6.8-1.6a4,4,0,0,1-7.2-2.4,4,4,0,0,1,2.4-3.66A1,1,0,1,0,7.1,11a6,6,0,1,0,7.2,9.1,1,1,0,0,0-1.6-1.2Z"/></svg>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function WheelChair({ ...props }) {
|
|
2
|
+
return (
|
|
3
|
+
<svg
|
|
4
|
+
fill="currentColor"
|
|
5
|
+
width="24px"
|
|
6
|
+
height="24px"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
9
|
+
{...props}
|
|
10
|
+
>
|
|
11
|
+
<path d="M12,6.5a2,2,0,1,0-2-2A2,2,0,0,0,12,6.5Zm7.5,14h-1v-5a1,1,0,0,0-1-1h-5v-2h5a1,1,0,0,0,0-2h-5v-2a1,1,0,0,0-2,0v7a1,1,0,0,0,1,1h5v5a1,1,0,0,0,1,1h2a1,1,0,0,0,0-2Zm-6.8-1.6a4,4,0,0,1-7.2-2.4,4,4,0,0,1,2.4-3.66A1,1,0,1,0,7.1,11a6,6,0,1,0,7.2,9.1,1,1,0,0,0-1.6-1.2Z" />
|
|
12
|
+
</svg>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export default WheelChair;
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./WheelChair";
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
|
2
|
+
<svg fill="inheritColor" width="24px" height="24px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1"><path d="M12,6.5a2,2,0,1,0-2-2A2,2,0,0,0,12,6.5Zm7.5,14h-1v-5a1,1,0,0,0-1-1h-5v-2h5a1,1,0,0,0,0-2h-5v-2a1,1,0,0,0-2,0v7a1,1,0,0,0,1,1h5v5a1,1,0,0,0,1,1h2a1,1,0,0,0,0-2Zm-6.8-1.6a4,4,0,0,1-7.2-2.4,4,4,0,0,1,2.4-3.66A1,1,0,1,0,7.1,11a6,6,0,1,0,7.2,9.1,1,1,0,0,0-1.6-1.2Z"/></svg>
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import register from "preact-custom-element";
|
|
2
|
+
|
|
3
|
+
import MobilityMap from "./MobilityMap";
|
|
4
|
+
import MobilitySearch from "./StopsSearch";
|
|
5
|
+
|
|
6
|
+
register(
|
|
7
|
+
MobilityMap,
|
|
8
|
+
"geops-mobility",
|
|
9
|
+
[
|
|
10
|
+
"apikey",
|
|
11
|
+
"baselayer",
|
|
12
|
+
"center",
|
|
13
|
+
"geolocation",
|
|
14
|
+
"mapsurl",
|
|
15
|
+
"mots",
|
|
16
|
+
"notification",
|
|
17
|
+
"notificationat",
|
|
18
|
+
"notificationurl",
|
|
19
|
+
"notificationbeforelayerid",
|
|
20
|
+
"realtime",
|
|
21
|
+
"realtimeUrl",
|
|
22
|
+
"search",
|
|
23
|
+
"tenant",
|
|
24
|
+
"zoom",
|
|
25
|
+
"permalink",
|
|
26
|
+
],
|
|
27
|
+
{ shadow: true },
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
register(
|
|
31
|
+
MobilitySearch,
|
|
32
|
+
"geops-mobility-search",
|
|
33
|
+
[
|
|
34
|
+
"apikey",
|
|
35
|
+
"bbox",
|
|
36
|
+
"countrycode",
|
|
37
|
+
"event",
|
|
38
|
+
"field",
|
|
39
|
+
"limit",
|
|
40
|
+
"mots",
|
|
41
|
+
"onselect",
|
|
42
|
+
"params",
|
|
43
|
+
"prefagencies",
|
|
44
|
+
"reflocation",
|
|
45
|
+
"url",
|
|
46
|
+
],
|
|
47
|
+
{
|
|
48
|
+
shadow: true,
|
|
49
|
+
},
|
|
50
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MobilityMapProps } from "../MobilityMap/MobilityMap";
|
|
2
|
+
|
|
3
|
+
export type MobilityEventType =
|
|
4
|
+
| "mwc:attribute"
|
|
5
|
+
| "mwc:stopssearchselect"
|
|
6
|
+
| string;
|
|
7
|
+
|
|
8
|
+
class MobilityEvent<T> extends Event {
|
|
9
|
+
data: MobilityMapProps;
|
|
10
|
+
|
|
11
|
+
constructor(name: MobilityEventType, data: T, options: EventInit = {}) {
|
|
12
|
+
super(name, { ...options, composed: true });
|
|
13
|
+
this.data = data;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
logImportantData() {
|
|
17
|
+
console.log(this.data);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default MobilityEvent;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Add a source and styleLayer using the id in parameter.
|
|
2
|
+
const addSourceAndLayers = (
|
|
3
|
+
mapboxLayer,
|
|
4
|
+
sourceId,
|
|
5
|
+
sourceData,
|
|
6
|
+
styleLayer,
|
|
7
|
+
beforeLayerId,
|
|
8
|
+
) => {
|
|
9
|
+
if (!mapboxLayer.loaded) {
|
|
10
|
+
mapboxLayer.once("load", () => {
|
|
11
|
+
addSourceAndLayers(
|
|
12
|
+
mapboxLayer,
|
|
13
|
+
sourceId,
|
|
14
|
+
sourceData,
|
|
15
|
+
styleLayer,
|
|
16
|
+
beforeLayerId,
|
|
17
|
+
);
|
|
18
|
+
});
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const { mbMap } = mapboxLayer;
|
|
22
|
+
|
|
23
|
+
// Update source
|
|
24
|
+
if (sourceId && sourceData) {
|
|
25
|
+
const source = mbMap.getSource(sourceId);
|
|
26
|
+
if (source) {
|
|
27
|
+
source.setData(sourceData.data);
|
|
28
|
+
} else {
|
|
29
|
+
mbMap.addSource(sourceId, sourceData);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Update layer
|
|
34
|
+
if (styleLayer) {
|
|
35
|
+
let layer = mbMap.getLayer(sourceId);
|
|
36
|
+
if (layer) {
|
|
37
|
+
mbMap.removeLayer(layer.id);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// styleLayer could be an array of styles to add.
|
|
41
|
+
let styleLayers = styleLayer;
|
|
42
|
+
if (!Array.isArray(styleLayer)) {
|
|
43
|
+
styleLayers = [styleLayer];
|
|
44
|
+
}
|
|
45
|
+
styleLayers.forEach((style) => {
|
|
46
|
+
if (mbMap.getSource(style.source)) {
|
|
47
|
+
layer = mbMap.getLayer(style.id);
|
|
48
|
+
if (layer) {
|
|
49
|
+
mbMap.removeLayer(layer.id);
|
|
50
|
+
}
|
|
51
|
+
mbMap.addLayer(style, beforeLayerId);
|
|
52
|
+
} else {
|
|
53
|
+
console.warn(
|
|
54
|
+
`The source ${style.source} doesn't exist. This layer can't be added`,
|
|
55
|
+
style,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export default addSourceAndLayers;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Map } from "ol";
|
|
2
|
+
import { fromLonLat } from "ol/proj";
|
|
3
|
+
|
|
4
|
+
import { StationFeature } from "../StopsSearch";
|
|
5
|
+
|
|
6
|
+
const centerOnStation = (selectedStation: StationFeature, map: Map) => {
|
|
7
|
+
const center = selectedStation?.geometry?.coordinates;
|
|
8
|
+
if (center) {
|
|
9
|
+
map?.getView()?.animate({
|
|
10
|
+
center: fromLonLat(center),
|
|
11
|
+
duration: 500,
|
|
12
|
+
zoom: 16,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default centerOnStation;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getVehiclePosition } from "mobility-toolbox-js/ol";
|
|
2
|
+
import { RealtimeTrajectory } from "mobility-toolbox-js/types";
|
|
3
|
+
import { Map } from "ol";
|
|
4
|
+
import { linear } from "ol/easing";
|
|
5
|
+
|
|
6
|
+
const centerOnVehicle = async (
|
|
7
|
+
vehicle: RealtimeTrajectory,
|
|
8
|
+
map: Map,
|
|
9
|
+
targetZoom = 0,
|
|
10
|
+
) => {
|
|
11
|
+
if (!vehicle) {
|
|
12
|
+
return Promise.reject();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
geometry,
|
|
17
|
+
properties: { coordinate },
|
|
18
|
+
} = vehicle;
|
|
19
|
+
const view = map.getView();
|
|
20
|
+
const zoom = targetZoom || view.getZoom();
|
|
21
|
+
const resolution = zoom > 0 ? view.getResolutionForZoom(zoom) : undefined;
|
|
22
|
+
|
|
23
|
+
let center = coordinate;
|
|
24
|
+
if (!center && geometry) {
|
|
25
|
+
const { coord } = getVehiclePosition(Date.now(), vehicle, true);
|
|
26
|
+
center = coord as [number, number];
|
|
27
|
+
}
|
|
28
|
+
if (!center) {
|
|
29
|
+
return Promise.reject();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
view.cancelAnimations();
|
|
33
|
+
|
|
34
|
+
const promise = new Promise((resolve) => {
|
|
35
|
+
view.animate(
|
|
36
|
+
{
|
|
37
|
+
center,
|
|
38
|
+
duration: 1000,
|
|
39
|
+
easing: linear,
|
|
40
|
+
resolution,
|
|
41
|
+
},
|
|
42
|
+
(success) => {
|
|
43
|
+
resolve(success);
|
|
44
|
+
},
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
return promise;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default centerOnVehicle;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import getDelayColor from "./getDelayColor";
|
|
2
|
+
|
|
3
|
+
describe("getDelayColor", () => {
|
|
4
|
+
it("returns green", () => {
|
|
5
|
+
expect(getDelayColor(0)).toBe("#16a34a");
|
|
6
|
+
expect(getDelayColor(2.49 * 60 * 1000)).toBe("#16a34a");
|
|
7
|
+
});
|
|
8
|
+
it("returns yellow", () => {
|
|
9
|
+
expect(getDelayColor(3 * 60 * 1000)).toBe("#ca8a04");
|
|
10
|
+
expect(getDelayColor(4.49 * 60 * 1000 - 1)).toBe("#ca8a04");
|
|
11
|
+
});
|
|
12
|
+
it("returns orange", () => {
|
|
13
|
+
expect(getDelayColor(5 * 60 * 1000)).toBe("#ea580c");
|
|
14
|
+
expect(getDelayColor(9.49 * 60 * 1000 - 1)).toBe("#ea580c");
|
|
15
|
+
});
|
|
16
|
+
it("returns red", () => {
|
|
17
|
+
expect(getDelayColor(10 * 60 * 1000)).toBe("#dc2626");
|
|
18
|
+
expect(getDelayColor(180 * 60 * 1000)).toBe("#dc2626");
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a color class to display the delay.
|
|
3
|
+
* @param {Number} time Delay time in milliseconds.
|
|
4
|
+
*/
|
|
5
|
+
const getDelayColor = (timeInMs: number) => {
|
|
6
|
+
// we use rounded value to fit the getDelayString method.
|
|
7
|
+
const minutes = Math.round(timeInMs / 1000 / 60);
|
|
8
|
+
// if (minutes >= 60) {
|
|
9
|
+
// }
|
|
10
|
+
if (minutes >= 10) {
|
|
11
|
+
return "#dc2626"; // "text-red-600";
|
|
12
|
+
}
|
|
13
|
+
if (minutes >= 5) {
|
|
14
|
+
return "#ea580c"; // "text-orange-600";
|
|
15
|
+
// return "#d97706"; // "text-amber-600";
|
|
16
|
+
}
|
|
17
|
+
if (minutes >= 3) {
|
|
18
|
+
return "#ca8a04"; // "text-yellow-600";
|
|
19
|
+
}
|
|
20
|
+
return "#16a34a"; // "text-green-600";
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default getDelayColor;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import getDelayColorForVehicle from "./getDelayColorForVehicle";
|
|
2
|
+
|
|
3
|
+
describe("getDelayColorForVehicle", () => {
|
|
4
|
+
it("returns cancelled color", () => {
|
|
5
|
+
expect(getDelayColorForVehicle(0, true, true)).toBe("#dc2626");
|
|
6
|
+
expect(getDelayColorForVehicle(0, true, false)).toBe("#a0a0a0");
|
|
7
|
+
});
|
|
8
|
+
it("returns null delay (no realtime train) color", () => {
|
|
9
|
+
expect(getDelayColorForVehicle(null)).toBe("#a0a0a0");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("returns green", () => {
|
|
13
|
+
expect(getDelayColorForVehicle(0)).toBe("#16a34a");
|
|
14
|
+
expect(getDelayColorForVehicle(2.49 * 60 * 1000)).toBe("#16a34a");
|
|
15
|
+
});
|
|
16
|
+
it("returns yellow", () => {
|
|
17
|
+
expect(getDelayColorForVehicle(3 * 60 * 1000)).toBe("#ca8a04");
|
|
18
|
+
expect(getDelayColorForVehicle(4.49 * 60 * 1000 - 1)).toBe("#ca8a04");
|
|
19
|
+
});
|
|
20
|
+
it("returns orange", () => {
|
|
21
|
+
expect(getDelayColorForVehicle(5 * 60 * 1000)).toBe("#ea580c");
|
|
22
|
+
expect(getDelayColorForVehicle(9.49 * 60 * 1000 - 1)).toBe("#ea580c");
|
|
23
|
+
});
|
|
24
|
+
it("returns red", () => {
|
|
25
|
+
expect(getDelayColorForVehicle(10 * 60 * 1000)).toBe("#dc2626");
|
|
26
|
+
expect(getDelayColorForVehicle(180 * 60 * 1000)).toBe("#dc2626");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import getDelayColor from "./getDelayColor";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @private
|
|
5
|
+
* @param {number} delayInMs Delay in milliseconds.
|
|
6
|
+
* @param {boolean} cancelled true if the journey is cancelled.
|
|
7
|
+
* @param {boolean} isDelayText true if the color is used for delay text of the symbol.
|
|
8
|
+
*/
|
|
9
|
+
const getDelayColorForVehicle = (
|
|
10
|
+
delayInMs: null | number,
|
|
11
|
+
cancelled?: boolean,
|
|
12
|
+
isDelayText?: boolean,
|
|
13
|
+
): string => {
|
|
14
|
+
if (cancelled) {
|
|
15
|
+
return isDelayText
|
|
16
|
+
? "#dc2626" // "text-red-600";
|
|
17
|
+
: "#a0a0a0"; // gray
|
|
18
|
+
}
|
|
19
|
+
if (delayInMs === null) {
|
|
20
|
+
return "#a0a0a0";
|
|
21
|
+
}
|
|
22
|
+
return getDelayColor(delayInMs);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default getDelayColorForVehicle;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import getDelayString from "./getDelayString";
|
|
2
|
+
|
|
3
|
+
describe("getDelayString", () => {
|
|
4
|
+
it("returns hours (floor)", () => {
|
|
5
|
+
expect(getDelayString(7200000)).toBe("2h");
|
|
6
|
+
expect(getDelayString(7255555)).toBe("2h1m");
|
|
7
|
+
});
|
|
8
|
+
it("returns minutes (round)", () => {
|
|
9
|
+
expect(getDelayString(120000)).toBe("2m");
|
|
10
|
+
expect(getDelayString(151000)).toBe("3m");
|
|
11
|
+
});
|
|
12
|
+
it("doesn't display seconds", () => {
|
|
13
|
+
expect(getDelayString(1000)).toBe("0");
|
|
14
|
+
expect(getDelayString(30000)).toBe("1m");
|
|
15
|
+
expect(getDelayString(7255555)).toBe("2h1m");
|
|
16
|
+
});
|
|
17
|
+
it("returns defsult 0 value", () => {
|
|
18
|
+
expect(getDelayString(0)).toBe("0");
|
|
19
|
+
expect(getDelayString(null)).toBe("0");
|
|
20
|
+
expect(getDelayString(undefined)).toBe("0");
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a string representing a delay.
|
|
3
|
+
* @param {Number} timeInMs Delay time in milliseconds.
|
|
4
|
+
* @ignore
|
|
5
|
+
*/
|
|
6
|
+
const getDelayString = (delayInMs: number) => {
|
|
7
|
+
let timeInMs = delayInMs;
|
|
8
|
+
if (timeInMs < 0) {
|
|
9
|
+
timeInMs = 0;
|
|
10
|
+
}
|
|
11
|
+
const h = Math.floor(timeInMs / 3600000);
|
|
12
|
+
const m = Math.round((timeInMs % 3600000) / 60000);
|
|
13
|
+
// const s = Math.floor(((timeInMs % 3600000) % 60000) / 1000);
|
|
14
|
+
|
|
15
|
+
let str = "";
|
|
16
|
+
if (h > 0) {
|
|
17
|
+
str += `${h}h`;
|
|
18
|
+
}
|
|
19
|
+
if (m > 0) {
|
|
20
|
+
str += `${m}m`;
|
|
21
|
+
}
|
|
22
|
+
// if (s > 0) {
|
|
23
|
+
// str += `${s}s`;
|
|
24
|
+
// }
|
|
25
|
+
return str || "0";
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default getDelayString;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import getDelayTextForVehicle from "./getDelayTextForVehicle";
|
|
2
|
+
|
|
3
|
+
describe("getDelayTextForVehicle", () => {
|
|
4
|
+
it("returns cancelled character", () => {
|
|
5
|
+
expect(getDelayTextForVehicle(7200000, true)).toBe(
|
|
6
|
+
String.fromCodePoint(0x00d7),
|
|
7
|
+
);
|
|
8
|
+
});
|
|
9
|
+
it("returns hours (floor)", () => {
|
|
10
|
+
expect(getDelayTextForVehicle(7200000)).toBe("+2h");
|
|
11
|
+
expect(getDelayTextForVehicle(7255555)).toBe("+2h1m");
|
|
12
|
+
});
|
|
13
|
+
it("returns minutes (round)", () => {
|
|
14
|
+
expect(getDelayTextForVehicle(120000)).toBe("+2m");
|
|
15
|
+
expect(getDelayTextForVehicle(151000)).toBe("+3m");
|
|
16
|
+
});
|
|
17
|
+
it("doesn't display seconds", () => {
|
|
18
|
+
expect(getDelayTextForVehicle(1000)).toBe("");
|
|
19
|
+
expect(getDelayTextForVehicle(30000)).toBe("+1m");
|
|
20
|
+
expect(getDelayTextForVehicle(7255555)).toBe("+2h1m");
|
|
21
|
+
});
|
|
22
|
+
it("returns empty value", () => {
|
|
23
|
+
expect(getDelayTextForVehicle(1000)).toBe("");
|
|
24
|
+
expect(getDelayTextForVehicle(null)).toBe("");
|
|
25
|
+
expect(getDelayTextForVehicle(undefined)).toBe("");
|
|
26
|
+
expect(getDelayTextForVehicle(0)).toBe("");
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import getDelayString from "./getDelayString";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This function returns the text displays near the vehicle.
|
|
5
|
+
* We use getDelayString inside it to make sure that RouteSchedule and
|
|
6
|
+
* the map have the same values.
|
|
7
|
+
*/
|
|
8
|
+
const getDelayTextForVehicle = (
|
|
9
|
+
delayInMs: number,
|
|
10
|
+
cancelled = false,
|
|
11
|
+
): string => {
|
|
12
|
+
if (cancelled) {
|
|
13
|
+
return String.fromCodePoint(0x00d7);
|
|
14
|
+
}
|
|
15
|
+
const delayString = getDelayString(delayInMs);
|
|
16
|
+
if (delayString === "0") {
|
|
17
|
+
return "";
|
|
18
|
+
}
|
|
19
|
+
return `+${delayString}`;
|
|
20
|
+
};
|
|
21
|
+
export default getDelayTextForVehicle;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { RealtimeLayer } from "mobility-toolbox-js/ol";
|
|
2
|
+
import { RealtimeTrainId } from "mobility-toolbox-js/types";
|
|
3
|
+
import { Map } from "ol";
|
|
4
|
+
import { GeoJSON } from "ol/format";
|
|
5
|
+
import { Vector } from "ol/source";
|
|
6
|
+
|
|
7
|
+
const getFullTrajectoryAndFit = async (
|
|
8
|
+
map: Map,
|
|
9
|
+
realtimeLayer: RealtimeLayer,
|
|
10
|
+
trainId: RealtimeTrainId,
|
|
11
|
+
targetZoom = 0,
|
|
12
|
+
) => {
|
|
13
|
+
// TO IMPROVE:
|
|
14
|
+
// We should be able to get a trajectory directly but it does not work because the trajectory is outside the bbox
|
|
15
|
+
// see /BAHNMW-805 and TGSRVI-1126
|
|
16
|
+
// So we get the full trajectory then zoom on it.
|
|
17
|
+
|
|
18
|
+
const fullTrajectory = await realtimeLayer.api.getFullTrajectory(
|
|
19
|
+
trainId,
|
|
20
|
+
realtimeLayer.mode,
|
|
21
|
+
realtimeLayer.engine.generalizationLevelByZoom[targetZoom],
|
|
22
|
+
);
|
|
23
|
+
if (fullTrajectory?.content?.features?.length) {
|
|
24
|
+
const extent = new Vector({
|
|
25
|
+
features: new GeoJSON().readFeatures(fullTrajectory.content),
|
|
26
|
+
}).getExtent();
|
|
27
|
+
|
|
28
|
+
const promise = new Promise((resolve) => {
|
|
29
|
+
map.getView().fit(extent, {
|
|
30
|
+
callback: (success) => {
|
|
31
|
+
resolve(success);
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
return promise;
|
|
36
|
+
}
|
|
37
|
+
return Promise.resolve(false);
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export default getFullTrajectoryAndFit;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import getHoursAndMinutes from "./getHoursAndMinutes";
|
|
2
|
+
|
|
3
|
+
describe("getHoursAndMinutes", () => {
|
|
4
|
+
it("returns hours and minutes", () => {
|
|
5
|
+
expect(getHoursAndMinutes(7200000)).toBe("02:00");
|
|
6
|
+
expect(getHoursAndMinutes(72999999)).toBe("20:16");
|
|
7
|
+
});
|
|
8
|
+
it("returns empty string", () => {
|
|
9
|
+
expect(getHoursAndMinutes(null)).toBe("");
|
|
10
|
+
expect(getHoursAndMinutes(undefined)).toBe("");
|
|
11
|
+
expect(getHoursAndMinutes(0)).toBe("");
|
|
12
|
+
expect(getHoursAndMinutes(-500000)).toBe("");
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a string representation of a number, with a zero if the number is lower than 10.
|
|
3
|
+
* @ignore
|
|
4
|
+
*/
|
|
5
|
+
const pad = (integer: number) => {
|
|
6
|
+
return integer < 10 ? `0${integer}` : integer;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Returns a 'hh:mm' string from a time in ms.
|
|
11
|
+
* @param {Number} timeInMs Time in milliseconds.
|
|
12
|
+
* @ignore
|
|
13
|
+
*/
|
|
14
|
+
const getHoursAndMinutes = (timeInMs: number) => {
|
|
15
|
+
if (!timeInMs || timeInMs <= 0) {
|
|
16
|
+
return "";
|
|
17
|
+
}
|
|
18
|
+
const date = new Date(timeInMs);
|
|
19
|
+
return `${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default getHoursAndMinutes;
|