Kemo Kemo - 2 months ago 14
JSON Question

Displaying markers in a certain radius in Android

I am making an app that uses maps api. I have a bunch of markers on the server. What I want to do is display only the markers in the certain radius of user's current location (for example, show all markers in a 10 kilometer radius from my current location).

MapFragment:

if (myLocation != null) {
latitude = myLocation.getLatitude();
longitude = myLocation.getLongitude();
}

MarkerOptions markerOptions = new MarkerOptions().position(
new LatLng(latitude, longitude)).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker_me));

mMap.addMarker(markerOptions);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(latitude, longitude)).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));

mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {

@Override
public void onMapLongClick(final LatLng arg0) {

RequestQueue queue = Volley.newRequestQueue(getActivity());
String url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + String.valueOf(arg0.latitude) + "," + String.valueOf(arg0.longitude) + "&key=myKey";

// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
try {
JSONArray jObj = new JSONObject(response).getJSONArray("results").getJSONObject(0).getJSONArray("address_components");

Intent intent = new Intent(getActivity(), SetRestaurantActivity.class);

for (int i = 0; i < jObj.length(); i++) {
String componentName = new JSONObject(jObj.getString(i)).getJSONArray("types").getString(0);
if (componentName.equals("postal_code") || componentName.equals("locality") || componentName.equals("street_number") || componentName.equals("route")
|| componentName.equals("neighborhood") || componentName.equals("sublocality") || componentName.equals("administrative_area_level_2")
|| componentName.equals("administrative_area_level_1") || componentName.equals("country")) {
intent.putExtra(componentName, new JSONObject(jObj.getString(i)).getString("short_name"));
}
}

intent.putExtra("latitude", arg0.latitude);
intent.putExtra("longitude", arg0.longitude);

startActivity(intent);

} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
int x = 1;
}
});
queue.add(stringRequest);

}
});


MyRestaurantsFragment:

public class RestaurantsFragment extends Fragment {

private static final String TAG = RestaurantsFragment.class.getSimpleName();

// Restaurants json url
private ProgressDialog pDialog;
private List<Restaurant> restaurantList = new ArrayList<>();
private ListView listView;
private CustomListAdapter adapter;

@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_restaurants, container, false);

listView = (ListView) view.findViewById(R.id.restaurants_list);
adapter = new CustomListAdapter(getActivity(), restaurantList);
listView.setAdapter(adapter);

pDialog = new ProgressDialog(getActivity());

pDialog.setMessage("Loading...");
pDialog.show();

SQLiteHandler db = new SQLiteHandler(getActivity().getApplicationContext());
HashMap<String, String> user = db.getUserDetails();
final String userId = user.get("uid");

StringRequest restaurantReq = new StringRequest(Request.Method.POST,
AppConfig.URL_GET_RESTAURANT, new Response.Listener<String>() {

@Override
public void onResponse(String response) {
Log.d(TAG, "Login Response: " + response.toString());
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");

if (!error) {
JSONArray restaurants = jObj.getJSONArray("restaurant");

Log.d(TAG, response.toString());
hidePDialog();

// Parsing json
for (int i = 0; i < restaurants.length(); i++) {
try {

JSONObject obj = restaurants.getJSONObject(i);
Restaurant restaurant = new Restaurant();
restaurant.setUserName(obj.getString("name"));
if (obj.getString("image") != null && !obj.getString("image").isEmpty()) {
restaurant.setThumbnailUrl(obj.getString("image"));
}
restaurant.setLat(obj.getString("latitude"));
restaurant.setLon(obj.getString("longitude"));
restaurant.setDate(obj.getString("restaurant_name"));
restaurant.setTime(obj.getString("restaurant_description"));

// adding restaurant to restaurant array
restaurantList.add(restaurant);

} catch (JSONException e) {
e.printStackTrace();
}

}

// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
} else {
// Error. Get the error message
String errorMsg = jObj.getString("error_msg");
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}

}
},

Answer

Use SpherialUtils method computeDistanceBetween() from google-maps-utils to calculate distance from your position to every restaurant and filter out its collection by calculated distance

    ...
    restaurant.setDate(obj.getString("restaurant_name"));
    restaurant.setTime(obj.getString("restaurant_description"));
    restaurant.setLat(obj.getString("latitude"));
    restaurant.setLon(obj.getString("longitude"));
    // adding restaurant to restaurant array
    if (SphericalUtil.computeDistanceBetween(new LatLng(restaurant.getLat(), restaurant.getLon()), userLatLng)<10)
       restaurantList.add(restaurant);
    }