@geops/rvf-mobility-web-component 0.1.22 → 0.1.24-beta.0
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 +7 -0
- package/index.html +1 -0
- package/index.js +196 -140
- package/package.json +1 -1
- package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +6 -6
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/RvfSharedMobilityDetails.tsx +11 -87
- package/src/RvfFeatureDetails/RvfSharedMobilityDetail/StationDetails/StationDetails.tsx +3 -159
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +21 -5
- package/src/RvfSharedMobilityLayerGroup2/RvfSharedMobilityLayerGroup2.tsx +740 -0
- package/src/RvfSharedMobilityLayerGroup2/index.tsx +1 -0
- package/src/RvfSingleClickListener/RvfSingleClickListener.tsx +76 -19
- package/src/index.tsx +2 -1
- package/src/utils/constants.ts +65 -1
- package/src/utils/createFreeFloatMobilityLayer.ts +5 -2
- package/src/utils/createMobiDataBwWfsLayer.ts +6 -3
- package/src/utils/sharingGraphqlUtils.ts +313 -0
- package/src/utils/sharingStylesUtils.ts +222 -0
- package/src/utils/sharingWFSUtils.ts +74 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./RvfSharedMobilityLayerGroup2";
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
import { GeoJSONSource } from "maplibre-gl";
|
|
1
2
|
import { Feature, MapBrowserEvent } from "ol";
|
|
2
3
|
import { GeoJSON } from "ol/format";
|
|
3
4
|
import { unByKey } from "ol/Observable";
|
|
4
5
|
import { toLonLat } from "ol/proj";
|
|
5
6
|
import { useCallback, useEffect } from "preact/hooks";
|
|
6
7
|
|
|
8
|
+
import { PROVIDER_LOGOS_BY_FEED_ID } from "../utils/constants";
|
|
7
9
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
8
10
|
import useRvfContext from "../utils/hooks/useRvfContext";
|
|
9
11
|
import MobilityEvent from "../utils/MobilityEvent";
|
|
12
|
+
import { fetchSharingStation } from "../utils/sharingGraphqlUtils";
|
|
10
13
|
|
|
11
14
|
const geojson = new GeoJSON();
|
|
12
15
|
|
|
13
16
|
function SingleClickListener() {
|
|
14
17
|
const {
|
|
18
|
+
baseLayer,
|
|
15
19
|
map,
|
|
16
20
|
realtimeLayer,
|
|
17
21
|
setStationId,
|
|
@@ -21,7 +25,23 @@ function SingleClickListener() {
|
|
|
21
25
|
tenant,
|
|
22
26
|
trainId,
|
|
23
27
|
} = useMapContext();
|
|
24
|
-
const { setSelectedFeature, setSelectedFeatures } =
|
|
28
|
+
const { selectedFeature, setSelectedFeature, setSelectedFeatures } =
|
|
29
|
+
useRvfContext();
|
|
30
|
+
|
|
31
|
+
// Send the selctedFEature to the parent window
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
if (!map) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
map.getTargetElement().dispatchEvent(
|
|
38
|
+
new MobilityEvent("selectedfeature", {
|
|
39
|
+
feature: selectedFeature
|
|
40
|
+
? geojson.writeFeatureObject(selectedFeature)
|
|
41
|
+
: null,
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
}, [map, selectedFeature]);
|
|
25
45
|
|
|
26
46
|
const onPointerMove = useCallback(
|
|
27
47
|
async (evt: MapBrowserEvent<PointerEvent>) => {
|
|
@@ -59,6 +79,9 @@ function SingleClickListener() {
|
|
|
59
79
|
|
|
60
80
|
const onSingleClick = useCallback(
|
|
61
81
|
async (evt: MapBrowserEvent<PointerEvent>) => {
|
|
82
|
+
if (!baseLayer.mapLibreMap) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
62
85
|
const [realtimeFeature] = evt.map.getFeaturesAtPixel(evt.pixel, {
|
|
63
86
|
layerFilter: (l) => {
|
|
64
87
|
return l === realtimeLayer;
|
|
@@ -95,26 +118,59 @@ function SingleClickListener() {
|
|
|
95
118
|
return l.get("isQueryable");
|
|
96
119
|
},
|
|
97
120
|
}) as Feature[];
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
121
|
+
|
|
122
|
+
// Append more infos about the features
|
|
123
|
+
const addMoreData = async (features) => {
|
|
124
|
+
for (const feature of features) {
|
|
125
|
+
const clusterId = feature.get("cluster_id");
|
|
126
|
+
if (clusterId) {
|
|
127
|
+
const vtFeat = feature.get("vectorTileFeature");
|
|
128
|
+
const sourceId = vtFeat.layer.source;
|
|
129
|
+
const leaves =
|
|
130
|
+
(await (
|
|
131
|
+
baseLayer.mapLibreMap.getSource(sourceId) as GeoJSONSource
|
|
132
|
+
)?.getClusterLeaves(clusterId, 1000, 0)) || [];
|
|
133
|
+
|
|
134
|
+
feature.set(
|
|
135
|
+
"features",
|
|
136
|
+
leaves.map((l) => {
|
|
137
|
+
return geojson.readFeature(l);
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Sharing station
|
|
143
|
+
const sharingStationId = selectedFeature?.get("station_id");
|
|
144
|
+
if (sharingStationId) {
|
|
145
|
+
const sharingStationInfo =
|
|
146
|
+
await fetchSharingStation(sharingStationId);
|
|
147
|
+
selectedFeature.setProperties(sharingStationInfo);
|
|
148
|
+
selectedFeature.set(
|
|
149
|
+
"provider_logo",
|
|
150
|
+
PROVIDER_LOGOS_BY_FEED_ID[selectedFeature?.get("feed_id")],
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
evt.map.getTargetElement().dispatchEvent(
|
|
155
|
+
new MobilityEvent("singleclick", {
|
|
156
|
+
...evt,
|
|
157
|
+
features: geojson.writeFeaturesObject(features),
|
|
158
|
+
lonlat: toLonLat(evt.coordinate),
|
|
159
|
+
}),
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
if (newStationId || newTrainId || !features.length) {
|
|
163
|
+
setSelectedFeature(null);
|
|
164
|
+
setSelectedFeatures([]);
|
|
165
|
+
} else {
|
|
166
|
+
setSelectedFeatures(features);
|
|
167
|
+
setSelectedFeature(features[0]);
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
addMoreData(features);
|
|
116
171
|
},
|
|
117
172
|
[
|
|
173
|
+
baseLayer?.mapLibreMap,
|
|
118
174
|
stationId,
|
|
119
175
|
trainId,
|
|
120
176
|
realtimeLayer,
|
|
@@ -122,6 +178,7 @@ function SingleClickListener() {
|
|
|
122
178
|
tenant,
|
|
123
179
|
setStationId,
|
|
124
180
|
setTrainId,
|
|
181
|
+
selectedFeature,
|
|
125
182
|
setSelectedFeature,
|
|
126
183
|
setSelectedFeatures,
|
|
127
184
|
],
|
package/src/index.tsx
CHANGED
|
@@ -13,6 +13,7 @@ register(
|
|
|
13
13
|
"extent",
|
|
14
14
|
"maxextent",
|
|
15
15
|
"geolocation",
|
|
16
|
+
"details",
|
|
16
17
|
"layers",
|
|
17
18
|
"layertree",
|
|
18
19
|
"mapsurl",
|
|
@@ -23,7 +24,7 @@ register(
|
|
|
23
24
|
"notificationbeforelayerid",
|
|
24
25
|
"print",
|
|
25
26
|
"realtime",
|
|
26
|
-
"
|
|
27
|
+
"realtimeurl",
|
|
27
28
|
"search",
|
|
28
29
|
"share",
|
|
29
30
|
"tenant",
|
package/src/utils/constants.ts
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import { transformExtent } from "ol/proj";
|
|
1
|
+
import { fromLonLat, toLonLat, transformExtent } from "ol/proj";
|
|
2
|
+
|
|
3
|
+
import callBike from "../logos/callabike_logo.png";
|
|
4
|
+
import flinkster from "../logos/flinkster_logo.png";
|
|
5
|
+
import grueneFlotteLogo from "../logos/gruene_flotte_logo.png";
|
|
6
|
+
import lastenVeloLogo from "../logos/lasten_velo_freiburg.png";
|
|
7
|
+
import freloLogo from "../logos/logo_frelo_web_rgb.png";
|
|
8
|
+
import naturEnergieLogo from "../logos/natur_energie_logo.png";
|
|
9
|
+
import yoioLogo from "../logos/yoio_logo.png";
|
|
10
|
+
import zeusLogo from "../logos/zeus_logo.png";
|
|
2
11
|
|
|
3
12
|
export const RVF_EXTENT_4326 = [7.5, 47.7, 8.45, 48.4];
|
|
4
13
|
|
|
@@ -7,7 +16,12 @@ export const RVF_EXTENT_3857 = transformExtent(
|
|
|
7
16
|
"EPSG:4326",
|
|
8
17
|
"EPSG:3857",
|
|
9
18
|
);
|
|
19
|
+
console.log(fromLonLat([7.844388, 47.991351]));
|
|
10
20
|
|
|
21
|
+
// @ts-expect-error - testsdsd sd
|
|
22
|
+
window.fromLonLat = fromLonLat;
|
|
23
|
+
// @ts-expect-error - testsdsd sd
|
|
24
|
+
window.toLonLat = toLonLat;
|
|
11
25
|
export const LAYER_PROP_IS_EXPORTING = "isExporting";
|
|
12
26
|
|
|
13
27
|
export const RVF_LAYERS_TITLES = {
|
|
@@ -27,7 +41,14 @@ export const RVF_LAYERS_TITLES = {
|
|
|
27
41
|
|
|
28
42
|
export const RVF_LAYERS_NAMES = {
|
|
29
43
|
auto: "auto",
|
|
44
|
+
bikeFrelo: "frelo",
|
|
45
|
+
bikeOthers: "bikeothers",
|
|
30
46
|
cargobike: "cargobike",
|
|
47
|
+
cargobikeFrelo: "cargobikefrelo",
|
|
48
|
+
cargobikeOthers: "cargobikeothers",
|
|
49
|
+
carGrf: "grueneflotte",
|
|
50
|
+
carNatur: "naturenergie",
|
|
51
|
+
carOthers: "carothers",
|
|
31
52
|
echtzeit: "echtzeit",
|
|
32
53
|
eroller: "e-roller",
|
|
33
54
|
fahrrad: "fahrrad",
|
|
@@ -91,3 +112,46 @@ export const PROVIDER_BY_FEED_ID = {
|
|
|
91
112
|
// "carvelo",
|
|
92
113
|
// "CarSharing"
|
|
93
114
|
};
|
|
115
|
+
|
|
116
|
+
export const BIKE_FORM_FACTOR = "bicycle";
|
|
117
|
+
export const CAR_FORM_FACTOR = "car";
|
|
118
|
+
export const CARGOBIKE_FORM_FACTOR = "cargo_bicycle";
|
|
119
|
+
export const SCOOTER_FORM_FACTOR = "scooter";
|
|
120
|
+
|
|
121
|
+
// Station system ids
|
|
122
|
+
// "pickebike_basel",
|
|
123
|
+
// "dott_basel",
|
|
124
|
+
// "gruene-flotte_freiburg",
|
|
125
|
+
// "voi_ch",
|
|
126
|
+
// "nextbike_df",
|
|
127
|
+
// "carvelo2go_ch",
|
|
128
|
+
// "naturenergie_sharing",
|
|
129
|
+
// "lastenvelo_fr",
|
|
130
|
+
// "donkey_neuchatel",
|
|
131
|
+
// "flinkster_carsharing"
|
|
132
|
+
export const GRUNFLOTTE_FEED_ID = "gruene-flotte_freiburg";
|
|
133
|
+
export const NATURENERGIE_FEED_ID = "naturenergie_sharing";
|
|
134
|
+
export const CAR_OTHERS_FEED_IDS = ["flinkster_carsharing"];
|
|
135
|
+
|
|
136
|
+
export const FRELO_FEED_ID = "nextbike_df";
|
|
137
|
+
export const BIKE_OTHERS_FEED_IDS = [
|
|
138
|
+
"callabike_ice", // don't exist in graphql
|
|
139
|
+
"pickebike_basel",
|
|
140
|
+
"donkey_neuchatel",
|
|
141
|
+
];
|
|
142
|
+
|
|
143
|
+
export const CARGOBIKE_FRELO_ID = "nextbike_df";
|
|
144
|
+
export const CARGOBIKE_OTHERS_FEED_IDS = ["lastenvelo_fr", "carvelo2go_ch"];
|
|
145
|
+
|
|
146
|
+
export const SCOOTER_OTHERS_FEED_IDS = ["voi_ch"];
|
|
147
|
+
|
|
148
|
+
export const PROVIDER_LOGOS_BY_FEED_ID = {
|
|
149
|
+
callabike_ice: callBike,
|
|
150
|
+
flinkster_carsharing: flinkster,
|
|
151
|
+
"gruene-flotte_freiburg": grueneFlotteLogo,
|
|
152
|
+
lastenvelo_fr: lastenVeloLogo,
|
|
153
|
+
naturenergie_sharing: naturEnergieLogo,
|
|
154
|
+
nextbike_df: freloLogo,
|
|
155
|
+
yoio_freiburg: yoioLogo,
|
|
156
|
+
zeus_freiburg: zeusLogo,
|
|
157
|
+
};
|
|
@@ -57,7 +57,7 @@ function createFreeFloatMobilityLayer(
|
|
|
57
57
|
"MobiData-BW:" +
|
|
58
58
|
name +
|
|
59
59
|
"&" +
|
|
60
|
-
"outputFormat=application/json
|
|
60
|
+
"outputFormat=application/json" +
|
|
61
61
|
"bbox=" +
|
|
62
62
|
extent.join(",") +
|
|
63
63
|
",EPSG:3857";
|
|
@@ -72,7 +72,10 @@ function createFreeFloatMobilityLayer(
|
|
|
72
72
|
if (xhr.status == 200) {
|
|
73
73
|
const features = source
|
|
74
74
|
.getFormat()
|
|
75
|
-
.readFeatures(xhr.responseText
|
|
75
|
+
.readFeatures(xhr.responseText, {
|
|
76
|
+
dataProjection: "EPSG:4326",
|
|
77
|
+
featureProjection: "EPSG:3857",
|
|
78
|
+
})
|
|
76
79
|
?.filter((feature) => {
|
|
77
80
|
if (formFactor) {
|
|
78
81
|
return feature.get("form_factor") === formFactor;
|
|
@@ -78,11 +78,14 @@ function createMobiDataBwWfsLayer(
|
|
|
78
78
|
name: string,
|
|
79
79
|
color: string,
|
|
80
80
|
layerOptions: Options = {
|
|
81
|
-
minZoom:
|
|
81
|
+
minZoom: 0,
|
|
82
82
|
},
|
|
83
83
|
): VectorLayer<Vector<Feature<Point>>> {
|
|
84
84
|
const source = new Vector({
|
|
85
|
-
format: new GeoJSON(
|
|
85
|
+
format: new GeoJSON({
|
|
86
|
+
dataProjection: "EPSG:4326",
|
|
87
|
+
featureProjection: "EPSG:3857",
|
|
88
|
+
}),
|
|
86
89
|
strategy: bboxStrategy,
|
|
87
90
|
url: function (extent) {
|
|
88
91
|
return (
|
|
@@ -94,7 +97,7 @@ function createMobiDataBwWfsLayer(
|
|
|
94
97
|
"MobiData-BW:" +
|
|
95
98
|
name +
|
|
96
99
|
"&" +
|
|
97
|
-
"outputFormat=application/json&
|
|
100
|
+
"outputFormat=application/json&" +
|
|
98
101
|
"bbox=" +
|
|
99
102
|
extent.join(",") +
|
|
100
103
|
",EPSG:3857"
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { FeatureCollection, Point } from "geojson";
|
|
2
|
+
import { gql, GraphQLClient } from "graphql-request";
|
|
3
|
+
import { Extent } from "ol/extent";
|
|
4
|
+
|
|
5
|
+
import { RVF_EXTENT_4326 } from "./constants";
|
|
6
|
+
|
|
7
|
+
const GQL_URL = "https://api.mobidata-bw.de/sharing/graphql";
|
|
8
|
+
|
|
9
|
+
export interface SharingStation {
|
|
10
|
+
id: string;
|
|
11
|
+
lat: number;
|
|
12
|
+
lon: number;
|
|
13
|
+
name: {
|
|
14
|
+
translation: {
|
|
15
|
+
language: string;
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
numVehiclesAvailable: number;
|
|
20
|
+
system: {
|
|
21
|
+
id: string;
|
|
22
|
+
name: {
|
|
23
|
+
translation: {
|
|
24
|
+
language: string;
|
|
25
|
+
value: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
operator: {
|
|
29
|
+
id: string;
|
|
30
|
+
name: {
|
|
31
|
+
translation: {
|
|
32
|
+
language: string;
|
|
33
|
+
value: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
shortName: {
|
|
38
|
+
translation: {
|
|
39
|
+
language: string;
|
|
40
|
+
value: string;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const queryStation = gql`
|
|
47
|
+
query station($id: String!) {
|
|
48
|
+
station(id: $id) {
|
|
49
|
+
name {
|
|
50
|
+
translation {
|
|
51
|
+
language
|
|
52
|
+
value
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
shortName {
|
|
56
|
+
translation {
|
|
57
|
+
language
|
|
58
|
+
value
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
lat
|
|
62
|
+
lon
|
|
63
|
+
region {
|
|
64
|
+
id
|
|
65
|
+
}
|
|
66
|
+
rentalUris {
|
|
67
|
+
android
|
|
68
|
+
ios
|
|
69
|
+
web
|
|
70
|
+
}
|
|
71
|
+
isVirtualStation
|
|
72
|
+
rentalMethods
|
|
73
|
+
parkingHoop
|
|
74
|
+
parkingType
|
|
75
|
+
contactPhone
|
|
76
|
+
address
|
|
77
|
+
rentalMethods
|
|
78
|
+
capacity
|
|
79
|
+
vehicleTypesAvailable {
|
|
80
|
+
count
|
|
81
|
+
vehicleType {
|
|
82
|
+
id
|
|
83
|
+
formFactor
|
|
84
|
+
riderCapacity
|
|
85
|
+
cargoVolumeCapacity
|
|
86
|
+
cargoLoadCapacity
|
|
87
|
+
propulsionType
|
|
88
|
+
ecoLabels {
|
|
89
|
+
countryCode
|
|
90
|
+
ecoSticker
|
|
91
|
+
}
|
|
92
|
+
maxRangeMeters
|
|
93
|
+
name {
|
|
94
|
+
translation {
|
|
95
|
+
language
|
|
96
|
+
value
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
description {
|
|
100
|
+
translation {
|
|
101
|
+
language
|
|
102
|
+
value
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
vehicleAccessories
|
|
106
|
+
gCO2km
|
|
107
|
+
vehicleImage
|
|
108
|
+
make
|
|
109
|
+
model
|
|
110
|
+
color
|
|
111
|
+
wheelCount
|
|
112
|
+
maxPermittedSpeed
|
|
113
|
+
ratedPower
|
|
114
|
+
defaultReserveTime
|
|
115
|
+
returnConstraint
|
|
116
|
+
vehicleAssets {
|
|
117
|
+
iconUrl
|
|
118
|
+
iconUrlDark
|
|
119
|
+
iconLastModified
|
|
120
|
+
}
|
|
121
|
+
defaultReserveTime
|
|
122
|
+
defaultPricingPlan {
|
|
123
|
+
id
|
|
124
|
+
url
|
|
125
|
+
currency
|
|
126
|
+
isTaxable
|
|
127
|
+
description {
|
|
128
|
+
translation {
|
|
129
|
+
language
|
|
130
|
+
value
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
perKmPricing {
|
|
134
|
+
start
|
|
135
|
+
rate
|
|
136
|
+
interval
|
|
137
|
+
end
|
|
138
|
+
}
|
|
139
|
+
perMinPricing {
|
|
140
|
+
start
|
|
141
|
+
rate
|
|
142
|
+
interval
|
|
143
|
+
end
|
|
144
|
+
}
|
|
145
|
+
surgePricing
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
count
|
|
149
|
+
}
|
|
150
|
+
vehicleDocksCapacity {
|
|
151
|
+
vehicleTypes {
|
|
152
|
+
id
|
|
153
|
+
}
|
|
154
|
+
count
|
|
155
|
+
}
|
|
156
|
+
numVehiclesAvailable
|
|
157
|
+
numDocksDisabled
|
|
158
|
+
numVehiclesDisabled
|
|
159
|
+
numDocksAvailable
|
|
160
|
+
isInstalled
|
|
161
|
+
isRenting
|
|
162
|
+
isReturning
|
|
163
|
+
pricingPlans {
|
|
164
|
+
id
|
|
165
|
+
url
|
|
166
|
+
currency
|
|
167
|
+
isTaxable
|
|
168
|
+
description {
|
|
169
|
+
translation {
|
|
170
|
+
language
|
|
171
|
+
value
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
perKmPricing {
|
|
175
|
+
start
|
|
176
|
+
rate
|
|
177
|
+
interval
|
|
178
|
+
end
|
|
179
|
+
}
|
|
180
|
+
perMinPricing {
|
|
181
|
+
start
|
|
182
|
+
rate
|
|
183
|
+
interval
|
|
184
|
+
end
|
|
185
|
+
}
|
|
186
|
+
surgePricing
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
`;
|
|
191
|
+
const queryStations = gql`
|
|
192
|
+
query stations(
|
|
193
|
+
$ids: [String!]
|
|
194
|
+
$minimumLatitude: Float
|
|
195
|
+
$minimumLongitude: Float
|
|
196
|
+
$maximumLatitude: Float
|
|
197
|
+
$maximumLongitude: Float
|
|
198
|
+
$systems: [System!]
|
|
199
|
+
$operators: [Operator!]
|
|
200
|
+
$availableFormFactors: [FormFactor!]
|
|
201
|
+
) {
|
|
202
|
+
stations(
|
|
203
|
+
ids: $ids
|
|
204
|
+
minimumLatitude: $minimumLatitude
|
|
205
|
+
minimumLongitude: $minimumLongitude
|
|
206
|
+
maximumLatitude: $maximumLatitude
|
|
207
|
+
maximumLongitude: $maximumLongitude
|
|
208
|
+
operators: $operators
|
|
209
|
+
availableFormFactors: $availableFormFactors
|
|
210
|
+
) {
|
|
211
|
+
lon
|
|
212
|
+
id
|
|
213
|
+
lat
|
|
214
|
+
name {
|
|
215
|
+
translation {
|
|
216
|
+
language
|
|
217
|
+
value
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
numVehiclesAvailable
|
|
221
|
+
system {
|
|
222
|
+
id
|
|
223
|
+
name {
|
|
224
|
+
translation {
|
|
225
|
+
language
|
|
226
|
+
value
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
shortName {
|
|
230
|
+
translation {
|
|
231
|
+
language
|
|
232
|
+
value
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
operator {
|
|
236
|
+
id
|
|
237
|
+
name {
|
|
238
|
+
translation {
|
|
239
|
+
language
|
|
240
|
+
value
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
`;
|
|
248
|
+
|
|
249
|
+
export const fetchSharingStation = async (id: string) => {
|
|
250
|
+
const client = new GraphQLClient(GQL_URL, {
|
|
251
|
+
method: "GET",
|
|
252
|
+
});
|
|
253
|
+
const { station }: { station: unknown } = await client.request(queryStation, {
|
|
254
|
+
__operation: "station",
|
|
255
|
+
id: id,
|
|
256
|
+
});
|
|
257
|
+
return station;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
export const fetchSharingStations = async (
|
|
261
|
+
ids: null | string[],
|
|
262
|
+
extent: Extent = RVF_EXTENT_4326,
|
|
263
|
+
operators: null | string[] = null,
|
|
264
|
+
abortController: AbortController,
|
|
265
|
+
) => {
|
|
266
|
+
const client = new GraphQLClient(
|
|
267
|
+
"https://api.mobidata-bw.de/sharing/graphql",
|
|
268
|
+
{
|
|
269
|
+
method: "GET",
|
|
270
|
+
signal: abortController.signal,
|
|
271
|
+
},
|
|
272
|
+
);
|
|
273
|
+
const { stations }: { stations: SharingStation[] } = await client.request(
|
|
274
|
+
queryStations,
|
|
275
|
+
{
|
|
276
|
+
// availableFormFactors: ["BICYCLE"],
|
|
277
|
+
// id: "NBK:Station:33269707",
|
|
278
|
+
ids: ids,
|
|
279
|
+
maximumLatitude: extent?.[3],
|
|
280
|
+
maximumLongitude: extent?.[2],
|
|
281
|
+
minimumLatitude: extent?.[1],
|
|
282
|
+
minimumLongitude: extent?.[0],
|
|
283
|
+
operators: operators, //["BK:Operator:nextbike"],
|
|
284
|
+
},
|
|
285
|
+
);
|
|
286
|
+
const featureCollection: FeatureCollection<Point, SharingStation> = {
|
|
287
|
+
features: stations.map((station: SharingStation) => {
|
|
288
|
+
console.log("station", station);
|
|
289
|
+
return {
|
|
290
|
+
geometry: {
|
|
291
|
+
coordinates: [station.lon, station.lat],
|
|
292
|
+
type: "Point",
|
|
293
|
+
},
|
|
294
|
+
properties: {
|
|
295
|
+
...station,
|
|
296
|
+
num_vehicles_available: station.numVehiclesAvailable,
|
|
297
|
+
provider_name: station.system.name.translation[0].value.replace(
|
|
298
|
+
"Freiburg",
|
|
299
|
+
"",
|
|
300
|
+
),
|
|
301
|
+
station_id: station.id,
|
|
302
|
+
},
|
|
303
|
+
type: "Feature",
|
|
304
|
+
};
|
|
305
|
+
}),
|
|
306
|
+
type: "FeatureCollection",
|
|
307
|
+
};
|
|
308
|
+
return featureCollection;
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
export default {
|
|
312
|
+
fetchSharingStations,
|
|
313
|
+
};
|