142 lines
3.7 KiB
TypeScript
142 lines
3.7 KiB
TypeScript
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,
|
|
};
|
|
});
|
|
}
|