/** * Simplifies the given polyline * * 1. calculate the bearing angle between the first two points p1 and p2: b1 * 2. calculate the bearing angle between the next two points p2 and p3: b2 * 3. calculate the difference between b1 and b2: deltaB; if deltaB is * smaller than the threshold angle, remove the middle point p2 * 4. start again at (1.) as long as the polyline contains more points * * @param Polyline $polyline * * @return Polyline */ public function simplify(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; }