Ted Piotrowski

Code to live. Live to spend time outdoors.

Page 3


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

terrain-pro.jpg

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

Development

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

cover.jpg

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.

Traffic

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?

krakenimages-liT5AlTmC8I-unsplash.jpg

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 →


Argonaut and Sherpa, Part 2

Sherpa peak notch looking down

I woke up the next morning from the type of deep sleep that makes you forget where you put your phone the night before. Eventually I found it in the pocket of my puffy and we snoozed it for another hour. Going to bed the night before we both had a “let’s see how we feel in the morning” attitude, but now we were going to have to move if we had any chance of making it up Sherpa. The technique for me is to just fire up the stove and see how I feel, make and eat the oatmeal and see if I still want to go, filter the water and so on. Each small action added to the snowball effect and by 6:45am we were packed and walking on the Ingalls Creek trail.

Sherpa Peak meadow

Heading up the meadow from Ingalls Creek

The uphill trail to Sherpa starts on climbers left of a meadow or you can start in the bushes to the left, but the best track is eventually through the trees. It was a nice change of pace to quickly make...

Continue reading →


Argonaut and Sherpa, Part 1

Sunset on Argonaut

Sunset on Argonaut

A wise man once said, “Good plans are all alike, each bad plan is bad in its own way”. Cassondra suggested (for the record) that we try Argonaut and Sherpa over Labor Day weekend. I love being enveloped in 30 mph winds as I bask in summit glory, so the forecast seemed about right. We took most of Saturday to organise gear. After spending all summer in 30L packs, we decided to dust off the ol’ 60L to make sure we wouldn’t go hungry. We got a few hours of sleep, left Bothell at 4am and arrived at Beverly Turnpike trailhead around 6:30am. A casual 3 hour approach with brilliant views of Argonaut brought us to Ingalls Creek.

Ingalls Creek Forth Creek campsite

Basecamp: where we spent a total of 6 hours all weekend

We pitched camp and I asked Cassondra for the stats on Argonaut. Four thousand feet of gain? Hmmm, that’s not super tall. We can probably take a nap. We packed our summit packs and set out...

Continue reading →


Mount Rainier

IMG_8933.JPG

I first tried to climb Mt Rainier in 2011 with my friends Jordan and Jake. I had just spent the previous week on the John Muir trail camping above 12,000’ so I felt acclimated and confident I could do it. Jake was not feeling his best that day and stayed at Camp Muir. Jordan and I called it quits around 5am at Ingraham Flats. I’ve had a nagging feeling over the years that maybe we could have made it that day, but we weren’t really committed to trying. Stopping due to objective hazards like weather absolves you from failure, but giving up with gas in the tank can eat at you sometimes.

IMG_8901.JPG

The white whale

Well, I got a chance at redemption this week. Cassondra and I are very fortunate to be able to plan climbs on short notice and the weather on Sunday night was incredible - summit temperatures just below freezing and wind speeds at 5-10 mph. In order to climb Rainier you must reserve a...

Continue reading →