儘管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