Kotlin中展开运算符传递LatLng数组至vararg参数失败求助
问题:Kotlin调用Google RoadsApi.snapToRoads时参数传递失败
我用Kotlin(Jetpack Compose)结合Google Routes API开发,调用RoadsApi.snapToRoads时遇到参数不匹配错误。该函数要求传入vararg LatLng!(Java类),我尝试用Array、List配合展开运算符*和.toTypedArray()传递参数,但都无效。
我当前使用的LatLng类定义
com.google.android.gms.maps.model.LatLng @Contract(pure = true) public LatLng(double latitude, double longitude)
错误提示
None of the following functions can be called with the arguments supplied.
snapToRoads(GeoApiContext!, vararg LatLng!) defined in com.google.maps.RoadsApi
snapToRoads(GeoApiContext!, Boolean, vararg LatLng!) defined in com.google.maps.RoadsApi
GeoApiContext在其他无vararg参数的API调用中工作正常,请问如何正确传递参数?
依赖配置(build.gradle.kts)
implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.activity:activity-compose:1.8.1") implementation(platform("androidx.compose:compose-bom:2023.03.00")) implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) androidTestImplementation("androidx.compose.ui:ui-test-junit4") debugImplementation("androidx.compose.ui:ui-tooling") debugImplementation("androidx.compose.ui:ui-test-manifest") implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1") implementation("androidx.appcompat:appcompat:1.6.1") // Maps implementation ("com.google.maps.android:maps-compose:2.9.0") implementation ("com.google.android.gms:play-services-maps:18.2.0") implementation("com.google.android.gms:play-services-location:21.0.1") // Lifecycle implementation ("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2") implementation ("androidx.lifecycle:lifecycle-runtime-compose:2.6.2") implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.2") // DirectionsAPI+ implementation ("com.google.maps:google-maps-services:2.2.0") implementation ("org.slf4j:slf4j-simple:1.7.25")
我的Kotlin函数代码
fun getRoadsSnapped( // First: Snap to Roads to get placeIds dirlist: List<LatLng>, callback: (Array<Double>) -> Unit ){ // Handle Pathlist that it is below 100 in size var tmpPathlist: Array<LatLng> = emptyArray() var divider: Int = 1 // RoadsApi only allowed 100 paths in snapToRoads. Reduce them evenly. if (dirlist.size > 100){ divider = ceil((dirlist.size.toFloat() / 100f)).roundToInt() } for (i in dirlist.indices step divider){ tmpPathlist += dirlist[i] } println("Size of handed over Array: " + tmpPathlist.size.toString()) val snapped = RoadsApi.snapToRoads(mGeoApiContext, *tmpPathlist) // [...] setCallback... }
解决方案
根本原因
你混淆了两个不同包的LatLng类:
- 你当前使用的是
com.google.android.gms.maps.model.LatLng(来自play-services-maps库,用于Google Maps Android SDK) - 而
RoadsApi(来自google-maps-services库)要求的是com.google.maps.model.LatLng(用于Google Maps Web Service API)
这两个类属于不同的库,类型完全不兼容,导致参数传递失败。
解决步骤
- 区分不同包的LatLng:用别名区分两个类,避免代码混淆
- 转换LatLng类型:将Android SDK的LatLng转换为Web Service库要求的LatLng
- 优化数组构建:用Kotlin集合操作简化点数筛选和类型转换
修改后的代码
// 用别名区分两个不同的LatLng类 import com.google.maps.model.LatLng as WebServiceLatLng import com.google.android.gms.maps.model.LatLng as GmsLatLng fun getRoadsSnapped( dirlist: List<GmsLatLng>, callback: (Array<Double>) -> Unit ){ val maxPoints = 100 val divider = if (dirlist.size > maxPoints) { ceil(dirlist.size.toFloat() / maxPoints).roundToInt() } else { 1 } // 筛选符合数量要求的点,并转换为Web Service库的LatLng类型 val convertedPoints = dirlist.filterIndexed { index, _ -> index % divider == 0 }.map { gmsLatLng -> WebServiceLatLng(gmsLatLng.latitude, gmsLatLng.longitude) }.toTypedArray() println("Size of handed over Array: ${convertedPoints.size}") // 正确调用snapToRoads,传递转换后的数组 val snapped = RoadsApi.snapToRoads(mGeoApiContext, *convertedPoints) // [...] 后续的callback逻辑 }
额外说明
google-maps-services库的RoadsApi限制单次请求最多100个点,你的点数处理逻辑是正确的,用filterIndexed替代循环让代码更简洁- 别名的使用可以彻底避免两个
LatLng类的混淆问题
内容的提问来源于stack exchange,提问作者neftLevel
相关产品推荐
相关产品推荐

