public function simplify(Polyline $polyline): Polyline
    {
        $counterPoints = $polyline->getNumberOfPoints();

        if ($counterPoints < 3) {
            return clone $polyline;
        }

        $result      = new Polyline();
        $bearingCalc = new BearingEllipsoidal();

        $points = $polyline->getPoints();

        $index = 0;

        // add the first point to the resulting polyline
        $result->addPoint($points[$index]);

        do {
            $index++;

            // preserve the last point of the original polyline
            if ($index === ($counterPoints - 1)) {
                $result->addPoint($points[$index]);
                break;
            }

            $bearing1 = $bearingCalc->calculateBearing($points[$index - 1], $points[$index]);
            $bearing2 = $bearingCalc->calculateBearing($points[$index], $points[$index + 1]);

            $bearingDifference = min(
                fmod($bearing1 - $bearing2 + 360, 360),
                fmod($bearing2 - $bearing1 + 360, 360)
            );

            if ($bearingDifference > $this->bearingAngle) {
                $result->addPoint($points[$index]);
            }
        } while ($index < $counterPoints);

        return $result;
    }