Основные данные iOS для запроса к набору геопространственных данных

#ios #ios4 #core-data

#iOS #ios4 #основные данные

Вопрос:

Я использую Core Data Framework для управления набором учетных записей, которые также включают данные о координатах геопространства (GPS) для каждой учетной записи. Как я могу запросить к этим данным на основе положения устройства, чтобы получить список учетных записей в пределах x футов и перечислить их в порядке расстояния?

Ответ №1:

для начала вот метод, который я использую в своем приложении для iOS, который возвращает расстояние в метрах между двумя местоположениями CLLocationCoordinate2D, предполагая сферическую проекцию Google Mercator (если вы хотите использовать другую проекцию, вы можете указать соответствующее значение коэффициента сглаживания (f) и значение большой полуоси (a). если вам нужны значения прямого и обратного азимута между координатами, вы можете раскомментировать и вернуть значения faz и baz вместе с расстоянием, определив свою собственную структуру. этот метод можно использовать для добавления расстояния до каждого из объектов вашей учетной записи и текущего местоположения, сообщаемого вашим объектом CLLocationManager, тогда вы могли бы легко сортировать и фильтровать массив объектов учетной записи на основе их расстояний.

на основе кода Джеральда Эвендена, расположенного здесь:http://article.gmane.org/gmane.comp.gis.proj-4.devel/3478

 #define PI 3.141592653589793238462643
#define EPS 5e-14
#define DEG_TO_RAD 0.0174532925199432958

// returns the geodesic distance in meters between two coordinates based on the google spherical mercator projection.
- (int) geodesicDistanceFromCoordinate: (CLLocationCoordinate2D) fromCoord toCoordinate: (CLLocationCoordinate2D) toCoord {
    double c, d, e, r, x, y, sa, cx, cy, cz, sx, sy, c2a, cu1, cu2, su1, tu1, tu2, ts, phi1, lam1, phi2, lam2, f, baz, faz, s, a;

    phi1 = fromCoord.latitude * DEG_TO_RAD;
    lam1 = fromCoord.longitude * DEG_TO_RAD;
    phi2 = toCoord.latitude * DEG_TO_RAD;
    lam2 = toCoord.longitude * DEG_TO_RAD;
    f = 0;  //google's spherical mercator projection has no flattening
    a = 6378137;  //earth's axis in meters used in google's projection

    r = 1. - f;
    tu1 = r * tan(phi1);
    tu2 = r * tan(phi2);
    cu1 = 1. / sqrt(tu1 * tu1   1.);
    su1 = cu1 * tu1;
    cu2 = 1. / sqrt(tu2 * tu2   1.);
    ts = cu1 * cu2;
    baz = ts * tu2;
    faz = baz * tu1;
    x = lam2 - lam1;

    do {
        sx = sin(x);
        cx = cos(x);
        tu1 = cu2 * sx;
        tu2 = baz - su1 * cu2 * cx;
        sy = sqrt(tu1 * tu1   tu2 * tu2);
        cy = ts * cx   faz;
        y = atan2(sy, cy);
        sa = ts * sx / sy;
        c2a = -sa * sa   1.;
        cz = faz   faz;
        if (c2a > 0.)
            cz = -cz / c2a   cy;
        e = cz * cz * 2. - 1.;
        c = ((c2a * -3.   4.) * f   4.) * c2a * f / 16.;
        d = x;
        x = ((e * cy * c   cz) * sy * c   y) * sa;
        x = (1. - c) * x * f   lam2 - lam1;
    } while (fabs(d - x) > EPS);

//forward azimuth    faz = atan2(tu1, tu2);
//backward azimuth    baz = atan2(cu1 * sx, baz * cx - su1 * cu2)   PI;
    x = sqrt((1. / r / r - 1.) * c2a   1.)   1.;
    x = (x - 2.) / x;
    c = (x * x / 4.   1.) / (1. - x);
    d = (x * .375 * x - 1.) * x;
    s = ((((sy * sy * 4. - 3.) * (1. - e - e) * cz * d / 6. - e * cy) * d / 4.   cz) * sy * d   y) * c * r;
    return (int)(s * a);
}
  

Комментарии:

1. да, метры. существует также distanceFromLocation: метод для объекта CLLocation, который можно использовать для определения расстояния между местоположением и другим.

2. Использует ли MapKit ту же проекцию, что и Google Maps, или для нее известен коэффициент сглаживания?