Skip to content

Commit 2d81a65

Browse files
committed
Github pages
1 parent f940181 commit 2d81a65

3 files changed

Lines changed: 94 additions & 66 deletions

File tree

.github/workflows/deploy-github-pages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ name: Deploy GitHub Pages
44

55
on:
66
push:
7-
branches: [main, master]
7+
branches: [main]
88
workflow_dispatch:
99

1010
permissions:

app.js

Lines changed: 83 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434
* See EXPORT_PDF_ZOOM_TABLE_STRICT if z is below extent-fit.
3535
*/
3636
const EXPORT_PDF_ZOOM_BY_SCALE_DEN = {
37-
5000: 18,
38-
10000: 17,
37+
5000: 17,
38+
10000: 16,
3939
15000: 16,
4040
25000: 15,
4141
50000: 14,
@@ -254,8 +254,8 @@
254254
const scaleEl = document.getElementById("scale-den");
255255
const scaleDen = scaleEl ? Number(scaleEl.value) : 25000;
256256
const dpi = EXPORT_RASTER_DPI;
257-
const magEl = document.getElementById("pdf-magnetic-north");
258-
const magneticNorthUp = !!(magEl && magEl.checked);
257+
/** PDF magnetic export hidden: georef vs rotation still wrong; re-enable when fixed. */
258+
const magneticNorthUp = false;
259259
return { paper, orient, scaleDen, dpi, magneticNorthUp };
260260
}
261261

@@ -558,43 +558,55 @@
558558
}
559559

