Подтвердить что ты не робот

Как создать MKMapRect с учетом двух точек, каждый из которых задан с широтой и долготой?

У меня есть пользовательский класс, который расширяет NSObject и реализует протокол MKOverlay. В результате мне нужно реализовать свойство boundingMapRect протокола, которое является MKMapRect. Чтобы создать MKMapRect, я могу, конечно, использовать MKMapRectMake для его создания. Тем не менее, я не знаю, как создать MKMapRect, используя данные, которые у меня есть, это две точки, каждая из которых задана широтой и долготой. MKMapRectMake docs:

MKMapRect MKMapRectMake(
    double x,
    double y,
    double width,
    double height
);

Parameters
x
    The point along the east-west axis of the map projection to use for the origin.
y
    The point along the north-south axis of the map projection to use for the origin.
width
    The width of the rectangle (measured using map points).
height
    The height of the rectangle (measured using map points).
Return Value
    A map rectangle with the specified values.

Значения широты и долготы, которые я должен указать MKMapRect, следующие:

24.7433195, -124.7844079
49.3457868, -66.9513812

Таким образом, целевой MKMapRect должен будет указать область, которая выглядит примерно так: The Target MKMapRect

Итак, чтобы повторить, как мне использовать значения lat/lon для создания MKMapRect, который я могу установить как свойство MKOverlay protocol @property (nonatomic, readonly) MKMapRect boundingMapRect?

4b9b3361

Ответ 1

Это должно сделать это:

// these are your two lat/long coordinates
CLLocationCoordinate2D coordinate1 = CLLocationCoordinate2DMake(lat1,long1);
CLLocationCoordinate2D coordinate2 = CLLocationCoordinate2DMake(lat2,long2);

// convert them to MKMapPoint
MKMapPoint p1 = MKMapPointForCoordinate (coordinate1);
MKMapPoint p2 = MKMapPointForCoordinate (coordinate2);

// and make a MKMapRect using mins and spans
MKMapRect mapRect = MKMapRectMake(fmin(p1.x,p2.x), fmin(p1.y,p2.y), fabs(p1.x-p2.x), fabs(p1.y-p2.y));

это использует меньшее из двух координат x и y для вашей начальной точки и вычисляет интервалы x/y между двумя точками для ширины и высоты.

Ответ 2

Для любого количества координат в Swift (4.2):

// Assuming 'coordinates' is of type '[CLLocationCoordinate2D]'
let rects = coordinates.lazy.map { MKMapRect(origin: MKMapPoint($0), size: MKMapSize()) }
let fittingRect = rects.reduce(MKMapRect.null) { $0.union($1) }

Как отмечает @Abin Baby, это не учитывает обтекание (на + / -180 долгота и + / -90 широта). Результат все равно будет правильным, но это не будет наименьший возможный прямоугольник.

Ответ 3

На основании Патрика ответьте на расширение MKMapRect:

extension MKMapRect {
    init(coordinates: [CLLocationCoordinate2D]) {
        self = coordinates.map({ MKMapPointForCoordinate($0) }).map({ MKMapRect(origin: $0, size: MKMapSize(width: 0, height: 0)) }).reduce(MKMapRectNull, combine: MKMapRectUnion)
    }
}

Ответ 4

Это то, что сработало для меня.

Нет проблем даже при пересечении между + / -180 долготой и + / -90 широтой.

Swift 4.2

func makeRect(coordinates:[CLLocationCoordinate2D]) -> MKMapRect {
    var rect = MKMapRect()
    var coordinates = coordinates
    if !coordinates.isEmpty {
        let first = coordinates.removeFirst()
        var top = first.latitude
        var bottom = first.latitude
        var left = first.longitude
        var right = first.longitude
        coordinates.forEach { coordinate in
            top = max(top, coordinate.latitude)
            bottom = min(bottom, coordinate.latitude)
            left = min(left, coordinate.longitude)
            right = max(right, coordinate.longitude)
        }
        let topLeft = MKMapPoint(CLLocationCoordinate2D(latitude:top, longitude:left))
        let bottomRight = MKMapPoint(CLLocationCoordinate2D(latitude:bottom, longitude:right))
        rect = MKMapRect(x:topLeft.x, y:topLeft.y,
                         width:bottomRight.x - topLeft.x, height:bottomRight.y - topLeft.y)
    }
    return rect
}