Кому интересно, переписал класс с c++ на php.
Этот код
https://github.com/VladimirBalun/Algorithms/blob/m...
Объяснение в этой статье
https://habr.com/ru/post/448618/
class RamerDuglasPeucker
{
/* @var Monitoring $start_point */
/* @var Monitoring $end_point */
/* @var Monitoring $point */
private static function get_distance_between_point_and_line_segment($start_point, $end_point, $point)
{
// тут мои кастомные методы (getLatitude, getLongitude). Можно заменить их на ['lat'], ['long']
$x = $point->getLatitude();
$y = $point->getLongitude();
$x1 = $start_point->getLatitude();
$y1 = $start_point->getLongitude();
$x2 = $end_point->getLatitude();
$y2 = $end_point->getLongitude();
$double_area = abs(($y2 - $y1) * $x - ($x2 - $x1) * $y + $x2 * $y1 - $y2 * $x1);
$line_segment_length = sqrt(pow(($x2 - $x1), 2) + pow(($y2 - $y1), 2));
if ($line_segment_length != 0)
return $double_area / $line_segment_length;
else
return 0;
}
private static function simplify_points(array $src_points, array &$dest_points, float $tolerance, int $begin, int $end)
{
if ($begin + 1 == $end)
return;
$max_distance = -1;
$max_index = 0;
for ($i = $begin + 1; $i < $end; $i++) {
$cur_point = $src_points[$i];
$start_point = $src_points[$begin];
$end_point = $src_points[$end];
$distance = RamerDuglasPeucker::get_distance_between_point_and_line_segment($start_point, $end_point, $cur_point);
if ($distance > $max_distance) {
$max_distance = $distance;
$max_index = $i;
}
}
if ($max_distance > $tolerance) {
RamerDuglasPeucker::simplify_points($src_points, $dest_points, $tolerance, $begin, $max_index);
$dest_points[] = $src_points[$max_index];
RamerDuglasPeucker::simplify_points($src_points, $dest_points, $tolerance, $max_index, $end);
}
}
public static function downsample(array &$src_points, float $tolerance)
{
if ($tolerance <= 0)
return $src_points;
$dest_points = [];
$dest_points[] = reset($src_points);
RamerDuglasPeucker::simplify_points($src_points, $dest_points, $tolerance, 0, count($src_points) - 1);
$dest_points[] = end($src_points);
return $dest_points;
}
}