2

I'm trying to trace the route by free hand on a MKMapView using overlays (MKOverlay).

Each time when we move the finger i extend the polyline with last coordinate with new coordinate,all are working fine except when extending polyline overlay the whole overlay is blinking in device(only sometimes),so i can,t trace the problem.

The code i have tried is given below.

- (void)viewDidLoad

{

    j=0;    
    coords1 = malloc(2* sizeof(CLLocationCoordinate2D));

    coordinatearray=[[NSMutableArray alloc]init];

    UIPanGestureRecognizer *GestureRecogonized = [[UIPanGestureRecognizer alloc]     initWithTarget:self action:@selector(gestureDetacted:)];

    [self.myMapView addGestureRecognizer:GestureRecogonized];

}

- (void)gestureDetacted:(UIPanGestureRecognizer *)recognizer
{

    if(UIGestureRecognizerStateBegan==recognizer.state)
    {

        CGPoint point = [recognizer locationInView:self.myMapView];   
        CLLocationCoordinate2D tapPoint = [self.myMapView convertPoint:point toCoordinateFromView:self.view];

        CLLocation *curLocation = [[CLLocation alloc] initWithLatitude:tapPoint.latitude longitude:tapPoint.longitude];

        [coordinatearray addObject:curLocation];
    }

    coords1[0]=[[coordinatearray objectAtIndex:j] coordinate];

    if(UIGestureRecognizerStateChanged==recognizer.state)  
    {
         j++;

         CGPoint point = [recognizer locationInView:self.myMapView];
         CLLocationCoordinate2D tapPoint = [self.myMapView convertPoint:point toCoordinateFromView:self.view];

        CLLocation *curLocation = [[CLLocation alloc] initWithLatitude:tapPoint.latitude longitude:tapPoint.longitude];

        [coordinatearray addObject:curLocation];
        coords1[1]=CLLocationCoordinate2DMake(tapPoint.latitude,tapPoint.longitude);

        polyLine = [MKPolyline polylineWithCoordinates:coords1 count:2];

        [self.myMapView addOverlay:polyLine];
    }
}

in overlay delegate

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay {

    if([overlay isKindOfClass:[MKPolyline class]]){

        MKPolylineView *polylineView = [[MKPolylineView alloc] initWithPolyline:overlay];

        polylineView.strokeColor = [UIColor orangeColor];
        polylineView.lineWidth = 20;

        polylineView.fillColor=[[UIColor orangeColor] colorWithAlphaComponent:.1];

         return polylineView;
    }
}

can anybody know why that flickering or blinking effect is coming and how to remove it.

Thanks in advance.

Mayur Prajapati
  • 5,454
  • 7
  • 41
  • 70
Anoop K
  • 75
  • 2

1 Answers1

1

Rather than adding hundreds of really small views (which is really computationally intensive), i would rather remove the polyline overlay and add a new one with all the points on the map in it at each change in the pan recognizer (for a smoother effect, you can first add the new one and then remove the old one). Use your coordinateArray to create the MKPolyline overlay that contains all of the points, rather than the last 2 points. You could do something like:

[coordinatearray addObject:curLocation];;
CLLocationCoordinate2D* coordArray = malloc(sizeof(CLLocationCoordinate2D)*[coordinatearray count]);
memcpy(coordArray, self.coordinates, sizeof(CLLocationCoordinate2D)*([coordinatearray count]-1));    
coordArray[[coordinatearray count]-1] = curLocation;
free(self.coordinates);
self.coordinates = coordArray;
MKPolyline *polyline = [MKPolyline polylineWithCoordinates:coordArray count:[coordinatearray count]];
MKPolyline *old = [[self.mapView overlays] lastObject];
[self.mapView addOverlay:polyline];
[self.mapView removeOverlay:old];

Where self.coordinate is a property of type CLLocationCoordinate2D*, this way you can memcpy the existing array into a new one (memcpy is really efficent) and only need to add the last point to the array, rather than having to loop through each point of the NSArray *coordinatearray.

You also have to change your if(UIGestureRecognizerStateBegan==recognizer.state) part, to add in self.coordinates the first tapped point. Just something like:

self.coordinates = malloc(sizeof(CLLocationCoordinate2D));
self.coordinates[0] = curLocation;

EDIT: I think the problem is that map overlays draw themselves for different discrete values of zoom levels. At a certain zoom level it would appear that the overlay first draws itself at the bigger zoom level, and then at the smaller zoom level (in fact drawing over the previously drawn overlay). When you try to show an animation such as that from drawing the user panning gesture at this zoom level, that is why the overlay keeps flickering. A possible solution would be to use a transparent view that you put on top of the map view, where the drawing is performed while the user keeps moving the finger. Only once the panning gesture ends you then create a map overlay that you "pin" to the map and you clean the drawing view. You also need to be careful when redrawing the view, as you should each time specify only the rect to be redrawn and then redraw only in that rect, as redrawing the whole thing each time would cause a flicker in this view as well. This is definitely much more coding involved, but it should work. Check this question for how to incrementally draw on a view.

Community
  • 1
  • 1
micantox
  • 5,446
  • 2
  • 23
  • 27
  • Thanks for your reply, The only problem is while we drawing polyline by free hand all previously added polyline also blinking(flicker),so drawing is not feeling as continous.Most of the time it's working fine,the problem occure only when keeping the map zoom level at particular level,so i can't trace the real problem.I am tested the code in device not in simulator. – Anoop K May 10 '13 at 10:48
  • You're right, i just noticed that at a particular zoom level it blinks at each update. I'm gonna investigate, nevertheless, i believe my approach should result in better performances – micantox May 10 '13 at 10:55
  • I tried as you explained(adding and removing overlay),then also i found the same problem. – Anoop K May 10 '13 at 11:47
  • Yeah i know, the problem is a different one, check my edited answer! – micantox May 10 '13 at 11:50