Platform: iOS
Mapbox SDK version: 3.2.0
I filmed a small video, in first part of it you can see my app with opened MapBox map, there are markers what relocating from water to the land, or from one street to another when i change zoom level. After i opened Google Maps add marker and also change zoom level, and here marker position looks more correctly during zoom.
_Please note the location of markers_
Video
Correct marker position while zooming
Unclear marker position while zooming
Can you share the images you鈥檙e using for the annotations, as well as the code you鈥檙e using to set those annotation images? The image鈥檚 center point matches the annotation鈥檚 coordinate. With the images depicted in your recording, you鈥檇 probably expect the bottom center of the image to match the annotation鈥檚 coordinate. To accomplish that, you need to add some extra whitespace to the bottom of your image.
centerOffset property to MGLAnnotationImage, so you won鈥檛 have to add that whitespace yourself. #3220 is a proposed fix for GL annotations, but it鈥檚 blocked on data-driven styles: https://github.com/mapbox/mapbox-gl-native/pull/3220#issuecomment-174081656. In the meantime, we鈥檙e working on native annotation views (#1784), which would make it easier to implement this feature.@1ec5 Thank you for informative answer! Here code you asked.
How i add annotation image:
- (MGLAnnotationImage *)mapView:(MGLMapView *)mapView imageForAnnotation:(id <MGLAnnotation>)annotation {
Listing *listing = ...;
MGLAnnotationImage *annotationImage;
// as i show different images at the same time i check what image to show
// firstly trying to get image by identifier
if ([listing.section_id integerValue] == 0) {
annotationImage = [mapView dequeueReusableAnnotationImageWithIdentifier:@"pin_b1"];
}else{
annotationImage = [mapView dequeueReusableAnnotationImageWithIdentifier:@"pin_b2"];
}
// if no image create it
if (!annotationImage) {
if ([listing.section_id integerValue] == 0) {
// resize image, look code below
UIImage *image = [MyClass imageWithImage:[UIImage imageNamed:@"pin_b1"] scaledToSize:CGSizeMake(30, 56)];
annotationImage = [MGLAnnotationImage annotationImageWithImage:image reuseIdentifier:@"pin_b1"];
}else{
UIImage *image = [MyClass imageWithImage:[UIImage imageNamed:@"pin_b2"] scaledToSize:CGSizeMake(30, 56)];
annotationImage = [MGLAnnotationImage annotationImageWithImage:image reuseIdentifier:@"pin_b2"];
}
}
return annotationImage;
}
I resize image programmatically.
+ (UIImage *)imageWithImage:(UIImage *)image scaledToSize:(CGSize)newSize {
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
OK, assuming the tip of the pin is at the bottom of pin_b1 and pin_b2, you鈥檒l need to double the height of the size you pass into UIGraphicsBeginImageContextWithOptions(), but still draw the image at the same size as before. You鈥檒l probably also want to make the invisible bottom half of the image non-tappable, so you鈥檇 modify the image鈥檚 alignment rect insets (either in your asset catalog or using -[UIImage imageWithAlignmentRectInsets:]) to exclude the bottom half.
This example shows how to use an alignment rect with a double-height image.
Note that, as of v3.3.0, which is currently in beta, MGLAnnotationView has a centerOffset property. The workaround is still necessary if you need to use MGLAnnotationImage instead of MGLAnnotationView.
MapKit annotations don't require a double height image with blank space. Why is this necessary? In MapKit, you can just adjust the centreOffset so that the bottom of the pin is placed exactly on top of the coordinate...