Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add routes and marker functionality #10

Merged
merged 2 commits into from
Dec 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/ActivityShortcode.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public static function init() {
}

// Shortcode handler function
// [ride id=id som=metric map_width="100%" map_height="400px"]
// [ride id=id som=metric map_width="100%" map_height="400px" markers=false]
public static function handler( $atts ) {
self::$add_script = true;

Expand All @@ -20,6 +20,7 @@ public static function handler( $atts ) {
'map_width' => '480',
'map_height' => '320',
'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
'markers' => false,
);

extract( shortcode_atts( $defaults, $atts ) );
Expand Down Expand Up @@ -67,7 +68,7 @@ public static function handler( $atts ) {
</tr>
</tbody>
</table>' .
WPStrava_StaticMap::get_image_tag( $ride_details, $map_height, $map_width ) .
WPStrava_StaticMap::get_image_tag( $ride_details, $map_height, $map_width, $markers ) .
'</div>';
} // End if( $ride_details ).
} // handler
Expand Down
152 changes: 152 additions & 0 deletions lib/Polyline.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<?php

/**
* Polyline
*
* PHP Version 5.3
*
* A simple class to handle polyline-encoding for Google Maps
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @category Mapping
* @package Polyline
* @author E. McConville <[email protected]>
* @copyright 2009-2015 E. McConville
* @license http://www.gnu.org/licenses/lgpl.html LGPL v3
* @version GIT: $Id: db01b3fea5d96533da928252135ac8f247c1b250 $
* @link https://github.com/emcconville/google-map-polyline-encoding-tool
*/

/**
* Polyline encoding & decoding class
*
* Convert list of points to encoded string following Google's Polyline
* Algorithm.
*
* @category Mapping
* @package Polyline
* @author E. McConville <[email protected]>
* @license http://www.gnu.org/licenses/lgpl.html LGPL v3
* @link https://github.com/emcconville/google-map-polyline-encoding-tool
*/
class Polyline
{
/**
* Default precision level of 1e-5.
*
* Overwrite this property in extended class to adjust precision of numbers.
* !!!CAUTION!!!
* 1) Adjusting this value will not guarantee that third party
* libraries will understand the change.
* 2) Float point arithmetic IS NOT real number arithmetic. PHP's internal
* float precision may contribute to undesired rounding.
*
* @var int $precision
*/
protected static $precision = 5;

/**
* Apply Google Polyline algorithm to list of points.
*
* @param array $points List of points to encode. Can be a list of tuples,
* or a flat on dimensional array.
*
* @return string encoded string
*/
final public static function encode( $points )
{
$points = self::flatten($points);
$encodedString = '';
$index = 0;
$previous = array(0,0);
foreach ( $points as $number ) {
$number = (float)($number);
$number = (int)round($number * pow(10, static::$precision));
$diff = $number - $previous[$index % 2];
$previous[$index % 2] = $number;
$number = $diff;
$index++;
$number = ($number < 0) ? ~($number << 1) : ($number << 1);
$chunk = '';
while ( $number >= 0x20 ) {
$chunk .= chr((0x20 | ($number & 0x1f)) + 63);
$number >>= 5;
}
$chunk .= chr($number + 63);
$encodedString .= $chunk;
}
return $encodedString;
}

/**
* Reverse Google Polyline algorithm on encoded string.
*
* @param string $string Encoded string to extract points from.
*
* @return array points
*/
final public static function decode( $string )
{
$points = array();
$index = $i = 0;
$previous = array(0,0);
while ($i < strlen($string)) {
$shift = $result = 0x00;
do {
$bit = ord(substr($string, $i++)) - 63;
$result |= ($bit & 0x1f) << $shift;
$shift += 5;
} while ($bit >= 0x20);

$diff = ($result & 1) ? ~($result >> 1) : ($result >> 1);
$number = $previous[$index % 2] + $diff;
$previous[$index % 2] = $number;
$index++;
$points[] = $number * 1 / pow(10, static::$precision);
}
return $points;
}

/**
* Reduce multi-dimensional to single list
*
* @param array $array Subject array to flatten.
*
* @return array flattened
*/
final public static function flatten( $array )
{
$flatten = array();
array_walk_recursive(
$array, // @codeCoverageIgnore
function ($current) use (&$flatten) {
$flatten[] = $current;
}
);
return $flatten;
}

/**
* Concat list into pairs of points
*
* @param array $list One-dimensional array to segment into list of tuples.
*
* @return array pairs
*/
final public static function pair( $list )
{
return is_array($list) ? array_chunk($list, 2) : array();
}
}
77 changes: 77 additions & 0 deletions lib/RouteShortcode.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

