Bij Unit-T, waar ik werk, hebben ze fantastische ideeën.
Na de virtuele dodentocht, waarin ik 300 km aflegde in 4 weken, kwam het feestcomité met het idee om eens zelf intern een challenge te organiseren:
Afhankelijk van hoeveel collega’s zich inschreven zou dat ofwel een makkie, ofwel een onmogelijke opdracht worden.
Om de technische kant te faciliteren werd mijn hulp ingeroepen. Op één of andere manier moeten de kilometers kunnen geregistreerd worden en moet de voortgang kunnen bijgehouden worden.
In Strava is er helaas geen mogelijkheid om een ‘wandel- & loopclub’ aan te maken. In de loopclub worden geen wandelactiviteiten meegeteld en in een algemene club zou fietsen ook meetellen (en dan wordt het te makkelijk).
Ik besloot dus gebruik te maken van de Strava API. Dat bleek makkelijker dan verwacht. In enkele tellen was die actief.
Een API
Dankzij wat copy/paste werk vanuit github.com/iamstuartwilson kreeg ik in no time activiteiten binnen en kon ik die importeren in een database.
$yesterdaysepoch = mktime(0, 0, 0, date("m"), date("d")-8, date("Y")); // niet yesterday, maar laatste week :)
if ($yesterdaysepoch < $challengestart) $yesterdaysepoch = $challengestart; // niets opvragen vóór de startdatum
$response = $api->get(
'clubs/772000/activities',
[
'page' => 1,
'per_page' => 200,
'after' => $yesterdaysepoch
]
);
$i = $t = $a = $b = 0;
//vars voor logging
foreach($response as $activity) {
$t++;
if (is_object($activity)) {
$activityname = $activity->name;
$activitytype = $activity->type;
$activitydistance = $activity->distance;
$activitymovingtime = $activity->moving_time;
$athletename = $activity->athlete->firstname." ".$activity->athlete->lastname;
$stmt = $db->prepare("INSERT IGNORE INTO `strava_walkchallenge` (`actvityname`, `activitytype`, `activitydistance`, `activitymovingtime`, `athletename`) VALUES (?,?,?,?,?);")
$stmt->bind_param("ssdis", $activityname, $activitytype, $activitydistance, $activitymovingtime, $athletename);
$stmt->execute();
if ($stmt->affected_rows > 0) {
if ($activitytype == 'Walk' || $activitytype == 'Run' || $activitytype == 'Hike') {
$a = $a + $stmt->affected_rows;
}
else {
$b = $b + $stmt->affected_rows;
}
}
$stmt->close();
$allownaam = str_replace(' ', '%', $athletename);
$stmt = $db->prepare("INSERT IGNORE INTO `strava_allowlist` (`naam`, `allow`) VALUES (?,0);");
$stmt->bind_param("s", $allownaam);
$stmt->execute();
$stmt->close();
$stmt = $db->prepare("UPDATE `swatweb`.`strava_settings` SET `value`='".date("Y-m-d H:i:s")."' WHERE `key`='lastupdate';");
$stmt->execute();
if ($stmt->affected_rows != 1) {
}
$stmt->close();
$i++;
}
}
Dan was het enkel kwestie om deze te filteren op “hike, run, walk”, een cronjob op te zetten en een mooi tellertje tonen.
if($stmt=$db->prepare("SELECT SUM(s.activitydistance) as walkeddistance, MAX(s.added) AS lastactivity, COUNT(DISTINCT s.athletename) AS actievedlns
FROM strava_walkchallenge s
WHERE s.activitytype IN ('Walk', 'Run', 'Hike')
AND s.del = 0
AND REPLACE(s.athletename,' ','%') IN (SELECT naam FROM strava_allowlist WHERE allow=1)
AND s.added > from_unixtime((SELECT `value` FROM strava_settings WHERE `key` = 'challenge_start'))")){
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
$walkeddistance = number_format((($row['walkeddistance'])/1000),0,',', '');
$kmtegaan = (int)2505-(int)$walkeddistance;
$lastactivity = $row['lastactivity'];
$actievedlns = $row['actievedlns'];
}
$stmt->close();
}
$t0 = new DateTime($startdate);
$t1 = new DateTime(date("Y-m-d"));
$t2 = new DateTime($stopdate);
$days2go = $t1->diff($t2)->format('%r%a');
if ($actievedlns > 0) {
if (((int)$actievedlns>0) && ((int)$days2go > 0)) {
$kmperdlnperdag = number_format(((int)$kmtegaan/(int)$actievedlns/(int)$days2go),0);
}
}
else {
$kmperdlnperdag = 9999;
}
$challengedays = $t0->diff($t2)->format('%r%a') +1; //+1 want de stopdatum zelf telt ook mee.
$schema_kmpd = $challenge_distance/$challengedays;
$schema_dayspassed = $challengedays-$days2go;
$schema_targettoday = $schema_kmpd*$schema_dayspassed;
$schema = $walkeddistance-$schema_targettoday;
Visualisatie
Om het nog wat visueler te maken was er ook het idee de virtueel afgelegde afstand op een kaart te tonen.
De tracelijn heb ik op een alternatieve manier op de map getoverd. Ik plot gewoon alle trackpoints. Niet de ideale manier, wel de makkelijkste 🙂
Ik exporteerde daarvoor eerst de GPX file zodat ik alle trackpoints had. Omdat dit er veel te veel waren, heb ik die via een online Tracks optimizer (source op GitHub) verminderd tot een 2500-tal punten. Deze in een array gestoken en afhankelijk van de afgelegde afstand tot dat punt plotten in’t groen en vanaf daar de resterende array plotten in ’t rood met een interval van een 100-tal punten.
for (var i = 0; i < allPoints.length; i = i + jumper) {
var iconcolor = 'green';
var myLatlng = new google.maps.LatLng(allPoints[i][1], allPoints[i][0]);
if (i > <?= $walkeddistance ?>) {
iconcolor = 'red';
jumper = 100;
var marker = new google.maps.Marker({
position : myLatlng,
map : map,
icon : {
path: google.maps.SymbolPath.CIRCLE,
scale: 3,
strokeColor: iconcolor,
fillColor: iconcolor,
fillOpacity: 100
}
});
}
else {
jumper = 2;
var marker = new google.maps.Marker({
position : myLatlng,
map : map,
icon : {
path: google.maps.SymbolPath.CIRCLE,
scale: 2,
strokeColor: iconcolor,
fillColor: iconcolor,
fillOpacity: 100
}
});
}
}
Natuurlijk mag javascriptvuurwerk ook niet ontbreken als de challenge werd gehaald 🙂
Google Maps
Om Google Maps te mogen gebruiken is er ook een API key nodig. Dit is gratis als je onder een bepaald aantal requests blijft. Gelukkig kan je onder Billing > Budgets & Alerts op voorhand instellen hoeveel euro je er voor over hebt.
https://developers.google.com/maps/documentation/javascript/get-api-key
De Challenge zelf
Uiteindelijk schreven meer dan dertig collega’s zich in. Elk 85 km in een maand zou een uitdaging worden, maar niet onmogelijk. Halverwege was het wat spannend, maar dankzij een eindsprintje haalden we het.
In deze 31 dagen durende challenge legde ik zelf 210 km te voet af. Soms onder een stralende zon, soms in de regen, maar vooral door de modder
Een infographic mag dan ook niet ontbreken 🙂
Een reactie achterlaten