diff --git a/gmap_polyutil.inc b/gmap_polyutil.inc
index d33af92..b0a2700 100644
--- a/gmap_polyutil.inc
+++ b/gmap_polyutil.inc
@@ -16,6 +16,7 @@ DEFINE('GMAP_DP_EPSILON', 0.00001);
 DEFINE('GMAP_ZOOM_LEVELS', 18);
 DEFINE('GMAP_ZOOM_FACTOR', 2);
 
+use Drupal\gmap\GmapPolylineToolbox;
 
 /**
  * The following three functions will encode numbers so that they may be used
@@ -26,71 +27,63 @@ DEFINE('GMAP_ZOOM_FACTOR', 2);
  * differently--when generating Encoded Polylines, latitudes and longitudes are
  * encoded with gmap_polyutil_encode_signed(), and "levels" are encoded using
  * gmap_polyutil_encode_unsigned().
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setLatLonNumber($x)->getEncodedLatLon();
  */
 function gmap_polyutil_encode_latlon($x) {
-  $x = round($x * 1e5) << 1;
-  if ($x < 0) {
-    $x = ~$x;
-  }
-  return _gmap_polyutil_encode($x);
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setLatLonNumber($x)->getEncodedLatLon();
 }
 
+/**
+ * @param $x
+ * @return string
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setLatLonNumber($x)->getEncodedLevels();
+ */
 function gmap_polyutil_encode_levels($x) {
-  return _gmap_polyutil_encode(abs($x));
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setLatLonNumber($x)->getEncodedLevels();
 }
 
