Hunter Maximillion Monk Hunter Maximillion Monk - 5 months ago 26
iOS Question

Get SW/NE point on MKMapView after rotation

I'm writing an application in Swift, and using Parse as the back-end.

In order to setup a query to Parse, I want to get the southwest-most point and northeast-most point displayed on the current MKMapView.

I currently get these values as displayed here:

//___ To calculate the search bounds, first we need to calculate the corners of the map
let nePoint = CGPointMake(self.myMap.bounds.origin.x + myMap.bounds.size.width, myMap.bounds.origin.y);
let swPoint = CGPointMake((self.myMap.bounds.origin.x), (myMap.bounds.origin.y + myMap.bounds.size.height));

//___ Then transform those point into lat, lng values
let neCoord = myMap.convertPoint(nePoint, toCoordinateFromView: myMap)
let swCoord = myMap.convertPoint(swPoint, toCoordinateFromView: myMap)

let neGP = PFGeoPoint(latitude: neCoord.latitude, longitude: neCoord.longitude)
let swGP = PFGeoPoint(latitude: swCoord.latitude, longitude: swCoord.longitude)

var query = PFQuery(className: "locations")
//___ Limit what could be a lot of points.
query.limit = 25
query.whereKey("location", withinGeoBoxFromSouthwest: swGP, toNortheast: neGP)


This works perfectly until the map is rotated.

However, once the user rotates the map, the top-right and bottom-left points no longer represent the northeast-most and southwest-most points.

How can I always calculate the true southwestern-most and northeastern-most points displayed on the map?

Thanks.

Answer

I came up with a (pretty clunky) solution.

This displays the actual northeast most and southwest most points that are visible on the map view rather than just rotating the points around the center of the map, which causes the points to be moved outside of the view due to the screen's rectangular shape.

    let heading = myMap.camera.heading

    let mapWidth = Double(myMap.frame.width)
    let mapHeight = Double(myMap.frame.height)

    var neX = mapWidth
    var neY = 0.0

    var swX = 0.0
    var swY = mapHeight


    if heading >= 0 && heading <= 90 {
        println("Q1")
        let ratio = heading / 90

        neX = (1-ratio) * mapWidth
        swX = (mapWidth*ratio)
    } else if heading >= 90 && heading <= 180 {
        println("Q2")
        let ratio = (heading - 90) / 90
        neX = 0
        neY = (mapHeight*ratio)
        swY = (1-ratio) * mapHeight
        swX = mapWidth

    } else if heading >= 180 && heading <= 270 {
        println("Q3")
        let ratio = (heading - 180) / 90
        neX = mapWidth*ratio
        neY = mapHeight
        swX = (1-ratio) * mapWidth
        swY = 0

    } else if heading >= 270 && heading <= 360 {
        println("Q4")
        let ratio = (heading - 270) / 90
        neX = mapWidth
        neY = (1-ratio) * mapHeight
        swY = ratio * mapHeight

    }

    let swPoint = CGPointMake(CGFloat(swX), CGFloat(swY))
    let nePoint = CGPointMake(CGFloat(neX), CGFloat(neY))

    let swCoord = myMap.convertPoint(swPoint, toCoordinateFromView: myMap)
    let neCoord = myMap.convertPoint(nePoint, toCoordinateFromView: myMap)


    //___ Then transform those point into lat,lng values
    let swGP = PFGeoPoint(latitude: swCoord.latitude, longitude: swCoord.longitude)
    let neGP = PFGeoPoint(latitude: neCoord.latitude, longitude: neCoord.longitude)