Merge pull request #614 from trails-cool/fix/planner-clear-route-under-two
fix(planner): clear the route when waypoints drop below two
This commit is contained in:
commit
1473e2f291
3 changed files with 54 additions and 1 deletions
|
|
@ -6,6 +6,8 @@ import {
|
||||||
PROFILE_KEY,
|
PROFILE_KEY,
|
||||||
ROAD_METADATA_KEYS,
|
ROAD_METADATA_KEYS,
|
||||||
clearRouteData,
|
clearRouteData,
|
||||||
|
clearComputedRoute,
|
||||||
|
hasComputedRoute,
|
||||||
extractNoGoAreas,
|
extractNoGoAreas,
|
||||||
getBaseLayer,
|
getBaseLayer,
|
||||||
getColorMode,
|
getColorMode,
|
||||||
|
|
@ -266,6 +268,28 @@ describe("clearRouteData", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("clearComputedRoute / hasComputedRoute", () => {
|
||||||
|
it("detects computed geometry and clears it while keeping the profile", () => {
|
||||||
|
const { doc, routeData } = createDoc();
|
||||||
|
expect(hasComputedRoute(routeData)).toBe(false);
|
||||||
|
|
||||||
|
writeComputedRoute(doc, routeData, enrichedFixture());
|
||||||
|
setProfile(routeData, "trekking");
|
||||||
|
setColorMode(routeData, "surface");
|
||||||
|
expect(hasComputedRoute(routeData)).toBe(true);
|
||||||
|
|
||||||
|
clearComputedRoute(doc, routeData);
|
||||||
|
|
||||||
|
expect(hasComputedRoute(routeData)).toBe(false);
|
||||||
|
expect(getCoordinates(routeData)).toBeNull();
|
||||||
|
expect(readGeojson(routeData)).toBeUndefined();
|
||||||
|
expect(readRoadMetadata(routeData).surfaces).toEqual([]);
|
||||||
|
// profile (and other prefs) survive — unlike clearRouteData
|
||||||
|
expect(getProfile(routeData)).toBe("trekking");
|
||||||
|
expect(getColorMode(routeData)).toBe("surface");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("extractNoGoAreas", () => {
|
describe("extractNoGoAreas", () => {
|
||||||
it("reads areas and drops degenerate ones", () => {
|
it("reads areas and drops degenerate ones", () => {
|
||||||
const doc = new Y.Doc();
|
const doc = new Y.Doc();
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,12 @@ export function setGeojson(routeData: Y.Map<unknown>, geojson: unknown): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes the computed route and profile (view preferences are kept). */
|
/** Removes the computed route and profile (view preferences are kept). */
|
||||||
export function clearRouteData(doc: Y.Doc, routeData: Y.Map<unknown>): void {
|
/**
|
||||||
|
* Clear the computed route geometry + per-coordinate road metadata, but keep
|
||||||
|
* the routing profile. Used when the route can no longer exist (fewer than two
|
||||||
|
* waypoints) so the stale line stops rendering without resetting the profile.
|
||||||
|
*/
|
||||||
|
export function clearComputedRoute(doc: Y.Doc, routeData: Y.Map<unknown>): void {
|
||||||
doc.transact(() => {
|
doc.transact(() => {
|
||||||
routeData.delete("geojson");
|
routeData.delete("geojson");
|
||||||
routeData.delete("coordinates");
|
routeData.delete("coordinates");
|
||||||
|
|
@ -198,6 +203,17 @@ export function clearRouteData(doc: Y.Doc, routeData: Y.Map<unknown>): void {
|
||||||
for (const key of ROAD_METADATA_KEYS) {
|
for (const key of ROAD_METADATA_KEYS) {
|
||||||
routeData.delete(key);
|
routeData.delete(key);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** True if the route data currently holds computed geometry. */
|
||||||
|
export function hasComputedRoute(routeData: Y.Map<unknown>): boolean {
|
||||||
|
return routeData.get("coordinates") !== undefined || routeData.get("geojson") !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearRouteData(doc: Y.Doc, routeData: Y.Map<unknown>): void {
|
||||||
|
doc.transact(() => {
|
||||||
|
clearComputedRoute(doc, routeData);
|
||||||
routeData.delete(PROFILE_KEY);
|
routeData.delete(PROFILE_KEY);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ import {
|
||||||
extractNoGoAreas,
|
extractNoGoAreas,
|
||||||
getProfile,
|
getProfile,
|
||||||
writeComputedRoute,
|
writeComputedRoute,
|
||||||
|
clearComputedRoute,
|
||||||
|
hasComputedRoute,
|
||||||
} from "./route-data.ts";
|
} from "./route-data.ts";
|
||||||
import { extractWaypoints } from "./waypoint-ymap.ts";
|
import { extractWaypoints } from "./waypoint-ymap.ts";
|
||||||
|
|
||||||
|
|
@ -210,11 +212,22 @@ export function useRouting(yjs: YjsState | null, sessionId: string) {
|
||||||
triggerRecompute();
|
triggerRecompute();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// When waypoints drop below two, no route can exist — drop the stale
|
||||||
|
// geometry so the line stops rendering. (Recompute for >=2 is triggered by
|
||||||
|
// the add/move/delete handlers themselves.)
|
||||||
|
const waypointsObserver = () => {
|
||||||
|
if (getWaypointsFromYjs(yjs.waypoints).length < 2 && hasComputedRoute(yjs.routeData)) {
|
||||||
|
clearComputedRoute(yjs.doc, yjs.routeData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
yjs.routeData.observe(profileObserver);
|
yjs.routeData.observe(profileObserver);
|
||||||
yjs.noGoAreas.observeDeep(noGoObserver);
|
yjs.noGoAreas.observeDeep(noGoObserver);
|
||||||
|
yjs.waypoints.observeDeep(waypointsObserver);
|
||||||
return () => {
|
return () => {
|
||||||
yjs.routeData.unobserve(profileObserver);
|
yjs.routeData.unobserve(profileObserver);
|
||||||
yjs.noGoAreas.unobserveDeep(noGoObserver);
|
yjs.noGoAreas.unobserveDeep(noGoObserver);
|
||||||
|
yjs.waypoints.unobserveDeep(waypointsObserver);
|
||||||
};
|
};
|
||||||
}, [yjs, isHost, requestRoute]);
|
}, [yjs, isHost, requestRoute]);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue