Draw polyline on map with Mapbox

tdrayson

I use Strava to track all my activities. On my personal website, I use the polyline that Strava generates in their API to draw the routes onto a map.

Example

screenshot 2022 11 04 at 19.16.17
This tutorial can be used with any polyline data that you have.

1. Load scripts and styles

We need to load 2 Mapbox scripts from a CDN.

Javascript – <script src='https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.js'></script>

CSS – <link href='https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css' rel='stylesheet' />

2. Decode polyline to array

We next need to convert our polyline to an array of lat and lon points. This is what Mapbox uses to plot the points on the map and draw a line between them.

Example of a Polyline

cwjwHggc@LCZ?DED@TGLQFELYDgAIsABo@GSGKAWEW@]Kw@@WCk@IYI{@Ia@Wo@GQSg@Gg@IOAaAPQ^@BAFGF@h@h@PFf@FVHH@FCXa@VmAPa@HYDETk@J]CI?u@MmACi@CMCeA@qAG{AEm@AWGc@?c@OsACECaAA{@@UC]DaA?m@NkA@uAAw@Iq@CE[_@IIEAMBGJ[BKCu@X[@e@J]BSHKAI@KH}@Do@JK?GBG?UFW?MD]@SFm@BQEQ@s@H[HKAWJI@QEG@m@Vq@BIBKA_@JqAP]?QFM?EBIAKDSAGBSIGH]FKPKCU@EDEAE@GCq@D_APIMOG[Be@Ak@LqAJw@NS?e@HM?MBa@Ds@JY@u@NKF_@DK?a@LU@KFIPEBMEMFECEGGCKSI_@]y@Gg@W}@AUUk@Ge@KOGUGMAWGICUQg@CWQm@AWMg@CSIQMu@MUSs@]gBKSAGGGSFGPGFGh@GJKp@EHGb@W`AKRY`@O`@EXKR]XEBI@QPILCRQN[n@KHQTOHe@`@CLEBKXERMX?^?HEFARG??HEB?JDDEBIXM~@GHIZGh@FZAHGt@CFEBKp@CFAHCACFHHR?JCBCV@`@^ZT\d@RN\p@\VPVRd@TLRf@`@b@Vj@PLZNDJTbA?HCFBPMb@MNEl@ENOrCG|@Dx@JLf@^j@T`@FDDLDJ?\VNDDBDCBDl@TdAj@x@^b@HRJPB`@RTDDDb@TNBd@RPBRJ^HJFX@PLLBHCJ@h@`@ZDZPTBt@T`@APPN?PLVHHF`@HLFZX\DDAFD^B|@f@^Bh@r@JHPFLNP\d@`@h@n@`@Nl@j@NBJFh@Hb@IDEXMVSb@UN?TE\BNCRDv@DZAL@LHLBt@GT?JFJ@

We are going to be using a function created from Peter Chng.

Add the function below into your functions.php or code snippet plugin as we will be using this in the next step.

PHP

        <?php

function decodePolylineToArray($encoded)
{
  $length = strlen($encoded);
  $index = 0;
  $points = array();
  $lat = 0;
  $lng = 0;

  while ($index < $length)
  {
    // Temporary variable to hold each ASCII byte.
    $b = 0;

    // The encoded polyline consists of a latitude value followed by a
    // longitude value.  They should always come in pairs.  Read the
    // latitude value first.
    $shift = 0;
    $result = 0;
    do
    {
      // The `ord(substr($encoded, $index++))` statement returns the ASCII
      //  code for the character at $index.  Subtract 63 to get the original
      // value. (63 was added to ensure proper ASCII characters are displayed
      // in the encoded polyline string, which is `human` readable)
      $b = ord(substr($encoded, $index++)) - 63;

      // AND the bits of the byte with 0x1f to get the original 5-bit `chunk.
      // Then left shift the bits by the required amount, which increases
      // by 5 bits each time.
      // OR the value into $results, which sums up the individual 5-bit chunks
      // into the original value.  Since the 5-bit chunks were reversed in
      // order during encoding, reading them in this way ensures proper
      // summation.
      $result |= ($b & 0x1f) << $shift;
      $shift += 5;
    }
    // Continue while the read byte is >= 0x20 since the last `chunk`
    // was not OR'd with 0x20 during the conversion process. (Signals the end)
    while ($b >= 0x20);

    // Check if negative, and convert. (All negative values have the last bit
    // set)
    $dlat = (($result & 1) ? ~($result >> 1) : ($result >> 1));

    // Compute actual latitude since value is offset from previous value.
    $lat += $dlat;

    // The next values will correspond to the longitude for this point.
    $shift = 0;
    $result = 0;
    do
    {
      $b = ord(substr($encoded, $index++)) - 63;
      $result |= ($b & 0x1f) << $shift;
      $shift += 5;
    }
    while ($b >= 0x20);

    $dlng = (($result & 1) ? ~($result >> 1) : ($result >> 1));
    $lng += $dlng;

    // The actual latitude and longitude values were multiplied by
    // 1e5 before encoding so that they could be converted to a 32-bit
    // integer representation. (With a decimal accuracy of 5 places)
    // Convert back to original values.
    $points[] = array($lat * 1e-5, $lng * 1e-5);
  }

  return $points;
}
      
Copy

3. Adding our map

Next we want to add our map and decode our polyline.

Members content only

Become a SnippetClub member to gain instant access to this tutorial plus tons more premium content.

Already a member? Log in below.

Login Form

👋🏻 Weekly Tutorial Digest

I send out a weekly newsletter with links to new tutorials written in the last week, you can subscribe below.

Newsletter

🔒I won't send you spam, I promise