Геокодирование большого объема и проверка расстояния - PullRequest
1 голос
/ 23 декабря 2009

Я пытаюсь написать приложение для компании, которая ведет реестр, который обновляется каждый день. Приложению потребуется взять местоположение пользователя и отобразить все ближайшие местоположения в этом реестре. До сих пор я получил приложение для вызова в Google и получения информации о геокодировании для небольшого Plist, который я придумал. Однако, учитывая это с точки зрения масштабирования ... Я сейчас использую один ключ геокодирования, и это приложение не может работать правильно и быстро в реальном мире, потому что Google дает только 15000 запросов в день на ключ ... и список находится на сервере компании. Это большой список. свыше 25000 точек данных.

Как этим ребятам нравится приложение "Yowza" или любое другое приложение на основе местоположения, которое выполняет поиск в этих базах данных, которые часто обновляются при получении информации о геокодировании, которая им нужна для всех пользователей. Хранят ли они лат и лонги для заданных мест или мне нужно что-то особенное от Google? И как они получают информацию так быстро. Помогает ли в этом реализация базы данных SQLite? Заранее спасибо.

Ответы [ 5 ]

1 голос
/ 23 декабря 2009

Если ваши местоположения статичны, и вам просто нужно знать, как далеко пользователь находится от одного из местоположений, вы можете использовать этот фрагмент (извините, он такой небрежный):

- (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: метод.

0 голосов
/ 23 декабря 2009

Этот список на стороне сервера уже должен содержать координаты широты / долготы для всех точек данных. Если у них их нет сейчас, начните конвертировать сегодня, используя свои 1500 конверсий Google в день. Затем вы просто выполняете пространственные запросы на стороне сервера, чтобы найти точки, локальные для пользователя, и размещаете их на карте.

25 тыс. Точек данных, честно говоря, не так уж много, но вы можете хранить их локально в приложении и запросить новые точки данных в приложении. Существует также пространственный вариант sqllite, который вы можете использовать, чтобы попытаться выполнить локальные пространственные запросы устройства.

0 голосов
/ 23 декабря 2009

Если еще не поздно выбрать ядро ​​базы данных, SQL Server 2008 теперь имеет функции, позволяющие работать с пространственными данными. Вы можете делать такие вещи, как расчеты расстояния в T-SQL. Есть очень хорошая статья о работе с пространственными данными через SQL Server 2008 здесь .

0 голосов
/ 23 декабря 2009

Можете ли вы уточнить, где вы делаете геокодирование? Изменяются ли ваши 25 тыс. Точек данных каждый день, или вы думаете, что у вас будет достаточно пользователей iPhone, чтобы ежедневно превышать 15 тыс. Лимитов? Кроме того, вы пытаетесь получить широту и долготу от адреса, или адрес от широты и долготы?

Если все, что вы делаете, это отображаете верхние XX ближайших местоположений, то вам не нужно будет выполнять геокодирование с iPhone. Вы можете получить текущую широту и долготу из основного местоположения. Затем вы можете сравнить это местоположение с вашей базой данных, чтобы выяснить, что находится ближе всего. Если ваша база данных поддерживает ГИС / пространственные функции (большинство из них), то используйте их. Если нет, сверните свое собственное (тригонометрия - ваш друг).

Если вы действительно знаете, что достигнете предела, рассмотрите возможность кэширования данных геокодирования. Таким образом, вы можете сначала проверить, насколько далеко вы (iPhone или «реестр») находитесь от кэшированного местоположения. Если вы достаточно близко к расположению в кэше (может быть, 1/4 мили, зависит от того, что это за вещи), то используйте результаты из кэша. Делайте геокодирование, только если вы слишком далеко.

0 голосов
/ 23 декабря 2009

у гугла не знаю сколько серверов. Они могут быть очень быстрыми с этим.

Если вашему приложению требуется много чувствительных ко времени пользовательских данных, доступных по всей сети, я действительно не знаю другого способа сделать это, кроме как посылать обновления отовсюду на ваш сервер БД. И если он должен быть быстрым, тогда вам нужно много мускулов, немного действительно умного кодирования или оба.

Тогда, если вам нужно найти пользователей, которые находятся поблизости, то, я полагаю, вы можете вернуть всех пользователей, которые находятся в пределах определенного окна широты / долготы.

...