Skip to content

Commit

Permalink
Added setup.py, reorganized files
Browse files Browse the repository at this point in the history
  • Loading branch information
benmayersohn committed Apr 20, 2019
1 parent 372f42d commit 189c106
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 20 deletions.
14 changes: 12 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
__pycache__
*.kml
*.pyc
footprints.py
strava_*.py
gpxinfo.py
gpxinfo.py
Building Footprints.kml
basemap*
.idea
venv
shadegpx.egg-info
build
dist/
temp/
CherryBlossom2019.gpx
get_sun_cherryblossom.py
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ See [my blog post](https://www.benmayersohn.com/2019/03/made-in-the-shade/) for

### Files

Here is the structure of our repository:
<pre class="language-bash"><code class="language-bash">
shadegpx
|____badangle.jpg # good shot photo shade in front of the runner
|____goodangle.jpg # bad photo with a lot of harsh sunlight in the runner's face
|____examples # examples of GPX files, scripts to calculate shade factors, and output plots
|____shadegpx
| |____shadegpx.py # contains tools for computing shade factor
|____setup.py # for installation purposes
|____output # directory with output of simulations
|____README.md
|____download_race_gpx.py # script for downloading GPX file from race URL on Strava
</code></pre>

The file `shadegpx.py` contains two functions: `shade_factor`, which computes the above metric using the required parameters; and `shade_calc` which takes a GPX file, start time, and end time and returns the average shade factor at each coordinate over the specified duration.

My code makes use of the wonderful [PySolar](https://pysolar.readthedocs.io/en/latest/) library to calculate the sun elevation and azimuth at each time.
Expand Down
46 changes: 46 additions & 0 deletions download_race_gpx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Download GPX from a running-race page in Strava
For example, let's consider the Brooklyn Half. The link to the race and course map is here:
https://www.strava.com/running-races/2018-popular-brooklyn-half
But there is no option to download the GPX from here. If you visit the page and examine the HTML source code, you'll see this:
var runningRaceJson = {
"id": 1669,
"name": "Popular Brooklyn Half",
"distance": 21097.0,
"city": "Brooklyn",
"state": "NY",
"measurement_preference": null,
"url": "2018-popular-brooklyn-half",
"start_date_local": "2018-05-19T07:00:00Z",
"vanity": "2018-popular-brooklyn-half"
};
This gives us a route ID of 1669. We can use this to download the GPX data.
"""

import requests
import time

# Visit https://www.strava.com/settings/api to get all this info
CLIENT_ID = 'SEE LINK ABOVE'
ACCESS_TOKEN = 'SEE LINK ABOVE'

headers = {'Authorization': 'Bearer {}'.format(ACCESS_TOKEN)}

###########################

ROUTE_ID = 1669
filename = 'brooklynhalf.gpx'

# save to file
url = 'https://www.strava.com/api/v3/routes/{}/export_gpx'.format(ROUTE_ID)
r = requests.get(url, headers=headers)
with open(filename, 'wb') as fd:
for chunk in r.iter_content(chunk_size=128):
fd.write(chunk)


10 changes: 2 additions & 8 deletions examples/get_sun_nyc_half.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import matplotlib
matplotlib.use('Qt5Agg')
import os
import matplotlib.pyplot as plt
import datetime
from pytz import timezone
from datetime import timedelta
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import shadegpx
from shadegpx import shadegpx

filename = 'NYC-Half-2019.gpx'
tz = timezone('EST')
tz = timezone('US/Eastern')
start_time = datetime.datetime(2018, 3, 17, 7, 30, tzinfo=tz) # 7:30 AM EST
end_time = start_time + timedelta(hours=2, minutes=30) # 2.5 hrs of cheering

Expand Down
10 changes: 2 additions & 8 deletions examples/get_sun_prospect_park.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import matplotlib
matplotlib.use('Qt5Agg')
import os
import matplotlib.pyplot as plt
import datetime
from pytz import timezone
from datetime import timedelta
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import shadegpx
from shadegpx import shadegpx

filename = 'prospectpark.gpx'
tz = timezone('EST')
tz = timezone('US/Eastern')
start_time = datetime.datetime(2018, 2, 17, 10, tzinfo=tz) # 10 AM EST
end_time = start_time + timedelta(hours=1, minutes=30) # 1.5 hrs of cheering

Expand Down
61 changes: 61 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import io
import os

from setuptools import setup

# Package meta-data.
NAME = 'shadegpx'
DESCRIPTION = 'Compute "shade factor" on a runner during a race using GPX data and solar positions.'
URL = 'https://github.com/benmayersohn'
EMAIL = '[email protected]'
AUTHOR = 'Ben Mayersohn'
REQUIRES_PYTHON = '>=3.6.0'
VERSION = None

# What packages are required for this module to be executed?
REQUIRED = ['matplotlib>=3.0', 'pandas>=0.24', 'scipy>=1.2', 'seaborn>=0.9', 'numpy>=1.16', 'pysolar==0.8',
'pytz>=2018', 'gpxpy>=1.3', 'requests>=2.21']

here = os.path.abspath(os.path.dirname(__file__))

# Import the README and use it as the long-description.
try:
with io.open(os.path.join(here, 'README.md'), encoding='utf-8') as f:
long_description = '\n' + f.read()
except FileNotFoundError:
long_description = DESCRIPTION

# Load the package's __version__.py module as a dictionary.
about = {}
if not VERSION:
project_slug = NAME.lower().replace("-", "_").replace(" ", "_")
with open(os.path.join(here, project_slug, '__version__.py')) as f:
exec(f.read(), about)
else:
about['__version__'] = VERSION


# Where the magic happens:
setup(
name=NAME,
version=about['__version__'],
description=DESCRIPTION,
long_description=long_description,
long_description_content_type='text/markdown',
author=AUTHOR,
author_email=EMAIL,
python_requires=REQUIRES_PYTHON,
url=URL,
py_modules=['shadegpx'],
install_requires=REQUIRED,
include_package_data=True,
license='Freely Distributable',
classifiers=[
# Trove classifiers
# Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers
'License :: Freely Distributable',
'Programming Language :: Python',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6'
]
)
Empty file added shadegpx/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions shadegpx/__version__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
__title__ = 'shadegpx'
__description__ = 'Compute "shade factor" on a runner during a race using GPX data and solar positions.'
__url__ = 'https://www.github.com/benmayersohn'
__version__ = '0.0.1'
__author__ = 'Ben Mayersohn'
__author_email__ = '[email protected]'
__copyright__ = 'Copyright 2019 Ben Mayersohn'
9 changes: 7 additions & 2 deletions shadegpx.py → shadegpx/shadegpx.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import pysolar.solar as solar
from datetime import timedelta


def shade_factor(lat_deg, lon_deg, dx, dy, t):
altitude = np.pi * solar.get_altitude(lat_deg, lon_deg, t) / 180.
azimuth = np.pi * solar.get_azimuth(lat_deg, lon_deg, t) / 180.
Expand All @@ -11,7 +12,8 @@ def shade_factor(lat_deg, lon_deg, dx, dy, t):
theta_a[dx < 0] = np.pi - np.arctan2(dy[dx < 0], np.abs(dx[dx < 0]))
return 0.5 * (1 - np.sin(theta_a + azimuth)) * np.cos(altitude)

def shade_calc(filename, start_time, end_time):

def shade_calc(filename, start_time, end_time, return_xy=True):

# open GPX
with open(filename) as the_file:
Expand Down Expand Up @@ -75,4 +77,7 @@ def shade_calc(filename, start_time, end_time):

avg_color = np.mean(colors, axis=0)

return x, y, avg_color
if return_xy:
return x, y, avg_color

return lons, lats, avg_color

0 comments on commit 189c106

Please sign in to comment.