tag:tedpiotrowski.svbtle.com,2014:/feedTed Piotrowski2023-11-21T10:57:10-08:00Ted Piotrowskihttps://tedpiotrowski.svbtle.comSvbtle.comtag:tedpiotrowski.svbtle.com,2014:Post/epinepherine-red-rocks2023-11-21T10:57:10-08:002023-11-21T10:57:10-08:00Epinepherine - Red Rocks<p>Featuring: Stephen Michael Sherman</p>
<p><a href="https://svbtleusercontent.com/4KbxUzKUVbELZBUQwDDTtv0xspap.jpg"><img src="https://svbtleusercontent.com/4KbxUzKUVbELZBUQwDDTtv0xspap_small.jpg" alt="Looking up Epinepherine"></a></p>
<p><em>5:40am - Looking up Epinepherine from the base</em></p>
<p>It was the third day of our annual trip to Red Rocks and after a leisurely climb up <a href="https://www.mountainproject.com/route/105796219/algae-on-parade">Algae on Parade</a> Loni suggested that she take a rest day and Sherman and I should go do something “big” on Sunday. I think we both instantly thought about the Red Rocks classic <a href="https://www.mountainproject.com/route/105732422/epinephrine">Epinepherine</a> (currently number three on <a href="https://mountainproject.com">Mountain Project</a>’s Top 20 Classic Climbs).</p>
<p><a href="https://svbtleusercontent.com/baQVpwoPhBBdcoKRo5NeJB0xspap.jpeg"><img src="https://svbtleusercontent.com/baQVpwoPhBBdcoKRo5NeJB0xspap_small.jpeg" alt="Pitch 1 Ephinepherine"></a></p>
<p><em>5:54am - On our way, pitch 1</em></p>
<p>There were a few hurdles. It’s a long route (~1600’) and November 5th is not exactly the longest day of the year. People say it’s a tricky walk-off in the dark. The pitches average about 150’ so you can’t rappel it on a single 60 meter rope. I’d never lead 5.9 trad in Red Rocks or anywhere else as far as I could remember. We told some climbing friends at dinner and the general reaction was: “It’s a long route”, which I interpreted as, you’ll be climbing after dark.</p>
<p><a href="https://svbtleusercontent.com/77VkNtevqfX15H5kuowzH10xspap.jpeg"><img src="https://svbtleusercontent.com/77VkNtevqfX15H5kuowzH10xspap_small.jpeg" alt="Black Velvet canyon sunrise"></a></p>
<p><em>6:11am - Sunrise</em></p>
<p>The weather was going to be great (warm, no wind) and the climb is in the shade. Loni let us borrow her twin ropes so we had the option to rappel if things were going slow. I downloaded the SAR walk-off map onto my phone and packed a bivy in case things got interesting after dark. We decided to take a single Flash 22 pack so only the follower had to wear a pack through the chimneys. Food, 3 liters of water, a few warm layers, a Garmin InReach, Rocky Talkies and a double rack of gear + nuts + #4. We wore our harnesses on the approach (sans the leg loops) with all the quick draws attached.</p>
<p><a href="https://svbtleusercontent.com/gR3Tu8iYubLuPNhb6pL1Te0xspap.jpeg"><img src="https://svbtleusercontent.com/gR3Tu8iYubLuPNhb6pL1Te0xspap_small.jpeg" alt="Looking up last chimney pitck"></a></p>
<p><em>9:31am - Looking up last chimney pitch</em></p>
<p>We woke up at 3am, ate a quick breakfast, and drove the 30 minutes to Black Velvet canyon arriving at 4:30am. (One funny mishap that happened on the way out was that I opened the garage door while the hatch of the car was up and the two collided, breaking the automatic garage mechanism so we had to spend some time to fix that on a day when time was super precious.) The approach was straightforward up the dry creek, with one pretty obvious scramble on the left to get past a tall waterfall. No sign of other climbers. We were first in line.</p>
<p><a href="https://svbtleusercontent.com/c6AmSvN2EjSuVsb7HjyHzt0xspap.jpeg"><img src="https://svbtleusercontent.com/c6AmSvN2EjSuVsb7HjyHzt0xspap_small.jpeg" alt="Looking down last chimney pitch"></a></p>
<p><em>9:43am - Looking down last chimney pitch</em></p>
<p>The first pitch is 5.8 and I was feeling a bit nervous about my leading so I asked to go first. If this pitch felt hard, chances were slim I’d be much help on the cruxes higher up. The start looked very smooth but it was bolted and with the help of a tree, I was on my way up some decent crimps in no time. I finished the pitch and felt confident; the sky now full of color as the sun rose near the mouth of the canyon. As Stephen followed up I heard some distinct voices and instantly suspected that we’d have company on this popular classic.</p>
<p><a href="https://svbtleusercontent.com/pW9aw6CD9FVGiwKfxMixai0xspap.jpeg"><img src="https://svbtleusercontent.com/pW9aw6CD9FVGiwKfxMixai0xspap_small.jpeg" alt="Hanging belay Epinepherine"></a></p>
<p><em>12:40pm - Steve’s favorite belay station</em></p>
<p>The next pitch had some route finding and backtracking for Steve but he figured it all out just as the second party reached me at the first belay station. They were climbers from Switzerland and only got a late start because Daylight Savings Time had pushed clocks back the night before and the Swiss were not aware since Europe switched to DST a few weeks before. I followed up behind Steve and we were soon at the base of the three chimney pitches.</p>
<p><a href="https://svbtleusercontent.com/nvRLvE6CrH9J1WjK4tDqC80xspap.jpeg"><img src="https://svbtleusercontent.com/nvRLvE6CrH9J1WjK4tDqC80xspap_small.jpeg" alt="Epinepherine Whiskey Peak"></a></p>
<p><em>1:30pm - Whiskey Peak in the distance (can you spot the tiny climbers on our left?)</em></p>
<p>Because I opted to lead first, it meant I’d have to do two of the chimney pitches. Ooooof. The first one was labeled as the crux of the climb on our topo and I will admit I was pooping my pants a bit. I lost a bit of skin on my elbows and shoulders scooting up the tight walls and Stephen joked with the Swiss that I sounded like I was giving birth at times. I did have a 30 second breakdown while catching my breath where I thought, I want to go home. But then the crux turned out to protect really well with a #3 and I walked it up until I arrived at the belay.</p>
<p><a href="https://svbtleusercontent.com/dA4K3kyMJsV8SZthiLP4vG0xspap.jpeg"><img src="https://svbtleusercontent.com/dA4K3kyMJsV8SZthiLP4vG0xspap_small.jpeg" alt="Last hard pitch"></a></p>
<p><em>1:45pm - Steven on final hard pitch (10)</em></p>
<p>Stephen followed up with the pack hanging off his harness. I thought carrying the pack on follow felt worse than leading. His chimney technique was more graceful and I thought his chimney pitch was harder as we only had one #4 which he kept placing and recovering. The Swiss were now prying on our heels but declined to pass as they watched on. The final pitch of the chimney was the most vertical but the easiest. It has two bolts for protection and tiny ledges for your feet. You could almost wedge yourself in there well enough to take a nap. At the end of this pitch we had finished the crux of the route and stood atop of Black Tower. It was 10:45 am.</p>
<p><a href="https://svbtleusercontent.com/a8SJ9ravPucVDRUVDV2EEz0xspap.jpeg"><img src="https://svbtleusercontent.com/a8SJ9ravPucVDRUVDV2EEz0xspap_small.jpeg" alt="Epinepherine finish"></a></p>
<p><em>3:34pm - The Pine Tree, finish in sight</em></p>
<p>It felt good to get through the crux but the pitches above were long, vertical and exposed. The sun was scheduled to set at 4:45pm. We ate a quick snack and got back into it. The next six pitches were all quite similar in difficulty with good options for gear, but they were quite vertical. I didn’t say much for the next few hours as we were now 800’ above the canyon and I was busy hyping myself up in my head to go out for another lead. One reward of doing the first pitch is that Steve got stuck on the one hanging belay of the climb (was not planned). Pitch 9 was the last hard pitch for me and it was the longest, so got some good endorphins when I arrived at the bolts.</p>
<p><a href="https://svbtleusercontent.com/6Tn7NnrgVvmwYf1mYN626L0xspap.jpeg"><img src="https://svbtleusercontent.com/6Tn7NnrgVvmwYf1mYN626L0xspap_small.jpeg" alt="Epinepherine summit"></a></p>
<p><em>4:38pm - summit of Black Velvet wall</em></p>
<p>Things began to mellow from pitch 11 on-wards. Route finding and the race against sundown were now the main difficulties. Steve did more than his share speeding us along on the main climb and now he led as we tried to save time by simul-climbing with a whole rope length between us. This resulted in him feeling the drag of a truck so he belayed me up and now I simuled out first with only about 80 feet between us. The final few hundered feet were mellow and we arrived at the “Pine Tree” finish at 4pm. I looked over at Whiskey Peak below us and remembered looking over here in awe after my first multi-pitch follow in Red Rocks (<a href="https://www.mountainproject.com/route/105732899/bourbon-street">Bourbon Street</a>). Now we had done it!</p>
<p><a href="https://svbtleusercontent.com/gibjPGx1Ea5oP7Whhq5UMw0xspap.jpeg"><img src="https://svbtleusercontent.com/gibjPGx1Ea5oP7Whhq5UMw0xspap_small.jpeg" alt="Black Velvet night time descent"></a></p>
<p><em>5:45pm - Vegas lighting up the night</em></p>
<p>It was 45 minutes to sundown so we didn’t take much time to celebrate. We ate a quick snack, coiled the ropes, and glanced in the emergency stash as we started to speed walk along the descent route. There was cairns many places on the summit so the map we downloaded came through in the clutch. The sun was setting now and it was just that perfect combination of beauty and elation that sears itself forever in your memory.</p>
<p><a href="https://svbtleusercontent.com/sMNuouSjZ2RLPzVbJUt1eP0xspap.jpeg"><img src="https://svbtleusercontent.com/sMNuouSjZ2RLPzVbJUt1eP0xspap_small.jpeg" alt="Reunited with Oreos"></a></p>
<p><em>6:15pm - reunited with Oreos</em></p>
<p>The Swiss caught up and passed us on the descent. They didn’t seem irritated by any delays we had caused them en route. It turned out we were the only four to climb Epinepherine that day. Not bad for a Sunday. It was pitch dark when we merged onto the Whiskey Peak descent and my toes were hurting (and continued to hurt for a few more days) from being in climbing shoes all day. It made for a slow descent but we were at the car at 6:15pm and back home eating takeout (which Loni kindly offered to pickup) by 7pm.</p>
tag:tedpiotrowski.svbtle.com,2014:Post/sun-and-shadow-maps-models-vs-reality2023-11-17T08:44:06-08:002023-11-17T08:44:06-08:00Sun and Shadow Maps: Models vs Reality<p>During the Mapbox BUILD conference this week, something was said that gave me clarity on my vision for sun and shadow simulation. The speaker gave a demo of Mapbox GL JS v3 which includes 3D tree renderings. The speaker said that the trees were not accurate depictions because the purpose of maps is to convey information and not depict reality. The maps purpose is to let you know trees are there without specifying their height or type (oak, pine, cedar, birch, etc). Maps simplify how we represent the real world.</p>
<p><img src="https://assets-global.website-files.com/5f2a93fe880654a977c51043/64e61fccedf3262a53b87516_london%20eye%20dark%20-Mapbox%20Standard-2023-MKTG-approved.png"></p>
<p><em>Rendering of trees in London in Mapbox GL JS v3</em></p>
<p>In the same sense <a href="https://shademap.app">shademap.app</a> has been nothing more than a model of sun and shadow, more akin to a fancier version of <a href="https://www.suncalc.org">suncalc</a>. It models where the shadows will fall but it does not reflect reality. The reason is because the map is constructed from models. It uses an elevation model and building models.</p>
<p>Lets start with the elevation model. The elevation model is gathered from space using radar topography. This data covers the entire planet but in some areas measurements are only gathered every 30 meters. How do we know the elevations between the sample points? We model them using a best guess, often drawing a straight line between the two points. But there are many cases where this does not model reality.</p>
<p><a href="https://svbtleusercontent.com/bZVpzHdK9he94eHqjea33T0xspap.png"><img src="https://svbtleusercontent.com/bZVpzHdK9he94eHqjea33T0xspap_small.png" alt="Shadow simulation using models"></a></p>
<p><em>Models often simplify reality</em></p>
<p>Next are the building models. The building footprints are estimated from satellite images and most of the building heights come from volunteers of <a href="https://openstreetmap.org">OpenStreetMap</a> who walk around and record the number of stories. Buildings not surveyed by volunteers are just assumed to be single story. How tall is a single story? We have a model for that. We assume it’s 3 meters or about 10 feet. In reality, the height of a story varies building to building. Then there is the roof shape. Once again we model most buildings with a flat roof which is inaccurate for many houses around the world.</p>
<p>Each time we use a model to represent reality we lose accuracy. When <a href="https://shademap.app">shademap.app</a> calculates shadows and hours of sunlight for a location on the map, it’s really just an estimate. Treat it as a model of reality but not the truth.</p>
<p>I like to think of models vs. reality in terms of maps versus aerial photos. A map shows you where a road, house or river is but it can’t tell you exactly how wide that river is at point x, if a house has a steel or tile roof or if a road has large potholes. That’s not it’s job and a map would be overwhelming if it tried to convey all this data. Aerial photos, on the other hand, can answer all of the above questions with a glance. </p>
<h2 id="can-shadows-be-realistic_2">Can shadows be realistic? <a class="head_anchor" href="#can-shadows-be-realistic_2">#</a>
</h2>
<p>Yes. We now have data on exact heights of terrain, buildings and trees thanks to LiDAR (Light Detection and Ranging). This technology determines the height of surfaces on the ground by measuring the time it takes light emitted from a plane to bounce off the ground and return to the aircraft. An aircraft can takes thousands of these measurements a second, with each sample less than half a meter (1.5 feet apart). It’s similar to a laser distance measure you can buy at your local hardware store. Trees, buildings, towers and fences are all captured in these surveys and their positions and heights are accurate to within inches.</p>
<p><a href="https://svbtleusercontent.com/3T9dKArBTurNihhC2T4NAu0xspap.png"><img src="https://svbtleusercontent.com/3T9dKArBTurNihhC2T4NAu0xspap_small.png" alt="Shade modeled using map data"></a></p>
<p><em>Shade modeled using elevation + building models. Useful?</em></p>
<p>In sun and shadow simulation LiDAR data (or what I currently call “Tree Data” on <a href="https://shademap.app">shademap.app</a>) is the much more realistic model akin to aerial photos. LiDAR data can be used to model shadows far more accurately than previous elevation and building models. It can be used to accurately answer questions such as: “how much direct sunlight can I expect in this location” and “will this spot be in the shade at 4pm”.</p>
<p><a href="https://svbtleusercontent.com/gaxu4Dg3PcMxU1QZ4WFJNz0xspap.png"><img src="https://svbtleusercontent.com/gaxu4Dg3PcMxU1QZ4WFJNz0xspap_small.png" alt="Shade modeled using LiDAR"></a></p>
<p><em>Same location modeled with LiDAR. Trees!</em></p>
<p>This is why I will be focusing much of my attention on sourcing LiDAR data for more regions of the world and conveying their value to ShadeMap users. I don’t see the point of building more features for analyzing sun/shadow based on the currently inadequate elevation and building models. It conveys a false truth.</p>
<h2 id="the-future_2">The future <a class="head_anchor" href="#the-future_2">#</a>
</h2>
<p>I think Google has this market cornered at the moment. They have amassed and processed a mass trove of LiDAR data (A reader pointed out that <a href="https://en.wikipedia.org/wiki/Photogrammetry">photogrammetry</a> may be the source of this data as well). You can see this when you tilt a Google Map in satellite view and trees and buildings rise up in three dimensions. These 3D models are now available to developers via a standard called <a href="https://cesium.com/why-cesium/3d-tiles/">3D Tiles</a>.</p>
<p><img src="https://images.prismic.io/cesium/227a49ef-ccba-471d-b13d-745ea322bddf_00_GoogleUnrealPreview.jpg?auto=compress%2Cformat&w=1851"></p>
<p><em>Google’s 3D tiles. Wow!</em></p>
<p>Mapbox GL JS v3, on the other hand, is about to release realistic lighting with shadow casting for their map models. It is also, in theory, capable of loading 3D Tiles. <strong>This hints at the fact that world-wide sun and shadow simulation is about to be commoditized</strong>. Any developer will be able to build a more realistic version of <a href="https://shademap.app">shademap.app</a> in a day if they are willing to stomach the cost of paying for Google’s and Mapbox’s API fees. The moat is gone.</p>
<p>I’m not sure what position this leaves me in. ShadeMap was just a hobby project I’ve been trying to build into a business for a few years. The technology offerings on the horizon can make ShadeMap infinitely better but at a very high cost (fees to Google and Mapbox) that will make it prohibitive to host for free and I’m not sure there’s a large market of people that are willing to pay this premium. There’s also the possibility that if the demand is there, Google or Mapbox can add this feature to their own offerings, since it will be a trivial investment on their part.</p>
<p>Anyways, I just wanted to get these thoughts down as I’ve been thinking about this since yesterday. I still plan to work on ShadeMap full time for the present as it has be an incredible learning opportunity. I enjoy using maps and I hope to use my new found knowledge to build more projects centered around my personal pursuits in the outdoors.</p>
tag:tedpiotrowski.svbtle.com,2014:Post/vite-js-client-side-routing2023-10-27T08:40:08-07:002023-10-27T08:40:08-07:00Vite JS Client Side Routing<p>I recently migrated from <a href="https://create-react-app.dev/">create-react-app</a> to <a href="https://vitejs.dev/">Vite</a> because the initial startup and reload speeds are extremely fast. Vite helps me iterate faster on my project. </p>
<p>One major difference between Vite and create-react-app is that Vite does not do client side routing by default. In client side routing, any url you visit serves up your React App.tsx. You can then parse the urls in Javascript using React router and render the corresponding components for <code class="prettyprint">/profile</code> or <code class="prettyprint">/login</code>, etc.</p>
<p>Vite, however, will return a 404 for any url that’s not the root <code class="prettyprint">/</code> url. So if you navigate to <code class="prettyprint">/profile</code> you will get a 404 Not Found. To fix this, you can modify your <code class="prettyprint">vite.config.js</code> file and serve your root App.tsx for any url matching a regex by adding the code below.</p>
<p>Note: You can’t serve the root for all paths <code class="prettyprint">/.*</code> because your static assets will break. You will need to modify the regex to match your needs. My regex redirects all urls starting with <code class="prettyprint">@[number]</code> to App.tsx because on <a href="https://shademap.app">shademap.app</a> I permalink map locations, camera angles and times in the url like so <code class="prettyprint">/@47.6784,-122.1857,15z,1698422000851t,0b,0p,0m</code></p>
<pre><code class="prettyprint">import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
const ClientSideRouting = {
name: "dynamic-router",
configureServer(server) {
server.middlewares.use((req, res, next) => {
if (req.url.search(/^\/@\d+/) !== -1) {
req.url = "/";
}
next();
});
},
};
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), ClientSideRouting],
server: {
port: 3000,
},
});
</code></pre>
<p>The <code class="prettyprint">port: 3000</code> configuration is optional, but you’ll recognize it as following the convention set by create-react-app. What can I say, change is hard.</p>
tag:tedpiotrowski.svbtle.com,2014:Post/cloudflare-pages-yarn-version2023-09-28T08:33:37-07:002023-09-28T08:33:37-07:00Cloudflare Pages Node/Yarn versions<p>I spent an hour today debugging this error which occurs when deploying a Github repo to Cloudflare Pages:</p>
<pre><code class="prettyprint">07:50:42.633 Success: Finished cloning repository files
07:50:43.436 Detected the following tools from environment: yarn@3.6.3, nodejs@18.17.1
07:50:43.438 Installing project dependencies: yarn
07:50:44.208 ➤ YN0070: Migrating from Yarn 1; automatically enabling the compatibility node-modules linker 👍
07:50:44.211
07:50:44.264 ➤ YN0000: ┌ Resolution step
07:50:48.645 ➤ YN0032: │ fsevents@npm:2.3.3: Implicit dependencies on node-gyp are discouraged
07:50:52.853 ➤ YN0000: └ Completed in 8s 590ms
07:50:52.879 ➤ YN0000: ┌ Post-resolution validation
07:50:52.879 ➤ YN0028: │ The lockfile would have been modified by this install, which is explicitly forbidden.
07:50:52.880 ➤ YN0000: └ Completed
07:50:52.880 ➤ YN0000: Failed with errors in 8s 618ms
</code></pre>
<p>It turns out that Cloudflare Pages has two versions of Ubuntu (20 and 22) and each version comes bundled with specific versions of Node and Yarn. I was using Yarn v1 on my local machine and Cloudflare Pages was using Ubuntu 22 which in turn uses Yarn v3. </p>
<p>I was stumped by the error because Cloudflare Pages works for other projects that I use Yarn v1 for locally. It turns out that you can pick your version of Ubuntu under <strong>Settings > Build & Deployments > Build System Version</strong>. </p>
<p><a href="https://svbtleusercontent.com/hFaG6whi83j5mD8pEy9nao0xspap.png"><img src="https://svbtleusercontent.com/hFaG6whi83j5mD8pEy9nao0xspap_small.png" alt="Screenshot 2023-09-28 at 10.22.49 AM.png"></a></p>
<p>The way Cloudflare picks the Ubuntu version for you project appears based on the node version required in <code class="prettyprint">package.json</code> and for Vite this is:</p>
<pre><code class="prettyprint"> "engines": {
"node": "^14.18.0 || >=16.0.0"
},
</code></pre>
<p>Ubuntu 20 uses Node version 12.x, so I believe Cloudflare chose Ubuntu 22 due to my project requiring Node 14.x/16.x. </p>
<p>Locally I use Node 16.14 and Yarn 1.22. Because Node and Yarn versions are tied together on Cloudflare pages, you need to configure your local environment to reflect either the Ubuntu 20 or Ubuntu 22 configuration: <strong>Either use Node 12.x + Yarn 1.x OR Node >=14.x/16.x + Yarn 3.x</strong></p>
tag:tedpiotrowski.svbtle.com,2014:Post/using-lidar-for-tree-shadows-in-shademap2023-07-09T12:20:53-07:002023-07-09T12:20:53-07:00Using LiDAR to map tree shadows<p><strong>tl;dr;</strong> <em>I can load LiDAR data to simulate tree shadows for any time of year, but the hardware demands and hosting costs may be prohibitive so I’m only sharing a small <a href="https://pub-2f76d53a7bba403bbf5ca35a8bf7e094.r2.dev/leaflet.html">demo</a> for now</em> </p>
<p><strong>Update: I can now offer LiDAR data for large parts of the planet in 1 square km blocks on <a href="https://shademap.app">shademap.app</a> (<a href="https://youtu.be/CN7lQhNOv4I">Demo video</a>)</strong></p>
<p>Two years ago, I launched shademap.app, and since then, a common question I receive is: “Where are the trees?” It’s a valid inquiry, considering I reside in the Pacific Northwest—a region known for its towering trees that significantly affect the amount of direct sunlight a location receives.</p>
<p>Here are two renderings of the shadows on Bainbridge Island for July 9th at 7:09 AM. Radar clearly misses 90% of the shadows cast because it does not include vegetation. Radar only reflects off the ground (<strong>Correction: an <a href="https://news.ycombinator.com/item?id=36662701">HN user</a> pointed out that radar does reflect off surfaces like vegetation. I assumed it did not because SRTM radar dataset is cited as the source of ground level elevation data. Will clarify once I understand more. We’re all learning here.</strong>), making objects such as trees and buildings invisible. On the other hand, LiDAR reflects off all objects, creating a much richer model of the earth’s surface.</p>
<p><a href="https://svbtleusercontent.com/bY4zNi97cMS6orbwoJmDKg0xspap.jpg"><img src="https://svbtleusercontent.com/bY4zNi97cMS6orbwoJmDKg0xspap_small.jpg" alt="Radar vs LiDAR shadow simulation"></a></p>
<p>So why hasn’t ShadeMap included trees from the beginning? It’s because ShadeMap uses elevation data to simulate shadows and the only readily available world-wide elevation data sets come from <a href="https://en.wikipedia.org/wiki/Shuttle_Radar_Topography_Mission">radar</a>. Radar works at night time and penetrates clouds, so satellites are able to compile this data 24 hours per day from space.</p>
<p>LiDAR, on the other hand, is much more accurate but is collected from airplanes or drones and cannot penetrate fog and clouds. It’s much more time consuming and expensive to collect, leaving each local government to fund its surveying costs. However, I recently discovered that my state of Washington provides an extensive <a href="https://lidarportal.dnr.wa.gov/">LiDAR dataset</a> that covers large amounts of the state.</p>
<p><a href="https://svbtleusercontent.com/tF4Je2rM5W8N1eLXgDmybA0xspap.jpg"><img src="https://svbtleusercontent.com/tF4Je2rM5W8N1eLXgDmybA0xspap_small.jpg" alt="WA LiDAR portal"></a></p>
<p>I could finally fill in the gaps in my shadow simulation-for my own backyard, at least. But there was one problem. The data format was geared towards traditional GIS software (it’s a GeoTIFF) and not browser friends (like a JPG or PNG). In order to use the data, I would have to take 100’s of gigabytes of floating point, imperial feet, GeoTIFF files and slice them up into small fast-loading image tiles where metric meters are encoded as red, green and blue pixel values.</p>
<p>I bought a 1TB hard drive and started asking ChatGPT questions on how to convert the data. (ChatGPT is a marvelous assistant and has saved me hours of reading documentation and irrelevant Google search results) Once, I started to run the conversion process, I realized that my 16GB of RAM could not load these large data files and I had to rewrite the conversion code to just work with a small region of the map at a time. For the first time in a long time, I’m feeling the need for a more powerful machine…</p>
<p>And it works. Or actually…it’s working right now. I’m attempting to convert just the Seattle metropolitan area and it’s only about half way done after 12 hours. The tiles are over 15GB and growing. The simulations are incredible, but I’m not sure I want to sink money into hosting this data and making it publicly available. It’s a shame but it’s the sound financial decision for now.</p>
<p><a href="https://svbtleusercontent.com/pd7efcJtXN5f8vho7JVP9y0xspap.gif"><img src="https://svbtleusercontent.com/pd7efcJtXN5f8vho7JVP9y0xspap_small.gif" alt="LiDAR shadow simulation"></a></p>
<p>However, I can host small portions of this dataset for free so if you’re curious what my long-term vision for ShadeMap is, try this <a href="https://pub-2f76d53a7bba403bbf5ca35a8bf7e094.r2.dev/leaflet.html">demo</a></p>
<p>As always, follow me on <a href="https://twitter.com/shademap">Twitter</a> for frequent updates on this project or if you want to get in touch.</p>
tag:tedpiotrowski.svbtle.com,2014:Post/mount-index2023-05-29T19:24:18-07:002023-05-29T19:24:18-07:00Mount Index<p><a href="https://svbtleusercontent.com/ba32pty7J2f79cWotSyodz0xspap.jpg"><img src="https://svbtleusercontent.com/ba32pty7J2f79cWotSyodz0xspap_small.jpg" alt="Mount index hourglass gully from Mount Baring"></a></p>
<p>This rugged peak is impossible to miss on a clear day while driving westward on Highway 2. Its intimidating pillars of granite, rising thousands of feet into the air, are complemented by the beautiful Lake Serene at its base. A visit during the winter months is guaranteed to impress with frequent avalanches of snow roaring down its icy walls. Mount Index actually consists of three distinct summits and this blog post is about reaching the tallest but easiest of the three.</p>
<p><a href="https://svbtleusercontent.com/p2NrK5CyTXL3kRzq3dBUfw0xspap.jpg"><img src="https://svbtleusercontent.com/p2NrK5CyTXL3kRzq3dBUfw0xspap_small.jpg" alt="Mount index traverse around Lake Serene"></a></p>
<p>Cassondra and I set out to climb it on May 20th. It was a rather hot day, with summit temps forecast at 60 degrees Fahrenheit. Ideally you want the temperatures cool for this climb because the upper route faces south east and gets baked by the sun throughout the day. We had attempted Index in April of last year but when the sun hit the upper mountain we watched avalanche after avalanche cascade down the mountain. It was awesome to watch, but not a good day for climbing.</p>
<p><a href="https://svbtleusercontent.com/iVxkL9pXCCkJRxuXcxmcTd0xspap.jpeg"><img src="https://svbtleusercontent.com/iVxkL9pXCCkJRxuXcxmcTd0xspap_small.jpeg" alt="Mount Index east ridge"></a></p>
<p><em>Overgrown section of the east ridge</em></p>
<p>This time around, the temps had already been high for weeks and we were confident the mountain had gone through its shed cycle. Our main concern now was that the snow which made the upper gullies passable would be too thin to boot up or completely gone exposing the wet 5th class rock below.</p>
<p><a href="https://svbtleusercontent.com/eT9V4QteaBuNGEoRxdXhNv0xspap.jpg"><img src="https://svbtleusercontent.com/eT9V4QteaBuNGEoRxdXhNv0xspap_small.jpg" alt="Traverse to hourglass gully"></a></p>
<p><em>Traverse to hourglass gully</em></p>
<p>We started at 2:30am to avoid the worst of the heat. A thunderstorm had just rolled through and we could still see lightning to the east. Nevertheless, we set out towards Lake Serene and arrived just after 4:30am. The lake ice was already breaking up but the boulder field we needed to follow along the west shore was still packed solid with snow. We ate a quick snack on Lunch Rock and put on our boots and gaiters to deal with snow.</p>
<p><a href="https://svbtleusercontent.com/fu8iyPrKiZZZ6CJhzrFfgz0xspap.jpg"><img src="https://svbtleusercontent.com/fu8iyPrKiZZZ6CJhzrFfgz0xspap_small.jpg" alt="Heading up hourglass gully"></a></p>
<p><em>Starting up hourglass gully</em></p>
<p>From Lunch Rock, a well worn climber’s trail avoids some lake shore cliffs by traversing high in the trees and then depositing you back to the lake shore via a simple downhill scramble. Rockfall and avalanches are common here, so no need to venture uphill until you reach the south end of the lake. Framing the south shore you can already see the crux of the climb, the steep east ridge. With adequate snow, you won’t encounter much bushwhacking, but there was not adequate snow and Cassondra began to regret wearing shorts.</p>
<p><a href="https://svbtleusercontent.com/vbQayxsiMRbSt9iGDZmy7a0xspap.jpg"><img src="https://svbtleusercontent.com/vbQayxsiMRbSt9iGDZmy7a0xspap_small.jpg" alt="hourglass gully"></a></p>
<p><em>Looking up from constriction</em></p>
<p>There are two distinct rock slabs on the ridge. The first one is less steep and less exposed and covered in snow during winter. The second one is definitely fourth to easy fifth class with exposure. If it seems harder than that, you’re off route. In general, you want to be more on the Lake Serene side of the ridge when it starts getting steep. Save weight and just bring a few alpine draws to sling trees if you opt for roping up. Cassondra and I roped up and swapped quick leads up the ridge. After some steep climbing you will traverse across a small saddle. From here there is only 50 or so feet of steeper climbing before the ridge begins to flatten out.</p>
<p><a href="https://svbtleusercontent.com/6BrPZ7YiaK1nw2QzL8G8hS0xspap.jpg"><img src="https://svbtleusercontent.com/6BrPZ7YiaK1nw2QzL8G8hS0xspap_small.jpg" alt="IMG_5706.jpg"></a></p>
<p><em>Looking up at the upper hourglass</em></p>
<p>Follow the ridge until it meets the cliffs of Index and then traverse under the cliffs until you encounter the first wide gully to your right. This is the start of the hourglass gully. We arrived here around 10:45am. I read reports about icefall raining down the gully in winter but all we encountered was one large but slowly rolling boulder. We put on microspikes and booted towards the constriction. Moats were forming to the left and right, but the center of the constriction was still plenty thick.</p>
<p><a href="https://svbtleusercontent.com/qkZ49xceabQgzksxSiXW880xspap.jpeg"><img src="https://svbtleusercontent.com/qkZ49xceabQgzksxSiXW880xspap_small.jpeg" alt="IMG_8424.jpeg"></a></p>
<p><em>Thwarted: downclimbing upper hourglass</em></p>
<p>From the constriction, the top of the hourglass continues slightly towards the left and gets steeper. We booted up in this direction but were devastated to find an impassable moat splitting the gully just 100’ from the summit ridge. It was noon, and with the midday heat upon us, we felt like our only option was to start heading home. We took a quick look at the topo map and it seemed like there was a gentler slope to our right that also led to the top. We decided to give it a shot.</p>
<p><a href="https://svbtleusercontent.com/87kRapCYMtk5qAZkDDr2nJ0xspap.jpg"><img src="https://svbtleusercontent.com/87kRapCYMtk5qAZkDDr2nJ0xspap_small.jpg" alt="Mount index hourglass gully"></a></p>
<p><em>Cassondra traversing upper hourglass</em></p>
<p>We downclimbed towards the constriction and then traversed over to climbers right. We found a snow free patch underneath some trees and stopped to cool off in the shade, eat a snack, put on crampons and ditch any gear not necessary for the final ascent. It was hard to see from here if this alternate route would go but it didn’t seem very steep. We had never encountered any GPS routes or trip reports that didn’t follow the upper hourglass so the excitement was building as we started up.</p>
<p><a href="https://svbtleusercontent.com/32Q4VzqbPGBrQcDmSZBTn40xspap.jpg"><img src="https://svbtleusercontent.com/32Q4VzqbPGBrQcDmSZBTn40xspap_small.jpg" alt="Mount index summit ridge"></a></p>
<p><em>Summit ridge</em></p>
<p>After the first 300’, we could see that we’d make it up. In fact, the route was much less steep than the upper hourglass. There was even an option to get off the snow and scramble up on mellow rocks to the right. We found two old backpacks and a bivy sack among the rocks here. One backpack had two backcountry meals and a pair of rock climbing shoes. They seemed from the early 2000’s. I’m not sure why they were abandoned here.</p>
<p><a href="https://svbtleusercontent.com/6vxhEfVawAFKNxG2hTDWiU0xspap.jpeg"><img src="https://svbtleusercontent.com/6vxhEfVawAFKNxG2hTDWiU0xspap_small.jpeg" alt="Mount Index summit"></a></p>
<p><em>On the summit</em></p>
<p>We had now gained the summit ridge and from here it was just a flat walk to the summit itself. We topped out at 2:15pm under blue skies and virtually no wind. We looked down at the town of Index and Lake Serene, then lounged out on the summit while we read the single sheet of paper that was the summit register. We started back down at 3:15pm.</p>
<p><a href="https://svbtleusercontent.com/gL9LCS5Q4LLohbQcJm51Fi0xspap.jpeg"><img src="https://svbtleusercontent.com/gL9LCS5Q4LLohbQcJm51Fi0xspap_small.jpeg" alt="Mount index east ridge"></a></p>
<p><em>Descending east ridge</em></p>
<p>The descent was uneventful until we hit the east ridge. We downclimbed most of it using veggie belays, but opted to rappel the low 5th class section. On the lower rock slab, we passed a few existing rappel stations that didn’t seem appealing but at some point were forced to set up our own. This ended up being a terrible rappel through trees and we were unable to pull the rope. I prusiked back up and managed to free it. We were finally off the ridge by 7pm.</p>
<p><a href="https://svbtleusercontent.com/2aLaPEpZ6iMSgtE1XtQFF20xspap.jpeg"><img src="https://svbtleusercontent.com/2aLaPEpZ6iMSgtE1XtQFF20xspap_small.jpeg" alt="Lake Serene"></a></p>
<p><em>Heading home</em></p>
<p>The rest was just a basic reversal of the uphill route and we were back at the car around 10:30pm. It was already dark and I promptly fell asleep in the passenger seat as Cassondra drove us to Wendy’s and then home by midnight.</p>
<p>GPX track: <a href="https://www.strava.com/activities/9111276622">https://www.strava.com/activities/9111276622</a></p>
tag:tedpiotrowski.svbtle.com,2014:Post/knowledge-work2023-04-24T09:47:30-07:002023-04-24T09:47:30-07:00Knowledge Work<p><a href="https://svbtleusercontent.com/vAzJ4Dfwj295by29B1ssGu0xspap.jpg"><img src="https://svbtleusercontent.com/vAzJ4Dfwj295by29B1ssGu0xspap_small.jpg" alt="IMG_7275(1).jpg"></a></p>
<blockquote class="short">
<p>I’ve spent way too much time answering questions on stack overflow. I don’t know why. -Greggman</p>
</blockquote>
<p>Recently, I think I enjoy doing house work more than programming. There’s a sense of accomplishment in finishing a task. When I set out to wash the dishes or do a load of laundry, I know that I will succeed and I can even do a decent job of estimating how long the task will take.</p>
<p>Knowledge work is different. Often, you can put time in for months without seeing any meaningful results. Often you throw all your efforts away if they’re not fruitful. I console myself on these occasions by telling myself I’ve learned something and even though the work is trashed, the knowledge remains.</p>
<p>Stack Overflow provides the type of validation that knowledge workers crave. You are given a relatively simple task and if you can finish it, expect check-marks and points in a relatively timely fashion. That’s why I think greggman <a href="https://games.greggman.com/game/done-with-stackoverflow/">continued for so long</a> despite not caring about attribution or reputation. It’s just nice to feel the sense of accomplishment when you’ve solved a problem.</p>
<p>It’s why I’ve often found myself answering WebGL questions instead of writing code for ShadeMap.</p>
tag:tedpiotrowski.svbtle.com,2014:Post/tajumulco-volcano-guatemala-s-highpoint2023-03-20T13:19:48-07:002023-03-20T13:19:48-07:00Tajumulco Volcano - Guatemala's Highpoint<p>Cassondra, myself and my sister Ilona were invited to attend a wedding in Antigua on Saturday, March 11th and because it was a bit of a financial and time commitment to get there, we decided that we would fly in the weekend before and do some exploring. </p>
<p><a href="https://svbtleusercontent.com/2Yq9TXcUtjqej3EMXAKaRU0xspap.jpg"><img src="https://svbtleusercontent.com/2Yq9TXcUtjqej3EMXAKaRU0xspap_small.jpg" alt="IMG_7739.JPG"></a></p>
<p><em>Hotel parking by trailhead</em></p>
<p>We rented a car at the airport and spent two days with a guided group on the active volcano Fuego, outside of Antigua. It was a blast but then we decided to opt for the less visited country high point of Guatemala: Tajumulco Volcano 13,739’.</p>
<p><a href="https://svbtleusercontent.com/cJ8zGz8aRMNLVfUta9exgF0xspap.jpg"><img src="https://svbtleusercontent.com/cJ8zGz8aRMNLVfUta9exgF0xspap_small.jpg" alt="IMG_7679.JPG"></a></p>
<p><em>First views of Tajumulco from the road</em></p>
<p>We stayed at the Hotel Fuentes in San Marcos, an hour’s drive south of the volcano. The night before our hike, we did some Googling of the route, the directions to the trailhead and gathering general “beta”. We discovered a hotel near the trail with a parking lot where we could leave the car. </p>
<p><a href="https://svbtleusercontent.com/iyUF4Qb5dTR71ppnP9CpfK0xspap.jpg"><img src="https://svbtleusercontent.com/iyUF4Qb5dTR71ppnP9CpfK0xspap_small.jpg" alt="IMG_7681.JPG"></a></p>
<p><em>Sporadic trail markers along the road</em></p>
<p>The hotel reviews on Google mentioned hiking the volcano and several people boasted that they had made it safely, only having to pay a small bribe and avoiding nearby gunfire. As a precaution we left all our luggage and money in San Marcos city, taking only $10 and leaving at 5am the next morning.</p>
<p><a href="https://svbtleusercontent.com/jfp9hbv1J9uhZ1R7xfsgnu0xspap.jpg"><img src="https://svbtleusercontent.com/jfp9hbv1J9uhZ1R7xfsgnu0xspap_small.jpg" alt="IMG_7684.JPG"></a></p>
<p><em>Info sign before single track trail</em></p>
<p>The drive took an extra half hour because of semi trucks engine braking down the mountain passes. We also ran into a police roadblock in San Sebastian where we had to pay one dollar to drive through what looked like a cattle auction. We arrived at the hotel and asked the owner how much it would be to park the car. He said $10. We only had $9 but we figured some oreo’s would make up the difference.</p>
<p><a href="https://svbtleusercontent.com/5X2b12UAtbsfpuMLVF7iqn0xspap.jpg"><img src="https://svbtleusercontent.com/5X2b12UAtbsfpuMLVF7iqn0xspap_small.jpg" alt="IMG_7687.jpg"></a></p>
<p><em>Starting up the single track</em></p>
<p>We started up a dirt road and quickly came across three military jeeps with roof mounted machine guns. Several guys in military fatigues were standing outside and we said Volcano Tajumulco and just waved us by. Farther up the road, we heard a pickup truck coming up behind us. It was filled with about 10 men and they all just smiled and waved at us. About two miles up the road we came to an empty parking lot and a single track trail leading towards the summit.</p>
<p><a href="https://svbtleusercontent.com/jbpmBBDSqXh7myY4Z4WK360xspap.jpg"><img src="https://svbtleusercontent.com/jbpmBBDSqXh7myY4Z4WK360xspap_small.jpg" alt="IMG_7697.JPG"></a></p>
<p><em>Final ascent and stations of the cross</em></p>
<p>The hike was pleasant and I was surprised by the amount of shade and trees. We saw three campers coming down the mountain but they didn’t seem interested in talking. There was also a lot of garbage cans along the trail and even some signs remind people to pick up their trash.</p>
<p><a href="https://svbtleusercontent.com/deiFk57LU37qAStGYhRLfN0xspap.jpg"><img src="https://svbtleusercontent.com/deiFk57LU37qAStGYhRLfN0xspap_small.jpg" alt="IMG_7700.JPG"></a></p>
<p><em>Scrambling towards the summit</em></p>
<p>The final ascent to the crater had the 14 stations of the cross commemorating Jesus’s crucifixion. There were a few rocky steps which required using your hands but no exposure. We made the top around 10:30am and the hike took about 4 hours from the hotel where we parked. Before we left, a French Canadian couple arrived on the summit. They were the only other hikers we saw that day.</p>
<p><a href="https://svbtleusercontent.com/muX8P9dvQCYxza1E12qqhP0xspap.jpg"><img src="https://svbtleusercontent.com/muX8P9dvQCYxza1E12qqhP0xspap_small.jpg" alt="IMG_7709.JPG"></a></p>
<p><em>Cassondra with Pacific clouds</em></p>
<p>We descended an alternate route down the north side of the crater and when we caught back up to the main trail we ran into a group of police armed with rifles. They wanted our phone so they could take our picture but I was a bit on edge and refused. They ended up taking pictures with us on their own phones and then carried on up the mountain.</p>
<p><a href="https://svbtleusercontent.com/5YBrfUocHMvU4vS7XfFBTN0xspap.jpg"><img src="https://svbtleusercontent.com/5YBrfUocHMvU4vS7XfFBTN0xspap_small.jpg" alt="IMG_7715.JPG"></a></p>
<p><em>Summit shot</em></p>
<p>At this point, the amount of military and police presence made us a bit uneasy. It seemed to imply the area was not safe and we decided to keep a low profile and hike out in silence. Some early afternoon clouds were forming and turned into a nice cool fog as we descended. </p>
<p><a href="https://svbtleusercontent.com/3MVe4wVWhGDfYSGWaBnJtB0xspap.jpg"><img src="https://svbtleusercontent.com/3MVe4wVWhGDfYSGWaBnJtB0xspap_small.jpg" alt="IMG_7724.JPG"></a></p>
<p><em>Police patrol truck</em></p>
<p>We skirted past the military jeeps unnoticed and waved to a few kids playing in their yards. When we got back to the main highway we noticed an armored personnel carrier was now parked there. We quickly made our way back to the hotel and found the owner. We gave him all our money and a package of oreos and he seemed pleased. </p>
<p><a href="https://svbtleusercontent.com/vc8eHHcBkSvWkGk7tgkCea0xspap.jpg"><img src="https://svbtleusercontent.com/vc8eHHcBkSvWkGk7tgkCea0xspap_small.jpg" alt="IMG_7731.JPG"></a></p>
<p><em>Military jeeps</em></p>
<p>When we got back to San Marcos, we googled some more and found the the State Department had issued a Level 4 - Do Not Travel advisory for rural areas around San Marcos due to narcotics trafficking and lack of police presence. Luckily, it seemed like the Tajumulco area was pretty well patrolled when we were there but I’d do your own research before going.</p>
<p><a href="https://svbtleusercontent.com/dynbF3VKrT155RzvPi63Rn0xspap.jpg"><img src="https://svbtleusercontent.com/dynbF3VKrT155RzvPi63Rn0xspap_small.jpg" alt="IMG_7733.jpg"></a></p>
<p><em>Armored personnel carrier</em></p>
tag:tedpiotrowski.svbtle.com,2014:Post/forbidden-peak2022-11-28T09:56:51-08:002022-11-28T09:56:51-08:00Forbidden Peak<p><a href="https://svbtleusercontent.com/c7vgpsP93Ua7oqmDYsh7ha0xspap.jpg"><img src="https://svbtleusercontent.com/c7vgpsP93Ua7oqmDYsh7ha0xspap_small.jpg" alt="Forbidden Peak"></a></p>
<p>Late summer/early fall is my favorite season in the Cascades. The mornings are crisp but the evenings are fairly warm. You can get away with a light backpack because you don’t need to bring warm layers or serious snow gear. Eldorado, Sahale, Sherpa and Argonaut were all incredible climbs we did during this season in years past.</p>
<p>So after many weeks abroad, we were back in Seattle for Labor day and eager to get in at least one epic climb before the snow started to fall. Cassondra managed to secure a Saturday night permit for Boston Basin and we decided to try Forbidden Peak.</p>
<p><a href="https://svbtleusercontent.com/kUpQ6e9R3pNoZfpUncERG0xspap.jpeg"><img src="https://svbtleusercontent.com/kUpQ6e9R3pNoZfpUncERG0xspap_small.jpeg" alt="Crossing Boston Creek"></a></p>
<p><em>Finding a way across Boston Creek</em></p>
<p>The weather was chilly, with summit temperatures forecasted to be around 40 degrees with 15 mph winds and a chance of an afternoon misting totaling 0.01mm of accumulation. It wasn’t a great forecast for standing around and belaying the 1000’ or so of climbing but we knew what to expect and prepared to endure some discomfort.</p>
<p>Lance picked us up in Bothell at 7am and we drove to the Marblemount ranger station to pick up our permit. The parking lot was packed and we had to wait close to an hour for our number to be called. While we waited, I observed the other parties waiting in line. Lots of them were climbers and the ground was littered with ropes and helmets. I wasn’t sure how many were climbing Forbidden, but I made a mental note that we should get an early start the next morning.</p>
<p><a href="https://svbtleusercontent.com/5zWZcdGgWvFGmvdJJRR8sn0xspap.jpg"><img src="https://svbtleusercontent.com/5zWZcdGgWvFGmvdJJRR8sn0xspap_small.jpg" alt="Hiking across Boston Basin"></a></p>
<p><em>Hiking across Boston Basin</em></p>
<p>By early afternoon we were hiking into Boston Basin, camping gear in tow. We completely missed the easy Boston Creek crossing because it was obscured by a large boulder downstream. Instead we left the trail and climbed upstream, eventually finding some shallow tributaries we could confidently get across. During one crossing I had to run back across the water to help Cassondra chase away a black bear that had followed us along the creek.</p>
<p>At this point it’s worthwhile to mention that we ran into another party on the hike in. They had climbed Forbidden, starting from the parking lot the previous morning. Their aim was to return to the parking lot that night, but the climb took longer than they expected and darkness fell when they were still at the notch. Not wanting to rappel the rest of the way in the dark and not bothering to bring down jackets on such a beautiful day, they huddled for warmth until it was light enough to descend the next day. We’re not the fastest climbers and I thought that camping would give us the extra time needed to avoid a similar stranding but less than 24 hours from now we’d find ourselves in similar circumstances.</p>
<p><a href="https://svbtleusercontent.com/kji6KyxBtYWggHN4CSYttB0xspap.jpeg"><img src="https://svbtleusercontent.com/kji6KyxBtYWggHN4CSYttB0xspap_small.jpeg" alt="Relaxing at camp"></a></p>
<p><em>Relaxing at camp</em></p>
<p>We made it to camp at 4pm, pitched the tent, filtered water and ate. Clouds moved in and there was a light breeze. We’d occasionally hear climbers yelling to each other on Forbidden. Two guys from Portland and a guided group of 3 would be going up with us the next day. We went to bed at 8pm and at some point during the night woke to a climbing party making a joyous entrance after a late night descent from the same peak we would begin climbing in just a few hours.</p>
<h2 id="summit-day_2">Summit day <a class="head_anchor" href="#summit-day_2">#</a>
</h2>
<p>We woke at 3am. Packed a single rack and one 60 meter rope (and one backup 60m) into our Flash 22 packs. We opted for trail runners, microspikes and an ice axe for ascending the snow at the base of the climb. Navigating without a GPS track would have been difficult in the dark because you need to scramble up a number of rock slabs, some of which are vertical in places. The microspikes felt comfortable on the snow except near the top where the snow was steep and hard.</p>
<p><a href="https://svbtleusercontent.com/jfN2dSZznPAGtw1uPbmBW60xspap.jpeg"><img src="https://svbtleusercontent.com/jfN2dSZznPAGtw1uPbmBW60xspap_small.jpeg" alt="Looking at stars in Boston Basin"></a></p>
<p><em>3am start</em></p>
<p>We straddled off the snow and onto the base of the rock, ditched our snow gear and started to scramble to the base of the Cat Scratch gullies. An incredible sunrise was unfolding behind us. The east face of Glacier Peak was the first to catch the light as it overpowered that “Cascade orange” light on the horizon. Mount Formidable and Johannesburg mountain lit up next. We put on our harnesses and waited for the Portland party of two to get a head start up the gullies.</p>
<p>It took us about 2 hours to climb to the notch. I think we got there in four long, easy pitches that felt secure with only 2 or 3 pieces of protection per pitch. We used some established rappel stations for belaying and noted their location for the descent. We took a quick break at the notch and started up the west ridge around 8:30am, beginning with the airy step. The next few hours were slow but steady progress. I led each pitch and then belayed Cassondra and Lance up. They were both tied into the end of my rope, about 15 feet apart. No one ever fell.</p>
<p><a href="https://svbtleusercontent.com/6ke2p4twtQWZjkDdE45xbq0xspap.jpeg"><img src="https://svbtleusercontent.com/6ke2p4twtQWZjkDdE45xbq0xspap_small.jpeg" alt="Roping up at Cat Scratch Gullies"></a></p>
<p><em>Roping up</em></p>
<p>At some point, the guided party of 3 caught up and passed us. Some pitches I ran out of rope just shy of a rappel anchor and had to resort to building my own belay stations and in other places I only noticed a nearby rappel anchor after I already built my own. This ate up a lot of time and we could see rain clouds building to the west while we were still two pitches short of the summit. </p>
<p><a href="https://svbtleusercontent.com/bovMHPnxECJpS5AjZyzEfL0xspap.jpg"><img src="https://svbtleusercontent.com/bovMHPnxECJpS5AjZyzEfL0xspap_small.jpg" alt="Climbing Cat Scratch gullies"></a></p>
<p><em>Starting the Cat Scratch gullies</em></p>
<p>On this day, I surprised myself by not really needing to go on. It looked like what remained of the ridge ahead was very similar to the climbing we had already done. We had succeeded in getting past the crux pitch and being so close to the summit, the views would likely be similar to what we had experienced all day. On top of that, we knew we were slow and wanted to get a head start on the rappelling and down climbing ahead of others. It was one of the wisest decisions we ever made.</p>
<p>The wind was starting to pick up as we rappelled, flinging the rope strands wildly and frustrating all attempts at throwing the rope. We rappelled twice, ending at the base of the crux pitch and then down climbed a horizontal pitch along the ridge. We did another rappel and slowly began down climbing the rest of the route to the notch. During this time the air became saturated with moisture and although it wasn’t raining it became very foggy and damp. Soon, it became hard to see more than 20 feet. My best guess is that we arrived at the notch around 7pm. </p>
<p><a href="https://svbtleusercontent.com/3tPY3xPeYfgEiRt1op4CAn0xspap.jpeg"><img src="https://svbtleusercontent.com/3tPY3xPeYfgEiRt1op4CAn0xspap_small.jpeg" alt="Top of Cat Scratch gullies"></a></p>
<p><em>Top of the Cat Scratch Gullies</em></p>
<p>At this point we had about 30 minutes before nightfall. Everyone had passed us and we were the last party left on the mountain. Cassondra, who’s normally hotter than a furnace was cold and shivering. The wind was howling and it had started to rain. Given the weather, sleeping on a rock ledge at 8000’ evoked images of great suffering so we decided we had to keep descending in the dark.</p>
<p>Luckily, we saw the first rappel station on our way up and we found it again just as darkness fell. We turned on our headlamps and realized that the fog and moisture reflected most of the light making them useless beyond a distance of 10 feet. We knew the next two rappel stations were below us and a third was on the other side of the gully. After that we’d be descending into the foggy unknown. We moved as fast as we could, water running down our hands as the rappels squeezed water out of the rope. Each time we made a rappel, we managed to find another rappel station. Some were only 50’ away but not wanting to run the risk of descending too far we had to stop at every one of them.</p>
<p><a href="https://svbtleusercontent.com/2qQEWcKEw2mQ95JneuYnQ10xspap.jpg"><img src="https://svbtleusercontent.com/2qQEWcKEw2mQ95JneuYnQ10xspap_small.jpg" alt="Forbidden Peak notch with West Ridge"></a></p>
<p><em>West Ridge from the notch</em></p>
<p>It was around eleven pm when we came upon the last rappel station. For extra insurance, we took out the second rope and did a long double rope rappel. I made a big mistake here. Even though we couldn’t see anything, we suspected that we could rappel straight down onto the snow from here. Unfortunately, we had left our snow gear in the rocks below to our right and without ice axes or crampons we’d slide right off the mountain. Instead I chose to rappel diagonally towards where our gear was stashed, crossing some terrible choss, un-equalizing the rappel anchor and eventually making the ropes impossible to pull. </p>
<p>I understand better now why people make bad choices in these situations. It’s often the choice that promises to end the suffering, the cold and the fatigue the fastest. The right choice was to rappel straight down to the snow and prusik back up if there wasn’t a safe place to stand but after hours of being pelted by wind and rain I took the option that I hoped would protect us from the elements the fastest.</p>
<p><a href="https://svbtleusercontent.com/65speMvQnYBNWJqD4XfFJj0xspap.jpeg"><img src="https://svbtleusercontent.com/65speMvQnYBNWJqD4XfFJj0xspap_small.jpeg" alt="Rappelling Forbidden Peak"></a></p>
<p><em>Starting to rappel down</em></p>
<p>But we were finally down off the rock, next to the glacier and back in possession of our snow gear. The wind wasn’t much better here and it was still raining. We knew down climbing the snow would be difficult and given our present condition we decided we should wait until daylight. We tried to find a comfortable place to sleep, even exploring some caves underneath the glacier but ended up having to bivy on a slanted pile of rocks with melt water running through them. Lance propped himself on his backpack and Cassondra and I squeezed into a single bivy. </p>
<p><a href="https://svbtleusercontent.com/o1LG434d5sCXZpw9kY6rpA0xspap.png"><img src="https://svbtleusercontent.com/o1LG434d5sCXZpw9kY6rpA0xspap_small.png" alt="Bad weather Forbidden Peak"></a></p>
<p><em>Weather moving in</em></p>
<p>The night stretched on. The rain didn’t stop and the wind gusts would chill you to the bone. We tried to sleep but the sharp rocks would pierce into our knees, hips and shoulders. We shivered non-stop. Eventually the numbness of a pinched nerve would crescendo forcing us to roll over, the bivy tearing on the sharp rocks and our precious body heat escaping in the process. At 2am I couldn’t take it anymore. I began clearing rocks and used an ice axe to shape the wet sand underneath into a sleeping platform. Cassondra and I unfurled our remaining dry bivy sack and tried to get comfortable for the next 4 hours. </p>
<p><a href="https://svbtleusercontent.com/pCf7runk2rxtssK3Kr7WS90xspap.jpeg"><img src="https://svbtleusercontent.com/pCf7runk2rxtssK3Kr7WS90xspap_small.jpeg" alt="Bivy Forbidden Peak"></a></p>
<p><em>Bivy next to the glacier</em></p>
<p>At some point the clouds cleared momentarily revealing a single point of light. Jupiter. I remember staring at it entranced. It seemed unusually large and bright during that long dark night. I think a mind devoid of any thoughts and staring up at the darkness for hours can really appreciate that kind of thing.</p>
<p>I remember falling asleep once or twice and eventually the sky began to turn from black to dark gray. The rain had stopped but there would be no sun. Packing up was incredibly cold and I kept wearing the bivy as a shirt to stay warm. None of us had the energy to climb back up to save the ropes so we carefully descended the snow. Halfway down we met a party on their way up and exchanged contact info on the off chance that they managed to pack out our ropes (they did!). At this point the steepness of the snow eased up and the sustained movement was starting to generate body heat. We arrived back to camp and were greeted by the guide who had been with us on the climb the day before. He held a fresh brewed cup of coffee he had made for us. Thanks Jack from <a href="https://www.indigoalpineguides.com/">Indigo Alpine Guides</a>.</p>
<p><a href="https://svbtleusercontent.com/3TABQ6jnDNxVmMyfcFiuhX0xspap.jpg"><img src="https://svbtleusercontent.com/3TABQ6jnDNxVmMyfcFiuhX0xspap_small.jpg" alt="Coffee and Ramen Boston Basin"></a></p>
<p><em>Coffee and ramen back at camp</em></p>
<p>At camp we ate some hot ramen. I still remember it tasting amazing. Deprivation can really enhance the pleasure of everyday things. Things were back to normal now and we took a casual pace back to the parking lot, stopped at Wendy’s and slept most of the rest of the day. </p>
<p>Cassondra and I had an amazing streak of successful summits when we first met that made us feel unstoppable. The past year was punctuated by a few disappointments but I think we’re just trying things that are harder for us and that’s okay. In the end it’s mostly about getting out there and getting back to the car.</p>
tag:tedpiotrowski.svbtle.com,2014:Post/how-to-find-the-current-time-for-any-location-using-mapbox-free-tier2022-11-18T10:26:04-08:002022-11-18T10:26:04-08:00How to find the current time for any location using Mapbox free tier<p><a href="https://shademap.app">shademap.app</a> simulates shadows based on the current time of day, but the current time of day in Seattle is not the current time of day in London. When it’s morning in Seattle and the shadows are cast to the west, it’s already evening in London and the shadows are being cast to the east. </p>
<p>While ShadeMap has always displayed the correct shadows, it has never adjusted times based on the location of the map. This meant that if a user from Seattle wanted to view 7AM shadows in London, they would have to set the time slider to 11PM Pacific Standard Time (which is 7AM in London). This is confusing as most people would not consider 11PM to be an early morning time. You can see an example of this below.</p>
<p><a href="https://svbtleusercontent.com/tZ3v39pPT44WRYXietws7z0xspap.png"><img src="https://svbtleusercontent.com/tZ3v39pPT44WRYXietws7z0xspap_small.png" alt="ShadeMap user time"></a></p>
<p>ShadeMap needed to display times using the map’s timezone, not the user’s timezone. In this case, September 22nd in London, the correct timezone to use is British Summer Time. Using British Summer Time, ShadeMap displays a more sensible morning time of 7:44AM.</p>
<p><a href="https://svbtleusercontent.com/vdHeoBq54tDZhwTi24ysL10xspap.png"><img src="https://svbtleusercontent.com/vdHeoBq54tDZhwTi24ysL10xspap_small.png" alt="ShadeMap location time"></a></p>
<p>So how do I display a given location’s current time? I will give the answer in this blogpost. That answer can be broken down into two parts:</p>
<ol>
<li>Using the Javascript Date object</li>
<li>Using freely available data to lookup a location’s timezone</li>
</ol>
<h2 id="javascript-date-object_2">Javascript Date object <a class="head_anchor" href="#javascript-date-object_2">#</a>
</h2>
<p>The Javascript side is simple. The <code class="prettyprint">Date</code> object’s <code class="prettyprint">.toLocaleTimeString()</code> method takes <code class="prettyprint">timeZone</code> as a parameter. If the <code class="prettyprint">timeZone</code> parameter is present, the method returns the time in the given timezone (don’t forget to capitalize the <code class="prettyprint">Z</code> or the <code class="prettyprint">timeZone</code> parameter will be ignored and the method will return your local time). I am in Seattle, so 7:00AM here is 10:00AM in New York City:</p>
<pre><code class="prettyprint lang-javascript">>> (new Date("11/18/22 7:00 AM")).toLocaleTimeString([], {
timeZone: "America/New_York"
});
// "10:00:00 AM"
</code></pre>
<p>You can try another <code class="prettyprint">timeZone</code> if you know it’s name by heart, but if you don’t then know that they come from <a href="https://en.wikipedia.org/wiki/Tz_database">tz database</a> which is a collaborative compilation of information about timezones intended to be used by computers. You can find available names in <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List">this table</a> under the <strong>TZ database name</strong> column.</p>
<h2 id="timezone-data-for-maps_2">Timezone data for maps <a class="head_anchor" href="#timezone-data-for-maps_2">#</a>
</h2>
<p>Because ShadeMap already uses Mapbox, I wanted a solution that worked well with Mapbox GL JS. There is this <a href="https://docs.mapbox.com/help/tutorials/create-a-timezone-finder-with-mapbox-tilequery-api/">example</a> of using Mapbox Tilequery API to lookup timezones but Mapbox only offers 100,000 free requests per month. Because we need to calculate the timezone any time the user moves or zooms the map these requests will add up.</p>
<p><a href="https://svbtleusercontent.com/bxF9TE3Y4LjnuQXNm51rg20xspap.png"><img src="https://svbtleusercontent.com/bxF9TE3Y4LjnuQXNm51rg20xspap_small.png" alt="Mapbox timezone tileset"></a></p>
<p>Instead, you can merge the <a href="https://studio.mapbox.com/tilesets/examples.4ze9z6tv/">vector map tileset</a> used by the Tilequery example (<code class="prettyprint">examples.4ze9z6tv</code>) with your current Mapbox tileset (ShadeMap uses Outdoors) using Mapbox Studio and then use the Mapbox GL JS <code class="prettyprint">queryRenderedFeatures([x,y])</code> method to retrieve the timezone data from your map itself. Below is a screenshot of adding the timezone data as a new <code class="prettyprint">Layer</code> on my existing tileset. (I set the layer opacity to 0 to make it invisible)</p>
<p><a href="https://svbtleusercontent.com/oTAWT8jBM9ZPGVzUENiuzC0xspap.png"><img src="https://svbtleusercontent.com/oTAWT8jBM9ZPGVzUENiuzC0xspap_small.png" alt="Mapbox Studio timezones"></a></p>
<p>In my tileset the <code class="prettyprint">Layer</code> is named <code class="prettyprint">Timezones</code> and this is how I retrieve the the timezone name for the center of the map anytime the map is moved (using the <code class="prettyprint">moveend</code> event)</p>
<pre><code class="prettyprint">map.queryRenderedFeatures(
[window.innerWidth / 2, window.innerHeight / 2],
{
layers: ["Timezones"],
}
);
</code></pre>
<h2 id="one-problem_2">One problem <a class="head_anchor" href="#one-problem_2">#</a>
</h2>
<p>The Mapbox timezone tileset does not work in all cases. It does not define timezones in the oceans and does not have data for low zoom levels. In those instances, <code class="prettyprint">queryRenderedFeatures</code> will fail to return a timezone. (<strong>update: the return value could also be “unihabited”, which you should treat as undefined</strong>) If this happens, we can approximate the timezone by using 15 degree bands of longitude as illustrated on this early time zone chart.</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/59/World_Time_Zone_Chart_1942.jpg/2880px-World_Time_Zone_Chart_1942.jpg" alt="Early timezone chart"></p>
<p>For each 15 degrees we travel west or east, the time changes by one hour and we can use the corresponding timezone names of <code class="prettyprint">Etc/GMT+1</code>, <code class="prettyprint">Etc/GMT+2</code>, etc or <code class="prettyprint">Etc/GMT-1</code>, <code class="prettyprint">Etc/GMT-2</code>, etc to adjust the users time accordingly. Below is a Javascript implementation of this approximation:</p>
<pre><code class="prettyprint">const getLongitudeTimeZone = (lng: number) => {
return `Etc/GMT+${-Math.ceil((lng / 7.5 - 1) / 2)}`.replace("+-", "-");
};
</code></pre>
<p>The approach documented in this blog is not perfect, but it is the approach that ShadeMap currently uses in production. It is cross browser, performant and best of all, it is free if you already use Mapbox GL JS to host your maps. </p>
<p>For more updates on how I build ShadeMap, you can follow me on Twitter <a href="https://twitter.com/shademap">@shademap</a></p>