Ted Piotrowski

Code to live. Live to spend time outdoors.

Page 2

Thoughts on refilling isobutane canisters


I have a hard time throwing things away and that can turn into a hoarding habit at times. For over 10 years I’ve been holding on to various isobutane fuel canisters in the hopes of burning that last bit of gas. So finally I purchased a refill valve on Amazon and decided to consolidate the gas into a single canister.

I punctured (swift blow with the pick of an ice axe) empty canisters to make sure all the gas was gone and weighed them:

  • 3.4oz (small)
  • 4.5oz (medium)
  • 7.3oz (large)

Then I weighed full canisters:

  • 7.4oz (small)
  • 13.1oz (medium)
  • 23oz (large)


Now I knew when to stop transferring gas either because a canister was empty or a canister was full. (I should also say MSR does an excellent job putting gross/net weight on their canisters which aligns with these numbers)

Next I took an bowl, filled it with an ice cube tray’s worth of ice, placed the destination canister inside...

Continue reading →

Full Day Sun Exposure

ShadeMap now displays the sunniest and shadiest locations over the course of a day. Click the full day sun exposure button located near the lower left corner of the screen to try it in Manhattan.


Initially ShadeMap answered the question: where can I find shade now (or at a specific date and time)? However, knowing how much sun or shade a location gets over the course of an entire day can be valuable as well. For example, finding a parking spot in the shade on a hot day or determining what snow fields will melt the fastest.


To implement this feature, ShadeMap takes a snapshot of shadows over the course of a day and overlays them on top of each other in real-time. The darkest areas receive the least sun and the lightest areas, the most.


In the image above the dark splotches are Pennsylvania pit mines. These massive pits receive virtually no sunlight during the winter. Below you...

Continue reading →

Climbing in El Potrero Chico


Tropical vacation? Maybe not…

Cassondra had school vacation in February and we decided to check out El Potrero Chico. Because we are very last minute planners, we didn’t book cheap flights ahead of time, but did manage to find a last-minute, week-long, all-inclusive package (flights, hotel and car rental) from Expedia for around $1000. The main downside was that the hotel was in Monterrey, about an hour drive from Potrero Chico.

Day 1


Driving around in the Nissan March

We left Seattle at 7am, laid-over in Houston and landed in Monterrey in the early afternoon where we were presented with a freshly washed Nissan March. It was still early so we decided to forgo the hotel and head straight to see Potrero Chico. It was dark when we arrived, but the canyon was illuminated with floodlights (appears to be a weekend thing) and as we walked through the gate we occasionally glimpsed...

Continue reading →

Shade Map Pro

tl;dr Shade Map continues to be free for anyone, but a new paid tier provides the latest map data and additional features. See screenshots or read on for more detail


Pro includes elevation contour lines and 3D terrain

My hope is to democratize software. I admire how open source software has leveled the playing field between corporations and solo entrepreneurs. Websites like Wikipedia and MDN provide free, valuable information to anyone with an internet connection. Similarly, I’ve aspired to make Shade Map free as an educational resource and as a tool to improve people’s lives.

That being said, there are some technologies Shade Map relies on that are not yet freely or easily available. Among these are up-to-date map tiles, high quality elevation data and 3D terrain rendering.

For the past year I have relied on Mapbox and Mapbox GL JS for these features and although it offers a...

Continue reading →

Free GeoIP API with Cloudflare Workers

A nice feature of Google Maps is to display a map of your region whenever you visit maps.google.com. This is useful because you likely want to look at a map of something nearby instead of on the other side of the world. The way Google knows your general location is because it knows what IP address you’re requesting the map from and it has a database mapping IP addresses to geographic coordinates. This process is called Geolocation, or more specifically GeoIP lookup.

There are free GeoIP API services out there. Here is an example of an IP lookup and response

const response = await fetch(`http://ip-api.com/json/${ip}?fields=lat,lon`);

// response JSON
    "lat": 47.6722,
    "lon": -122.1257

