Convert NSArray to CLLCoordinate - iphone

I am trying to covert an array of Latitude and Longitude into coordinate and set annotation to it. The app crashes upon doing so. Where am I doing it wrong? Somehow the data got messed up when it changes to double.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
CLLocationCoordinate2D addressCoordinate;
NSLog(#"latArray at index %i is %d in double", indexPath.row, [[latArray objectAtIndex:indexPath.row] doubleValue]);
NSLog(#"longArray at index %i is %d in double", indexPath.row, [[longArray objectAtIndex:indexPath.row] doubleValue]);
NSLog(#"latArray at index %i is %#", indexPath.row, [latArray objectAtIndex:indexPath.row]);
NSLog(#"longArray at index %i is %#", indexPath.row, [longArray objectAtIndex:indexPath.row]);
addressCoordinate.latitude = (CLLocationDegrees)[[latArray objectAtIndex:indexPath.row] doubleValue];
addressCoordinate.longitude = (CLLocationDegrees)[[longArray objectAtIndex:indexPath.row] doubleValue];
[mapView removeAnnotation:annotation];
[annotation moveAnnotation:addressCoordinate];
annotation.title = [titleArray objectAtIndex:indexPath.row];
annotation.subtitle = [subtitleArray objectAtIndex:indexPath.row];
[mapView addAnnotation:annotation];
}
// the console log
2011-08-27 00:16:58.286 myApp[1140:207] latArray at index 0 is -1954958020 in double
2011-08-27 00:16:58.287 myApp[1140:207] longArray at index 0 is 519365137 in double
2011-08-27 00:16:58.287 myApp[1140:207] latArray at index 0 is 1.3450389335879
2011-08-27 00:16:58.287 myApp[1140:207] longArray at index 0 is 103.69812749781
2011-08-27 00:16:58.291 myApp[1140:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFSet addObject:]: attempt to insert nil'
}
How I prepared the arrays
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
SBJsonParser *parser = [[SBJsonParser alloc] init];
responseArray = [parser objectWithData:responseData];
NSDictionary *dict = [responseArray objectAtIndex:i];
for (int i = 1; i < [responseArray count]; i++) {
[latArray insertObject:[dict objectForKey:#"lat"] atIndex:i - 1];
[longArray insertObject:[dict objectForKey:#"long"] atIndex:i - 1];
}

What is latArray keep ? I assume its NSNumber from the way you call doubleValue. In that case you don't need to cast to CLLocationDegrees in
addressCoordinate.latitude = (CLLocationDegrees)[[latArray objectAtIndex:indexPath.row] doubleValue];
addressCoordinate.longitude = (CLLocationDegrees)[[longArray objectAtIndex:indexPath.row] doubleValue];
and use
CLLocationCoordinate2DMake for CLLocationCoordinate2D
because its also double. But I think the problem lia in [mapView addAnnotation:annotation]; I don't see any annotation created here don't know if it is ivar. Need more info.

Try this:
addressCoordinate = CLLocationCoordinate2DMake((CLLocationDegrees)[[latArray objectAtIndex:indexPath.row] doubleValue],(CLLocationDegrees)[[longArray objectAtIndex:indexPath.row] doubleValue]);
instead of trying to set the latitude and longitude as you are now and see what happens.

Related

How to add elements to an array created by a 'for' loop ?

I am using for loop for get distance from current location to destination location. I would like an array that contains all distances from current to destination location.
for (i = 0; i < [Arr_Lat count]; i++)
{
NSString *latst1 = [[NSString alloc]initWithFormat:[Arr_Lat objectAtIndex:i]];
NSString *longst1 = [[NSString alloc]initWithFormat:[Arr_Long objectAtIndex:i]];
NSLog(#"First lat : %#",latst1);
NSLog(#"First ong : %#",longst1);
double Doblat1 = [latst1 doubleValue];
double Doblong1 = [longst1 doubleValue];
CLLocationCoordinate2D coord1 = CLLocationCoordinate2DMake(coord1.latitude = Doblat1, coord1.longitude = Doblat1);
NSLog(#" Coordinat ==== : %f -- %f",coord1.latitude,coord1.longitude) ;
CLLocation *currLoc = [[CLLocation alloc] initWithLatitude:appDel.curr_lat longitude:appDel.curr_long];
CLLocation *destLoc1 = [[CLLocation alloc] initWithLatitude:Doblat1 longitude:Doblong1];
NSLog(#" Currennt Location : %#", currLoc);
NSLog(#" Destination Location : %#" , destLoc1);
distance = [destLoc1 distanceFromLocation:currLoc];
NSLog(#" Distance : ------- %0.3f", distance);
DistStr = [[NSString alloc]initWithFormat:#" %f",distance];
[currLoc release];
[destLoc1 release];
[Arr_title retain];
[tbl_nearplace reloadData];
}
If you want to store the distance you need an NSMutableArray.
Declare a NSMutableArray *distanceArray; in class scope.
Initialize it: distanceArray = [[NSMutableArray alloc] init];
In the for loop after DistStr =[[NSString alloc]initWithFormat:#" %f",distance];
write the following code:
[distanceArray addObject:DistStr];
Say we have this array with stuff we want to iterate over and add those items to another array
NSArray *someArrayWithStuff = #[#"Hello",
#"Its",
#"Very",
#"Cold",
#"Outside",
#"Today"];
Say we want the content of someArrayWithStuff to be added to this other array so we create an NSMutableArray
NSMutableArray *theNewArrayWithOurStuff = [NSMutableArray array];
We loop through the someArrayWithStuff
for (int i = 0; i < someArrayWithStuff.count; i++) {
// Add object to the new array
[theNewArrayWithOurStuff addObject:[someArrayWithStuff objectAtIndex:i]];
}
NSMutableArray *Distance=[[NSMutableArray alloc]Init];
for (i = 0; i < [Arr_Lat count]; i++)
{
NSString *latst1 = [[NSString alloc]initWithFormat:[Arr_Lat objectAtIndex:i]];
NSString *longst1 = [[NSString alloc]initWithFormat:[Arr_Long objectAtIndex:i]];
NSLog(#"First lat : %#",latst1);
NSLog(#"First ong : %#",longst1);
double Doblat1 = [latst1 doubleValue];
double Doblong1 = [longst1 doubleValue];
CLLocationCoordinate2D coord1 = CLLocationCoordinate2DMake(coord1.latitude = Doblat1, coord1.longitude = Doblat1);
NSLog(#" Coordinat ==== : %f -- %f",coord1.latitude,coord1.longitude) ;
CLLocation *currLoc = [[CLLocation alloc] initWithLatitude:appDel.curr_lat longitude:appDel.curr_long];
CLLocation *destLoc1 = [[CLLocation alloc] initWithLatitude:Doblat1 longitude:Doblong1];
NSLog(#" Currennt Location : %#", currLoc);
NSLog(#" Destination Location : %#" , destLoc1);
distance = [destLoc1 distanceFromLocation:currLoc];
NSLog(#" Distance : ------- %0.3f", distance);
NSString *DistStr = [[NSString alloc]initWithFormat:#" %f",distance];
[Distance addObject:DistStr];
[DistStr release];
[currLoc release];
[destLoc1 release];
[Arr_title retain];
[tbl_nearplace reloadData];
}

Add annotations to a MapView in a loop

I am trying to add some annotations to my mkMapView in this loop:
for (PFObject *fetchedCompany in companyArray)
{
Store *store = [[Store alloc] initWithObject:fetchedCompany];
[self loadStore:store];
[store release];
}
- (void) loadStore:(Store *) store {
CLLocationCoordinate2D location = [self getLocationFromAddressString:store.address];
MapViewAnnotation *mapAnnotation = [[MapViewAnnotation alloc] initWithTitle:store.name coordinate:location];
[self.indexMapView addAnnotation:mapAnnotation];
}
And this the getLocationFromAddressString method that convert the address to a location using google api:
-(CLLocationCoordinate2D) getLocationFromAddressString:(NSString*) addressStr {
NSString *urlStr = [NSString stringWithFormat:#"http://maps.google.com/maps/geo?q=%#&output=csv", [addressStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
NSError *error = nil;
NSString *locationStr = [NSString stringWithContentsOfURL:[NSURL URLWithString:urlStr] encoding:NSUTF8StringEncoding error:&error];
NSArray *items = [locationStr componentsSeparatedByString:#","];
double lat = 0.0;
double lon = 0.0;
if([items count] >= 4 && [[items objectAtIndex:0] isEqualToString:#"200"]) {
lat = [[items objectAtIndex:2] doubleValue];
lon = [[items objectAtIndex:3] doubleValue];
}
else {
NSLog(#"Address, %# not found: Error %#",addressStr, [items objectAtIndex:0]);
}
CLLocationCoordinate2D location;
location.latitude = lat;
location.longitude = lon;
return location;
}
When I send just one location always it works perfectly, but when I add annotations in my loop sometimes some locations could not be recognized and I got the error from my NSLog:
Address, Vallgatan 3 GĂ–TEBORG not found: Error 620
The thing is I am pretty sure about the addresses because when I tried them without loop they worked. Do you know how can I solve the problem?
You've submitted too many queries and your request got rejected. See Geocoding API V2 docs.
620: G_GEO_TOO_MANY_QUERIES
"The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time. If you're sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don't send the requests too quickly"

Solve Simple NSCSF Number Problem

Getting the error: -[NSCFNumber length]: unrecognized selector sent to instance at line [firstComponentText setString:[pickerArray objectAtIndex:row]];.
-(void) viewDidLoad
pickerArray = [[NSMutableArray alloc] initWithCapacity:700];
for ( float i = 0.0 ; i <= 1000.0 ; i = i + 2.5)
[pickerArray addObject:[NSNumber numberWithFloat:i]];
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (thePickerView.tag==1)//weight
{
[firstComponentText setString:[pickerArray objectAtIndex:row]];
weightLabel.text = firstComponentText;
}
}
Does your pickerArray contain NSNumber objects? If so, to get an NSString, you'll need to use a method like +[NSString stringWithFormat:] or -[NSNumber stringValue].
If that's the case, try either of the following:
[firstComponentText setString:[[pickerArray objectAtIndex:row] stringValue]];
or
[firstComponentText setString:[NSString stringWithFormat:#"%#", [pickerArray objectAtIndex:row]]];

Newbie iphone development question

I am trying to draw a map with routes from a file. I am trying to learn this procedure by following this blog (http://spitzkoff.com/craig/?p=108).
When the process hits my function, it terminates (I have given the error message below)
- (void) drawRoute {
//
// load the points from our local resource
//
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"route" ofType:#"csv"];
NSString* fileContents = [NSString stringWithContentsOfFile:filePath];
NSArray* pointStrings = [fileContents componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSMutableArray* points = [[NSMutableArray alloc] initWithCapacity:pointStrings.count];
for(int idx = 0; idx < pointStrings.count; idx++)
{
// break the string down even further to latitude and longitude fields.
NSString* currentPointString = [pointStrings objectAtIndex:idx];
NSArray* latLonArr = [currentPointString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#","]];
CLLocationDegrees latitude = [[latLonArr objectAtIndex:0] doubleValue];
CLLocationDegrees longitude = [[latLonArr objectAtIndex:1] doubleValue];
CLLocation* currentLocation = [[[CLLocation alloc] initWithLatitude:latitude longitude:longitude] autorelease];
[points addObject:currentLocation];
}
// CREATE THE ANNOTATIONS AND ADD THEM TO THE MAP
// first create the route annotation, so it does not draw on top of the other annotations.
CSRouteAnnotation* routeAnnotation = [[[CSRouteAnnotation alloc] initWithPoints:points] autorelease];
[secondMap addAnnotation:routeAnnotation];
// create the rest of the annotations
CSMapAnnotation* annotation = nil;
// create the start annotation and add it to the array
annotation = [[[CSMapAnnotation alloc] initWithCoordinate:[[points objectAtIndex:0] coordinate]
annotationType:CSMapAnnotationTypeStart
title:#"Start Point"] autorelease];
[secondMap addAnnotation:annotation];
// create the end annotation and add it to the array
annotation = [[[CSMapAnnotation alloc] initWithCoordinate:[[points objectAtIndex:points.count - 1] coordinate]
annotationType:CSMapAnnotationTypeEnd
title:#"End Point"] autorelease];
[secondMap addAnnotation:annotation];
[points release];
// center and size the map view on the region computed by our route annotation.
[secondMap setRegion:routeAnnotation.region];
}
Error message:
[Session started at 2010-07-30 01:22:13 -0400.]
2010-07-30 01:22:19.078 ActualTry[4893:20b] Found center of new Route Annotation at 0.000000, 0
2010-07-30 01:22:19.079 ActualTry[4893:20b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFArray objectAtIndex:]: index (0) beyond bounds (0)'
2010-07-30 01:22:19.080 ActualTry[4893:20b] Stack: (
807902715,
2492862011,
807986683,
807986522,
810976489,
810572359,
13379,
12278,
10121,
814709201,
815110321,
815119058,
815114270,
814813151,
814722763,
814748641,
839148405,
807687520,
807683624,
839142449,
839142646,
814752238,
9380,
9234
)
I will be really thankful if someone could help me in this. I know that this is basic gdb debugging, but I am not able to figure this out.
Thank you.
The error message says that you are trying to access an object in the array which doesn't exist. Looking at your code, it seems pointStrings array is empty. Are you sure your csv file has data? Try printing the pointStrings with NSlog.

how to use sortUsingFunction:context

appdata.items is NSMutableArray.
I connot compile This code.
Error code is "prop.173 has an incomplete type".
NSInteger compareInfo(id aInfo1, id aInfo2, void *context){
NSDate* info1 = [aInfo1 objectAtIndex:2];
NSDate* info2 = [aInfo2 objectAtIndex:2];
return [info1 compare:info2];
}
-(void)saveData{
NSData* data = [[NSMutableData alloc] init];
appdata.items = [appdata.items sortUsingFunction:compareInfo context:NULL];
NSKeyedArchiver* archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:appdata forKey:DATAKEY];
[archiver finishEncoding];
[data writeToFile:[self dataFilePath] atomically:YES];
[archiver release];
[data release];
}
Here is some code that might help you, (I spend pretty much time making it working, doc is not really helpfull)
It computes the distance between POI object and a currentLocation and order POI Object from the closest to the fartest from this location
NSInteger compareDistance(id num1, id num2, void *context)
{
int retour;
// fist we need to cast all the parameters
CLLocation* location = context;
POI* param1 = num1;
POI* param2 = num2;
// then we can use them as standard ObjC objects
CLLocation* locationCoordinates = [[CLLocation alloc] initWithLatitude:location.coordinate.latitude longitude:location.coordinate.longitude];
CLLocation* locationPOI1 = [[CLLocation alloc] initWithLatitude:param1.coords.latitude longitude:param1.coords.longitude];
CLLocation* locationPOI2 = [[CLLocation alloc] initWithLatitude:param2.coords.latitude longitude:param2.coords.longitude];
CLLocationDistance distance1 = [locationPOI1 distanceFromLocation:locationCoordinates];
CLLocationDistance distance2 = [locationPOI2 distanceFromLocation:locationCoordinates];
//make the comparaison
if (distance1 < distance2)
retour = NSOrderedAscending;
else if (distance1 > distance2)
retour = NSOrderedDescending;
else
retour = NSOrderedSame;
[locationCoordinates release];
[locationPOI1 release];
[locationPOI2 release];
return retour;
}
-(void) orderByProximityFromLocation:(CLLocationCoordinate2D) coordinates
{
CLLocation* currentLocation = [[CLLocation alloc] initWithLatitude:coordinates.latitude longitude:coordinates.longitude];
[listOfPOI sortUsingFunction:compareDistance context:currentLocation];
[currentLocation release];
}
The method sortUsingFunction:context: is for NSMutableArray, not NSArray, which sorts the contents of the mutable array. The method you want is sortedArrayUsingFunction:context: which will return a sorted array which you can assign, as you're currently trying to do.
Unless, of course, items is an NSMutableArray, in which case you can call sortUsingFunction:context: but as it doesn't return anything, so you don't assign it to items.