+/**
+ * @param $x
+ * @return string
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setLatLonNumber($x)->getEncode();
+ */
 function _gmap_polyutil_encode($x) {
-  $result = '';
-  while ($x >= 32) {
-    $result .= chr((32 | ($x & 31)) + 63);
-    $x >>= 5;
-  }
-  $result .= chr(($x & 31) + 63);
-  return $result;
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setLatLonNumber($x)->getEncode();
 }
 
 /**
  * Distance in two dimensions.
  * √((x1-x0)^2 + (y1-y0)^2)
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setLinePoints($p1, $p2)->getDist();
  */
 function gmap_polyutil_dist($p1, $p2) {
-  return sqrt(pow($p2[0] - $p1[0], 2) + pow($p2[1] - $p1[1], 2));
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setLinePoints($p1, $p2)->getDist();
 }
 
 /**
  * Distance between a point and a line segment.
+ *
  * @param $q
- *   Point to measure.
+ * Point to measure.
  * @param $p1
- *   Start point of line segment.
+ * Start point of line segment.
  * @param $p2
- *   End point of line segment.
+ * End point of line segment.
+ * @return float
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setMeasurePoint($q)->setLinePoints($p1, $p2)->getPointLineDist();
  */
 function gmap_polyutil_point_line_dist($q, $p1, $p2) {
-  if ($p1[0] == $p2[0] && $p1[1] == $p2[1]) {
-    // lp1 and lp2 are the same point--they don't define a line--so we return
-    // the distance between two points.
-    return gmap_polyutil_dist($q, $p1);
-  }
-
-  // Use the dot product to find where q lies with respect to the line segment
-  // p1p2. For more information, see:
-  //   http://local.wasp.uwa.edu.au/~pbourke/geometry/pointline/
-  //   http://www.codeguru.com/forum/printthread.php?t=194400
-  $u = (($p2[1] - $p1[1]) * ($q[1] - $p1[1]) + ($p2[0] - $p1[0]) * ($q[0] - $p1[0])) / (pow($p2[1] - $p1[1], 2) + pow($p2[0] - $p1[0], 2));
-
-  if ($u <= 0) { // point is not alongside segment, it is further off in $p1's direction
-    return gmap_polyutil_dist($q, $p1);
-  }
-  elseif ($u >= 1) { // point is not alongside segment, it is further off in $p2's direction
-    return gmap_polyutil_dist($q, $p2);
-  }
-  else { // point is alongside segment
-    // calculate distance between q and the nearest point on the line segment
-    // use $u to calculate the nearest point on the line segment:
-    //   p1 + u*(p2 - p1) => [p1x + u*(p2x - p1x), p1y + u*(p2y - p1y)]
-    return gmap_polyutil_dist($q, array($p1[0] + $u * ($p2[0] - $p1[0]), $p1[1] + $u * ($p2[1] - $p1[1])));
-  }
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setMeasurePoint($q)->setLinePoints($p1, $p2)->getPointLineDist();
 }
 
 /**
@@ -99,107 +92,51 @@ function gmap_polyutil_point_line_dist($q, $p1, $p2) {
  *
  * @param $points
  *   An array of coordinate pairs.
- * @return
+ * @return array
  *   An array of keys => weights; the keys correspond with indices of points in
  *   the $points array. Some points may be insignificant according to the
  *   algorithm--they will not have entries in the return array. The "weights"
  *   are actually the point's distance from the line segment that it subdivides.
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setPoints($points)->getDPEncode();
  */
 function gmap_polyutil_dp_encode($points) {
-  $weights = array();
-
-  if (count($points) > 2) {
-    // the 'stack' holds line segments to be simplified
-    $stack[] = array(0, count($points) - 1);
-
-    while (count($stack) > 0) {
-      // take a line segment to look at
-      $segment = array_pop($stack);
-
-      // figure out which subdividing point is the furthest off the line segment
-      $max_dist = 0;
-      for ($i = $segment[0] + 1; $i < $segment[1]; $i++) {
-        $dist = gmap_polyutil_point_line_dist($points[$i], $points[$segment[0]], $points[$segment[1]]);
-        if ($dist > $max_dist) {
-          $max_dist = $dist;
-          $max_i = $i;
-        }
-      }
-
-      // if the subdividing point found above is significantly off the line
-      // segment then we want to simplify further. Add sub-segments to the stack.
-      if ($max_dist > GMAP_DP_EPSILON) {
-        $weights[$max_i] = $max_dist;
-        array_push($stack, array($segment[0], $max_i));
-        array_push($stack, array($max_i, $segment[1]));
-      }
-    }
-  }
-
-  // The first and last points of the line should always be visible.
-  $levels = _gmap_polyutil_zoom_levels();
-  $weights[0] = $levels[0];
-  $weights[count($points) - 1] = $levels[0];
-
-  return $weights;
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setPoints($points)->getDPEncode();
 }
 
 /**
  * Simplify a set of points and generate an "Encoded Polyline" for Google Maps.
- * @param $points
+ * @param $points array
  *   An array of coordinate pairs as latitude, longitude.
- * @return
+ * @return array
  *   An array containing the point and zoom information necessary to display
  *   encoded polylines on Google Maps: 'points', 'levels', 'numLevels', and 'zoomFactor'.
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setPoints($points)->getPolyline();
  */
 function gmap_polyutil_polyline($points) {
-  $points_encoded = '';
-  $levels_encoded = '';
-
-  // simplify the line
-  $weights = gmap_polyutil_dp_encode($points);
-
-  $previous = array(0, 0);
-  foreach ($points as $i => $p) {
-    if (isset($weights[$i])) {
-      // encode each simplified point
-      // the deltas between points are encoded, rather than the point values themselves
-      $points_encoded .= gmap_polyutil_encode_latlon($p[0] - $previous[0]) . gmap_polyutil_encode_latlon($p[1] - $previous[1]);
-      $levels_encoded .= gmap_polyutil_encode_levels(_gmap_polyutil_get_zoom_level($weights[$i]));
-      $previous = $p;
-    }
-  }
-
-  return array(
-    'points' => $points_encoded,
-    'levels' => $levels_encoded,
-    'numLevels' => GMAP_ZOOM_LEVELS,
-    'zoomFactor' => GMAP_ZOOM_FACTOR,
-  );
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setPoints($points)->getPolyline();
 }
 
 /**
  * Build a logarithmic scale of zoom levels.
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->getZoomLevels();
  */
 function _gmap_polyutil_zoom_levels() {
-  static $levels;
-  if (!isset($levels)) {
-    for ($i = 0; $i < GMAP_ZOOM_LEVELS; $i++) {
-      $levels[$i] = GMAP_DP_EPSILON * pow(GMAP_ZOOM_FACTOR, GMAP_ZOOM_LEVELS - $i - 1);
-    }
-  }
-  return $levels;
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->getZoomLevels();
 }
 
 /**
  * Place points in levels based on their "weight" -- a value derived from
  * distance calculations in the simplification algorithm, gmap_polyutil_dp_encode().
+ *
+ * @deprecated use GmapPolylineToolbox::getInstance()->setWeight($weight)->getZoomLevel();
  */
 function _gmap_polyutil_get_zoom_level($weight) {
-  $levels = _gmap_polyutil_zoom_levels();
-  $i = 0;
-  while ($levels[$i] > $weight) {
-    $i++;
-  }
-  return GMAP_ZOOM_LEVELS - $i - 1;
+  include_once(drupal_get_path('module', 'gmap') . '/lib/Drupal/gmap/GmapPolylineToolbox.php');
+  return GmapPolylineToolbox::getInstance()->setWeight($weight)->getZoomLevel();
 }
