mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-22 23:16:46 +00:00
feat(tours): OpenHikingMap as a hiking base map of the tour planner (MAP-01)
While a hike is planned, the planner's map switch offers "Hiking" beside the map, topo and satellite: OpenHikingMap, with marked trails over the terrain. It is a choice of the planner's view alone, like topo: the global map setting, the tour and its days stay as they are. With no tour open, over an import viewed as it came in and for a paddle tour it is not offered, and a choice made earlier falls back to the standard map there. openmaps.fr's tile usage policy is followed: tiles load only as the map shows them, with the browser's Referer, from the server's own caching; no service worker rule keeps them and the 3D flyover's warm-up passes their source by. Its credit and donation link are on the map; the 3D map, whose attribution is folded away under the panel, shows them as a line of its own above its controls. The service is best effort. A run of failed tiles while it is shown marks the switch, with a tooltip and a status for screen readers that say it is not answering and that the tour is untouched; one tile arriving clears it. The tile health the seamark overlay had is now useTileHealth, shared by both. The source is free for non-commercial installs up to 500,000 tiles a month. tours_hiking_map_enabled is an admin switch under Tours (admin tours-hiking-map, audited), on by default, for an install that is commercial or larger to switch off until it has an agreement with the operator. /api/addons carries it as toursHikingMap, true only while Tours is on. Leaflet, GL and the 3D map read one table of the planner's raster bases (tourRasterBases), so topo and the hiking map are drawn the same way. tile.openmaps.fr is on the CSP's connect-src for the GL maps.
This commit is contained in:
@@ -325,6 +325,9 @@ export function applyGlobalMiddleware(
|
||||
// Tours planner (PAD-10). Leaflet loads it as an <img>; the GL map reads it
|
||||
// through fetch and needs it here.
|
||||
'https://tiles.openseamap.org',
|
||||
// OpenHikingMap, the hiking base map of the Tours planner (MAP-01), loaded only
|
||||
// while a user shows it and the admin allows it; GL reads it through fetch.
|
||||
'https://tile.openmaps.fr',
|
||||
// Amap's raster tiles, for an install whose users are in China, for the
|
||||
// same reason as the hosts above (#2180). Road (webrd01..04) and
|
||||
// satellite (webst01..04) are numbered shards of one domain, so the
|
||||
|
||||
@@ -78,6 +78,19 @@ export class AddonsService {
|
||||
return { enabled: !!enabled };
|
||||
}
|
||||
|
||||
/**
|
||||
* MAP-01: the admin's switch for OpenHikingMap under Tours, as stored. Fail-open: an install
|
||||
* that never saved it offers the map, one whose admin switched it off does not.
|
||||
*/
|
||||
async getToursHikingMap() {
|
||||
const value = await readAppSetting(this.appSettings, 'tours_hiking_map_enabled');
|
||||
return { enabled: value !== 'false' };
|
||||
}
|
||||
|
||||
async updateToursHikingMap(enabled: boolean) {
|
||||
return this.writeFlag('tours_hiking_map_enabled', enabled);
|
||||
}
|
||||
|
||||
/** wanderer may be used: Tours is on and the admin allowed it under Tours. */
|
||||
async isWandererAvailable(): Promise<boolean> {
|
||||
return (await this.isAddonEnabled(ADDON_IDS.TOURS)) && (await this.getToursWanderer()).enabled;
|
||||
@@ -163,6 +176,7 @@ export class AddonsService {
|
||||
collabFeatures: await this.getCollabFeatures(),
|
||||
bagTracking: (await this.getBagTracking()).enabled,
|
||||
toursWanderer: await this.isWandererAvailable(),
|
||||
toursHikingMap: (await this.isAddonEnabled(ADDON_IDS.TOURS)) && (await this.getToursHikingMap()).enabled,
|
||||
addons: [
|
||||
// The repository row carries every scalar column (description, config,
|
||||
// sort_order included); the legacy statement selected only these five,
|
||||
|
||||
@@ -304,6 +304,25 @@ export class AdminController {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Get('tours-hiking-map')
|
||||
@ResponseContract(adminFeatureToggleResponseSchema)
|
||||
getToursHikingMap() {
|
||||
return this.addons.getToursHikingMap();
|
||||
}
|
||||
|
||||
@Put('tours-hiking-map')
|
||||
@ResponseContract(adminFeatureToggleResponseSchema)
|
||||
async updateToursHikingMap(@CurrentUser() user: User, @Body() body: AdminFeatureToggleDto, @Req() req: Request) {
|
||||
const result = await this.addons.updateToursHikingMap(body.enabled);
|
||||
await this.audit.writeAudit({
|
||||
userId: user.id,
|
||||
action: 'admin.tours_hiking_map',
|
||||
ip: getClientIp(req),
|
||||
details: { enabled: result.enabled },
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Get('places-photos')
|
||||
getPlacesPhotos() {
|
||||
return this.addons.getPlacesPhotos();
|
||||
|
||||
@@ -108,6 +108,10 @@ export const APP_SETTINGS = {
|
||||
bag_tracking_enabled: { schema: flag, default: 'false' },
|
||||
// Off until an admin allows it: every user's wanderer calls go out to an address of their choosing.
|
||||
tours_wanderer_enabled: { schema: flag, default: 'false' },
|
||||
// MAP-01: OpenHikingMap as a base map of the Tours planner. On, since its tiles are free for
|
||||
// the installs TREK is made for; an admin whose install is commercial or larger switches it off
|
||||
// until there is an agreement with the operator (openmaps.fr/tile-usage-policy.html).
|
||||
tours_hiking_map_enabled: { schema: flag, default: 'true' },
|
||||
route_usage_enabled: { schema: flag, default: 'false' },
|
||||
// PAD-11C: how TREK gets the water data of a place a paddler plans in (auto, ask, off) and the largest extract it loads by itself.
|
||||
paddle_auto_load: { schema: z.enum(['auto', 'ask', 'off']), default: 'auto' },
|
||||
|
||||
Reference in New Issue
Block a user