Я работаю с видовыми экранами и границами, возвращаемыми из Google Geocoding API. При выполнении обратного геокодирования для заданной координаты сервис возвращает несколько результатов с различной степенью детализации (страна, административный район, населенный пункт, населенный пункт, маршрут и т.д.). Я хочу выбрать наиболее подходящий из этих результатов, учитывая текущую видимую область на карте.
Я остановился на алгоритме, который сравнивает соотношения площадей (в MKMapPoint
²) видового экрана местоположения, текущего видового экрана карты и их пересечения (с помощью функции MKMapRectIntersection
). Это работает очень хорошо до тех пор, пока область просмотра местоположения не пересекает меридиан 180. В этом случае их пересечение равно 0.
Я начал исследовать причину и в качестве отладочной помощи отображаю MKPolygon
оверлеи на карте, чтобы дать мне визуальные подсказки о том, что происходит. Чтобы избежать возможных ошибок, вносимых моим кодом, который выполняет преобразование между геокоординатами и MKMapRect
, я построил наложение полигонов, используя исходные координаты из результатов Google следующим образом:
CLLocationCoordinate2D sw, ne, nw, se;
sw = location.viewportSouthWest.coordinate;
ne = location.viewportNorthEast.coordinate;
nw = CLLocationCoordinate2DMake(ne.latitude, sw.longitude);
se = CLLocationCoordinate2DMake(sw.latitude, ne.longitude);
CLLocationCoordinate2D coords[] = {nw, ne, se, sw};
MKPolygon *p = [MKPolygon polygonWithCoordinates:coords count:4];
Для примера проблемного местоположения, вот окно просмотра, возвращенное для Соединенных Штатов, последний результат типа страна, при геокодировании координат где-то в Вирджинии:
Southwest: 18.9110643, 172.4546967
Northeast: 71.3898880, -66.9453948
Обратите внимание, что юго-западная координата, которая находится в левом нижнем углу окна просмотра местоположения, лежит через 180 меридиан. При отображении этого местоположения в виде многоугольника на карте оно отображается неправильно справа от границ США (большой коричневый прямоугольник, виден только левый нижний угол):
Аналогично, при отображении вьюпорта местоположения для России прямоугольник расположен неправильно слева от границы России.
Это визуально подтверждает наличие подобной проблемы, когда я конвертирую вьюпорт местоположения в MKMapPoint
s и MKMapRect
и не нахожу пересечения между вьюпортом карты (белый прямоугольник на рисунке выше) и вьюпортом местоположения.
Способ, которым я вычисляю прямоугольник карты, похож на ответы в этом вопросе SO:
Как вписать определенную границу, состоящую из координат NE и SW, в видимый вид карты?
... который работает нормально, если только координаты не пересекают 180-й меридиан. Тестирование MKMapRect
с MKMapRectSpans180thMeridian
возвращает false
, так что метод построения неверен.
Документация Apple не помогает в этом вопросе. Единственная подсказка, которую я нашел, находится в MKOverlay.h
:
// boundingMapRect should be the smallest rectangle that completely contains
// the overlay.
// For overlays that span the 180th meridian, boundingMapRect should have
// either a negative MinX or a MaxX that is greater than MKMapSizeWorld.width.
@property (nonatomic, readonly) MKMapRect boundingMapRect;
Каков правильный способ отображения наложения полигонов, охватывающих 180-й меридиан?
.
Как правильно построить MKMapRect
, который охватывает 180-й меридиан?