'
+ })
+ });
+ }
+
+ /**
+ * Rounds the given number to a fixed number of decimals in order to avoid floating point inaccuracies
+ * (for example to make 0.1 + 0.2 = 0.3 instead of 0.30000000000000004).
+ */
+ static fixFloatingPoint(number: number): number {
+ return AutoGraticule.round(number, 12);
+ }
+
+ /**
+ * Rounds the given number to the given number of decimals.
+ */
+ static round(number: number, digits: number) {
+ const fac = Math.pow(10, digits);
+ return Math.round(number * fac) / fac;
+ }
+
+ /**
+ * Given the distance between two coordinates, floors this distance to 90, 60, 45, 30 or
+ * 10, 5, 2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01, ...
+ * This will define the distance between two grid lines.
+ * @param variableDistance This should be true when the distance between the grid lines will be variable, that is for the latitude
+ * lines (because in Meractor projection the distance between two latitutes gets larger towards the poles, but the distance
+ * between two longitudes is constant throughout the globe).
+ * For constant distance lines (longitude), a line should be shown for every coordinate dividable by the result of this
+ * function. For example, if the result is 45, a line should be shown for longitudes -180, -135, -90, -45, 0, 45, 90, 135, 180.
+ * For variable distance lines (latitude), a line should be shown for coordinates dividable by a result of this function, but
+ * not for every single coordinate but only those that have a minimum distance towards their neighbour coordinate line. For
+ * variable distance lines, the maximum number returned by this function is 5, meaning at low zoom levels, all latitude lines
+ * are dividable by 5 (but not every latitude dividable by 5 will get a line).
+ */
+ static getGridDivisor(number: number, variableDistance: boolean) {
+ if (number <= 0 || !isFinite(number))
+ throw new Error("Invalid number " + number);
+ else {
+ if (variableDistance && number >= 5)
+ return 5;
+ if (number <= 10) {
+ let fac = 1;
+ while (number > 1) { fac *= 10; number /= 10; }
+ while (number <= 0.1) { fac /= 10; number *= 10; }
+
+ // Dist is now some number between 0.1 and 1, so we can round it conveniently and then multiply it again by fac to get back to the original dist
+
+ if (number == 0.1)
+ return AutoGraticule.fixFloatingPoint(0.1 * fac);
+ else if (number <= 0.2)
+ return AutoGraticule.fixFloatingPoint(0.2 * fac);
+ else if (number <= 0.5)
+ return AutoGraticule.fixFloatingPoint(0.5 * fac);
+ else
+ return fac;
+ } else if (number <= 30)
+ return 30;
+ else if (number <= 45)
+ return 45;
+ else if (number <= 60)
+ return 60;
+ else
+ return 90;
+ }
+ }
+ // Backwards compatibility
+ static niceRound = AutoGraticule.getGridDivisor;
+
+ static bboxIntersect(bbox1: LatLngBounds | LatLngExpression[], bbox2: LatLngBounds | LatLngExpression[]) {
+ const bounds1 = bbox1 instanceof LatLngBounds ? bbox1 : latLngBounds(bbox1);
+ const bounds2 = bbox2 instanceof LatLngBounds ? bbox2 : latLngBounds(bbox2);
+ return latLngBounds([
+ [Math.max(bounds1.getSouth(), bounds2.getSouth()), Math.max(bounds1.getWest(), bounds2.getWest())],
+ [Math.min(bounds1.getNorth(), bounds2.getNorth()), Math.min(bounds1.getEast(), bounds2.getEast())]
+ ]);
+ }
+}
\ No newline at end of file
diff --git a/web/src/lib/vendor/leaflet-image/leaflet-image.js b/web/src/lib/vendor/leaflet-image/leaflet-image.js
index e3cbbfd8..3364ca9e 100644
--- a/web/src/lib/vendor/leaflet-image/leaflet-image.js
+++ b/web/src/lib/vendor/leaflet-image/leaflet-image.js
@@ -197,12 +197,11 @@ export default function leafletImage(map, callback) {
minPoint = new L.Point(pixelBounds.min.x, pixelBounds.min.y),
pixelPoint = map.project(marker.getLatLng()),
url = "/vendor/leaflet-image/marker.png",
- icon = getComputedStyle(marker._icon.children[0], ':before').getPropertyValue('content').substring(1, 2) ?? "\uf111",
im = new Image(),
options = marker.options.icon.options,
size = options.iconSize,
pos = pixelPoint.subtract(minPoint),
- anchor = L.point(options.iconAnchor || size && size.divideBy(2, true));
+ anchor = L.point(options.iconAnchor || size && { x: size[0], y: size[1] });
if (size instanceof L.Point) size = [size.x, size.y];
@@ -214,10 +213,28 @@ export default function leafletImage(map, callback) {
im.crossOrigin = '';
im.onload = function () {
- ctx.drawImage(this, x, y, size[0], size[1]);
- ctx.font = '600 14px "Font Awesome 6 Free"';
- ctx.fillStyle = "#ffffff";
- ctx.fillText(icon, x + 10.2, y + 24);
+ if (marker._icon.classList.contains("leaflet-grid-label")) {
+ const label = marker._icon.children[0].textContent;
+ ctx.font = '600 8px "Font Awesome 6 Free"';
+ ctx.fillStyle = "#000";
+ ctx.fillText(label, x + 4, y + 12);
+ } else {
+ const waypointName = marker.options.meta?.waypointName;
+ const icon = getComputedStyle(marker._icon.children[0], ':before').getPropertyValue('content').substring(1, 2) ?? "\uf111";
+ ctx.drawImage(this, x, y, size[0], size[1]);
+ ctx.font = '600 14px "Font Awesome 6 Free"';
+ ctx.fillStyle = "#ffffff";
+ ctx.fillText(icon, x + 10.2, y + 24);
+ if (waypointName) {
+ ctx.fillStyle = "#313131"
+ ctx.roundRect(x - 8, y - 18, waypointName.length * 7, 20, 5)
+ ctx.fill();
+ ctx.font = '600 12px "IBMPlexSans"';
+ ctx.fillStyle = "#ffffff";
+ ctx.fillText(waypointName, x, y - 4);
+ }
+ }
+
callback(null, {
canvas: canvas
});
diff --git a/web/src/routes/map/trail/[id]/print/+page.svelte b/web/src/routes/map/trail/[id]/print/+page.svelte
index 2df02add..65ac4e86 100644
--- a/web/src/routes/map/trail/[id]/print/+page.svelte
+++ b/web/src/routes/map/trail/[id]/print/+page.svelte
@@ -2,8 +2,15 @@
import { page } from "$app/stores";
import Button from "$lib/components/base/button.svelte";
import Select from "$lib/components/base/select.svelte";
+ import LogoText from "$lib/components/logo/logo_text.svelte";
import MapWithElevation from "$lib/components/trail/map_with_elevation.svelte";
import { trail } from "$lib/stores/trail_store";
+ import { currentUser } from "$lib/stores/user_store";
+ import {
+ formatDistance,
+ formatElevation,
+ formatTimeHHMM,
+ } from "$lib/util/format_util";
import {
calculatePixelPerMeter,
calculateScaleFactor,
@@ -16,14 +23,7 @@
import "leaflet/dist/leaflet.css";
import QrCodeWithLogo from "qrcode-with-logos";
import { onMount, tick } from "svelte";
- import { currentUser } from "$lib/stores/user_store";
- import {
- formatDistance,
- formatElevation,
- formatTimeHHMM,
- } from "$lib/util/format_util";
- import LogoTextLight from "$lib/components/logo/logo_text_light.svelte";
- import LogoText from "$lib/components/logo/logo_text.svelte";
+ import { _ } from "svelte-i18n";
let map: Map;
@@ -164,9 +164,13 @@
}
-
+
+ {$_("print")} | wanderer
+
+
+