Как вписать определенные границы, состоящие из координат NE и SW, в видимый вид карты? - PullRequest
5 голосов
/ 14 декабря 2011

Мне нужно вписать определенные границы в карту.Я получаю границы от вызова геокодера Google и чтения свойства окна просмотра, которое выглядит следующим образом:

{
    northeast =     {
        lat = "30.4212235";
        lng = "-97.486942";
    };
    southwest =     {
        lat = "30.1128403";
        lng = "-97.99917959999999";
    };
}

Затем я преобразую их в CLLocationCoordinate2D

NSDictionary *viewport = [[[results objectAtIndex:0] objectForKey:@"geometry"] 
                                                     objectForKey:@"viewport"];
NSDictionary *NEDictionary = [viewport objectForKey:@"northeast"];
NSDictionary *SWDictionary = [viewport objectForKey:@"southwest"];

CLLocationCoordinate2D SWCoordinate = 
    CLLocationCoordinate2DMake(
        [[SWDictionary objectForKey:@"lat"] floatValue], 
        [[SWDictionary objectForKey:@"lng"] floatValue]
    );
CLLocationCoordinate2D NECoordinate = 
    CLLocationCoordinate2DMake(
        [[NEDictionary objectForKey:@"lat"] floatValue], 
        [[NEDictionary objectForKey:@"lng"] floatValue]
    );    

Я знаю, что мне нужно сгенерировать MKMapRect(или MKMapRegion, в зависимости от того, что проще) из этих координат, а затем [mapView setVisibleRect: newRect animated: YES] (или [mapView setRegion: newRegion animated: YES], но я не совсем уверен, как туда добраться. Мне нужен метод дляпреобразовать границы в правильную структуру данных, что-то вроде:

- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                   NE:(CLLocationCoordinate2D)ne {
    // CGFloat x = ??
    // CGFloat y = ??
    // CGFloat width = ??
    // CGFloat height = ??
    MKMapRect mapRectFromBounds = MKMapRectMake(x,y,width,height);
    return mapRectFromBounds;
}

Есть мысли?

Ответы [ 3 ]

10 голосов
/ 14 декабря 2011

Есть несколько способов сделать это.

Вы можете создать MKCoordinateRegion, вычислив точку center, и тогда span - это абсолютная разница в градусах между углами.

Или вы можете создать MKMapRect с помощью функции MapKit MKMapPointForCoordinate. Чтобы получить origin, определите северо-западную координату и конвертируйте ее в MKMapPoint. Чтобы получить width и height, получите абсолютную разницу в mappoints между углами (преобразуйте углы из координат в MKMapPoint s, используя сначала функцию).

Еще один быстрый способ - небольшой трюк с использованием функции MKMapRectUnion. Создайте нулевой размер MKMapRect из каждой координаты, а затем объедините два ряда в один большой прямоугольник, используя функцию:

MKMapPoint swPoint = MKMapPointForCoordinate(SWCoordinate);
MKMapRect swRect = MKMapRectMake(swPoint.x, swPoint.y, 0, 0);

MKMapPoint nePoint = MKMapPointForCoordinate(NECoordinate);
MKMapRect neRect = MKMapRectMake(nePoint.x, nePoint.y, 0, 0);

MKMapRect rect = MKMapRectUnion(swRect, neRect);

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

2 голосов
/ 28 января 2012

Если ваши границы могут охватывать 180-й меридиан, вы должны учесть это в преобразовании:

- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                   NE:(CLLocationCoordinate2D)ne 
{
    MKMapPoint pSW = MKMapPointForCoordinate(sw);
    MKMapPoint pNE = MKMapPointForCoordinate(ne);

    double antimeridianOveflow = 
      (ne.longitude > sw.longitude) ? 0 : MKMapSizeWorld.width;    

    return MKMapRectMake(pSW.x, pNE.y, 
                        (pNE.x - pSW.x) + antimeridianOveflow, 
                        (pSW.y - pNE.y));
}

Но остерегайтесь тех MKMapRect, которые охватывают антимитридиан , потому что они приходят с земли, где живут драконы. Если вы хотите узнать о некоторых опасностях, которые лежат там, посмотрите на MKMapRect и отображение наложений карты, которые охватывают 180-й меридиан . Вы были предупреждены!

0 голосов
/ 14 декабря 2011

Я нашел то, что работает.Я закончил с этим:

- (MKMapRect) mapRectThatFitsBoundsSW:(CLLocationCoordinate2D)sw 
                                   NE:(CLLocationCoordinate2D)ne {
    MKMapPoint nePoint = MKMapPointForCoordinate(ne);
    MKMapPoint swPoint = MKMapPointForCoordinate(sw);
    CGFloat width = ABS(nePoint.x - swPoint.x);
    CGFloat height = ABS(nePoint.y - swPoint.y);
    MKMapRect newMapRect = MKMapRectMake(
        MIN(swPoint.x, nePoint.x), 
        MIN(swPoint.y, nePoint.y), 
        width, 
        height
    );

    // if (!MKMapRectSpans180thMeridian(newMapRect)) {
        return newMapRect;
    // } else {
        // ????
    // }
}
...