MapKit Annotations Appear in One View Controller, and not in another - ios

In my browse view controller, the Map Kit annotations show up.
_mapVC = [[CollectionMapViewController alloc] init];
mapVC.collectedLeafArray = [collectionFetchedResultsController fetchedObjects];
mapVC.canShowCallout = YES;
mapVC.delegate = self;
[mapVC layoutMapView];
[self addChildViewController:mapVC];
[self.view insertSubview:mapVC.view belowSubview:_userCollectionSortMenu.view];
[mapVC didMoveToParentViewController:self];
I set up my child view controller the exact same way in my note taking view controller. However, they annotation pins don't show up.
_mapVC = [[CollectionMapViewController alloc] init];
_mapVC.collectedLeafArray = [NSArray arrayWithObject:_collectedLeaf];
_mapVC.delegate = self;
_mapVC.canShowCallout = NO;
[_mapVC layoutMapView];
[self addChildViewController:_mapVC];
[_scrollView addSubview:_mapVC.view];
[_mapVC didMoveToParentViewController:self];
I know the collected leaf is not nil, because I check the latitude in the CollectionMapViewController method that sets the annotations:
- (void)layoutMapView
{
NSMutableArray* leavesWithValidGeotag = [[NSMutableArray alloc] initWithCapacity:[collectedLeafArray count]];
for (CollectedLeaf* collectedLeaf in collectedLeafArray)
{
NSLog(#"latitude: %#", collectedLeaf.latitude);
if ( ![collectedLeaf.latitude isEqualToString:kGeoLocationNotAvailable] )
{
[leavesWithValidGeotag addObject:collectedLeaf];
LeafAnnotation* annotation = [[LeafAnnotation alloc] initWithLeaf:collectedLeaf];
[mapView addAnnotation:annotation];
[annotation release];
}
}
//// Adjust the region
if([leavesWithValidGeotag count] > 1)
{
NSArray* westEastSort = [leavesWithValidGeotag sortedArrayUsingSelector:#selector(longitudeCompare:)];
CollectedLeaf* eastMostLeaf = [westEastSort objectAtIndex:0];
CollectedLeaf* westMostLeaf = [westEastSort lastObject];
NSArray* southNorthSort = [leavesWithValidGeotag sortedArrayUsingSelector:#selector(latitudeCompare:)];
CollectedLeaf* southMostLeaf = [southNorthSort objectAtIndex:0];
CollectedLeaf* northMostLeaf = [southNorthSort lastObject];
CLLocationCoordinate2D center;
center.longitude = ([westMostLeaf.longitude doubleValue] + [eastMostLeaf.longitude doubleValue]) / 2.0f;
center.latitude = ([southMostLeaf.latitude doubleValue] + [northMostLeaf.latitude doubleValue]) / 2.0f;
MKCoordinateSpan span = MKCoordinateSpanMake(1.5 * fabs([northMostLeaf.latitude doubleValue] - [southMostLeaf.latitude doubleValue]),
1.5 * fabs([westMostLeaf.longitude doubleValue] - [eastMostLeaf.longitude doubleValue]));
if ( span.latitudeDelta < kMinimumSpan )
{
span.latitudeDelta = kMinimumSpan;
}
if ( span.longitudeDelta < kMinimumSpan )
{
span.longitudeDelta = kMinimumSpan;
}
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
[mapView setRegion:region];
}
else if([leavesWithValidGeotag count] == 1)
{
CollectedLeaf* theLeaf = [leavesWithValidGeotag objectAtIndex:0];
CLLocationCoordinate2D center;
center.longitude = [theLeaf.longitude doubleValue];
center.latitude = [theLeaf.latitude doubleValue];
MKCoordinateSpan span = MKCoordinateSpanMake(kMinimumSpan, kMinimumSpan);
MKCoordinateRegion region = MKCoordinateRegionMake(center, span);
[mapView setRegion:region];
}
[leavesWithValidGeotag release];
}

Maybe, you need to copy NSArray object.
NSArray *test1 = [NSArray arrayWithObject:_collectedLeaf];
_mapVC.collectedLeafArray = [test1 copy];

Related

How to add Coordinates to CLLocationCoordinate2D from Dynamic NSMutableArray?

I have a MapView in which I would like to add annotations and a route from defined coordinates that I add from a Textfield and store in an NSMutableArray.
Now I'm able to show the route from multiple coordinates but only when I insert them in my code as follow :
-(void)loadMap{
int Coordinates;
//MAP
CLLocationCoordinate2D coordinateArray[Coordinates];
coordinateArray[0] = CLLocationCoordinate2DMake(LatA, LongA);
coordinateArray[1] = CLLocationCoordinate2DMake(LatB, LongB);
coordinateArray[2] = CLLocationCoordinate2DMake(LatC, LongC);
coordinateArray[3] = CLLocationCoordinate2DMake(LatD, LongD);
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:Coordinates];
[MapViewHome setVisibleMapRect:[self.routeLine boundingMapRect]]; //If you want the route to be visible
[MapViewHome addOverlay:self.routeLine];
MapViewHome.mapType = MKMapTypeHybrid;
[self zoomToFitMapAnnotations:MapViewHome];
}
To Add Annotations I do this:
-(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id<MKOverlay>)overlay
{
if(overlay == self.routeLine)
{
if(nil == self.routeLineView)
{
self.routeLineView = [[MKPolylineView alloc] initWithPolyline:self.routeLine];
self.routeLineView.fillColor = [UIColor purpleColor];
self.routeLineView.strokeColor = [UIColor purpleColor];
self.routeLineView.lineWidth = 5;
}
return self.routeLineView;
}
return nil;
}
-(void)AddAnotations{
DeparturePoint = [[MKPointAnnotation alloc] init];
DeparturePoint.coordinate = CLLocationCoordinate2DMake(LatA, LongA);
DeparturePoint.title = [NSString stringWithFormat:#"A"];
[MapViewHome addAnnotation:DeparturePoint];
ArrivalPoint = [[MKPointAnnotation alloc] init];
ArrivalPoint.coordinate = CLLocationCoordinate2DMake(LatB, LongB);
ArrivalPoint.title = [NSString stringWithFormat:#"B"];
[MapViewHome addAnnotation:ArrivalPoint];
C = [[MKPointAnnotation alloc] init];
C.coordinate = CLLocationCoordinate2DMake(LatC, LongC);
C.title = [NSString stringWithFormat:#"C"];
[MapViewHome addAnnotation:C];
D = [[MKPointAnnotation alloc] init];
D.coordinate = CLLocationCoordinate2DMake(LatD, LongD);
D.title = [NSString stringWithFormat:#"D"];
[MapViewHome addAnnotation:D];
}
NOW I would like to get Insert my Dynamic NSMutableArray in the LoadMap function in order to refresh the mapView and get a longer Route ! Any Idea ?
Here's the first solution I could think of...
First we wrap the CLLocationCoordinate2D into an object. For this I've made a wrapper class called KBLocationWrapper. Here's the interface:
#interface KBLocationWrapper : NSObject
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#end
Next generate the NSMutableArray ...
NSMutableArray *locationCoordinatesArray = [NSMutableArray array];
Then add each coordinate to the array via the object wrapper...
KBLocationWrapper *locationWrapper = [[KBLocationWrapper alloc] init];
locationWrapper.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[locationCoordinatesArray addObject:locationWrapper];
Finally, figure out how you're going to get the locationCoordinatesArray into the -loadMap method, and then loop through each object and map the coordinate property to its respective place in coordinateArray... (I would write a separate method for this functionality, but for demonstration purposes it's going straight into -loadMap)
-(void)loadMap{
....
int Coordinates = (int)[locationCoordinatesArray count];
CLLocationCoordinate2D coordinateArray[Coordinates];
// loop through coordinates
for (int i = 0; i < Coordinates; ++i) {
// write data from the CLLocationCoordinate2D stored in the wrapper
// to the primitive data array 'coordinateArray'
coordinateArray[i] = [locationCoordinatesArray[i] coordinate];
}
// then generate the routeLine.
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:Coordinates];
...
}
I add an object to NSMutableArray "NSLat" when i Unwind from another ViewController:
- (IBAction)UnwindPoiint:(UIStoryboardSegue *)segue {
float latitude;
float longitude;
NSString*PointName;
NSString*coordinates;
AddPointViewController *messageViewController = segue.sourceViewController;
PointName = messageViewController.PointBack;
latitude = [messageViewController.PointLatitude floatValue];
longitude = [messageViewController.PointLongitude floatValue];
KBLocationWrapper *locationWrapper = [[KBLocationWrapper alloc] init];
locationWrapper.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
[NSLat addObject:locationWrapper];
coordinates = [NSString stringWithFormat:#"%f,%f,%#",latitude,longitude,PointName];
// [NSLat addObject:coordinates];
[self AddAnotations];
[self loadMap];
[FlightLogTable reloadData];
NSLog(#"%#",coordinates);
NSLog(#"%lu",(unsigned long)NSLat.count);
}
And I add Annotations & load Map as filed :
-(void)AddAnotations{
for(int idx = 0; idx < NSLat.count; idx++)
{
// break the string down even further to latitude and longitude fields.
NSString* currentPointString = [NSLat objectAtIndex:idx];
NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]];
CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue];
CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];
NSString*Name = [NSString stringWithFormat:#"%#",[latLonArr objectAtIndex:2]];
DeparturePoint = [[MKPointAnnotation alloc] init];
DeparturePoint.coordinate = CLLocationCoordinate2DMake(latitude, longitude);
DeparturePoint.title = Name;
[MapViewHome addAnnotation:DeparturePoint];
}
[self loadMap];
}
-(void)zoomToFitMapAnnotations:(MKMapView*)mapView
{
if([mapView.annotations count] == 0)
return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKPointAnnotation*annotation in MapViewHome.annotations)
{
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 2; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 2; // Add a little extra space on the sides
region = [mapView regionThatFits:region];
[MapViewHome setRegion:region animated:YES];
}
-(void)loadMap{
int Coordinates = (int)[NSLat count];
CLLocationCoordinate2D coordinateArray[Coordinates];
// loop through coordinates
for (int i = 0; i < Coordinates; ++i) {
// write data from the CLLocationCoordinate2D stored in the wrapper
// to the primitive data array 'coordinateArray'
coordinateArray[i] = [NSLat[i] coordinate];
}
// then generate the routeLine.
self.routeLine = [MKPolyline polylineWithCoordinates:coordinateArray count:Coordinates];
[MapViewHome setVisibleMapRect:[self.routeLine boundingMapRect]]; //If you want the route to be visible
[MapViewHome addOverlay:self.routeLine];
MapViewHome.mapType = MKMapTypeHybrid;
[self zoomToFitMapAnnotations:MapViewHome];
}

Draw route directions using Google Maps iOS

I am getting a GMSPolyline to custom location but I am not getting a route direction (GMSPolyline) from user location to some custom location.
What I have done is placed a GMSMapView and kept core location. I am updating the route in core location delegate method (locationManager: didUpdateLocations:).
I want to use Google Maps for iOS SDK since Apple Maps don't have directions in the country I need. My code is below:
- (void)viewDidLoad
{
[super viewDidLoad];
waypointStrings_ = [[NSMutableArray alloc]init];
GMSCameraPosition *camera = [GMSCameraPosition cameraWithLatitude:self.latitude longitude:self.longitude zoom:13];
mapView_ = [GMSMapView mapWithFrame:CGRectZero camera:camera];
mapView_.myLocationEnabled = YES;
self.view = mapView_;
CLLocationManager *locManager = [[CLLocationManager alloc] init];
if ( [CLLocationManager locationServicesEnabled] ) {
[locManager setDelegate:self];
[locManager setDesiredAccuracy:kCLLocationAccuracyBest];
[locManager startUpdatingLocation];
}
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
CLLocationCoordinate2D userCoordinate = [[locations lastObject] coordinate];
GMSMarker *marker = [GMSMarker markerWithPosition:CLLocationCoordinate2DMake(self.latitude,self.longitude)];
marker.map = mapView_;
NSString *majlisPositionString = [[NSString alloc] initWithFormat:#"%f,%f", self.latitude,self.longitude];
[waypointStrings_ addObject:majlisPositionString];
GMSMarker *userMarker = [GMSMarker markerWithPosition:CLLocationCoordinate2DMake(userCoordinate.latitude, userCoordinate.longitude)];
userMarker.map = mapView_;
NSString *userPositionString = [[NSString alloc] initWithFormat:#"%f,%f", userCoordinate.latitude, userCoordinate.longitude];
[waypointStrings_ addObject:userPositionString];
NSString *sensor = #"false";
NSArray *parameters = [NSArray arrayWithObjects:sensor, waypointStrings_, nil];
NSArray *keys = [NSArray arrayWithObjects:#"sensor", #"waypoints", nil];
NSDictionary *query = [NSDictionary dictionaryWithObjects:parameters forKeys:keys];
MDDirectionService *mds=[[MDDirectionService alloc] init];
SEL selector = #selector(addDirections:);
[mds setDirectionsQuery:query withSelector:selector withDelegate:self];
}
- (void)addDirections:(NSDictionary *)json {
NSDictionary *routes = [json objectForKey:#"routes"][0];
NSDictionary *route = [routes objectForKey:#"overview_polyline"];
NSString *overview_route = [route objectForKey:#"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:overview_route];
GMSPolyline *polyline = [GMSPolyline polylineWithPath:path];
polyline.map = mapView_;
}
-(void)LoadMapRoute:(NSString*)SourceAddress andDestinationAddress:(NSString*)DestinationAdds
{
NSString *strUrl;
strUrl= [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false",SourceAddress,DestinationAdds];
strUrl=[strUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *data =[NSData dataWithContentsOfURL:[NSURL URLWithString:strUrl]];
NSError* error;
if (data) {
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data //1
options:kNilOptions
error:&error];
NSArray *arrRouts=[json objectForKey:#"routes"];
if ([arrRouts isKindOfClass:[NSArray class]]&&arrRouts.count==0) {
[self zoomToFitMapAnnotations:self.mapView];
return;
}
CLLocationCoordinate2D coordinates[2];
coordinates[0].latitude = [[CommonUtils checkNullString:[AppDelegate getAppDelegate].strLatitude] doubleValue];Current loaction latitude.
coordinates[0].longitude = [[CommonUtils checkNullString:[AppDelegate getAppDelegate].strLongitude] doubleValue];//Current loaction longitude.
coordinates[1].latitude = [[CommonUtils checkNullString:latitute] doubleValue];
coordinates[1].longitude = [[CommonUtils checkNullString:longitude] doubleValue];
if (CLLocationCoordinate2DIsValid(coordinates[1]) && CLLocationCoordinate2DIsValid(coordinates[0]))
{
//NSLog(#"Coordinate valid");
self.mapView.delegate=self;
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:coordinates[0].latitude longitude:coordinates[0].longitude];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:coordinates[1].latitude longitude:coordinates[1].longitude];
CLLocationDistance kilometers = [location1 distanceFromLocation:location2] / 1000;
//NSLog(#"%f",kilometers);
self.lblRideViewkilometer.text=[NSString stringWithFormat:#"%f KM",kilometers];
// //NSLog(#"Distance i meters: %f", [location1 distanceFromLocation:location2]);
// self.polyline = [MKPolyline polylineWithCoordinates:coordinates count:2];
// [self.mapView setVisibleMapRect:[self.polyline boundingMapRect]];
//
//
// //If you want the route to be visible
// [self.mapView addOverlay:self.polyline];
} else {
//NSLog(#"Coordinate invalid");
}
NSArray* arrpolyline = [[[json valueForKeyPath:#"routes.legs.steps.polyline.points"] objectAtIndex:0] objectAtIndex:0]; //2
double srcLat=[[[[json valueForKeyPath:#"routes.legs.start_location.lat"] objectAtIndex:0] objectAtIndex:0] doubleValue];
double srcLong=[[[[json valueForKeyPath:#"routes.legs.start_location.lng"] objectAtIndex:0] objectAtIndex:0] doubleValue];
double destLat=[[[[json valueForKeyPath:#"routes.legs.end_location.lat"] objectAtIndex:0] objectAtIndex:0] doubleValue];
double destLong=[[[[json valueForKeyPath:#"routes.legs.end_location.lng"] objectAtIndex:0] objectAtIndex:0] doubleValue];
CLLocationCoordinate2D sourceCordinate = CLLocationCoordinate2DMake(srcLat, srcLong);
CLLocationCoordinate2D destCordinate = CLLocationCoordinate2DMake(destLat, destLong);
[self addAnnotationSrcAndDestination:sourceCordinate :destCordinate andAdds:nil andDestinationAddress:DestinationAdds];
// NSArray *steps=[[aary objectAtIndex:0]valueForKey:#"steps"];
// replace lines with this may work
polyLinesArray =[[NSMutableArray alloc]initWithCapacity:0];
for (int i = 0; i < [arrpolyline count]; i++)
{
NSString* encodedPoints = [arrpolyline objectAtIndex:i] ;
MKPolyline *route = [self polylineWithEncodedString:encodedPoints];
[polyLinesArray addObject:route];
}
self.polyline = [MKPolyline polylineWithCoordinates:coordinates count:2];
[self.mapView setVisibleMapRect:[self.polyline boundingMapRect]];
[self.mapView addOverlays:polyLinesArray];
self.mapView.delegate = self;
[self zoomToFitMapAnnotations:self.mapView];
}else{
// [self.btnDirection setEnabled:NO];
// [self ShowAlert:#"didn't find direction"];
}
}-(void)addAnnotationSrcAndDestination :(CLLocationCoordinate2D )srcCord :(CLLocationCoordinate2D)destCord andAdds:(NSString*)SourceAddress andDestinationAddress:(NSString*)DestinationAdds
{
MKPointAnnotation *sourceAnnotation = [[MKPointAnnotation alloc]init];
destAnnotation = [[MKPointAnnotation alloc]init];
sourceAnnotation.coordinate=srcCord;
destAnnotation.coordinate=destCord;
sourceAnnotation.title=SourceAddress;
CLLocation *LocationAtual = [[CLLocation alloc] initWithLatitude:destCord.latitude longitude:destCord.longitude];
CLGeocoder *geocoder = [[CLGeocoder alloc] init] ;
[geocoder reverseGeocodeLocation:LocationAtual
completionHandler:^(NSArray *placemarks, NSError *error)
{
if (error){
//NSLog(#"Geocode failed with error: %#", error);
return;
}
CLPlacemark *placemark = [placemarks objectAtIndex:0];
//NSLog(#"placemark.ISOcountryCode %#",placemark.ISOcountryCode);
//NSLog(#"locality %#",placemark.subLocality);
//NSLog(#"postalCode %#",placemark.postalCode);
destAnnotation.title=[NSString stringWithFormat:#"%# %# ",placemark.name,placemark.locality];
// [self.mapView.userLocation setTitle:[NSString stringWithFormat:#"%# %# ",placemark.name,placemark.locality]];
}];
// destAnnotation.title=DestinationAdds;
//destAnnotation.title=[NSString stringWithFormat:#"%#,%#,%#",[self.dictRetailerInfo objectForKey:#"street_address1"],[self.dictRetailerInfo objectForKey:#"city"],[self.dictRetailerInfo objectForKey:#"country"]];
// destAnnotation.title=nil;
[self.mapView addAnnotation:sourceAnnotation];
[self.mapView addAnnotation:destAnnotation];
}
- (MKPolyline *)polylineWithEncodedString:(NSString *)encodedString {
const char *bytes = [encodedString UTF8String];
NSUInteger length = [encodedString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
NSUInteger idx = 0;
NSUInteger count = length / 4;
CLLocationCoordinate2D *coords = calloc(count, sizeof(CLLocationCoordinate2D));
NSUInteger coordIdx = 0;
float latitude = 0;
float longitude = 0;
while (idx < length) {
char byte = 0;
int res = 0;
char shift = 0;
do {
byte = bytes[idx++] - 63;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLat = ((res & 1) ? ~(res >> 1) : (res >> 1));
latitude += deltaLat;
shift = 0;
res = 0;
do {
byte = bytes[idx++] - 0x3F;
res |= (byte & 0x1F) << shift;
shift += 5;
} while (byte >= 0x20);
float deltaLon = ((res & 1) ? ~(res >> 1) : (res >> 1));
longitude += deltaLon;
float finalLat = latitude * 1E-5;
float finalLon = longitude * 1E-5;
CLLocationCoordinate2D coord = CLLocationCoordinate2DMake(finalLat, finalLon);
coords[coordIdx++] = coord;
if (coordIdx == count) {
NSUInteger newCount = count + 10;
coords = realloc(coords, newCount * sizeof(CLLocationCoordinate2D));
count = newCount;
}
}
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coords count:coordIdx];
free(coords);
return polyline;
}
-(void)zoomToFitMapAnnotations:(MKMapView*)aMapView
{
if([aMapView.annotations count] == 0)
return;
CLLocationCoordinate2D topLeftCoord;
topLeftCoord.latitude = -90;
topLeftCoord.longitude = 180;
CLLocationCoordinate2D bottomRightCoord;
bottomRightCoord.latitude = 90;
bottomRightCoord.longitude = -180;
for(MKPointAnnotation *annotation in self.mapView.annotations)
{
if (![[annotation class] isEqual:[MKUserLocation class]]) {
topLeftCoord.longitude = fmin(topLeftCoord.longitude, annotation.coordinate.longitude);
topLeftCoord.latitude = fmax(topLeftCoord.latitude, annotation.coordinate.latitude);
bottomRightCoord.longitude = fmax(bottomRightCoord.longitude, annotation.coordinate.longitude);
bottomRightCoord.latitude = fmin(bottomRightCoord.latitude, annotation.coordinate.latitude);
}
}
MKCoordinateRegion region;
region.center.latitude = topLeftCoord.latitude - (topLeftCoord.latitude - bottomRightCoord.latitude) * 0.5;
region.center.longitude = topLeftCoord.longitude + (bottomRightCoord.longitude - topLeftCoord.longitude) * 0.5;
region.span.latitudeDelta = fabs(topLeftCoord.latitude - bottomRightCoord.latitude) * 1.1; // Add a little extra space on the sides
region.span.longitudeDelta = fabs(bottomRightCoord.longitude - topLeftCoord.longitude) * 1.1; // Add a little extra space on the sides
region = [aMapView regionThatFits:region];
[self.mapView setRegion:region animated:YES];
mapZoom=YES;
}
//- (void)mapView:(MKMapView *)mv didAddAnnotationViews:(NSArray *)views
//{
// MKMapRect zoomRect = MKMapRectNull;
// for (id <MKAnnotation> annotation in mv.annotations)
// {
// MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
// MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0.1, 0.1);
// zoomRect = MKMapRectUnion(zoomRect, pointRect);
// }
// [mv setVisibleMapRect:zoomRect animated:YES];
//}
- (void)moveMapToLocation:(CLLocation*)tmpLocation {
CLLocationDistance visibleDistance = 1000; // 1 kilometers
MKCoordinateRegion viewRegion = MKCoordinateRegionMakeWithDistance(tmpLocation.coordinate, visibleDistance, visibleDistance);
MKCoordinateRegion adjustedRegion = [self.mapView regionThatFits:viewRegion];
[self.mapView setRegion:adjustedRegion animated:YES];
}
var arrayPolyline = [GMSPolyline]()
var selectedRought:String!
func LoadMapRoute1()
{
let strUrl:String = "https://maps.googleapis.com/maps/api/directions/json?sensor=false&mode=driving&alternatives=true&origin=\(self.source.latitude),\(self.source.longitude)&destination=\(self.destination.latitude),\(self.destination.longitude)"
let escapedString = strUrl.replacingOccurrences(of: " ", with: "")
let url = URL(string: escapedString)
URLSession.shared.dataTask(with: url!, completionHandler:
{
(data, response, error) in
if(error != nil)
{
print("error")
}
else
{
do{
let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String : AnyObject]
let arrRouts = json["routes"] as! NSArray
for polyline in self.arrayPolyline
{
polyline.map = nil;
}
self.arrayPolyline.removeAll()
let pathForRought:GMSMutablePath = GMSMutablePath()
if (arrRouts.count == 0)
{
let distance:CLLocationDistance = CLLocation.init(latitude: self.source.latitude, longitude: self.source.longitude).distance(from: CLLocation.init(latitude: self.destination.latitude, longitude: self.destination.longitude))
pathForRought.add(self.source)
pathForRought.add(self.destination)
let polyline = GMSPolyline.init(path: pathForRought)
polyline.strokeWidth = 5
polyline.strokeColor = UIColor.blue
polyline.isTappable = true
self.arrayPolyline.append(polyline)
if (distance > 8000000)
{
polyline.geodesic = false
}
else
{
polyline.geodesic = true
}
polyline.map = self.mapView;
}
else
{
for (index, element) in arrRouts.enumerated()
{
let dicData:NSDictionary = element as! NSDictionary
let routeOverviewPolyline = dicData["overview_polyline"] as! NSDictionary
let path = GMSPath.init(fromEncodedPath: routeOverviewPolyline["points"] as! String)
let polyline = GMSPolyline.init(path: path)
polyline.isTappable = true
self.arrayPolyline.append(polyline)
polyline.strokeWidth = 5
if index == 0
{
polyline.strokeColor = UIColor.blue;
}
else
{
polyline.strokeColor = UIColor.darkGray;
}
polyline.geodesic = true;
}
for po in self.arrayPolyline.reversed()
{
po.map = self.mapView;
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
{
let bounds:GMSCoordinateBounds = GMSCoordinateBounds.init(path: GMSPath.init(fromEncodedPath: self.selectedRought)!)
self.mapView.animate(with: GMSCameraUpdate.fit(bounds))
}
}
catch let error as NSError
{
print("error:\(error)")
}
}
}).resume()
}

Need to showing screen that show both CLLocation pins

I have mapView that suppose to contain both user location pin and object pin. What i want, is show screen that contain both pins, no matter how large distance is between them (it suppose to be not too much). For some reason i can't show user location, screen moves to some point in the ocean. There is my code and attempts to get it:
-(MKCoordinateRegion)regionForAnnotations:(NSArray*)annotations{
MKCoordinateRegion region;
if ([annotations count] ==0){
region = MKCoordinateRegionMakeWithDistance(self.mapView.userLocation.coordinate, 1000, 1000);
} else if ([annotations count] ==1 ){
id <MKAnnotation> annotation = [annotations lastObject];
region = MKCoordinateRegionMakeWithDistance(annotation.coordinate, 1000, 1000);
} else {
CLLocationCoordinate2D topLeftCord;
topLeftCord.latitude = -90;
topLeftCord.longitude = 180;
CLLocationCoordinate2D bottomRightCord;
bottomRightCord.latitude = 90;
bottomRightCord.longitude = -180;
for (id <MKAnnotation> annotation in annotations){
topLeftCord.latitude = fmax(topLeftCord.latitude, annotation.coordinate.latitude);
topLeftCord.longitude = fmin(topLeftCord.longitude, annotation.coordinate.longitude);
bottomRightCord.latitude = fmin(bottomRightCord.latitude, annotation.coordinate.latitude);
bottomRightCord.longitude = fmax(bottomRightCord.longitude, annotation.coordinate.longitude);
}
const double extraSpace = 1.1;
region.center.longitude = topLeftCord.longitude - (topLeftCord.longitude - bottomRightCord.longitude)/2.0;
region.center.latitude = topLeftCord.latitude - (topLeftCord.latitude - bottomRightCord.latitude)/2.0;
region.span.latitudeDelta = fabs(topLeftCord.latitude - bottomRightCord.latitude)*extraSpace;
region.span.longitudeDelta = fabs(topLeftCord.longitude - bottomRightCord.longitude)*extraSpace;
}
return [self.mapView regionThatFits:region];
}
-(MKAnnotationView*)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
//2
static NSString *identifier = #"Location";
MKPinAnnotationView *annotationView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil){
annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:identifier];
}
//3
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.animatesDrop = YES;
annotationView.pinColor = MKPinAnnotationColorPurple;
//4
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(getRoute:) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = rightButton;
return annotationView;
};
-(void)setEntityCoordiate{
CLLocationCoordinate2D location;
location.latitude = [self.latitudeString doubleValue];
location.longitude = [self.longitudeString doubleValue];
CLLocationCoordinate2D user;
user.latitude = self.mapView.userLocation.coordinate.latitude;
user.latitude = self.mapView.userLocation.coordinate.longitude;
CLLocation *userLocation = [[CLLocation alloc]initWithLatitude:user.latitude longitude:user.longitude ];
CLLocation *entityLocation = [[CLLocation alloc]initWithLatitude:location.latitude longitude:location.longitude];
MKCoordinateSpan span;
span.latitudeDelta = 100;
span.longitudeDelta = 100;
MKCoordinateRegion region = MKCoordinateRegionMakeWithDistance(location, 400, 400);
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init];
annotation.coordinate = location;
annotation.title = _titleForEntity;
[_locations addObject:userLocation];
[_locations addObject:entityLocation];
[_mapView addAnnotation:annotation];
}
-(void)getRoute:(UIButton*)button{
MKCoordinateRegion region = [self regionForAnnotations:_locations];
[self.mapView setRegion:region animated:YES];
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self setEntityCoordiate];
}
There is might be "too much" code, but i can't figure out where i made mistake i paste it all. I think i might have problem with array containing location objects.
How to finally make screen with that two locations? Any advice would be appreciated, thanks!
Try creating an area flyTo that will "contain" your given annotations:
MKMapRect flyTo = MKMapRectNull;
for (id <MKAnnotation> annotation in annotations) {
MKMapPoint annotationPoint = MKMapPointForCoordinate(annotation.coordinate);
MKMapRect pointRect = MKMapRectMake(annotationPoint.x, annotationPoint.y, 0, 0);
if (MKMapRectIsNull(flyTo)) {
flyTo = pointRect;
} else {
flyTo = MKMapRectUnion(flyTo, pointRect);
}
}
mapview.visibleMapRect = flyTo;

iOS checking to see if annotation's coordinate is {0,0}

I have a loop statement that displays my annotations on the mapView from an array. How do I check to see if any of the coordinates in the array are 0,0, and if so, remove/dont plot them?
Thanks.
Code:
CLLocationCoordinate2D maxCoord = {45.60250f,-122.39181f};
CLLocationCoordinate2D minCoord = {45.35697f,-123.12789f};
NSArray *callsArray = [xmlParser calls];
for (JointCAD *call in callsArray) {
NSString *callnumber = [call.callnumber stringByAppendingFormat:#". "];
NSString *callandnumber = [callnumber stringByAppendingString:call.currentCallType];
CLLocationCoordinate2D newCoord = { [call.latitude doubleValue], [call.longitude doubleValue]};
if ([call.longitude doubleValue] > maxCoord.longitude)
{
maxCoord.longitude = [call.longitude doubleValue];
}
if ([call.latitude doubleValue] > maxCoord.latitude)
{
maxCoord.latitude = [call.latitude doubleValue];
}
if ([call.longitude doubleValue] < minCoord.longitude)
{
minCoord.longitude = [call.longitude doubleValue];
}
if ([call.latitude doubleValue] < minCoord.latitude)
{
minCoord.latitude = [call.latitude doubleValue];
}
Annotation *ann = [[Annotation alloc] init];
ann.title = callandnumber;
ann.subtitle = [call location];
ann.coordinate = newCoord;
[mapView addAnnotation:ann];
}
MKCoordinateRegion region = {{0.0f, 0.0f}, {0.0f, 0.0f}};
region.center.longitude = (minCoord.longitude + maxCoord.longitude) / 2.0;
region.center.latitude = (minCoord.latitude + maxCoord.latitude) / 2.0;
region.span.longitudeDelta = (maxCoord.longitude - minCoord.longitude) * 1.1;
region.span.latitudeDelta = (maxCoord.latitude - minCoord.latitude) * 1.1;
[mapView regionThatFits:region];
[self.mapView setRegion:region animated:YES];
[self setRefreshState:#"Finished"];
Hm why don't you just add a continue in your for loop when the coordinates are equal 0?
Before creating the Annotation object just add a simple
if(newCoord.latitude == 0 && newCoord.longitude == 0) continue;
continue simply skips to the next iteration of a loop.

Why "CLLocationCoordinate2D location2 = [self adressLocation“ isn't working

The code should do an adress search. The line CLLocationCoordinate2D location2 = [self adressLocation isn't working. It's saying "Invalid Initializer". What could be wrong?
-(IBAction) search {
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.4;
span.longitudeDelta = 0.4;
CLLocationCoordinate2D location2 = [self adressLocation];
region.span = span;
region.center = location2;
Mark adr = [[Mark alloc] initWithCoordinate:location2];
[mapView addAnnotation:adr];
}
-(CLLocationCoordinate2D) adressLocation {
NSString * urlString = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv",[suchFeld.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSString * locationString = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlString] encoding:NSUTF8StringEncoding error:&fileError];
NSArray * listItems = [locationString componentsSeparatedByString:#","];
double latitude2 = 0.0;
double longitude2 = 0.0;
if ([listItems count] >= 4 && [[listItems objectAtIndex:0] isEqualToString:#"200"])
{
latitude2 = [[listItems objectAtIndex:2] doubleValue];
longitude2 = [[listItems objectAtIndex:3] doubleValue];
} else {
// error
CLLocationCoordinate2D location2;
location2.latitude = latitude2;
location2.longitude = longitude2;
return location2;
}
The adressLocation method is probably not declared in the .h file and since the method is defined after the code calling it, the compiler gives that error. Add this to the .h file:
-(CLLocationCoordinate2D) adressLocation;
Some separate issues:
In the search method, you have Mark adr = [[Mark alloc]....
This should be Mark *adr = [[Mark alloc]... (note asterisk).
Also in the search method, you need to do [adr release]; after the addAnnotation line.
Finally, adressLocation does not return a value in all cases.
It only does a return in the else-part. It needs to return a value in the if-part also.

Resources