реализация простой геозоны в цель-C - PullRequest
3 голосов
/ 01 апреля 2011

Я пытаюсь реализовать несколько простой алгоритм геозоны, который в основном делает следующее:

  1. Скажем, у меня есть две точки A и B (каждая точка имеет широту и долготу значение в земле).
  2. Я могу нарисовать прямую линию из точки А в точку Б
  3. Я могу установить периметр, который является прямоугольником, вокруг этой линии (см. Рисунок ниже для большей наглядности)

enter image description here

Я хочу сделать следующее: если текущее местоположение телефона находится за пределами этого красного периметра, то это вызывает что-то, в основном делегата. Размер периметра должен регулироваться в процентах, поэтому 5% будет небольшим периметром вокруг линии, а 70% будет большим периметром вокруг линии. Помните, что периметр должен быть прямоугольником, а не кругом с радиусом. Я предполагаю, что будет множество операторов if, участвующих в построении этого ... если кто-нибудь сможет придумать простое и элегантное решение этого (было бы здорово, если бы я мог видеть код в target-C), это было бы здорово , Или было бы полезно любое руководство

Ответы [ 2 ]

1 голос
/ 01 апреля 2011

Вы можете создать путь из четырех точек прямоугольника и затем использовать CGPathContainsPoint, чтобы проверить, находится ли текущее местоположение внутри пути.

Что касается преобразования широты и долготы в плоскую x,координаты y, самое простое решение - использовать проекцию Меркатора с помощью Map Kit.Проверьте Понимание геометрии карты для получения дополнительной информации.

Вот пример:

// create four rectangle points from A, B
dx = (B.x - A.x) * 0.05; // 5% of the A-B length
dy = (B.y - A.y) * 0.05;

// topmost corner, above B
points[0].x = B.x + dx - dy;
points[0].y = B.y + dy + dx;

//rightmost corner, to the right from B
points[1].x = B.x + dx + dy;
points[1].y = B.y + dy - dx;

...


CGMutablePathRef path = CGPathCreateMutable(); 

CGPathMoveToPoint(path, NULL, points[0].x, points[0].y);
CGPathAddLineToPoint(path, NULL, points[1].x, points[1].y);
CGPathAddLineToPoint(path, NULL, points[2].x, points[2].y);
CGPathAddLineToPoint(path, NULL, points[3].x, points[3].y);

CGPathCloseSubpath(path);

// convert latitude, longitude to planar coordinates
MKMapPoint location = MKMapPointForCoordinate([newLocation coordinate]);

BOOL inside = CGPathContainsPoint(path, NULL, CGPointMake(location.x, location.y), YES);

CGPathRelease(path);

Примечание: этот код ожидает, что текущее местоположение является точкой, в то время как в действительности,это точка и радиус точности, который фактически является кругом.Это немного усложняет ситуацию, потому что теперь вам нужно определить, как обрабатывать ситуации, когда текущее местоположение неизвестно точно , но вы знаете только, что оно где-то в кругу.Если прямоугольник большой (скажем, 5 км), тогда вам может потребоваться радиус точности менее 50 м, выполнить расчет, как если бы текущее местоположение было точным, и игнорировать небольшую неточность вычисления.Если прямоугольник меньше (скажем, 50 м), вы также можете выполнить расчет, как если бы текущее местоположение было точным, но тогда вероятность ложных срабатываний была бы выше (например, иногда вы были бы обнаружены как в прямоугольнике, в то время как вы стояли бы снаружи).из этого).

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

1 голос
/ 01 апреля 2011

Вам нужно найти ближайшую точку на главной линии A-B к местоположению пользователя. Посмотрите следующую ссылку для получения дополнительной информации ... Point Line

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...