mirror of https://github.com/tasks/tasks
Convert Geocoders to Kotlin
parent
af9b89fef3
commit
5c5833ee8f
@ -0,0 +1,15 @@
|
|||||||
|
package org.tasks.injection
|
||||||
|
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import org.tasks.location.Geocoder
|
||||||
|
import org.tasks.location.MapboxGeocoder
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
class FlavorModule {
|
||||||
|
@Provides
|
||||||
|
fun getGeocoder(geocoder: MapboxGeocoder): Geocoder = geocoder
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package org.tasks.injection
|
||||||
|
|
||||||
|
import dagger.Module
|
||||||
|
import dagger.Provides
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
import org.tasks.location.Geocoder
|
||||||
|
import org.tasks.location.MapboxGeocoder
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
class FlavorModule {
|
||||||
|
@Provides
|
||||||
|
fun getGeocoder(geocoder: MapboxGeocoder): Geocoder = geocoder
|
||||||
|
}
|
@ -1,50 +0,0 @@
|
|||||||
package org.tasks.location;
|
|
||||||
|
|
||||||
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
|
|
||||||
import static org.tasks.data.Place.newPlace;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.location.Address;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import org.tasks.data.Place;
|
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class AndroidGeocoder implements Geocoder {
|
|
||||||
|
|
||||||
private final Context context;
|
|
||||||
|
|
||||||
public AndroidGeocoder(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Place reverseGeocode(MapPosition mapPosition) throws IOException {
|
|
||||||
assertNotMainThread();
|
|
||||||
|
|
||||||
android.location.Geocoder geocoder = new android.location.Geocoder(context);
|
|
||||||
List<Address> addresses =
|
|
||||||
geocoder.getFromLocation(mapPosition.getLatitude(), mapPosition.getLongitude(), 1);
|
|
||||||
Place place = newPlace(mapPosition);
|
|
||||||
if (addresses.isEmpty()) {
|
|
||||||
return place;
|
|
||||||
}
|
|
||||||
|
|
||||||
Address address = addresses.get(0);
|
|
||||||
if (address.getMaxAddressLineIndex() >= 0) {
|
|
||||||
place.setName(address.getAddressLine(0));
|
|
||||||
StringBuilder builder = new StringBuilder(place.getName());
|
|
||||||
for (int i = 1; i <= address.getMaxAddressLineIndex(); i++) {
|
|
||||||
builder.append(", ").append(address.getAddressLine(i));
|
|
||||||
}
|
|
||||||
place.setAddress(builder.toString());
|
|
||||||
}
|
|
||||||
if (address.hasLatitude() && address.hasLongitude()) {
|
|
||||||
place.setLatitude(address.getLatitude());
|
|
||||||
place.setLongitude(address.getLongitude());
|
|
||||||
}
|
|
||||||
place.setPhone(address.getPhone());
|
|
||||||
place.setUrl(address.getUrl());
|
|
||||||
return place;
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,43 @@
|
|||||||
|
package org.tasks.location
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.tasks.data.Place
|
||||||
|
import org.tasks.data.Place.Companion.newPlace
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
class AndroidGeocoder @Inject constructor(@ApplicationContext context: Context) : Geocoder {
|
||||||
|
private val geocoder = if (android.location.Geocoder.isPresent()) {
|
||||||
|
android.location.Geocoder(context)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun reverseGeocode(mapPosition: MapPosition): Place =
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
val addresses = geocoder?.getFromLocation(mapPosition.latitude, mapPosition.longitude, 1) ?: emptyList()
|
||||||
|
val place = newPlace(mapPosition)
|
||||||
|
if (addresses.isEmpty()) {
|
||||||
|
return@withContext place!!
|
||||||
|
}
|
||||||
|
val address = addresses[0]
|
||||||
|
if (address.maxAddressLineIndex >= 0) {
|
||||||
|
place!!.name = address.getAddressLine(0)
|
||||||
|
val builder = StringBuilder(place.name)
|
||||||
|
for (i in 1..address.maxAddressLineIndex) {
|
||||||
|
builder.append(", ").append(address.getAddressLine(i))
|
||||||
|
}
|
||||||
|
place.address = builder.toString()
|
||||||
|
}
|
||||||
|
if (address.hasLatitude() && address.hasLongitude()) {
|
||||||
|
place!!.latitude = address.latitude
|
||||||
|
place.longitude = address.longitude
|
||||||
|
}
|
||||||
|
place!!.phone = address.phone
|
||||||
|
place.url = address.url
|
||||||
|
place
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package org.tasks.location;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import org.tasks.data.Place;
|
|
||||||
|
|
||||||
public interface Geocoder {
|
|
||||||
Place reverseGeocode(MapPosition mapPosition) throws IOException;
|
|
||||||
}
|
|
@ -0,0 +1,7 @@
|
|||||||
|
package org.tasks.location
|
||||||
|
|
||||||
|
import org.tasks.data.Place
|
||||||
|
|
||||||
|
interface Geocoder {
|
||||||
|
suspend fun reverseGeocode(mapPosition: MapPosition): Place
|
||||||
|
}
|
@ -1,58 +0,0 @@
|
|||||||
package org.tasks.location;
|
|
||||||
|
|
||||||
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
|
|
||||||
import static org.tasks.data.Place.newPlace;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonParser;
|
|
||||||
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 java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
import org.tasks.BuildConfig;
|
|
||||||
import org.tasks.R;
|
|
||||||
import org.tasks.data.Place;
|
|
||||||
import retrofit2.Response;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
public class MapboxGeocoder implements Geocoder {
|
|
||||||
|
|
||||||
private final String token;
|
|
||||||
|
|
||||||
public MapboxGeocoder(Context context) {
|
|
||||||
token = context.getString(R.string.mapbox_key);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String prettyPrint(String json) {
|
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
return new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(json));
|
|
||||||
}
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Place reverseGeocode(MapPosition mapPosition) throws IOException {
|
|
||||||
assertNotMainThread();
|
|
||||||
|
|
||||||
Response<GeocodingResponse> response =
|
|
||||||
MapboxGeocoding.builder()
|
|
||||||
.accessToken(token)
|
|
||||||
.query(Point.fromLngLat(mapPosition.getLongitude(), mapPosition.getLatitude()))
|
|
||||||
.build()
|
|
||||||
.executeCall();
|
|
||||||
GeocodingResponse body = response.body();
|
|
||||||
if (response.isSuccessful() && body != null) {
|
|
||||||
Timber.d(prettyPrint(body.toJson()));
|
|
||||||
List<CarmenFeature> features = body.features();
|
|
||||||
if (features.size() > 0) {
|
|
||||||
return newPlace(features.get(0));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Timber.e(response.errorBody().string());
|
|
||||||
}
|
|
||||||
return newPlace(mapPosition);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,48 @@
|
|||||||
|
package org.tasks.location
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.google.gson.GsonBuilder
|
||||||
|
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 org.tasks.R
|
||||||
|
import org.tasks.data.Place
|
||||||
|
import org.tasks.data.Place.Companion.newPlace
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class MapboxGeocoder @Inject constructor(@ApplicationContext context: Context) : Geocoder {
|
||||||
|
private val token: String = context.getString(R.string.mapbox_key)
|
||||||
|
|
||||||
|
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])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Timber.e(response.errorBody()!!.string())
|
||||||
|
}
|
||||||
|
newPlace(mapPosition)!!
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun prettyPrint(json: String): String {
|
||||||
|
return if (BuildConfig.DEBUG) {
|
||||||
|
GsonBuilder().setPrettyPrinting().create().toJson(JsonParser().parse(json))
|
||||||
|
} else json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue