我正在开发一款使用GPS坐标进行排行榜的iPhone应用。我不需要坐标准确 - 实际上我并不希望坐标准确,以保护用户隐私。
我正在为期望的准确度指定kCLLocationAccuracyThreeKilometers,但是当GPS处于活动状态时,它似乎也可以在设备拥有它时获取确切的位置。
问题:我可以使用任何简单的算法来使GPS数据更粗糙吗?比如说,让它精细到3km。
如果我只是缩放数字并删除小数点并再次缩小它会使它在世界某些地方比其他地方更粗糙。
谢谢!
答案 0 :(得分:2)
这与之前的问题非常相似 Rounding Lat and Long to Show Approximate Location in Google Maps
如果你假设地球是一个球体(可能适合这个问题),那么你只需要计算一个与给定纬度和经度有一定距离的位置。选择距离和(随机)方向,并使用距离公式计算新位置。
这里有相反问题(两个纬度/经度点之间的距离)的良好讨论:http://mathforum.org/library/drmath/view/51756.html
从那里去寻找距离给定点一定距离的点应该是相对简单的。
答案 1 :(得分:0)
我尝试在Ruby中实现解决方案但在我的情况下,粗略坐标与实际有很大差异。粗调坐标仅在纬度变化时改变,但当拉特保持相同且长时间移动时,粗调保持不变。如果有人可以检查下面的代码,也许我的编码很糟糕。
class CoarseLocation
AREA_LIMIT = 1000
class << self
def make_location_coarse(lat, lon)
if lat.nil? && lon.nil?
raise InvalidParamsError
end
location = [lat.to_f, lat.to_f]
new_location_up = get_location_by_offset(location, AREA_LIMIT, 0)
granularityLat = location[0] - new_location_up[0]
if granularityLat < 0
granularityLat = -granularityLat
end
new_location_right = get_location_by_offset(location, AREA_LIMIT, 1.57079633)
granularityLon = location[1] - new_location_right[1]
if(granularityLon < 0)
granularityLon = -granularityLon
end
course_lat = location[0]
course_lon = location[1]
if(granularityLat == 0.0) || (granularityLon == 0.0)
course_lat = 0
course_lon = 0
else
course_lat = (course_lat / granularityLat).to_i * granularityLat
course_lon = (course_lon / granularityLon).to_i * granularityLon
end
[course_lat, course_lon]
end
def get_location_by_offset(location, offset, angle)
lat_radius = location[0] * Math::PI / 180
lon_radius = location[1] * Math::PI / 180
distance = (offset / 1000).to_f
earth_radius = 6371
lat_radius_1 = (Math::asin( Math::sin(lat_radius) * Math::cos(distance/earth_radius) + Math::cos(lat_radius) * Math::sin(distance/earth_radius) * Math::cos(angle))).to_f
lon_radius_1 = (lon_radius + Math::atan2(Math::sin(angle)*Math::sin(distance/earth_radius)*Math::cos(lat_radius), Math::cos(distance/earth_radius) - Math::sin(lat_radius)*Math::sin(lat_radius_1))).to_f
new_lat = lat_radius_1 * 180 / Math::PI
new_lon = lon_radius_1 * 180 / Math::PI
return [new_lat.to_f, new_lon.to_f]
end
end
end
位置字段始终是2个元素的数组,其中[0]为lat且[1]为long。
答案 2 :(得分:0)
猪瘟的答案还可以,但不需要这么复杂的数学。如果您要四舍五入到网格,那么纬度会在地球上的所有点上以恒定量变化。根据你离赤道的距离,经度会有不同的变化。
以下代码将纬度和经度捕捉到任意网格大小
double EARTH_RADIUS_KM = 6371;
double GRID_SIZE_KM = 1.6; // <----- Our grid size in km..
double DEGREES_LAT_GRID = Math.toDegrees(GRID_SIZE_KM / EARTH_RADIUS_KM);
// ^^^^^^ This is constant for a given grid size.
public Location snapToGrid(Location myLoc) {
double cos = Math.cos(Math.toRadians(myLoc.latitude));
double degreesLonGrid = DEGREES_LAT_GRID / cos;
return new Location (
Math.round(myLoc.longitude / degreesLonGrid) * degreesLonGrid,
Math.round(myLoc.latitude / DEGREES_LAT_GRID) * DEGREES_LAT_GRID);
}
请注意,在您处于极点的情况下(当cos函数接近零时),这将失败。根据您的网格大小,当您接近+/- 90度的纬度时,结果将变得不可预测。处理这是一个留给读者的练习:)