mirror of https://github.com/tasks/tasks
Use Mapbox for reverse geocoding
parent
c350314cd2
commit
71c2d125c2
@ -0,0 +1,24 @@
|
||||
package org.tasks.injection;
|
||||
|
||||
import android.content.Context;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import org.tasks.location.MapFragment;
|
||||
import org.tasks.location.MapboxMapFragment;
|
||||
import org.tasks.location.MapboxSearchProvider;
|
||||
import org.tasks.location.PlaceSearchProvider;
|
||||
|
||||
@Module
|
||||
public class LocationModule {
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public PlaceSearchProvider getPlaceSearchProvider(@ForApplication Context context) {
|
||||
return new MapboxSearchProvider(context);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public MapFragment getMapFragment(@ForApplication Context context) {
|
||||
return new MapboxMapFragment(context);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package org.tasks.location;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import java.util.List;
|
||||
import org.tasks.data.Place;
|
||||
|
||||
public class GoogleMapFragment implements MapFragment {
|
||||
|
||||
public GoogleMapFragment(Context context) {}
|
||||
|
||||
@Override
|
||||
public void init(FragmentManager fragmentManager, MapFragmentCallback callback, boolean dark) {}
|
||||
|
||||
@Override
|
||||
public MapPosition getMapPosition() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void movePosition(MapPosition mapPosition, boolean animate) {}
|
||||
|
||||
@Override
|
||||
public void setMarkers(List<Place> places) {}
|
||||
|
||||
@Override
|
||||
public void showMyLocation() {}
|
||||
|
||||
@Override
|
||||
public int getMarkerId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package org.tasks.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import java.util.List;
|
||||
import org.tasks.Callback;
|
||||
import org.tasks.data.Place;
|
||||
|
||||
public class GooglePlacesSearchProvider implements PlaceSearchProvider {
|
||||
|
||||
public GooglePlacesSearchProvider(Context context) {}
|
||||
|
||||
@Override
|
||||
public void restoreState(Bundle savedInstanceState) {}
|
||||
|
||||
@Override
|
||||
public void saveState(Bundle outState) {}
|
||||
|
||||
@Override
|
||||
public int getAttributionRes(boolean dark) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(
|
||||
String query,
|
||||
MapPosition bias,
|
||||
Callback<List<PlaceSearchResult>> onSuccess,
|
||||
Callback<String> onError) {}
|
||||
|
||||
@Override
|
||||
public void fetch(
|
||||
PlaceSearchResult placeSearchResult, Callback<Place> onSuccess, Callback<String> onError) {}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package org.tasks.injection;
|
||||
|
||||
import android.content.Context;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import org.tasks.location.MapFragment;
|
||||
import org.tasks.location.MapboxMapFragment;
|
||||
import org.tasks.location.MapboxSearchProvider;
|
||||
import org.tasks.location.PlaceSearchProvider;
|
||||
|
||||
@Module
|
||||
public class LocationModule {
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public PlaceSearchProvider getPlaceSearchProvider(@ForApplication Context context) {
|
||||
return new MapboxSearchProvider(context);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public MapFragment getMapFragment(@ForApplication Context context) {
|
||||
return new MapboxMapFragment(context);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package org.tasks.location;
|
||||
|
||||
import android.content.Context;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import java.util.List;
|
||||
import org.tasks.data.Place;
|
||||
|
||||
public class GoogleMapFragment implements MapFragment {
|
||||
|
||||
public GoogleMapFragment(Context context) {}
|
||||
|
||||
@Override
|
||||
public void init(FragmentManager fragmentManager, MapFragmentCallback callback, boolean dark) {}
|
||||
|
||||
@Override
|
||||
public MapPosition getMapPosition() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void movePosition(MapPosition mapPosition, boolean animate) {}
|
||||
|
||||
@Override
|
||||
public void setMarkers(List<Place> places) {}
|
||||
|
||||
@Override
|
||||
public void showMyLocation() {}
|
||||
|
||||
@Override
|
||||
public int getMarkerId() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package org.tasks.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import java.util.List;
|
||||
import org.tasks.Callback;
|
||||
import org.tasks.data.Place;
|
||||
|
||||
public class GooglePlacesSearchProvider implements PlaceSearchProvider {
|
||||
|
||||
public GooglePlacesSearchProvider(Context context) {}
|
||||
|
||||
@Override
|
||||
public void restoreState(Bundle savedInstanceState) {}
|
||||
|
||||
@Override
|
||||
public void saveState(Bundle outState) {}
|
||||
|
||||
@Override
|
||||
public int getAttributionRes(boolean dark) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void search(
|
||||
String query,
|
||||
MapPosition bias,
|
||||
Callback<List<PlaceSearchResult>> onSuccess,
|
||||
Callback<String> onError) {}
|
||||
|
||||
@Override
|
||||
public void fetch(
|
||||
PlaceSearchResult placeSearchResult, Callback<Place> onSuccess, Callback<String> onError) {}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package org.tasks.injection;
|
||||
|
||||
import android.content.Context;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import org.tasks.billing.Inventory;
|
||||
import org.tasks.gtasks.PlayServices;
|
||||
import org.tasks.location.GoogleMapFragment;
|
||||
import org.tasks.location.GooglePlacesSearchProvider;
|
||||
import org.tasks.location.MapFragment;
|
||||
import org.tasks.location.MapboxMapFragment;
|
||||
import org.tasks.location.MapboxSearchProvider;
|
||||
import org.tasks.location.PlaceSearchProvider;
|
||||
import org.tasks.preferences.Preferences;
|
||||
|
||||
@Module
|
||||
public class LocationModule {
|
||||
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public PlaceSearchProvider getPlaceSearchProvider(
|
||||
@ForApplication Context context,
|
||||
Preferences preferences,
|
||||
PlayServices playServices,
|
||||
Inventory inventory) {
|
||||
return preferences.useGooglePlaces()
|
||||
&& playServices.isPlayServicesAvailable()
|
||||
&& inventory.hasPro()
|
||||
? new GooglePlacesSearchProvider(context)
|
||||
: new MapboxSearchProvider(context);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ActivityScope
|
||||
public MapFragment getMapFragment(@ForApplication Context context, Preferences preferences) {
|
||||
return preferences.useGoogleMaps()
|
||||
? new GoogleMapFragment(context)
|
||||
: new MapboxMapFragment(context);
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
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,8 @@
|
||||
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,60 @@
|
||||
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 com.mapbox.mapboxsdk.Mapbox;
|
||||
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);
|
||||
Mapbox.getInstance(context, token);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue