Skip to content
This repository has been archived by the owner on May 4, 2024. It is now read-only.

Commit

Permalink
Zoom in on the map when Select Paths
Browse files Browse the repository at this point in the history
  • Loading branch information
zoi23333 committed Dec 17, 2023
1 parent 5f5b7aa commit 0a167ae
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 11 deletions.
15 changes: 11 additions & 4 deletions backend/src/roads/road.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,18 @@ export class RoadController {
/**
* Get all the roads in the database.
*
* @author Kerbourc'h
* @author Kerbourc'h, Chen
*/
@Get('paths')
async getRoadsPaths() {
return await this.service.getRoadsPaths();
@Get('paths/:wayId?')
async getRoadsInfo(@Param('wayId') wayId?: OSMWayId) {
if (wayId) {
// Get the length of the specific way
const wayData = await this.service.getWayData(wayId);
return { length: wayData.length };
} else {
// Get all roads if no specific wayId is provided
return await this.service.getRoadsPaths();
}
}

/**
Expand Down
14 changes: 10 additions & 4 deletions frontend/src/Components/Map/Hooks/ForceMapUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ interface Props {
triggerUpdate?: number;
/** The coordinates of the map center*/
position?: LatLng;
/** Zoom level for the map */
zoomLevel?: number;
}

/**
* This component is used to force an update of the map. It is used in conjunction with the useMap hook.
*
* @author Kerbourc'h
* @author Kerbourc'h, Chen
*/
const ForceMapUpdate: React.FC<Props> = ({ triggerUpdate, position }) => {
const ForceMapUpdate: React.FC<Props> = ({
triggerUpdate,
position,
zoomLevel,
}) => {
const map = useMap();

useEffect(() => {
Expand All @@ -24,9 +30,9 @@ const ForceMapUpdate: React.FC<Props> = ({ triggerUpdate, position }) => {
// TODO: not working when moving too little
useEffect(() => {
if (position) {
map.flyTo(position);
map.flyTo(position, zoomLevel);
}
}, [position]);
}, [position, zoomLevel]);

return null;
};
Expand Down
80 changes: 77 additions & 3 deletions frontend/src/pages/Main.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FC, useCallback, useEffect, useState } from 'react';
import Hamburger from '../Components/Map/Inputs/Hamburger';
import { IRoad } from '../models/path';
import { getRoadsPaths } from '../queries/road';
import { IRoad, WayId } from '../models/path';
import { getRoadsPaths, getWayLength } from '../queries/road';
import { LatLng, SurveyListItem } from '../models/models';
import { FeatureCollection } from 'geojson';
import { getAllConditions } from '../queries/conditions';
Expand Down Expand Up @@ -32,6 +32,39 @@ import InfoButton from '../Components/Conditions/InfoButton';
import UploadPanel from '../Components/Conditions/UploadPanel';
import ProgressCircle from '../Components/ProgressCircle';

/**
/* Function to calculate the zoom level
/*
/* @author Chen
*/
const calculateZoomLevel = (maxDistance: number): number => {
let slope = -7.8e-5; // Default
let intercept = 12.6; // Default
if (maxDistance <= 900) {
slope = -7.8e-5;
intercept = 16.5;
} else if (maxDistance > 900 && maxDistance <= 2500) {
slope = -7.8e-5;
intercept = 14.1;
} else if (maxDistance > 2500 && maxDistance <= 8000) {
slope = -7.9e-5;
intercept = 13.8;
} else if (maxDistance > 8000 && maxDistance <= 20000) {
slope = -7.8e-5;
intercept = 14;
} else if (maxDistance > 20000 && maxDistance <= 40000) {
slope = -6.7e-5;
intercept = 14;
} else if (maxDistance > 40000 && maxDistance <= 100000) {
slope = -5e-5;
intercept = 14;
} else {
return 10;
}
const ZoomInParam = slope * maxDistance + intercept;
return ZoomInParam;
};

/**
* Component rendering the main page
*
Expand Down Expand Up @@ -196,6 +229,43 @@ const Main: FC = () => {
});
}, []);

// Control Zoom level by the length of roads when selecting a road on the map
const [zoomLevel, setZoomLevel] = useState<number>(13); // Default zoom level
const [wayLength, setWayLength] = useState<number | null>(null);

/**
/* Function to calculate the total length of roads
/*
/* @author Chen
*/
const fetchAndSumWayLengths = useCallback(
async (branches: WayId[][]) => {
try {
const promises = branches.flat().map(
(wayId) =>
new Promise<number>((resolve) => {
getWayLength(wayId, resolve);
}),
);
const lengths = await Promise.all(promises);
const totalLength = lengths.reduce((sum, length) => sum + length, 0);
setWayLength(totalLength);
} catch (error) {
console.error('Error fetching way lengths:', error);
setWayLength(0);
}
},
[getWayLength, setWayLength],
);

// Zoom in when calling onSelectedPath
useEffect(() => {
if (wayLength !== null) {
const zoom = calculateZoomLevel(wayLength);
setZoomLevel(zoom);
}
}, [wayLength]);

return (
<>
<div className="nav-wrapper">
Expand Down Expand Up @@ -313,6 +383,10 @@ const Main: FC = () => {
if (selectedRoadIdx === -1 && selectedSurvey == null) {
// If no road is selected, select the road
setSelectedRoadIdx(index);
// Get information of road branches for Zoom in
const selectedRoad = roads[index];
const Branches = selectedRoad.branches;
fetchAndSumWayLengths(Branches); // Call fetchAndSumWayLengths to calculate parameters and zoom in
} else if (selectedRoadIdx != -1) {
// if a road is selected, go to the inspect page for the clicked road branch
navigate(
Expand Down Expand Up @@ -344,7 +418,7 @@ const Main: FC = () => {
}
}}
/>
<ForceMapUpdate position={moveToPosition} />
<ForceMapUpdate position={moveToPosition} zoomLevel={zoomLevel} />
</ConditionsMap>
{isUploadPanelOpened && (
<UploadPanel
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/queries/road.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,18 @@ export const getRoadsData = (
) => {
post('/roads/data', wayIds, callback);
};

/**
* Fetch the length of a specific way by its OSMWayId.
* @param wayId the OSMWayId of the way
*
* @author Chen
*/
export const getWayLength = (
wayId: string,
callback: (length: number) => void,
) => {
get(`/roads/paths/${wayId}`, (data: { length: number }) => {
callback(data.length);
});
};

0 comments on commit 0a167ae

Please sign in to comment.