First, thank you, and next, it's my problem, the core code:
for(int idx = 0; idx < route0.polyLine.count; idx++)
{
CLLocationCoordinate2D coordinate = [[route0.polyLine objectAtIndex:idx] coordinate];
minLat = MIN(minLat, coordinate.latitude);
minLon = MIN(minLon, coordinate.longitude);
maxLat = MAX(maxLat, coordinate.latitude);
maxLon = MAX(maxLon, coordinate.longitude);
}
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 1.06f*(maxLat - minLat);
span.longitudeDelta = 1.06f*(maxLon - minLon);
CLLocationCoordinate2D location;
location.latitude = (minLat + maxLat)/2;
location.longitude = (minLon + maxLon)/2;
region.span=span;
region.center=location;
[_mapView regionThatFits:region];
[_mapView setRegion:region animated:false];
My attentio is let the annotations on the mapview just fit screen, but if the annotations is too close, will appear:
When I show UIViewController with UIMapView, in viewDidLoad I add PointAnnotation to map and to array. Then I calculate the region for these annotations and set that region to map.
The point is that sometimes (basically only once after installing app for the first time) the map shows region for equator even if my data is correct.
-(void)viewDidLoad
{
NSLog(#"Spot: %#", _spot);
_annotations = [[NSMutableArray alloc] init];
[super viewDidLoad];
// Adding annotation of spot
CLLocationCoordinate2D annotationCoord;
annotationCoord.latitude = self.spot.latitude;
annotationCoord.longitude = self.spot.longitude;
POPointAnnotation *annotationPoint = [[POPointAnnotation alloc] init];
annotationPoint.coordinate = annotationCoord;
annotationPoint.title = self.spot.name;
annotationPoint.subtitle = self.spot.address;
annotationPoint.type = PointAnnotaitonTypeSpot;
[_annotations addObject:annotationPoint];
[((SpotsMapView *)self.view).mapView addAnnotation:annotationPoint];
[annotationPoint release];
// Adding annotation of user position
CLLocationCoordinate2D userCoord;
userCoord = [[POLocationManager sharedInstance] location].coordinate;
POPointAnnotation *userPoint = [[POPointAnnotation alloc] init];
userPoint.coordinate = userCoord;
userPoint.title = NSLocalizedString(#"Punkt startowy", #"Punkt startowy");
userPoint.type = PointAnnotationTypeStart;
[_annotations addObject:userPoint];
[((SpotsMapView *)self.view).mapView addAnnotation:userPoint];
[userPoint release];
[((SpotsMapView *)self.view).mapView setRegion:[self regionFromLocations] animated:YES];
[((SpotsMapView *)self.view).mapView setShowsUserLocation:YES];
}
and region here:
- (MKCoordinateRegion)regionFromLocations {
CLLocationCoordinate2D upper = [[self.annotations objectAtIndex:1] coordinate];
CLLocationCoordinate2D lower = [[self.annotations objectAtIndex:1] coordinate];
NSLog(#"Loc Upper: %f, %f", upper.latitude, upper.longitude);
NSLog(#"Loc Lower: %f, %f", lower.latitude, lower.longitude);
// FIND LIMITS
for(MKPointAnnotation *eachLocation in self.annotations) {
if([eachLocation coordinate].latitude > upper.latitude) upper.latitude = [eachLocation coordinate].latitude;
if([eachLocation coordinate].latitude < lower.latitude) lower.latitude = [eachLocation coordinate].latitude;
if([eachLocation coordinate].longitude > upper.longitude) upper.longitude = [eachLocation coordinate].longitude;
if([eachLocation coordinate].longitude < lower.longitude) lower.longitude = [eachLocation coordinate].longitude;
}
NSLog(#"Loc Upper: %f, %f", upper.latitude, upper.longitude);
NSLog(#"Loc Lower: %f, %f", lower.latitude, lower.longitude);
// FIND REGION
MKCoordinateSpan locationSpan;
locationSpan.latitudeDelta = upper.latitude - lower.latitude + 0.003;
locationSpan.longitudeDelta = upper.longitude - lower.longitude+ 0.003;
CLLocationCoordinate2D locationCenter;
locationCenter.latitude = (upper.latitude + lower.latitude) / 2;
locationCenter.longitude = (upper.longitude + lower.longitude) / 2;
MKCoordinateRegion region = MKCoordinateRegionMake(locationCenter, locationSpan);
return region;
}
Once after installing app I get this:
and after that I get this view:
Any idea what can be wrong?
When i drop multiple pins in map depends on different latitude and longitude values. im getting all pins are at one place in map.
I wrote this code for dropping multiple pins .
dealerMapView.mapType = MKMapTypeStandard;
dealerMapView.zoomEnabled =YES;
[dealerMapView setDelegate:nil];
dealerMapView.scrollEnabled = YES;
dealerMapView.showsUserLocation = NO;
CLLocationCoordinate2D location;
for (int i =0; i<[delarsInfoArray count]; i++) {
NSString *lattitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LATITUDE" ];
NSString *longitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LONGITUDE" ];
CLLocationCoordinate2D pCoordinate ;
pCoordinate.latitude = [lattitudeValue floatValue];
pCoordinate.longitude = [longitudeValue floatValue];
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta = 0.005;
span.longitudeDelta = 0.005;
region.span = span;
region.center = location;
[dealerMapView setRegion:region animated:YES];
myAnnotation1 = [[MyAnnotation alloc] init];
myAnnotation1.coordinate = location;
myAnnotation1.title = [[delarsInfoArray objectAtIndex:i]objectForKey:#"STORE"];
[dealerMapView addAnnotation:myAnnotation1];
}
Try this code:
MKCoordinateSpan span;
span.latitudeDelta = 0.2;
span.longitudeDelta= 0.2;
if( [delarsInfoArray count] > 0 ){
CLLocationCoordinate2D start;
NSString *lattitudeValue = [[delarsInfoArray objectAtIndex:0]objectForKey:#"LATITUDE" ];
NSString *longitudeValue = [[delarsInfoArray objectAtIndex:j]objectForKey:#"LONGITUDE" ];
// create region, consisting of span and location
MKCoordinateRegion mapRegion;
mapRegion.span = span;
mapRegion.center = start;
//Move the map to our location //
[dealerMapView setRegion:mapRegion animated:YES];
}
// do not show pins and annotations more then 200 in the map at a time.
for (int j = 0; j< ([delarsInfoArray count] < 200?[delarsInfoArray count]:200); j++) {
NSString *lattitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LATITUDE"];
NSString *longitudeValue = [[delarsInfoArray objectAtIndex:i]objectForKey:#"LONGITUDE" ];
CLLocationCoordinate2D pinLocation;
if(([lattitudeValue floatValue] != 0) && ([longitudeValue floatValue] != 0) ) {
pinLocation.latitude = [lattitudeValue floatValue];
pinLocation.longitude = [longitudeValue floatValue];
if(pinLocation.latitude !=0 && pinLocation.longitude !=0) {
myAnnotation1 = [[MyAnnotation alloc] init];
myAnnotation1.coordinate = location;
myAnnotation1.title = [[delarsInfoArray objectAtIndex:i] objectForKey: #"STORE"];
[dealerMapView addAnnotation:myAnnotation1];
}
}
}
I hope it helps you!! Best Luck. Cheers!!
I have been working on an iPhone app, where-in i have list of users in a NSMutableArray like below.
myMutableArray: (
{
FirstName = Getsy;
LastName = marie;
Latitude = "30.237314";
Longitude = "-92.461008";
},
{
FirstName = Angel;
LastName = openza;
Latitude = "30.260329";
Longitude = "-92.450414";
},
{
FirstName = Sara;
LastName = Hetzel;
Latitude = "30.2584499";
Longitude = "-92.4135357";
}
)
I need to sort users based on the location who is nearby to my location by calculating latitude and longitude. I am not able to achieve this till now. Could someone help me on giving some samples?
UPDATED: I am trying like below as per Mr.sch suggested. Please check my updated code. Is it fine?.
NSArray *orderedUsers = [myMutableArray sortedArrayUsingComparator:^(id a,id b) {
NSArray *userA = (NSArray *)a;
NSArray *userB = (NSArray *)b;
CGFloat aLatitude = [[userA valueForKey:#"Latitude"] floatValue];
CGFloat aLongitude = [[userA valueForKey:#"Longitude"] floatValue];
CLLocation *participantALocation = [[CLLocation alloc] initWithLatitude:aLatitude longitude:aLongitude];
CGFloat bLatitude = [[userA valueForKey:#"Latitude"] floatValue];
CGFloat bLongitude = [[userA valueForKey:#"Longitude"] floatValue];
CLLocation *participantBLocation = [[CLLocation alloc] initWithLatitude:bLatitude longitude:bLongitude];
CLLocation *myLocation = [[CLLocation alloc] initWithLatitude:locationCoordinates.latitude longitude:locationCoordinates.longitude];
CLLocationDistance distanceA = [participantALocation distanceFromLocation:myLocation];
CLLocationDistance distanceB = [participantBLocation distanceFromLocation:myLocation];
if (distanceA < distanceB) {
return NSOrderedAscending;
} else if (distanceA > distanceB) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}];
Thank you!
NSArray *orderedUsers = [users sortedArrayUsingComparator:^(id a,id b) {
User *userA = (User *)a;
User *userB = (User *)b;
CLLocationDistance distanceA = [userA.location getDistanceFromLocation:myLocation];
CLLocationDistance distanceB = [userB.location getDistanceFromLocation:myLocation];
if (distanceA < distanceB) {
return NSOrderedAscending
} else if (distanceA > distanceB) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}];
First thing, you will need to calculate the distance between your current location and the location of each other user.
Talking mathematically, here is a Wolfram|Alpha example
Now "programmatic-ally", you can use CLLocation class, here is an example:
(CLLocationDistance)getDistanceFrom:(const CLLocation *)location
But first you will need to create the location object from your Latitude and Longitude. You can use:
(id)initWithLatitude:(CLLocationDegrees)latitude longitude:(CLLocationDegrees)longitude
You can calculate the distance (geographical, not flat plane!) between your position and each of these items' positions and order by that value.
- (void)viewDidLoad {
[super viewDidLoad];
// This Array Taken Globally
List_of_locationsArray =[[NSMutableArray alloc]initWithObjects:
#{#"latitude" : #"17.415045",#"logitude":#"78.421424"} ,#{#"latitude" : #"17.415045",#"logitude":#"78.421424"},#{#"latitude" : #"17.415045",#"logitude":#"78.421424"},#{#"latitude" : #"17.415045",#"logitude":#"78.421424"},#{#"latitude" : #"17.415045",#"logitude":#"78.421424"}
,nil];
}
-(void)sortingLocationsArray{
// CLLocation* currentLocation =[[CLLocation alloc]initWithLatitude:[currentLatitude doubleValue] longitude:[currentLogitude doubleValue]];
CLLocation* currentLocation =[[CLLocation alloc]initWithLatitude: currentLatitudeHere longitude:CurrentLogHere];
NSMutableArray* tempLocationsArr = [[NSMutableArray alloc]initWithCapacity:[locationsArray count]];
for (int i=0; i<[locationsArray count]; i++) {
CLLocationDegrees latValue = [[locationsArray[i] objectForKey:#"latitude"] doubleValue];
CLLocationDegrees longValue = [[locationsArray[i] objectForKey:#"logitude"] doubleValue];
CLLocation* location = [[CLLocation alloc]initWithLatitude:latValue longitude:longValue];
[tempLocationsArr addObject:location];
NSArray* sortLocationArry = [tempLocationsArr sortedArrayUsingComparator:^NSComparisonResult(CLLocation* location1, CLLocation* location2) {
CLLocationDistance distA = [location1 distanceFromLocation:currentLocation];
CLLocationDistance distB = [location2 distanceFromLocation:currentLocation];
if (distA < distB) {
return NSOrderedAscending;
} else if ( distA > distB) {
return NSOrderedDescending;
} else {
return NSOrderedSame;
}
}];
//ArrayAfterSorting is another mutable Array to Store Sorting Data
[ArrayAfterSorting removeAllObjects];
[sortLocationArry enumerateObjectsUsingBlock:^(CLLocation* location, NSUInteger idx, BOOL *stop) {
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc]init];
[tempDict setObject:[NSString stringWithFormat:#"%f",location.coordinate.latitude] forKey:#"latitude"];
[tempDict setObject:[NSString stringWithFormat:#"%f",location.coordinate.longitude] forKey:#"logitude"];
[ArrayAfterSorting addObject:tempDict];
}];
NSLog(#"sortedArray : %#", ArrayAfterSorting);
}
}
You may solve your problem in following way
1)Firstly store all above values in separate array Like latArray ,longArray,nameArray
2)Now get the distance between location(longArray,latArray) from your current location.
Then store these distances in separate Array(distanceArray).
//getDistance Between currentLocation and desired Location
-(void *)getDistanceFromCurrentLocation{
for(int val=0;val<[latArray count];val++){
NSString *dis_From_Current_Location;
dis_From_Current_Location =nil;
CGFloat str_Longitude=[[defaults objectForKey:#"long"]floatValue];
CGFloat str_Latitude=[[defaults objectForKey:#"lati"]floatValue];
//Suppose this is your current location
CGFloat lat1= [[latArray objectAtIndex:val]floatValue];
//these array for lat
CGFloat long1=[[longArray objectAtIndex:val]floatValue];
//these array for longArray
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:lat1 longitude:long1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:str_Latitude longitude:str_Longitude];
CLLocationDistance dist=[location1 distanceFromLocation:location2];
NSLog(#"Distance i meters: %f", [location1 distanceFromLocation:location2]);
long long v = llabs(dist/1000);
dis_From_Current_Location=[NSString stringWithFormat:#"%lld km",v];
[location1 release];
[location2 release];
[distanceArray addObject: dis_From_Current_Location];
//distanceArray is Global NsMutableArray.
}
}
Now You should Apply sorting method(selection, bubble) fro sorting the distances.
One thing need to care is that when you sort the distanceArray
please adjust values of nameArray as according to the distanceArray
See Below code for sorting the distanceArray and adjust the nameArray's value.
-(void)getSoretdArray{
NSString * tempStr,*tempStr2;
for(int i=0;i<[distanceArray count]; i++){
for(int j=i+1;j<[distanceArray count]; j++){
if([distanceArray objectAtIndex:j]>[distanceArray objectAtIndex:j+1]){
tempStr=[distanceArray objectAtIndex:j];
NSString* str= [distanceArray objectAtIndex:j+1];
[ distanceArray insertObject:str atIndex:j];
[distanceArray insertObject:tempStr atIndex:j+1] ;
//also change the name of corresponding location.
//you have to adjust the stored names in namArray for storing names of Corresponding Distances
tempStr2=[nameArray objectAtIndex:j];
NSString* str1= [nameArray objectAtIndex:j+1];
[ nameArray insertObject:str1 atIndex:j];
[nameArray insertObject:tempStr2 atIndex:j+1] ;
}
}
}
}
This will definitely work just try to use carefully
i have the following code...
DistanceInformation *distanceInformation=[[DistanceInformation alloc]init];
NSArray *latLongArray=[distanceInformation calculateDistance];
[distanceInformation release];
NSLog(#"lat l %#",latLongArray);
NSUInteger length,count;
length = [[latLongArray objectAtIndex:0] count];
//Calcualte center of the map based on current location and airport location
CLLocationCoordinate2D centerOfMap;
centerOfMap.latitude = (27.1766700 + 28.6361600)/2;
centerOfMap.longitude = (78.0080700 + 78.0526500)/2;
//Set map span according to the distance between airport and user location
CGFloat zoomingLevel;
//set the zoom level of the map according to the distance to airport
if([[latLongArray objectAtIndex:2] intValue] <= 50)
zoomingLevel = 0.2;
else if(([[latLongArray objectAtIndex:2] intValue] > 50)&&([[latLongArray objectAtIndex:2] intValue] <= 100))
zoomingLevel = 0.6;
else if(([[latLongArray objectAtIndex:2] intValue]> 100)&&([[latLongArray objectAtIndex:2] intValue] <= 500))
zoomingLevel = 1.7;
else if(([[latLongArray objectAtIndex:2] intValue] > 500)&&([[latLongArray objectAtIndex:2] intValue] <= 1000))
zoomingLevel = 2.0;
else
zoomingLevel = 2.5;
NSLog(#"Center of map: %f, %f",centerOfMap.latitude, centerOfMap.longitude);
MKCoordinateRegion region;
MKCoordinateSpan span;
span.latitudeDelta=zoomingLevel;
span.longitudeDelta=zoomingLevel;
region.span = span;
region.center = centerOfMap;
[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];
CLLocationCoordinate2D coords[length];
for (count = 0; count<length; count++) {
NSLog(#"coo ");
coords[count] = CLLocationCoordinate2DMake([[[latLongArray objectAtIndex:0] objectAtIndex:count] doubleValue], [[[latLongArray objectAtIndex:1] objectAtIndex:count] doubleValue]);
}
//Display polyline containing route points as an overlay over the mapview
MKPolyline *polyLine=[MKPolyline polylineWithCoordinates:coords count:length];
NSLog(#"polyLine.pointCount %d",polyLine.pointCount) ;
[mapView addOverlay:polyLine];
[polyLine release];
but the polyline is not visible on map. The polyline is getting initialized with values that I have checked..
Noob mistake on my side... Forgot to implement the MKMapViewDelegate method..
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id < MKOverlay >)overlay{
}