fetching data from api for route preview
This commit is contained in:
141
src/preview/components/route-preview/mappers/mapRouteFromApi.ts
Normal file
141
src/preview/components/route-preview/mappers/mapRouteFromApi.ts
Normal file
@ -0,0 +1,141 @@
|
||||
import { MapData, StationOnMap } from "@mt/components";
|
||||
import { TEMP_STATION_TYPE_MAP } from "@mt/common-types";
|
||||
import {
|
||||
Coordinates,
|
||||
Route,
|
||||
RouteStation,
|
||||
Station,
|
||||
Track,
|
||||
TransferStation,
|
||||
} from "@mt/common-types";
|
||||
|
||||
export function mapRouteFromApi(
|
||||
routeData: Route,
|
||||
stations: Station[]
|
||||
): MapData {
|
||||
const {
|
||||
generalInfo,
|
||||
attractionGroupings,
|
||||
stations: routeStations,
|
||||
} = routeData;
|
||||
const { rotate, scale1, scale2, centerCoordinates, track } = generalInfo;
|
||||
|
||||
return {
|
||||
mapRotateAngle: rotate,
|
||||
fullMapScale: scale1,
|
||||
zoomedMapScale: scale2,
|
||||
centerOfMapPoint: centerCoordinates,
|
||||
trackPoints: track,
|
||||
stationsOnMap: mapStationsFromApi(routeStations, stations, track),
|
||||
touristAttractionGroupsOnMap: attractionGroupings
|
||||
.filter(({ coordinates }) => Boolean(coordinates))
|
||||
.map(({ iconSize, coordinates, attractionIds }) => ({
|
||||
iconSize,
|
||||
pointOnMap: coordinates,
|
||||
touristAttractionsOnMap: attractionIds.map((id) => ({
|
||||
id,
|
||||
pointOnMap: coordinates,
|
||||
})),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
function mapStationsFromApi(
|
||||
routeStations: RouteStation[],
|
||||
stations: Station[],
|
||||
track: Track
|
||||
): MapData["stationsOnMap"] {
|
||||
const stationsMap = new Map(stations.map((station) => [station.id, station]));
|
||||
const unionStations: Array<Omit<RouteStation, "stationId"> & Station> =
|
||||
routeStations.map(({ stationId, ...station }) => ({
|
||||
...station,
|
||||
...stationsMap.get(stationId),
|
||||
}));
|
||||
|
||||
const mappedStations = unionStations.map((station) => {
|
||||
const {
|
||||
id,
|
||||
name,
|
||||
shortName,
|
||||
coordinates,
|
||||
textAlignment,
|
||||
mapOffsets,
|
||||
stationTypeId,
|
||||
transferStations,
|
||||
iconUrl,
|
||||
} = station;
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
shortName,
|
||||
coordinates,
|
||||
transferStationInfos: mapTransfersToMap(transferStations, stationsMap),
|
||||
labelAlignment: textAlignment,
|
||||
labelOffset: mapOffsets,
|
||||
iconUrl,
|
||||
stationTypeId,
|
||||
};
|
||||
});
|
||||
|
||||
const stationsOnMap = mappedStations.map((station) => {
|
||||
const { coordinates } = station;
|
||||
const trackIndex = track.findIndex(
|
||||
(trackPoint) =>
|
||||
coordinates.lat === trackPoint.lat && coordinates.lon === trackPoint.lon
|
||||
);
|
||||
|
||||
return {
|
||||
...station,
|
||||
pointOnMap: {
|
||||
...coordinates,
|
||||
trackIndex,
|
||||
},
|
||||
};
|
||||
}) as MapData["stationsOnMap"];
|
||||
|
||||
return sortStationsByTrackOrder(track, stationsOnMap);
|
||||
}
|
||||
|
||||
function sortStationsByTrackOrder(
|
||||
track: Track,
|
||||
stations: StationOnMap[]
|
||||
): StationOnMap[] {
|
||||
// Create a map to store the index of each coordinate in the second array
|
||||
const coordinateIndexMap = new Map<string, number>();
|
||||
track.forEach((coordinate, index) => {
|
||||
coordinateIndexMap.set(getCoordinateString(coordinate), index);
|
||||
});
|
||||
|
||||
// Sort the first array based on the order of coordinates in the second array
|
||||
return [...stations].sort((a, b) => {
|
||||
const indexA =
|
||||
coordinateIndexMap.get(getCoordinateString(a.coordinates)) || 0;
|
||||
const indexB =
|
||||
coordinateIndexMap.get(getCoordinateString(b.coordinates)) || 0;
|
||||
|
||||
return indexA - indexB;
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: move to shared utils and refactor across the project
|
||||
function getCoordinateString(coordinate: Coordinates): string {
|
||||
return `${coordinate.lat}:${coordinate.lon}`;
|
||||
}
|
||||
|
||||
function mapTransfersToMap(
|
||||
transferStations: TransferStation[],
|
||||
stationsMap: Map<string, Station>
|
||||
) {
|
||||
return transferStations
|
||||
.filter(({ isShowOnMap }) => isShowOnMap)
|
||||
.sort(({ ordinal: ordinalA }, { ordinal: ordinalB }) => ordinalA - ordinalB)
|
||||
.map(({ stationId }) => {
|
||||
const { stationTypeId, shortName } = stationsMap.get(stationId);
|
||||
|
||||
return {
|
||||
type: TEMP_STATION_TYPE_MAP[stationTypeId].type,
|
||||
name: shortName,
|
||||
};
|
||||
});
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { Route, RouteStation } from "@admin/types";
|
||||
import { MapSettings } from "@mt/components";
|
||||
import { DeepPartial } from "react-hook-form";
|
||||
|
||||
export const mapRouteToApi = (
|
||||
{ rotateAngle, fullScale, zoomedScale, center }: MapSettings,
|
||||
updatedStations: Partial<RouteStation>,
|
||||
previousData
|
||||
): DeepPartial<Route> => {
|
||||
return {
|
||||
...previousData,
|
||||
generalInfo: {
|
||||
...previousData.generalInfo,
|
||||
rotate: rotateAngle,
|
||||
scale1: fullScale,
|
||||
scale2: zoomedScale,
|
||||
centerCoordinates: center,
|
||||
},
|
||||
stations: previousData.stations.map((station: RouteStation) => {
|
||||
return updatedStations[station.stationId]
|
||||
? { ...station, ...updatedStations[station.stationId] }
|
||||
: station;
|
||||
}),
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user