mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 04:43:54 +01:00
Merge pull request #482 from maskaravivek/refactorNearby
Refactored NearbyActivity to extract out reusable code outside of the activity
This commit is contained in:
commit
397f7dbc85
11 changed files with 368 additions and 270 deletions
7
app/src/main/java/fr/free/nrw/commons/ViewHolder.java
Normal file
7
app/src/main/java/fr/free/nrw/commons/ViewHolder.java
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package fr.free.nrw.commons;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public interface ViewHolder<T> {
|
||||
void bindModel(Context context, T model);
|
||||
}
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
package fr.free.nrw.commons.location;
|
||||
|
||||
public class LatLng {
|
||||
|
||||
public final double latitude;
|
||||
public final double longitude;
|
||||
|
||||
LatLng(double latitude, double longitude) {
|
||||
/** Accepts latitude and longitude.
|
||||
* @param latitude double value
|
||||
* @param longitude double value
|
||||
*/
|
||||
public LatLng(double latitude, double longitude) {
|
||||
if(-180.0D <= longitude && longitude < 180.0D) {
|
||||
this.longitude = longitude;
|
||||
} else {
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package fr.free.nrw.commons.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
public class LocationServiceManager implements LocationListener {
|
||||
public static final String TAG = "LocationServiceManager";
|
||||
private String provider;
|
||||
private LocationManager locationManager;
|
||||
private LatLng latestLocation;
|
||||
|
||||
public LocationServiceManager(Context context) {
|
||||
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||
provider = locationManager.getBestProvider(new Criteria(), true);
|
||||
}
|
||||
|
||||
public LatLng getLatestLocation() {
|
||||
return latestLocation;
|
||||
}
|
||||
|
||||
/** Registers a LocationManager to listen for current location.
|
||||
*/
|
||||
public void registerLocationManager() {
|
||||
try {
|
||||
locationManager.requestLocationUpdates(provider, 400, 1, this);
|
||||
Location location = locationManager.getLastKnownLocation(provider);
|
||||
//Location works, just need to 'send' GPS coords
|
||||
// via emulator extended controls if testing on emulator
|
||||
Log.d(TAG, "Checking for location...");
|
||||
if (location != null) {
|
||||
this.onLocationChanged(location);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Illegal argument exception", e);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Security exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/** Unregisters location manager.
|
||||
*/
|
||||
public void unregisterLocationManager() {
|
||||
try {
|
||||
locationManager.removeUpdates(this);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Security exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
double currentLatitude = location.getLatitude();
|
||||
double currentLongitude = location.getLongitude();
|
||||
Log.d(TAG, "Latitude: " + String.valueOf(currentLatitude)
|
||||
+ " Longitude: " + String.valueOf(currentLongitude));
|
||||
|
||||
latestLocation = new LatLng(currentLatitude, currentLongitude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
Log.d(TAG, provider + "'s status changed to " + status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
Log.d(TAG, "Provider " + provider + " enabled");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
Log.d(TAG, "Provider " + provider + " disabled");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,18 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.Context;
|
||||
import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
|
||||
public class NearbyActivity extends BaseActivity {
|
||||
|
||||
private MyLocationListener myLocationListener;
|
||||
private LocationManager locationManager;
|
||||
private String provider;
|
||||
private Criteria criteria;
|
||||
private LatLng mLatestLocation;
|
||||
|
||||
private double currentLatitude, currentLongitude;
|
||||
//private String gpsCoords;
|
||||
private LocationServiceManager locationManager;
|
||||
|
||||
private static final String TAG = NearbyActivity.class.getName();
|
||||
|
||||
|
|
@ -35,7 +23,8 @@ public class NearbyActivity extends BaseActivity {
|
|||
if (getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
registerLocationManager();
|
||||
locationManager = new LocationServiceManager(this);
|
||||
locationManager.registerLocationManager();
|
||||
|
||||
// Begin the transaction
|
||||
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
|
||||
|
|
@ -70,75 +59,10 @@ public class NearbyActivity extends BaseActivity {
|
|||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.container, new NearbyListFragment()).commit();
|
||||
}
|
||||
protected LatLng getmLatestLocation() {
|
||||
return mLatestLocation;
|
||||
}
|
||||
/**
|
||||
* Registers a LocationManager to listen for current location
|
||||
*/
|
||||
protected void registerLocationManager() {
|
||||
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
|
||||
criteria = new Criteria();
|
||||
provider = locationManager.getBestProvider(criteria, true);
|
||||
myLocationListener = new MyLocationListener();
|
||||
|
||||
try {
|
||||
locationManager.requestLocationUpdates(provider, 400, 1, myLocationListener);
|
||||
Location location = locationManager.getLastKnownLocation(provider);
|
||||
//Location works, just need to 'send' GPS coords via emulator extended controls if testing on emulator
|
||||
Log.d(TAG, "Checking for location...");
|
||||
if (location != null) {
|
||||
myLocationListener.onLocationChanged(location);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "Illegal argument exception", e);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Security exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void unregisterLocationManager() {
|
||||
try {
|
||||
locationManager.removeUpdates(myLocationListener);
|
||||
} catch (SecurityException e) {
|
||||
Log.e(TAG, "Security exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for user's location when it changes
|
||||
*/
|
||||
private class MyLocationListener implements LocationListener {
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
currentLatitude = location.getLatitude();
|
||||
currentLongitude = location.getLongitude();
|
||||
Log.d(TAG, "Latitude: " + String.valueOf(currentLatitude) + " Longitude: " + String.valueOf(currentLongitude));
|
||||
|
||||
mLatestLocation = new LatLng(currentLatitude, currentLongitude);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||
Log.d(TAG, provider + "'s status changed to " + status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider) {
|
||||
Log.d(TAG, "Provider " + provider + " enabled");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider) {
|
||||
Log.d(TAG, "Provider " + provider + " disabled");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy(){
|
||||
super.onDestroy();
|
||||
|
||||
unregisterLocationManager();
|
||||
locationManager.unregisterLocationManager();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class NearbyAdapter extends ArrayAdapter<Place> {
|
||||
private List<Place> placesList;
|
||||
private Context context;
|
||||
|
||||
public List<Place> getPlacesList() {
|
||||
return placesList;
|
||||
}
|
||||
|
||||
/** Accepts activity context and list of places.
|
||||
* @param context activity context
|
||||
* @param places list of places
|
||||
*/
|
||||
public NearbyAdapter(Context context, List<Place> places) {
|
||||
super(context, R.layout.item_place, places);
|
||||
this.context = context;
|
||||
placesList = places;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
// Get the data item for this position
|
||||
Place place = getItem(position);
|
||||
Log.d("NearbyAdapter", "Place " + place.name);
|
||||
|
||||
// Check if an existing view is being reused, otherwise inflate the view
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(getContext())
|
||||
.inflate(R.layout.item_place, parent, false);
|
||||
}
|
||||
|
||||
NearbyViewHolder viewHolder = new NearbyViewHolder(convertView);
|
||||
viewHolder.bindModel(context, place);
|
||||
// Return the completed view to render on screen
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.Context;
|
||||
import static fr.free.nrw.commons.utils.LengthUtils.computeDistanceBetween;
|
||||
import static fr.free.nrw.commons.utils.LengthUtils.formatDistanceBetween;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
|
|
@ -10,27 +12,28 @@ import android.util.Log;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnItemClick;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
public class NearbyListFragment extends ListFragment implements TaskListener {
|
||||
|
||||
private NearbyAsyncTask nearbyAsyncTask;
|
||||
private NearbyAdapter mAdapter;
|
||||
private ListView listview;
|
||||
|
||||
private ProgressBar progressBar;
|
||||
@BindView(R.id.listview) ListView listview;
|
||||
@BindView(R.id.progressBar) ProgressBar progressBar;
|
||||
|
||||
private boolean isTaskRunning = false;
|
||||
|
||||
private List<Place> places;
|
||||
|
|
@ -53,7 +56,7 @@ public class NearbyListFragment extends ListFragment implements TaskListener {
|
|||
|
||||
Log.d(TAG, "NearbyListFragment created");
|
||||
View view = inflater.inflate(R.layout.fragment_nearby, container, false);
|
||||
progressBar = (ProgressBar) view.findViewById(R.id.progressBar);
|
||||
ButterKnife.bind(this, view);
|
||||
return view;
|
||||
}
|
||||
|
||||
|
|
@ -62,8 +65,7 @@ public class NearbyListFragment extends ListFragment implements TaskListener {
|
|||
|
||||
//Check that this is the first time view is created, to avoid double list when screen orientation changed
|
||||
if(savedInstanceState == null) {
|
||||
mLatestLocation = ((NearbyActivity) getActivity()).getmLatestLocation();
|
||||
listview = (ListView) getView().findViewById(R.id.listview);
|
||||
mLatestLocation = new LocationServiceManager(getActivity()).getLatestLocation();
|
||||
nearbyAsyncTask = new NearbyAsyncTask(this);
|
||||
nearbyAsyncTask.execute();
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
|
@ -159,145 +161,30 @@ public class NearbyListFragment extends ListFragment implements TaskListener {
|
|||
|
||||
listview.setAdapter(mAdapter);
|
||||
|
||||
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
|
||||
Place place = places.get(position);
|
||||
LatLng placeLatLng = place.location;
|
||||
|
||||
double latitude = placeLatLng.latitude;
|
||||
double longitude = placeLatLng.longitude;
|
||||
|
||||
Log.d(TAG, "Item at position " + position + " has coords: Lat: " + latitude + " Long: " + longitude);
|
||||
|
||||
//Open map app at given position
|
||||
Uri gmmIntentUri = Uri.parse("geo:0,0?q=" + latitude + "," + longitude);
|
||||
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
|
||||
|
||||
if (mapIntent.resolveActivity(getActivity().getPackageManager()) != null) {
|
||||
startActivity(mapIntent);
|
||||
}
|
||||
}
|
||||
});
|
||||
listener.onTaskFinished(result);
|
||||
mAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private class NearbyAdapter extends ArrayAdapter<Place> {
|
||||
@OnItemClick(R.id.listview)
|
||||
void onItemClicked(int position) {
|
||||
Place place = places.get(position);
|
||||
LatLng placeLatLng = place.location;
|
||||
|
||||
public List<Place> placesList;
|
||||
private Context mContext;
|
||||
double latitude = placeLatLng.latitude;
|
||||
double longitude = placeLatLng.longitude;
|
||||
|
||||
public NearbyAdapter(Context context, List<Place> places) {
|
||||
super(context, R.layout.item_place, places);
|
||||
mContext = context;
|
||||
placesList = places;
|
||||
}
|
||||
Log.d(TAG, "Item at position "
|
||||
+ position + " has coords: Lat: "
|
||||
+ latitude + " Long: "
|
||||
+ longitude);
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
// Get the data item for this position
|
||||
Place place = getItem(position);
|
||||
Log.d(TAG, "Place " + place.name);
|
||||
//Open map app at given position
|
||||
Uri gmmIntentUri = Uri.parse("geo:0,0?q=" + latitude + "," + longitude);
|
||||
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
|
||||
|
||||
// Check if an existing view is being reused, otherwise inflate the view
|
||||
if (convertView == null) {
|
||||
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_place, parent, false);
|
||||
}
|
||||
|
||||
// Lookup view for data population
|
||||
TextView tvName = (TextView) convertView.findViewById(R.id.tvName);
|
||||
TextView tvDesc = (TextView) convertView.findViewById(R.id.tvDesc);
|
||||
TextView distance = (TextView) convertView.findViewById(R.id.distance);
|
||||
ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
|
||||
|
||||
String quotelessName = place.name.replaceAll("^\"|\"$", "");
|
||||
|
||||
// Populate the data into the template view using the data object
|
||||
tvName.setText(quotelessName);
|
||||
tvDesc.setText(place.description);
|
||||
distance.setText(place.distance);
|
||||
|
||||
// See https://github.com/commons-app/apps-android-commons/issues/250
|
||||
// Most common types of desc: building, house, cottage, farmhouse, village, civil parish, church, railway station,
|
||||
// gatehouse, milestone, inn, secondary school, hotel
|
||||
switch(place.description) {
|
||||
case "building":
|
||||
icon.setImageResource(R.drawable.round_icon_generic_building);
|
||||
break;
|
||||
case "house":
|
||||
icon.setImageResource(R.drawable.round_icon_house);
|
||||
break;
|
||||
case "cottage":
|
||||
icon.setImageResource(R.drawable.round_icon_house);
|
||||
break;
|
||||
case "farmhouse":
|
||||
icon.setImageResource(R.drawable.round_icon_house);
|
||||
break;
|
||||
case "church":
|
||||
icon.setImageResource(R.drawable.round_icon_church);
|
||||
break;
|
||||
case "railway station":
|
||||
icon.setImageResource(R.drawable.round_icon_railway_station);
|
||||
break;
|
||||
case "gatehouse":
|
||||
icon.setImageResource(R.drawable.round_icon_gatehouse);
|
||||
break;
|
||||
case "milestone":
|
||||
icon.setImageResource(R.drawable.round_icon_milestone);
|
||||
break;
|
||||
case "inn":
|
||||
icon.setImageResource(R.drawable.round_icon_house);
|
||||
break;
|
||||
case "city":
|
||||
icon.setImageResource(R.drawable.round_icon_city);
|
||||
break;
|
||||
case "secondary school":
|
||||
icon.setImageResource(R.drawable.round_icon_school);
|
||||
break;
|
||||
case "edu":
|
||||
icon.setImageResource(R.drawable.round_icon_school);
|
||||
break;
|
||||
case "isle":
|
||||
icon.setImageResource(R.drawable.round_icon_island);
|
||||
break;
|
||||
case "mountain":
|
||||
icon.setImageResource(R.drawable.round_icon_mountain);
|
||||
break;
|
||||
case "airport":
|
||||
icon.setImageResource(R.drawable.round_icon_airport);
|
||||
break;
|
||||
case "bridge":
|
||||
icon.setImageResource(R.drawable.round_icon_bridge);
|
||||
break;
|
||||
case "road":
|
||||
icon.setImageResource(R.drawable.round_icon_road);
|
||||
break;
|
||||
case "forest":
|
||||
icon.setImageResource(R.drawable.round_icon_forest);
|
||||
break;
|
||||
case "park":
|
||||
icon.setImageResource(R.drawable.round_icon_park);
|
||||
break;
|
||||
case "river":
|
||||
icon.setImageResource(R.drawable.round_icon_river);
|
||||
break;
|
||||
case "waterfall":
|
||||
icon.setImageResource(R.drawable.round_icon_waterfall);
|
||||
break;
|
||||
default:
|
||||
icon.setImageResource(R.drawable.round_icon_unknown);
|
||||
}
|
||||
|
||||
// Return the completed view to render on screen
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
return position;
|
||||
if (mapIntent.resolveActivity(getActivity().getPackageManager()) != null) {
|
||||
startActivity(mapIntent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,47 +216,4 @@ public class NearbyListFragment extends ListFragment implements TaskListener {
|
|||
}
|
||||
return places;
|
||||
}
|
||||
|
||||
private String formatDistanceBetween(LatLng point1, LatLng point2) {
|
||||
if (point1 == null || point2 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NumberFormat numberFormat = NumberFormat.getNumberInstance();
|
||||
double distance = Math.round(computeDistanceBetween(point1, point2));
|
||||
|
||||
// Adjust to KM if M goes over 1000 (see javadoc of method for note
|
||||
// on only supporting metric)
|
||||
if (distance >= 1000) {
|
||||
numberFormat.setMaximumFractionDigits(1);
|
||||
return numberFormat.format(distance / 1000) + "km";
|
||||
}
|
||||
return numberFormat.format(distance) + "m";
|
||||
}
|
||||
|
||||
private static double computeDistanceBetween(LatLng from, LatLng to) {
|
||||
return computeAngleBetween(from, to) * 6371009.0D;
|
||||
}
|
||||
|
||||
private static double computeAngleBetween(LatLng from, LatLng to) {
|
||||
return distanceRadians(Math.toRadians(from.latitude), Math.toRadians(from.longitude), Math.toRadians(to.latitude), Math.toRadians(to.longitude));
|
||||
}
|
||||
|
||||
private static double distanceRadians(double lat1, double lng1, double lat2, double lng2) {
|
||||
return arcHav(havDistance(lat1, lat2, lng1 - lng2));
|
||||
}
|
||||
|
||||
private static double arcHav(double x) {
|
||||
return 2.0D * Math.asin(Math.sqrt(x));
|
||||
}
|
||||
|
||||
private static double havDistance(double lat1, double lat2, double dLng) {
|
||||
return hav(lat1 - lat2) + hav(dLng) * Math.cos(lat1) * Math.cos(lat2);
|
||||
}
|
||||
|
||||
private static double hav(double x) {
|
||||
double sinHalf = Math.sin(x * 0.5D);
|
||||
return sinHalf * sinHalf;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package fr.free.nrw.commons.nearby;
|
|||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
|
@ -10,6 +12,7 @@ import java.net.URL;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class NearbyPlaces {
|
||||
|
||||
private static final String TAG = NearbyPlaces.class.getName();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.ViewHolder;
|
||||
import fr.free.nrw.commons.utils.ResourceUtils;
|
||||
|
||||
public class NearbyViewHolder implements ViewHolder<Place> {
|
||||
@BindView(R.id.tvName) TextView tvName;
|
||||
@BindView(R.id.tvDesc) TextView tvDesc;
|
||||
@BindView(R.id.distance) TextView distance;
|
||||
@BindView(R.id.icon) ImageView icon;
|
||||
|
||||
public NearbyViewHolder(View view) {
|
||||
ButterKnife.bind(this, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindModel(Context context, Place place) {
|
||||
String quotelessName = place.name.replaceAll("^\"|\"$", "");
|
||||
|
||||
// Populate the data into the template view using the data object
|
||||
tvName.setText(quotelessName);
|
||||
tvDesc.setText(place.description);
|
||||
distance.setText(place.distance);
|
||||
|
||||
icon.setImageResource(ResourceUtils.getDescriptionIcon(place.description));
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ package fr.free.nrw.commons.nearby;
|
|||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
|
||||
public class Place {
|
||||
|
||||
public String name;
|
||||
|
|
|
|||
57
app/src/main/java/fr/free/nrw/commons/utils/LengthUtils.java
Normal file
57
app/src/main/java/fr/free/nrw/commons/utils/LengthUtils.java
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class LengthUtils {
|
||||
/** Returns a formatted distance string between two points.
|
||||
* @param point1 LatLng type point1
|
||||
* @param point2 LatLng type point2
|
||||
* @return string distance
|
||||
*/
|
||||
public static String formatDistanceBetween(LatLng point1, LatLng point2) {
|
||||
if (point1 == null || point2 == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NumberFormat numberFormat = NumberFormat.getNumberInstance();
|
||||
double distance = Math.round(computeDistanceBetween(point1, point2));
|
||||
|
||||
// Adjust to KM if M goes over 1000 (see javadoc of method for note
|
||||
// on only supporting metric)
|
||||
if (distance >= 1000) {
|
||||
numberFormat.setMaximumFractionDigits(1);
|
||||
return numberFormat.format(distance / 1000) + "km";
|
||||
}
|
||||
return numberFormat.format(distance) + "m";
|
||||
}
|
||||
|
||||
public static double computeDistanceBetween(LatLng from, LatLng to) {
|
||||
return computeAngleBetween(from, to) * 6371009.0D;
|
||||
}
|
||||
|
||||
private static double computeAngleBetween(LatLng from, LatLng to) {
|
||||
return distanceRadians(Math.toRadians(from.latitude),
|
||||
Math.toRadians(from.longitude),
|
||||
Math.toRadians(to.latitude),
|
||||
Math.toRadians(to.longitude));
|
||||
}
|
||||
|
||||
private static double distanceRadians(double lat1, double lng1, double lat2, double lng2) {
|
||||
return arcHav(havDistance(lat1, lat2, lng1 - lng2));
|
||||
}
|
||||
|
||||
private static double arcHav(double x) {
|
||||
return 2.0D * Math.asin(Math.sqrt(x));
|
||||
}
|
||||
|
||||
private static double havDistance(double lat1, double lat2, double longitude) {
|
||||
return hav(lat1 - lat2) + hav(longitude) * Math.cos(lat1) * Math.cos(lat2);
|
||||
}
|
||||
|
||||
private static double hav(double x) {
|
||||
double sinHalf = Math.sin(x * 0.5D);
|
||||
return sinHalf * sinHalf;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import android.support.annotation.DrawableRes;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
public class ResourceUtils {
|
||||
|
||||
/**
|
||||
* See https://github.com/commons-app/apps-android-commons/issues/250
|
||||
* Most common types of desc: building, house, cottage, farmhouse,
|
||||
* village, civil parish, church, railway station,
|
||||
* gatehouse, milestone, inn, secondary school, hotel
|
||||
* @param description Place description
|
||||
* @return icon res id
|
||||
*/
|
||||
@DrawableRes
|
||||
public static int getDescriptionIcon(String description) {
|
||||
int resourceId;
|
||||
switch (description) {
|
||||
case "building":
|
||||
resourceId = R.drawable.round_icon_generic_building;
|
||||
break;
|
||||
case "house":
|
||||
resourceId = R.drawable.round_icon_house;
|
||||
break;
|
||||
case "cottage":
|
||||
resourceId = R.drawable.round_icon_house;
|
||||
break;
|
||||
case "farmhouse":
|
||||
resourceId = R.drawable.round_icon_house;
|
||||
break;
|
||||
case "church":
|
||||
resourceId = R.drawable.round_icon_church;
|
||||
break;
|
||||
case "railway station":
|
||||
resourceId = R.drawable.round_icon_railway_station;
|
||||
break;
|
||||
case "gatehouse":
|
||||
resourceId = R.drawable.round_icon_gatehouse;
|
||||
break;
|
||||
case "milestone":
|
||||
resourceId = R.drawable.round_icon_milestone;
|
||||
break;
|
||||
case "inn":
|
||||
resourceId = R.drawable.round_icon_house;
|
||||
break;
|
||||
case "city":
|
||||
resourceId = R.drawable.round_icon_city;
|
||||
break;
|
||||
case "secondary school":
|
||||
resourceId = R.drawable.round_icon_school;
|
||||
break;
|
||||
case "edu":
|
||||
resourceId = R.drawable.round_icon_school;
|
||||
break;
|
||||
case "isle":
|
||||
resourceId = R.drawable.round_icon_island;
|
||||
break;
|
||||
case "mountain":
|
||||
resourceId = R.drawable.round_icon_mountain;
|
||||
break;
|
||||
case "airport":
|
||||
resourceId = R.drawable.round_icon_airport;
|
||||
break;
|
||||
case "bridge":
|
||||
resourceId = R.drawable.round_icon_bridge;
|
||||
break;
|
||||
case "road":
|
||||
resourceId = R.drawable.round_icon_road;
|
||||
break;
|
||||
case "forest":
|
||||
resourceId = R.drawable.round_icon_forest;
|
||||
break;
|
||||
case "park":
|
||||
resourceId = R.drawable.round_icon_park;
|
||||
break;
|
||||
case "river":
|
||||
resourceId = R.drawable.round_icon_river;
|
||||
break;
|
||||
case "waterfall":
|
||||
resourceId = R.drawable.round_icon_waterfall;
|
||||
break;
|
||||
default:
|
||||
resourceId = R.drawable.round_icon_unknown;
|
||||
}
|
||||
return resourceId;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue