fix bugs
This commit is contained in:
88
app/Services/PolylineEncoder.php
Normal file
88
app/Services/PolylineEncoder.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
/**
|
||||
* Class PolylineEncoder
|
||||
*
|
||||
* Encodes a list of latitude/longitude coordinates into an encoded polyline string.
|
||||
*
|
||||
* This implementation is compatible with Google's Polyline Algorithm Format:
|
||||
* https://developers.google.com/maps/documentation/utilities/polylinealgorithm
|
||||
*
|
||||
* Example input:
|
||||
* [
|
||||
* [lat, lng],
|
||||
* [lat, lng]
|
||||
* ]
|
||||
*
|
||||
* or if `$lng_lat_format = true`:
|
||||
* [
|
||||
* [lng, lat],
|
||||
* [lng, lat]
|
||||
* ]
|
||||
*
|
||||
* @package App\Services
|
||||
*/
|
||||
class PolylineEncoder
|
||||
{
|
||||
/**
|
||||
* Encode an array of coordinates into a polyline string.
|
||||
*
|
||||
* Each coordinate is encoded as a delta from the previous point,
|
||||
* scaled by the given precision factor.
|
||||
*
|
||||
* @param array $coords Array of coordinate pairs:
|
||||
* - default: [lat, lng]
|
||||
* - if $lng_lat_format = true: [lng, lat]
|
||||
* @param int $precision Number of decimal places to preserve (default: 6)
|
||||
* @param bool $lng_lat_format If true, input is treated as [lng, lat] instead of [lat, lng]
|
||||
*
|
||||
* @return string Encoded polyline string
|
||||
*/
|
||||
public function encodePolyline(array $coords, int $precision = 6, bool $lng_lat_format = false): string
|
||||
{
|
||||
$factor = 10 ** $precision;
|
||||
$output = '';
|
||||
$prevLat = 0;
|
||||
$prevLng = 0;
|
||||
|
||||
foreach ($coords as [$a, $b]) {
|
||||
[$lat, $lng] = $lng_lat_format ? [$b, $a] : [$a, $b];
|
||||
|
||||
$output .= $this->encodeValue((int)round($lat * $factor) - $prevLat);
|
||||
$output .= $this->encodeValue((int)round($lng * $factor) - $prevLng);
|
||||
|
||||
$prevLat = (int)round($lat * $factor);
|
||||
$prevLng = (int)round($lng * $factor);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a single integer value using Google's polyline encoding algorithm.
|
||||
*
|
||||
* Steps:
|
||||
* - Left shift the value
|
||||
* - Invert bits if negative
|
||||
* - Split into 5-bit chunks
|
||||
* - Convert to ASCII characters
|
||||
*
|
||||
* @param int $value Signed integer delta to encode
|
||||
*
|
||||
* @return string Encoded character sequence
|
||||
*/
|
||||
public function encodeValue(int $value): string
|
||||
{
|
||||
$value = $value < 0 ? ~($value << 1) : ($value << 1);
|
||||
$result = '';
|
||||
|
||||
while ($value >= 0x20) {
|
||||
$result .= chr((0x20 | ($value & 0x1f)) + 63);
|
||||
$value >>= 5;
|
||||
}
|
||||
|
||||
return $result . chr($value + 63);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user