Skip to content
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

feat: Adding PolyUtil extensions to List<LatLng> #16

Merged
merged 3 commits into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 55 additions & 3 deletions maps-utils-ktx/src/main/java/com/google/maps/android/ktx/LatLng.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,65 @@
*
*/
@file:Suppress("NOTHING_TO_INLINE")

package com.google.maps.android.ktx

import com.google.android.gms.maps.model.LatLng
import com.google.maps.android.PolyUtil
import com.google.maps.android.SphericalUtil

/**
* Computes whether the given [latLng] lies on or is near this polyline within [tolerance] (in
* meters).
*
* @param latLng the LatLng to inspect
* @param geodesic if this polyline is geodesic or not
* @param tolerance the tolerance in meters
* @return true if [latLng] is on this path, otherwise, false
*
* @see PolyUtil.isLocationOnPath
*/
inline fun List<LatLng>.isLocationOnPath(
latLng: LatLng,
geodesic: Boolean,
tolerance: Double = 0.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.1 should be DEFAULT_TOLERANCE from the Java lib

): Boolean = PolyUtil.isLocationOnPath(latLng, this, geodesic, tolerance)

/**
* Checks whether or not [latLng] lies on or is near the edge of this polygon within the [tolerance]
* (in meters). The default value is [PolyUtil.DEFAULT_TOLERANCE].
*
* @param latLng the LatLng to inspect
* @param geodesic if this polygon is geodesic or not
* @param tolerance the tolerance in meters
* @return true if [latLng] lies on or is near the edge of this Polygon, otherwise, false
*
* @see PolyUtil.isLocationOnEdge
*/
inline fun List<LatLng>.isOnEdge(
latLng: LatLng,
geodesic: Boolean,
tolerance: Double = 0.1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0.1 should be DEFAULT_TOLERANCE from the Java lib

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's what I meant to do now that AMU 1.0.1 is live on maven. I'll need to bump the version used by the KTX lib and update this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I'll address this as a separate PR (with version bumping AMU to 1.0.1). Will update the PR with doc edits though.

): Boolean = PolyUtil.isLocationOnEdge(latLng, this, geodesic, tolerance)

/**
* Computes whether the [latLng] lies inside this.
*
* The polygon is always considered closed, regardless of whether the last point equals
* the first or not.
*
* Inside is defined as not containing the South Pole -- the South Pole is always outside.
* The polygon is formed of great circle segments if [geodesic] is true, and of rhumb
* (loxodromic) segments otherwise.
*
* @param latLng the LatLng to check if it is contained within this polygon
* @param geodesic if this Polygon is geodesic or not
*
* @see PolyUtil.containsLocation
*/
inline fun List<LatLng>.containsLocation(latLng: LatLng, geodesic: Boolean): Boolean =
PolyUtil.containsLocation(latLng, this, geodesic)

/**
* Simplifies this list of LatLng using the Douglas-Peucker decimation. Increasing the value of
* [tolerance] will result in fewer points.
Expand All @@ -30,7 +83,8 @@ import com.google.maps.android.SphericalUtil
*
* @see PolyUtil.simplify
*/
inline fun List<LatLng>.simplify(tolerance: Double): List<LatLng> = PolyUtil.simplify(this, tolerance)
inline fun List<LatLng>.simplify(tolerance: Double): List<LatLng> =
PolyUtil.simplify(this, tolerance)

/**
* Decodes this encoded string into a [LatLng] list.
Expand All @@ -48,7 +102,6 @@ inline fun String.toLatLngList(): List<LatLng> = PolyUtil.decode(this)
* @return the encoded String
*
* @see [Polyline Algorithm Format](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)
*
*/
inline fun List<LatLng>.latLngListEncode(): String = PolyUtil.encode(this)

Expand All @@ -75,7 +128,6 @@ inline fun List<LatLng>.sphericalPathLength(): Double = SphericalUtil.computeLen
*/
inline fun List<LatLng>.sphericalPolygonArea(): Double = SphericalUtil.computeArea(this)


/**
* Computes the signed area under a closed path on Earth. The sign of the area may be used to
* determine the orientation of the path.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,40 @@ class LatLngTest {
1e-6
)
}

@Test
fun `contains location evaluates to true`() {
val latLngList = listOf(LatLng(0.0, 0.0), LatLng(0.0, 90.0), LatLng(-90.0, 45.0))
assertTrue(latLngList.containsLocation(LatLng(30.0, 45.0), geodesic = true))
}

@Test
fun `contains location evaluates to false`() {
val latLngList = listOf(LatLng(0.0, 0.0), LatLng(0.0, 90.0), LatLng(-90.0, 45.0))
assertFalse(latLngList.containsLocation(LatLng(-30.0, 45.0), geodesic = true))
}

@Test
fun `isOnEdge location evaluates to true`() {
val latLngList = listOf(LatLng(0.0, 0.0), LatLng(0.0, 90.0), LatLng(-90.0, 45.0))
assertTrue(latLngList.isOnEdge(LatLng(0.0, 45.0), geodesic = true))
}

@Test
fun `isOnEdge location evaluates to false`() {
val latLngList = listOf(LatLng(0.0, 0.0), LatLng(0.0, 90.0), LatLng(-90.0, 45.0))
assertFalse(latLngList.isOnEdge(LatLng(0.0, -45.0), geodesic = true))
}

@Test
fun `isLocationOnPath location evaluates to true`() {
val latLngList = listOf(LatLng(0.0, 0.0), LatLng(0.0, 90.0), LatLng(0.0, 180.0))
assertTrue(latLngList.isLocationOnPath(LatLng(0.0, 45.0), geodesic = true))
}

@Test
fun `isLocationOnPath location evaluates to false`() {
val latLngList = listOf(LatLng(0.0, 0.0), LatLng(0.0, 90.0), LatLng(0.0, 180.0))
assertFalse(latLngList.isLocationOnPath(LatLng(0.0, -45.0), geodesic = true))
}
}