Skip to content

Commit

Permalink
Add auto cropping
Browse files Browse the repository at this point in the history
  • Loading branch information
remisalmon committed Feb 8, 2021
1 parent fcd69c6 commit aa922d0
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 10 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ Optimized for cycling activities :bicyclist:
## Features

* Minimal Python dependencies (`numpy`+`matplotlib`)
* Fast (3x faster than `gpxpy.parse()`)
* Fast (parse 3x faster than `gpxpy.parse`)

## Usage

* Download your GPX files to the `gpx` folder (https://support.strava.com/hc/en-us/articles/216918437-Exporting-your-Data-and-Bulk-Export)
* Install dependencies from `requirements.txt`
* Install the python dependencies from `requirements.txt`
* Run `python strava_local_heatmap.py`

### Command-line options
Expand Down Expand Up @@ -44,7 +44,7 @@ On the use of histogram equalization: [https://medium.com/strava-engineering/the
## Examples

command|output
--|--
-------|------
`strava_local_heatmap.py`|![heatmap.png](images/heatmap.png)
`strava_local_heatmap.py --orange`|![orange.png](images/orange.png)
`strava_local_heatmap.py --csv`|See https://umap.openstreetmap.fr/en/map/demo-heatmap_261644 (by [@badele](https://github.com/badele))
Expand Down
25 changes: 18 additions & 7 deletions strava_local_heatmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,15 @@
import matplotlib.pyplot as plt

# globals
HEATMAP_MAX_SIZE = (2160, 3840) # maximum heatmap size in pixel
HEATMAP_MARGIN_SIZE = 32 # margin around heatmap trackpoints in pixel

PLT_COLORMAP = 'hot' # matplotlib color map
MAX_TILE_COUNT = 100 # maximum number of tiles to download
MAX_HEATMAP_SIZE = (2160, 3840) # maximum heatmap size in pixel

OSM_TILE_SERVER = 'https://maps.wikimedia.org/osm-intl/{}/{}/{}.png' # OSM tile url from https://wiki.openstreetmap.org/wiki/Tile_servers
OSM_TILE_SIZE = 256 # OSM tile size in pixel
OSM_MAX_ZOOM = 19 # OSM maximum zoom level
OSM_MAX_TILE_COUNT = 100 # maximum number of tiles to download

# functions
def deg2xy(lat_deg, lon_deg, zoom):
Expand Down Expand Up @@ -179,8 +181,8 @@ def main(args):
x_tile_min, y_tile_max = map(int, deg2xy(lat_min, lon_min, zoom))
x_tile_max, y_tile_min = map(int, deg2xy(lat_max, lon_max, zoom))

if ((x_tile_max-x_tile_min+1)*OSM_TILE_SIZE <= MAX_HEATMAP_SIZE[0] and
(y_tile_max-y_tile_min+1)*OSM_TILE_SIZE <= MAX_HEATMAP_SIZE[1]):
if ((x_tile_max-x_tile_min+1)*OSM_TILE_SIZE <= HEATMAP_MAX_SIZE[0] and
(y_tile_max-y_tile_min+1)*OSM_TILE_SIZE <= HEATMAP_MAX_SIZE[1]):
break

zoom -= 1
Expand All @@ -189,7 +191,7 @@ def main(args):

tile_count = (x_tile_max-x_tile_min+1)*(y_tile_max-y_tile_min+1)

if tile_count > MAX_TILE_COUNT:
if tile_count > OSM_MAX_TILE_COUNT:
exit('ERROR zoom value too high, too many tiles to download')

# download tiles
Expand Down Expand Up @@ -236,9 +238,11 @@ def main(args):
xy_data = deg2xy(lat_lon_data[:, 0], lat_lon_data[:, 1], zoom)

xy_data = np.array(xy_data).T
xy_data = np.round((xy_data-[x_tile_min, y_tile_min])*OSM_TILE_SIZE) # to supertile coordinates
xy_data = np.round((xy_data-[x_tile_min, y_tile_min])*OSM_TILE_SIZE)

ij_data = np.flip(xy_data.astype(int), axis = 1) # to supertile coordinates

for j, i in xy_data.astype(int):
for i, j in ij_data:
data[i-sigma_pixel:i+sigma_pixel, j-sigma_pixel:j+sigma_pixel] += 1.0

# threshold to max accumulation of trackpoint
Expand Down Expand Up @@ -290,6 +294,13 @@ def main(args):
for c in range(3):
supertile[:, :, c] = (1.0-data)*supertile[:, :, c]+data*color[c]

# crop image
i_min, j_min = np.min(ij_data, axis = 0)
i_max, j_max = np.max(ij_data, axis = 0)

supertile = supertile[max(i_min-HEATMAP_MARGIN_SIZE, 0):min(i_max+HEATMAP_MARGIN_SIZE, supertile.shape[0]),
max(j_min-HEATMAP_MARGIN_SIZE, 0):min(j_max+HEATMAP_MARGIN_SIZE, supertile.shape[1])]

# save image
plt.imsave(args.output, supertile)

Expand Down

0 comments on commit aa922d0

Please sign in to comment.