大容量地理编码和距离检查

时间:2009-12-23 00:57:09

标签: iphone sqlite geocoding core-location

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

这些人如何喜欢“Yowza”应用程序或任何其他基于位置的应用程序搜索这些数据库,这些数据库经常更新,同时获取所有用户所需的地理编码信息。他们是否存储了给定位置的拉特和长片,还是需要谷歌特别的东西?他们如何如此快速地获取信息。 SQLite数据库的实现是否有助于此?提前谢谢。

5 个答案:

答案 0 :(得分:1)

如果您的位置是静态的,您只需要知道用户距其中一个位置的距离就可以使用此代码段(抱歉它太邋)了:

- (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:方法。

答案 1 :(得分:0)

谷歌我不知道有多少台服务器。他们可以非常快。

如果您的应用程序需要大量时间敏感的用户数据(可在整个网络中使用),除了从各处向您的数据库服务器发送更新之外,我真的不知道另一种方法。如果它需要很快,那么你需要很多肌肉,一些非常聪明的编码,或者两者兼而有之。

然后,如果您需要找到附近的用户,那么我想,您可以返回特定纬度/经度窗口内的所有用户。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

您能澄清一下您在进行地理编码的位置吗?您的25k数据点是否每天都在变化,或者您是否认为您将有足够的iPhone用户每天达到15k的限制?此外,您是尝试从地址获取纬度和经度,还是从纬度和经度获取地址?

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

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

答案 4 :(得分:0)

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

实际上,25k数据点并不是那么多,您可以在应用程序中本地存储它们并让应用程序查询新数据点。还有一个sqllite的空间变体,您可以使用它来尝试进行设备本地空间查询。