【问题标题】:Large volume geocoding and distance checking大容量地理编码和距离检查
【发布时间】:2009-12-23 00:57:09
【问题描述】:

我正在尝试为一家维护每天更新的注册表的公司编写应用程序。该应用程序必须获取用户的位置并显示该注册表中所有最近的位置。到目前为止,我已经让该应用程序调用谷歌并获取我想出的一个小型 Plist 的地理编码信息。但是,从放大的角度考虑......我现在正在使用一个地理编码密钥,这个应用程序无法在现实世界中正确快速地工作,因为谷歌每天每个密钥只提供 15000 个请求......和列表位于公司的服务器上。这是一个很大的清单。超过 25000 个数据点。

这些人喜欢“Yowza”应用程序或任何其他基于位置的应用程序如何通过这些经常更新的数据库进行搜索,同时获取所有用户所需的地理编码信息。他们是否存储给定位置的纬度和经度,还是我需要谷歌提供的一些特别的东西?以及他们如何如此快速地获取信息。 SQLite 数据库的实现对此有帮助吗?提前谢谢你。

【问题讨论】:

    标签: iphone sqlite geocoding core-location


    【解决方案1】:

    如果您的位置是静态的,并且您只需要知道用户距离其中一个位置有多远,您就可以使用这个 sn-p(对不起,它太草率了):

    - (CLLocationDistance)distanceToLocation: (CLLocationCoordinate2D)theLocation
    {   
        CLLocationCoordinate2D location1 = [[locationManager location] coordinate];     
        CLLocationCoordinate2D location2 = theLocation;
    
        typedef double KLLocationRadians;
    
        //////////
        const double DEGREES_TO_RADIANS = 0.0174532925;
        CLLocationDistance R = 6371;    // mean radius of the earth in km
        CLLocationDegrees dLat = (location2.latitude - location1.latitude);
        CLLocationDegrees dLon = (location2.longitude - location1.longitude);
        KLLocationRadians dLatRadians = dLat * DEGREES_TO_RADIANS;
        KLLocationRadians dLonRadians = dLon * DEGREES_TO_RADIANS;
    
        double sinDLatRadiansOver2Squared = sin( dLatRadians / 2.0 ) * sin( dLatRadians / 2.0 );
        double cosLocation1InRadiansTimeCosLocation2InRadians = 
        cos( location1.latitude * DEGREES_TO_RADIANS ) * cos( location2.latitude * DEGREES_TO_RADIANS );
        double sinDLonRadiansOver2Squared = (sin( dLonRadians / 2.0 ) * sin( dLonRadians / 2.0 ));
    
        double a = sinDLatRadiansOver2Squared + (cosLocation1InRadiansTimeCosLocation2InRadians * sinDLonRadiansOver2Squared);
    
        double c = 2.0 * atan2( sqrt( a ), sqrt( 1 - a ) );
        CLLocationDistance distance = R * c;
        //NSLog( @"Distance is: %.2fkm - %.2fmiles", distance, (distance * 0.621371192) );
    
        return (distance * 0.621371192); // return distance in miles
    }
    

    另外,您可以创建两个 CLLocation 对象并使用 distanceToLocation: 方法。

    【讨论】:

    • right.. 这计算了一个人的距离,但我如何克服 google 15k 地理编码请求。这个 sn-p 取决于我必须获取地理编码这一事实,这使我们回到了最初的问题
    【解决方案2】:

    Google 有我不知道有多少台服务器。他们可以很快做到这一点。

    如果您的应用程序需要大量时间敏感的用户数据,这些数据可以在整个网络上使用,我真的不知道其他方法可以做到这一点,除了从任何地方向您的数据库服务器发送更新。如果它需要活泼,那么你需要大量的肌肉,一些非常聪明的编码,或者两者兼而有之。

    然后,如果您需要查找附近的用户,那么您可以返回某个纬度/经度窗口内的所有用户。

    【讨论】:

      【解决方案3】:

      如果现在选择数据库引擎还为时不晚,SQL Server 2008 现在具有允许您处理空间数据的功能。您可以在 T-SQL 中执行距离计算等操作。有一篇关于通过 SQL Server 2008 here 处理空间数据的非常好的文章。

      【讨论】:

      • 或者您可以使用任意数量的带有空间扩展的免费数据库(如 postgresSQL)。如果您需要工业级空间数据库,我会选择 Oracle。
      【解决方案4】:

      您能否说明您在哪里进行地理编码?您的 25k 数据点是否每天都在变化,或者您是否认为您将有足够的 iPhone 用户每天达到 15k 的限制?另外,您是想从地址中获取纬度和经度,还是从纬度和经度中获取地址?

      如果您所做的只是显示前 XX 个最近的位置,那么您无需从 iPhone 进行任何地理编码。您可以从核心位置获取当前的纬度和经度。然后,您可以将该位置与您的数据库进行比较,以找出最接近的位置。如果您的数据库支持 GIS/空间功能(大多数都支持),请使用它们。如果没有,请自己滚动(三角函数是您的朋友)。

      如果您真的知道自己会达到极限,那么请考虑缓存地理编码数据。这样,您可以首先检查它(iPhone 或“注册表”位置)是否离缓存位置有多远。如果您离缓存位置足够近(可能 1/4 英里,取决于这些东西是什么),那么使用缓存的结果。仅当您离得太远时才进行地理编码。

      【讨论】:

      • 地理编码是在 iPhone 上完成的,方法是联系谷歌并获取给定地址的地理编码。每天更新 25k 个数据点,这也是我不愿按照其他人的建议将其存储在应用程序中的原因之一。我相信,如果应用程序推出,它会出现在那里。我知道 15k 听起来很多,但是当多人搜索 25k 数据库时,我认为它会在那里。就是这样,该公司从未有过这样的事情,因此他们的数据库不会将 Lats 和 longs 存储为数据点的一部分。他们存储地址。
      • 最好的方法是存储这些数据点,然后进行比较分析,看看更接近什么?
      【解决方案5】:

      这个服务器端列表应该已经提供了所有数据点的纬度/经度坐标。如果它现在没有它们,请立即使用您每天 1500 次 Google 转化开始转化。然后,您只需在服务器端进行空间查询,以查找用户本地的点并将它们布置在地图上。

      25k 数据点确实不算多,您可以将它们本地存储在应用程序中,并让应用程序查询新数据点。您还可以使用 sqllite 的空间变体来尝试执行设备本地空间查询。

      【讨论】:

        猜你喜欢
        • 2011-03-12
        • 2010-11-09
        • 1970-01-01
        • 1970-01-01
        • 2016-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多