Skip to content

Commit dab9d28

Browse files
Added experimental custom map boundaries
1 parent 1c0cb77 commit dab9d28

File tree

3 files changed

+108
-34
lines changed

3 files changed

+108
-34
lines changed

index.html

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,20 @@ <h3>Stage</h3>
249249
Upload custom map:</label>
250250
<input type="file" id="custom-map-upload" accept="image/*">
251251
</div>
252+
<div>
253+
<input type="checkbox" id="enable-custom-bounds" /><label for="enable-custom-bounds"
254+
title="[EXPERIMENTAL] Define custom map boundaries instead of auto-cropping.">Use custom map boundaries</label>
255+
</div>
256+
<div id="custom-bounds-inputs" class="hidden">
257+
<div>
258+
<label for="min-lat">Min lat:</label><input type="number" id="min-lat" step="any" min="-90" max="90">
259+
<label for="max-lat">Max lat:</label><input type="number" id="max-lat" step="any" min="-90" max="90">
260+
</div>
261+
<div>
262+
<label for="min-lng">Min lng:</label><input type="number" id="min-lng" step="any" min="-180" max="180">
263+
<label for="max-lng">Max lng:</label><input type="number" id="max-lng" step="any" min="-180" max="180">
264+
</div>
265+
</div>
252266
</fieldset>
253267
<fieldset id="custom-scale-section">
254268
<legend>Scale settings</legend>

static/css/style.css

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,35 @@ ion-icon+span {
494494
margin-right: 0.4em;
495495
}
496496

497+
#custom-bounds-inputs {
498+
display: flex;
499+
flex-direction: column;
500+
gap: 0.5rem;
501+
margin-top: 0.5rem;
502+
padding: 0.5rem;
503+
background-color: rgba(0, 0, 0, 0.05);
504+
border-radius: 0.25rem;
505+
}
506+
507+
#custom-bounds-inputs>div {
508+
display: flex;
509+
gap: 0.5rem;
510+
align-items: center;
511+
}
512+
513+
#custom-bounds-inputs label {
514+
font-size: 0.9em;
515+
flex-shrink: 0;
516+
}
517+
518+
#custom-bounds-inputs input[type="number"] {
519+
width: 100%;
520+
padding: 5px;
521+
border: 1px solid #ccc;
522+
border-radius: .25rem;
523+
font-family: 'Roboto Mono', monospace;
524+
}
525+
497526
#options-container fieldset label {
498527
padding-left: 0.25em;
499528
padding-right: 0.1em;

static/js/generate.js

Lines changed: 65 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ document.addEventListener("DOMContentLoaded", () => {
251251
updateScaleSelector();
252252
showScaleEditor(name);
253253
});
254+
255+
const customBoundsCheckbox = document.getElementById("enable-custom-bounds");
256+
const customBoundsInputs = document.getElementById("custom-bounds-inputs");
257+
if (customBoundsCheckbox && customBoundsInputs) {
258+
customBoundsCheckbox.addEventListener("change", (e) => {
259+
customBoundsInputs.classList.toggle("hidden", !e.target.checked);
260+
});
261+
}
254262
});
255263

