Add Tile LOD controls (#2958)

Co-authored-by: Bart Louwers <bart@emeel.net>
Co-authored-by: Adrian Cojocaru <adrian.cojocaru92@yahoo.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
alasram
2025-06-04 05:49:41 -07:00
committed by GitHub
parent 2e4541c441
commit b11134a301
43 changed files with 1066 additions and 114 deletions

View File

@@ -121,10 +121,19 @@ typedef NS_ENUM(NSInteger, MBXSettingsMiscellaneousRows) {
MBXSettingsMiscellaneousShowCustomLocationManager,
MBXSettingsMiscellaneousOrnamentsPlacement,
MBXSettingsMiscellaneousLatLngBoundsWithPadding,
MBXSettingsMiscellaneousCycleTileLOD,
MBXSettingsMiscellaneousPrintLogFile,
MBXSettingsMiscellaneousDeleteLogFile
};
typedef NS_ENUM(NSInteger, MBXTileLodMode) {
MBXTileLodModeNoLod = 0,
MBXTileLodModeDefault,
MBXTileLodModeReduced,
MBXTileLodModeAggressive,
MBXTileLodModeCount
};
// Utility methods
CLLocationCoordinate2D coordinateCentered(CLLocationCoordinate2D origin, CLLocationDegrees bearing, CLLocationDistance distance) {
@@ -245,6 +254,8 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
NSDictionary* _pointFeatures;
NSLock* _loadLock;
MBXTileLodMode _tileLodMode;
}
// MARK: - Setup & Teardown
@@ -474,7 +485,8 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
[NSString stringWithFormat:@"Turn %@ Content Insets", (_contentInsetsEnabled ? @"Off" : @"On")],
@"View Route Simulation",
@"Ornaments Placement",
@"Lat Long bounds with padding"
@"Lat Long bounds with padding",
[NSString stringWithFormat:@"Cycle tile LOD mode: %@", [self getTileLodModeName]]
]];
break;
@@ -807,6 +819,9 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
case MBXSettingsMiscellaneousLatLngBoundsWithPadding:
[self flyToWithLatLngBoundsAndPadding];
break;
case MBXSettingsMiscellaneousCycleTileLOD:
[self cycleTileLodMode];
break;
default:
NSAssert(NO, @"All miscellaneous setting rows should be implemented");
break;
@@ -1992,6 +2007,114 @@ CLLocationCoordinate2D randomWorldCoordinate(void) {
}];
}
-(void)cycleTileLodMode
{
// TileLodMode::Default parameters
static const double defaultRadius = self.mapView.tileLodMinRadius;
static const double defaultScale = self.mapView.tileLodScale;
static const double defaultPitchThreshold = self.mapView.tileLodPitchThreshold;
_tileLodMode = static_cast<MBXTileLodMode>((static_cast<int>(_tileLodMode) + 1) % static_cast<int>(MBXTileLodModeCount));
switch (_tileLodMode) {
case MBXTileLodModeDefault:
self.mapView.tileLodMinRadius = defaultRadius;
self.mapView.tileLodScale = defaultScale;
self.mapView.tileLodPitchThreshold = defaultPitchThreshold;
break;
case MBXTileLodModeNoLod:
// When LOD is off we set a maximum PitchThreshold
self.mapView.tileLodPitchThreshold = M_PI;
break;
case MBXTileLodModeReduced:
self.mapView.tileLodMinRadius = 2;
self.mapView.tileLodScale = 1.5;
self.mapView.tileLodPitchThreshold = M_PI / 4;
break;
case MBXTileLodModeAggressive:
self.mapView.tileLodMinRadius = 1;
self.mapView.tileLodScale = 2;
self.mapView.tileLodPitchThreshold = 0;
break;
default:
break;
}
// update UI
static UISlider* zoomSlider = nil;
if (zoomSlider && _tileLodMode == MBXTileLodModeNoLod) {
[zoomSlider removeFromSuperview];
zoomSlider = nil;
}
if (!zoomSlider && _tileLodMode != MBXTileLodModeNoLod) {
const float zoomShiftRange = 5.0f;
zoomSlider = [[UISlider alloc] init];
zoomSlider.minimumValue = -zoomShiftRange / 2.0f;
zoomSlider.maximumValue = zoomShiftRange / 2.0f;
zoomSlider.value = self.mapView.tileLodZoomShift;
zoomSlider.continuous = NO;
[zoomSlider addTarget:self action:@selector(updateTileLodZoom:) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:zoomSlider];
zoomSlider.translatesAutoresizingMaskIntoConstraints = NO;
zoomSlider.frame = CGRectMake(0, 0, 100, 100);
NSArray<NSLayoutConstraint*>* layout = @[
[NSLayoutConstraint constraintWithItem:zoomSlider
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0],
[NSLayoutConstraint constraintWithItem:zoomSlider
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeWidth
multiplier:0.5
constant:0],
[NSLayoutConstraint constraintWithItem:zoomSlider
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterY
multiplier:1
constant:0],
[zoomSlider.bottomAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.bottomAnchor]];
[self.view addConstraints:layout];
}
[self.mapView triggerRepaint];
}
-(void)updateTileLodZoom:(id)sender {
UISlider* slider = (UISlider*)sender;
self.mapView.tileLodZoomShift = slider.value;
[self.mapView triggerRepaint];
NSLog(@"Tile LOD zoom shift: %f", self.mapView.tileLodZoomShift);
}
-(NSString*)getTileLodModeName {
switch (_tileLodMode) {
case MBXTileLodModeDefault:
return @"Default";
case MBXTileLodModeNoLod:
return @"Disabled";
case MBXTileLodModeReduced:
return @"Reduced";
case MBXTileLodModeAggressive:
return @"Aggressive";
default:
return @"";
}
}
// MARK: - Random World Tour
- (void)addAnnotations:(NSInteger)numAnnotations aroundCoordinate:(CLLocationCoordinate2D)coordinate radius:(CLLocationDistance)radius {

View File

@@ -463,6 +463,50 @@ MLN_EXPORT
@property (nonatomic, assign) BOOL tileCacheEnabled;
// MARK: Tile LOD controls
/**
Camera based tile level of detail controls
Minimum radius around the view point in unit of tiles in which the fine
grained zoom level tiles are always used when performing LOD
radius must be greater than 1 (At least 1 fine detailed tile is present)
A smaller radius value may improve performance at the cost of quality (tiles away from
camera use lower Zoom levels)
*/
@property (nonatomic, assign) double tileLodMinRadius;
/**
Camera based tile level of detail controls
Factor for the distance to the camera view point
A value larger than 1 increases the distance to the camera view point reducing LOD
Larger values may improve performance at the cost of quality (tiles away from camera
use lower Zoom levels)
*/
@property (nonatomic, assign) double tileLodScale;
/**
Camera based tile level of detail controls
Pitch angle in radians above which LOD calculation is performed
A smaller radius value may improve performance at the cost of quality
*/
@property (nonatomic, assign) double tileLodPitchThreshold;
/**
Camera based tile level of detail controls
Shift applied to the Zoom level during LOD calculation
A negative value shifts the Zoom level to a coarser level reducing quality but improving
performance A positive value shifts the Zoom level to a finer level increasing details but
negatively affecting performance A value of zero (default) does not apply any shift to the Zoom
level It is not recommended to change the default value unless performance is critical and the loss
of quality is acceptable. A value of -1 reduces the number of displayed tiles by a factor of 4 on
average It is recommended to first configure the pixelRatio before adjusting TileLodZoomShift.
*/
@property (nonatomic, assign) double tileLodZoomShift;
// MARK: Displaying the User’s Location
/**

View File

@@ -3231,6 +3231,46 @@ static void *windowScreenContext = &windowScreenContext;
return _rendererFrontend->getTileCacheEnabled();
}
- (void)setTileLodMinRadius:(double)tileLodMinRadius
{
_mbglMap->setTileLodMinRadius(tileLodMinRadius);
}
- (double)tileLodMinRadius
{
return _mbglMap->getTileLodMinRadius();
}
- (void)setTileLodScale:(double)tileLodScale
{
_mbglMap->setTileLodScale(tileLodScale);
}
- (double)tileLodScale
{
return _mbglMap->getTileLodScale();
}
-(void)setTileLodPitchThreshold:(double)tileLodPitchThreshold
{
_mbglMap->setTileLodPitchThreshold(tileLodPitchThreshold);
}
-(double)tileLodPitchThreshold
{
return _mbglMap->getTileLodPitchThreshold();
}
-(void)setTileLodZoomShift:(double)tileLodZoomShift
{
_mbglMap->setTileLodZoomShift(tileLodZoomShift);
}
-(double)tileLodZoomShift
{
return _mbglMap->getTileLodZoomShift();
}
// MARK: - Accessibility -
- (NSString *)accessibilityValue