package com.example.agathe.tsgtest.database; import android.content.Context; import android.location.Address; import android.location.Geocoder; import android.os.AsyncTask; import com.amazonaws.mobile.AWSMobileClient; import com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBMapper; import com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.DynamoDBQueryExpression; import com.amazonaws.mobileconnectors.dynamodbv2.dynamodbmapper.PaginatedQueryList; import com.amazonaws.models.nosql.PathsDO; import com.amazonaws.services.dynamodbv2.model.AttributeValue; import com.amazonaws.services.dynamodbv2.model.ComparisonOperator; import com.amazonaws.services.dynamodbv2.model.Condition; import com.example.agathe.tsgtest.dto.CommonTravel; import com.example.agathe.tsgtest.dto.Place; import com.example.agathe.tsgtest.dto.User; import com.google.android.gms.maps.model.LatLng; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Locale; /** * Created by agathe on 30/11/16. */ public class AllPathsUserTask extends AsyncTask<String, Void, ArrayList<CommonTravel>> { private static String LOG_TAG = "LoadObjectTask"; private String type = ""; private String clientId = ""; private Context context = null; // Fetch the default configured DynamoDB ObjectMapper final DynamoDBMapper mapper = AWSMobileClient.defaultMobileClient().getDynamoDBMapper(); @Override protected ArrayList<CommonTravel> doInBackground(String... strings) { // The userId has to be set to user's Cognito Identity Id for private / protected tables. // User's Cognito Identity Id can be fetched by using: PaginatedQueryList<PathsDO> resultFinalLon = null, resultFinalLat = null, resultFinalStart = null, resultFinalEnd = null; List<PathsDO> resultFinal = new ArrayList<>(); PathsDO path = new PathsDO(); path.setUserId(clientId); DynamoDBQueryExpression queryExpression = new DynamoDBQueryExpression() .withHashKeyValues(path) .withConsistentRead(false); PaginatedQueryList<PathsDO> resultsForCurrentUser = mapper.query(PathsDO.class, queryExpression); List<Place> places = null; // liste de mes contacts List<User> contacts = new ArrayList<>(); ArrayList<CommonTravel> travels = new ArrayList<>(); // Pour chaque trajet, on regarde ceux qui ont une longitude / latitude / startTime / endTime assez proche, ici pour le même utilisateur, ce qui n'a pas de sens if (resultsForCurrentUser.size() != 0) { for (PathsDO p : resultsForCurrentUser) { List<User> users = new ArrayList<>(); Condition lonCondition = new Condition() .withComparisonOperator(ComparisonOperator.BETWEEN) .withAttributeValueList(new AttributeValue().withN(String.valueOf((p.getLon() - 0.5))), new AttributeValue().withN(String.valueOf((p.getLon() + 0.5)))); Condition latCondition = new Condition() .withComparisonOperator(ComparisonOperator.BETWEEN) .withAttributeValueList(new AttributeValue().withN(String.valueOf((p.getLat() - 0.5))), new AttributeValue().withN(String.valueOf((p.getLat() + 0.5)))); Condition startTimeCondition = new Condition() .withComparisonOperator(ComparisonOperator.BETWEEN) .withAttributeValueList(new AttributeValue().withN(String.valueOf((p.getStartTime() - 0.5))), new AttributeValue().withN(String.valueOf((p.getEndTime() + 0.5)))); Condition endTimeCondition = new Condition() .withComparisonOperator(ComparisonOperator.BETWEEN) .withAttributeValueList(new AttributeValue().withN(String.valueOf((p.getStartTime() - 0.5))), new AttributeValue().withN(String.valueOf((p.getEndTime() + 0.5)))); // pour chacun de ses contacts if (contacts != null) { for (User u : contacts) { PathsDO pathOtherUser = new PathsDO(); pathOtherUser.setUserId(u.name); DynamoDBQueryExpression queryExpressionLat = new DynamoDBQueryExpression() .withHashKeyValues(pathOtherUser) .withRangeKeyCondition("lat", latCondition) .withConsistentRead(false); DynamoDBQueryExpression queryExpressionLon = new DynamoDBQueryExpression() .withHashKeyValues(pathOtherUser) .withRangeKeyCondition("lon", lonCondition) .withConsistentRead(false); DynamoDBQueryExpression queryExpressionStart = new DynamoDBQueryExpression() .withHashKeyValues(pathOtherUser) .withRangeKeyCondition("startTime", startTimeCondition) .withConsistentRead(false); DynamoDBQueryExpression queryExpressionEnd = new DynamoDBQueryExpression() .withHashKeyValues(pathOtherUser) .withRangeKeyCondition("endTime", endTimeCondition) .withConsistentRead(false); resultFinalLat = mapper.query(PathsDO.class, queryExpressionLat); resultFinalLon = mapper.query(PathsDO.class, queryExpressionLon); resultFinalStart = mapper.query(PathsDO.class, queryExpressionStart); resultFinalEnd = mapper.query(PathsDO.class, queryExpressionEnd); // Ne garde que les éléments communs aux différents paramètres for (PathsDO pathLat : resultFinalLat) { for (PathsDO pathLon : resultFinalLon) { for (PathsDO pathStart : resultFinalStart) { for (PathsDO pathEnd : resultFinalEnd) { if (delta(pathLat.getLat(), pathLon.getLat()) == 0 && delta(pathLat.getLat(), pathStart.getLat()) == 0 && delta(pathLat.getLat(), pathEnd.getLat()) == 0) { // ajouter l'utilisateur dans une liste qu'on ajoutera à la fin au trajet users.add(u); break; } } } } } } if (users.size() != 0) { Place place = new Place(path.getLon(), path.getEndTime(), path.getLat(), path.getStartTime(), users); places.add(place); } } } if (contacts != null) { // A la fin, on a une liste de lieux en commun. Il faut distinguer des trajets ("CommonTravel") for (User u : contacts) { Place firstPlace = null; // trouver les places en commun for (Place p : places) { if (p.getUsers().contains(u) && firstPlace.equals(null)) { firstPlace = p; } if (p.getUsers().contains(u) && !firstPlace.equals(null)) { List<User> users = new ArrayList<>(); users.add(u); Geocoder geocoder; List<Address> addresses1 = null, addresses2 = null; geocoder = new Geocoder(context, Locale.getDefault()); try { addresses1 = geocoder.getFromLocation(firstPlace.getLat(), firstPlace.getLon(), 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5 addresses2 = geocoder.getFromLocation(firstPlace.getLat(), firstPlace.getLon(), 1); } catch (IOException e) { e.printStackTrace(); } String address1 = addresses1.get(0).getAddressLine(0); String city1 = addresses1.get(0).getLocality(); String postalCode1 = addresses1.get(0).getPostalCode(); String address2 = addresses2.get(0).getAddressLine(0); String city2 = addresses2.get(0).getLocality(); String postalCode2 = addresses2.get(0).getPostalCode(); CommonTravel ct = new CommonTravel(address1 + city1 + postalCode1, address2 + city2 + postalCode2, new LatLng(firstPlace.getLat(), firstPlace.getLon()), new LatLng(p.getLat(), p.getLon()), users); travels.add(ct); } } } } } return travels; } public static double delta(double d1, double d2) { return Math.abs(d1- d2) / Math.max(Math.abs(d1), Math.abs(d2)); } public AllPathsUserTask(String type2, String clientId2, Context ct) { type = type2; clientId = clientId2; context = ct; } }