有什么简单的方法可以使 GPS 坐标变粗吗? [英] Is there any easy way to make GPS coordinates coarse?

查看:15
本文介绍了有什么简单的方法可以使 GPS 坐标变粗吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个将 GPS 坐标用于排行榜的 iPhone 应用.我不需要精确的坐标 --- 实际上,为了保护用户隐私,我不希望坐标精确.

I'm working on an iPhone app that is using GPS coordinates for leaderboards. I don't need the coordinates to be exact --- actually I don't ever want the coordinates to be exact, to protect user privacy.

我将 kCLLocationAccuracyThreeKilometers 指定为desiredAccuracy,但是当 GPS 处于活动状态时,它似乎也可以在设备拥有它时获取确切位置.

I am specifying kCLLocationAccuracyThreeKilometers for desiredAccuracy, but when the GPS is active it seems it can also pick up the exact location when the device has it.

问题:我可以使用任何简单的算法来使 GPS 数据更粗略吗?比如说,把它细化到 3 公里.

QUESTION: Is there any easy algorithm I can use to make the GPS data more coarse? Say, make it granular to 3km.

如果我只是放大数字并删除小数点并再次缩小它们,它会使其在世界某些地方比其他地方更粗糙.

If I just scale the numbers up and remove decimal points and scale them down again it will make it more coarse in some parts of the world than others.

谢谢!

推荐答案

虽然上面 Mark 的回答很有用,但它仍然没有产生具有一致结果的公式,因为它依赖于随机数生成器.

While Mark's answer above was a useful, it still did not yield a formula with consistent results because it relied on a random number generator.

我的好友为此提供了最佳答案:

My buddy provided the best answer for this:

根据粒度将纬度、经度四舍五入到最接近的有效数字,但这会导致某个位置附近的所有纬度/经度都在同一位置.此方法将使用 lat/lon 中两点之间的距离来计算 lat lon 的舍入.使用下面相同的公式并将路线设置为 0,那么距离就是您的距离粒度.计算得到的新纬度/经度减去两个纬度/经度以获得纬度的舍入量.然后将航向设置为 90 并重新计算并从旧的 lat/lon 中减去新的 lat/lon 以获得 lon 的四舍五入量.

Round the lat,lon to the nearest significant figure depending on the granularity, but this would result in all the lat/lons near a certain location, wind up in the same location. This method would use the distance between two points in lat/lon to calculate the rounding of the lat lon. Use the same formula below and set the course to 0, then the distance is your distance granularity. Calculate the resulting new lat/lon subtract the two lat/lons to get the rounding amount for lat. Then set the heading to 90 and recalculate and subtract the new lat/lon from the old to get the rounding amount for 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);
  }*/
};

这篇关于有什么简单的方法可以使 GPS 坐标变粗吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