256264
class MapManager {
@@ -633,6 +641,8 @@ function createMap(data, accessible) {
633641
const imageContainer = elements.imageContainer;
634642
const smallerDotsCheckbox = document.getElementById("smaller-dots");
635643

644+
const useCustomBounds = document.getElementById("enable-custom-bounds")?.checked;
645+
636646
const computeAceCheckbox = document.getElementById("compute-ace");
637647
const shouldComputeAce = computeAceCheckbox ? computeAceCheckbox.checked : true;
638648
const acePanel = document.getElementById("ace-results");
@@ -713,45 +723,66 @@ function createMap(data, accessible) {
713723
westernmostLng -= 360; // adjust back if westernmost was shifted
714724
}
715725

716-
const centerLng = normalizeLongitude((easternmostLng + westernmostLng) / 2);
717-
const centerX = (centerLng + 180) / 360 * FULL_WIDTH;
718-
719-
const halfLngDist = Math.max(
720-
Math.abs(normalizeLongitude(easternmostLng - centerLng)),
721-
Math.abs(normalizeLongitude(westernmostLng - centerLng))
722-
) * FULL_WIDTH / 360;
723-
const paddingLng = (FULL_WIDTH * 5) / 360;
724-
let left = centerX - halfLngDist - paddingLng;
725-
let right = centerX + halfLngDist + paddingLng;
726-
727-
let top = minLat - (FULL_HEIGHT * 5) / 180;
728-
let bottom = maxLat + (FULL_HEIGHT * 5) / 180;
729-
730-
let width = right - left;
731-
let height = bottom - top;
732-
733-
const minWidth = (FULL_HEIGHT * 45) / 180;
734-
if (width < minWidth) {
735-
const padding = (minWidth - width) / 2;
736-
left -= padding;
737-
right += padding;
738-
width = right - left;
739-
}
726+
let left, right, top, bottom;
727+
728+
if (useCustomBounds) {
729+
const minLatInput = parseFloat(document.getElementById("min-lat").value);
730+
const maxLatInput = parseFloat(document.getElementById("max-lat").value);
731+
const minLngInput = parseFloat(document.getElementById("min-lng").value);
732+
const maxLngInput = parseFloat(document.getElementById("max-lng").value);
740733

741-
if (width < height) {
742-
const padding = (height - width) / 2;
743-
left -= padding;
744-
right += padding;
745-
width = right - left;
734+
if (!isNaN(minLatInput) && !isNaN(maxLatInput) && !isNaN(minLngInput) && !isNaN(maxLngInput)) {
735+
top = FULL_HEIGHT / 2 - (maxLatInput * FULL_HEIGHT / 180);
736+
bottom = FULL_HEIGHT / 2 - (minLatInput * FULL_HEIGHT / 180);
737+
left = (minLngInput + 180) / 360 * FULL_WIDTH;
738+
right = (maxLngInput + 180) / 360 * FULL_WIDTH;
739+
}
746740
}
741+
742+
if (left === undefined) { // fallback to auto-cropping if custom bounds are not set or invalid
743+
const centerLng = normalizeLongitude((easternmostLng + westernmostLng) / 2);
744+
const centerX = (centerLng + 180) / 360 * FULL_WIDTH;
745+
746+
const halfLngDist = Math.max(
747+
Math.abs(normalizeLongitude(easternmostLng - centerLng)),
748+
Math.abs(normalizeLongitude(westernmostLng - centerLng))
749+
) * FULL_WIDTH / 360;
750+
const paddingLng = (FULL_WIDTH * 5) / 360;
751+
left = centerX - halfLngDist - paddingLng;
752+
right = centerX + halfLngDist + paddingLng;
753+
754+
top = minLat - (FULL_HEIGHT * 5) / 180;
755+
bottom = maxLat + (FULL_HEIGHT * 5) / 180;
756+
757+
let width = right - left;
758+
let height = bottom - top;
759+
760+
const minWidth = (FULL_HEIGHT * 45) / 180;
761+
if (width < minWidth) {
762+
const padding = (minWidth - width) / 2;
763+
left -= padding;
764+
right += padding;
765+
width = right - left;
766+
}
767+
768+
if (width < height) {
769+
const padding = (height - width) / 2;
770+
left -= padding;
771+
right += padding;
772+
width = right - left;
773+
}
747774

748-
if (height < width / 1.618033988749894) {
749-
const padding = (width / 1.618033988749894 - height) / 2;
750-
top -= padding;
751-
bottom += padding;
752-
height = bottom - top;
775+
if (height < width / 1.618033988749894) {
776+
const padding = (width / 1.618033988749894 - height) / 2;
777+
top -= padding;
778+
bottom += padding;
779+
height = bottom - top;
780+
}
753781
}
754782

783+
const width = right - left;
784+
const height = bottom - top;
785+
755786
canvas.width = width;
756787
canvas.height = height;
757788

0 commit comments

Comments
 (0)