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

Commit

Permalink
Zoom on the map when Selecting Paths (#182)
Browse files Browse the repository at this point in the history
  • Loading branch information
zoi23333 authored Dec 18, 2023
1 parent ee96ac6 commit 7ed275d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 6 deletions.
1 change: 1 addition & 0 deletions backend/src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export interface Road {
way_name: string;
branches: OSMWayId[][];
geometries: Record<OSMWayId, LatLng[]>;
length: number;
}

/**
Expand Down
13 changes: 12 additions & 1 deletion backend/src/roads/road.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,18 @@ export class RoadService {
Object.values(ways).forEach((way) => {
geometries[way.osm_id] = way.section_geom;
});
return { way_name: wayName, branches: branches, geometries: geometries };

const sumLength = longestBranches.reduce(
(total, branch) => total + branch.length,
0,
);

return {
way_name: wayName,
branches: branches,
geometries: geometries,
length: sumLength,
};
}

/**
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
1 change: 1 addition & 0 deletions frontend/src/models/path.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface IRoad {
branches: WayId[][];
// the geometry of each way
geometries: Record<WayId, LatLng[]>;
length: number;
}

export enum ImageType {
Expand Down
55 changes: 54 additions & 1 deletion frontend/src/pages/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Hamburger from '../Components/Map/Inputs/Hamburger';
import { IRoad } from '../models/path';
import { getRoadsPaths } from '../queries/road';
import { LatLng, SurveyListItem } from '../models/models';
import { LatLng as LatLngLeaflet } from 'leaflet';
import { FeatureCollection } from 'geojson';
import { getAllConditions } from '../queries/conditions';

Expand Down Expand Up @@ -32,6 +33,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 +230,9 @@ 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

return (
<>
<div className="nav-wrapper">
Expand All @@ -207,6 +244,17 @@ const Main: FC = () => {
survey.geometry[Math.floor(survey.geometry.length / 2)];
setMoveToPosition({ lat: coord[1], lng: coord[0] });

const path = survey.geometry.map(
(coord) => new LatLngLeaflet(coord[1], coord[0]),
);

let len = 0;
for (let i = 0; i < path.length - 1; i++) {
len += path[i].distanceTo(path[i + 1]);
}
const zoomParam = calculateZoomLevel(len);
setZoomLevel(zoomParam);

setSelectedSurvey(survey);
}}
/>
Expand Down Expand Up @@ -313,6 +361,11 @@ 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 sumLength = selectedRoad.length;
const zoomParam = calculateZoomLevel(sumLength);
setZoomLevel(zoomParam);
} 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 +397,7 @@ const Main: FC = () => {
}
}}
/>
<ForceMapUpdate position={moveToPosition} />
<ForceMapUpdate position={moveToPosition} zoomLevel={zoomLevel} />
</ConditionsMap>
{isUploadPanelOpened && (
<UploadPanel
Expand Down

0 comments on commit 7ed275d

Please sign in to comment.