Skip to content

Commit

Permalink
Add Tile LOD controls
Browse files Browse the repository at this point in the history
  • Loading branch information
alasram committed Nov 5, 2024
1 parent 7ba023c commit a1f6780
Show file tree
Hide file tree
Showing 23 changed files with 518 additions and 46 deletions.
2 changes: 1 addition & 1 deletion benchmark/util/tilecover.benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static void TileCoverPitchedViewport(benchmark::State& state) {

std::size_t length = 0;
while (state.KeepRunning()) {
auto tiles = util::tileCover(transform.getState(), 8);
auto tiles = util::tileCover({transform.getState()}, 8);
length += tiles.size();
}
(void)length;
Expand Down
32 changes: 32 additions & 0 deletions include/mbgl/map/map.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,38 @@ class Map : private util::noncopyable {
void setFreeCameraOptions(const FreeCameraOptions& camera);
FreeCameraOptions getFreeCameraOptions() const;

// Tile LOD controls
//
/// The number of map tile requests can be reduced by using a lower level
/// of details (Lower zoom level) away from the camera.
/// This can improve performance, particularly when the camera pitch is high.
/// The LOD calculation uses a heuristic based on the distance to the camera
/// view point. The heuristic behavior is controlled with 3 parameters:
/// - `TileLodMinRadius` is a radius around the view point in unit of tiles
/// in which the fine grained zoom level tiles are always used
/// - `TileLodScale` is a scale factor for the distance to the camera view
/// point. A value larger than 1 increases the distance to the camera view
/// point in which case the LOD is reduced
/// - `TileLodPitchThreshold` is the pitch angle in radians above which LOD
/// calculation is performed.
/// LOD calculation is always performed if `TileLodPitchThreshold` is zero.
/// LOD calculation is never performed if `TileLodPitchThreshold` is pi.
/// - `TileLodZoomShift` shifts the the Zoom level used for LOD calculation
/// A value of zero (default) does not change the Zoom level
/// A positive value increases the Zoom level and a negative value decreases
/// the Zoom level
/// A negative values typically improves performance but reduces quality.
/// For instance, a value of -1 reduces the zoom level by 1 and this
/// reduces the number of tiles by a factor of 4 for the same camera view.
void setTileLodMinRadius(double radius);
double getTileLodMinRadius() const;
void setTileLodScale(double scale);
double getTileLodScale() const;
void setTileLodPitchThreshold(double threshold);
double getTileLodPitchThreshold() const;
void setTileLodZoomShift(double shift);
double getTileLodZoomShift() const;

protected:
class Impl;
const std::unique_ptr<Impl> impl;
Expand Down
40 changes: 40 additions & 0 deletions platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1220,6 +1220,38 @@ jni::jboolean NativeMapView::getTileCacheEnabled(JNIEnv&) {
return jni::jboolean(rendererFrontend->getTileCacheEnabled());
}

void NativeMapView::setTileLodMinRadius(JNIEnv&, jni::jdouble radius) {
map->setTileLodMinRadius(radius);
}

jni::jdouble NativeMapView::getTileLodMinRadius(JNIEnv&) {
return jni::jdouble(map->getTileLodMinRadius());
}

void NativeMapView::setTileLodScale(JNIEnv&, jni::jdouble scale) {
map->setTileLodScale(scale);
}

jni::jdouble NativeMapView::getTileLodScale(JNIEnv&) {
return jni::jdouble(map->getTileLodScale());
}

void NativeMapView::setTileLodPitchThreshold(JNIEnv&, jni::jdouble threshold) {
map->setTileLodPitchThreshold(threshold);
}

jni::jdouble NativeMapView::getTileLodPitchThreshold(JNIEnv&) {
return jni::jdouble(map->getTileLodPitchThreshold());
}

void NativeMapView::setTileLodZoomShift(JNIEnv&, jni::jdouble shift) {
map->setTileLodZoomShift(shift);
}

jni::jdouble NativeMapView::getTileLodZoomShift(JNIEnv&) {
return jni::jdouble(map->getTileLodZoomShift());
}

mbgl::Map& NativeMapView::getMap() {
return *map;
}
Expand Down Expand Up @@ -1339,6 +1371,14 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
METHOD(&NativeMapView::getPrefetchZoomDelta, "nativeGetPrefetchZoomDelta"),
METHOD(&NativeMapView::setTileCacheEnabled, "nativeSetTileCacheEnabled"),
METHOD(&NativeMapView::getTileCacheEnabled, "nativeGetTileCacheEnabled"),
METHOD(&NativeMapView::setTileLodMinRadius, "nativeSetTileLodMinRadius"),
METHOD(&NativeMapView::getTileLodMinRadius, "nativeGetTileLodMinRadius"),
METHOD(&NativeMapView::setTileLodScale, "nativeSetTileLodScale"),
METHOD(&NativeMapView::getTileLodScale, "nativeGetTileLodScale"),
METHOD(&NativeMapView::setTileLodPitchThreshold, "nativeSetTileLodPitchThreshold"),
METHOD(&NativeMapView::getTileLodPitchThreshold, "nativeGetTileLodPitchThreshold"),
METHOD(&NativeMapView::setTileLodZoomShift, "nativeSetTileLodZoomShift"),
METHOD(&NativeMapView::getTileLodZoomShift, "nativeGetTileLodZoomShift"),
METHOD(&NativeMapView::triggerRepaint, "nativeTriggerRepaint"));
}

