profileAccessibleScore = (quayProperties, profile) => {
const RATINGRANGE = [0, 1, 2, 3];
const RATINGNA = 4;
const maximumRating = RATINGRANGE.slice(-1)[0];
const ratingScale = (domain) =>
d3.scaleThreshold().domain(domain).range(RATINGRANGE);
const THRESHOLDDOMAIN = [-0.021, -0.011, 0];
const QUAYNARROWESTWIDTHDOMAIN = [-0.05, 0, 0.05];
const RAMPROOMWIDTHDOMAIN = [-0.2, 0, 0.05];
const RAMPMINHEIGHTDOMAIN = [-0.04, -0.02, 0];
const VEHICLETHRESHOLDDOMAIN = [-0.021, -0.011, 0];
const VEHICLETRAMHEIGHT = 0.29;
const VEHICLEBUSHEIGHT = 0.23;
const RAMPWIDTHNEEDED = 1.5;
const WHEELCHAIRELECTRIC = "Elektrische rolstoel";
const WHEELCHAIRMANUAL = "Handrolstoel";
const SCOOTMOBILE = "Scootmobiel";
const WALKINGAID = "Rollator";
// TODO: also add a formula for scoot mobiles
const MINHEIGHT_MANUAL_BUS = 0.161;
const MINHEIGHT_SCOOTMOBILE_BUS = 0.126;
const MINHEIGHT_ELECTRIC_BUS = 0.126;
const MINHEIGHT_MANUAL_TRAM = 0.221;
const MINHEIGHT_ELECTRIC_TRAM = 0.186;
const MINHEIGHT_SCOOTMOBILE_TRAM = 0.186;
const quay = quayProperties;
const transportMode = quay.transportmode || "unknown";
// Threshold rating block
const threshold =
!quay.ramp &&
!quay.lift &&
!quay.stopplaceaccessroute &&
quay.heightwithenvironment !== 0;
const quayThresholdProfile = profile.threshold / 100;
const quayThreshold = threshold ? quay.kerbheight : undefined;
const quayThresholdDifference = quayThresholdProfile - quayThreshold;
// voorbeeld: profiel: maxdrempel is 5, situatie: drempel is 6 => difference 5-6= -1
const quayThresholdRating =
threshold && transportMode !== "ferry"
? ratingScale(THRESHOLDDOMAIN)(quayThresholdDifference)
: maximumRating;
// quayNarrowestWidthRating block
const quayNarrowestWidthProfile = profile.width / 100;
const quayNarrowestWidth =
quay.narrowestpassagewidth || quay.boardingpositionwidth; // a small percentage of quays have an unknown narrowestwidth (mostly metros and ferrys)
const quayNarrowestWidthDifference =
quayNarrowestWidth - quayNarrowestWidthProfile;
const quayNarrowestWidthRating =
transportMode !== "ferry"
? ratingScale(QUAYNARROWESTWIDTHDOMAIN)(quayNarrowestWidthDifference)
: maximumRating;
// vehicleThresholdRating block
const vehicleThresholdProfile = profile.threshold / 100;
const vehicleThreshold =
transportMode === "tram"
? VEHICLETRAMHEIGHT - quay.kerbheight
: transportMode === "bus"
? VEHICLEBUSHEIGHT - quay.kerbheight
: // set metro and ferry treshold to 0, leading to a max rating
transportMode === "metro" || transportMode === "ferry"
? 0
: null;
const vehicleThresholdDifference =
vehicleThresholdProfile - Math.abs(vehicleThreshold);
// give this the highest rating if user needs a ramp
const vehicleThresholdRating = ratingScale(VEHICLETHRESHOLDDOMAIN)(
vehicleThresholdDifference
);
// rampRoomWidthRating block
const rampRoomWidthProfile = RAMPWIDTHNEEDED;
const rampRoomWidth = quay.boardingpositionwidth;
const rampRoomWidthDifference = rampRoomWidth - rampRoomWidthProfile;
// give this the highest rating if user does not need a ramp
const rampRoomWidthRating =
transportMode === "metro" || transportMode === "ferry"
? maximumRating
: ratingScale(RAMPROOMWIDTHDOMAIN)(rampRoomWidthDifference);
// rampRoomMinHeightRating block
// TODO: we don't take the different ramp dimensions of tram and bus into account
const rampMinHeightProfile =
(profile.modality === WHEELCHAIRMANUAL ||
profile.modality === WALKINGAID) &&
transportMode === "bus"
? MINHEIGHT_MANUAL_BUS
: profile.modality === WHEELCHAIRELECTRIC && transportMode === "bus"
? MINHEIGHT_ELECTRIC_BUS
: profile.modality === SCOOTMOBILE && transportMode === "bus"
? MINHEIGHT_SCOOTMOBILE_BUS
: (profile.modality === WHEELCHAIRMANUAL ||
profile.modality === WALKINGAID) &&
transportMode === "tram"
? MINHEIGHT_MANUAL_TRAM
: profile.modality === WHEELCHAIRELECTRIC && transportMode === "tram"
? MINHEIGHT_ELECTRIC_TRAM
: profile.modality === SCOOTMOBILE && transportMode === "tram"
? MINHEIGHT_SCOOTMOBILE_TRAM
: // for now we throw a null for other transportmodes, leading to a max rating
null;
const rampKerbHeight = quay.kerbheight || 0; // unknown kerbs are presumed to have no height
const rampMinHeightDifference = rampKerbHeight - rampMinHeightProfile;
// TODO: maybe there should be a difference in the rating for a bus and a tram quay here
// give this the highest rating if user does not need a ramp
const rampMinHeightRating = ratingScale(RAMPMINHEIGHTDOMAIN)(
rampMinHeightDifference
);
// we use a combined ramp rating
const rampRating = Math.min(rampMinHeightRating, rampRoomWidthRating);
const allRatings = [
quayThresholdRating,
quayNarrowestWidthRating,
vehicleThresholdRating,
rampRoomWidthRating,
rampMinHeightRating
];
const rampRatings = [
quayThresholdRating,
quayNarrowestWidthRating,
rampRoomWidthRating,
rampMinHeightRating
];
const noRampRatings = [
quayThresholdRating,
quayNarrowestWidthRating,
vehicleThresholdRating
];
// TODO: enable ramp row overlays when vehicleThresholdRating > rampRating
// if the vehiclethreshold rating is ok, disregard the ramp from the rating.
// If profile cannot get in the vehicle without ramp,
// take the lowest of the ramp related ratings.
const overallRating = profile.ramp
? vehicleThresholdRating > rampRating
? Math.min(...noRampRatings)
: Math.min(...rampRatings)
: Math.min(...noRampRatings);
// to return all calculated constands, we construct them in an object here
// TODO: is there a better way?
return {
transportMode,
allRatings,
overallRating,
threshold,
quayThresholdProfile,
quayThreshold,
quayThresholdDifference,
quayThresholdRating,
quayNarrowestWidthProfile,
quayNarrowestWidth,
quayNarrowestWidthDifference,
quayNarrowestWidthRating,
vehicleThresholdProfile,
vehicleThreshold,
vehicleThresholdDifference,
vehicleThresholdRating,
rampRoomWidthProfile,
rampRoomWidth,
rampRoomWidthDifference,
rampRoomWidthRating,
rampMinHeightProfile,
rampKerbHeight,
rampMinHeightDifference,
rampMinHeightRating,
rampRating
};
}