I am working diligently on figuring how to get lines to show on my map. I am attempting to draw a line from touches began to touches end.
At the moment I am taking the coords of where I touch, add it to an array, take the cords of where touch end, add it to an array then draw the line. This is my code below.
When I ran the code sadly my line did not show. However while sitting wondering what I was missing (cause my coords are being saved to the array) I kept swiping my screen in frustration and suddenly a line appeared! I closed the program and did the same thing again and as far as I can tell, lines are being drawn randomly, and at the wrong coordinates.
I changed
CLLocationCoordinate2D obh1=CLLocationCoordinate2DMake
(startTouch.latitude, startTouch.longitude);
to
CLLocationCoordinate2D obh1=CLLocationCoordinate2DMake
(startTouch.longitude, startTouch.latitude);
to see if I was somehow mixing my coords but the same thing is happening. The lines are being drawn in random locations.
Would appreciate if someone could offer me a little help to solve this.
I have done some work and this is what I have come up with. The 4 lines points you see appear when I click on the map. They are the touches end, the touches begin. I have no idea where they are coming from but not from my code.
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches began");
UITouch *touch = [touches anyObject];
// Get the specific point that was touched
CGPoint point = [touch locationInView:self.view];
//convert toc
CLLocationCoordinate2D startTouch
=[self.map convertPoint:point toCoordinateFromView:_map];
CLLocationCoordinate2D obh1=CLLocationCoordinate2DMake(startTouch.latitude, startTouch.longitude);
[arrayOfLine addObject: [NSValue valueWithMKCoordinate:obh1]];
NSLog(@"array: %@", arrayOfLine);
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"Touches END");
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
CLLocationCoordinate2D endTouch
=[self.map convertPoint:point toCoordinateFromView:_map];
CLLocationCoordinate2D obh=CLLocationCoordinate2DMake(endTouch.latitude, endTouch.longitude);
[arrayOfLine addObject: [NSValue valueWithMKCoordinate:obh]];
NSLog(@"array: %@", arrayOfLine);
MKPolyline *polygon = [MKPolyline polylineWithCoordinates:&obh count:[arrayOfLine count]];
[_map addOverlay:polygon];
}
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
if ([overlay isKindOfClass:[MKPolyline class]])
{
MKPolylineView *overlayView = [[MKPolylineView alloc] initWithPolyline:overlay];
overlayView.strokeColor = [[UIColor blueColor] colorWithAlphaComponent:0.7];
overlayView.lineWidth = 3;
return overlayView;
}
return nil;
}
The random lines are coming from the code in question.
The main problem is in touchesEnded
in this section:
CLLocationCoordinate2D obh=CLLocationCoordinate2DMake(endTouch.latitude, endTouch.longitude);
[arrayOfLine addObject: [NSValue valueWithMKCoordinate:obh]];
NSLog(@"array: %@", arrayOfLine);
MKPolyline *polygon = [MKPolyline polylineWithCoordinates:&obh count:[arrayOfLine count]];
When calling polylineWithCoordinates
, the code is giving the address of obh
which is a single CLLocationCoordinate2D
struct but the count
is set to the number of objects in arrayOfLine
which would most likely be two (touch begin + touch end).
The polylineWithCoordinates
method is expecting a plain C array of CLLocationCoordinate2D
structs.
Currently, the code is giving the method only a single struct but the count tells the method to also use the bytes in memory following the single struct as coordinates in the array. The bytes in memory following obh
are most likely going to be random values which translate to meaningless coordinates and so you get random lines or no lines at all.
To fix this, you need to construct a plain C array from arrayOfLine
(an Objective-C NSArray
).
Here's one way to do it:
//REPLACE this existing line with the code below:
//MKPolyline *polygon = [MKPolyline polylineWithCoordinates:&obh count:[arrayOfLine count]];
CLLocationCoordinate2D coords[arrayOfLine.count];
for (int c = 0; c < arrayOfLine.count; c++)
{
NSValue *v = [arrayOfLine objectAtIndex:c];
coords[c] = v.MKCoordinateValue;
}
MKPolyline *polygon = [MKPolyline polylineWithCoordinates:coords count:[arrayOfLine count]];
touchesBegan
, creating obh1
is unnecessary. startTouch
is already a CLLocationCoordinate2D
that you can add to the array.touchesEnded
, creating obh
is unnecessary. endTouch
is already a CLLocationCoordinate2D
that you can add to the array.arrayOfLine
is not being cleared at any point. This means whenever touches end, all lines the user has drawn are re-drawn (and connected together). Not sure what the intention is but if you only want the current begin+end touch pair to be drawn, then at the top of touchesBegan
, do [arrayOfLine removeAllObjects];
.userInteractionEnabled
is set to NO
on the map view otherwise it may interfere with the touch methods and cause strange behavior (like touchesEnded
not getting called).