-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(library): Port PolyUtil to Kotlin and enhance tests #1565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This commit ports the `MathUtil` class from Java to idiomatic Kotlin. The existing tests were leveraged to ensure that the port was successful, and a new test was added for `MathUtil` to ensure that it is well-tested.
This commit ports the `SphericalUtil` class from Java to idiomatic Kotlin. The existing tests were leveraged to ensure that the port was successful, and the tests were updated to use Google Truth assertions.
This commit introduces a significant modernization of the `PolyUtil` class by porting it from Java to idiomatic Kotlin. This change improves the code's conciseness, readability, and null safety. The key changes in this commit are: - **Porting `PolyUtil` to Kotlin**: The `PolyUtil` class has been completely rewritten in Kotlin, taking advantage of features like top-level functions, default arguments, and extension functions. The public API has been preserved with `@JvmStatic` annotations to ensure backward compatibility for Java consumers. - **Updating tests to use Google Truth**: The corresponding `PolyUtilTest` has been updated to use Google Truth assertions. This makes the tests more readable and expressive.
Code Coverage
|
kikoso
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks really good! One thought is if we want to incorporate at this point a wrapper for LatLng, but it can be introduced when more classes are migrated.
Co-authored-by: Enrique López-Mañas <[email protected]>
# [3.16.0](v3.15.0...v3.16.0) (2025-08-26) ### Features * **library:** Port PolyUtil to Kotlin and enhance tests ([#1565](#1565)) ([90c56df](90c56df))
|
🎉 This PR is included in version 3.16.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
|
🎉 This PR is included in version 3.16.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
1 similar comment
|
🎉 This PR is included in version 3.16.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
| * using either geodesic (great circle) or rhumb (loxodromic) paths. | ||
| */ | ||
| object PolyUtil { | ||
| private const val DEFAULT_TOLERANCE = 0.1 // meters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dkhawk DEFAULT_TOLERANCE used to be public API, now it's private. Unintentional breaking change?
| public static final double DEFAULT_TOLERANCE = 0.1; // meters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @bubenheimer, apologies for the delay. This should have been marked, in fact, as a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, @kikoso, I wish there was some documentation why 0.1 as a default on various APIs in this and related libs, rather than a seemingly arbitrary constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bubenheimer , 0.1 is generally used as a de facto tolerance value when using the Douglas-Peucker algorithm, which is the one used in the Polyline. Agree, this should be clarified in the documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, that is a good rationale!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kikoso At the same time, in my opinion, if it is a commonly used constant with that algorithm, then it is meaningful for this API, and should remain a part of the public API, not just some default value. For example, in my case, I try to use accuracy of device location as the tolerance value for some of these APIs, but when accuracy is unavailable, I need to default to something else, i.e. the 0.1 constant, now with an added comment, rather than call the method with a different signature to automatically get the default, which is even more obscure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding to that, it appears the DEFAULT_TOLERANCE constant isn't actually used by the Douglas-Peucker implementation unless it's explicitly passed in.
This isn't a new change with the Kotlin port; the previous Java implementation had the same behavior (see PolyUtil.java): https://github.com/googlemaps/android-maps-utils/blob/0bb1d348290ee02c74c02fef13e0e560b4bd370f/library/src/main/java/com/google/maps/android/PolyUtil.java
The current simplify() method still requires the tolerance as an argument, so users would only be using that 0.1 value if they were passing DEFAULT_TOLERANCE in manually. The tolerance value is the primary lever for simplification and is highly use-case-dependent.
Low Tolerance (e.g., 0.1): In my testing, this was often overkill and didn't provide a meaningful reduction in points.
Higher Tolerance (e.g., 5.0 - 10.0): This offered dramatic point savings. While it does create a noticeable (but often acceptable) change in the polyline's shape, it's very effective for things like GPS track rendering (which often has overly dense location data).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And FWIW, we made the constant public again: #1619
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you, @dkhawk, for these valuable details, which may come in handy for me in the future. At this time I've been using DEFAULT_TOLERANCE just as a fallback for isLocationOnEdge(), but I did not heavily test it. I should use simplify() as well, though, as I need to constrain polygon complexity for performance.
This commit introduces a significant modernization of the
PolyUtilclass by porting it from Java to idiomatic Kotlin. This change improves the code's conciseness, readability, and null safety.The key changes in this commit are:
PolyUtilto Kotlin: ThePolyUtilclass has been completely rewritten in Kotlin, taking advantage of features like top-level functions, default arguments, and extension functions. The public API has been preserved with@JvmStaticannotations to ensure backward compatibility for Java consumers.PolyUtilTesthas been updated to use Google Truth assertions. This makes the tests more readable and expressive.