560560
/**
561-
* Corners of the centre-cropped page in pre-crop canvas pixels → lat/lng via inverse of CSS rotate(-dec)
562-
* on the print map (same φ as boundsCornersRotatedScreen).
561+
* Map outer html2canvas pixel (origin top-left of rotated outer) → lat/lng (inverse CSS rotate(-dec)).
563562
*
564563
* @param {L.Map} printMap
565564
* @param {number} decDeg east-positive declination
566-
* @param {number} W crop width / inner map px
567-
* @param {number} H crop height
568-
* @param {number} canvasW html2canvas width before centre crop
569-
* @param {number} canvasH
570-
* @param {number} sx crop left (centred)
571-
* @param {number} sy crop top
572-
* @returns {number[]} GPTS length 8
565+
* @param {number} W inner map CSS px width
566+
* @param {number} H inner map CSS px height
567+
* @param {number} canvasW pre-crop canvas width
568+
* @param {number} canvasH pre-crop canvas height
569+
* @param {number} px
570+
* @param {number} py
571+
* @param {number} ps pixel scale (html2canvas scale)
573572
*/
574-
function gptsFromMagneticCentreCrop(printMap, decDeg, W, H, canvasW, canvasH, sx, sy, pixelScale) {
575-
const ps = pixelScale && pixelScale > 0 ? pixelScale : 1;
573+
function magneticOuterPxToLatLng(printMap, decDeg, W, H, canvasW, canvasH, px, py, ps) {
576574
const Ox = canvasW / 2;
577575
const Oy = canvasH / 2;
578576
const phi = (-decDeg * Math.PI) / 180;
579577
const cos = Math.cos(phi);
580578
const sin = Math.sin(phi);
579+
const rxo = px - Ox;
580+
const ryo = py - Oy;
581+
const dx = rxo * cos - ryo * sin;
582+
const dy = rxo * sin + ryo * cos;
583+
const lx = W / 2 + dx / ps;
584+
const ly = H / 2 + dy / ps;
585+
return printMap.containerPointToLatLng(L.point(lx, ly));
586+
}
581587

582-
function pxToLatLng(px, py) {
583-
const rxo = px - Ox;
584-
const ryo = py - Oy;
585-
const dx = rxo * cos - ryo * sin;
586-
const dy = rxo * sin + ryo * cos;
587-
const lx = W / 2 + dx / ps;
588-
const ly = H / 2 + dy / ps;
589-
return printMap.containerPointToLatLng(L.point(lx, ly));
588+
/**
589+
* @param {L.Map} printMap
590+
* @param {number} decDeg
591+
* @param {number} W
592+
* @param {number} H
593+
* @param {number} canvasW
594+
* @param {number} canvasH
595+
* @param {number} sx
596+
* @param {number} sy
597+
* @param {number} sw
598+
* @param {number} sh
599+
* @param {number} ps
600+
* @returns {number[]}
601+
*/
602+
function gptsFromMagneticCropRect(printMap, decDeg, W, H, canvasW, canvasH, sx, sy, sw, sh, ps) {
603+
function p2ll(px, py) {
604+
return magneticOuterPxToLatLng(printMap, decDeg, W, H, canvasW, canvasH, px, py, ps);
590605
}
591-
592-
const cw = W * ps;
593-
const ch = H * ps;
594-
const swLL = pxToLatLng(sx, sy + ch);
595-
const nwLL = pxToLatLng(sx, sy);
596-
const neLL = pxToLatLng(sx + cw, sy);
597-
const seLL = pxToLatLng(sx + cw, sy + ch);
606+
const swLL = p2ll(sx, sy + sh);
607+
const nwLL = p2ll(sx, sy);
608+
const neLL = p2ll(sx + sw, sy);
609+
const seLL = p2ll(sx + sw, sy + sh);
598610
return [swLL.lat, swLL.lng, nwLL.lat, nwLL.lng, neLL.lat, neLL.lng, seLL.lat, seLL.lng];
599611
}
600612

@@ -1133,15 +1145,16 @@
11331145
const maxNativeZoom = zoomFromTableUsed
11341146
? zDisplay
11351147
: Math.min(maxZoom, Math.max(minZoom, zDisplay - EXPORT_PDF_TILE_LEVELS_COARSER));
1136-
const layer = L.tileLayer(url, {
1137-
bounds: bounds,
1148+
const layerOpts = {
11381149
minZoom,
11391150
maxZoom,
11401151
maxNativeZoom,
11411152
tms,
11421153
attribution: "Tiles",
11431154
...TILE_LAYER_OPTIONS,
1144-
});
1155+
};
1156+
if (!doCrop) layerOpts.bounds = bounds;
1157+
const layer = L.tileLayer(url, layerOpts);
11451158

11461159
setExportStatus("Loading map tiles for PDF…");
11471160
await new Promise(function (resolve) {
@@ -1224,6 +1237,9 @@
12241237
* fitBounds keeps the whole LatLngBounds visible; Mercator vs container aspect often letterboxes,
12251238
* so getBounds() is larger than `bounds` and the raster would show extra map (wrong 1:scale vs orange extent).
12261239
*/
1240+
/** @type {{ sx: number; sy: number; sw: number; sh: number; preW: number; preH: number } | null} */
1241+
let magneticCropOnOuter = null;
1242+
12271243
if (!doCrop) {
12281244
const aabb = exportBoundsContainerPxAabb(printMap, bounds);
12291245
const loose = 1.5;
@@ -1245,41 +1261,50 @@
12451261
}
12461262
}
12471263
}
1248-
}
1249-
1250-
const sW = Math.round(W * h2cScale);
1251-
const sH = Math.round(H * h2cScale);
1252-
let sxCrop = 0;
1253-
let syCrop = 0;
1254-
if (doCrop && canvas.width >= sW && canvas.height >= sH) {
1255-
sxCrop = Math.round((canvas.width - sW) / 2);
1256-
syCrop = Math.round((canvas.height - sH) / 2);
1264+
} else if (declUsed !== null && Math.abs(declUsed) > 0.001) {
1265+
const aabb = exportBoundsContainerPxAabb(printMap, bounds);
1266+
const padL = (outerW - W) / 2;
1267+
const padT = (outerH - H) / 2;
1268+
const s = h2cScale;
1269+
let sxB = Math.floor((aabb.minX + padL) * s);
1270+
let syB = Math.floor((aabb.minY + padT) * s);
1271+
let swB = Math.max(1, Math.ceil(aabb.w * s));
1272+
let shB = Math.max(1, Math.ceil(aabb.h * s));
1273+
sxB = Math.max(0, Math.min(sxB, canvas.width - 2));
1274+
syB = Math.max(0, Math.min(syB, canvas.height - 2));
1275+
swB = Math.min(swB, canvas.width - sxB);
1276+
shB = Math.min(shB, canvas.height - syB);
1277+
if (swB > 4 && shB > 4) {
1278+
magneticCropOnOuter = { sx: sxB, sy: syB, sw: swB, sh: shB, preW: canvas.width, preH: canvas.height };
1279+
const cMag = document.createElement("canvas");
1280+
cMag.width = swB;
1281+
cMag.height = shB;
1282+
const ctxM = cMag.getContext("2d");
1283+
if (ctxM) {
1284+
ctxM.drawImage(canvas, sxB, syB, swB, shB, 0, 0, swB, shB);
1285+
canvas = cMag;
1286+
}
1287+
}
12571288
}
12581289

12591290
let gptsForEmbed = gptsFromBoundsBox(bounds);
1260-
if (doCrop && declUsed !== null && Math.abs(declUsed) > 0.001 && canvas.width >= sW && canvas.height >= sH) {
1261-
gptsForEmbed = gptsFromMagneticCentreCrop(
1291+
if (magneticCropOnOuter && declUsed !== null && Math.abs(declUsed) > 0.001) {
1292+
const m = magneticCropOnOuter;
1293+
gptsForEmbed = gptsFromMagneticCropRect(
12621294
printMap,
12631295
declUsed,
12641296
W,
12651297
H,
1266-
canvas.width,
1267-
canvas.height,
1268-
sxCrop,
1269-
syCrop,
1298+
m.preW,
1299+
m.preH,
1300+
m.sx,
1301+
m.sy,
1302+
m.sw,
1303+
m.sh,
12701304
h2cScale,
12711305
);
12721306
}
12731307

1274-
if (doCrop && canvas.width >= sW && canvas.height >= sH) {
1275-
const c2 = document.createElement("canvas");
1276-
c2.width = sW;
1277-
c2.height = sH;
1278-
const ctx2 = c2.getContext("2d");
1279-
if (ctx2) ctx2.drawImage(canvas, sxCrop, syCrop, sW, sH, 0, 0, sW, sH);
1280-
canvas = c2;
1281-
}
1282-
12831308
const prePdfEmbedW = canvas.width;
12841309
const prePdfEmbedH = canvas.height;
12851310
canvas = clampCanvasLongEdgeForJsPdf(canvas, EXPORT_JSPDF_MAX_IMAGE_LONG_EDGE_PX);
@@ -1406,6 +1431,7 @@
14061431

14071432
const pdfMag = document.getElementById("pdf-magnetic-north");
14081433
if (pdfMag) {
1434+
pdfMag.checked = false;
14091435
const onPdfMagnetic = function () {
14101436
if (exportOutline && exportBounds) refreshExportOutline();
14111437
};

index.html

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,15 @@ <h3 id="export-sidebar-title" class="export-panel-heading">Export settings</h3>
8282
<option value="250000">1 : 250 000</option>
8383
</select>
8484
</label>
85-
<label class="check">
86-
<input type="checkbox" id="pdf-magnetic-north" />
87-
<span>Orient PDF to magnetic north (WMM2020)</span>
88-
</label>
89-
<p class="hint export-hint">
90-
Rotates the export so <strong>page top ≈ magnetic north</strong>.
91-
</p>
85+
<div id="pdf-magnetic-export-wrap" class="export-magnetic-pdf" hidden aria-hidden="true">
86+
<label class="check">
87+
<input type="checkbox" id="pdf-magnetic-north" />
88+
<span>Orient PDF to magnetic north (WMM2020)</span>
89+
</label>
90+
<p class="hint export-hint">
91+
Rotates the export so <strong>page top ≈ magnetic north</strong>.
92+
</p>
93+
</div>
9294
<div class="export-actions">
9395
<button type="button" class="btn ghost" id="export-cancel">Cancel</button>
9496
<button type="button" class="btn primary" id="export-pdf">Download PDF</button>
@@ -123,6 +125,6 @@ <h3 id="export-sidebar-title" class="export-panel-heading">Export settings</h3>
123125
<script src="https://unpkg.com/proj4@2.11.0/dist/proj4.js" crossorigin=""></script>
124126
<script src="./vendor/geomag.js"></script>
125127
<!-- Bump ?v= when app.js changes so browsers don’t keep an old cached copy -->
126-
<script src="./app.js?v=20260502m"></script>
128+
<script src="./app.js?v=20260502o"></script>
127129
</body>
128130
</html>

0 commit comments

Comments
 (0)