MKCoordinateRegionMakeWithDistance не устанавливает правильный регион в MapView - PullRequest
6 голосов
/ 04 сентября 2011

У меня есть этот код:

- (void)viewDidLoad
{
    [super viewDidLoad];

    CLLocationCoordinate2D userLocation = CLLocationCoordinate2DMake(48.9793946200, 2.4726272850);
    CLLocationDistance dist1 = 636.9887048804;
    CLLocationDistance dist2 = 900.8380655203;
    CLLocationDistance dist = dist1;

    [self.myMapView setRegion:MKCoordinateRegionMakeWithDistance(userLocation, dist, dist) animated:YES];

    // TEST
    // ------------------------------------------------------------
    MKCoordinateRegion region = self.myMapView.region;
    CLLocationDegrees lat = region.center.latitude;
    CLLocationDegrees lon = region.center.longitude - region.span.longitudeDelta/2;
    CLLocation *west = [[[CLLocation alloc] initWithLatitude:lat longitude:lon] autorelease];

    NSLog(@"User location: lat : %.10lf long : %.10lf", userLocation.latitude, userLocation.longitude);
    NSLog(@"distance set: %.10lfm", dist);
    NSLog(@"center: lat : %.8lf long : %.8lf", region.center.latitude, region.center.longitude);

    CLLocation* centerRegion = [[[CLLocation alloc] initWithLatitude:region.center.latitude longitude:region.center.longitude] autorelease];
    NSLog(@"distance to western boundary: %.2lfm", [centerRegion distanceFromLocation:west]);

    lat = region.center.latitude - region.span.latitudeDelta/2 ;
    lon = region.center.longitude;
    CLLocation *north = [[[CLLocation alloc] initWithLatitude:lat longitude:lon] autorelease];

    NSLog(@"distance to western boundary: %.2lfm", [centerRegion distanceFromLocation:north]);
    // ------------------------------------------------------------
}

При установке dist = dist1 это дает:

User location: lat : 48.9793946200 long : 2.4726272850
distance set: 636.9887048804m

center: lat : 48.97937199 long : 2.47269630
distance to western boundary: 500.44m
distance to western boundary: 650.57m

enter image description here

При установке dist = dist2 это дает:

User location: lat : 48.9793946200 long : 2.4726272850
distance set: 900.8380655203m

center: lat : 48.97937199 long : 2.47269630
distance to western boundary: 500.44m
distance to western boundary: 650.57m

enter image description here

В чем здесь проблема? Почему у меня один и тот же дисплей с двумя разными расстояниями?

Последний вопрос: как я могу быть уверен, что на карте отображаются требуемые метры, как минимум для горизонтального и вертикального изображения (с анимацией или без нее)?

Ответы [ 2 ]

8 голосов
/ 14 сентября 2011

Если я правильно понимаю, вы хотите сказать mapView «дай мне карту, которая имеет ширину 636 м» или «дай мне карту, которая имеет ширину 900 м».Но карта дает вам одинаковое расстояние в обоих направлениях.

Когда вы устанавливаете регион карты, вы, как правило, получаете не то, что просили, а лучшее соответствие.Вид карты смотрит на регион, который вы запросили, а затем создает регион, который соответствует вашему региону внутри него.Проблема состоит в том, что вид карты не точно увеличивает требуемый регион, он находит самый высокий уровень масштабирования, который позволяет видеть весь ваш регион.Он не будет использовать промежуточный уровень масштабирования.Вот почему при использовании setRegion: карта всегда выглядит четкой.Вы можете вручную установить промежуточный уровень масштабирования, сжимая или уменьшая его, но не (насколько я знаю) программно.

Обратите внимание, что представление карты может изменить фактическую переменную region, которую вы передаетеЭто.Вот документы:

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

Вы можете увидеть разницу в регионах, зарегистрировав регион, который вы ему дали, и тот, которыйВид карты на самом деле устанавливается (хотя я не видел пройденное myRegion изменение):

MKCoordinateRegion myRegion = MKCoordinateRegionMakeWithDistance(userLocation, dist, dist);
NSLog(@"Passed: %f %f", myRegion.span.latitudeDelta, myRegion.span.longitudeDelta);
[self.mapView setRegion:myRegion animated:YES];

NSLog(@"Passed 2: %f %f", myRegion.span.latitudeDelta, myRegion.span.longitudeDelta);
NSLog(@"Set: %f %f", mapView.region.span.latitudeDelta, mapView.region.span.longitudeDelta);

> Passed: 0.005728 0.008702
> Passed 2: 0.005728 0.008702
> Set: 0.012957 0.013733

Если вы увеличите расстояние до 1200 м, вы сможете увидеть следующий уровень масштабирования.

Кстати, в вашем коде есть небольшая ошибка:

NSLog(@"distance to western boundary: %.2lfm", [centerRegion distanceFromLocation:north]);

должно быть

NSLog(@"distance to northern boundary: %.2lfm", [centerRegion distanceFromLocation:north]);
1 голос
/ 04 сентября 2011

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

При установке региона MKMapView не будет использовать его точно так, как есть, но изменит его так, чтобы:

  1. его соотношение сторон соответствует формату вида
  2. новый регион содержит указанный

Таким образом, если ваше представление имеет соотношение сторон ширина: высота 2: 1, то западная / восточная границы будут находиться в 200 метрах от центра, а северная / южная границы - в 100 метрах от центра.

Что-то попробовать после установки региона, как указано выше:

MKCoordinateRegion region = self.mapView.region;
CLLocationDegrees lat = region.center.latitude;
CLLocationDegrees lon = region.center.longitude - region.span.longitudeDelta/2;
CLLocation *west = [[CLLocation alloc] initWithLatitude:lat longitude:lon];

NSLog(@"distance to western boundary: %.2lfm", [userLocation distanceFromLocation:west]);

lat = region.center.latitude + region.span.latitudeDelta/2 
lon = region.center.longitude;
CLLocation *north = [[CLLocation alloc] initWithLatitude:lat longitude:lon];

NSLog(@"distance to northern boundary: %.2lfm", [userLocation distanceFromLocation:north]);

Один из них должен быть 100 м. Если нет, мне было бы интересно посмотреть, что они из себя представляют.

P.S. Код выше не был проверен в любом случае.

...