I have this code for my iOS app:
NSString *location = [[NSString alloc] initWithFormat:#"%#, %#", [self.campus campusStreetAddress], [self.campus campusCityStateZip]];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKCoordinateRegion region = self.campusMap.region;
region.center = placemark.region.center; //DEPRECATED iOS 7
region.span.longitudeDelta /= 1500;
region.span.latitudeDelta /= 1500;
[self.campusMap setRegion:region animated:NO];
[self.campusMap addAnnotation:placemark];
}
}
];
But, when I upgraded my app to iOS 7, placemark.region.center is deprecated. Is there a replacement I should use? Is this even a proper method to creating a map in a view?
Thanks!!
Try this:
region.center = [(CLCircularRegion *)placemark.region center];
if you just want the center of the region you can use :
region.center = placemark.location.coordinate
Combination of Heesien's and other answers and a bit of experimenting.
- (void)centerMapAroundPlacemark:(MKPlacemark *)placemark
{
CLRegion *region = placemark.region;
if ([region isKindOfClass:[CLCircularRegion class]])
{
[self centerMapAroundCircularRegion:(CLCircularRegion *)region
centerCoodinate:placemark.location.coordinate];
}
else
{
[self centerMapAroundCoorinate:placemark.location.coordinate];
}
}
- (void)centerMapAroundCircularRegion:(CLCircularRegion *)circularRegion
{
MKCoordinateRegion coordinateRegion =
MKCoordinateRegionMakeWithDistance(circularRegion.center,
circularRegion.radius,
circularRegion.radius);
[self.mapView setRegion:coordinateRegion animated:YES];
}
- (void)centerMapAroundCircularRegion:(CLCircularRegion *)circularRegion
centerCoodinate:(CLLocationCoordinate2D)centerCoodinate
{
// Only user the radius of region for an appropriate zoom level.
// The center of the region is not accurate.
// To see this search for 'Bath, UK'
MKCoordinateRegion coordinateRegion =
MKCoordinateRegionMakeWithDistance(centerCoodinate,
circularRegion.radius,
circularRegion.radius);
[self.mapView setRegion:coordinateRegion animated:YES];
}
Related
I'm using the below code to display addresses from an array (responseObject) as annotations on my mapview. It works, and the pin is dropped successfully from my location string, however it only shows a pin for the most recent address added to the array. How can I change my code so that it shows pins on the map for all addresses in my array instead of just the most recent one? Apologies if this is a newb question. Thanks!
viewcontroller.m
NSMutableDictionary *viewParams = [NSMutableDictionary new];
[viewParams setValue:#"u000" forKey:#"view_name"];
[DIOSView viewGet:viewParams success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.addressData = [responseObject mutableCopy];
NSString *location = self.addressData[0][#"address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
MKCoordinateRegion region = self.mapView.region;
// region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = self.addressData[0][#"users_name"];
point.subtitle = self.addressData[0][#"userbio"];
[self.mapView addAnnotation:point];
You are accessing only one object ?
NSString *location = self.addressData[0][#"address"];
Edited
I think you should handle your data, separated with your view. i.e. implement geocoder related code in the mapView:viewForAnnotation: method in your map view delegate. Then you should be able to create the annotations one by one and use [self.mapView addAnnotations] for all of them
For your code, which I believe is inspired by this answer, you should be able to iterate through all location addresses by something like
for (NSMutableDictionary *loc in self.addressData) {
NSString *loc = location[#"address"];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
......
}
Forgive me if the syntax is wrong for Objective C.
This shouldnt be this hard... I'm just trying to geocode an address string so I can zoom to that address on the map on viewDidLoad, but every time I run the geocoding method I get 0 0 as my lat and long.
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:addressOfSelected completionHandler:^(NSArray *placemarks, NSError *error) {
if (error) {
NSLog(#"Geocode failed with error: %#", error);
return;
}
if (placemarks && placemarks.count > 0)
{
CLPlacemark *placemark = placemarks[0];
CLLocation *location = placemark.location;
self.shackCoords = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude);
}
}];
MKCoordinateRegion region;
region.center.latitude = self.shackCoords.latitude;
region.center.longitude = self.shackCoords.longitude;
region.span.latitudeDelta = .05;
region.span.longitudeDelta = .05;
[self.mapView setRegion:region];
shackCoords is just a CLLocationCoordinate2D.
There must be an easy way to do this or somewhere I am going wrong but I can't seem to save my current location as a global variable and then add it to my array to populate my UITableView.
Basically, at the moment I have an empty UITableView that is used to populate results from a local search, via a search bar. This part works great. BUT, what I want is to always have the 1st row as the users current location, like in maps, google maps, reminders etc. I figured this would be a simple task but I cant get it to work. Can someone help me please.
I use the following code to get my current location, reverse geocode it, and plot it on the map when the app starts:
self.locationManager = [[CLLocationManager alloc]init];
if ([CLLocationManager locationServicesEnabled]) {
self.locationManager.delegate = self;
self.locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
}
CLLocationCoordinate2D zoomLocation;
zoomLocation.latitude = _locationManager.location.coordinate.latitude;
zoomLocation.longitude= _locationManager.location.coordinate.longitude;
currentCoord.latitude = _locationManager.location.coordinate.latitude;
currentCoord.longitude= _locationManager.location.coordinate.longitude;
//reverse geocoder
CLLocation *currentLocation = [[CLLocation alloc] initWithLatitude:zoomLocation.latitude longitude:zoomLocation.longitude];
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
[geoCoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
for (CLPlacemark *placemark in placemarks) {
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = zoomLocation;
annotation.title = #"Current Location";
annotation.subtitle = placemark.name;
// 2
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(zoomLocation, 0.5*METERS_PER_MILE, 0.5*METERS_PER_MILE);
// 3
[_mapView setRegion:viewRegion animated:YES];
[_mapView addAnnotation:annotation];
}
}];
When I run my local search I use the following code to populate my array to load the table with:
MKLocalSearchRequest *request =
[[MKLocalSearchRequest alloc] init];
request.naturalLanguageQuery = _searchBar.text;
request.region = _mapView.region;
MKLocalSearch *search =
[[MKLocalSearch alloc]initWithRequest:request];
[search startWithCompletionHandler:^(MKLocalSearchResponse
*response, NSError *error) {
if (response.mapItems.count == 0)
NSLog(#"No Matches");
else
for (MKMapItem *item in response.mapItems)
{
[tableData addObject:item];
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = item.placemark.coordinate;
annotation.title = item.placemark.name;
annotation.subtitle = item.placemark.title;
[annotations addObject:annotation];
[_tableResults reloadData];
}
}];
I really can't figure this out. How would I add my current location? Would really appreciate some advise. Thanks in advance guys!
Try this,
[search startWithCompletionHandler:^(MKLocalSearchResponse
*response, NSError *error) {
if (response.mapItems.count == 0)
NSLog(#"No Matches");
else
for (MKMapItem *item in response.mapItems)
{
[tableData addObject:item];
[annotations addObject:[self annotationFromMapItem:item]];
}
double latitude = self.locationManager.location.coordinate.latitude;
double longitude = self.locationManager.location.coordinate.longitude;
MKPlacemark *placemark = [[[MKPlacemark alloc] initWithCoordinate:CLLocationCoordinate2DMake(latitude, longitude) addressDictionary:nil] autorelease];
MKMapItem *mapItem = [[[MKMapItem alloc] initWithPlacemark:placemark] autorelease];
[mapItem setName:Current Location];
[tableData insertObject:mapItem atIndex:0];
[annotations insertObject:[self annotationFromMapItem:mapItem] atIndex:0];
[_tableResults reloadData];
}];
- (MKPointAnnotation) annotationFromMapItem:(MKMapItem *)item {
MKPointAnnotation *annotation =
[[MKPointAnnotation alloc]init];
annotation.coordinate = item.placemark.coordinate;
annotation.title = item.placemark.name;
annotation.subtitle = item.placemark.title;
return annotation;
}
I want to make a functionality in my app by which I can get a line drawn from my current location to the desired coordinates which are float values. Please suggest me the best efficient way for doing the same.
I have got the answear of my question for all ios and it is as follows
// To show direction using geo coder...*
- (void)showDirection:(id)sender
{
NSString *deviceVersion = [[UIDevice currentDevice] systemVersion];
NSLog(#"My Device version is :%# ",deviceVersion);
//********* For ios 6 supporting devices *********
if ([deviceVersion isEqualToString:#"6.0"])
{
Class itemClass = [MKMapItem class];
if (itemClass && [itemClass respondsToSelector:#selector(openMapsWithItems:launchOptions:)]) {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
CLLocation *newLocation = [[CLLocation alloc]initWithLatitude:getLatitude
longitude:getLongitude];
[geocoder reverseGeocodeLocation:newLocation
completionHandler:^(NSArray *placemarks, NSError *error) {
MKPlacemark *placeMark = [[MKPlacemark alloc] initWithPlacemark:[placemarks objectAtIndex:0]];
MKMapItem *mapItem = [[MKMapItem alloc]initWithPlacemark:placeMark];
MKMapItem *mapItem2 = [MKMapItem mapItemForCurrentLocation];
NSArray *mapItems = #[mapItem, mapItem2];
NSDictionary *options = #{
MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeDriving,
MKLaunchOptionsMapTypeKey:
[NSNumber numberWithInteger:MKMapTypeStandard],
MKLaunchOptionsShowsTrafficKey:#YES
};
[MKMapItem openMapsWithItems:mapItems launchOptions:options];
} ];
}
else
{
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Failed to Get Your Location"delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[errorAlert show];
}
}
//********* For other ios supporting devices *********
else {
MKCoordinateRegion region = { {0.0, 0.0 }, { 0.0, 0.0 } };
region.center.latitude = getLatitude;
region.center.longitude = getLongitude;
MKCoordinateRegion currentRegion = { {0.0, 0.0 }, { 0.0, 0.0 } };
currentRegion.center.latitude = currentLatitude;
currentRegion.center.longitude = currentLongitude;
region.span.longitudeDelta = 4.0f;
region.span.latitudeDelta = 4.0f;
currentRegion.span.longitudeDelta = 4.0f;
currentRegion.span.latitudeDelta = 4.0f;
CLLocationCoordinate2D start = { currentRegion.center.latitude, currentRegion.center.longitude };
CLLocationCoordinate2D destination = { region.center.latitude, region.center.longitude };
NSString *googleMapsURLString = [NSString stringWithFormat:#"http://maps.google.com/?saddr=%1.6f,%1.6f&daddr=%1.6f,%1.6f",start.latitude, start.longitude, destination.latitude, destination.longitude];
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:googleMapsURLString]];
}
}
I'm having issues setting the title and subtitle of my placemark.
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:location
completionHandler:^(NSArray* placemarks, NSError* error){
if (placemarks && placemarks.count > 0) {
CLPlacemark *topResult = [placemarks objectAtIndex:0];
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
placemark.title = #"Some Title";
placemark.subtitle = #"Some subtitle";
MKCoordinateRegion region = self.mapView.region;
region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:placemark];
}
}
];
placemark.title = #"Some Title"; and placemark.subtitle = #"Some subtitle";
give me an error of:
Assigning to property with 'readonly' attribute not allowed
Why can I not set the Title and Subtitle here?
Thought I'd wake this thread up and give you a solution that I came up with.
As far as I'm aware, MKPlacemark's title/subtitle are readonly properties due to inherent assignment. However, with the solution I found, you can simply pass your MKPlacemark into an MKPointAnnotation as follows:
CLPlacemark *topResult = [placemarks objectAtIndex:0];
// Create an MLPlacemark
MKPlacemark *placemark = [[MKPlacemark alloc] initWithPlacemark:topResult];
// Create an editable PointAnnotation, using placemark's coordinates, and set your own title/subtitle
MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
point.coordinate = placemark.coordinate;
point.title = #"Sample Location";
point.subtitle = #"Sample Subtitle";
// Set your region using placemark (not point)
MKCoordinateRegion region = self.mapView.region;
region.center = placemark.region.center;
region.span.longitudeDelta /= 8.0;
region.span.latitudeDelta /= 8.0;
// Add point (not placemark) to the mapView
[self.mapView setRegion:region animated:YES];
[self.mapView addAnnotation:point];
// Select the PointAnnotation programatically
[self.mapView selectAnnotation:point animated:NO];
Please note that the final [self.mapView selectAnnotation:point animated:NO]; is a workaround to allow automatic popping-up of the placemark. However, the animated:BOOL portion only seems to work with NO in iOS5 - You might want to implement a workaround if you experience issues manually popping up the point-annotation, which can be found here:
MKAnnotation not getting selected in iOS5
I'm sure you've already found your own solution by now, but I hope this is, in some way, informative.