class WPStrava_RouteShortcode {
private static $add_script;

public static function init() {
add_shortcode( 'route', array( __CLASS__, 'handler' ) );
add_action( 'wp_footer', array( __CLASS__, 'print_scripts' ) );
}

// Shortcode handler function
// [route id=id som=metric map_width="100%" map_height="400px" markers=false]
public static function handler( $atts ) {
self::$add_script = true;

$defaults = array(
'id' => 0,
'som' => WPStrava::get_instance()->settings->som,
'map_width' => '480',
'map_height' => '320',
'athlete_token' => WPStrava::get_instance()->settings->get_default_token(),
'markers' => false,
);

extract( shortcode_atts( $defaults, $atts ) );

$strava_som = WPStrava_SOM::get_som( $som );
$route = WPStrava::get_instance()->routes;
$route_details = $route->getRoute( $id );

//sanitize width & height
$map_width = str_replace( '%', '', $map_width );
$map_height = str_replace( '%', '', $map_height );
$map_width = str_replace( 'px', '', $map_width );
$map_height = str_replace( 'px', '', $map_height );

if ( $route_details ) {
return '
<div id="ride-header-' . $id . '" class="wp-strava-ride-container">
<table id="ride-details-table">
<thead>
<tr>
<th>' . __( 'Est. Moving Time', 'wp-strava' ) . '</th>
<th>' . __( 'Distance', 'wp-strava' ) . '</th>
<th>' . __( 'Elevation Gain', 'wp-strava' ) . '</th>
</tr>
</thead>
<tbody>
<tr class="ride-details-table-info">
<td>' . $strava_som->time( $route_details->estimated_moving_time ) . '</td>
<td>' . $strava_som->distance( $route_details->distance ) . '</td>
<td>' . $strava_som->elevation( $route_details->elevation_gain ) . '</td>
</tr>
<tr class="ride-details-table-units">
<td>' . $strava_som->get_time_label() . '</td>
<td>' . $strava_som->get_distance_label() . '</td>
<td>' . $strava_som->get_elevation_label() . '</td>
</tr>
</tbody>
</table>' .
WPStrava_StaticMap::get_image_tag( $route_details, $map_height, $map_width, $markers ) .
'</div>';
} // End if( $route_details ).
} // handler

public static function print_scripts() {
if ( self::$add_script ) {
wp_enqueue_style( 'wp-strava-style' );

//wp_print_scripts('google-maps');
//wp_print_scripts('wp-strava-script');
}
}
}

// Initialize short code
WPStrava_RouteShortcode::init();
20 changes: 20 additions & 0 deletions lib/Routes.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php
/*
* Routes is a class wrapper for the Strava REST API functions.
*/

class WPStrava_Routes
{
const ROUTES_URL = 'http://app.strava.com/routes/';

/**
* Get single route by ID.
*
* @param int $route_id ID of activity to retrieve.
* @return object stdClass representing this route.
* @author Daniel Lintott
*/
public function getRoute($route_id ) {
return WPStrava::get_instance()->get_api()->get( "routes/{$route_id}" );
} // getRouteDetails
}
22 changes: 21 additions & 1 deletion lib/StaticMap.class.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

