Skip to content

Commit b1f849b

Browse files
committed
Improve LRR map symbology
Style splits with a round rect background to make visually distinct from leg numbers Make the low-zoom icon for stations pill shaped and include the line color for better cohesion Patch old LRR23 style to work with new splits layers
1 parent 067a66e commit b1f849b

10 files changed

+82
-61
lines changed
328 Bytes
Loading
328 Bytes
Loading
328 Bytes
Loading
327 Bytes
Loading
327 Bytes
Loading

js/LegCalculator.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,22 @@ export class LegCalculator extends HTMLElement {
104104
let distance = cumulativeDistances[rightValue] - cumulativeDistances[leftValue]
105105
let ascent = cumulativeAscents[rightValue] - cumulativeAscents[leftValue]
106106
let descent = cumulativeDescents[rightValue] - cumulativeDescents[leftValue]
107-
let legName = ""
107+
let segmentName = ""
108108
if (this._legToExchangeId.length > 0) {
109-
legName = `${exchangeInfo[this._legToExchangeId[leftValue]].name} to ${exchangeInfo[this._legToExchangeId[rightValue]].name}`
109+
segmentName = `${exchangeInfo[this._legToExchangeId[leftValue]].name} to ${exchangeInfo[this._legToExchangeId[rightValue]].name}`
110110
}
111111

112112
// "values" has the "to" function from "format" applied
113113
// "unencoded" contains the raw numerical slider values
114-
let legDesc = `<div class="d-flex flex-column flex-lg-row justify-content-between align-items-baseline"><h5>${legName}</h5><h6>${distance.toFixed(2)}mi ↑${ascent.toFixed(0)}ft ↓${descent.toFixed(0)}ft</h6></div>`
115-
container.querySelector("#leg-calculator-description").innerHTML = legDesc
114+
let segmentDesc = `
115+
<div class="d-flex flex-column flex-lg-row justify-content-between align-items-baseline">
116+
<h5>${segmentName}</h5>
117+
<div class="d-flex flex-column text-lg-end flex-shrink-0 mb-1">
118+
<h6 class="mb-0">${distance.toFixed(2)}mi ↑${ascent.toFixed(0)}ft ↓${descent.toFixed(0)}ft</h6>
119+
<div class="text-secondary">${rightValue - leftValue} legs (${leftValue + 1} through ${rightValue})</div>
120+
</div>
121+
</div>`
122+
container.querySelector("#leg-calculator-description").innerHTML = segmentDesc
116123
});
117124

118125
let profile = container.querySelector("elevation-profile")

js/RelayMap.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,42 @@ export class RelayMap extends LitElement {
155155
return;
156156
}
157157
this.map.addImage(`${code}stationcode`, image.data, { pixelRatio: 4 });
158+
})
159+
this.map.loadImage(`${this.imgBasePath}${code}_station_code_vertical_dark_small.png`).then((image) => {
160+
if (!image || !image.data) {
161+
console.warn(`Image for ${code} not found or invalid.`);
162+
return;
163+
}
164+
this.map.addImage(`${code}stationcodesmall`, image.data, { pixelRatio: 1 });
158165

159166
})
160167
} catch (e) {
161168
console.warn(`Failed to load station code image for ${code}:`, e);
162169
}
163170
}
171+
// Generate a roundrect texture
172+
const canvas = document.createElement('canvas');
173+
canvas.width = 36;
174+
canvas.height = 24;
175+
const radius = 4;
176+
const padding = 12;
177+
const ctx = canvas.getContext('2d');
178+
ctx.fillStyle = '#ffffff';
179+
ctx.beginPath();
180+
ctx.roundRect(0, 0, canvas.width, canvas.height, radius);
181+
ctx.fill();
182+
this.map.addImage('roundrect', {
183+
width: canvas.width,
184+
height: canvas.height,
185+
data: ctx.getImageData(0, 0, canvas.width, canvas.height).data,
186+
stretchX: [radius + 1, canvas.width - radius - 1],
187+
stretchY: [radius + 1, canvas.height - radius - 1],
188+
content: [radius + 1 + padding, radius + 1 + padding, canvas.width - radius - 1 - padding, canvas.height - radius - 1 - padding],
189+
pixelRatio: 1,
190+
sdf: true
191+
});
192+
193+
164194
}
165195
}
166196

