Ios Map: Getting latitude and longitude - iphone

Am trying to read the longitude and latitude when the user touch (tap) on the ios Map place i want to get that particular (user tapping place) place latitude and longitude points.
(for (e.x) if the user touch the ios head office means i want to show ios head office place longitude and latitude points). How can i do this. Any one can help me to solve this issue.

Override a touch handler (touchesBegan or UITapGestureRecognizer) and then use
- (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view in MKMapView, class reference here. Then add an appropriate annotation to the map using a class conforming to the MKAnnotation protocol, e.g. MKPinAnnotationView.
So an example touch handler method would look something like:
-(void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
CGPoint pt = [[touches anyObject]locationInView:self.mapView];
CLLocationCoordinate2D latLong = [self.mapView convertPoint:pt toCoordinateFromView:self.mapView];
//add code here for annotation
}
Then add the annotation - this tutorial http://www.raywenderlich.com/21365/introduction-to-mapkit-in-ios-6-tutorial should help you with that- there's an iOS5 version on the same site as well.

Related

In iOS, how to trace the swiped distance in google maps?

I've an application where I'm using Google maps SDK.
If the user is doing a wild swipe on the map view controller,(say 100miles), Then I want to take the user back to his current location.
How to implement this functionality in maps ?
How to trace the wild swipe which moved the map 100miles on the screen ?
How to know the intensity of the swipe? and how many miles that swipe take you from the current location based on the zoom level?
Thanks in advance!
What do you mean by wild swipe? Move map 100 miles in one swipe? If so, you can add an UIPanGestureRecognizer to the map view,
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:aGMSMapView action:#selector(pan:)];
[aGMSMapView addGestureRecognizer:panRecognizer];
and implement a method to detect if the state of pan gesture is end or not. If so, check the center of the map view to determine how far you moved
-(void)pan:(UIPanGestureRecognizer*) gestureRecognizer
{
if(gestureRecognizer.state == UIGestureRecognizerStateEnded)
{
//get the center of map view, and calculate distance
CGPoint *point = aGMSMapView.center;
CLLocationCoordinate2D coor = [aGMSMapView.projection coordinateForPoint:point];
CLLocation *mapCenter = [[CLLocation alloc]initWithLatitude:coor.latitude longitude:coor.longitude];
CLLocationDistance d = [mapCenter distanceFromLocation:currentLocation];
if (d>= 106900)
{
//move your map view and do whatever you want...
}
}
}

Get coordinates upon mapview gesture

How do I get the latitude and longitude on the point where the user do a longhold(eg 2s)on the mapView.
I chanced upon a similar question : get coordinates on tap in iphone application
But I don't understand how do I go about handling the touch event on the mapView.
What I intent to achieve it to drop a pin annotation to the location, do nesscary reverse geocoding via Google API and display it on the subtitle. So firstly, I would need to get the required coordinates.
Examples would be very much appreciated.
Thanks.
You can convert the coordinates of the touch in the view retrieved from the gesture to gps coordinates like this...
- (void)mapLongPress:(UILongPressGestureRecognizer *)gestureRecognizer{
if(gestureRecognizer.state == UIGestureRecognizerStateBegan){
CGPoint touchLocation = [gestureRecognizer locationInView:mapView];
CLLocationCoordinate2D coordinate;
coordinate = [mapView convertPoint:touchLocation toCoordinateFromView:mapView];
}
}
Note that in my example, I had the gesture applied to the mapView itself. You would have to pass the view to which you applied the gesture to toCoordinateFromView:mapView

query the color of the MKpolygon on where the user is

I was wondering if there was a way to query what color my MKPolygon layer is, if the users locations is on top of it.
Thank you
Nope. No way.I was on the same situation ten days ago and i searched in web all along and couldnt do that functionality. I think apple should come up with some delegates on MKOverlay in future iOS SDK's for touch events on polygons.
When your MKMapView delegate receives a user location update you can loop through your overlays and see if the users location is inside the bounding map rect for any of the overlays. On your overlay, just add a "color" property that you can use to find the color.
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
for (MyOverlayClass* overlay in mapView.overlays)
{
MKMapPoint userPoint = MKMapPointForCoordinate(userLocation.location.coordinate);
if ( MKMapRectContainsPoint(overlay.boundingMapRect, userPoint) )
{
UIColor* userInColor = overlay.color;
}
}
}

