MKMapRect и отображение наложений карты, которые охватывают 180-й меридиан

Я работаю с видовыми экранами и границами, возвращаемыми из 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 меридиан. При отображении этого местоположения в виде многоугольника на карте оно отображается неправильно справа от границ США (большой коричневый прямоугольник, виден только левый нижний угол):

Viewport of USA overlayed on mapViewport of Russia overlayed on map

Аналогично, при отображении вьюпорта местоположения для России прямоугольник расположен неправильно слева от границы России.

Это визуально подтверждает наличие подобной проблемы, когда я конвертирую вьюпорт местоположения в MKMapPoints и 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-й меридиан?

7
задан Community 23 May 2017 в 11:47
поделиться