List Order

3

My query is as follows: I have a list of objects where each one receives a latitude and longitude. Using a CustomAdapter I show the objects and with a method I calculate the distance between my position and that of the list to show how many kilometers I am

@Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        dialogo.dismiss();

        lista.setAdapter(new MiListaAdapter(cxt, R.layout.item_list, jsonArray, lat1, lon1));
        lista.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    }

Where jsonArray is the list. I read that to order I need to use a class Comparator and I was looking at some examples but it is not completely clear to me. Could you give me some help with this? Thanks in advance

With this code I calculate the distance:

 public static double distance(LatLng StartP, LatLng EndP) {
    double lat1 = StartP.latitude;
    double lat2 = EndP.latitude;
    double lon1 = StartP.longitude;
    double lon2 = EndP.longitude;
    double dLat = Math.toRadians(lat2-lat1);
    double dLon = Math.toRadians(lon2-lon1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                    Math.sin(dLon/2) * Math.sin(dLon/2);
    double c = 2 * Math.asin(Math.sqrt(a));
    return 6366000 * c;
}

And in my adapter I paint how many Km. of each object I am with this:

Double distance = distance(new LatLng(lat1, lon1),
                new LatLng(Double.parseDouble(lat2), Double.parseDouble(lon2)));

        v.txtDistancia.setText("Distancia: " + distance);

Here is the structure of the JSON:

[
 {
  "id":4,
  "empresa_id":2,,
  "descripcion":null,
  "ubicacion":{
    "latitud":"-25.2677084",
    "longitud":"-57.58343660000003"
  },
  "direccion":""
},
{
  "id":7,
  "empresa_id":4,
  "descripcion":null,
  "ubicacion":{
    "latitud":"-25.268784",
    "longitud":"-57.580160999999976"
  },
  "direccion":""
 }
 ...
 ...
]

MyListaAdapter Code:

public class MiListaAdapter extends ArrayAdapter<JSONObject> {
   public JSONArray data;
   Context cxt;
   LayoutInflater inflater;
   double lat1, lon1;  //Latitud y longitud del teléfono

public MiListaAdapter(Context context, int resource, JSONArray data, Double lat1, Double lon1) {
    super(context, resource);
    this.data = data;
    this.cxt = context;
    this.lat1 = lat1;
    this.lon1 = lon1;
    inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}

class ViewHolder {
    TextView txtDistancia;
    LinearLayout itemContainer;
}

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

@NonNull
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder v = null;
    if(convertView == null) {
        convertView = inflater.inflate(R.layout.item_list, null, false);
        v = new ViewHolder();
        v.txtDistancia = (TextView)convertView.findViewById(R.id.textDistance);
        v.itemContainer = (LinearLayout)convertView.findViewById(R.id.itemContainer);
        convertView.setTag(v);
    }
    else {
        v = (ViewHolder)convertView.getTag();
    }

    try {
        final JSONObject content = data.getJSONObject(position);
        String lat2 = content.getJSONObject("ubicacion").getString("latitud");
        String lon2 = content.getJSONObject("ubicacion").getString("longitud");

        //Calcular distancia entre lat y long con el metodo 'Distance'
        Double distance = distance(new LatLng(lat1, lon1),
                new LatLng(Double.parseDouble(lat2), Double.parseDouble(lon2)));

        v.txtDistancia.setText("Distancia: " + distance);

    return convertView;
}

public static double distance(LatLng StartP, LatLng EndP) {
    double lat1 = StartP.latitude;
    double lat2 = EndP.latitude;
    double lon1 = StartP.longitude;
    double lon2 = EndP.longitude;
    double dLat = Math.toRadians(lat2-lat1);
    double dLon = Math.toRadians(lon2-lon1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
            Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
                    Math.sin(dLon/2) * Math.sin(dLon/2);
    double c = 2 * Math.asin(Math.sqrt(a));
    return 6366000 * c;
}

public static String getBetterValueKmMetres(double pValue)
{
    String output = "";
    int intDivider = (int)pValue/1000;
    NumberFormat format = NumberFormat.getNumberInstance();
    format.setMinimumFractionDigits(2);
    format.setMaximumFractionDigits(2);
    if(intDivider > 0)
    {
        pValue /= 1000;
        output = format.format(pValue);
        output+= " Km";
    }
    else
    {
        output = format.format(pValue);
        output+= " m";
    }

    return output;
}}
    
asked by Megaherx 23.11.2017 в 14:06
source

1 answer

5

Create a class that implements Comparable

Class Ubicacion :

        public class Ubicacion implements Comparable { 

          public double distancia;
          public String latitude;
          public String longitude;

         @Override
            public int compareTo(Ubicacion compararCon) {
                int distanciaComparada=(int)((Ubicacion)compararCon).distancia;
                /* Para orden ascendiente*/
                return ((int)this.distancia)-distanciaComparada;

                /* Para orden descendiente */
                //return distanciaComparada-this.distancia;
            }


        }

Your Adaptador should receive a ArrayList of Ubicacion

    public class MiListaAdapter extends ArrayAdapter<JSONObject> {
       public List<Ubicacion> data;
       Context cxt;
       LayoutInflater inflater;
       double lat1, lon1;  //Latitud y longitud del teléfono

Your method getView() change it to:

       @NonNull
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        ViewHolder v = null;
        if(convertView == null) {
            convertView = inflater.inflate(R.layout.item_list, null, false);
            v = new ViewHolder();
            v.txtDistancia = (TextView)convertView.findViewById(R.id.textDistance);
            v.itemContainer = (LinearLayout)convertView.findViewById(R.id.itemContainer);
            convertView.setTag(v);
        }
        else {
            v = (ViewHolder)convertView.getTag();
        }

            final Ubicacion content = data.get(position);

            v.txtDistancia.setText("Distancia: " + content.distancia);

        return convertView;
    }

Sorting done before calling MiListaAdapter

        //antes de que llames a tu adapter
        List<Ubicacion> lista = new ArrayList<Ubicacion>();
         // data es tu JSON ARRAY
        for(int i=0; i< data.length(); i++){
            Ubicacion ubicacion = new Ubicacion();
         final JSONObject content = data.getJSONObject(position);

        String lat2 = content.getJSONObject("ubicacion").getString("latitud");
        String lon2 = content.getJSONObject("ubicacion").getString("longitud");

        //Calcular distancia entre lat y long con el metodo 'Distance'
        double distance = distance(new LatLng(lat1, lon1),
                new LatLng(Double.parseDouble(lat2), Double.parseDouble(lon2)));

           ubicacion.latitude = lat2;
           ubicacion.longitude = long2;
            ubicacion.distancia = distance;

            lista.add(ubicacion);

          }

After you have your arrayList with the data of JSON , then sort like this

 Collections.sort(lista);

Finally you can now call your adapter with your arraylist : list (which is already sorted)

    
answered by 23.11.2017 / 15:04
source