require_once WPSTRAVA_PLUGIN_DIR . 'lib/Polyline.php';

class WPStrava_StaticMap {

/**
Expand All @@ -12,8 +14,9 @@ class WPStrava_StaticMap {
* @param object $ride Ride object from strava.
* @param int $height Height of map in pixels.
* @param int $width Width of map in pixels.
* @param bool $markers Display start and finish markers.
*/
public static function get_image_tag( $ride, $height = 320, $width = 480 ) {
public static function get_image_tag( $ride, $height = 320, $width = 480, $markers = false ) {
$key = WPStrava::get_instance()->settings->gmaps_key;

// Short circuit if missing key or ride object doesn't have the data we need.
Expand All @@ -27,11 +30,28 @@ public static function get_image_tag( $ride, $height = 320, $width = 480 ) {

if ( ! empty( $ride->map->polyline ) && ( $url_len + strlen( $ride->map->polyline ) < $max_chars ) ) {
$url .= $ride->map->polyline;
$points = self::decode_polyline($ride->map->polyline);
} elseif ( ! empty( $ride->map->summary_polyline ) ) {
$url .= $ride->map->summary_polyline;
$points = self::decode_polyline($ride->map->summary_polyline);
}

if ($markers) {
$markers = '&markers=color:green|' . $points['start'][0] . ',' . $points['start'][1] .
'&markers=color:red|' . $points['finish'][0] . ',' . $points['finish'][1];
$url .= $markers;
}

return "<img class='wp-strava-img' src='{$url}' />";
}

private static function decode_polyline($enc) {
$points = Polyline::decode($enc);
$points = Polyline::pair($points);
$start = $points[0];
$finish = $points[count($points)-1];

return array('start' => $start, 'finish' => $finish);
}

}
14 changes: 13 additions & 1 deletion lib/Strava.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
require_once WPSTRAVA_PLUGIN_DIR . 'lib/LatestRidesWidget.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/LatestMapWidget.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/ActivityShortcode.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/RouteShortcode.class.php';
require_once WPSTRAVA_PLUGIN_DIR . 'lib/StaticMap.class.php';

class WPStrava {
Expand All @@ -13,6 +14,7 @@ class WPStrava {
private $settings = null;
private $api = array(); // Holds an array of APIs.
private $rides = null;
private $routes = null;

private function __construct() {
$this->settings = new WPStrava_Settings();
Expand Down Expand Up @@ -40,7 +42,9 @@ public function __get( $name ) {
// On-demand classes.
if ( $name == 'rides' ) {
return $this->get_rides();
}
} elseif ( $name == 'routes' ) {
return $this->get_routes();
}

if ( isset( $this->{$name} ) ) {
return $this->{$name};
Expand Down Expand Up @@ -71,6 +75,14 @@ public function get_rides() {
return $this->rides;
}

public function get_routes() {
if ( ! $this->routes ) {
require_once WPSTRAVA_PLUGIN_DIR . 'lib/Routes.class.php';
$this->routes = new WPStrava_Routes();
}
return $this->routes;
}

public function register_scripts() {
// Register a personalized stylesheet
wp_register_style( 'wp-strava-style', WPSTRAVA_PLUGIN_URL . 'css/wp-strava.css' );
Expand Down
5 changes: 5 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,14 @@ Also takes the following optional parameters:
* map_width - width (width of image in pixels).
* map_height - height (height of image in pixels).
* athlete_token - specify a different athlete (you can copy this value from https://www.strava.com/settings/api or the wp-strava settings page at /wp-admin/options-general.php?page=wp-strava-options).
* markers - Display markers at the start/finish point (true/false, defaults to false).

[ride] is an alias for [activity] and will accept the same parameters (kept for backwards compatibility).

[route id=NUMBER] - add to any page or post. Shows a summary of the activity plus a map if a google maps key has been added.

This also takes the same optional parameters as the activity shortcode above.

= Widgets =

Strava Latest Activity List - shows a list of the last few activities.
Expand Down