Twitter fabric API:根据位置对推文进行排序(最近的优先)
Twitter fabric API: Sorting tweets based on location (nearest first)
所以我正在使用 Fabric API 开发失物招领应用程序。它可以选择根据用户的当前位置对收集到的推文进行排序。我在网上找到了以下使用比较器进行排序的方法。然而,这似乎不起作用,排序前和排序后的结果完全一样。
public class SortLocations implements Comparator<Tweet> {
Double currLat;
Double currLng;
public SortLocations(Double currLat1, Double currLng1) {
currLat = currLat1;
currLng = currLng1;
}
@Override
public int compare(final Tweet tweet1, final Tweet tweet2) {
double lat1 = 0, lon1 = 0, lat2 = 0, lon2 = 0, distanceToPlace1 = 0, distanceToPlace2 = 0;
try {
lat1 = tweet1.coordinates.getLatitude();
lon1 = tweet1.coordinates.getLongitude();
lat2 = tweet2.coordinates.getLatitude();
lon2 = tweet2.coordinates.getLongitude();
distanceToPlace1 = distance(currLat, currLng, lat1, lon1);
distanceToPlace2 = distance(currLat, currLng, lat2, lon2);
} catch (Exception E) {
Log.d("No coordinates", "");
}
return (int) (distanceToPlace1 - distanceToPlace2);
}
public double distance(double fromLat, double fromLon, double toLat, double toLon) {
double radius = 6378137; // approximate Earth radius, *in meters*
double deltaLat = toLat - fromLat;
double deltaLon = toLon - fromLon;
double angle = 2 * Math.asin(Math.sqrt(
Math.pow(Math.sin(deltaLat / 2), 2) +
Math.cos(fromLat) * Math.cos(toLat) *
Math.pow(Math.sin(deltaLon / 2), 2)));
return radius * angle;
}
}
这就是 class 在我的 activity
中的使用方式
Collections.sort(tweetsSortedByLocation, new SortLocations(currLat, currLng));
其中 tweetsSortedByLocation 是列表类型。非常感谢任何帮助:)
我可能会建议一种稍微不同的方法,它可以让您的生活更轻松一些,而且不会浪费任何计算时间。
您当前的解决方案可能是 n + n log(n) 次:n 次用于将推文添加到集合,然后 n log(n) 次用于排序。如果您使用 PriorityQueue(在 Java 中作为最小堆实现)而不是常规列表(我假设 tweetsSortedByLocation 是),那么它会在您添加时进行排序,给您 n log(n) 时间: n 用于每个元素,log(n) 用于每次插入(想想二进制搜索)。
您可以像这样使用 PriorityQueue (https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html):
PriorityQueue<Tweet> tweetsSortedByLocation = new PriorityQueue<>(10, new SortLocations(currLat, currLong));
tweetsSortedByLocation.add(new Tweet()); // Or however you add them now
您也可以内联比较器,但使用 SortLocations 更好。
现在关于为什么排序时没有任何变化,这意味着 compare() 必须每次都返回 0。如果您计算的两个距离之间的差异小于 1,就会发生这种情况。查看此行上的整数:
return (int) (distanceToPlace1 - distanceToPlace2);
如果 distanceToPlace1 和 distanceToPlace2 的差异不超过 1,则整数转换将其变为 0,这在必须实现比较的方式中意味着相等。 (参见 https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html。)所以,试试这个(首先对最小距离进行排序(即按距离升序)):
if (distanceToPlace1 < distanceToPlace2) {
return -1;
} else if (distanceToPlace1 > distanceToPlace2) {
return 1;
} else {
return 0;
}
希望能解决您的问题
所以我正在使用 Fabric API 开发失物招领应用程序。它可以选择根据用户的当前位置对收集到的推文进行排序。我在网上找到了以下使用比较器进行排序的方法。然而,这似乎不起作用,排序前和排序后的结果完全一样。
public class SortLocations implements Comparator<Tweet> {
Double currLat;
Double currLng;
public SortLocations(Double currLat1, Double currLng1) {
currLat = currLat1;
currLng = currLng1;
}
@Override
public int compare(final Tweet tweet1, final Tweet tweet2) {
double lat1 = 0, lon1 = 0, lat2 = 0, lon2 = 0, distanceToPlace1 = 0, distanceToPlace2 = 0;
try {
lat1 = tweet1.coordinates.getLatitude();
lon1 = tweet1.coordinates.getLongitude();
lat2 = tweet2.coordinates.getLatitude();
lon2 = tweet2.coordinates.getLongitude();
distanceToPlace1 = distance(currLat, currLng, lat1, lon1);
distanceToPlace2 = distance(currLat, currLng, lat2, lon2);
} catch (Exception E) {
Log.d("No coordinates", "");
}
return (int) (distanceToPlace1 - distanceToPlace2);
}
public double distance(double fromLat, double fromLon, double toLat, double toLon) {
double radius = 6378137; // approximate Earth radius, *in meters*
double deltaLat = toLat - fromLat;
double deltaLon = toLon - fromLon;
double angle = 2 * Math.asin(Math.sqrt(
Math.pow(Math.sin(deltaLat / 2), 2) +
Math.cos(fromLat) * Math.cos(toLat) *
Math.pow(Math.sin(deltaLon / 2), 2)));
return radius * angle;
}
}
这就是 class 在我的 activity
中的使用方式Collections.sort(tweetsSortedByLocation, new SortLocations(currLat, currLng));
其中 tweetsSortedByLocation 是列表类型。非常感谢任何帮助:)
我可能会建议一种稍微不同的方法,它可以让您的生活更轻松一些,而且不会浪费任何计算时间。
您当前的解决方案可能是 n + n log(n) 次:n 次用于将推文添加到集合,然后 n log(n) 次用于排序。如果您使用 PriorityQueue(在 Java 中作为最小堆实现)而不是常规列表(我假设 tweetsSortedByLocation 是),那么它会在您添加时进行排序,给您 n log(n) 时间: n 用于每个元素,log(n) 用于每次插入(想想二进制搜索)。
您可以像这样使用 PriorityQueue (https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html):
PriorityQueue<Tweet> tweetsSortedByLocation = new PriorityQueue<>(10, new SortLocations(currLat, currLong));
tweetsSortedByLocation.add(new Tweet()); // Or however you add them now
您也可以内联比较器,但使用 SortLocations 更好。
现在关于为什么排序时没有任何变化,这意味着 compare() 必须每次都返回 0。如果您计算的两个距离之间的差异小于 1,就会发生这种情况。查看此行上的整数:
return (int) (distanceToPlace1 - distanceToPlace2);
如果 distanceToPlace1 和 distanceToPlace2 的差异不超过 1,则整数转换将其变为 0,这在必须实现比较的方式中意味着相等。 (参见 https://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html。)所以,试试这个(首先对最小距离进行排序(即按距离升序)):
if (distanceToPlace1 < distanceToPlace2) {
return -1;
} else if (distanceToPlace1 > distanceToPlace2) {
return 1;
} else {
return 0;
}
希望能解决您的问题