* feat: add boilerplate
* feat: add working paths
* feat: improve building selection controls and add week schedule
Signed-off-by: doprz <52579214+doprz@users.noreply.github.com>
* fix: sort week schedule
Signed-off-by: doprz <52579214+doprz@users.noreply.github.com>
* feat(testing): improve pathfinding
* Revert "feat(testing): improve pathfinding"
This reverts commit 87998cedbf.
* feat: add pathfinding with building selection controls
Signed-off-by: doprz <52579214+doprz@users.noreply.github.com>
* feat: improve path finding algorithm thresholds
* feat: add DaySelector, PathStats, and WeekSchedule components
* feat: add working stats and daily schedule
* chore: refactor everything
* feat: add linear walkway node generation
* feat: add bezier curve walkway node generation
* feat: add circular walkway node generation
* docs: add docs
* feat: add individual path selection and bump version
* fix: tsdoc and updated components/utils
* chore(deps): update deps
* feat: add UTRP Map and Debug Page to Settings > Developer Mode
* chore: fix pr review comments
* chore: add showDebugNodes
* chore: add all buildings around the UT tower
* chore: add stadium POIs
* chore: add east mall buildings
* chore: update DaySelector to use proper button styling
* chore: add university ave walkway
* feat: add zoom, pan, and dev controls functionality
- Fix SVG Overlay Alignment
- Use SVG for map
- Add Dev Controls
- Fix day selector position
- Update the SVG's `preserveAspectRatio` attribute to `xMidYMid` meet to
ensure proper scaling
- Use `useCallback` for event handlers to prevent unnecessary re-renders
- Remove old PNG map
* feat: add dynamic rendering"
* feat: add dynamicRendering dev toggle and fullscreen support
* chore: update deps
* chore: disable viewport svg overlay culling if dynamic rendering is off
* chore: update pnpm-lock.yaml
* chore: add north mall buildings
* chore: add buildings next to JES
* refactor: map components into individual files
* fix: missing import
---------
Signed-off-by: doprz <52579214+doprz@users.noreply.github.com>
87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
import React from 'react';
|
|
|
|
import { graphNodes } from './graphNodes';
|
|
import { isValidNode, PIXELS_TO_FEET, WALKING_SPEED } from './types';
|
|
|
|
type PathStatsProps = {
|
|
startId: string;
|
|
endId: string;
|
|
};
|
|
|
|
/**
|
|
* Calculates the direct path statistics between two nodes.
|
|
*
|
|
* @param startId - The ID of the starting node.
|
|
* @param endId - The ID of the ending node.
|
|
*
|
|
* @returns The distance in feet and walking time in minutes between the two nodes.
|
|
*/
|
|
export const calcDirectPathStats = ({ startId, endId }: PathStatsProps) => {
|
|
const startNode = graphNodes[startId];
|
|
const endNode = graphNodes[endId];
|
|
|
|
if (!isValidNode(startNode) || !isValidNode(endNode)) {
|
|
return null;
|
|
}
|
|
|
|
// Calculate distance in pixels
|
|
const distanceInPixels = Math.sqrt((endNode.x - startNode.x) ** 2 + (endNode.y - startNode.y) ** 2);
|
|
|
|
// Convert to feet and calculate time
|
|
const distanceInFeet = Math.round(distanceInPixels * PIXELS_TO_FEET);
|
|
const walkingTimeMinutes = Math.ceil(distanceInFeet / WALKING_SPEED);
|
|
|
|
return {
|
|
distanceInFeet,
|
|
walkingTimeMinutes,
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Component to display statistics about a path between two nodes on a map.
|
|
*
|
|
* @param startId - The ID of the starting node.
|
|
* @param endId - The ID of the ending node.
|
|
*
|
|
* @returns A JSX element displaying the path statistics, or null if the nodes are invalid.
|
|
*/
|
|
export const PathStats = ({ startId, endId }: PathStatsProps): JSX.Element | null => {
|
|
const startNode = graphNodes[startId];
|
|
const endNode = graphNodes[endId];
|
|
|
|
if (!isValidNode(startNode) || !isValidNode(endNode)) {
|
|
return null;
|
|
}
|
|
|
|
// Calculate distance in pixels
|
|
const distanceInPixels = Math.sqrt((endNode.x - startNode.x) ** 2 + (endNode.y - startNode.y) ** 2);
|
|
|
|
// Convert to feet and calculate time
|
|
const distanceInFeet = Math.round(distanceInPixels * PIXELS_TO_FEET);
|
|
const walkingTimeMinutes = Math.ceil(distanceInFeet / WALKING_SPEED);
|
|
|
|
return (
|
|
<div className='rounded-md bg-white/90 p-3 shadow-sm space-y-2'>
|
|
<h3 className='text-sm font-medium'>Path Statistics</h3>
|
|
<div className='space-y-1'>
|
|
<div className='flex justify-between text-xs'>
|
|
<span>Distance:</span>
|
|
<span className='font-medium'>{distanceInFeet} ft</span>
|
|
</div>
|
|
<div className='flex justify-between text-xs'>
|
|
<span>Walking Time:</span>
|
|
<span className='font-medium'>{walkingTimeMinutes} min</span>
|
|
</div>
|
|
<div className='flex justify-between text-xs'>
|
|
<span>From:</span>
|
|
<span className='font-medium'>{startId}</span>
|
|
</div>
|
|
<div className='flex justify-between text-xs'>
|
|
<span>To:</span>
|
|
<span className='font-medium'>{endId}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|