diff --git a/Sources/SwiftSimplify/Point2DRepresentable.swift b/Sources/SwiftSimplify/Point2DRepresentable.swift index 8f9e946..bdec87b 100644 --- a/Sources/SwiftSimplify/Point2DRepresentable.swift +++ b/Sources/SwiftSimplify/Point2DRepresentable.swift @@ -36,6 +36,7 @@ import CoreLocation public protocol Point2DRepresentable { var xValue: Float { get } var yValue: Float { get } + var isMandatory: Bool { get } var cgPoint: CGPoint { get } @@ -47,6 +48,10 @@ public protocol Point2DRepresentable { public extension Point2DRepresentable { + var isMandatory: Bool { + return false + } + func equalsTo(_ compare: Self) -> Bool { xValue == compare.xValue && yValue == compare.yValue } diff --git a/Sources/SwiftSimplify/SwiftSimplify.swift b/Sources/SwiftSimplify/SwiftSimplify.swift index b2d63a9..5e36f6e 100644 --- a/Sources/SwiftSimplify/SwiftSimplify.swift +++ b/Sources/SwiftSimplify/SwiftSimplify.swift @@ -38,15 +38,29 @@ import Foundation public enum SwiftSimplify { public static func simplify(_ points: [P], tolerance: Float?, highestQuality: Bool = false) -> [P] { - guard points.count > 1 else { - return points - } - let sqTolerance = tolerance != nil ? (tolerance! * tolerance!) : 1.0 - var result = highestQuality ? points : simplifyRadialDistance(points, tolerance: sqTolerance) - result = simplifyDouglasPeucker(result, sqTolerance: sqTolerance) + + // Split the given points by their mandatory members. + // Since the first (and last) point of each simplification loop will be + // added to the final result, all mandatory points will be included. + let splitPoints = points + .split(whereSeparator: { $0.isMandatory }) + .map({ Array($0) }) - return result + var results: [[P]] = [] + + for somePoints in splitPoints { + guard somePoints.count > 1 else { + results.append(somePoints) + continue + } + + var result = highestQuality ? somePoints : simplifyRadialDistance(somePoints, tolerance: sqTolerance) + result = simplifyDouglasPeucker(result, sqTolerance: sqTolerance) + results.append(result) + } + + return results.flatMap({ return $0 }) } private static func simplifyRadialDistance(_ points: [P], tolerance: Float) -> [P] {