@@ -26,8 +26,8 @@ import kotlin.math.pow
2626 * - It allows to encode a 3rd dimension with a given precision, which may be a level, altitude, elevation or some other custom value
2727 */
2828object FlexiblePolyline {
29-
3029 const val VERSION = 1L
30+
3131 // Base64 URL-safe characters
3232 private val ENCODING_TABLE = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_" .toCharArray()
3333 private val DECODING_TABLE = intArrayOf(
@@ -38,7 +38,8 @@ object FlexiblePolyline {
3838 )
3939
4040 /* *
41- * Encode the list of coordinate triples.<BR></BR><BR></BR>
41+ * Encode the list of coordinate triples.
42+ *
4243 * The third dimension value will be eligible for encoding only when ThirdDimension is other than ABSENT.
4344 * This is lossy compression based on precision accuracy.
4445 *
@@ -53,15 +54,15 @@ object FlexiblePolyline {
5354 require(! coordinates.isNullOrEmpty()) { " Invalid coordinates!" }
5455 requireNotNull(thirdDimension) { " Invalid thirdDimension" }
5556 val enc = Encoder (precision, thirdDimension, thirdDimPrecision)
56- val iterator = coordinates.iterator()
57- while (iterator.hasNext()) {
58- enc.add(iterator.next())
57+ coordinates.iterator().forEach {
58+ enc.add(it)
5959 }
6060 return enc.getEncoded()
6161 }
6262
6363 /* *
64- * Decode the encoded input [String] to [List] of coordinate triples.<BR></BR><BR></BR>
64+ * Decode the encoded input [String] to [List] of coordinate triples.
65+ *
6566 * @param encoded URL-safe encoded [String]
6667 * @return [List] of coordinate triples that are decoded from input
6768 *
@@ -70,11 +71,11 @@ object FlexiblePolyline {
7071 */
7172 @JvmStatic
7273 fun decode (encoded : String? ): List <LatLngZ > {
73- require(! ( encoded == null || encoded.trim { it <= ' ' }.isEmpty() )) { " Invalid argument!" }
74+ require(! encoded.isNullOrBlank( )) { " Invalid argument!" }
7475 val result: MutableList <LatLngZ > = ArrayList ()
7576 val dec = Decoder (encoded)
76- while ( dec.hasNext()) {
77- result.add(dec.decodeOne() )
77+ dec.iterator().forEach {
78+ result.add(it )
7879 }
7980 return result
8081 }
@@ -102,10 +103,9 @@ object FlexiblePolyline {
102103 */
103104 private class Encoder (precision : Int , private val thirdDimension : ThirdDimension , thirdDimPrecision : Int ) {
104105 private val result: StringBuilder = StringBuilder ()
105- private val latConveter: Converter = Converter (precision)
106- private val lngConveter: Converter = Converter (precision)
107- private val zConveter: Converter = Converter (thirdDimPrecision)
108-
106+ private val latConverter: Converter = Converter (precision)
107+ private val lngConverter: Converter = Converter (precision)
108+ private val zConverter: Converter = Converter (thirdDimPrecision)
109109
110110 init {
111111 encodeHeader(precision, this .thirdDimension.num, thirdDimPrecision)
@@ -124,14 +124,14 @@ object FlexiblePolyline {
124124 }
125125
126126 private fun add (lat : Double , lng : Double ) {
127- latConveter .encodeValue(lat, result)
128- lngConveter .encodeValue(lng, result)
127+ latConverter .encodeValue(lat, result)
128+ lngConverter .encodeValue(lng, result)
129129 }
130130
131131 private fun add (lat : Double , lng : Double , z : Double ) {
132132 add(lat, lng)
133133 if (thirdDimension != ThirdDimension .ABSENT ) {
134- zConveter .encodeValue(z, result)
134+ zConverter .encodeValue(z, result)
135135 }
136136 }
137137
@@ -148,8 +148,8 @@ object FlexiblePolyline {
148148 /*
149149 * Single instance for decoding an input request.
150150 */
151- private class Decoder (encoded : String ) {
152- private val encoded: CharIterator = ( encoded) .iterator()
151+ private class Decoder (encoded : String ) : Iterator<LatLngZ> {
152+ private val encoded: CharIterator = encoded.iterator()
153153 private val latConverter: Converter
154154 private val lngConverter: Converter
155155 private val zConverter: Converter
@@ -176,7 +176,7 @@ object FlexiblePolyline {
176176 return Converter .decodeUnsignedVarInt(encoded).toInt()
177177 }
178178
179- fun decodeOne (): LatLngZ {
179+ override fun next (): LatLngZ {
180180 val lat = latConverter.decodeValue(encoded)
181181 val lng = lngConverter.decodeValue(encoded)
182182
@@ -187,7 +187,7 @@ object FlexiblePolyline {
187187 return LatLngZ (lat, lng)
188188 }
189189
190- fun hasNext (): Boolean {
190+ override fun hasNext (): Boolean {
191191 return encoded.hasNext()
192192 }
193193 }
@@ -250,11 +250,11 @@ object FlexiblePolyline {
250250 fun decodeUnsignedVarInt (encoded : CharIterator ): Long {
251251 var shift: Short = 0
252252 var result: Long = 0
253- while ( encoded.hasNext() ) {
254- val c = encoded.next()
255- val value = decodeChar(c ).toLong()
253+
254+ encoded.forEach {
255+ val value = decodeChar(it ).toLong()
256256 if (value < 0 ) {
257- throw IllegalArgumentException (" Unexpected value found :: '$c " )
257+ throw IllegalArgumentException (" Unexpected value found :: '$it " )
258258 }
259259 result = result or ((value and 0x1FL ) shl shift.toInt())
260260 if ((value and 0x20L ) == 0L ) {
@@ -291,28 +291,12 @@ object FlexiblePolyline {
291291 /* *
292292 * Coordinate triple
293293 */
294- class LatLngZ @JvmOverloads constructor(val lat : Double , val lng : Double , val z : Double = 0.0 ) {
295- override fun toString (): String {
296- return " LatLngZ [lat=$lat , lng=$lng , z=$z ]"
297- }
298-
299- override fun equals (other : Any? ): Boolean {
300- if (this == = other) {
301- return true
302- }
303- if (other is LatLngZ ) {
304- if (other.lat == lat && other.lng == lng && other.z == z) {
305- return true
306- }
307- }
308- return false
309- }
310-
311- override fun hashCode (): Int {
312- var result = lat.hashCode()
313- result = 31 * result + lng.hashCode()
314- result = 31 * result + z.hashCode()
315- return result
316- }
317- }
294+ /* *
295+ * Coordinate triple
296+ */
297+ data class LatLngZ (
298+ val lat : Double ,
299+ val lng : Double ,
300+ val z : Double = 0.0
301+ ){}
318302}
0 commit comments