Expand Down
16 changes: 16 additions & 0 deletions platform/android/MapLibreAndroid/src/cpp/native_map_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,22 @@ class NativeMapView : public MapObserver {

jni::jboolean getTileCacheEnabled(JNIEnv&);

void setTileLodMinRadius(JNIEnv&, jni::jdouble);

jni::jdouble getTileLodMinRadius(JNIEnv&);

void setTileLodScale(JNIEnv&, jni::jdouble);

jni::jdouble getTileLodScale(JNIEnv&);

void setTileLodPitchThreshold(JNIEnv&, jni::jdouble);

jni::jdouble getTileLodPitchThreshold(JNIEnv&);

void setTileLodZoomShift(JNIEnv&, jni::jdouble);

jni::jdouble getTileLodZoomShift(JNIEnv&);

mbgl::Map& getMap();

void triggerRepaint(JNIEnv&);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,101 @@ public boolean getTileCacheEnabled() {
return nativeMapView.getTileCacheEnabled();
}

/**
* Camera based tile level of detail controls
*
* @param radius 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)
*/
public void setTileLodMinRadius(@FloatRange(from = 1, fromInclusive = true) double radius) {
nativeMapView.setTileLodMinRadius(radius);
}

/**
* Camera based tile level of detail controls
*
* @return minimum radius around the view point in unit of tiles in which the fine grained
* zoom level tiles are always used when performing LOD
* @see MapLibreMap#setTileLodMinRadius(double)
*/
public double getTileLodMinRadius() {
return nativeMapView.getTileLodMinRadius();
}

/**
* Camera based tile level of detail controls
*
* @param scale 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)
*/
public void setTileLodScale(@FloatRange(from = 0, fromInclusive = false) double scale) {
nativeMapView.setTileLodScale(scale);
}

/**
* Camera based tile level of detail controls
*
* @return scale factor for the distance to the camera view point
* @see MapLibreMap#setTileLodScale(double)
*/
public double getTileLodScale() {
return nativeMapView.getTileLodScale();
}

/**
* Camera based tile level of detail controls
*
* @param threshold pitch angle in radians above which LOD calculation is performed
* A smaller radius value may improve performance at the cost of quality
*/
public void setTileLodPitchThreshold(@FloatRange(from = 0, to = Math.PI) double threshold) {
nativeMapView.setTileLodPitchThreshold(threshold);
}

/**
* Camera based tile level of detail controls
*
* @return pitch angle threshold in radians above which LOD calculation is performed
* @see MapLibreMap#setTileLodPitchThreshold(double)
*/
public double getTileLodPitchThreshold() {
return nativeMapView.getTileLodPitchThreshold();
}

/**
* Camera based tile level of detail controls
*
* @param shift 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. {@link MapLibreMapOptions#pixelRatio(float)}
*/
public void setTileLodZoomShift(double shift) {
nativeMapView.setTileLodZoomShift(shift);
}

/**
* Camera based tile level of detail controls
*
* @return shift applied to the Zoom level during LOD calculation
* @see MapLibreMap#setTileLodZoomShift(double)
*/
public double getTileLodZoomShift() {
return nativeMapView.getTileLodZoomShift();
}

//
// MinZoom
//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,22 @@ List<Feature> queryRenderedFeatures(@NonNull RectF coordinates,

boolean getTileCacheEnabled();

void setTileLodMinRadius(double radius);

double getTileLodMinRadius();

void setTileLodScale(double scale);

double getTileLodScale();

void setTileLodPitchThreshold(double threshold);

double getTileLodPitchThreshold();

void setTileLodZoomShift(double shift);

double getTileLodZoomShift();

void setGestureInProgress(boolean inProgress);

float getPixelRatio();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,70 @@ public boolean getTileCacheEnabled() {
}
return nativeGetTileCacheEnabled();
}

@Override
public void setTileLodMinRadius(double radius) {
if (checkState("setTileLodMinRadius")) {
return;
}
nativeSetTileLodMinRadius(radius);
}

@Override
public double getTileLodMinRadius() {
if (checkState("getTileLodMinRadius")) {
return 0;
}
return nativeGetTileLodMinRadius();
}

@Override
public void setTileLodScale(double scale) {
if (checkState("setTileLodScale")) {
return;
}
nativeSetTileLodScale(scale);
}

@Override
public double getTileLodScale() {
if (checkState("getTileLodScale")) {
return 0;
}
return nativeGetTileLodScale();
}

@Override
public void setTileLodPitchThreshold(double threshold) {
if (checkState("setTileLodPitchThreshold")) {
return;
}
nativeSetTileLodPitchThreshold(threshold);
}

@Override
public double getTileLodPitchThreshold() {
if (checkState("getTileLodPitchThreshold")) {
return 0;
}
return nativeGetTileLodPitchThreshold();
}

@Override
public void setTileLodZoomShift(double shift) {
if (checkState("setTileLodZoomShift")) {
return;
}
nativeSetTileLodZoomShift(shift);
}

@Override
public double getTileLodZoomShift() {
if (checkState("getTileLodZoomShift")) {
return 0;
}
return nativeGetTileLodZoomShift();
}
// Runtime style Api

@Override
Expand Down Expand Up @@ -1594,6 +1658,30 @@ private native Feature[] nativeQueryRenderedFeaturesForBox(float left, float top
@Keep
private native int nativeGetPrefetchZoomDelta();

@Keep
private native void nativeSetTileLodMinRadius(double radius);

@Keep
private native double nativeGetTileLodMinRadius();

@Keep
private native void nativeSetTileLodScale(double scale);

@Keep
private native double nativeGetTileLodScale();

@Keep
private native void nativeSetTileLodPitchThreshold(double threshold);

@Keep
private native double nativeGetTileLodPitchThreshold();

@Keep
private native void nativeSetTileLodZoomShift(double shift);

@Keep
private native double nativeGetTileLodZoomShift();

@Override
public long getNativePtr() {
return nativePtr;
Expand Down
Loading

0 comments on commit a1f6780

Please sign in to comment.