I need to build an array using something like the following:
CLLocationCoordinate2D points[4];
points[0] = CLLocationCoordinate2DMake(41.000512, -109.050116);
points[1] = CLLocationCoordinate2DMake(41.002371, -102.052066);
points[2] = CLLocationCoordinate2DMake(36.993076, -102.041981);
points[3] = CLLocationCoordinate2DMake(36.99892, -109.045267);
Problem is, I will never know how many items are going to be in the array, so I can specify the count. Is there a way to create a CLLocationCoordinate2D array, and just insert new coordinates without knowing what the final total will be?
EDIT: My final goal is to use the coordinates to make an MKPolyline, using the polylineWithCoordinates method which needs a CLLocationCoordinate2D array.
// unpacking an array of NSValues into memory
CLLocationCoordinate2D *points = malloc([mutablePoints count] * sizeof(CLLocationCoordinate2D));
for(int i = 0; i < [mutablePoints count]; i++) {
[[mutablePoints objectAtIndex:i] getValue:(points + i)];
}
MKPolyline *myPolyline = [MKPolyline polylineWithCoordinates:points count:[mutablePoints count]];
free(points);
Box them up in an NSValue object and throw them in an NSMutableArray.
Related
I am trying to to call MKPolylines' + polylineWithCoordinates:count: method.
How can I create a CLLocationCoordinate2D * object in this case. I have gone through this particular answer in CLLocationCoordinate2D without knowing how many will be in the array?
// unpacking an array of NSValues into memory
CLLocationCoordinate2D *points = malloc([mutablePoints count] * sizeof(CLLocationCoordinate2D));
for(int i = 0; i < [mutablePoints count]; i++) {
[[mutablePoints objectAtIndex:i] getValue:(points + i)];
}
MKPolyline *myPolyline = [MKPolyline polylineWithCoordinates:points count:[mutablePoints count]];
free(points);
What kind of entries are in the array mutablePoints in the above case?
If your question is simply what kind of entries are in the array, the answer is quite simple: NSValue entries. You can have a look at this guide for more info on how to use NSValues.
CLLocationCoordinate2D coordinate;
for (int i = 0; i < arr.count; i++)
{
float t1 = [[arr objectAtIndex:1] floatValue];
float t2 = [[arr objectAtIndex:0] floatValue];
coordinate.latitude = t1;
coordinate.longitude = t2;
}
I add a NSTimer to record the location from location manager ,and put ever location into a NSMutableArray.
-(void)OnTimer:(NSTimer *)param{
[self.locationRecoder addObject:self.manager.location];
}
and I add a button to UI, when I click the button, it invoke this method
-(IBAction)Click:(id)sender(){
NSArray *coordinateArray = [self.locationRecorder valueForKeyPath:#"coordinate"];
MKPolyline *lines = [MKPolyline ploylineWithCoordinates:(CLLocationCoordinate2D *)coordinateArray count:coordinateArray.count];
[self.map addOverlay:lines];
}
then there is nothing drawn. did i do something wrong in type cast?
The polylineWithCoordinates method requires a plain C array of structs of type CLLocationCoordinate2D.
After the call to valueForKeyPath, coordinateArray is an NSArray of NSValue objects.
That is not the same thing as a C array of structs.
Casting that NSArray to (CLLocationCoordinate2D *) doesn't convert it to a C array of structs.
Instead, you have to create the C array manually using malloc and looping through the locationRecoder array:
CLLocationCoordinate2D *coordinateArray
= malloc(sizeof(CLLocationCoordinate2D) * locationRecorder.count);
int caIndex = 0;
for (CLLocation *loc in locationRecorder) {
coordinateArray[caIndex] = loc.coordinate;
caIndex++;
}
MKPolyline *lines = [MKPolyline polylineWithCoordinates:coordinateArray
count:locationRecorder.count];
free(coordinateArray);
[self.map addOverlay:lines];
I'm trying to add Annotations to an array to place multiple pins on a map. I have everything in a for loop. The first time it loops through, it adds the object to the array just fine. When it goes back through... the array has 0 objects in it. Can anyone tell me why?
EDIT: I'm using ARC.
-(void)plotMultipleLocs {
float latitude;
float longitude;
NSRange commaIndex;
NSString *coordGroups;
for (int i=0; i<=cgIdArray.count; i++) {
coordGroups = [cgInAreaArray objectAtIndex:i];
commaIndex = [coordGroups rangeOfString:#","];
latitude = [[coordGroups substringToIndex:commaIndex.location] floatValue];
longitude = [[coordGroups substringFromIndex:commaIndex.location + 1] floatValue];
CLLocationCoordinate2D loc = CLLocationCoordinate2DMake(latitude, longitude);
MKCoordinateRegion reg = MKCoordinateRegionMakeWithDistance(loc, 1000, 1000);
self->mapView.region = reg;
MKPointAnnotation* ann = [[MKPointAnnotation alloc] init];
ann.coordinate = loc;
ann.title = [cgNameArray objectAtIndex:i];
ann.subtitle = [cgLocArray objectAtIndex:i];
NSMutableArray *mutAnnArray = [NSMutableArray arrayWithArray:annArray];
[mutAnnArray addObject:ann];
}
}
You are creating a mutable array within the loop and adding your object to it.
At the next iteration of the loop, you create a new mutable array and add a new annotation to it.
Leave aside the fact that you are creating it from another array rather than just adding your annotation to annArray
Basically, the array that you are adding objects to last as long as one iteration, and then goes out of scope.
Try moving the array out of the loop:
-(void)plotMultipleLocs {
float latitude;
float longitude;
NSRange commaIndex;
NSString *coordGroups;
NSMutableArray *mutAnnArray = [NSMutableArray arrayWithArray:annArray]; // Create one array outside the loop.
for (int i=0; i<=cgIdArray.count; i++) {
coordGroups = [cgInAreaArray objectAtIndex:i];
commaIndex = [coordGroups rangeOfString:#","];
latitude = [[coordGroups substringToIndex:commaIndex.location] floatValue];
longitude = [[coordGroups substringFromIndex:commaIndex.location + 1] floatValue];
CLLocationCoordinate2D loc = CLLocationCoordinate2DMake(latitude, longitude);
MKCoordinateRegion reg = MKCoordinateRegionMakeWithDistance(loc, 1000, 1000);
self->mapView.region = reg;
MKPointAnnotation* ann = [[MKPointAnnotation alloc] init];
ann.coordinate = loc;
ann.title = [cgNameArray objectAtIndex:i];
ann.subtitle = [cgLocArray objectAtIndex:i];
[mutAnnArray addObject:ann]; // Add the annotation to the single array.
}
// mutAnnArray will go out of scope here, so maybe return it, or assign it to a property
}
Have you tried retaining the instance to avoid it being released?
Every time through the loop, you create a new mutable array with the contents of a different array. The mutable array containing the object you added on the previous iteration is not kept.
I'm new to iOS programming and am not sure what is wrong with this code:
CLLocationCoordinate2D *locations = malloc(sizeof(CLLocationCoordinate2D) * points.count/2);
int count = 0;
for (int i = 0; i < points.count; i++)
{
CLLocationCoordinate2D point = CLLocationCoordinate2DMake([[points objectAtIndex:i] doubleValue], [[points objectAtIndex:++i] doubleValue]);
// Fill the array.
locations[count] = point;
count++;
NSLog(#"%#", locations[count-1].latitude);
NSLog(#"%#", locations[count-1].longitude);
}
// Create the polyline based on the array of points.
MKPolyline *routeLine = [MKPolyline polylineWithCoordinates:locations count:points.count/2];
MKPolylineView *routeLineView = [[MKPolylineView alloc] initWithPolyline:routeLine];
routeLineView.fillColor = [UIColor blueColor];
routeLineView.strokeColor = [UIColor blueColor];
routeLineView.lineWidth = 5;
// Add overlay to map.
[mapOutlet addOverlay:routeLine];
[mapOutlet setVisibleMapRect:routeLine.boundingMapRect];
// clear the memory allocated earlier for the points.
free(locations);
I get an EXC_BAD_ACCESS error on the first call to NSLOG(). Any thoughts?
FYI: 'points' is an array of strings containing latitude and longitude values.
When you use %# to print a value, NSLog tries to use the argument as an object pointer but these are double float values. Use the %f to print doubles:
NSLog(#"%f", locations[count-1].latitude);
NSLog(#"%f", locations[count-1].longitude);
I have a plist with dictionary of array's with coordinates (stored as strings).
I want to create a CLLocationCoordinate2D from every array and crate an overlay for the map.
I did that -
NSString *thePath = [[NSBundle mainBundle] pathForResource:#"Roots" ofType:#"plist"];
NSDictionary *pointsDic = [[NSDictionary alloc] initWithContentsOfFile:thePath];
NSArray *pointsArray = [NSArray arrayWithArray:[pointsDic objectForKey:#"roade1"]];
CLLocationCoordinate2D pointsToUse[256];
for(int i = 0; i < 256; i++) {
CGPoint p = CGPointFromString([pointsArray objectAtIndex:i]);
pointsToUse[i] = CLLocationCoordinate2DMake(p.x,p.y);
NSLog(#"coord %f",pointsToUse [i].longitude);
NSLog(#"coord %f",pointsToUse [i].latitude);
}
MKPolyline *myPolyline = [MKPolyline polylineWithCoordinates:pointsToUse count:256];
[[self mv] addOverlay:myPolyline];
but the app is crashing without any error.
(BTW when i remove the addOverLay method the app does not crash).
I have 2 questions-
What am i doing wrong?
I have tried to set the pointsArray count as the argument for the CLLocationCoordinate2D like that -
CLLocationCoordinate2D pointsToUse[pointsArray count];
And i am getting an error.
How can i set the CLLocationCoordinate2D dynamically ?
Thanks for any help.
Shani
O.K
The problem was indeed in the viewForOverlay method (thanks aBitObvious and all the rest).
It appears that the line loading of the point from the array is working good.
and for the second question i just separated it to 2 steps:
NSInteger c = [pointsArray count];
CLLocationCoordinate2D pointsToUse[c];
and it worked fine, so if any one is looking for a way to load overlayes from plist, that way is working for me.
Thanks
shani