尽管Mark的回答很有用,但仍然没有产生一致结果的公式,因为它依赖于随机数生成器。
我的好友为此提供了最好的回答:
回合的纬度,经度取决于粒度最近显著的身影,但是这将导致所有附近的某个位置的纬度/经度,风中相同的位置。该方法将使用纬度/经度中两点之间的距离来计算纬度的四舍五入。使用下面的公式,并将路线设置为0,那么距离就是您的距离粒度。计算产生的新纬度/经度减去两个纬度/经度以获得纬度的舍入量。然后将标题设置为90并重新计算并从旧中减去新的经纬度以获得lon的舍入量。
而这里的C++代码:
class LocationUtility
{
public: static Location getLocationNow()
{
Location location;
if(context != null)
{
double latitude = 0;
double longitude = 0;
::of_getCurrentLocation(&latitude, &longitude);
location.setLatitude(latitude);
location.setLongitude(longitude);
location = makeLocationCoarse(location);
}
return location;
}
public: static Location makeLocationCoarse(const Location& location)
{
double granularityInMeters = 3 * 1000;
return makeLocationCoarse(location, granularityInMeters);
}
public: static Location makeLocationCoarse(const Location& location,
double granularityInMeters)
{
Location courseLocation;
if(location.getLatitude() == (double)0 &&
location.getLongitude() == (double)0)
{
// Special marker, don't bother.
}
else
{
double granularityLat = 0;
double granularityLon = 0;
{
// Calculate granularityLat
{
double angleUpInRadians = 0;
Location newLocationUp = getLocationOffsetBy(location,
granularityInMeters, angleUpInRadians);
granularityLat = location.getLatitude() -
newLocationUp.getLatitude();
if(granularityLat < (double)0)
{
granularityLat = -granularityLat;
}
}
// Calculate granularityLon
{
double angleRightInRadians = 1.57079633;
Location newLocationRight = getLocationOffsetBy(location,
granularityInMeters, angleRightInRadians);
granularityLon = location.getLongitude() -
newLocationRight.getLongitude();
if(granularityLon < (double)0)
{
granularityLon = -granularityLon;
}
}
}
double courseLatitude = location.getLatitude();
double courseLongitude = location.getLongitude();
{
if(granularityLon == (double)0 || granularityLat == (double)0)
{
courseLatitude = 0;
courseLongitude = 0;
}
else
{
courseLatitude = (int)(courseLatitude/granularityLat) *
granularityLat;
courseLongitude = (int)(courseLongitude/granularityLon) *
granularityLon;
}
}
courseLocation.setLatitude(courseLatitude);
courseLocation.setLongitude(courseLongitude);
}
return courseLocation;
}
// http://www.movable-type.co.uk/scripts/latlong.html
private: static Location getLocationOffsetBy(const Location& location,
double offsetInMeters, double angleInRadians)
{
Location newLocation;
double lat1 = location.getLatitude();
double lon1 = location.getLongitude();
lat1 = deg2rad(lat1);
lon1 = deg2rad(lon1);
double distanceKm = offsetInMeters/(double)1000;
const double earthRadiusKm = 6371;
double lat2 = asin(sin(lat1)*cos(distanceKm/earthRadiusKm) +
cos(lat1)*sin(distanceKm/earthRadiusKm)*cos(angleInRadians));
double lon2 = lon1 +
atan2(sin(angleInRadians)*sin(distanceKm/earthRadiusKm)*cos(lat1),
cos(distanceKm/earthRadiusKm)-sin(lat1)*sin(lat2));
lat2 = rad2deg(lat2);
lon2 = rad2deg(lon2);
newLocation.setLatitude(lat2);
newLocation.setLongitude(lon2);
return newLocation;
}
private: static double rad2deg(double radians)
{
static double ratio = (double)(180.0/3.141592653589793238);
return radians * ratio;
}
private: static double deg2rad(double radians)
{
static double ratio = (double)(180.0/3.141592653589793238);
return radians/ratio;
}
/*
public: static void testCoarse()
{
Location vancouver(49.2445, -123.099146);
Location vancouver2 = makeLocationCoarse(vancouver);
Location korea(37.423938, 126.692488);
Location korea2 = makeLocationCoarse(korea);
Location hiroshima(34.3937, 132.464);
Location hiroshima2 = makeLocationCoarse(hiroshima);
Location zagreb(45.791958, 15.935786);
Location zagreb2 = makeLocationCoarse(zagreb);
Location anchorage(61.367778, -149.900208);
Location anchorage2 = makeLocationCoarse(anchorage);
}*/
};
请记住,相似的长度有所不同。我的意思是在赤道附近(纬度〜0°),一个单一的经度是一个更大的距离,然后是靠近两极的一个单一的经度。在极点(纬度+/- 90°)处,经度甚至失去了它的意义。 – Plap