Comment créer un MKMapRect avec deux points, chacun spécifié avec une valeur de latitude et de longitude?

j'ai une classe personnalisée qui s'étend NSObject et met en œuvre l' MKOverlay protocole. En conséquence, je dois mettre en œuvre le protocole boundingMapRect propriété qui est un MKMapRect. Pour créer un MKMapRect je peux bien sûr utiliser MKMapRectMake pour en faire un. Cependant, je ne sais pas comment créer un MKMapRect en utilisant ces données j'ai qui est deux points, chacun spécifié par une latitude et longitude. MKMapRectMake's docs de l'état:

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.

Les valeurs de latitude et longitude-je spec MKMapRect sont:

24.7433195, -124.7844079
49.3457868, -66.9513812

cible MKMapRect devrait donc spécifier une zone qui ressemble à ceci:The Target MKMapRect

donc, pour réitérer, comment utiliser mes valeurs lat/lon pour créer un MKMapRect que je peux mettre comme MKOverlay le protocole est @property (nonatomic, readonly) MKMapRect boundingMapRect propriété?

21
demandé sur ROMANIA_engineer 2014-06-04 00:13:53

4 réponses

Cela devrait le faire:

// 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));

ceci utilise la moindre des deux coordonnées x et y pour votre point de départ, et calcule les portées x/y entre les deux points pour la largeur et la hauteur.

33
répondu CSmith 2014-06-03 20:36:12

pour tout nombre de coordonnées, dans Swift (4.2):

let coordinates: [CLLocationCoordinate2D] = []
let rects = coordinates.map { MKMapRect(origin: MKMapPoint(), size: MKMapSize()) }
let fittingRect = rects.reduce(MKMapRect.null) { .union() }

comme l'a noté @Abin Baby, cela ne tiendra pas compte de wrap around (à +/-180 longitude & +/-90 latitude). Le résultat sera toujours correct, mais ce ne sera pas le plus petit rectangle possible.

14
répondu Patrick Pijnappel 2018-09-23 22:53:35

basé sur la réponse de Patrick une extension sur MKMapRect:

extension MKMapRect {
    init(coordinates: [CLLocationCoordinate2D]) {
        self = coordinates.map({ MKMapPointForCoordinate() }).map({ MKMapRect(origin: , size: MKMapSize(width: 0, height: 0)) }).reduce(MKMapRectNull, combine: MKMapRectUnion)
    }
}
6
répondu boliva 2017-01-04 13:24:05

C'est ce qui a fonctionné pour moi.

aucun problème même en traversant entre + / -180 longitude et + / -90 latitude.

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
}
0
répondu zero 2018-09-29 10:21:24