Author: fdesbois Date: 2012-09-10 15:33:34 +0200 (Mon, 10 Sep 2012) New Revision: 566 Url: http://forge.codelutin.com/repositories/revision/sammoa/566 Log: fixes #1464 : Rewrite all the algorithm for closestPoint and beforeDate Added: trunk/sammoa-persistence/src/test/java/fr/ulr/sammoa/persistence/DatesTest.java Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Dates.java trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/GeoPoints.java Modified: trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java =================================================================== --- trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-10 11:10:56 UTC (rev 565) +++ trunk/sammoa-application/src/main/java/fr/ulr/sammoa/application/flightController/FlightControllerValidation.java 2012-09-10 13:33:34 UTC (rev 566) @@ -121,7 +121,7 @@ } // Create a new location if no one is available for the newTime - if (!locationTime.equals(newTime)) { + if (!locationTime.isEqual(newTime)) { result = new GeoPointImpl(location.getLatitude(), location.getLongitude()); result.setSpeed(location.getSpeed()); Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Dates.java =================================================================== --- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Dates.java 2012-09-10 11:10:56 UTC (rev 565) +++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/Dates.java 2012-09-10 13:33:34 UTC (rev 566) @@ -24,10 +24,14 @@ * #L% */ +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.common.collect.Ordering; import org.joda.time.DateTime; import org.joda.time.Interval; import java.util.Date; +import java.util.Iterator; /** * Created: 31/08/12 @@ -52,6 +56,25 @@ return new DateTime(date); } + public static Date getBeforeDate(Date date, Iterable<Date> source) { + + Date result = null; + if (!Iterables.isEmpty(source)) { + + Iterator<Date> dates = Ordering.natural().sortedCopy(source).iterator(); + + Date current = dates.next(); + + while (current != null && !current.after(date)) { + // Current is before or equal to date + result = current; + // Go to next date + current = dates.hasNext() ? dates.next() : null; + } + } + return result; + } + public static Date newDateWithoutMillis() { return DateTime.now().withMillisOfSecond(0).toDate(); } @@ -64,6 +87,16 @@ return interval.contains(toDateTime(date)); } + public static Function<Date, DateTime> toDateTime() { + return new Function<Date, DateTime>() { + + @Override + public DateTime apply(Date input) { + return toDateTime(input); + } + }; + } + // public static Predicate<Date> inInterval(Interval interval) { // return new InIntervalPredicate(interval); // } Modified: trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/GeoPoints.java =================================================================== --- trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/GeoPoints.java 2012-09-10 11:10:56 UTC (rev 565) +++ trunk/sammoa-persistence/src/main/java/fr/ulr/sammoa/persistence/GeoPoints.java 2012-09-10 13:33:34 UTC (rev 566) @@ -25,16 +25,12 @@ import com.google.common.base.Function; import com.google.common.base.Objects; -import com.google.common.base.Preconditions; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.FluentIterable; -import com.google.common.collect.Lists; +import com.google.common.collect.Iterables; import com.google.common.collect.Ordering; -import org.joda.time.DateTime; -import org.joda.time.Interval; -import java.util.Comparator; import java.util.Date; import java.util.List; @@ -91,129 +87,86 @@ return TO_DATE_FUNCTION; } - public static Comparator<GeoPoint> orderByDate() { - return BY_DATE_COMPARATOR; + public static List<GeoPoint> getClosestPoints(List<GeoPoint> geoPoints, + Iterable<Date> dates) { + + return FluentIterable.from(dates) + .transform(toClosestGeoPoint(geoPoints)) + .toImmutableList(); } - public static List<GeoPoint> getClosestPoints(List<GeoPoint> geoPoints, Iterable<Date> dates) { + public static GeoPoint getClosestPoint(List<GeoPoint> geoPoints, + Date date) { - List<GeoPoint> result = Lists.newArrayList(); + return toClosestGeoPoint(geoPoints).apply(date); + } - if (!geoPoints.isEmpty()) { + public static Function<Date, GeoPoint> toClosestGeoPoint(List<GeoPoint> list) { + return new ToClosestPointFunction(list); + } - List<GeoPoint> source = - Ordering.from(orderByDate()).sortedCopy(geoPoints); + public static Predicate<GeoPoint> withDate(Date date) { + return new WithDatePredicate(date); + } - List<Date> geoPointDates = Lists.transform(source, toDate()); + private static Function<GeoPoint, Date> TO_DATE_FUNCTION = new Function<GeoPoint, Date>() { - int index = 0; - for (Date date : dates) { + @Override + public Date apply(GeoPoint input) { + return input.getRecordTime(); + } + }; - // We continue starting from the previous index to avoid loop on all the date list - index = getBeforeDateIndex(index > 0 ? index - 1 : 0, geoPointDates, date); + private static Predicate<GeoPoint> IS_COORDINATES_EMPTY_PREDICATE = new Predicate<GeoPoint>() { - if (index != -1) { - result.add(geoPoints.get(index)); - } else { - result.add(newEmptyGeoPoint(date)); - } - } + @Override + public boolean apply(GeoPoint input) { + return isCoordinatesEmpty(input); } - return result; - } + }; - public static GeoPoint getClosestPoint(List<GeoPoint> geoPoints, Date date) { + private static class WithDatePredicate implements Predicate<GeoPoint> { - GeoPoint result = null; + protected Date date; - if (!geoPoints.isEmpty()) { + private WithDatePredicate(Date date) { + this.date = date; + } - List<GeoPoint> source = - Ordering.from(orderByDate()).sortedCopy(geoPoints); - - List<Date> geoPointDates = Lists.transform(source, toDate()); - - int index = getBeforeDateIndex(0, geoPointDates, date); - if (index != -1) { - result = geoPoints.get(index); - } else { - result = newEmptyGeoPoint(date); - } + @Override + public boolean apply(GeoPoint input) { + return date != null && date.equals(input.getRecordTime()); } - return result; } - protected static int getBeforeDateIndex(int startIndex, List<Date> source, Date date) { - int size = source.size(); - Preconditions.checkElementIndex(startIndex, size); - DateTime dateTime = Dates.toDateTime(date); + private static class ToClosestPointFunction implements Function<Date, GeoPoint> { - // If the first date is after the argument date we return -1, no date - // is available before - if (Dates.toDateTime(source.get(0)).isAfter(dateTime)) { - return -1; - } + protected Date date; - for (int index = startIndex; index < size; index++) { + protected List<GeoPoint> list; - int nextIndex = index + 1; - if (nextIndex < size) { + protected List<Date> dates; - Date begin = source.get(index); - Date end = source.get(nextIndex); - Interval interval = Dates.toInterval(begin, end); - - if (interval.contains(dateTime)) { - return index; - } - -// // If the date is equal or before we take the current index -// if (date.equals(before) || date.before(before)) { -// return index; -// -// // If the date is before the next date, we check which one -// // of the before and after is the nearest value and we return -// // its index -// } else if (date.before(after)) { -// -// long diffBefore = date.getTime() - before.getTime(); -// long diffAfter = after.getTime() - date.getTime(); -// -// if (diffBefore <= diffAfter) { -// return index; -// -// } else { -// return nextIndex; -// } -// } - } + private ToClosestPointFunction(List<GeoPoint> list) { + this.list = list; + this.dates = FluentIterable + .from(list) + .transform(toDate()) + .toSortedImmutableList(Ordering.natural()); } - // We loop over the whole list, we return the last index - return size - 1; - } - private static Function<GeoPoint, Date> TO_DATE_FUNCTION = new Function<GeoPoint, Date>() { - @Override - public Date apply(GeoPoint input) { - return input.getRecordTime(); - } - }; + public GeoPoint apply(Date input) { - private static Comparator<GeoPoint> BY_DATE_COMPARATOR = new Comparator<GeoPoint>() { + // Get the date before + Date beforeDate = Dates.getBeforeDate(input, dates); - @Override - public int compare(GeoPoint o1, GeoPoint o2) { - return o1.getRecordTime().compareTo(o2.getRecordTime()); - } - }; + // Find the matching GeoPoint or create an empty one with the date + GeoPoint result = Iterables.find( + list, withDate(beforeDate), newEmptyGeoPoint(input)); - private static Predicate<GeoPoint> IS_COORDINATES_EMPTY_PREDICATE = new Predicate<GeoPoint>() { - - @Override - public boolean apply(GeoPoint input) { - return isCoordinatesEmpty(input); + return result; } - }; + } } Added: trunk/sammoa-persistence/src/test/java/fr/ulr/sammoa/persistence/DatesTest.java =================================================================== --- trunk/sammoa-persistence/src/test/java/fr/ulr/sammoa/persistence/DatesTest.java (rev 0) +++ trunk/sammoa-persistence/src/test/java/fr/ulr/sammoa/persistence/DatesTest.java 2012-09-10 13:33:34 UTC (rev 566) @@ -0,0 +1,54 @@ +package fr.ulr.sammoa.persistence; + +import com.google.common.collect.ImmutableList; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Date; +import java.util.List; + +/** + * Created: 10/09/12 + * + * @author fdesbois <florian.desbois@codelutin.com> + */ +public class DatesTest { + + @Test + public void testGetBeforeDate() throws Exception { + + List<Date> dates = ImmutableList.of( + new Date(2000), + new Date(4000), + new Date(3000) + ); + + // Begin case + { + Date date = new Date(1000); + Date result = Dates.getBeforeDate(date, dates); + Assert.assertNull(result); + } + + // Normal case + { + Date date = new Date(2100); + Date result = Dates.getBeforeDate(date, dates); + Assert.assertEquals(2000, result.getTime()); + } + + // Equal case + { + Date date = new Date(3000); + Date result = Dates.getBeforeDate(date, dates); + Assert.assertEquals(3000, result.getTime()); + } + + // End case + { + Date date = new Date(4100); + Date result = Dates.getBeforeDate(date, dates); + Assert.assertEquals(4000, result.getTime()); + } + } +} Property changes on: trunk/sammoa-persistence/src/test/java/fr/ulr/sammoa/persistence/DatesTest.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native