points = $points; $this->numLevels = $numLevels; $this->zoomFactor = $zoomFactor; $this->verySmall = $verySmall; $this->forceEndpoints = $forceEndpoints; for($i = 0; $i < $this->numLevels; $i++){ $this->zoomLevelBreaks[$i] = $this->verySmall*pow($this->zoomFactor, $this->numLevels-$i-1); } } protected $points; protected $numLevels; protected $zoomFactor; protected $verySmall; protected $forceEndpoints; protected $zoomLevelBreaks; // Returns the supplied coordinates public function getPoints() { return $this->points; } // The main method which is called to perform the encoding // Returns an associative array containing the encoded points, levels, // an escaped string literal containing the encoded points // It also returns the zoomFactor and numLevels public function dpEncode() { if(count($this->points) > 2) { $stack[] = array(0, count($this->points)-1); while(count($stack) > 0) { $current = array_pop($stack); $maxDist = 0; $absMaxDist = 0; for($i = $current[0]+1; $i < $current[1]; $i++) { $temp = self::distance($this->points[$i], $this->points[$current[0]], $this->points[$current[1]]); if($temp > $maxDist) { $maxDist = $temp; $maxLoc = $i; if($maxDist > $absMaxDist) { $absMaxDist = $maxDist; } } } if($maxDist > $this->verySmall) { $dists[$maxLoc] = $maxDist; array_push($stack, array($current[0], $maxLoc)); array_push($stack, array($maxLoc, $current[1])); } } } $encodedPoints = self::createEncodings($this->points, $dists); $encodedLevels = self::encodeLevels($this->points, $dists, $absMaxDist); $encodedPointsLiteral = str_replace('\\',"\\\\",$encodedPoints); $polyline["Points"] = $encodedPoints; $polyline["Levels"] = $encodedLevels; $polyline["PointsLiteral"] = $encodedPointsLiteral; $polyline["ZoomFactor"] = $this->zoomFactor; $polyline["NumLevels"] = $this->numLevels; return $polyline; } protected function computeLevel($dd) { if($dd > $this->verySmall) { $lev = 0; while($dd < $this->zoomLevelBreaks[$lev]) { $lev++; } } return $lev; } protected function distance($p0, $p1, $p2) { if($p1[0] == $p2[0] && $p1[1] == $p2[1]) { $out = sqrt(pow($p2[0]-$p0[0],2) + pow($p2[1]-$p0[1],2)); } else { $u = (($p0[0]-$p1[0])*($p2[0]-$p1[0]) + ($p0[1]-$p1[1]) * ($p2[1]-$p1[1])) / (pow($p2[0]-$p1[0],2) + pow($p2[1]-$p1[1],2)); if($u <= 0) { $out = sqrt(pow($p0[0] - $p1[0],2) + pow($p0[1] - $p1[1],2)); } if($u >= 1) { $out = sqrt(pow($p0[0] - $p2[0],2) + pow($p0[1] - $p2[1],2)); } if(0 < $u && $u < 1) { $out = sqrt(pow($p0[0]-$p1[0]-$u*($p2[0]-$p1[0]),2) + pow($p0[1]-$p1[1]-$u*($p2[1]-$p1[1]),2)); } } return $out; } protected static function encodeSignedNumber($num) { $sgn_num = $num << 1; if ($num < 0) { $sgn_num = ~($sgn_num); } return self::encodeNumber($sgn_num); } protected static function createEncodings($points, $dists) { $plat = 0; $plng = 0; $encoded_points = ""; for($i=0; $iforceEndpoints) { $encoded_levels .= self::encodeNumber($this->numLevels-1); } else { $encoded_levels .= self::encodeNumber($this->numLevels - self::computeLevel($absMaxDist)-1); } for($i=1; $inumLevels - self::computeLevel($dists[$i])-1); } } if($this->forceEndpoints) { $encoded_levels .= self::encodeNumber($this->numLevels -1); } else { $encoded_levels .= self::encodeNumber($this->numLevels - self::computeLevel($absMaxDist)-1); } return $encoded_levels; } protected static function encodeNumber($num) { $encodeString = ""; while($num >= 0x20) { $nextValue = (0x20 | ($num & 0x1f)) + 63; $encodeString .= chr($nextValue); $num >>= 5; } $finalValue = $num + 63; $encodeString .= chr($finalValue); return $encodeString; } } ?>