how can I show compass/heading on mapkit mapview

on the iPhone 3GS in the "Maps" app you can click the icon which usually shows your position twice and the blue dot gains what looks like a beam from a headlamp, basically showing you the direction you are facing on the map and rotating the image accordingly.
Is this option available using MapKit MapView ?
I'm know that I can get my heading with something like
- (void)locationManager:(CLLocationManager *) manager didUpdateHeading:(CLHeading *) newHeading {
// If the accuracy is valid, process the event.
if (newHeading.headingAccuracy > 0) {
CLLocationDirection theHeading = newHeading.magneticHeading;
...
}
}
but I don't know how to get that nice headlamp effect in Mapkit and there doesn't seem to be any documentation.
Any ideas?
Adding user tracking mode also helps. I know I am late, but possibly a help to other developers like me :)
self.mapView.userTrackingMode = RMUserTrackingModeFollowWithHeading;
I found a solution:
I rotate the map using the available heading-information with
[mapView setTransform:CGAffineTransformMakeRotation(heading.magneticHeading * M_PI / -180.0)];
Therefore the "beam" always points to the top of the device. I now just display an ImageView on top of the map and change it's position in locationManager:didUpdateToLocation:fromLocation:
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
// scroll to new location
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(newLocation.coordinate, 2000, 2000);
[self.mapView setRegion:region animated:YES];
// set position of "beam" to position of blue dot
self.headingAngleView.center = [self.mapView convertCoordinate:newLocation.coordinate toPointToView:self.view];
// slightly adjust position of beam
self.headingAngleView.frameTop -= self.headingAngleView.frameHeight/2 + 8;
}
Whereby frameTop and frameHeight are shortcuts for frame.origin.y and frame.size.height.
It is not ideal and sometimes lacks a little bit when the dot changes it's position, but I'm happy with the solution b/c it works.
Have a look at my OpenSource framework MTLocation which does this all (and a lot of other cool Map-related stuff for you):
MTLocation
The rotating logic of the other answers are good, however relying on the location manager delegate methods won't result in a good solution. The "beam" image will rarely be in the same place as the blue dot and will bounce around a lot.
The best solution is to get a reference to the blue dot view, and add the "beam" image as a subview to it. I went with a beam image that was a square, with the beam up top and transparency all around it. Imagine the blue dot being in the center of the image.
// An MKMapViewDelegate method. Use this to get a reference to the blue dot annotation view as soon as it gets added
- (void)mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView *annotationView in views) {
// Get the user location view, check for all of your custom annotation view classes here
if (![annotationView isKindOfClass:[MKPinAnnotationView class]])
{
self.userLocationAnnotationView = annotationView;
gotUsersLocationView = YES;
}
}
}
// Adds the 'viewPortView' to the annotation view. Assumes we have a reference to the annotation view. Call this before you start listening to for heading events.
- (void)addViewportToUserLocationAnnotationView {
TTDASSERT(self.userLocationAnnotationView != nil);
if (self.userLocationAnnotationView == nil) {
// No reference to the view, can't do anything
return;
}
if (self.viewPortView == nil) {
self.viewPortView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"map_viewport.png"]] autorelease];
}
[self.userLocationAnnotationView addSubview:self.viewPortView];
[self.userLocationAnnotationView sendSubviewToBack:self.viewPortView];
self.viewPortView.frame = CGRectMake((-1 * self.viewPortView.frame.size.width/2) + self.userLocationAnnotationView.frame.size.width/2,
(-1 * self.viewPortView.frame.size.height/2) + self.userLocationAnnotationView.frame.size.height/2,
self.viewPortView.frame.size.width,
self.viewPortView.frame.size.height);
}
I could think of one method, though I have not implemented but may help you a bit.
Firstly you need an image with a pointer of your choice, this pointer must be pointing Upwards 90degree.
Now in your MapKit off the Current Location Marker.
In your didUpdateHeading use the x and y values to calculate the angle of the direction.
Use this angle to rotate the image of the pointer
Use this rotated image as a Annotation Pin in your map.
You would require to update the position of the pointer frequently.
Please post your suggestions/changes for the above approach.
Swift 3 implementation
mapView.userTrackingMode = MKUserTrackingMode.followWithHeading

