From 9126c29aaaa267ce6de6d26eed79745c08d29a3b Mon Sep 17 00:00:00 2001 From: Alex Baker Date: Fri, 12 Feb 2021 14:24:12 -0600 Subject: [PATCH] Remove Mapbox SDK and use Mapbox HTTP API --- app/build.gradle.kts | 1 - app/licenses.yml | 43 -- .../java/org/tasks/TestUtilities.kt | 2 +- .../org/tasks/injection/LocationModule.kt | 6 +- app/src/main/assets/licenses.json | 96 ----- app/src/main/java/org/tasks/data/Place.kt | 28 +- .../java/org/tasks/jobs/ReverseGeocodeWork.kt | 5 +- .../org/tasks/location/AndroidGeocoder.kt | 8 +- .../main/java/org/tasks/location/Geocoder.kt | 2 +- .../tasks/location/LocationPickerActivity.kt | 3 +- .../java/org/tasks/location/MapboxGeocoder.kt | 78 ++-- .../tasks/location/MapboxSearchProvider.kt | 84 ++-- .../org/tasks/location/MapboxGeocoderTest.kt | 34 ++ .../tasks/location/MapboxPlaceSearchTest.kt | 43 ++ app/src/test/resources/mapbox/address.json | 407 ++++++++++++++++++ .../test/resources/mapbox/empty_search.json | 8 + app/src/test/resources/mapbox/poi.json | 341 +++++++++++++++ app/src/test/resources/mapbox/search.json | 305 +++++++++++++ deps_fdroid.txt | 23 +- deps_googleplay.txt | 23 +- 20 files changed, 1255 insertions(+), 285 deletions(-) create mode 100644 app/src/test/java/org/tasks/location/MapboxGeocoderTest.kt create mode 100644 app/src/test/java/org/tasks/location/MapboxPlaceSearchTest.kt create mode 100644 app/src/test/resources/mapbox/address.json create mode 100644 app/src/test/resources/mapbox/empty_search.json create mode 100644 app/src/test/resources/mapbox/poi.json create mode 100644 app/src/test/resources/mapbox/search.json diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 00a195358..f32e1c3ab 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -201,7 +201,6 @@ dependencies { implementation("com.google.auth:google-auth-library-oauth2-http:0.23.0") implementation("androidx.work:work-runtime:${Versions.work}") implementation("androidx.work:work-runtime-ktx:${Versions.work}") - implementation("com.mapbox.mapboxsdk:mapbox-sdk-services:5.8.0") implementation("com.etesync:journalmanager:1.1.1") implementation("com.etebase:client:2.3.2") implementation("com.github.QuadFlask:colorpicker:0.0.15") diff --git a/app/licenses.yml b/app/licenses.yml index 33efd7b16..3d64430d0 100644 --- a/app/licenses.yml +++ b/app/licenses.yml @@ -48,13 +48,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: http://developer.android.com/tools/extras/support-library.html -- artifact: com.mapbox.mapboxsdk:mapbox-sdk-services:+ - name: Mapbox services - copyrightHolder: Mapbox - license: MIT License - licenseUrl: http://www.opensource.org/licenses/mit-license.php - url: https://github.com/mapbox/mapbox-java - forceGenerate: true - artifact: androidx.core:core:+ name: Android Support Library compat copyrightHolder: Android Open Source Project @@ -178,13 +171,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: http://commons.apache.org/proper/commons-lang/ -- artifact: com.mapbox.mapboxsdk:mapbox-sdk-geojson:+ - name: Mapbox services-geojson - copyrightHolder: Mapbox - license: MIT License - licenseUrl: http://www.opensource.org/licenses/mit-license.php - url: https://github.com/mapbox/mapbox-java - forceGenerate: true - artifact: androidx.loader:loader:+ name: Android Support Library loader copyrightHolder: Android Open Source Project @@ -318,13 +304,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: https://developer.android.com/topic/libraries/architecture/index.html -- artifact: com.mapbox.mapboxsdk:mapbox-sdk-core:+ - name: Mapbox services-core - copyrightHolder: Mapbox - license: MIT License - licenseUrl: http://www.opensource.org/licenses/mit-license.php - url: https://github.com/mapbox/mapbox-java - forceGenerate: true - artifact: androidx.lifecycle:lifecycle-process:+ name: Android Lifecycle Process copyrightHolder: Android Open Source Project @@ -404,11 +383,6 @@ copyrightHolder: Square, Inc. license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt -- artifact: com.squareup.retrofit2:retrofit:+ - name: Retrofit - copyrightHolder: Square, Inc. - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - artifact: org.slf4j:slf4j-api:+ name: SLF4J API Module copyrightHolder: QOS.ch @@ -433,11 +407,6 @@ license: The Apache Software License, Version 2.0 licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt url: https://github.com/JakeWharton/butterknife/ -- artifact: com.squareup.retrofit2:converter-gson:+ - name: "Converter: Gson" - copyrightHolder: Square, Inc. - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - artifact: com.squareup.okhttp3:logging-interceptor:+ name: OkHttp Logging Interceptor copyrightHolder: Square, Inc. @@ -629,18 +598,6 @@ copyrightHolder: Google LLC license: The Apache Software License, Version 2.0 url: https://github.com/google/auto/tree/master/value -- artifact: com.mapbox.mapboxsdk:mapbox-sdk-directions-refresh-models:+ - name: mapbox-sdk-directions-refresh-models - copyrightHolder: Mapbox - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/mapbox/mapbox-java -- artifact: com.mapbox.mapboxsdk:mapbox-sdk-directions-models:+ - name: mapbox-sdk-directions-models - copyrightHolder: Mapbox - license: The Apache Software License, Version 2.0 - licenseUrl: http://www.apache.org/licenses/LICENSE-2.0.txt - url: https://github.com/mapbox/mapbox-java - artifact: com.sun.mail:android-mail:+ name: android-mail copyrightHolder: Oracle and/or its affiliates diff --git a/app/src/commonTest/java/org/tasks/TestUtilities.kt b/app/src/commonTest/java/org/tasks/TestUtilities.kt index dd306da37..5dc04f31f 100644 --- a/app/src/commonTest/java/org/tasks/TestUtilities.kt +++ b/app/src/commonTest/java/org/tasks/TestUtilities.kt @@ -55,7 +55,7 @@ object TestUtilities { private fun fromResource(path: String): at.bitfire.ical4android.Task = fromString(readFile(path)) - private fun readFile(path: String): String { + fun readFile(path: String): String { val uri = javaClass.classLoader?.getResource(path)?.toURI() ?: throw IllegalArgumentException() val paths = Paths.get(uri) diff --git a/app/src/googleplay/java/org/tasks/injection/LocationModule.kt b/app/src/googleplay/java/org/tasks/injection/LocationModule.kt index d3748fe3b..8aec5746b 100644 --- a/app/src/googleplay/java/org/tasks/injection/LocationModule.kt +++ b/app/src/googleplay/java/org/tasks/injection/LocationModule.kt @@ -23,13 +23,15 @@ internal class LocationModule { @ApplicationContext context: Context, preferences: Preferences, playServices: PlayServices, - inventory: Inventory): PlaceSearchProvider { + inventory: Inventory, + mapboxSearchProvider: MapboxSearchProvider + ): PlaceSearchProvider { return if (preferences.useGooglePlaces() && playServices.isPlayServicesAvailable && inventory.hasPro) { GooglePlacesSearchProvider(context) } else { - MapboxSearchProvider(context) + mapboxSearchProvider } } diff --git a/app/src/main/assets/licenses.json b/app/src/main/assets/licenses.json index 00e42840a..99bdee7ad 100644 --- a/app/src/main/assets/licenses.json +++ b/app/src/main/assets/licenses.json @@ -122,20 +122,6 @@ "url": "http://developer.android.com/tools/extras/support-library.html", "libraryName": "Android Support AnimatedVectorDrawable" }, - { - "artifactId": { - "name": "mapbox-sdk-services", - "group": "com.mapbox.mapboxsdk", - "version": "+" - }, - "copyrightHolder": "Mapbox", - "copyrightStatement": "Copyright © Mapbox. All rights reserved.", - "license": "MIT License", - "licenseUrl": "http://www.opensource.org/licenses/mit-license.php", - "normalizedLicense": "mit", - "url": "https://github.com/mapbox/mapbox-java", - "libraryName": "Mapbox services" - }, { "artifactId": { "name": "core", @@ -427,20 +413,6 @@ "url": "http://commons.apache.org/proper/commons-lang/", "libraryName": "Apache Commons Lang" }, - { - "artifactId": { - "name": "mapbox-sdk-geojson", - "group": "com.mapbox.mapboxsdk", - "version": "+" - }, - "copyrightHolder": "Mapbox", - "copyrightStatement": "Copyright © Mapbox. All rights reserved.", - "license": "MIT License", - "licenseUrl": "http://www.opensource.org/licenses/mit-license.php", - "normalizedLicense": "mit", - "url": "https://github.com/mapbox/mapbox-java", - "libraryName": "Mapbox services-geojson" - }, { "artifactId": { "name": "loader", @@ -749,20 +721,6 @@ "url": "https://developer.android.com/topic/libraries/architecture/index.html", "libraryName": "Android Lifecycle-Common" }, - { - "artifactId": { - "name": "mapbox-sdk-core", - "group": "com.mapbox.mapboxsdk", - "version": "+" - }, - "copyrightHolder": "Mapbox", - "copyrightStatement": "Copyright © Mapbox. All rights reserved.", - "license": "MIT License", - "licenseUrl": "http://www.opensource.org/licenses/mit-license.php", - "normalizedLicense": "mit", - "url": "https://github.com/mapbox/mapbox-java", - "libraryName": "Mapbox services-core" - }, { "artifactId": { "name": "lifecycle-process", @@ -954,19 +912,6 @@ "normalizedLicense": "apache2", "libraryName": "OkHttp" }, - { - "artifactId": { - "name": "retrofit", - "group": "com.squareup.retrofit2", - "version": "+" - }, - "copyrightHolder": "Square, Inc.", - "copyrightStatement": "Copyright © Square, Inc. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "libraryName": "Retrofit" - }, { "artifactId": { "name": "slf4j-api", @@ -1023,19 +968,6 @@ "url": "https://github.com/JakeWharton/butterknife/", "libraryName": "ButterKnife Annotations" }, - { - "artifactId": { - "name": "converter-gson", - "group": "com.squareup.retrofit2", - "version": "+" - }, - "copyrightHolder": "Square, Inc.", - "copyrightStatement": "Copyright © Square, Inc. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "libraryName": "Converter: Gson" - }, { "artifactId": { "name": "logging-interceptor", @@ -1499,34 +1431,6 @@ "url": "https://github.com/google/auto/tree/master/value", "libraryName": "AutoValue Annotations" }, - { - "artifactId": { - "name": "mapbox-sdk-directions-refresh-models", - "group": "com.mapbox.mapboxsdk", - "version": "+" - }, - "copyrightHolder": "Mapbox", - "copyrightStatement": "Copyright © Mapbox. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "url": "https://github.com/mapbox/mapbox-java", - "libraryName": "mapbox-sdk-directions-refresh-models" - }, - { - "artifactId": { - "name": "mapbox-sdk-directions-models", - "group": "com.mapbox.mapboxsdk", - "version": "+" - }, - "copyrightHolder": "Mapbox", - "copyrightStatement": "Copyright © Mapbox. All rights reserved.", - "license": "The Apache Software License, Version 2.0", - "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.txt", - "normalizedLicense": "apache2", - "url": "https://github.com/mapbox/mapbox-java", - "libraryName": "mapbox-sdk-directions-models" - }, { "artifactId": { "name": "android-mail", diff --git a/app/src/main/java/org/tasks/data/Place.kt b/app/src/main/java/org/tasks/data/Place.kt index 3b1e9e7f4..b634bbb22 100644 --- a/app/src/main/java/org/tasks/data/Place.kt +++ b/app/src/main/java/org/tasks/data/Place.kt @@ -7,8 +7,6 @@ import android.net.Uri import android.os.Parcel import android.os.Parcelable import androidx.room.* -import com.mapbox.api.geocoding.v5.GeocodingCriteria -import com.mapbox.api.geocoding.v5.models.CarmenFeature import com.todoroo.andlib.data.Table import com.todoroo.astrid.api.FilterListItem.NO_ORDER import com.todoroo.astrid.helper.UUIDHelper @@ -212,29 +210,9 @@ class Place : Serializable, Parcelable { longitude = geo.longitude.toDouble() } - @JvmStatic fun newPlace(mapPosition: MapPosition?): Place? { - if (mapPosition == null) { - return null - } - - return newPlace().apply { - latitude = mapPosition.latitude - longitude = mapPosition.longitude - } - } - - @JvmStatic fun newPlace(feature: CarmenFeature): Place = newPlace().apply { - val types = feature.placeType() - - name = if (types != null && types.contains(GeocodingCriteria.TYPE_ADDRESS)) { - "${feature.address()} ${feature.text()}" - } else { - feature.text() - } - - address = feature.placeName() - latitude = feature.center()!!.latitude() - longitude = feature.center()!!.longitude() + fun newPlace(mapPosition: MapPosition) = newPlace().apply { + latitude = mapPosition.latitude + longitude = mapPosition.longitude } @JvmStatic fun newPlace(): Place = Place().apply { uid = UUIDHelper.newUUID() } diff --git a/app/src/main/java/org/tasks/jobs/ReverseGeocodeWork.kt b/app/src/main/java/org/tasks/jobs/ReverseGeocodeWork.kt index 3ef9ff40f..128b3d7a7 100644 --- a/app/src/main/java/org/tasks/jobs/ReverseGeocodeWork.kt +++ b/app/src/main/java/org/tasks/jobs/ReverseGeocodeWork.kt @@ -11,7 +11,6 @@ import org.tasks.data.LocationDao import org.tasks.injection.BaseWorker import org.tasks.location.Geocoder import timber.log.Timber -import java.io.IOException @HiltWorker class ReverseGeocodeWork @AssistedInject constructor( @@ -38,14 +37,14 @@ class ReverseGeocodeWork @AssistedInject constructor( return Result.failure() } return try { - val result = geocoder.reverseGeocode(place.mapPosition) + val result = geocoder.reverseGeocode(place.mapPosition) ?: return Result.failure() result.id = place.id result.uid = place.uid locationDao.update(result) localBroadcastManager.broadcastRefresh() Timber.d("found $result") Result.success() - } catch (e: IOException) { + } catch (e: Exception) { firebase.reportException(e) Result.failure() } diff --git a/app/src/main/java/org/tasks/location/AndroidGeocoder.kt b/app/src/main/java/org/tasks/location/AndroidGeocoder.kt index 97b424661..48aca521a 100644 --- a/app/src/main/java/org/tasks/location/AndroidGeocoder.kt +++ b/app/src/main/java/org/tasks/location/AndroidGeocoder.kt @@ -21,11 +21,11 @@ class AndroidGeocoder @Inject constructor(@ApplicationContext context: Context) val addresses = geocoder?.getFromLocation(mapPosition.latitude, mapPosition.longitude, 1) ?: emptyList() val place = newPlace(mapPosition) if (addresses.isEmpty()) { - return@withContext place!! + return@withContext place } val address = addresses[0] if (address.maxAddressLineIndex >= 0) { - place!!.name = address.getAddressLine(0) + place.name = address.getAddressLine(0) val builder = StringBuilder(place.name) for (i in 1..address.maxAddressLineIndex) { builder.append(", ").append(address.getAddressLine(i)) @@ -33,10 +33,10 @@ class AndroidGeocoder @Inject constructor(@ApplicationContext context: Context) place.address = builder.toString() } if (address.hasLatitude() && address.hasLongitude()) { - place!!.latitude = address.latitude + place.latitude = address.latitude place.longitude = address.longitude } - place!!.phone = address.phone + place.phone = address.phone place.url = address.url place } diff --git a/app/src/main/java/org/tasks/location/Geocoder.kt b/app/src/main/java/org/tasks/location/Geocoder.kt index e0b11d319..30c70cb51 100644 --- a/app/src/main/java/org/tasks/location/Geocoder.kt +++ b/app/src/main/java/org/tasks/location/Geocoder.kt @@ -3,5 +3,5 @@ package org.tasks.location import org.tasks.data.Place interface Geocoder { - suspend fun reverseGeocode(mapPosition: MapPosition): Place + suspend fun reverseGeocode(mapPosition: MapPosition): Place? } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/location/LocationPickerActivity.kt b/app/src/main/java/org/tasks/location/LocationPickerActivity.kt index 812fd9136..3cf72c1f2 100644 --- a/app/src/main/java/org/tasks/location/LocationPickerActivity.kt +++ b/app/src/main/java/org/tasks/location/LocationPickerActivity.kt @@ -38,6 +38,7 @@ import org.tasks.billing.Inventory import org.tasks.caldav.GeoUtils.toLikeString import org.tasks.data.LocationDao import org.tasks.data.Place +import org.tasks.data.Place.Companion.newPlace import org.tasks.data.PlaceUsage import org.tasks.dialogs.DialogBuilder import org.tasks.injection.InjectingAppCompatActivity @@ -232,7 +233,7 @@ class LocationPickerActivity : InjectingAppCompatActivity(), Toolbar.OnMenuItemC val mapPosition = map.mapPosition ?: return loadingIndicator.visibility = View.VISIBLE lifecycleScope.launch { - val place = geocoder.reverseGeocode(mapPosition) + val place = geocoder.reverseGeocode(mapPosition) ?: newPlace(mapPosition) loadingIndicator.visibility = View.GONE returnPlace(place) } diff --git a/app/src/main/java/org/tasks/location/MapboxGeocoder.kt b/app/src/main/java/org/tasks/location/MapboxGeocoder.kt index ead9856eb..70cf469e0 100644 --- a/app/src/main/java/org/tasks/location/MapboxGeocoder.kt +++ b/app/src/main/java/org/tasks/location/MapboxGeocoder.kt @@ -1,48 +1,72 @@ package org.tasks.location import android.content.Context -import com.google.gson.GsonBuilder +import com.google.gson.JsonElement +import com.google.gson.JsonObject import com.google.gson.JsonParser -import com.mapbox.api.geocoding.v5.MapboxGeocoding -import com.mapbox.geojson.Point import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.tasks.BuildConfig +import okhttp3.OkHttpClient +import okhttp3.Request +import org.tasks.DebugNetworkInterceptor import org.tasks.R import org.tasks.data.Place import org.tasks.data.Place.Companion.newPlace -import timber.log.Timber +import org.tasks.preferences.Preferences +import java.io.IOException import javax.inject.Inject -class MapboxGeocoder @Inject constructor(@ApplicationContext context: Context) : Geocoder { - private val token: String = context.getString(R.string.mapbox_key) +class MapboxGeocoder @Inject constructor( + @ApplicationContext context: Context, + private val preferences: Preferences, + private val interceptor: DebugNetworkInterceptor, +) : Geocoder { + private val token = context.getString(R.string.mapbox_key) - override suspend fun reverseGeocode(mapPosition: MapPosition): Place = + override suspend fun reverseGeocode(mapPosition: MapPosition): Place? = withContext(Dispatchers.IO) { - val response = MapboxGeocoding.builder() - .accessToken(token) - .query(Point.fromLngLat(mapPosition.longitude, mapPosition.latitude)) - .build() - .executeCall() - val body = response.body() - if (response.isSuccessful && body != null) { - Timber.d(prettyPrint(body.toJson())) - val features = body.features() - if (features.size > 0) { - return@withContext newPlace(features[0]) - } + val builder = OkHttpClient().newBuilder() + if (preferences.isFlipperEnabled) { + interceptor.apply(builder) + } + val client = builder.build() + val url = "https://api.mapbox.com/geocoding/v5/mapbox.places/${mapPosition.longitude},${mapPosition.latitude}.json?access_token=$token" + val response = client.newCall(Request.Builder().get().url(url).build()).execute() + if (response.isSuccessful) { + response.body?.string()?.let { jsonToPlace(it) } } else { - Timber.e(response.errorBody()!!.string()) + throw IOException("${response.code} ${response.message}") } - newPlace(mapPosition)!! } companion object { - private fun prettyPrint(json: String): String { - return if (BuildConfig.DEBUG) { - GsonBuilder().setPrettyPrinting().create().toJson(JsonParser().parse(json)) - } else json - } + internal fun jsonToPlace(json: String): Place? = + JsonParser + .parseString(json).asJsonObject.getAsJsonArray("features") + .takeIf { it.size() > 0 }?.get(0)?.asJsonObject + ?.let { toPlace(it) } + + internal fun toPlace(feature: JsonObject): Place = + newPlace().apply { + val types = feature.get("place_type").asStringList + val text = feature.get("text").asString + name = if (types.contains("address")) { + "${feature.get("address").asString} $text" + } else { + text + } + address = feature.get("place_name").asString + feature.get("center").asCoordinates.let { + longitude = it.first + latitude = it.second + } + } + + private val JsonElement.asStringList: List + get() = asJsonArray.map { it.asString } + + private val JsonElement.asCoordinates: Pair + get() = asJsonArray.let { Pair(it[0].asDouble, it[1].asDouble) } } } \ No newline at end of file diff --git a/app/src/main/java/org/tasks/location/MapboxSearchProvider.kt b/app/src/main/java/org/tasks/location/MapboxSearchProvider.kt index 340462efd..b36bba783 100644 --- a/app/src/main/java/org/tasks/location/MapboxSearchProvider.kt +++ b/app/src/main/java/org/tasks/location/MapboxSearchProvider.kt @@ -2,22 +2,26 @@ package org.tasks.location import android.content.Context import android.os.Bundle -import com.mapbox.api.geocoding.v5.MapboxGeocoding -import com.mapbox.api.geocoding.v5.models.CarmenFeature -import com.mapbox.api.geocoding.v5.models.GeocodingResponse -import com.mapbox.geojson.Point +import com.google.gson.JsonParser +import dagger.hilt.android.qualifiers.ApplicationContext import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import okhttp3.OkHttpClient +import okhttp3.Request +import org.tasks.DebugNetworkInterceptor import org.tasks.R import org.tasks.data.Place -import org.tasks.data.Place.Companion.newPlace -import retrofit2.Call -import retrofit2.Response -import java.util.* -import kotlin.coroutines.suspendCoroutine +import org.tasks.location.MapboxGeocoder.Companion.toPlace +import org.tasks.preferences.Preferences +import java.io.IOException +import javax.inject.Inject -class MapboxSearchProvider(private val context: Context) : PlaceSearchProvider { - private var builder: MapboxGeocoding.Builder? = null +class MapboxSearchProvider @Inject constructor( + @ApplicationContext context: Context, + private val preferences: Preferences, + private val interceptor: DebugNetworkInterceptor, +) : PlaceSearchProvider { + val token = context.getString(R.string.mapbox_key) override fun restoreState(savedInstanceState: Bundle?) {} @@ -27,41 +31,39 @@ class MapboxSearchProvider(private val context: Context) : PlaceSearchProvider { override suspend fun search(query: String, bias: MapPosition?): List = withContext(Dispatchers.IO) { - suspendCoroutine { cont -> - if (builder == null) { - val token = context.getString(R.string.mapbox_key) - builder = MapboxGeocoding.builder().autocomplete(true).accessToken(token) - if (bias != null) { - builder?.proximity(Point.fromLngLat(bias.longitude, bias.latitude)) - } - } - builder - ?.query(query) - ?.build() - ?.enqueueCall( - object : retrofit2.Callback { - override fun onResponse( - call: Call, response: Response) { - val results: MutableList = ArrayList() - results.clear() - for (feature in response.body()!!.features()) { - results.add(toSearchResult(feature)) - } - cont.resumeWith(Result.success(results)) - } - - override fun onFailure(call: Call, t: Throwable) { - cont.resumeWith(Result.failure(t)) - } - }) + val builder = OkHttpClient().newBuilder() + if (preferences.isFlipperEnabled) { + interceptor.apply(builder) + } + val proximity = bias?.let { + "&proximity=${bias.longitude},${bias.latitude}" + } + val client = builder.build() + val url = "https://api.mapbox.com/geocoding/v5/mapbox.places/$query.json?access_token=$token$proximity" + val response = client.newCall(Request.Builder().get().url(url).build()).execute() + if (response.isSuccessful) { + response.body?.string()?.let { jsonToSearchResults(it) } ?: emptyList() + } else { + throw IOException("${response.code} ${response.message}") } } override suspend fun fetch(placeSearchResult: PlaceSearchResult): Place = placeSearchResult.place - private fun toSearchResult(feature: CarmenFeature): PlaceSearchResult { - val place = newPlace(feature) - return PlaceSearchResult(feature.id(), place.name, place.displayAddress, place) + companion object { + internal fun jsonToSearchResults(json: String): List = + JsonParser + .parseString(json).asJsonObject.getAsJsonArray("features") + .map { it.asJsonObject } + .map { + val place = toPlace(it) + PlaceSearchResult( + it.get("id").asString, + place.name, + place.displayAddress, + place + ) + } } } \ No newline at end of file diff --git a/app/src/test/java/org/tasks/location/MapboxGeocoderTest.kt b/app/src/test/java/org/tasks/location/MapboxGeocoderTest.kt new file mode 100644 index 000000000..590b40b48 --- /dev/null +++ b/app/src/test/java/org/tasks/location/MapboxGeocoderTest.kt @@ -0,0 +1,34 @@ +package org.tasks.location + +import org.junit.Assert.assertEquals +import org.junit.Test +import org.tasks.TestUtilities.readFile +import org.tasks.location.MapboxGeocoder.Companion.jsonToPlace + +class MapboxGeocoderTest { + @Test + fun poiGeocode() { + val place = jsonToPlace(readFile("mapbox/poi.json"))!! + + assertEquals("Guaranteed Rate Field", place.name) + assertEquals(-87.63380599999999, place.longitude, 0.0) + assertEquals(41.8299365, place.latitude, 0.0) + assertEquals( + "Guaranteed Rate Field, 333 W 35th St, Chicago, Illinois 60616, United States", + place.address + ) + } + + @Test + fun addressGeocode() { + val place = jsonToPlace(readFile("mapbox/address.json"))!! + + assertEquals("120 East 13th Street", place.name) + assertEquals(40.7330031, place.latitude, 0.0) + assertEquals(-73.9888929, place.longitude, 0.0) + assertEquals( + "120 East 13th Street, New York, New York 10003, United States", + place.address + ) + } +} \ No newline at end of file diff --git a/app/src/test/java/org/tasks/location/MapboxPlaceSearchTest.kt b/app/src/test/java/org/tasks/location/MapboxPlaceSearchTest.kt new file mode 100644 index 000000000..1dab4350c --- /dev/null +++ b/app/src/test/java/org/tasks/location/MapboxPlaceSearchTest.kt @@ -0,0 +1,43 @@ +package org.tasks.location + +import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.tasks.TestUtilities.readFile +import org.tasks.location.MapboxSearchProvider.Companion.jsonToSearchResults + +class MapboxPlaceSearchTest { + @Test + fun searchWithMultipleResults() { + val results = jsonToSearchResults(readFile("mapbox/search.json")) + + assertEquals( + listOf( + "poi.627065251624", + "poi.472446436443", + "poi.89343", + "poi.549755920662", + "poi.755914248504" + ), + results.map { it.id } + ) + } + + @Test + fun validatePlace() { + val place = jsonToSearchResults(readFile("mapbox/search.json"))[1] + + assertEquals("poi.472446436443", place.id) + assertEquals("Portillo's", place.name) + assertEquals(-87.962508, place.place.longitude, 0.0) + assertEquals(41.895473, place.place.latitude, 0.0) + assertEquals( + "155 S Il Route 83, Elmhurst, Illinois 60126, United States", + place.address + ) + } + + @Test + fun emptySearchResults() = + assertTrue(jsonToSearchResults(readFile("mapbox/empty_search.json")).isEmpty()) +} \ No newline at end of file diff --git a/app/src/test/resources/mapbox/address.json b/app/src/test/resources/mapbox/address.json new file mode 100644 index 000000000..f06619452 --- /dev/null +++ b/app/src/test/resources/mapbox/address.json @@ -0,0 +1,407 @@ +{ + "type": "FeatureCollection", + "query": [ + -73.989, + 40.733 + ], + "features": [ + { + "id": "address.5326841146807324", + "type": "Feature", + "place_type": [ + "address" + ], + "relevance": 1, + "properties": { + "accuracy": "rooftop" + }, + "text": "East 13th Street", + "place_name": "120 East 13th Street, New York, New York 10003, United States", + "center": [ + -73.9888929, + 40.7330031 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -73.9888929, + 40.7330031 + ] + }, + "address": "120", + "context": [ + { + "id": "neighborhood.2103290", + "text": "Greenwich Village" + }, + { + "id": "postcode.13482670360296810", + "text": "10003" + }, + { + "id": "locality.12696928000137850", + "wikidata": "Q11299", + "text": "Manhattan" + }, + { + "id": "place.15278078705964500", + "wikidata": "Q60", + "text": "New York" + }, + { + "id": "district.12113562209855570", + "wikidata": "Q500416", + "text": "New York County" + }, + { + "id": "region.17349986251855570", + "wikidata": "Q1384", + "short_code": "US-NY", + "text": "New York" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "neighborhood.2103290", + "type": "Feature", + "place_type": [ + "neighborhood" + ], + "relevance": 1, + "properties": {}, + "text": "Greenwich Village", + "place_name": "Greenwich Village, Manhattan, New York, New York 10003, United States", + "bbox": [ + -74.005282, + 40.72586, + -73.98734, + 40.73907 + ], + "center": [ + -74.0029, + 40.7284 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -74.0029, + 40.7284 + ] + }, + "context": [ + { + "id": "postcode.13482670360296810", + "text": "10003" + }, + { + "id": "locality.12696928000137850", + "wikidata": "Q11299", + "text": "Manhattan" + }, + { + "id": "place.15278078705964500", + "wikidata": "Q60", + "text": "New York" + }, + { + "id": "district.12113562209855570", + "wikidata": "Q500416", + "text": "New York County" + }, + { + "id": "region.17349986251855570", + "wikidata": "Q1384", + "short_code": "US-NY", + "text": "New York" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "postcode.13482670360296810", + "type": "Feature", + "place_type": [ + "postcode" + ], + "relevance": 1, + "properties": {}, + "text": "10003", + "place_name": "New York, New York 10003, United States", + "bbox": [ + -73.9996058238451, + 40.7229310019, + -73.9798620096375, + 40.7396749960342 + ], + "center": [ + -73.99, + 40.73 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -73.99, + 40.73 + ] + }, + "context": [ + { + "id": "locality.12696928000137850", + "wikidata": "Q11299", + "text": "Manhattan" + }, + { + "id": "place.15278078705964500", + "wikidata": "Q60", + "text": "New York" + }, + { + "id": "district.12113562209855570", + "wikidata": "Q500416", + "text": "New York County" + }, + { + "id": "region.17349986251855570", + "wikidata": "Q1384", + "short_code": "US-NY", + "text": "New York" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "locality.12696928000137850", + "type": "Feature", + "place_type": [ + "locality" + ], + "relevance": 1, + "properties": { + "wikidata": "Q11299" + }, + "text": "Manhattan", + "place_name": "Manhattan, New York, New York, United States", + "bbox": [ + -74.047313153061, + 40.679573, + -73.907, + 40.8820749648427 + ], + "center": [ + -73.9597, + 40.7903 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -73.9597, + 40.7903 + ] + }, + "context": [ + { + "id": "place.15278078705964500", + "wikidata": "Q60", + "text": "New York" + }, + { + "id": "district.12113562209855570", + "wikidata": "Q500416", + "text": "New York County" + }, + { + "id": "region.17349986251855570", + "wikidata": "Q1384", + "short_code": "US-NY", + "text": "New York" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "place.15278078705964500", + "type": "Feature", + "place_type": [ + "place" + ], + "relevance": 1, + "properties": { + "wikidata": "Q60" + }, + "text": "New York", + "place_name": "New York, New York, United States", + "bbox": [ + -74.2590879797556, + 40.477399, + -73.7008392055224, + 40.917576401307 + ], + "center": [ + -73.9808, + 40.7648 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -73.9808, + 40.7648 + ] + }, + "context": [ + { + "id": "district.12113562209855570", + "wikidata": "Q500416", + "text": "New York County" + }, + { + "id": "region.17349986251855570", + "wikidata": "Q1384", + "short_code": "US-NY", + "text": "New York" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "district.12113562209855570", + "type": "Feature", + "place_type": [ + "district" + ], + "relevance": 1, + "properties": { + "wikidata": "Q500416" + }, + "text": "New York County", + "place_name": "New York County, New York, United States", + "bbox": [ + -74.047227, + 40.682932, + -73.907, + 40.879278 + ], + "center": [ + -74, + 40.7167 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -74, + 40.7167 + ] + }, + "context": [ + { + "id": "region.17349986251855570", + "wikidata": "Q1384", + "short_code": "US-NY", + "text": "New York" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "region.17349986251855570", + "type": "Feature", + "place_type": [ + "region" + ], + "relevance": 1, + "properties": { + "wikidata": "Q1384", + "short_code": "US-NY" + }, + "text": "New York", + "place_name": "New York, United States", + "bbox": [ + -79.8578350999901, + 40.4771391062446, + -71.7564918092633, + 45.0239286969073 + ], + "center": [ + -75.4652471468304, + 42.751210955 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -75.4652471468304, + 42.751210955 + ] + }, + "context": [ + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "country.19678805456372290", + "type": "Feature", + "place_type": [ + "country" + ], + "relevance": 1, + "properties": { + "wikidata": "Q30", + "short_code": "us" + }, + "text": "United States", + "place_name": "United States", + "bbox": [ + -179.9, + 18.8163608007951, + -66.8847646185949, + 71.4202919997506 + ], + "center": [ + -97.9222112121185, + 39.3812661305678 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -97.9222112121185, + 39.3812661305678 + ] + } + } + ], + "attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare." +} \ No newline at end of file diff --git a/app/src/test/resources/mapbox/empty_search.json b/app/src/test/resources/mapbox/empty_search.json new file mode 100644 index 000000000..b33e563c4 --- /dev/null +++ b/app/src/test/resources/mapbox/empty_search.json @@ -0,0 +1,8 @@ +{ + "type": "FeatureCollection", + "query": [ + "xjiebrbcidksn" + ], + "features": [], + "attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare." +} \ No newline at end of file diff --git a/app/src/test/resources/mapbox/poi.json b/app/src/test/resources/mapbox/poi.json new file mode 100644 index 000000000..dd86e3295 --- /dev/null +++ b/app/src/test/resources/mapbox/poi.json @@ -0,0 +1,341 @@ +{ + "type": "FeatureCollection", + "query": [ + -87.63380599999999, + 41.8299365 + ], + "features": [ + { + "id": "poi.128849020577", + "type": "Feature", + "place_type": [ + "poi" + ], + "relevance": 1, + "properties": { + "wikidata": "Q633613", + "category": "baseball stadium, baseball, leisure", + "landmark": true, + "address": "333 W 35th St", + "foursquare": "40dcbc80f964a52080011fe3" + }, + "text": "Guaranteed Rate Field", + "place_name": "Guaranteed Rate Field, 333 W 35th St, Chicago, Illinois 60616, United States", + "center": [ + -87.63380599999999, + 41.8299365 + ], + "geometry": { + "coordinates": [ + -87.63380599999999, + 41.8299365 + ], + "type": "Point" + }, + "context": [ + { + "id": "neighborhood.33950", + "text": "Bridgeport" + }, + { + "id": "postcode.11036815072354260", + "text": "60616" + }, + { + "id": "place.1924128844701850", + "wikidata": "Q1297", + "text": "Chicago" + }, + { + "id": "district.8754923997749290", + "wikidata": "Q108418", + "text": "Cook County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "neighborhood.33950", + "type": "Feature", + "place_type": [ + "neighborhood" + ], + "relevance": 1, + "properties": {}, + "text": "Bridgeport", + "place_name": "Bridgeport, Chicago, Illinois 60616, United States", + "bbox": [ + -87.665847, + 41.823142, + -87.630759, + 41.849457 + ], + "center": [ + -87.6512, + 41.8381 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -87.6512, + 41.8381 + ] + }, + "context": [ + { + "id": "postcode.11036815072354260", + "text": "60616" + }, + { + "id": "place.1924128844701850", + "wikidata": "Q1297", + "text": "Chicago" + }, + { + "id": "district.8754923997749290", + "wikidata": "Q108418", + "text": "Cook County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "postcode.11036815072354260", + "type": "Feature", + "place_type": [ + "postcode" + ], + "relevance": 1, + "properties": {}, + "text": "60616", + "place_name": "Chicago, Illinois 60616, United States", + "bbox": [ + -87.6466359591625, + 41.8272291061023, + -87.592612118742, + 41.8674338954049 + ], + "center": [ + -87.62, + 41.86 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -87.62, + 41.86 + ] + }, + "context": [ + { + "id": "place.1924128844701850", + "wikidata": "Q1297", + "text": "Chicago" + }, + { + "id": "district.8754923997749290", + "wikidata": "Q108418", + "text": "Cook County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "place.1924128844701850", + "type": "Feature", + "place_type": [ + "place" + ], + "relevance": 1, + "properties": { + "wikidata": "Q1297" + }, + "text": "Chicago", + "place_name": "Chicago, Illinois, United States", + "bbox": [ + -87.9058109309507, + 41.6299229800457, + -87.523686109734, + 42.0234323628388 + ], + "center": [ + -87.6244, + 41.8756 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -87.6244, + 41.8756 + ] + }, + "context": [ + { + "id": "district.8754923997749290", + "wikidata": "Q108418", + "text": "Cook County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "district.8754923997749290", + "type": "Feature", + "place_type": [ + "district" + ], + "relevance": 1, + "properties": { + "wikidata": "Q108418" + }, + "text": "Cook County", + "place_name": "Cook County, Illinois, United States", + "bbox": [ + -88.263641, + 41.469705, + -87.523907, + 42.154292 + ], + "center": [ + -87.71667, + 41.8 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -87.71667, + 41.8 + ] + }, + "context": [ + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "region.10854263468358810", + "type": "Feature", + "place_type": [ + "region" + ], + "relevance": 1, + "properties": { + "wikidata": "Q1204", + "short_code": "US-IL" + }, + "text": "Illinois", + "place_name": "Illinois, United States", + "bbox": [ + -91.5130799991365, + 36.9702970055306, + -87.0117177165746, + 42.553081292589 + ], + "center": [ + -89.2749461071049, + 40.1492928594 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -89.2749461071049, + 40.1492928594 + ] + }, + "context": [ + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "country.19678805456372290", + "type": "Feature", + "place_type": [ + "country" + ], + "relevance": 1, + "properties": { + "wikidata": "Q30", + "short_code": "us" + }, + "text": "United States", + "place_name": "United States", + "bbox": [ + -179.9, + 18.8163608007951, + -66.8847646185949, + 71.4202919997506 + ], + "center": [ + -97.9222112121185, + 39.3812661305678 + ], + "geometry": { + "type": "Point", + "coordinates": [ + -97.9222112121185, + 39.3812661305678 + ] + } + } + ], + "attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare." +} \ No newline at end of file diff --git a/app/src/test/resources/mapbox/search.json b/app/src/test/resources/mapbox/search.json new file mode 100644 index 000000000..7282bd968 --- /dev/null +++ b/app/src/test/resources/mapbox/search.json @@ -0,0 +1,305 @@ +{ + "type": "FeatureCollection", + "query": [ + "portillos" + ], + "features": [ + { + "id": "poi.627065251624", + "type": "Feature", + "place_type": [ + "poi" + ], + "relevance": 1, + "properties": { + "foursquare": "4b5b4c55f964a5209ff228e3", + "landmark": true, + "address": "635 W North Ave", + "category": "burger joint" + }, + "text": "Portillo's", + "place_name": "Portillo's, 635 W North Ave, Villa Park, Illinois 60181, United States", + "center": [ + -87.994203, + 41.904793 + ], + "geometry": { + "coordinates": [ + -87.994203, + 41.904793 + ], + "type": "Point" + }, + "context": [ + { + "id": "neighborhood.277661", + "text": "South Addison" + }, + { + "id": "postcode.5355712630239150", + "text": "60181" + }, + { + "id": "place.14963076574860490", + "wikidata": "Q1863204", + "text": "Villa Park" + }, + { + "id": "district.7716179127556280", + "wikidata": "Q109626", + "text": "DuPage County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "poi.472446436443", + "type": "Feature", + "place_type": [ + "poi" + ], + "relevance": 1, + "properties": { + "foursquare": "4b099068f964a520811923e3", + "landmark": true, + "address": "155 S Il Route 83", + "category": "hot dog, fast food" + }, + "text": "Portillo's", + "place_name": "Portillo's, 155 S Il Route 83, Elmhurst, Illinois 60126, United States", + "center": [ + -87.962508, + 41.895473 + ], + "geometry": { + "coordinates": [ + -87.962508, + 41.895473 + ], + "type": "Point" + }, + "context": [ + { + "id": "neighborhood.287059", + "text": "Elmhurst City Centre" + }, + { + "id": "postcode.14277643230845500", + "text": "60126" + }, + { + "id": "place.10834168015713210", + "wikidata": "Q579542", + "text": "Elmhurst" + }, + { + "id": "district.7716179127556280", + "wikidata": "Q109626", + "text": "DuPage County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "poi.89343", + "type": "Feature", + "place_type": [ + "poi" + ], + "relevance": 1, + "properties": { + "foursquare": "4a293d31f964a52071951fe3", + "landmark": true, + "address": "1500 Butterfield Rd", + "category": "fast food", + "maki": "fast-food" + }, + "text": "Portillo's", + "place_name": "Portillo's, 1500 Butterfield Rd, Downers Grove, Illinois 60515, United States", + "center": [ + -88.022488, + 41.834394 + ], + "geometry": { + "coordinates": [ + -88.022488, + 41.834394 + ], + "type": "Point" + }, + "context": [ + { + "id": "neighborhood.272377", + "text": "Highland Hills" + }, + { + "id": "postcode.10443155941018200", + "text": "60515" + }, + { + "id": "place.13768728440893640", + "wikidata": "Q1007011", + "text": "Downers Grove" + }, + { + "id": "district.7716179127556280", + "wikidata": "Q109626", + "text": "DuPage County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "poi.549755920662", + "type": "Feature", + "place_type": [ + "poi" + ], + "relevance": 1, + "properties": { + "foursquare": "4ae88c30f964a52053b021e3", + "landmark": true, + "address": "235 E North Ave", + "category": "hot dog, fast food" + }, + "text": "Portillo's", + "place_name": "Portillo's, 235 E North Ave, Glendale Heights, Illinois 60139, United States", + "center": [ + -88.08045, + 41.902269 + ], + "geometry": { + "coordinates": [ + -88.08045, + 41.902269 + ], + "type": "Point" + }, + "context": [ + { + "id": "neighborhood.32979", + "text": "Shorewood" + }, + { + "id": "postcode.7546533656837130", + "text": "60139" + }, + { + "id": "place.10354477397635860", + "wikidata": "Q912145", + "text": "Glendale Heights" + }, + { + "id": "district.7716179127556280", + "wikidata": "Q109626", + "text": "DuPage County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + }, + { + "id": "poi.755914248504", + "type": "Feature", + "place_type": [ + "poi" + ], + "relevance": 1, + "properties": { + "foursquare": "4b44c97ff964a5202cfc25e3", + "landmark": true, + "address": "100 W Lake St", + "category": "hot dog, fast food" + }, + "text": "Portillo's", + "place_name": "Portillo's, 100 W Lake St, Addison, Illinois 60101, United States", + "center": [ + -87.991471, + 41.933674 + ], + "geometry": { + "coordinates": [ + -87.991471, + 41.933674 + ], + "type": "Point" + }, + "context": [ + { + "id": "neighborhood.287037", + "text": "Michael Lane Area" + }, + { + "id": "postcode.16750824071334230", + "text": "60101" + }, + { + "id": "place.12939236967422170", + "wikidata": "Q353080", + "text": "Addison" + }, + { + "id": "district.7716179127556280", + "wikidata": "Q109626", + "text": "DuPage County" + }, + { + "id": "region.10854263468358810", + "wikidata": "Q1204", + "short_code": "US-IL", + "text": "Illinois" + }, + { + "id": "country.19678805456372290", + "wikidata": "Q30", + "short_code": "us", + "text": "United States" + } + ] + } + ], + "attribution": "NOTICE: © 2021 Mapbox and its suppliers. All rights reserved. Use of this data is subject to the Mapbox Terms of Service (https://www.mapbox.com/about/maps/). This response and the information it contains may not be retained. POI(s) provided by Foursquare." +} \ No newline at end of file diff --git a/deps_fdroid.txt b/deps_fdroid.txt index 2a0e5637a..97eb14380 100644 --- a/deps_fdroid.txt +++ b/deps_fdroid.txt @@ -348,37 +348,20 @@ +| +--- androidx.work:work-runtime:2.5.0 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.21 -> 1.4.30 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 (*) -++--- com.mapbox.mapboxsdk:mapbox-sdk-services:5.8.0 -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-core:5.8.0 -+| | +--- com.google.code.gson:gson:2.8.6 -+| | +--- com.squareup.retrofit2:retrofit:2.7.2 -+| | | \--- com.squareup.okhttp3:okhttp:3.14.7 -> 4.8.1 (*) -+| | +--- com.squareup.retrofit2:converter-gson:2.7.2 -+| | | +--- com.squareup.retrofit2:retrofit:2.7.2 (*) -+| | | \--- com.google.code.gson:gson:2.8.5 -> 2.8.6 -+| | \--- com.squareup.okhttp3:logging-interceptor:3.12.7 -+| | \--- com.squareup.okhttp3:okhttp:3.12.7 -> 4.8.1 (*) -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0 -+| | \--- com.google.code.gson:gson:2.8.6 -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0 -+| | +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0 (*) -+| | \--- androidx.annotation:annotation:1.0.0 -> 1.1.0 -+| \--- com.mapbox.mapboxsdk:mapbox-sdk-directions-refresh-models:5.8.0 -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0 (*) -+| \--- androidx.annotation:annotation:1.0.0 -> 1.1.0 ++--- com.etesync:journalmanager:1.1.1 +| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.4.21 (*) +| +--- com.madgag.spongycastle:core:1.54.0.0 +| +--- com.madgag.spongycastle:prov:1.54.0.0 +| | \--- com.madgag.spongycastle:core:1.54.0.0 -+| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) ++| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 ++| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*) +| +--- com.google.code.gson:gson:1.7.2 -> 2.8.6 +| +--- org.apache.commons:commons-collections4:4.1 +| +--- org.apache.commons:commons-lang3:3.8.1 -> 3.9 +| \--- commons-codec:commons-codec:1.7 -> 1.11 ++--- com.etebase:client:2.3.2 +| +--- androidx.annotation:annotation:1.1.0 -+| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) ++| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 (*) ++--- com.github.QuadFlask:colorpicker:0.0.15 +| \--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*) +\--- com.github.openid:AppAuth-Android:0.8.0 diff --git a/deps_googleplay.txt b/deps_googleplay.txt index 1ae90f716..dc0a0babc 100644 --- a/deps_googleplay.txt +++ b/deps_googleplay.txt @@ -478,37 +478,20 @@ +| +--- androidx.work:work-runtime:2.5.0 (*) +| +--- org.jetbrains.kotlin:kotlin-stdlib:1.4.21 -> 1.4.30 (*) +| \--- org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1 (*) -++--- com.mapbox.mapboxsdk:mapbox-sdk-services:5.8.0 -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-core:5.8.0 -+| | +--- com.google.code.gson:gson:2.8.6 -+| | +--- com.squareup.retrofit2:retrofit:2.7.2 -+| | | \--- com.squareup.okhttp3:okhttp:3.14.7 -> 4.8.1 (*) -+| | +--- com.squareup.retrofit2:converter-gson:2.7.2 -+| | | +--- com.squareup.retrofit2:retrofit:2.7.2 (*) -+| | | \--- com.google.code.gson:gson:2.8.5 -> 2.8.6 -+| | \--- com.squareup.okhttp3:logging-interceptor:3.12.7 -+| | \--- com.squareup.okhttp3:okhttp:3.12.7 -> 4.8.1 (*) -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0 -+| | \--- com.google.code.gson:gson:2.8.6 -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0 -+| | +--- com.mapbox.mapboxsdk:mapbox-sdk-geojson:5.8.0 (*) -+| | \--- androidx.annotation:annotation:1.0.0 -> 1.1.0 -+| \--- com.mapbox.mapboxsdk:mapbox-sdk-directions-refresh-models:5.8.0 -+| +--- com.mapbox.mapboxsdk:mapbox-sdk-directions-models:5.8.0 (*) -+| \--- androidx.annotation:annotation:1.0.0 -> 1.1.0 ++--- com.etesync:journalmanager:1.1.1 +| +--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.71 -> 1.4.21 (*) +| +--- com.madgag.spongycastle:core:1.54.0.0 +| +--- com.madgag.spongycastle:prov:1.54.0.0 +| | \--- com.madgag.spongycastle:core:1.54.0.0 -+| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) ++| +--- com.squareup.okhttp3:logging-interceptor:3.12.1 ++| | \--- com.squareup.okhttp3:okhttp:3.12.1 -> 4.8.1 (*) +| +--- com.google.code.gson:gson:1.7.2 -> 2.8.6 +| +--- org.apache.commons:commons-collections4:4.1 +| +--- org.apache.commons:commons-lang3:3.8.1 -> 3.9 +| \--- commons-codec:commons-codec:1.7 -> 1.11 ++--- com.etebase:client:2.3.2 +| +--- androidx.annotation:annotation:1.1.0 -+| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 -> 3.12.7 (*) ++| \--- com.squareup.okhttp3:logging-interceptor:3.12.1 (*) ++--- com.github.QuadFlask:colorpicker:0.0.15 +| \--- androidx.appcompat:appcompat:1.1.0 -> 1.2.0 (*) +\--- com.github.openid:AppAuth-Android:0.8.0