Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the coordinates of a point from mkmapview on iphone

I'm trying to figure out how to put an annotation on a map based on where the user touches.

I have tried sub-classing the MKMapView and looked for the touchesBegan to fire but as it turns out, MKMapView does not use the standard touches methods.

I also have tried sub-classing a UIView, adding an MKMapView as a child and then listening for HitTest and touchesBegan. This works somewhat. if i have my map the full size of the UIView, then have something like this

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    return map;
}

and that works, my touchesBegan will be able to get the point using

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
  for (UITouch *touch in touches){
  CGPoint pt = [touch  locationInView:map];
  CLLocationCoordinate2D coord= [map convertPoint:pt toCoordinateFromView:map];
  NSLog([NSString stringWithFormat:@"x=%f y=%f - lat=%f long = %f",pt.x,pt.y,coord.latitude,coord.longitude]);
 }
}

but then the map has some crazy behavior like it will not scroll, and it will not zoom in unless double tapped but you can zoom out. and it only works if I return the map as the view. If I do not have the hit test method, the map works fine but obviously doesn't get any data.

Am I going about getting the coordinate wrong? Please tell me there is a better way. I know how to add annotations just fine, I just cannot find any examples of adding an annotation where and when a user touches the map.

like image 707
AtomRiot Avatar asked Jun 20 '10 17:06

AtomRiot


5 Answers

You can try this code

- (void)viewDidLoad
{
    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(foundTap:)];

    tapRecognizer.numberOfTapsRequired = 1;

    tapRecognizer.numberOfTouchesRequired = 1;

    [self.myMapView addGestureRecognizer:tapRecognizer];
}


-(IBAction)foundTap:(UITapGestureRecognizer *)recognizer
{
    CGPoint point = [recognizer locationInView:self.myMapView];  

    CLLocationCoordinate2D tapPoint = [self.myMapView convertPoint:point toCoordinateFromView:self.view];

    MKPointAnnotation *point1 = [[MKPointAnnotation alloc] init];

    point1.coordinate = tapPoint;

    [self.myMapView addAnnotation:point1];
}

All the best.

like image 89
anoop Avatar answered Nov 20 '22 17:11

anoop


so i found a way to do it, finally. If i create a view and add a map object to it with the same frame. then listen for hit test on that view, i can call convertPoint:toCoordinateFromView: on the touch point sent, and give it the map like so:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    CLLocationCoordinate2D coord= [map convertPoint:point toCoordinateFromView:map];
    NSLog(@"lat  %f",coord.latitude);
    NSLog(@"long %f",coord.longitude);

    ... add annotation ...

    return [super hitTest:point withEvent:event];
}

this is pretty rough as is and as you scroll the map it still constantly calls hit test so you will need to handle that, but its a start at getting the gps coordinates from touching a map.

like image 34
AtomRiot Avatar answered Nov 20 '22 18:11

AtomRiot


A bit of dead thread digging but as this is the top result in Google it may be worth it:

You can use the tap and hold gesture recognizer in order to get the coordinates and drop a pin on the map. Everything is explained at freshmob

like image 3
Erken Avatar answered Nov 20 '22 19:11

Erken


Swift 4.2

func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

for touch in touches {
    let touchPoint = touch.location(in: mapView)
    let location = mapView.convert(touchPoint, toCoordinateFrom: mapView)
    print ("\(location.latitude), \(location.longitude)")
}}
like image 3
Guilherme Rangel Avatar answered Nov 20 '22 19:11

Guilherme Rangel


Swift 2.2

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    let point = gestureRecognizer.locationInView(mapView)
    let tapPoint = mapView.convertPoint(point, toCoordinateFromView: view)
    coordinateLabel.text = "\(tapPoint.latitude),\(tapPoint.longitude)"

    return true
}
like image 1
Ramis Avatar answered Nov 20 '22 18:11

Ramis