[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-75407":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":15,"forks30d":15,"starsTrendScore":19,"compositeScore":20,"rankGlobal":9,"rankLanguage":9,"license":21,"archived":22,"fork":22,"defaultBranch":23,"hasWiki":24,"hasPages":22,"topics":25,"createdAt":9,"pushedAt":9,"updatedAt":26,"readmeContent":27,"aiSummary":28,"trendingCount":15,"starSnapshotCount":15,"syncStatus":29,"lastSyncTime":30,"discoverSource":31},75407,"running-heatmap","moresamwilson\u002Frunning-heatmap","moresamwilson","Generate heatmaps from your Strava export - frequency, pace, heart rate and gradient.",null,"Jupyter Notebook",446,42,8,1,0,13,18,298,39,4.9,"MIT License",false,"main",true,[],"2026-06-12 02:03:33","# Running Heatmap\n\nCode from [this video](https:\u002F\u002Fyoutu.be\u002FPA8d4u5T4BM?si=83GTMI449kCsgb4B) — shared by request.\n\nTurns a Strava data export into an interactive heatmap. No API needed - just the zip file Strava lets you download.\n\nThe output is a single HTML file with six layers you can switch between:\n\n| Layer | Colour | Shows |\n|---|---|---|\n| Frequency (linear) | Orange | How often you've run each path |\n| Frequency (log) | Orange | Same, log scale - better when a few paths dominate |\n| Pace (average) | Blue | Average pace - brighter = faster |\n| Heart rate (average) | Red | Average HR - brighter = higher |\n| Gradient (absolute) | White | Steepness - brighter = steeper |\n| Gradient (change) | Green \u002F purple | Direction - green = descending, purple = ascending |\n\n## Setup\n\n```\npip install -r requirements.txt\n```\n\n## Usage\n\n1. Request your data from Strava: **Settings → My Account → Download or Delete Your Account → Download Request**\n2. Unzip the export and place the folder next to `heatmap.ipynb`\n3. Update the config cell:\n\n```python\nACTIVITIES_DIR = \"your_export_folder\"   # name of the unzipped folder\nACTIVITY_TYPES = [\"Run\"]                # Run, Ride, Hike, Walk, ...\nDATE_FROM      = \"2024-01-01\"           # or None for no lower limit\nDATE_TO        = \"2024-12-31\"           # or None for today\n```\n\n4. Run all cells. Map is saved to `outputs\u002Fheatmap.html`.\n\n### Home detection\n\nHome is auto-detected from the most common activity start point in the date range, then only activities within `RADIUS_KM` of that point are included. It's a heuristic — if you started more runs from somewhere else (work, a club) than home in that period, that location wins. Override it with `HOME_LAT` \u002F `HOME_LON` if needed.\n\n### Caching\n\nParsing `.fit.gz` files is slow so GPS data is cached after the first run. Changing the date range or config won't re-parse files you've already loaded.\n\n---\n\n## Notes\n\n### The frequency map measures time on path, not number of passes\n\nGPS records at ~1 Hz, so the frequency layers count GPS samples per pixel rather than distinct activities. A slower run deposits more points on the same path than a faster one. In practice this means the map shows something closer to time spent on each road than how many times you've run it - which is arguably more useful, but worth knowing.\n\nThe log scale version exists because a few favourite routes tend to dominate completely on a linear scale, washing out everything else.\n\n### Pace and HR are all-time averages\n\nEach pixel is the mean across every activity that ever crossed it. A route you used to run slowly but now run fast will show somewhere in the middle. Narrow the date range if you want a specific period.\n\n### The gradient layers are only as good as GPS altitude\n\nGPS altitude is much noisier than horizontal position - typically ±10–20 m vertically versus ±3–5 m horizontally. The gradient layers are reliable on hilly terrain but can look noisy on flat routes where the signal-to-noise is poor.\n\n### Why the code uses two different projections\n\nThe raster grid is built in Web Mercator (EPSG:3857) so it aligns directly to the map tile basemap without any reprojection. But Web Mercator distorts distances at higher latitudes, so anything involving real-world metres - the clip radius around home, and the rise\u002Frun calculation for gradient - uses a local UTM projection instead. The visual output is unaffected, it just means the underlying measurements are accurate.\n","该项目用于从Strava导出的数据生成热力图，包括频率、配速、心率和坡度等信息。其核心功能是将Strava提供的zip文件转换成一个包含六个可切换图层的交互式HTML热力图，无需API调用。技术上，项目使用Jupyter Notebook编写，并通过解析GPS数据来绘制地图，支持缓存以提高处理效率。适用于跑步爱好者分析自己的运动习惯和路线选择，尤其是在需要可视化特定时间段内活动模式时特别有用。",2,"2026-06-11 03:52:39","CREATED_QUERY"]