diff --git a/lib/Drupal/gmap/GmapPolylineToolbox.php b/lib/Drupal/gmap/GmapPolylineToolbox.php
index 6278722..ff8f965 100644
--- a/lib/Drupal/gmap/GmapPolylineToolbox.php
+++ b/lib/Drupal/gmap/GmapPolylineToolbox.php
@@ -29,45 +29,46 @@ class GmapPolylineToolbox {
 
   const GMAP_ZOOM_FACTOR = 2;
 
-  public $latlonNumber;
+  private $latlonNumber;
 
-  public $latlonLevels;
+  private $latlonLevels;
 
-  public $encodedlatlonNumber;
+  private $encodedlatlonNumber;
 
-  public $encoded;
+  private $encoded;
 
-  public $startPoint;
+  private $startPoint;
 
-  public $endPoint;
+  private $endPoint;
 
-  public $distance;
+  private $distance;
 
-  public $measurePoint;
+  private $measurePoint;
 
   /**
    * @var array
    */
-  public $points;
+  private $points;
 
   /**
    * @var array
    */
-  public $pointWeights;
+  private $pointWeights;
 
-  public $weight;
+  private $weight;
 
-  static public $levels;
+  static protected $levels;
 
   /**
    * @var static Singleton instance
    */
-  static private $gmapInstance;
+  static protected $gmapInstance;
 
   /**
    * do not change
    */
   private function __construct() {
+    self::$levels = $this->getZoomLevels();
   }
 
   /**
@@ -109,7 +110,7 @@ class GmapPolylineToolbox {
     if ($this->latlonNumber < 0) {
       $this->latlonNumber = ~($this->latlonNumber);
     }
-    $this->encodedlatlonNumber = _gmap_polyutil_encode($this->latlonNumber);
+    $this->encodedlatlonNumber = $this->setLatLonNumber($this->latlonNumber)->getEncode();
     return $this->encodedlatlonNumber;
   }
 
@@ -118,7 +119,7 @@ class GmapPolylineToolbox {
    * @return string
    */
   function getEncodedLevels() {
-    $this->latlonLevels = _gmap_polyutil_encode(abs($this->latlonNumber));
+    $this->latlonLevels = $this->setLatLonNumber(abs($this->latlonNumber))->getEncode();
     return $this->latlonLevels;
   }
 
@@ -177,7 +178,7 @@ class GmapPolylineToolbox {
     if ($this->startPoint[0] == $this->endPoint[0] && $this->startPoint[1] == $this->endPoint[1]) {
       // lp1 and lp2 are the same point--they don't define a line--so we return
       // the distance between two points.
-      $this->distance = gmap_polyutil_dist($this->measurePoint, $this->startPoint);
+      $this->distance = $this->getDist();
       return $this->distance;
     }
 
@@ -188,19 +189,20 @@ class GmapPolylineToolbox {
     $u = (($this->endPoint[1] - $this->startPoint[1]) * ($this->measurePoint[1] - $this->startPoint[1]) + ($this->endPoint[0] - $this->startPoint[0]) * ($this->measurePoint[0] - $this->startPoint[0])) / (pow($this->endPoint[1] - $this->startPoint[1], 2) + pow($this->endPoint[0] - $this->startPoint[0], 2));
 
     if ($u <= 0) { // point is not alongside segment, it is further off in $p1's direction
-      return gmap_polyutil_dist($this->measurePoint, $this->startPoint);
+      return $this->setLinePoints($this->measurePoint, $this->startPoint)->getDist();
     }
     elseif ($u >= 1) { // point is not alongside segment, it is further off in $p2's direction
-      return gmap_polyutil_dist($this->measurePoint, $this->endPoint);
+      return $this->setLinePoints($this->measurePoint, $this->endPoint)->getDist();
     }
     else { // point is alongside segment
       // calculate distance between q and the nearest point on the line segment
       // use $u to calculate the nearest point on the line segment:
       //   p1 + u*(p2 - p1) => [p1x + u*(p2x - p1x), p1y + u*(p2y - p1y)]
-      $this->distance = gmap_polyutil_dist($this->measurePoint, array(
+
+      $this->distance = $this->setLinePoints($this->measurePoint, array(
         $this->startPoint[0] + $u * ($this->endPoint[0] - $this->startPoint[0]),
         $this->startPoint[1] + $u * ($this->endPoint[1] - $this->startPoint[1])
-      ));
+      ))->getDist();
       return $this->distance;
     }
   }
@@ -246,7 +248,10 @@ class GmapPolylineToolbox {
         // figure out which subdividing point is the furthest off the line segment
         $max_dist = 0;
         for ($i = $segment[0] + 1; $i < $segment[1]; $i++) {
-          $dist = gmap_polyutil_point_line_dist($this->points[$i], $this->points[$segment[0]], $this->points[$segment[1]]);
+          $dist = $this
+            ->setMeasurePoint($this->points[$i])
+            ->setLinePoints($this->points[$segment[0]], $this->points[$segment[1]])
+            ->getPointLineDist();
           if ($dist > $max_dist) {
             $max_dist = $dist;
             $max_i = $i;
@@ -264,7 +269,7 @@ class GmapPolylineToolbox {
     }
 
     // The first and last points of the line should always be visible.
-    $levels = _gmap_polyutil_zoom_levels();
+    $levels = $this->getZoomLevels();
     $this->pointWeights[0] = $levels[0];
     $this->pointWeights[count($this->points) - 1] = $levels[0];
 
@@ -285,15 +290,23 @@ class GmapPolylineToolbox {
     $levels_encoded = '';
 
     // simplify the line
-    $this->pointWeights = gmap_polyutil_dp_encode($this->points);
+    $this->pointWeights = $this->getDPEncode();
 
     $previous = array(0, 0);
     foreach ($this->points as $i => $p) {
       if (isset($this->pointWeights[$i])) {
         // encode each simplified point
         // the deltas between points are encoded, rather than the point values themselves
-        $points_encoded .= gmap_polyutil_encode_latlon($p[0] - $previous[0]) . gmap_polyutil_encode_latlon($p[1] - $previous[1]);
-        $levels_encoded .= gmap_polyutil_encode_levels(_gmap_polyutil_get_zoom_level($this->pointWeights[$i]));
+        $points_encoded .= $this
+          ->setLatLonNumber(($p[0] - $previous[0]) . $this
+              ->setLatLonNumber($p[1] - $previous[1])
+              ->getEncodedLatLon())
+          ->getEncodedLatLon();
+        $levels_encoded .= $this
+          ->setLatLonNumber($this
+            ->setWeight($this->pointWeights[$i])
+            ->getZoomLevel())
+          ->getEncodedLevels();
         $previous = $p;
       }
     }
@@ -341,7 +354,6 @@ class GmapPolylineToolbox {
    * @return int
    */
   function getZoomLevel() {
-    self::$levels = _gmap_polyutil_zoom_levels();
     $i = 0;
     while (self::$levels[$i] > $this->weight) {
       $i++;
