Picker map: smaller labels, darker roads; location label coords→place (#27)
* Picker map: smaller city labels, darker/bolder roads (split tile layers) Split the CARTO Voyager basemap into two raster layers so label size and road weight are independent: a labels-free base upscaled via tileSize 512 + zoomOffset -1 (bold, prominent roads) plus a labels-only layer at natural size on top (small, crisp city names). The darken/saturate filter now targets the base layer only (.mp-base: brightness .92, contrast 1.12), deepening the roads while leaving label text at full contrast. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B3Q2EkHHnTUX2BfhV5q1Zc * Location label: show coordinates immediately, then resolve to place name On selecting a location, write the raw coordinates to the location label right away, so the user sees the picked spot instantly instead of a stale/blank label. The existing post-fetch render already overwrites it with the reverse-geocoded "neighborhood, city, region" string (data.place), so the label now reads coords → place name live. - app.js / calendar.js / day.js: set coords in the selection handler before the fetch; the render/initOnce overwrite is unchanged. - compare.js: show coordinates through the pending + loading states (instead of "Locating…") so each chip's coords are replaced live by the place name once scored. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B3Q2EkHHnTUX2BfhV5q1Zc --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
20a4108397
commit
052b0a3e26
6 changed files with 40 additions and 13 deletions
|
|
@ -25,6 +25,10 @@ todayBtn.addEventListener("click", () => {
|
|||
|
||||
function selectLocation(lat, lon) {
|
||||
selected = { lat, lon };
|
||||
// Show the raw coordinates immediately; render() replaces them with the resolved
|
||||
// neighborhood + city name once the grade fetch returns.
|
||||
locLabel.textContent = `${lat.toFixed(3)}, ${lon.toFixed(3)}`;
|
||||
locLabel.hidden = false;
|
||||
runGrade();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -438,6 +438,10 @@ function selectLocation(lat, lon) {
|
|||
selected = { lat, lon };
|
||||
history.replaceState(null, "", `#lat=${lat.toFixed(5)}&lon=${lon.toFixed(5)}`);
|
||||
window.Thermograph.saveLastLocation(lat, lon); // keep date for the other views
|
||||
// Show the raw coordinates immediately; they're replaced with the resolved
|
||||
// neighborhood + city name once the first calendar chunk lands.
|
||||
locLabel.textContent = `${lat.toFixed(3)}, ${lon.toFixed(3)}`;
|
||||
locLabel.hidden = false;
|
||||
fetchCalendar();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,9 +250,13 @@ const deg = (v) => `${Math.round(v)}°`;
|
|||
function renderLocList() {
|
||||
locList.innerHTML = locations.map((l, i) => {
|
||||
let label, cls = "cmp-chip";
|
||||
if (l.loading) { label = "Locating…"; cls += " loading"; }
|
||||
// Show the raw coordinates while pending/loading (with the loading class still
|
||||
// driving the spinner); once scored, l.name holds the resolved neighborhood +
|
||||
// city, so the coordinates are replaced live by the place name.
|
||||
const coords = `${l.lat.toFixed(2)}, ${l.lon.toFixed(2)}`;
|
||||
if (l.loading) { label = l.name || coords; cls += " loading"; }
|
||||
else if (l.error) { label = "Couldn't load"; cls += " error"; }
|
||||
else if (!l.series) { label = l.name || `${l.lat.toFixed(2)}, ${l.lon.toFixed(2)}`; cls += " pending"; }
|
||||
else if (!l.series) { label = l.name || coords; cls += " pending"; }
|
||||
else { label = l.name; }
|
||||
return `<li class="${cls}"><span class="cmp-chip-name">${label}</span>` +
|
||||
`<button type="button" class="cmp-chip-x" data-i="${i}" aria-label="Remove ${label}">×</button></li>`;
|
||||
|
|
|
|||
|
|
@ -75,7 +75,14 @@ const findBtn = document.getElementById("find-btn");
|
|||
const locLabel = document.getElementById("loc-label");
|
||||
findBtn.innerHTML = `${window.LocationPicker.PIN_ICON} <span>Find a location</span>`;
|
||||
findBtn.addEventListener("click", () => {
|
||||
window.LocationPicker.open(selected, (lat, lon) => { selected = { lat, lon }; fetchDay(); });
|
||||
window.LocationPicker.open(selected, (lat, lon) => {
|
||||
selected = { lat, lon };
|
||||
// Show the raw coordinates immediately; render() replaces them with the
|
||||
// resolved neighborhood + city name once the day fetch returns.
|
||||
locLabel.textContent = `${lat.toFixed(3)}, ${lon.toFixed(3)}`;
|
||||
locLabel.hidden = false;
|
||||
fetchDay();
|
||||
});
|
||||
});
|
||||
|
||||
// ---- date navigation ----
|
||||
|
|
|
|||
|
|
@ -118,15 +118,22 @@
|
|||
|
||||
if (!map) {
|
||||
map = L.map(mapEl, { worldCopyJump: true, zoomControl: true }).setView([44.5, -95], 4);
|
||||
// Colorful CARTO "Voyager" basemap (no key needed) instead of the plain gray
|
||||
// OSM raster — used in both themes for its richer road/land/water colors.
|
||||
// Requesting tiles one zoom level lower and rendering them at 512px
|
||||
// (tileSize 512 + zoomOffset -1) makes roads and city labels noticeably
|
||||
// larger; @2x keeps them crisp while enlarged. A saturation boost (style.css)
|
||||
// pushes the colors further.
|
||||
L.tileLayer("https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}@2x.png", {
|
||||
// Colorful CARTO "Voyager" basemap (no key needed), split into two raster
|
||||
// layers so road weight and label size can be tuned independently:
|
||||
// • the label-free base is requested one zoom lower and drawn at 512px
|
||||
// (tileSize 512 + zoomOffset -1) so roads read bold and prominent;
|
||||
// • the labels-only layer is drawn on top at its natural size, keeping city
|
||||
// names small and crisp rather than scaled up with the roads.
|
||||
// @2x keeps both sharp; a darken/saturate filter (style.css, .mp-base only)
|
||||
// deepens the roads while leaving the label text at full contrast.
|
||||
const CARTO = "https://{s}.basemaps.cartocdn.com/rastertiles";
|
||||
const ATTRIB = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> © <a href="https://carto.com/attributions">CARTO</a>';
|
||||
L.tileLayer(`${CARTO}/voyager_nolabels/{z}/{x}/{y}@2x.png`, {
|
||||
subdomains: "abcd", maxZoom: 20, tileSize: 512, zoomOffset: -1,
|
||||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> © <a href="https://carto.com/attributions">CARTO</a>',
|
||||
className: "mp-base", attribution: ATTRIB,
|
||||
}).addTo(map);
|
||||
L.tileLayer(`${CARTO}/voyager_only_labels/{z}/{x}/{y}@2x.png`, {
|
||||
subdomains: "abcd", maxZoom: 20, className: "mp-labels",
|
||||
}).addTo(map);
|
||||
// Branded accent teardrop pin (the same glyph the Find button uses), styled
|
||||
// in style.css — replaces Leaflet's default blue raster marker.
|
||||
|
|
|
|||
|
|
@ -706,8 +706,9 @@ main { max-width: 1200px; margin: 0 auto; padding: 20px 24px 60px; }
|
|||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .25), 0 6px 18px rgba(0, 0, 0, .25);
|
||||
}
|
||||
.mp-map .leaflet-container { background: var(--surface-2); }
|
||||
/* Push the CARTO Voyager colors further — bolder roads, greener parks, bluer water. */
|
||||
.mp-map .leaflet-tile-pane { filter: saturate(1.35) contrast(1.05); }
|
||||
/* Base map only (roads/land/water): deepen the roads and push saturation. The
|
||||
labels layer (.mp-labels) is left unfiltered so city names keep full contrast. */
|
||||
.mp-map .mp-base { filter: saturate(1.3) contrast(1.12) brightness(0.92); }
|
||||
/* Branded accent teardrop pin (an L.divIcon wrapping the Find-button glyph),
|
||||
replacing Leaflet's default blue raster marker. */
|
||||
.mp-pin { background: none; border: none; filter: drop-shadow(0 3px 4px rgba(0, 0, 0, .45)); }
|
||||
|
|
|
|||
Loading…
Reference in a new issue