I got the current location based on the Longitude and Latitude values and then I also got multiple places on google map using Annotation. Now I want to get the longitude and latitude values based on the Address( i.e street,city and county).Need some guidance on how this can be achieved.
Till now, this is what I have tried:-
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize streetField = _streetField, cityField = _cityField, countryField = _countryField, fetchCoordinatesButton = _fetchCoordinatesButton, nameLabel = _nameLabel, coordinatesLabel = _coordinatesLabel;
#synthesize geocoder = _geocoder;
- (void)viewDidLoad
{
[super viewDidLoad];
_streetField.delegate=self;
_cityField.delegate=self;
_countryField.delegate=self;
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)fetchCoordinates:(id)sender {
NSLog(#"Fetch Coordinates");
if (!self.geocoder) {
NSLog(#"Geocdoing");
self.geocoder = [[CLGeocoder alloc] init];
}
NSString *address = [NSString stringWithFormat:#"%# %# %#", self.streetField.text, self.cityField.text, self.countryField.text];
NSLog(#"GET Addres%#",address);
self.fetchCoordinatesButton.enabled = NO;
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Fetch Gecodingaddress");
if ([placemarks count] > 0) {
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"GET placemark%#",placemark);
CLLocation *location = placemark.location;
NSLog(#"GET location%#",location);
CLLocationCoordinate2D coordinate = location.coordinate;
self.coordinatesLabel.text = [NSString stringWithFormat:#"%f, %f", coordinate.latitude, coordinate.longitude];
NSLog(#"CoordinatesLabel%#",self.coordinatesLabel.text);
if ([placemark.areasOfInterest count] > 0) {
NSString *areaOfInterest = [placemark.areasOfInterest objectAtIndex:0];
self.nameLabel.text = areaOfInterest;
NSLog(#"NameLabe%#",self.nameLabel.text);
}
}
self.fetchCoordinatesButton.enabled = YES;
}];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
#end
Above code is not working to give me the latitude and longitude.Need some help on what am I doing wrong here or if I am missing on something.
Thanks in Advance.
This was very old answer, Kindly check with new Updates
EDIT:
Before using this check with iOS8 updation
NSLocationAlwaysUsageDescription
NSLocationWhenInUseUsageDescription
This is for getting lat and long based user area like street name,state name,country.
-(CLLocationCoordinate2D) getLocationFromAddressString: (NSString*) addressStr {
double latitude = 0, longitude = 0;
NSString *esc_addr = [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude = longitude;
NSLog(#"View Controller get Location Logitute : %f",center.latitude);
NSLog(#"View Controller get Location Latitute : %f",center.longitude);
return center;
}
call the method like this in viewdidload method or somewhere according to your project
[self getLocationFromAddressString:#"chennai"];
just pass this in your browser
http://maps.google.com/maps/api/geocode/json?sensor=false&address=chennai
and you will have json format with lat and lon
http://maps.google.com/maps/api/geocode/json?sensor=false&address=#"your city name here"
NSString *address = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%# %# %#", self.streetField.text, self.cityField.text, self.countryField.text];
the usage of this method....
CLLocationCoordinate2D center;
center=[self getLocationFromAddressString:#"uthangarai"];
double latFrom=¢er.latitude;
double lonFrom=¢er.longitude;
NSLog(#"View Controller get Location Logitute : %f",latFrom);
NSLog(#"View Controller get Location Latitute : %f",lonFrom);
Someone looking for Swift 2.0 solution can use below :
let address = "1 Infinite Loop, CA, USA"
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address, completionHandler: {(placemarks, error) -> Void in
if((error) != nil){
print("Error", error)
}
if let placemark = placemarks?.first {
let coordinates:CLLocationCoordinate2D = placemark.location!.coordinate
coordinates.latitude
coordinates.longitude
print("lat", coordinates.latitude)
print("long", coordinates.longitude)
}
})
Try this,
NSString *address = [NSString stringWithFormat:#"%#,%#,%#", self.streetField.text, self.cityField.text,self.countryField.text];
[self.geocoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error)
{
if(!error)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSLog(#"%f",placemark.location.coordinate.latitude);
NSLog(#"%f",placemark.location.coordinate.longitude);
NSLog(#"%#",[NSString stringWithFormat:#"%#",[placemark description]]);
}
else
{
NSLog(#"There was a forward geocoding error\n%#",[error localizedDescription]);
}
}
];
Swift
public func getLocationFromAddress(address : String) -> CLLocationCoordinate2D {
var lat : Double = 0.0
var lon : Double = 0.0
do {
let url = String(format: "https://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", (address.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!))
let result = try Data(contentsOf: URL(string: url)!)
let json = JSON(data: result)
lat = json["results"][0]["geometry"]["location"]["lat"].doubleValue
lon = json["results"][0]["geometry"]["location"]["lng"].doubleValue
}
catch let error{
print(error)
}
return CLLocationCoordinate2D(latitude: lat, longitude: lon)
}
I used SwiftyJSON but you can parse the JSON response however you want
- (IBAction)forwardButton:(id)sender
{
if([self.address.text length])
{
NSString *place = self.address.text;
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
__unsafe_unretained RTGeoCoderViewController *weakSelf = self;
[geocoder geocodeAddressString:place completionHandler:^(NSArray* placemarks, NSError* error)
{
NSLog(#"completed");
if ( error )
{
NSLog(#"error = %#", error );
dispatch_async(dispatch_get_main_queue(),
^{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:[self errorMessage:error.code] delegate:nil cancelButtonTitle:nil otherButtonTitles:#"OK", nil];
[alert show];
});
}
else
{
NSLog(#"%#",placemarks);
}
}];
}
}
Try this
- (void)getAddressFromAdrress:(NSString *)address withCompletationHandle:(void (^)(NSDictionary *))completationHandler {
CLGeocoder *geoCoder = [[CLGeocoder alloc] init];
//Get the address through geoCoder
[geoCoder geocodeAddressString:address completionHandler:^(NSArray *placemarks, NSError *error) {
if ([placemarks count] > 0 && !error) {
//get the address from placemark
CLPlacemark *placemark = [placemarks objectAtIndex:0];
NSString *locatedAt = [[placemark.addressDictionary valueForKey:#"FormattedAddressLines"] componentsJoinedByString:#", "];
CLLocation *location = placemark.location;
CLLocationCoordinate2D coordinate = location.coordinate;
_latitudeUserLocation = coordinate.latitude;
_longitudeUserLocation = coordinate.longitude;
NSString *postalCode = placemark.addressDictionary[(NSString*)kABPersonAddressZIPKey];
if (postalCode == nil) postalCode = #"";
if (locatedAt == nil) locatedAt = #"";
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:
postalCode ,kPostalCode,
locatedAt ,kFullAddress,
nil];
completationHandler(dictionary);
} else {
completationHandler(nil);
}
}];
}
Related
I'm trying to display multiple arrays of locations on my mapView with the below code (Restaurants, Parks, Meet Ups & Stores). When I open the app, not all addresses inside the arrays are displayed on my mapView (even though all data is returned) - e.g. sometimes only 'Stores' and 'Parks' arrays of annotations will show up on my map, but Restaurants aren't visible (even though data for all arrays is returned successfully). If I close out and reopen the app, sometimes Parks will show on the map, but nothing else. Any idea why this happens, and how I can fix it? Code updated below. Been at this forever!
Note: ParksAnnotation, RestAnnotation, meetupAnn, & StoreAnnotation are all MKPointAnnotation classes.
UPDATE (10/13/2020): I tried logging 'placemarks' under the block of code that retrieves and geocodes my 'Stores' coordinates. It appears as though self.storeData is populated, as is the created NSDictionary storeFields. That said, when I log 'placemarks', it isn't returning any coordinates, even though storeFields[#"address"] is populated. The other blocks of code seem to be doing their job just fine (ie. retrieving Meet Ups and retrieving Parks). So Meet Ups, Restaurants and Parks annotations appear fine, but all Stores annotations aren't populated. This happens to at least one type of annotation (sometimes it's Stores that's missing, other times it's Parks) at random when I launch the app. I can't for the life of me sort out why this is happening.
See below code:
MapViewController.m
#import "StoreAnnotation.h"
#import "ParksAnnotation.h"
#import "RestAnnotation.h"
#import "meetupAnn.h"
#interface MapViewController ()
#end
#implementation MapViewController
-(void)viewWillAppear:(BOOL)animated {
NSMutableDictionary *viewParamsallUsers1 = [NSMutableDictionary new];
[viewParamsallUsers1 setValue:#"hosted_meet_ups" forKey:#"view_name"];
[DIOSView viewGet:viewParamsallUsers1 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.meetUps = [responseObject mutableCopy];
int index = 0;
for (NSMutableDictionary *allMeetups in self.meetUps) {
NSString *location = allMeetups[#"where"];
NSString *userNames = allMeetups[#"node_title"];
NSString *userBio = allMeetups[#"body"];
self.alertMessage = [allMeetups[#"node_title"] mutableCopy];
CLGeocoder *geocoderFriend = [[CLGeocoder alloc] init];
[geocoderFriend 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.span.longitudeDelta /= 150.0;
region.span.latitudeDelta /= 150.0;
meetupAnn *meet = [[meetupAnn alloc] init];
meet.coordinate = placemark.coordinate;
meet.title = userNames;
meet.subtitle = userBio;
meet.index = index; // Store index here.
[self.mapView addAnnotation:meet];
}
}
];
index = index + 1;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
/// GRAB ALL RESTAURANT LOCATIONS ///
NSMutableDictionary *viewParams6 = [NSMutableDictionary new];
[viewParams6 setValue:#"restaurants" forKey:#"view_name"];
[DIOSView viewGet:viewParams6 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.neighbourhoodData = [responseObject mutableCopy];
int index = 0;
for (NSMutableDictionary *multiplelocationsFriend in self.neighbourhoodData) {
NSString *location = multiplelocationsFriend[#"address"];
NSString *userNames = multiplelocationsFriend[#"node_title"];
NSString *ampRemoved = [userNames stringByReplacingOccurrencesOfString:#"amp;" withString:#""];
NSString *userBio = multiplelocationsFriend[#"body"];
self.x3 = multiplelocationsFriend[#"x3"];
CLGeocoder *geocoderFriend = [[CLGeocoder alloc] init];
[geocoderFriend 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.span.longitudeDelta /= 150.0;
region.span.latitudeDelta /= 150.0;
RestAnnotation *point1 = [[RestAnnotation alloc] init];
point1.coordinate = placemark.coordinate;
point1.title = ampRemoved;
point1.subtitle = userBio;
point1.index = index; // Store index here.
[self.mapView addAnnotation:point1];
}
}
];
index = index + 1;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
NSString *test = self.areaName;
NSLog(#"SHOW TEST %#", test);
/// GRAB ALL STORE LOCATIONS ///
NSMutableDictionary *viewParams7 = [NSMutableDictionary new];
[viewParams7 setValue:#"stores" forKey:#"view_name"];
[DIOSView viewGet:viewParams7 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.storesData = [responseObject mutableCopy];
int index = 0;
for (NSMutableDictionary *storeFields in self.storesData) {
NSString *location = storeFields[#"address"];
NSString *userNames = storeFields[#"node_title"];
NSString *ampRemoved = [userNames stringByReplacingOccurrencesOfString:#"amp;" withString:#""];
NSString *userBio = storeFields[#"body"];
self.x3 = storeFields[#"x3"];
CLGeocoder *geocoderFriend = [[CLGeocoder alloc] init];
[geocoderFriend 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.span.longitudeDelta /= 150.0;
region.span.latitudeDelta /= 150.0;
StoreAnnotation *point2 = [[StoreAnnotation alloc] init];
point2.coordinate = placemark.coordinate;
point2.title = ampRemoved;
point2.subtitle = userBio;
point2.index = index; // Store index here.
[self.mapView addAnnotation:point2];
}
}
];
index = index + 1;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
/// GRAB ALL PARKS LOCATIONS ///
NSMutableDictionary *viewParams8 = [NSMutableDictionary new];
[viewParams8 setValue:#"parks" forKey:#"view_name"];
[DIOSView viewGet:viewParams8 success:^(AFHTTPRequestOperation *operation, id responseObject) {
self.parksData = [responseObject mutableCopy];
int index = 0;
for (NSMutableDictionary *parkFields in self.parksData) {
// NSLog(#"WHAT IS IN FRIENDS %#", self.friendData);
NSString *location = parkFields[#"address"];
NSString *userNames = parkFields[#"node_title"];
NSString *ampRemoved = [userNames stringByReplacingOccurrencesOfString:#"amp;" withString:#""];
NSString *userBio = parkFields[#"body"];
self.x3 = parkFields[#"x3"];
CLGeocoder *geocoderFriend = [[CLGeocoder alloc] init];
[geocoderFriend 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.span.longitudeDelta /= 150.0;
region.span.latitudeDelta /= 150.0;
ParksAnnotation *point3 = [[ParksAnnotation alloc] init];
point3.coordinate = placemark.coordinate;
point3.title = ampRemoved;
point3.subtitle = userBio;
point3.index = index; // Store index here.
[self.mapView addAnnotation:point3];
}
}
];
index = index + 1;
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Failure: %#", [error localizedDescription]);
}];
}
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{
MKCoordinateRegion mapRegion;
mapRegion.center = mapView.userLocation.coordinate;
mapRegion.span.latitudeDelta = 0.5;
mapRegion.span.longitudeDelta = 0.5;
[mapView setRegion:mapRegion animated: YES];
[self.locationManager stopUpdatingLocation];
self.locationManager = nil;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 8000, 8000);
[mapView setRegion:[mapView regionThatFits:region] animated:YES];
[mapView addAnnotations:[mapView annotations]];
});
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
if([annotation isKindOfClass:[StoreAnnotation class]]) {
static NSString *identifier = #"stores";
MKAnnotationView *storesView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(storesView == nil) {
storesView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
storesView.displayPriority = MKFeatureDisplayPriorityRequired;
storesView.canShowCallout = YES;
storesView.image = [UIImage imageNamed:#"storeann4.png"];
}
else {
storesView.annotation = annotation;
}
return storesView;
}
if([annotation isKindOfClass:[meetupAnn class]]) {
static NSString *identifier = #"meetUps";
MKAnnotationView *pulsingView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(pulsingView == nil) {
pulsingView.displayPriority = MKFeatureDisplayPriorityRequired;
pulsingView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
pulsingView.image = [UIImage imageNamed:#"meetupbeacon.png"];
pulsingView.canShowCallout = YES;
}
else {
pulsingView.annotation = annotation;
}
return pulsingView;
}
if([annotation isKindOfClass:[ParksAnnotation class]]) {
static NSString *identifier = #"parks";
MKAnnotationView *parksView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(parksView == nil) {
parksView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
parksView.displayPriority = MKFeatureDisplayPriorityRequired;
parksView.image = [UIImage imageNamed:#"parksann.png"];
parksView.canShowCallout = YES;
}
else {
parksView.annotation = annotation;
}
return parksView;
}
if([annotation isKindOfClass:[RestAnnotation class]]) {
static NSString *identifier = #"rests";
MKAnnotationView *restView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(restView == nil) {
restView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
restView.displayPriority = MKFeatureDisplayPriorityRequired;
restView.image = [UIImage imageNamed:#"restann.png"];
restView.canShowCallout = YES;
}
else {
restView.annotation = annotation;
}
return restView;
}
As Ramis said, the problem is that you're setting the displayPriority before you even instantiate the pulsingView. Thus, the MKAnnotationView you subsequently instantiate never got its displayPriority set.
That having been said, I'd suggest a slightly different implementation, though. Specifically, I'd move the configuration of the annotation view into its own subclass, rather than cluttering the view controller with this sort of code:
#interface MeetUpAnnotationView: MKAnnotationView
#end
#implementation MeetUpAnnotationView
- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
self.displayPriority = MKFeatureDisplayPriorityRequired;
self.canShowCallout = YES;
self.image = [UIImage imageNamed:#"meetupbeacon.png"];
}
return self;
}
- (void)setAnnotation:(id<MKAnnotation>)annotation {
[super setAnnotation:annotation];
self.displayPriority = MKFeatureDisplayPriorityRequired;
}
#end
Then, if targeting iOS 11 or later, your view controller's viewDidLoad should register that subclass.
Now, if this is the only annotation view that you’re showing in iOS 11, you don't need a viewForAnnotation at all and can just register your default annotation view:
[self.mapView registerClass:[MeetUpAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultAnnotationViewReuseIdentifier];
And having registered the annotation view class, you're done. No viewForAnnotation is needed or desired.
The only time you have to implement viewForAnnotation in iOS 11 and later is if you have multiple custom annotation view types on your map. In that case, you'd register them:
[self.mapView registerClass:[MeetUpAnnotationView class] forAnnotationViewWithReuseIdentifier:meetupIdentifier];
[self.mapView registerClass:[SomeOtherAnnotationView class] forAnnotationViewWithReuseIdentifier:someOtherIdentifier];
And then use dequeueReusableAnnotationViewWithIdentifier:forAnnotation: in your viewForAnnotation:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MeetupAnn class]]) {
return [mapView dequeueReusableAnnotationViewWithIdentifier:meetupIdentifier forAnnotation:annotation];
}
if ([annotation isKindOfClass:[SomeOtherAnnotation class]]) {
return [mapView dequeueReusableAnnotationViewWithIdentifier:someOtherIdentifier forAnnotation:annotation];
}
...
return nil;
}
As you can see, in iOS 11 (especially when you have only one annotation view type), the code is greatly simplified.
But if you need to support older iOS versions, you can't register the identifier and you have to use the older dequeueReusableAnnotationViewWithIdentifier:, but I'd still let the annotation view subclass take care of configuring itself. But, a more subtle problem in your code is that you are not setting the annotation in an else clause, so make sure to do that, e.g.:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MeetupAnn class]]) {
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:meetupIdentifier];
if (!annotationView) {
annotationView = [[MeetUpAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:meetupIdentifier];
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
You should check if some of your geocoding requests are failing inconsistently.
CLGeocoder rate limits your requests and if you do too many requests in a short time, you'll receive an error. https://developer.apple.com/documentation/corelocation/clgeocoder/1423509-geocodeaddressstring?language=objc
Check if you are getting any reason for failure inside NSError* error inside the completionHandler block.
As many times as it fails, you should see as many less number of annotations on the MapView because it is not entering the following code path.
if (placemarks && placemarks.count > 0) {
// Not entering here
}
if (nil != error) {
// Could land here
}
The only other reason would be not properly calculating map region to show all annotations in screen. Make sure you are calculating/adjusting the region correctly upon each annotation being added to the mapView.
// Define these variables globally in the view controller
CLLocationDegrees minLatitude = 90.0;
CLLocationDegrees maxLatitude = -90.0;
CLLocationDegrees minLongitude = 180.0;
CLLocationDegrees maxLongitude = -180.0;
// Call following method every time a new annotation needs to be added to the mapView
-(void)addAnnotation:(id<MKAnnotation>)annotation toMapView:(MKMapView*)mapView {
// Add the annotation to map
[mapView addAnnotation:annotation];
// Set the map region to make it visible along with all other annotations
CLLocationDegrees latitude = annotation.coordinate.latitude;
CLLocationDegrees longitude = annotation.coordinate.longitude;
minLatitude = min(minLatitude, latitude);
maxLatitude = max(maxLatitude, latitude);
minLongitude = min(minLongitude, longitude);
maxLongitude = max(maxLongitude, longitude);
CLLocationDegrees latitudeDelta = (maxLatitude - minLatitude);
CLLocationDegrees longitudeDelta = (maxLongitude - minLongitude);
CLLocationDegrees midLatitude = (maxLatitude - latitudeDelta/2);
CLLocationDegrees midLongitude = (maxLongitude - longitudeDelta/2);
CLLocationCoordinate2D center = CLLocationCoordinate2DMake(midLatitude, midLongitude);
MKCoordinateSpan span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta);
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
if (CLLocationCoordinate2DIsValid(center)) {
[mapView setRegion:region animated:YES];
}
}
You are assigning MKFeatureDisplayPriorityRequired to empty object. Try to assign display priority in two case:
When pulsingView is not nil.
After pulsingView allocated.
if([annotation isKindOfClass:[meetupAnn class]]) {
static NSString *identifier = #"currentLocation";
MKAnnotationView *pulsingView = (MKAnnotationView *)[self.friendsMapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(pulsingView == nil) {
pulsingView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
pulsingView.displayPriority = MKFeatureDisplayPriorityRequired;
pulsingView.canShowCallout = YES;
pulsingView.image = [UIImage imageNamed:#"meetupbeacon.png"];
NSLog(#"Location Returned");
} else {
pulsingView.displayPriority = MKFeatureDisplayPriorityRequired;
// TODO: Do map pin initial setup.
}
}
I have MapView that shows two points on a map with a route. When I zoom into the map, after I release, the map zooms back out.
I have zoomEnabled and scrollEnabled all set to yes in Code and on the InterfaceBuilder
#interface MapViewController () <UIApplicationDelegate, MKMapViewDelegate,CLLocationManagerDelegate> {
CLLocationManager * locationManager;
CLPlacemark * pmDesination;
CLLocation * currentLocation;
MyAnnotation * destinationAnn;
MKPolyline *_routeOverlay;
MKRoute *_currentRoute;
}
#end
#implementation MapViewController
const static int TYPE_STATUS_PICKUP = 0;
const static int TYPE_STATUS_DROPOFF = 1;
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self stopLocationServices];
}
- (void) viewDidLoad {
[super viewDidLoad];
self.mapView.delegate = self;
self.mapView.zoomEnabled = YES;
self.mapView.scrollEnabled = YES;
[self startLocationServices];
//Show points on map
[self addressSearch:self.pickupLocation type:TYPE_STATUS_PICKUP];
[self addressSearch:self.dropoffLocation type:TYPE_STATUS_DROPOFF];
}
- (void) mapViewDidFinishLoadingMap:(MKMapView *)mapView {
[self showRoute];
NSMutableArray * pins = [[NSMutableArray alloc] init];
if (destinationAnn != nil) {
[pins addObject:destinationAnn];
}
if ([self getCurrentLocationAnnotation] != nil) {
[pins addObject:[self getCurrentLocationAnnotation]];
}
if (pins.count > 0) {
[_mapView showAnnotations:pins animated:YES];
}
}
#pragma mapping methods
- (void) addressSearch:(NSMutableDictionary *)pinLocation type:(int)type {
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder geocodeAddressString:pinLocation[#"address"] completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error) {
if (error) {
//ERROR LOOKING UP ADDRESS
} else {
CLPlacemark * pm = [placemarks lastObject];
location.latitude = pm.location.coordinate.latitude;
location.longitude = pm.location.coordinate.longitude;
[ann setCoordinate:location];
ann.title = [pinLocation objectForKey:#"title"];
ann.subtitle = [pinLocation objectForKey:#"address"];
if (type == _toLocation) {
destinationAnn = ann;
}
[self.mapView addAnnotation:ann];
}
}];
}
#pragma mark - SHOW ROUTE
- (void) showRoute {
MKDirectionsRequest *directionsRequest = [MKDirectionsRequest new];
MKMapItem *source = [MKMapItem mapItemForCurrentLocation];
// Make the destination
CLLocationCoordinate2D destinationCoords = CLLocationCoordinate2DMake(destinationAnn.coordinate.latitude, destinationAnn.coordinate.longitude);
MKPlacemark *destinationPlacemark = [[MKPlacemark alloc] initWithCoordinate:destinationCoords addressDictionary:nil];
MKMapItem *destination = [[MKMapItem alloc] initWithPlacemark:destinationPlacemark];
// Set the source and destination on the request
[directionsRequest setSource:source];
[directionsRequest setDestination:destination];
MKDirections *directions = [[MKDirections alloc] initWithRequest:directionsRequest];
[directions calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {
if (error) {
NSLog(#"There was an error getting your directions: %#", error.localizedDescription);
return;
}
_currentRoute = [response.routes firstObject];
[self plotRouteOnMap:_currentRoute];
}];
}
- (void)plotRouteOnMap:(MKRoute *)route
{
if(_routeOverlay) {
[self.mapView removeOverlay:_routeOverlay];
}
// Update the ivar
_routeOverlay = route.polyline;
// Add it to the map
[self.mapView addOverlay:_routeOverlay];
}
- (MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay
{
MKPolylineRenderer *renderer = [[MKPolylineRenderer alloc] initWithPolyline:overlay];
renderer.strokeColor = _toLocation ? [UIColor orangeColor] : [UIColor greenColor];
renderer.lineWidth = 4.0;
return renderer;
}
// DELGATE THAT RUNS TO SHOW CURRENT USER LOCATION
- (void) locationManager:(CLLocationManager *)manager didFailWithError:(nonnull NSError *)error {
NSLog(#"Location Services Error: %#", [error description]);
[[LoggingManager sharedReporting] addReportToLog:[NSString stringWithFormat:#"Mapping: locationManager:didFailWithError: %#",[error description] ]];
}
- (void) locationManager:(CLLocationManager *)manager didUpdateLocations: (NSArray *)locations {
currentLocation = [locations lastObject];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
currentLocation = newLocation;
}
#pragma mark - GET TO AND CURRENT POINTS
- (NSString*) getDestination {
NSDictionary * desDict = _toLocation ? self.dropoffLocation : self.pickupLocation;
NSString * address = #"";
if ([[desDict objectForKey:#"lat"] length] > 0 && [[desDict objectForKey:#"lon"] length] > 0) {
address = [NSString stringWithFormat:#"%#,%#",[desDict objectForKey:#"lat"], [desDict objectForKey:#"lon"]];
} else if ([desDict[#"address"] length] > 0 && [desDict[#"address"] rangeOfString:#"{"].location == NSNotFound) {
address = [desDict objectForKey:#"address"];
} else {
address = #"NULL";
}
return address;
}
- (NSString*) getCurrentLocation {
return [NSString stringWithFormat:#"%f,%f", currentLocation.coordinate.latitude, currentLocation.coordinate.longitude];
}
- (MyAnnotation*) getCurrentLocationAnnotation {
MyAnnotation * ann = [[MyAnnotation alloc] init];
CLLocationCoordinate2D location = CLLocationCoordinate2DMake(currentLocation.coordinate.latitude, currentLocation.coordinate.longitude);
[ann setCoordinate:location];
ann.title = #"My Current Location";
ann.subtitle = #"";
return ann;
}
#end
The problem is that you are setting the map's visible region by calling showAnnotations. This conflicts with the user zooming.
So I am trying to GeoCode an address and when someone types in "asdfsfdsf" it throws an error
"kCLErrorGeocodeFoundNoResult"
How can I catch the error so it doesn't show an ugly popup (i.e. with the error above) to the user?
-(void)geocodePinAddress:(NSString *)address withBlock:(void (^)(CLLocationCoordinate2D coord))block {
CLGeocoder* gc = [[CLGeocoder alloc] init];
__block CLLocationCoordinate2D coord;
[gc geocodeAddressString:address completionHandler: ^(NSArray *placemarks, NSError *error) {
// Check for returned placemarks
if (placemarks && placemarks.count > 0) {
CLPlacemark* mark = [placemarks objectAtIndex:0];
coord = mark.location.coordinate;
block(coord);
}
}];
}
Here is how you can handle geocoder domain errors :
if(placemarks.count > 0)
{
CLPlacemark *placemark = [placemarks objectAtIndex:0];
self.outputLabel.text = placemark.location.description;
}
else if (error.domain == kCLErrorDomain)
{
switch (error.code)
{
case kCLErrorDenied:
self.outputLabel.text = #"Location Services Denied by User";
break;
case kCLErrorNetwork:
self.outputLabel.text = #"No Network";
break;
case kCLErrorGeocodeFoundNoResult:
self.outputLabel.text = #"No Result Found";
break;
default:
self.outputLabel.text = error.localizedDescription;
break;
}
}
Why not just show the message if an error occurs?
- (void)geocodePinAddress:(NSString *)address withBlock:(void (^)(CLLocationCoordinate2D coord))block {
CLGeocoder *gc = [[CLGeocoder alloc] init];
__block CLLocationCoordinate2D coord;
[gc geocodeAddressString:address completionHandler: ^(NSArray *placemarks, NSError *error) {
// if there was some error geocoding
if (error) {
// display whatever message you want, however you want, here
return;
}
// Check for returned placemarks
if (placemarks && placemarks.count > 0) {
CLPlacemark* mark = [placemarks objectAtIndex:0];
coord = mark.location.coordinate;
block(coord);
}
}];
}
I want to pass information about the location of the user to another function which uses it. The delegate class MyLocation is a singleton which stores this information.
But in my code the didUpdateToLocation never gets called . Should n't it be called at least once whenever startUpdatingLocation is called even if the device is stationary?
I did check if locationmanager.location.coordinate.latitude and locationmanager.location.coordinate.longitude have the right values and they do. The location services are enabled and the user permission to access location services is also granted. I am still building for iOS 5. None of the previously given solutions seem to work for me!
Can someone please give me some idea as to why it is not working?
The code is as follows:
CLLocationManager *locationManager;
CLGeocoder *geocoder;
CLPlacemark *placemark;
#implementation MyLocation {
}
+ (id)getInstance {
static MyLocation *sharedMyLocation = nil;
static int i=0;
if(i==0){
sharedMyLocation = [[MyLocation alloc] init];
i=1;
}
return sharedMyLocation;
}
- (id)init {
if (self = [super init]) {
latitude = [[NSString alloc] init];
longitude = [[NSString alloc] init];
country = [[NSString alloc] init];
admin_area = [[NSString alloc] init];
postal_code = [[NSString alloc] init];
locality = [[NSString alloc] init];
subtfare = [[NSString alloc] init];
tfare = [[NSString alloc] init];
}
return self;
}
- (void) startupdate{
if(locationManager == nil)
{
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
}
if(geocoder == nil)
geocoder = [[CLGeocoder alloc] init];
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
{
NSLog(#"didFailWithError: %#", error);
}
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"didUpdateToLocation: %#", newLocation);
CLLocation *currentLocation = newLocation;
if(currentLocation != nil){
longitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.longitude];
latitude = [NSString stringWithFormat:#"%.8f", currentLocation.coordinate.latitude];
}
[locationManager stopUpdatingLocation];
// Reverse Geocoding
NSLog(#"Resolving the Address");
[geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"Found placemarks: %#, error: %#", placemarks, error);
if (error == nil && [placemarks count] > 0) {
placemark = [placemarks lastObject];
country = [NSString stringWithFormat:#"%#",placemark.country];
admin_area = [NSString stringWithFormat:#"%#",placemark.administrativeArea];
postal_code = [NSString stringWithFormat:#"%#",placemark.postalCode];
locality = [NSString stringWithFormat:#"%#",placemark.locality];
subtfare = [NSString stringWithFormat:#"%#",placemark.subThoroughfare];
tfare = [NSString stringWithFormat:#"%#",placemark.thoroughfare];
} else {
NSLog(#"%#", error.debugDescription);
}
} ];
}
- (NSString*) getLatitude
{
return latitude;
}
- (NSString*) getLongitude
{
return longitude;
}
- (NSString*) getCountry
{
return country;
}
- (NSString*) getAdminArea
{
return admin_area;
}
- (NSString*) getPostalCode
{
return postal_code;
}
- (NSString*) getLocality
{
return locality;
}
- (NSString*) getSubTFare
{
return subtfare;
}
- (NSString*) getTFare
{
return tfare;
}
error GPS_INTERFACE::getLatitude(char* buffer , unsigned int len)
{
id temp = [MyLocation getInstance];
[temp startupdate];
NSString* tempbuf = [temp getLatitude];
NSString *l = [NSString stringWithFormat:#"%#",tempbuf];
const char* lati= [l UTF8String];
if(strlen(lati) < len)
std::strncpy(buffer,lati,[l length]);
else
return Buffer_Insufficent;
return No_Error;
}
/* other similar getter functions! */
How can I get latitude and longitude from a full address (street, city, etc.) input by the user, using the iPhone SDK 3.x?
Here's an updated, more compact, version of unforgiven's code, which uses the latest v3 API:
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address
{
double latitude = 0, longitude = 0;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result) {
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil]) {
[scanner scanDouble:&latitude];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil]) {
[scanner scanDouble:&longitude];
}
}
}
CLLocationCoordinate2D center;
center.latitude = latitude;
center.longitude = longitude;
return center;
}
It makes the assumption that the coordinates for "location" come first, e.g. before those for "viewport", because it just takes the first coords it finds under the "lng" and "lat" keys. Feel free to use a proper JSON scanner (e.g. SBJSON) if you are worried about this simple scanning technique used here.
You can use Google Geocoding for this. It is as simple as getting data through HTTP and parsing it (it can return JSON KML, XML, CSV).
Here's a similar solution for obtaining the latitude and longitude from Google. Note: This example uses the SBJson library, which you can find on github:
+ (CLLocationCoordinate2D) geoCodeUsingAddress: (NSString *) address
{
CLLocationCoordinate2D myLocation;
// -- modified from the stackoverflow page - we use the SBJson parser instead of the string scanner --
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat: #"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSDictionary *googleResponse = [[NSString stringWithContentsOfURL: [NSURL URLWithString: req] encoding: NSUTF8StringEncoding error: NULL] JSONValue];
NSDictionary *resultsDict = [googleResponse valueForKey: #"results"]; // get the results dictionary
NSDictionary *geometryDict = [ resultsDict valueForKey: #"geometry"]; // geometry dictionary within the results dictionary
NSDictionary *locationDict = [ geometryDict valueForKey: #"location"]; // location dictionary within the geometry dictionary
// -- you should be able to strip the latitude & longitude from google's location information (while understanding what the json parser returns) --
DLog (#"-- returning latitude & longitude from google --");
NSArray *latArray = [locationDict valueForKey: #"lat"]; NSString *latString = [latArray lastObject]; // (one element) array entries provided by the json parser
NSArray *lngArray = [locationDict valueForKey: #"lng"]; NSString *lngString = [lngArray lastObject]; // (one element) array entries provided by the json parser
myLocation.latitude = [latString doubleValue]; // the json parser uses NSArrays which don't support "doubleValue"
myLocation.longitude = [lngString doubleValue];
return myLocation;
}
Update version, using iOS JSON:
- (CLLocationCoordinate2D)getLocation:(NSString *)address {
CLLocationCoordinate2D center;
NSString *esc_addr = [address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSData *responseData = [[NSData alloc] initWithContentsOfURL:
[NSURL URLWithString:req]]; NSError *error;
NSMutableDictionary *responseDictionary = [NSJSONSerialization
JSONObjectWithData:responseData
options:nil
error:&error];
if( error )
{
NSLog(#"%#", [error localizedDescription]);
center.latitude = 0;
center.longitude = 0;
return center;
}
else {
NSArray *results = (NSArray *) responseDictionary[#"results"];
NSDictionary *firstItem = (NSDictionary *) [results objectAtIndex:0];
NSDictionary *geometry = (NSDictionary *) [firstItem objectForKey:#"geometry"];
NSDictionary *location = (NSDictionary *) [geometry objectForKey:#"location"];
NSNumber *lat = (NSNumber *) [location objectForKey:#"lat"];
NSNumber *lng = (NSNumber *) [location objectForKey:#"lng"];
center.latitude = [lat doubleValue];
center.longitude = [lng doubleValue];
return center;
}
}
The following method does what you asked for. You need to insert your Google maps key for this to work correctly.
- (CLLocationCoordinate2D) geoCodeUsingAddress:(NSString *)address{
int code = -1;
int accuracy = -1;
float latitude = 0.0f;
float longitude = 0.0f;
CLLocationCoordinate2D center;
// setup maps api key
NSString * MAPS_API_KEY = #"YOUR GOOGLE MAPS KEY HERE";
NSString *escaped_address = [address stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
// Contact Google and make a geocoding request
NSString *requestString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv&oe=utf8&key=%#&sensor=false&gl=it", escaped_address, MAPS_API_KEY];
NSURL *url = [NSURL URLWithString:requestString];
NSString *result = [NSString stringWithContentsOfURL: url encoding: NSUTF8StringEncoding error:NULL];
if(result){
// we got a result from the server, now parse it
NSScanner *scanner = [NSScanner scannerWithString:result];
[scanner scanInt:&code];
if(code == 200){
// everything went off smoothly
[scanner scanString:#"," intoString:nil];
[scanner scanInt:&accuracy];
//NSLog(#"Accuracy: %d", accuracy);
[scanner scanString:#"," intoString:nil];
[scanner scanFloat:&latitude];
[scanner scanString:#"," intoString:nil];
[scanner scanFloat:&longitude];
center.latitude = latitude;
center.longitude = longitude;
return center;
}
else{
// the server answer was not the one we expected
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle: #"Warning"
message:#"Connection to Google Maps failed"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil] autorelease];
[alert show];
center.latitude = 0.0f;
center.longitude = 0.0f;
return center;
}
}
else{
// no result back from the server
UIAlertView *alert = [[[UIAlertView alloc]
initWithTitle: #"Warning"
message:#"Connection to Google Maps failed"
delegate:nil
cancelButtonTitle:nil
otherButtonTitles:#"OK", nil] autorelease];
[alert show];
center.latitude = 0.0f;
center.longitude = 0.0f;
return center;
}
}
center.latitude = 0.0f;
center.longitude = 0.0f;
return center;
}
For the google map key solution, as described by unforgiven above, doesn't one has to make the app free? As per google terms & conditions: 9.1 Free, Public Accessibility to Your Maps API Implementation. Your Maps API Implementation must be generally accessible to users without charge.
With map kit in sdk 3.0 this is easily done using the SDK. See apple's manuals or follow: https://developer.apple.com/documentation/mapkit
There's also CoreGeoLocation, which wraps up the functionality in a framework (Mac) or static library (iPhone). Supports lookups through Google or Yahoo, if you have a preference for one over the other.
https://github.com/thekarladam/CoreGeoLocation
- (void)viewDidLoad
{
app=(AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(#"%#", app.str_address);
NSLog(#"internet connect");
NSString *Str_address=_txt_zipcode.text;
double latitude1 = 0, longitude1 = 0;
NSString *esc_addr = [ Str_address stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *req = [NSString stringWithFormat:#"http://maps.google.com/maps/api/geocode/json?sensor=false&address=%#", esc_addr];
NSString *result = [NSString stringWithContentsOfURL:[NSURL URLWithString:req] encoding:NSUTF8StringEncoding error:NULL];
if (result)
{
NSScanner *scanner = [NSScanner scannerWithString:result];
if ([scanner scanUpToString:#"\"lat\" :" intoString:nil] && [scanner scanString:#"\"lat\" :" intoString:nil])
{
[scanner scanDouble:&latitude1];
if ([scanner scanUpToString:#"\"lng\" :" intoString:nil] && [scanner scanString:#"\"lng\" :" intoString:nil])
{
[scanner scanDouble:&longitude1];
}
}
}
//in #.hfile
// CLLocationCoordinate2D lat;
// CLLocationCoordinate2D lon;
// float address_latitude;
// float address_longitude;
lat.latitude=latitude1;
lon.longitude=longitude1;
address_latitude=lat.latitude;
address_longitude=lon.longitude;
}
func geoCodeUsingAddress(address: NSString) -> CLLocationCoordinate2D {
var latitude: Double = 0
var longitude: Double = 0
let addressstr : NSString = "http://maps.google.com/maps/api/geocode/json?sensor=false&address=\(address)" as NSString
let urlStr = addressstr.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
let searchURL: NSURL = NSURL(string: urlStr! as String)!
do {
let newdata = try Data(contentsOf: searchURL as URL)
if let responseDictionary = try JSONSerialization.jsonObject(with: newdata, options: []) as? NSDictionary {
print(responseDictionary)
let array = responseDictionary.object(forKey: "results") as! NSArray
let dic = array[0] as! NSDictionary
let locationDic = (dic.object(forKey: "geometry") as! NSDictionary).object(forKey: "location") as! NSDictionary
latitude = locationDic.object(forKey: "lat") as! Double
longitude = locationDic.object(forKey: "lng") as! Double
}} catch {
}
var center = CLLocationCoordinate2D()
center.latitude = latitude
center.longitude = longitude
return center
}