But because an IP can only be resolved server side and because browsers do not allow cross-domain requests, you have to query ip-api.com on the server side or use a Cloudflare worker.

Or… you...

Continue reading →

ShadeMap 2021 Wrap Up

Shade Map in 3D


A big change happened this fall. Right around the one-year mark I finally succeeded in migrating Shade Map (shademap.app) onto a vector based map. Up until this point I used tiled image maps which downloaded many small, square image tiles and stitched them together. Vector based maps instead download lists of GPS coordinates and use these coordinates to draw the roads, buildings and contour lines in the browser. Because the data is drawn on the fly, you can choose to draw the map with south pointing up. Or you can draw the map as if it’s tilted at 45 degrees. So Shade Map can now be rotated and viewed in 3D perspective, just like Google Maps. Here’s a demo I posted on Twitter at the time:

The other...

Continue reading →

Creating a custom tile set with Mapbox Tile Server


Mapbox is sponsoring a Maptober challenge to teach users how to create their own map vector tilesets. When you load a map you see roads, borders, place names, bodies of water and much more. But what if you wanted to include your own features on the map? They could be trees or something abstract like the path you take when you swim across a lake.

For the challenge, I decided to map my Strava activities. I have gone running, climbing and skiing in a few different places this year and I wanted to picture it all on a single map. I wrote a program to export my last 200 activities into GeoJSON format, which is required for creating custom map tiles. The GeoJSON contains latitude and longitude points along the route I took as well as some metadata like the total distance and elevation gain. Here’s a truncated sample:

    "type": "Feature",
    "geometry": {
        "type": "LineString",

Continue reading →

Summer update on Shade Map

It’s already mid October, so the summer update is bleeding into fall. Here’s a traffic update and three things I managed to accomplish over the summer months.


Screenshot 2021-10-21 at 22.47.23.png

shademap.app had just under 9,000 visitors over the summer months versus 2,000 visitors during spring. The spikes in the chart are an occasional mention on Hacker News or Reddit.

My biggest stress in the spring was paying the bill for map tiles, but everything turned out okay when I switched from using PNG image tiles to vector based tiles. Where before I was paying close to $100 a month, I can now serve up to 50,000 visitors per month using Mapbox’s free-tier. Along the way I released react-leaflet-vector-tile-layer for rendering vector tiles since I couldn’t find an existing solution.

Screenshot 2021-10-21 at 22.58.41.png

Google traffic has also been increasing nicely. I am number one for shademap and shade map keywords and in the top 5 results for...

Continue reading →

What’s up with tree shaking?


Me when I found out how tree shaking really works

I’m willing to bet you have a lot of “dead” code in your webpack bundles. I used to think unused code was magically excluded by webpack but it turned out I was wrong. Oh the woe for slow websites around the world. Here is how it all started…

The Discovery

I put a website into Page Speed Insights today and one of the opportunities to make my site faster was to reduce unused Javascript. It appeared that around half of my Javascript was unused. If this Javascript is unused, why is it being bundled into my application?

A few years ago I heard the term tree-shaking, which was the removal of unused code from a bundle. The big hype I inferred was that Webpack 4 would tree-shake while bundling, thus eliminating unused code and making bundles significantly smaller. Was this true? Not really, for two reasons:

  1. Packages have to explicitly...

Continue reading →

Three things I did to speed up my WebGL code

I made this visualisation to illustrate what happens during the day of the September equinox. On this day the sun rises almost directly to the east and sets almost directly to the west. But the thing I was most proud of is that this isn’t a FFMPEG compilation of screenshots but an actual recording of WebGL code executing in the browser on a retina screen.

How I got here

It’s been a learning journey to remove jitter/jank/lag from ShadeMap. The first version used +/-5 minute increment buttons because using a slider quickly caused the app to freeze. I’ve been able to improve the rendering performance by a factor of 20 over the last 6 months. Today, I’m even offering a High Quality retina option, which means crunching 4 times as many pixels as before.

I was a complete beginner at WebGL and at first I used the gpu.js library to write my rendering code in plain Javascript and transpile it...

Continue reading →