4

My objective is to convert the top left and bottom right points of my view to lat/lon coordinates. These lat/lon coordinates will be used to query annotation locations that only exist within the view (not all 5000+).

I found this Objective-C tip on Stackoverflow. But the issue I have is that it is converting 0,0 from the mapView (a lat/lon of -180,-180. Aka, the Southpole).

So instead of:

topLeft = mapView.convertPoint(CGPointMake(0, 0), toCoordinateFromView: self.mapView)

I figured I could simply do:

topLeft = view.convertPoint(CGPointMake(0, 0), toCoordinateFromView: self.mapView)

But I get the error:

Cannot invoke 'convertPoint' with an argument list of type '(CGPoint, toCoordinateFromView: MKMapView!)'

I have spent a day trying to figure it out, but to no avail, and I have come to you seeking guidance. Any help would be much appreciated.

Here is the complete function:

func findCornerLocations(){

    var topLeft = CLLocationCoordinate2D()
    let mapView = MKMapView()
    topLeft = view.convertPoint(CGPointMake(0, 0), toCoordinateFromView: self.mapView)

    print(topLeft.latitude, topLeft.longitude)
}
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
Geppelt
  • 363
  • 2
  • 14
  • Just to clarify, you're trying to get the coordinates of a point in your View that contains your MapView, right? – MQLN Nov 18 '15 at 16:36
  • @MacLean Correct. Points 0,0 (topLeft) and view.frame.size.width/height (bottomRight). – Geppelt Nov 18 '15 at 16:38
  • @MacLean but so far I have been just trying to get the topLeft coordinates to print out. Will implement bottomRight when I figure it out. – Geppelt Nov 18 '15 at 16:40
  • Michael, I just added all the code I used for my test. Let me know if it doesn't work, even when implemented my way. Best – MQLN Nov 18 '15 at 17:01
  • Please remove "Solved" from your title and post your own solution as a proper answer. – Jongware Dec 03 '15 at 22:18

2 Answers2

8

You were very, very close!

let topLeft = map.convertPoint(CGPointMake(0, 0), toCoordinateFromView: self.view)
let bottomleft = map.convertPoint(CGPointMake(0, self.view.frame.size.height), toCoordinateFromView: self.view)

When implemented, it'll look like this:

        let map = MKMapView()
        map.frame = CGRectMake(100, 100, 100, 100)
        let coord = CLLocationCoordinate2DMake(37, -122)
        let span = MKCoordinateSpanMake(1, 1)
        map.region = MKCoordinateRegionMake(coord, span)
        self.view.addSubview(map)

        let topleft = map.convertPoint(CGPointMake(0, 0), toCoordinateFromView: self.view)
        let bottomleft = map.convertPoint(CGPointMake(0, self.view.frame.size.height), toCoordinateFromView: self.view)

        print("top left = \(topleft)")
        print("bottom left = \(bottomleft)")
MQLN
  • 2,292
  • 2
  • 18
  • 33
  • Still gives a lat/lon of -180,-180. – Geppelt Nov 18 '15 at 16:54
  • Really? It's working perfectly for me! I just finished double checking my points vs Google Earth! Is your region established before trying to perform these calculations? – MQLN Nov 18 '15 at 16:55
  • I don't know, but yes it is still giving me the same lat/lon. – Geppelt Nov 18 '15 at 17:04
  • If you'd like, I could look over you code. We could start a Chat here. – MQLN Nov 18 '15 at 17:06
  • I do not fully understand your implementation, but your example is giving me coordinates near to San Fransisco. – Geppelt Nov 18 '15 at 17:11
  • Yes, because that's where I've set up the region for my map. The resulting code gives you the lat long of the topleft and bottomleft corners of where the corners of the superview (self.view) are in relation to the map. Basically like if the map could cover those points without changing it's center. Does this make sense? – MQLN Nov 18 '15 at 17:13
  • I am adding my map under viewDidLoad, and finding the coordinates in a separate function in preparation for additional functions to be implemented "down the road". As mapKit will default to the region based on the phone's settings when location services are no granted, I have no need to center the map on anything. But with that said, it seams that they are needed, because I can not get it to work without. – Geppelt Nov 18 '15 at 23:28
  • I was able to get it to work my adding my map wishing the same function. But as I said before, I would like this function to be implemented separately. – Geppelt Nov 18 '15 at 23:30
  • Okay. I was able to get it to work, but only when I a specify the map's bounds again within the function. Is there anything wrong in doing this? – Geppelt Nov 18 '15 at 23:36
0

A normal view doesn't have the convertPoint(_:toCoordinateFromView:) function, only an MKMapView, which explains the compiler error you're seeing. What made you stop using this version?

topLeft = mapView.convertPoint(CGPointMake(0, 0), toCoordinateFromView: self.mapView)

Additionally, if all the annotations are already added to the map view, you'll have much better success using the annotationsInMapRect method:

let visibleAnnotations = mapView.annotationsInMapRect(mapView.visibleMapRect)
for element in visibleAnnotations {
    guard let annotation = element as? MKAnnotation
        else { continue }

    print(annotation)
}
Nate Cook
  • 92,417
  • 32
  • 217
  • 178