Rotate MapView using Compass orientation

Is it possible to have an embedded MKMapView rotate to always face the direction the iPhone is facing? Basically I want to mimic the Map app rotation feature on my own app.
I see that the iPhone SDK does not expose the functionality. However, I wonder if it would work to rotate the entire view using CGAffineTransformMakeRotate. Would it affect tapping and zooming? Is there a better way?
To rotate the mapView but not the annotations you could use the following code to compensate for the maps rotation.
- (void)locationManager:(CLLocationManager *)manager
didUpdateHeading:(CLHeading *)newHeading
{
double rotation = newHeading.magneticHeading * 3.14159 / 180;
CGPoint anchorPoint = CGPointMake(0, -23); // The anchor point for your pin
[mapView setTransform:CGAffineTransformMakeRotation(-rotation)];
[[mapView annotations] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
MKAnnotationView * view = [mapView viewForAnnotation:obj];
[view setTransform:CGAffineTransformMakeRotation(rotation)];
[view setCenterOffset:CGPointApplyAffineTransform(anchorPoint, CGAffineTransformMakeRotation(rotation))];
}];
}
Another sollution is using a new method that has been added in iOS 5 to MKMapView.
Take a look at: http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MKMapView_Class/MKMapView/MKMapView.html
- (void)setUserTrackingMode:(MKUserTrackingMode)mode animated:(BOOL)animated;
I can confirm that it works fine. Here's the code that I'm using:
[mapView setTransform:CGAffineTransformMakeRotation(-1 * currentHeading.magneticHeading * 3.14159 / 180)];
mapView is my MKMapView instance
Simple solution in swift 3.0. Make sure to put the line in mapViewDidFinishLoadingMap or it will ignore it
public func mapViewDidFinishLoadingMap(_ mapView: MKMapView)
{
mapView.setUserTrackingMode(.followWithHeading, animated: false)
}
If you don't want the map to center on the user location you might do something like this
public func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading)
{
if(CLLocationCoordinate2DIsValid(mapView.centerCoordinate))
{
mapView.camera.heading = newHeading.trueHeading
}
}
If you look in the 3.0 iPhone Application Programming Guide under Device Support you'll find information on the magnetometer (aka compass). Once you start getting heading information (through the didUpdateHeading method) you should be able to get the compass data then use that to calculate the proper rotation transform value to apply to the map view.
Not sure if it handles zooming. In the standard map application I've noticed that compass heading tracking stops as soon as you start pinch-zooming.
Also, keep in mind that location directions are in degrees whereas transform rotation angles are in radians.
if you use a navigationVontroller try this:
//For Left button
MKUserTrackingBarButtonItem *buttonItem = [[MKUserTrackingBarButtonItem
alloc]initWithMapView:_mapView];
self.navigationItem.leftBarButtonItem = buttonItem;
// For Right Button
MKUserTrackingBarButtonItem *buttonItem = [[MKUserTrackingBarButtonItem
alloc]initWithMapView:_mapView];
self.navigationItem.rightBarButtonItem = buttonItem;