MKMapView Zoom и регион

85

Я знаком с использованием Google Maps Javascript API. Недавно я начал использовать фреймворк MapKit для проекта iphone, но мне трудно понять масштабирование и установить регион на карте.

В Google Maps API я использовал целочисленные уровни масштабирования, такие как 8, 9, 10 вместе с простой функцией setZoom (). Единственный эквивалентный метод, который я вижу в платформе MapKit, - это setRegion: animated. Насколько я понимаю, мне нужно установить значения "дельты" широты и долготы для диапазона, чтобы указать уровень масштабирования. Но я действительно не имею представления, что представляют собой эти значения (я читал документацию).

Когда я использую делегат MKMapView и отслеживаю значения диапазона в методе делегата regionDidChange, кажется, что результаты не коррелируют друг с другом. Это нормально, когда я уменьшаю масштаб и вижу, что значения дельты диапазона увеличиваются, как указано в документации. Но внезапно я перетаскиваю карту без увеличения, и значения дельты становятся равными 0,0.

Может кто-нибудь объяснить, какова точка отсчета для этих промежутков и дельты? Или есть какой-либо алгоритм для преобразования целочисленного уровня масштабирования (например, 9) в эти значения дельты?

В качестве бонуса вопрос, есть ли способ указать минимальный-максимальный уровень масштабирования в MKMapView :)

Благодарность

кокошник
источник

Ответы:

134

Прежде всего, MKMapView не использует / не имеет предопределенного набора уровней масштабирования, как в Google Maps.

Вместо этого видимая область MKMapView описывается с помощью MKCoordinateRegion , который состоит из двух значений:

  1. center (центральная точка региона), и
  2. span (размер видимой области вокруг центра).

Центральная точка должна быть очевидной (это центральная точка региона).

Однако span (который является MKCoordinateSpan ) состоит из:

  1. latitudeDelta (расстояние по вертикали, представленное регионом), и
  2. longitudeDelta (горизонтальное расстояние, представленное регионом).

Краткий пример. Вот такая игрушка MKCoordinateRegion:

  1. центр:
    • широта: 0
    • долгота: 0
  2. размах:
    • широтаДельта: 8
    • longitudeDelta: 6

Регион можно описать, используя его минимальные и максимальные координаты, следующим образом:

  1. мин. координата (нижняя левая точка):
    • широта: -4
    • долгота: -3
  2. максимальная координата (верхняя правая точка):
    • широта: 4
    • долгота: 3

Таким образом, вы можете указать уровни масштабирования вокруг центральной точки, используя MKCoordinateSpan соответствующего размера. В качестве приближения к числовым уровням масштабирования Google вы можете реконструировать размеры диапазона, которые Google использует для данного уровня масштабирования, и соответственно создать диапазон. (Google описывает их области просмотра так же, как MKMapView, как центр + промежуток, поэтому вы можете извлечь эти значения из Google Maps.)

Что касается ограничения региона, вы можете играть с этим методом делегата:

mapView:regionWillChangeAnimated

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

Кстати, в OS 3.1 есть определенные исправления / улучшения в аспектах MapKit, которые вызывали у меня проблемы в версии 3.0.

Кельвин
источник
@Kelvin, не могли бы вы подробнее описать, как «реконструировать размеры диапазона, которые Google использует для заданного уровня масштабирования, и создать диапазон». Мне это действительно нужно
Скофилд Тран
118

Если вы предпочитаете использовать явные уровни масштабирования вместо определения MKCoordinateSpan, я написал категорию, которая добавляет поддержку для указания уровня масштабирования MKMapView. Код можно найти здесь .

Трой Брант
источник
4
Сообщения в блоге Троя дали мне отличное понимание того, как работают mapkit и google maps. Я очень рекомендую это прочитать.
Аарон
5
git: //github.com/jdp-global/MKMapViewZoom.git
johndpope
@JohnMerlino, да, это так
Золтан Маток
5

Диапазон выражается в градусах широты и долготы. Вместо этого существует метод создания структур MKCoordinateRegion, использующий расстояние. Возможно, вы используете MKCoordinateRegionMakeWithDistance для указания диапазона, а затем, когда вы проверяете его в regionDidChange, вы видите диапазон широты / долготы, который хранится в структуре MKCoordinateRegion.

Насколько мне известно, целочисленные уровни масштабирования недоступны или вообще не используются при работе с MKMapKit. Я лично предпочитаю использовать цифры размаха, они более гибкие.

Вы не можете указать максимальное и минимальное масштабирование, и я не знаю, как его взломать. MKMapKit на самом деле сейчас довольно слаб, я очень разочарован отсутствием функций.

Алиса Изабель
источник
3

Быстрое сравнение уровней масштабирования для местоположения с помощью maps.google.com путем проверки строки запроса ссылки показывает, что значения диапазона dx и dy увеличиваются в 2 раза:

 (0.005334, 0.011834) starting span
 (0.010668, 0.023668) dx: x2, dy: x2 
 (0.021335, 0.047337) dx: x2, dy: x2
 (0.042671, 0.094671) dx: x2, dy: x2
  ...
Ари Брагинский
источник
2

Категория Бранта в MKMapView работает хорошо. Однако похоже, что он не был обновлен для поддержки новых устройств с экранами сетчатки при вычислении mapSizeInPixels.

Это можно исправить, заменив эту строку:

CGSize mapSizeInPixels = mapView.bounds.size;

С этой строкой:

CGSize mapSizeInPixels = CGSizeMake(mapView.bounds.size.width * [UIScreen mainScreen].scale, mapView.bounds.size.height * [UIScreen mainScreen].scale);
Даниэль
источник