{"id":18873,"date":"2020-05-24T16:38:44","date_gmt":"2020-05-24T20:38:44","guid":{"rendered":"https:\/\/nuxx.net\/blog\/?p=18873"},"modified":"2020-12-27T10:08:10","modified_gmt":"2020-12-27T15:08:10","slug":"high-resolution-strava-global-heatmap-in-josm","status":"publish","type":"post","link":"https:\/\/nuxx.net\/blog\/2020\/05\/24\/high-resolution-strava-global-heatmap-in-josm\/","title":{"rendered":"High Resolution Strava Global Heatmap in JOSM"},"content":{"rendered":"\n<p><a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-18914 size-large\" src=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche-1024x556.png\" alt=\"\" width=\"1024\" height=\"556\" srcset=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche-1024x556.png 1024w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche-300x163.png 300w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche-768x417.png 768w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche-1536x834.png 1536w, https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_high_res_avalanche-2048x1111.png 2048w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>Mapping trails in <a href=\"https:\/\/www.openstreetmap.org\">OpenStreetMap<\/a> (OSM), using <a href=\"https:\/\/josm.openstreetmap.de\/\">JOSM<\/a>, is done by overlaying one or more data sources, then hand-drawing the trail locations using this background data as a guide. While not a default in JOSM, with a little know-how and a <a href=\"https:\/\/www.strava.com\/subscribe\">paid Strava Subscription<\/a> the <a href=\"https:\/\/www.strava.com\/heatmap\">Strava Global Heatmap<\/a> data for this can be used as well.<\/p>\n<p>While there&#8217;s a fair bit of info about doing this scattered across some JOSM tickets (eg: <a href=\"https:\/\/josm.openstreetmap.de\/ticket\/16100\">#16100<\/a>), this post is to document how I make this work for me by creating a custom <a href=\"https:\/\/josm.openstreetmap.de\/wiki\/Help\/Preferences\/Imagery\">Imagery provider<\/a>. Because there isn&#8217;t an official (and robust) plugin to authenticate JOSM against Strava it&#8217;s a little tricky, but overall isn&#8217;t bad.<\/p>\n<p>First, you need to sign into Strava, then go to the Global Heatmap and get the values of the three cookies <em>CloudFront-Key-Pair-ID<\/em>, <em>CloudFront-Policy<\/em>, and <em>CloudFront-Signature<\/em>. These values are essentially saved credentials, and by using them in a custom <em>Imagery provider<\/em> <a href=\"https:\/\/en.wikipedia.org\/wiki\/URL\">URL<\/a>, JOSM will use these to access the Global Heatmap data via your account and make it available as an <a href=\"https:\/\/josm.openstreetmap.de\/wiki\/Help\/Menu\/Imagery\">Imagery<\/a> layer.<\/p>\n<p>The easiest way to get these cookie values is to use the Developer Tools built into your web browser:<\/p>\n<ol>\n<li>Launch your web browser, either Firefox, Chrome, or Edge.<\/li>\n<li>Go to the <a href=\"https:\/\/www.strava.com\/heatmap\">Strava Global Heatmap<\/a>, sign in if needed (check the <em>Remember me<\/em> checkbox), and be sure it&#8217;s properly displaying high resolution data.<\/li>\n<li>Load the developer tools for your browser to show cookie details:\n<ul>\n<li>Firefox: Click the <em>Hamburger Menu<\/em> \u2192 <em>Web Developer<\/em> \u2192 <em>Storage Inspector<\/em> (or press Shift-F9), expand <em>Cookies<\/em> and click <em>https:\/\/www.strava.com<\/em>.<\/li>\n<li>Chrome: Click the Three Dots Menu \u2192 More tools \u2192 Developer tools (or press Ctrl-Shift-I), select the <em>Application <\/em>tab, expand <em>Cookies<\/em>, then click <em>https:\/\/www.strava.com<\/em>.<\/li>\n<li>Edge: Click the Three Dots Menu \u2192 More tools \u2192 Developer Tools (or press F12), select the <em>Storage<\/em> tab, expand <em>Cookies<\/em>, then click <em>heatmap<\/em>.<\/li>\n<\/ul>\n<\/li>\n<li>Get the value of three cookies, C<em>loudFront-Key-Pair-ID<\/em>, <em>CloudFront-Policy<\/em>, and <em>CloudFront-Signature<\/em>, and make note of them (in Notepad or such). You&#8217;ll need them to build the custom URL. Here&#8217;s examples of what the three cookies will look like:\n<ul>\n<li>CloudFront-Key-Pair-ID: <code>VB4DYFIQ7PHQZMAGVMOI<\/code><\/li>\n<li>CloudFront-Policy: <code>FTUGYikErADOqGmqEnPTaaZ3LCE2QbOJSSsmPD9vdY0hfjSWWHZBgnRai1aQcvUe<br \/>2YtgkG3KdP8IencRaGrS3I5bHAeabQ4I776T7UipDPFzNVh9PBIRvb3DjDqVfssp<br \/>mBA5IrxacQGfB2YmKwegp9OTBfUFkvtEQOlzeXfqeuc34cp408GYXSvp2DsnxKFh<br \/>ofbwygraae3VZqnZxp3vBpz3lBoyPnBEN1djJkxpU1fF_<\/code><\/li>\n<li>CloudFront-Signature: <code>lrMJG0L6zJilpSdGEnWug0zskcMDD5VVGdSRu~P4OOVp5z8iCMBRBO040wxunEQQ<br \/>p0wVHdaCaTFAVqiM0jC0AApW7HigXjx57nsoEVslOzRuoX9S3g-<br \/>FCePWYNPyZcJ95~6SoGdNRHz-<br \/>b-ZZxk4ERhjzXCNIEE8Gt5uImitcPN3HRlhXexS39g30~5OEv~4FHzXfOOIhQ5X5<br \/>cGUD0SpdYviBE~vkAJCk3TbQMXxlJbyX4OOL5xvVPv5WjzMKTuvEk6Z9m6iFBbZc<br \/>8ov4qS60th0tZ1RM4pNMoIWKoqPS3~UPGISe6Xa8Kq-<br \/>tQPxHlfGciI5uhoTp4b7lPussh52QaN__<\/code><\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>(Note: These are not real values, you&#8217;ll need to look up your own.)<\/p>\n<p>Next is to add a custom imagery provider for the <a href=\"https:\/\/www.strava.com\/heatmap\">Strava Global Heatmap<\/a> to JOSM using a URL that you build with these cookie values:<\/p>\n<ol>\n<li><em>Edit<\/em> \u2192 <em>Preferences&#8230; (F9)<\/em> \u2192 <em>Imagery preferences<\/em><\/li>\n<li>Create a new TMS string by replacing the [] sections in the following string with the cookie values from above, without the []s:\n<ul>\n<li><code>tms[15]:https:\/\/heatmap-external-{switch:a,b,c}.strava.com\/tiles-auth\/all\/hot\/{zoom}\/{x}\/{y}.png?Key-Pair-Id=<strong>[CloudFront-Key-Pair-ID]<\/strong>&amp;Policy=<strong>[CloudFront-Policy]<\/strong>&amp;Signature=<strong>[CloudFront-Signature]<\/strong><\/code><\/li>\n<\/ul>\n<\/li>\n<li>Add a new TMS entry by clicking the <em>+TMS<\/em> button.<\/li>\n<li>Paste the string from Step 2 into Box 4, <em>Edit generated TMS URL (optional)<\/em>, and then give it a name in Box 5, such as <em>Strava Global Heatmap High-Res<\/em>.<\/li>\n<li>Click OK twice to return to the main JOSM window, and then try to use this layer over some existing data, just as you would aerial imagery.<\/li>\n<\/ol>\n<p>If it doesn&#8217;t work, double-check your URL and be sure the entered cookie values are right, including the underscores after <em>CloudFront-Policy<\/em> and <em>CloudFront-Signature<\/em>. Also be sure you haven&#8217;t logged out of Strava, as this will expire the cookies. (If you make changes to the URL in JOSM you will need to delete the existing imagery layer and then re-add it to have the new URL used.)<\/p>\n<p>These cookie values, in particular <em>CloudFront-Signature<\/em>, will occasionally change as cookies are expired and reset or if you log out of Strava. If things were working and then stopped, you may need to get new cookie values from your browser and update the TMS strings.<\/p>\n<p>By default the TMS URL we started with shows the default heatmap, for all activity types, with <em>Hot<\/em> coloring. Depending on what other data you are working with it may be useful to show just <em>Ride<\/em> or <em>Run<\/em> data, perhaps in different colors. In the TMS URL, the first part after <em>tiles-auth<\/em> is the type of data, and the second is the color. By using this format, replacing [data] and [color], you can create additional heatmap layers:<\/p>\n<p><code>tms[15]:https:\/\/heatmap-external-{switch:a,b,c}.strava.com\/tiles-auth\/<strong>[data]<\/strong>\/<strong>[color]<\/strong>\/{zoom}\/{x}\/{y}.png?Key-Pair-Id=[CloudFront-Key-Pair-ID]&amp;Policy=[CloudFront-Policy]&amp;Signature=[CloudFront-Signature]<\/code><\/p>\n<p>Valid values for type of data: <em>all<\/em>, <em>ride<\/em>, <em>run<\/em>, <em>water<\/em>, <em>winter<\/em>.<\/p>\n<p>Valid values for heatmap color: <em>hot,<\/em> <em>blue<\/em>, <em>purple<\/em>, <em>gray<\/em>, <em>bluered<\/em>.<\/p>\n<p>Creating multiple layers, riding-only and running-only, of different colors was extremely useful when mapping <a href=\"http:\/\/www.cityofboynecity.com\/**avalanche-trail-maps-192\/\">Avalanche Preserve Recreation Area in Boyne City<\/a> as cyclists tend to stick to the mountain bike trails and runners to the hiking trails. While I had orthorectified maps from both the city and <a href=\"https:\/\/www.tommba.org\/\">TOMMBA<\/a>, the separate riding and running heatmaps made the routes much clearer. In the example image above (<a href=\"https:\/\/nuxx.net\/blog\/wp-content\/uploads\/2020\/05\/josm_strava_ride-hot_run-blue.png\">link<\/a>) I have the <em>Ride<\/em> data as color <em>Hot<\/em> and the <em>Run<\/em> data as color <em>Blue; <\/em>perfect for illustrating the mountain bike vs. hiking trails.<\/p>\n<p>If you&#8217;d like to see this area as an example load the are around <a href=\"https:\/\/www.openstreetmap.org\/changeset\/85690641\">changeset 85690641<\/a> or a bounding box with the following values and see for yourself:<\/p>\n<ul>\n<li>Max Lat: 45.2077126<\/li>\n<li>Min Lat: 45.1878747<\/li>\n<li>Min Lon: -85.0339222<\/li>\n<li>Max Lon: -84.9832392<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,57,29],"tags":[],"class_list":["post-18873","post","type-post","status-publish","format-standard","hentry","category-cycling","category-mapping","category-outdoors","entry"],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/18873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/comments?post=18873"}],"version-history":[{"count":34,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/18873\/revisions"}],"predecessor-version":[{"id":18915,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/posts\/18873\/revisions\/18915"}],"wp:attachment":[{"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/media?parent=18873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/categories?post=18873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuxx.net\/blog\/wp-json\/wp\/v2\/tags?post=18873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}