0

I am getting my JSON data from the web. With many objects, one of these are latitude and longitude. I can calulate the exact distance but..

How can I sort the listview to show the nearest location first.

MainActivity

public class MainActivity extends ActionBarActivity {

    private ListView lv_nearestShops;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        GPSTracker gps;

        this.lv_nearestShops = (ListView) this.findViewById(R.id.lv_nearestShops);

        gps = new GPSTracker(MainActivity.this);

        if(gps.canGetLocation()) {
            double latitude = gps.getLatitude();
            double longitude = gps.getLongtitude();

            Log.d("Location = ", "Latitude: " + latitude + " - Longitude : " + longitude);
        }

        new GetAllShopsTask().execute(new ApiConnector());


    }

    public void setListAdapter(JSONArray jsonArray){

        this.lv_nearestShops.setAdapter(new lv_nearestShops_adapter(jsonArray, this));
    }

    private class GetAllShopsTask extends AsyncTask<ApiConnector,Long,JSONArray>
    {
        @Override
        protected JSONArray doInBackground(ApiConnector... params) {
            return params[0].GetAllShops();
        }

        @Override
        protected void onPostExecute(JSONArray jsonArray) {
            setListAdapter(jsonArray);

        }
    }


}

ApiConnector

public class ApiConnector {

    public JSONArray GetAllShops() {
        String url = ""; //php script

        HttpEntity httpEntity = null;

        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);

            HttpResponse httpResponse = httpClient.execute(httpGet);

            httpEntity = httpResponse.getEntity();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        JSONArray jsonArray = null;
        if (httpEntity != null) {
            try {
                String entityResponse = EntityUtils.toString(httpEntity);

                Log.e("Entity Response : ", entityResponse);

                jsonArray = new JSONArray(entityResponse);

            } catch (JSONException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return jsonArray;
    }
}

listview Adapter

public class lv_nearestShops_adapter extends BaseAdapter {

    private JSONArray dataArray;
    private Activity activity;

    double latA;
    double lngA;
    double latB;
    double lngB;

    private static LayoutInflater inflater = null;

    public lv_nearestShops_adapter(JSONArray jsonArray, Activity a)
    {
        this.dataArray = jsonArray;
        this.activity = a;

        inflater = (LayoutInflater) this.activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getCount() {
        return this.dataArray.length();
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.lv_nearestshop_layout, null);
            viewHolder = new ViewHolder();

            viewHolder.name = (TextView) convertView.findViewById(R.id.itemName);
            viewHolder.street = (TextView) convertView.findViewById(R.id.itemStreet);
            viewHolder.distance = (TextView) convertView.findViewById(R.id.itemDistance);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        try {
            JSONObject jsonObject = this.dataArray.getJSONObject(position);

            // naam
            viewHolder.name.setText(jsonObject.getString("name"));
            // street
            viewHolder.street.setText(jsonObject.getString("street"));

            // distance

            latB = jsonObject.getDouble("latitude");
            lngB = jsonObject.getDouble("longitude");

            float distance;

            GPSTracker gps;

            Context context = parent.getContext();
            gps = new GPSTracker(context);

            if(gps.canGetLocation()) {
                latA = gps.getLatitude();
                lngA = gps.getLongtitude();

                Log.e("Location = ", "Latitude: " + latA + " - Longitude : " + lngA);
            }

            Location locationA = new Location("point A");
            locationA.setLatitude(latA);
            locationA.setLongitude(lngA);
            Location locationB = new Location("point B");
            locationB.setLatitude(latB);
            locationB.setLongitude(lngB);
            distance = locationA.distanceTo(locationB);

            int iDistance= (int) distance;

            if(iDistance > 1000) {
                int result = iDistance / 1000;
                viewHolder.distance.setText(String.valueOf(result) + " km");
            } else {
                viewHolder.distance.setText(String.valueOf(iDistance) + " m");
            }

            jsonObject.put("distance", iDistance);


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


        return convertView;
    }

    private class ViewHolder{
        private TextView name;
        private TextView street;
        private TextView distance;
    }

}
tomwassing
  • 925
  • 1
  • 10
  • 30

2 Answers2

1

One way would be to convert you JSON array a standard ArrayList containing a wrapper class for the contents of the JSON object. e.g

class Location
{
    JSONObject jsonObject;

    public Location(JSONObject jsonObj)
    {
        this.jsonObject = jsonObj
    }

    long getLongitude()
    {
        // get longitude value from json object
    }

    long getLatitude()
    {
        // get latitude value from json object
    }


    // .. any other info
}


List<Location> locationList = new ArrayList<Location>(); 

Create a Comparator class for sorting this list by distance to current location, using the longitude, latitude stored in the Location class. Then Collection.sort(list, yourComparator) will sort the list for you.

Change your listview to use locationList object instead.

Sanj
  • 850
  • 7
  • 7
0

You can calculate distance between user's location and incoming lat-long json data like:

function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
 var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

Then you can store the distances in an array and sort the array. Display the sorted data in listview.

Courtesy

Community
  • 1
  • 1
Karan
  • 2,120
  • 15
  • 27