You are here

public function GmapPolylineToolbox::getDPEncode in GMap Module 7.2

Implementation of the Douglas-Peucker polyline simplification algorithm.

See: http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/algorithm.html

former gmap_polyutil_dp_encode($points)

Return value

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.

1 call to GmapPolylineToolbox::getDPEncode()
GmapPolylineToolbox::getPolyline in lib/Drupal/gmap/GmapPolylineToolbox.php
Simplify a set of points and generate an "Encoded Polyline" for GMaps.

File

lib/Drupal/gmap/GmapPolylineToolbox.php, line 253
Contains GmapPolylineToolbox.php Encoded polyline utilities.

Class

GmapPolylineToolbox

Namespace

Drupal\gmap

Code

public function getDPEncode() {
  $this->pointWeights = array();
  $max_i = 0;
  if (count($this->points) > 2) {

    // The 'stack' holds line segments to be simplified.
    $stack[] = array(
      0,
      count($this->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 = $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;
        }
      }

      // 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 > self::GMAP_DP_EPSILON) {
        $this->pointWeights[$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 = $this
    ->getZoomLevels();
  $this->pointWeights[0] = $levels[0];
  $this->pointWeights[count($this->points) - 1] = $levels[0];
  return $this->pointWeights;
}