maps/lrr23-map-style.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,16 @@
215215
"promoteId": "id",
216216
"data": {}
217217
},
218+
"leg-splits": {
219+
"type": "geojson",
220+
"promoteId": "id",
221+
"data": {}
222+
},
223+
"overall-splits": {
224+
"type": "geojson",
225+
"promoteId": "id",
226+
"data": {}
227+
},
218228
"exchanges": {
219229
"type": "geojson",
220230
"promoteId": "id",

maps/lrr24-map-style.json

Lines changed: 29 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3163,21 +3163,24 @@
31633163
"minzoom": 13,
31643164
"layout": {
31653165
"text-field": ["to-string", ["get", "distance"]],
3166-
"text-font": ["Noto Sans Regular"],
3166+
"text-font": ["Noto Sans Bold"],
31673167
"text-size": {
31683168
"stops": [
31693169
[9, 8],
3170-
[10, 10],
3171-
[16, 18]
3170+
[10, 8],
3171+
[16, 16]
31723172
]
31733173
},
31743174
"text-padding": 4,
3175-
"text-justify": "center"
3175+
"text-justify": "center",
3176+
"icon-image": "roundrect",
3177+
"icon-text-fit": "both",
3178+
3179+
"icon-text-fit-padding": [2, 2, 2, 2]
31763180
},
31773181
"paint": {
3178-
"text-color": "#FFF",
3179-
"text-halo-color": "rgba(0, 0, 0, 0.6)",
3180-
"text-halo-width": 2
3182+
"text-color": "#000",
3183+
"icon-opacity": 0.75
31813184
}
31823185
},
31833186
{
@@ -3195,22 +3198,25 @@
31953198
],
31963199
"minzoom": 13,
31973200
"layout": {
3198-
"text-field": ["to-string", ["get", "distance"]],
3199-
"text-font": ["Noto Sans Regular"],
3201+
"text-field": ["to-string", ["get", "distance"]],
3202+
"text-font": ["Noto Sans Bold"],
32003203
"text-size": {
32013204
"stops": [
32023205
[9, 8],
3203-
[10, 10],
3204-
[16, 18]
3206+
[10, 8],
3207+
[16, 16]
32053208
]
32063209
},
32073210
"text-padding": 4,
3208-
"text-justify": "center"
3211+
"text-justify": "center",
3212+
"icon-image": "roundrect",
3213+
"icon-text-fit": "both",
3214+
3215+
"icon-text-fit-padding": [2, 2, 2, 2]
32093216
},
32103217
"paint": {
3211-
"text-color": "#FFF",
3212-
"text-halo-color": "rgba(0, 0, 0, 0.6)",
3213-
"text-halo-width": 2
3218+
"text-color": "#000",
3219+
"icon-opacity": 0.75
32143220
}
32153221
},
32163222
{
@@ -3392,55 +3398,23 @@
33923398
},
33933399
{
33943400
"id": "exchange-circle-current",
3395-
"type": "circle",
3401+
"type": "symbol",
33963402
"source": "exchanges",
33973403
"filter": ["!=", ["get", "future"], true],
3398-
"paint": {
3399-
"circle-radius": {
3400-
"stops": [
3401-
[6, 1.5],
3402-
[9, 3],
3403-
[12, 6]
3404-
]
3405-
},
3406-
"circle-color": "#000",
3407-
"circle-opacity": 1.0,
3408-
"circle-stroke-opacity": 1.0,
3409-
"circle-stroke-color": "#AAA",
3410-
"circle-stroke-width": {
3411-
"stops": [
3412-
[6, 0.5],
3413-
[9, 0.5],
3414-
[12, 1]
3415-
]
3416-
}
3404+
"layout": {
3405+
"icon-image": ["concat", ["slice", ["to-string", ["get", "id"]], 0, 1], "stationcodesmall"]
34173406
}
34183407
},
34193408
{
34203409
"id": "exchange-circle-future",
3421-
"type": "circle",
3410+
"type": "symbol",
34223411
"source": "exchanges",
34233412
"filter": ["==", ["get", "future"], true],
34243413
"maxzoom": 15,
3425-
"paint": {
3426-
"circle-radius": {
3427-
"stops": [
3428-
[6, 1.5],
3429-
[9, 3],
3430-
[12, 6]
3431-
]
3432-
},
3433-
"circle-color": "#000",
3434-
"circle-opacity": 0.3,
3435-
"circle-stroke-opacity": 0.3,
3436-
"circle-stroke-color": "#AAA",
3437-
"circle-stroke-width": {
3438-
"stops": [
3439-
[6, 0.5],
3440-
[9, 0.5],
3441-
[12, 1]
3442-
]
3443-
}
3414+
"layout": {
3415+
"icon-image": ["concat", ["slice", ["to-string", ["get", "id"]], 0, 1], "stationcodesmall"]
3416+
}, "paint": {
3417+
"icon-opacity": 0.25
34443418
}
34453419
},
34463420
{

pages/light-rail-relay-25.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,7 +668,7 @@
668668
.link-station-label.link-station-label-dark {
669669
color: white;
670670
background-color: rgba(0, 0, 0, 0.85);
671-
border: 1px solid #CCC;
671+
border: 1px solid rgba(255,255,255,0.4);
672672

673673
}
674674
.link-station-label .line-name {
@@ -961,7 +961,7 @@ <h5>Small teams (4-10 runners)</h5>
961961
<h5>Large teams (>10 runners)</h5>
962962
<p>Our experience with a team of 20+ and multiple runners assigned to each leg is that a shared schedule spreadsheet helps a lot. You can see RCR's from <a href="https://docs.google.com/spreadsheets/d/1rd9Si3BcPgqt3fWxoHnuUB0rnN00XLtziMaHSPpQt14/edit#gid=0">2022</a> and <a href="https://docs.google.com/spreadsheets/d/1f6813y3qSEZf9UtAaosDixreD4fjyMbx-jMlCBcRQjc/edit?usp=sharing">2023</a> as examples. If you're planning to participate in this "club run" format, we'll provide a recommended schedule based on your runners' preferences, but it's up to the team captain (person who added the team) to finalize and distribute assignments.</p>
963963
<h5>Solo runners</h5>
964-
<p>It's possible to run the ~60k route unsupported. Otherwise, there are many shops along the way for supplies (zoom into the map to see data from OpenStreetMap). Here are some within 100ft of the route:</p>
964+
<p>It's possible to run the ~58k route unsupported. Otherwise, there are many shops along the way for supplies (zoom into the map to see data from OpenStreetMap). Here are some within 100ft of the route:</p>
965965
<ul>
966966
<li><b>Mile 0:</b> All Star Grocery, Chevron ExtraMile</li>
967967
<li><b>Mile 6.4:</b> Chevron Food Mart</li>

0 commit comments

Comments
 (0)