@opentripplanner/vehicle-rental-overlay 1.4.3 → 2.0.0-alpha.1
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/esm/StationPopup.js +99 -0
- package/esm/StationPopup.js.map +1 -0
- package/esm/index.js +145 -355
- package/esm/index.js.map +1 -1
- package/esm/styled.js +48 -50
- package/esm/styled.js.map +1 -1
- package/lib/StationPopup.d.ts +15 -0
- package/lib/StationPopup.d.ts.map +1 -0
- package/lib/StationPopup.js +119 -0
- package/lib/StationPopup.js.map +1 -0
- package/lib/index.d.ts +61 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +126 -334
- package/lib/index.js.map +1 -1
- package/lib/styled.d.ts +11 -0
- package/lib/styled.d.ts.map +1 -0
- package/lib/styled.js +48 -63
- package/lib/styled.js.map +1 -1
- package/package.json +8 -6
- package/src/StationPopup.tsx +146 -0
- package/src/VehicleRentalOverlay.story.tsx +124 -0
- package/src/index.tsx +255 -0
- package/src/styled.ts +52 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +4891 -0
- package/esm/DefaultMarkers/index.js +0 -140
- package/esm/DefaultMarkers/index.js.map +0 -1
- package/esm/bike-icons.js +0 -21
- package/esm/bike-icons.js.map +0 -1
- package/lib/DefaultMarkers/index.js +0 -165
- package/lib/DefaultMarkers/index.js.map +0 -1
- package/lib/bike-icons.js +0 -38
- package/lib/bike-icons.js.map +0 -1
- package/src/DefaultMarkers/index.js +0 -130
- package/src/VehicleRentalOverlay.story.js +0 -284
- package/src/bike-icons.js +0 -23
- package/src/index.js +0 -377
- package/src/styled.js +0 -78
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Styled as BaseMapStyled } from "@opentripplanner/base-map";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import FromToLocationPicker from "@opentripplanner/from-to-location-picker";
|
|
4
|
+
import coreUtils from "@opentripplanner/core-utils";
|
|
5
|
+
import { useIntl, FormattedMessage } from "react-intl";
|
|
6
|
+
import flatten from "flat"; // Load the default messages.
|
|
7
|
+
// @ts-expect-error why is this failing?
|
|
8
|
+
|
|
9
|
+
import defaultEnglishMessages from "../i18n/en-US.yml"; // HACK: We should flatten the messages loaded above because
|
|
10
|
+
// the YAML loaders behave differently between webpack and our version of jest:
|
|
11
|
+
// - the yaml loader for webpack returns a nested object,
|
|
12
|
+
// - the yaml loader for jest returns messages with flattened ids.
|
|
13
|
+
|
|
14
|
+
var defaultMessages = flatten(defaultEnglishMessages);
|
|
15
|
+
|
|
16
|
+
function makeDefaultGetStationName(intl) {
|
|
17
|
+
return function defaultGetStationName(configCompanies, station) {
|
|
18
|
+
var stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks((station === null || station === void 0 ? void 0 : station.networks) || [], configCompanies);
|
|
19
|
+
var stationName = station.name || station.id; // If the station name or id is a giant UUID (with more than 3 "-" characters)
|
|
20
|
+
// best not to show that at all and instead use the network name.
|
|
21
|
+
|
|
22
|
+
if ((stationName.match(/-/g) || []).length > 3) {
|
|
23
|
+
stationName = stationNetworks;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (station.isFloatingBike) {
|
|
27
|
+
stationName = intl.formatMessage({
|
|
28
|
+
defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingBike"],
|
|
29
|
+
description: "Popup title for a free-floating bike",
|
|
30
|
+
id: "otpUi.VehicleRentalOverlay.floatingBike"
|
|
31
|
+
}, {
|
|
32
|
+
name: stationName
|
|
33
|
+
});
|
|
34
|
+
} else if (station.isFloatingCar) {
|
|
35
|
+
stationName = intl.formatMessage({
|
|
36
|
+
defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingCar"],
|
|
37
|
+
description: "Popup title for a free-floating car",
|
|
38
|
+
id: "otpUi.VehicleRentalOverlay.floatingCar"
|
|
39
|
+
}, {
|
|
40
|
+
company: stationNetworks,
|
|
41
|
+
name: stationName
|
|
42
|
+
});
|
|
43
|
+
} else if (station.isFloatingVehicle) {
|
|
44
|
+
// assumes that all floating vehicles are E-scooters
|
|
45
|
+
stationName = intl.formatMessage({
|
|
46
|
+
defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingEScooter"],
|
|
47
|
+
description: "Popup title for a free-floating e-scooter",
|
|
48
|
+
id: "otpUi.VehicleRentalOverlay.floatingEScooter"
|
|
49
|
+
}, {
|
|
50
|
+
company: stationNetworks
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return stationName;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Render some popup html for a station. This contains custom logic for
|
|
60
|
+
* displaying rental vehicles in the TriMet MOD website that might not be
|
|
61
|
+
* applicable to other regions.
|
|
62
|
+
*/
|
|
63
|
+
var StationPopup = function StationPopup(props) {
|
|
64
|
+
var intl = useIntl();
|
|
65
|
+
var configCompanies = props.configCompanies,
|
|
66
|
+
getStationName = props.getStationName,
|
|
67
|
+
setLocation = props.setLocation,
|
|
68
|
+
station = props.station;
|
|
69
|
+
var stationIsHub = station.bikesAvailable !== undefined && !station.isFloatingBike;
|
|
70
|
+
var getStationNameFunc = getStationName || makeDefaultGetStationName(intl);
|
|
71
|
+
var stationName = getStationNameFunc(configCompanies, station);
|
|
72
|
+
var location = {
|
|
73
|
+
lat: station.y,
|
|
74
|
+
lon: station.x,
|
|
75
|
+
name: stationName
|
|
76
|
+
};
|
|
77
|
+
return /*#__PURE__*/React.createElement(BaseMapStyled.MapOverlayPopup, null, /*#__PURE__*/React.createElement(BaseMapStyled.PopupTitle, null, stationName), stationIsHub && /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
78
|
+
defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableBikes"],
|
|
79
|
+
description: "Label text for the number of bikes available",
|
|
80
|
+
id: "otpUi.VehicleRentalOverlay.availableBikes",
|
|
81
|
+
values: {
|
|
82
|
+
value: station.bikesAvailable
|
|
83
|
+
}
|
|
84
|
+
})), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
85
|
+
defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableDocks"],
|
|
86
|
+
description: "Label text for the number of docks available",
|
|
87
|
+
id: "otpUi.VehicleRentalOverlay.availableDocks",
|
|
88
|
+
values: {
|
|
89
|
+
value: station.spacesAvailable
|
|
90
|
+
}
|
|
91
|
+
}))), /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement(FromToLocationPicker, {
|
|
92
|
+
label: true,
|
|
93
|
+
location: location,
|
|
94
|
+
setLocation: setLocation
|
|
95
|
+
})));
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export default StationPopup;
|
|
99
|
+
//# sourceMappingURL=StationPopup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/StationPopup.tsx"],"names":["Styled","BaseMapStyled","React","FromToLocationPicker","coreUtils","useIntl","FormattedMessage","flatten","defaultEnglishMessages","defaultMessages","makeDefaultGetStationName","intl","defaultGetStationName","configCompanies","station","stationNetworks","itinerary","getCompaniesLabelFromNetworks","networks","stationName","name","id","match","length","isFloatingBike","formatMessage","defaultMessage","description","isFloatingCar","company","isFloatingVehicle","StationPopup","props","getStationName","setLocation","stationIsHub","bikesAvailable","undefined","getStationNameFunc","location","lat","y","lon","x","value","spacesAvailable"],"mappings":"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","sourcesContent":["import {\n Company,\n ConfiguredCompany,\n MapLocationActionArg,\n Station\n} from \"@opentripplanner/types\";\nimport { Styled as BaseMapStyled } from \"@opentripplanner/base-map\";\nimport React from \"react\";\nimport FromToLocationPicker from \"@opentripplanner/from-to-location-picker\";\nimport coreUtils from \"@opentripplanner/core-utils\";\nimport { IntlShape, useIntl, FormattedMessage } from \"react-intl\";\nimport flatten from \"flat\";\n\n// Load the default messages.\n// @ts-expect-error why is this failing?\nimport defaultEnglishMessages from \"../i18n/en-US.yml\";\n\n// HACK: We should flatten the messages loaded above because\n// the YAML loaders behave differently between webpack and our version of jest:\n// - the yaml loader for webpack returns a nested object,\n// - the yaml loader for jest returns messages with flattened ids.\nconst defaultMessages = flatten(defaultEnglishMessages);\n\nfunction makeDefaultGetStationName(intl: IntlShape) {\n return function defaultGetStationName(\n configCompanies: Company[],\n station: Station\n ) {\n const stationNetworks = coreUtils.itinerary.getCompaniesLabelFromNetworks(\n station?.networks || [],\n configCompanies\n );\n let stationName = station.name || station.id;\n // If the station name or id is a giant UUID (with more than 3 \"-\" characters)\n // best not to show that at all and instead use the network name.\n if ((stationName.match(/-/g) || []).length > 3) {\n stationName = stationNetworks;\n }\n\n if (station.isFloatingBike) {\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\"otpUi.VehicleRentalOverlay.floatingBike\"],\n description: \"Popup title for a free-floating bike\",\n id: \"otpUi.VehicleRentalOverlay.floatingBike\"\n },\n { name: stationName }\n );\n } else if (station.isFloatingCar) {\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\"otpUi.VehicleRentalOverlay.floatingCar\"],\n description: \"Popup title for a free-floating car\",\n id: \"otpUi.VehicleRentalOverlay.floatingCar\"\n },\n {\n company: stationNetworks,\n name: stationName\n }\n );\n } else if (station.isFloatingVehicle) {\n // assumes that all floating vehicles are E-scooters\n stationName = intl.formatMessage(\n {\n defaultMessage:\n defaultEnglishMessages[\n \"otpUi.VehicleRentalOverlay.floatingEScooter\"\n ],\n description: \"Popup title for a free-floating e-scooter\",\n id: \"otpUi.VehicleRentalOverlay.floatingEScooter\"\n },\n { company: stationNetworks }\n );\n }\n return stationName;\n };\n}\n\ntype Props = {\n station: Station;\n configCompanies: ConfiguredCompany[];\n getStationName: (configCompanies: Company[], station: Station) => string;\n setLocation: (arg: MapLocationActionArg) => void;\n};\n/**\n * Render some popup html for a station. This contains custom logic for\n * displaying rental vehicles in the TriMet MOD website that might not be\n * applicable to other regions.\n */\nconst StationPopup = (props: Props): JSX.Element => {\n const intl = useIntl();\n const { configCompanies, getStationName, setLocation, station } = props;\n const stationIsHub =\n station.bikesAvailable !== undefined && !station.isFloatingBike;\n const getStationNameFunc = getStationName || makeDefaultGetStationName(intl);\n const stationName = getStationNameFunc(configCompanies, station);\n const location = {\n lat: station.y,\n lon: station.x,\n name: stationName\n };\n return (\n <BaseMapStyled.MapOverlayPopup>\n <BaseMapStyled.PopupTitle>{stationName}</BaseMapStyled.PopupTitle>\n\n {/* render dock info if it is available */}\n {stationIsHub && (\n <BaseMapStyled.PopupRow>\n <div>\n <FormattedMessage\n defaultMessage={\n defaultMessages[\"otpUi.VehicleRentalOverlay.availableBikes\"]\n }\n description=\"Label text for the number of bikes available\"\n id=\"otpUi.VehicleRentalOverlay.availableBikes\"\n values={{ value: station.bikesAvailable }}\n />\n </div>\n <div>\n <FormattedMessage\n defaultMessage={\n defaultMessages[\"otpUi.VehicleRentalOverlay.availableDocks\"]\n }\n description=\"Label text for the number of docks available\"\n id=\"otpUi.VehicleRentalOverlay.availableDocks\"\n values={{ value: station.spacesAvailable }}\n />\n </div>\n </BaseMapStyled.PopupRow>\n )}\n\n {/* Set as from/to toolbar */}\n <BaseMapStyled.PopupRow>\n <FromToLocationPicker\n label\n location={location}\n setLocation={setLocation}\n />\n </BaseMapStyled.PopupRow>\n </BaseMapStyled.MapOverlayPopup>\n );\n};\n\nexport default StationPopup;\n"],"file":"StationPopup.js"}
|
package/esm/index.js
CHANGED
|
@@ -1,378 +1,168 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import _inherits from "@babel/runtime/helpers/inherits";
|
|
4
|
-
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
|
|
5
|
-
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
|
|
1
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
6
3
|
|
|
7
|
-
function
|
|
4
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
8
5
|
|
|
9
|
-
function
|
|
6
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
10
7
|
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import PropTypes from "prop-types";
|
|
17
|
-
import React from "react";
|
|
18
|
-
import { FormattedMessage, injectIntl } from "react-intl";
|
|
19
|
-
import { FeatureGroup, MapLayer, Popup, withLeaflet } from "react-leaflet";
|
|
20
|
-
import { GenericMarker, HubAndFloatingBike, SharedBikeCircle } from "./DefaultMarkers"; // Load the default messages.
|
|
8
|
+
import { Source, Layer, useMap, Popup } from "react-map-gl";
|
|
9
|
+
import React, { useEffect, useState } from "react";
|
|
10
|
+
import { MarkerWithPopup } from "@opentripplanner/base-map";
|
|
11
|
+
import StationPopup from "./StationPopup";
|
|
12
|
+
import { BaseBikeRentalIcon, StationMarker } from "./styled"; // TODO: Make configurable?
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
// the YAML loaders behave differently between webpack and our version of jest:
|
|
24
|
-
// - the yaml loader for webpack returns a nested object,
|
|
25
|
-
// - the yaml loader for jest returns messages with flattened ids.
|
|
14
|
+
var DETAILED_MARKER_CUTOFF = 16;
|
|
26
15
|
|
|
27
|
-
var
|
|
16
|
+
var getColorForStation = function getColorForStation(v) {
|
|
17
|
+
if (v.isFloatingCar) return "#009cde";
|
|
18
|
+
if (v.isFloatingVehicle) return "#f5a729"; // TODO: nicer color to match transitive
|
|
28
19
|
|
|
29
|
-
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
var stationName = station.name || station.id; // If the station name or id is a giant UUID (with more than 3 "-" characters)
|
|
33
|
-
// best not to show that at all and instead use the network name.
|
|
20
|
+
if (v.bikesAvailable !== undefined || v.isFloatingBike) return "#f00";
|
|
21
|
+
return "gray";
|
|
22
|
+
};
|
|
34
23
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
24
|
+
var checkIfPositionInViewport = function checkIfPositionInViewport(bounds, lat, lng) {
|
|
25
|
+
var PADDING = 0.001; // @ts-expect-error types appear to be wrong? version issue?
|
|
26
|
+
// eslint-disable-next-line no-underscore-dangle
|
|
38
27
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
name: stationName
|
|
46
|
-
});
|
|
47
|
-
} else if (station.isFloatingCar) {
|
|
48
|
-
stationName = intl.formatMessage({
|
|
49
|
-
defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingCar"],
|
|
50
|
-
description: "Popup title for a free-floating car",
|
|
51
|
-
id: "otpUi.VehicleRentalOverlay.floatingCar"
|
|
52
|
-
}, {
|
|
53
|
-
company: stationNetworks,
|
|
54
|
-
name: stationName
|
|
55
|
-
});
|
|
56
|
-
} else if (station.isFloatingVehicle) {
|
|
57
|
-
// assumes that all floating vehicles are E-scooters
|
|
58
|
-
stationName = intl.formatMessage({
|
|
59
|
-
defaultMessage: defaultEnglishMessages["otpUi.VehicleRentalOverlay.floatingEScooter"],
|
|
60
|
-
description: "Popup title for a free-floating e-scooter",
|
|
61
|
-
id: "otpUi.VehicleRentalOverlay.floatingEScooter"
|
|
62
|
-
}, {
|
|
63
|
-
company: stationNetworks
|
|
64
|
-
});
|
|
65
|
-
}
|
|
28
|
+
var _ref = [bounds._sw, bounds._ne],
|
|
29
|
+
sw = _ref[0],
|
|
30
|
+
ne = _ref[1];
|
|
31
|
+
if (!sw || !ne) return false;
|
|
32
|
+
return lat >= sw.lat - PADDING && lat <= ne.lat + PADDING && lng >= sw.lng - PADDING && lng <= ne.lng + PADDING;
|
|
33
|
+
};
|
|
66
34
|
|
|
67
|
-
return stationName;
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
35
|
/**
|
|
71
36
|
* This vehicle rental overlay can be used to render vehicle rentals of various
|
|
72
37
|
* types. This layer can be configured to show different styles of markers at
|
|
73
38
|
* different zoom levels.
|
|
74
39
|
*/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
var
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
// entity: coreUtils.types.stationType.isRequired,
|
|
101
|
-
zoom: PropTypes.number.isRequired
|
|
102
|
-
};
|
|
103
|
-
return SymbolWrapper;
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
_this.convertToZoomMarkerSymbols = function (mapSymbols) {
|
|
107
|
-
return mapSymbols.map(function (mapSymbol) {
|
|
108
|
-
// If mapSymbol uses zoomBasedSymbolType, use it as is.
|
|
109
|
-
if (mapSymbol.symbol) {
|
|
110
|
-
return mapSymbol;
|
|
111
|
-
} // Otherwise, convert into zoomBasedType (no support for symbols by type).
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
var symbol;
|
|
115
|
-
|
|
116
|
-
switch (mapSymbol.type) {
|
|
117
|
-
case "circle":
|
|
118
|
-
symbol = SharedBikeCircle(mapSymbol);
|
|
119
|
-
break;
|
|
120
|
-
|
|
121
|
-
case "hubAndFloatingBike":
|
|
122
|
-
symbol = HubAndFloatingBike;
|
|
123
|
-
break;
|
|
124
|
-
|
|
125
|
-
default:
|
|
126
|
-
symbol = GenericMarker(mapSymbol);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
minZoom: mapSymbol.minZoom,
|
|
131
|
-
symbol: symbol
|
|
132
|
-
};
|
|
133
|
-
});
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
_this.onOverlayAdded = function () {
|
|
137
|
-
_this.startRefreshing();
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
_this.onOverlayRemoved = function () {
|
|
141
|
-
_this.stopRefreshing();
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
_this.onViewportChanged = function (viewport) {
|
|
145
|
-
var newZoom = viewport.zoom;
|
|
146
|
-
|
|
147
|
-
if (_this.state.zoom !== newZoom) {
|
|
148
|
-
_this.setState({
|
|
149
|
-
zoom: newZoom
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
_this.renderPopupForStation = function (station) {
|
|
155
|
-
var stationIsHub = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
156
|
-
var _this$props = _this.props,
|
|
157
|
-
configCompanies = _this$props.configCompanies,
|
|
158
|
-
getStationName = _this$props.getStationName,
|
|
159
|
-
intl = _this$props.intl,
|
|
160
|
-
setLocation = _this$props.setLocation;
|
|
161
|
-
var getStationNameFunc = getStationName || makeDefaultGetStationName(intl);
|
|
162
|
-
var stationName = getStationNameFunc(configCompanies, station);
|
|
163
|
-
var location = {
|
|
164
|
-
lat: station.y,
|
|
165
|
-
lon: station.x,
|
|
166
|
-
name: stationName
|
|
167
|
-
};
|
|
168
|
-
return /*#__PURE__*/React.createElement(Popup, null, /*#__PURE__*/React.createElement(BaseMapStyled.MapOverlayPopup, null, /*#__PURE__*/React.createElement(BaseMapStyled.PopupTitle, null, stationName), stationIsHub && /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
169
|
-
defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableBikes"],
|
|
170
|
-
description: "Label text for the number of bikes available",
|
|
171
|
-
id: "otpUi.VehicleRentalOverlay.availableBikes",
|
|
172
|
-
values: {
|
|
173
|
-
value: station.bikesAvailable
|
|
174
|
-
}
|
|
175
|
-
})), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
176
|
-
defaultMessage: defaultMessages["otpUi.VehicleRentalOverlay.availableDocks"],
|
|
177
|
-
description: "Label text for the number of docks available",
|
|
178
|
-
id: "otpUi.VehicleRentalOverlay.availableDocks",
|
|
179
|
-
values: {
|
|
180
|
-
value: station.spacesAvailable
|
|
181
|
-
}
|
|
182
|
-
}))), /*#__PURE__*/React.createElement(BaseMapStyled.PopupRow, null, /*#__PURE__*/React.createElement(FromToLocationPicker, {
|
|
183
|
-
label: true,
|
|
184
|
-
location: location,
|
|
185
|
-
setLocation: setLocation
|
|
186
|
-
}))));
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
_this.state = {
|
|
190
|
-
zoom: null
|
|
191
|
-
};
|
|
192
|
-
return _this;
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* This helper method will be passed to the ZoomBasedMarkers symbolTransform prop.
|
|
196
|
-
* It creates a component that inserts a popup
|
|
197
|
-
* as a child of the specified symbol from the mapSymbols prop.
|
|
198
|
-
*/
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
_createClass(VehicleRentalOverlay, [{
|
|
202
|
-
key: "createLeafletElement",
|
|
203
|
-
value: function createLeafletElement() {}
|
|
204
|
-
}, {
|
|
205
|
-
key: "updateLeafletElement",
|
|
206
|
-
value: function updateLeafletElement() {}
|
|
207
|
-
}, {
|
|
208
|
-
key: "startRefreshing",
|
|
209
|
-
value: function startRefreshing() {
|
|
210
|
-
var refreshVehicles = this.props.refreshVehicles; // Create the timer only if refreshVehicles is a valid function.
|
|
211
|
-
|
|
212
|
-
if (typeof refreshVehicles === "function") {
|
|
213
|
-
// initial station retrieval
|
|
214
|
-
refreshVehicles(); // set up timer to refresh stations periodically
|
|
215
|
-
|
|
216
|
-
this.refreshTimer = setInterval(function () {
|
|
217
|
-
refreshVehicles();
|
|
218
|
-
}, 30000); // defaults to every 30 sec. TODO: make this configurable?
|
|
219
|
-
}
|
|
40
|
+
var VehicleRentalOverlay = function VehicleRentalOverlay(props) {
|
|
41
|
+
var _useMap = useMap(),
|
|
42
|
+
mainMap = _useMap.mainMap;
|
|
43
|
+
|
|
44
|
+
var zoom = mainMap === null || mainMap === void 0 ? void 0 : mainMap.getZoom();
|
|
45
|
+
var bounds = mainMap === null || mainMap === void 0 ? void 0 : mainMap.getBounds();
|
|
46
|
+
var configCompanies = props.configCompanies,
|
|
47
|
+
companies = props.companies,
|
|
48
|
+
getStationName = props.getStationName,
|
|
49
|
+
id = props.id,
|
|
50
|
+
refreshVehicles = props.refreshVehicles,
|
|
51
|
+
_setLocation = props.setLocation,
|
|
52
|
+
stations = props.stations,
|
|
53
|
+
visible = props.visible;
|
|
54
|
+
var layerId = "rental-vehicles-".concat(id);
|
|
55
|
+
|
|
56
|
+
var _useState = useState(null),
|
|
57
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
58
|
+
clickedVehicle = _useState2[0],
|
|
59
|
+
setClickedVehicle = _useState2[1];
|
|
60
|
+
|
|
61
|
+
useEffect(function () {
|
|
62
|
+
// TODO: Make 30s configurable?
|
|
63
|
+
if (!refreshVehicles || typeof refreshVehicles !== "function") {
|
|
64
|
+
return;
|
|
220
65
|
}
|
|
221
|
-
}, {
|
|
222
|
-
key: "stopRefreshing",
|
|
223
|
-
value: function stopRefreshing() {
|
|
224
|
-
if (this.refreshTimer) clearInterval(this.refreshTimer);
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* When the layer is added (or toggled on, or its visibility becomes true),
|
|
228
|
-
* start refreshing vehicle positions.
|
|
229
|
-
*/
|
|
230
66
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
function componentDidMount() {
|
|
240
|
-
var _this$props2 = this.props,
|
|
241
|
-
leaflet = _this$props2.leaflet,
|
|
242
|
-
registerOverlay = _this$props2.registerOverlay,
|
|
243
|
-
visible = _this$props2.visible;
|
|
244
|
-
this.setState({
|
|
245
|
-
zoom: leaflet.map.getZoom()
|
|
67
|
+
refreshVehicles();
|
|
68
|
+
setInterval(refreshVehicles, 30000);
|
|
69
|
+
}, [refreshVehicles]);
|
|
70
|
+
useEffect(function () {
|
|
71
|
+
var VEHICLE_LAYERS = [layerId];
|
|
72
|
+
VEHICLE_LAYERS.forEach(function (stopLayer) {
|
|
73
|
+
mainMap === null || mainMap === void 0 ? void 0 : mainMap.on("mouseenter", stopLayer, function () {
|
|
74
|
+
mainMap.getCanvas().style.cursor = "pointer";
|
|
246
75
|
});
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
}, {
|
|
254
|
-
key: "componentWillUnmount",
|
|
255
|
-
value: function componentWillUnmount() {
|
|
256
|
-
this.stopRefreshing();
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Render some popup html for a station. This contains custom logic for
|
|
260
|
-
* displaying rental vehicles in the TriMet MOD website that might not be
|
|
261
|
-
* applicable to other regions.
|
|
262
|
-
*/
|
|
263
|
-
|
|
264
|
-
}, {
|
|
265
|
-
key: "render",
|
|
266
|
-
value: function render() {
|
|
267
|
-
var _this$props3 = this.props,
|
|
268
|
-
companies = _this$props3.companies,
|
|
269
|
-
leaflet = _this$props3.leaflet,
|
|
270
|
-
mapSymbols = _this$props3.mapSymbols,
|
|
271
|
-
stations = _this$props3.stations;
|
|
272
|
-
var _this$state$zoom = this.state.zoom,
|
|
273
|
-
zoom = _this$state$zoom === void 0 ? leaflet.map.getZoom() : _this$state$zoom; // Render an empty FeatureGroup if the rental vehicles should not be visible
|
|
274
|
-
// on the map. Otherwise previous stations may still be shown due to some
|
|
275
|
-
// react-leaflet internals, maybe? Also, do not return null because that will
|
|
276
|
-
// prevent the overlay from appearing in the layer controls.
|
|
277
|
-
|
|
278
|
-
var filteredStations = stations;
|
|
279
|
-
|
|
280
|
-
if (companies) {
|
|
281
|
-
filteredStations = stations.filter(function (station) {
|
|
282
|
-
return station.networks.filter(function (value) {
|
|
283
|
-
return companies.includes(value);
|
|
284
|
-
}).length > 0;
|
|
285
|
-
});
|
|
286
|
-
}
|
|
76
|
+
mainMap === null || mainMap === void 0 ? void 0 : mainMap.on("mouseleave", stopLayer, function () {
|
|
77
|
+
mainMap.getCanvas().style.cursor = "";
|
|
78
|
+
});
|
|
79
|
+
mainMap === null || mainMap === void 0 ? void 0 : mainMap.on("click", stopLayer, function (event) {
|
|
80
|
+
var _event$features;
|
|
287
81
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
82
|
+
setClickedVehicle((_event$features = event.features) === null || _event$features === void 0 ? void 0 : _event$features[0].properties);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}, [mainMap]); // Don't render if no map or no stops are defined.
|
|
291
86
|
|
|
87
|
+
if (visible === false || !stations || stations.length === 0) {
|
|
88
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
89
|
+
}
|
|
292
90
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
91
|
+
var vehiclesGeoJSON = {
|
|
92
|
+
type: "FeatureCollection",
|
|
93
|
+
features: stations.filter(function (vehicle) {
|
|
94
|
+
return (// Include specified companies only if companies is specified and network info is available
|
|
95
|
+
!companies || !vehicle.networks || companies.includes(vehicle.networks[0])
|
|
96
|
+
);
|
|
97
|
+
}).map(function (vehicle) {
|
|
98
|
+
return {
|
|
99
|
+
type: "Feature",
|
|
100
|
+
properties: _objectSpread(_objectSpread({}, vehicle), {}, {
|
|
101
|
+
networks: JSON.stringify(vehicle.networks),
|
|
102
|
+
"stroke-width": vehicle.isFloatingBike || vehicle.isFloatingVehicle ? 1 : 2,
|
|
103
|
+
color: getColorForStation(vehicle)
|
|
104
|
+
}),
|
|
105
|
+
geometry: {
|
|
106
|
+
type: "Point",
|
|
107
|
+
coordinates: [vehicle.x, vehicle.y]
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
})
|
|
111
|
+
};
|
|
112
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, zoom < DETAILED_MARKER_CUTOFF && /*#__PURE__*/React.createElement(Source, {
|
|
113
|
+
type: "geojson",
|
|
114
|
+
data: vehiclesGeoJSON
|
|
115
|
+
}, /*#__PURE__*/React.createElement(Layer, {
|
|
116
|
+
id: layerId,
|
|
117
|
+
type: "circle",
|
|
118
|
+
paint: {
|
|
119
|
+
"circle-color": ["get", "color"],
|
|
120
|
+
"circle-opacity": 0.9,
|
|
121
|
+
"circle-stroke-width": ["get", "stroke-width"],
|
|
122
|
+
"circle-stroke-color": "#333"
|
|
300
123
|
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
* This will be dispatched with the following argument:
|
|
343
|
-
*
|
|
344
|
-
* ```js
|
|
345
|
-
* {
|
|
346
|
-
* location: {
|
|
347
|
-
* lat: number,
|
|
348
|
-
* lon: number,
|
|
349
|
-
* name: string
|
|
350
|
-
* },
|
|
351
|
-
* locationType: "from" or "to"
|
|
352
|
-
* }
|
|
353
|
-
* ```
|
|
354
|
-
*/
|
|
355
|
-
setLocation: PropTypes.func.isRequired,
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* A list of the vehicle rental stations specific to this overlay instance.
|
|
359
|
-
*/
|
|
360
|
-
// stations: PropTypes.arrayOf(coreUtils.types.stationType),
|
|
361
|
-
|
|
362
|
-
/**
|
|
363
|
-
* Whether the overlay is currently visible.
|
|
364
|
-
*/
|
|
365
|
-
visible: PropTypes.bool
|
|
124
|
+
})), zoom >= DETAILED_MARKER_CUTOFF && stations.filter(function (station) {
|
|
125
|
+
return checkIfPositionInViewport(bounds, station.y, station.x);
|
|
126
|
+
}).map(function (station) {
|
|
127
|
+
return /*#__PURE__*/React.createElement(MarkerWithPopup, {
|
|
128
|
+
key: station.id,
|
|
129
|
+
position: [station.y, station.x],
|
|
130
|
+
popupContents: /*#__PURE__*/React.createElement(StationPopup, {
|
|
131
|
+
configCompanies: configCompanies,
|
|
132
|
+
setLocation: function setLocation(location) {
|
|
133
|
+
setClickedVehicle(null);
|
|
134
|
+
|
|
135
|
+
_setLocation(location);
|
|
136
|
+
},
|
|
137
|
+
getStationName: getStationName,
|
|
138
|
+
station: station
|
|
139
|
+
})
|
|
140
|
+
}, station.bikesAvailable !== undefined && !station.isFloatingBike && !station.isFloatingVehicle && station.spacesAvailable !== undefined ? /*#__PURE__*/React.createElement(BaseBikeRentalIcon, {
|
|
141
|
+
percent: (station === null || station === void 0 ? void 0 : station.bikesAvailable) / ((station === null || station === void 0 ? void 0 : station.bikesAvailable) + (station === null || station === void 0 ? void 0 : station.spacesAvailable))
|
|
142
|
+
}) : /*#__PURE__*/React.createElement(StationMarker, {
|
|
143
|
+
width: 12,
|
|
144
|
+
color: getColorForStation(station)
|
|
145
|
+
}));
|
|
146
|
+
}), clickedVehicle && /*#__PURE__*/React.createElement(Popup, {
|
|
147
|
+
onClose: function onClose() {
|
|
148
|
+
setClickedVehicle(null);
|
|
149
|
+
},
|
|
150
|
+
longitude: clickedVehicle.x,
|
|
151
|
+
latitude: clickedVehicle.y,
|
|
152
|
+
maxWidth: "100%"
|
|
153
|
+
}, /*#__PURE__*/React.createElement(StationPopup, {
|
|
154
|
+
configCompanies: configCompanies,
|
|
155
|
+
setLocation: function setLocation(location) {
|
|
156
|
+
setClickedVehicle(null);
|
|
157
|
+
|
|
158
|
+
_setLocation(location);
|
|
159
|
+
},
|
|
160
|
+
getStationName: getStationName,
|
|
161
|
+
station: _objectSpread(_objectSpread({}, clickedVehicle), {}, {
|
|
162
|
+
networks: JSON.parse(clickedVehicle.networks)
|
|
163
|
+
})
|
|
164
|
+
})));
|
|
366
165
|
};
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
mapSymbols: [{
|
|
370
|
-
zoom: 0,
|
|
371
|
-
symbol: GenericMarker
|
|
372
|
-
}],
|
|
373
|
-
refreshVehicles: null,
|
|
374
|
-
stations: [],
|
|
375
|
-
visible: false
|
|
376
|
-
};
|
|
377
|
-
export default withLeaflet(injectIntl(VehicleRentalOverlay));
|
|
166
|
+
|
|
167
|
+
export default VehicleRentalOverlay;
|
|
378
168
|
//# sourceMappingURL=index.js.map
|