Mapbox-gl-js: Support max pitch > 60

Created on 1 Dec 2016  Â·  48Comments  Â·  Source: mapbox/mapbox-gl-js

As we improve support for custom rendering, there are legitimate cases for pitching the map beyond the hardcoded limit of 60 degrees. With the proper safeguards to prevent loading an absurd # of tiles, we could make the max pitch of the map configurable.

feature

Most helpful comment

I have tried a currently feasible method.
It's to limit high pitch(pitch>60) covering tiles loading.

the mapbox-gl version i used is [email protected].

  1. set max pitch
prototypeAccessors.pitch.set = function(pitch) {
    var MAX_PITCH = 85;
    var MIN_PITCH = 0;
    var p = util.clamp(pitch, MIN_PITCH, MAX_PITCH) / 180 * Math.PI;
    if (this._pitch === p) {
        return;
    }
    this._unmodified = false;
    this._pitch = p;
    this._calcMatrices();
};
  1. limit high pitch covering tiles loading
Transform.prototype.coveringTiles = function coveringTiles(
    options
) {
    var z = this.coveringZoomLevel(options);
    var actualZ = z;

    if (options.minzoom !== undefined && z < options.minzoom) {
        return [];
    }
    if (options.maxzoom !== undefined && z > options.maxzoom) {
        z = options.maxzoom;
    }

    var centerCoord = this.pointCoordinate(this.centerPoint, z);
    var centerPoint = new Point(centerCoord.column - 0.5, centerCoord.row - 0.5);

    // limit high pitch(pitch>60) covering tiles loading
    var initHeight = 0;
    var calHeight = initHeight;
    var HIGH_PITCH = 60;
    var MAX_PITCH = 85;
    if (this.pitch > HIGH_PITCH) {
        var CLIP_HEIGHT = this.height / 2 / 1.07;
        var CLIP_HEIGHT_ADJUST = 0.08;

        var pitchPercent = (this.pitch - HIGH_PITCH) / (MAX_PITCH - HIGH_PITCH);
        var zoomPercent = (this.zoom - this.minZoom) / (this.maxZoom - this.minZoom);
        var adjustAcordingZoom = 1 - zoomPercent;
        var adjustPercent = 1 + adjustAcordingZoom * CLIP_HEIGHT_ADJUST;

        calHeight = pitchPercent * CLIP_HEIGHT * adjustPercent;
    }

    var cornerCoords = [
        this.pointCoordinate(new Point(0, calHeight), z),
        this.pointCoordinate(new Point(this.width, calHeight), z),
        this.pointCoordinate(new Point(this.width, this.height), z),
        this.pointCoordinate(new Point(0, this.height), z)
    ];
    return tileCover(z, cornerCoords, options.reparseOverscaled ? actualZ : z, this._renderWorldCopies)
        .sort(function(a, b) {
            return centerPoint.dist(a.canonical) - centerPoint.dist(b.canonical);
        });
};
  1. and then you can see that.

    1. pitch == 60

      pitch60

    2. pitch == 70

      pitch70

    3. pitch == 80

      pitch80

that is a way i using now, hope that can help you.

All 48 comments

With the proper safeguards to prevent loading an absurd # of tiles

Yes! We've discussed some ideas about this with @ansis recently. Basically we should change the tile loading algorithm so that it loads lower zoom tiles on farther side, depending on how small they appear when projected.

| loads lower zoom tiles on farther side, depending on how small they appear when projected.

That would be really neat. If not, just rendering blur / some sort of background color in the distance would work fine as well - at least it would unblock our use cases.

Also, in deck.gl we are combining maps with general 3D geometry - so our main camera is a general projection matrix, which we currently have to constrain to fit with mapbox zoom and pitch limits. If we remove those constraints, this means that we could have pitch > 90 degrees!

It would certainly be OK not to render the base map in this case (we won't be underground). But we might still want to see extrusions (like buildings) from your 3D styles when looking up from street level.

Maybe this should be a separate issue?

besides level-of-detail tile loading we'll also need to fix:

  • label-placement (the tiled placement approach will completely fall apart)
  • antialiasing

label-placement (the tiled placement approach will completely fall apart)

For our purposes it would be OK if the labels disappeared at high pitch levels. They probably wouldn't be very legible anyway?

This would be really great! Any progress on this issue?

@Mariusun not on the main part of the issue but we are making progress one some sub-problems like improved label placement

I am new try to use mapboxGL. It's wonderful to change the slope. But I also have the need to pitch the map more to observe the 3D
The label don't need to slope too much I think...
Hope to have progress on this issue.

+1 This would also be useful for AR/VR Experiences for FPV and also when turning on 3D Buildings to look down streets

Related: mapbox/mapbox-gl-native#9037.

Any progress by now?

@areknawo we've finished some of the tasks that were blocking this, but the feature itself is not being actively worked on right now.

Alright, I have found my way around, thanks for information anyway.

@areknawo How are you working around this? Any pointers would be really helpful!

@Rushali it's basicaly like this:

  1. Set max pitch to 89.9 - it can't be full 90.
  2. In calcMatrices divide projMatix into two - one for calculating tiles (limited to 60) and one for viewport (limited to 90).
  3. As I use it for AR experience I want camera to rotate around itself so I change its position.
  4. I didn't test it with labels because I don't need them, but I think they won't work properly.
  5. I know this code isn't clear and it isn't working well, but at least it's working.

prototypeAccessors.pitch.set = function (pitch ) {
var p = util.clamp(pitch, 0, 89.9) / 180 * Math.PI;
console.log(p)
if (this._pitch === p) { return; }
this._unmodified = false;
this._pitch = p;
this._calcMatrices();
};

Transform.prototype._calcMatrices = function _calcMatrices () {
if (!this.height) { return; }

this.cameraToCenterDistance = 0.5 / Math.tan(this._fov / 2) * this.height /20;

// Find the distance from the center point [width/2, height/2] to the
// center top point [width/2, 0] in Z units, using the law of sines.
// 1 Z unit is equivalent to 1 horizontal px at the center of the map
// (the distance between[width/2, height/2] and [width/2 + 1, height/2])
var halfFov = this._fov / 2;
var groundAngle = Math.PI / 2 + this._pitch;
var topHalfSurfaceDistance = Math.sin(halfFov) * this.cameraToCenterDistance / Math.sin(Math.PI - groundAngle - halfFov);
var x = this.x, y = this.y;

// Calculate z distance of the farthest fragment that should be rendered.
var furthestDistance = Math.cos(Math.PI / 2 - this._pitch) * topHalfSurfaceDistance + this.cameraToCenterDistance;
// Add a bit extra to avoid precision problems when a fragment's distance is exactly `furthestDistance`
var farZ = furthestDistance * 1.01;

// matrix for conversion from location to GL coordinates (-1 .. 1)
var m = new Float64Array(16);
mat4.perspective(m, this._fov, this.width / this.height, 1, farZ);

mat4.scale(m, m, [1, -1, 1]);
mat4.translate(m, m, [0, 5, 0]);
mat4.rotateX(m, m, this._pitch);
mat4.rotateZ(m, m, this.angle);
mat4.translate(m, m, [-x, -y, 0]);

var m2 = new Float64Array(16);
mat4.perspective(m2, this._fov, this.width / this.height, 1, farZ);

mat4.scale(m2, m2, [1, -1, 1]);
mat4.translate(m2, m2, [0, 0, -this.cameraToCenterDistance]);
if(this._pitch > 60/180*Math.PI){
mat4.rotateX(m2, m2, 60/180*Math.PI);
}
else{
    mat4.rotateX(m2, m2, this._pitch);
}
mat4.rotateZ(m2, m2, this.angle);
mat4.translate(m2, m2, [-x, -y, 0]);

// scale vertically to meters per pixel (inverse of ground resolution):
// worldSize / (circumferenceOfEarth * cos(lat * π / 180))
var verticalScale = this.worldSize / (2 * Math.PI * 6378137 * Math.abs(Math.cos(this.center.lat * (Math.PI / 180))));
mat4.scale(m, m, [1, 1, verticalScale, 1]);
mat4.scale(m2, m2, [1, 1, verticalScale, 1]);

this.projMatrix = m;
this.projPointMatrix = m2;

// Make a second projection matrix that is aligned to a pixel grid for rendering raster tiles.
// We're rounding the (floating point) x/y values to achieve to avoid rendering raster images to fractional
// coordinates. Additionally, we adjust by half a pixel in either direction in case that viewport dimension
// is an odd integer to preserve rendering to the pixel grid. We're rotating this shift based on the angle
// of the transformation so that 0°, 90°, 180°, and 270° rasters are crisp, and adjust the shift so that
// it is always <= 0.5 pixels.
var xShift = (this.width % 2) / 2, yShift = (this.height % 2) / 2,
    angleCos = Math.cos(this.angle), angleSin = Math.sin(this.angle),
    dx = x - Math.round(x) + angleCos * xShift + angleSin * yShift,
    dy = y - Math.round(y) + angleCos * yShift + angleSin * xShift;
var alignedM = new Float64Array(m);
mat4.translate(alignedM, alignedM, [ dx > 0.5 ? dx - 1 : dx, dy > 0.5 ? dy - 1 : dy, 0 ]);
this.alignedProjMatrix = alignedM;

// matrix for conversion from location to screen coordinates
m = mat4.create();
mat4.scale(m, m, [this.width / 2, -this.height / 2, 1]);
mat4.translate(m, m, [1, -1, 0]);
this.pixelMatrix = mat4.multiply(new Float64Array(16), m, this.projPointMatrix);
m2 = mat4.create();
mat4.scale(m2, m2, [this.width / 2, -this.height / 2, 1]);
mat4.translate(m2, m2, [1, -1, 0]);
this.pixelPointMatrix = mat4.multiply(new Float64Array(16), m2, this.projMatrix);

// inverse matrix for conversion from screen coordinaes to location
m = mat4.invert(new Float64Array(16), this.pixelMatrix);
if (!m) { throw new Error("failed to invert matrix"); }
this.pixelMatrixInverse = m;

m2 = mat4.invert(new Float64Array(16), this.pixelPointMatrix);
if (!m2) { throw new Error("failed to invert matrix"); }
this.pixelPointMatrixInverse = m2;

this._posMatrixCache = {};
this._alignedPosMatrixCache = {};

};

Transform.prototype.coveringTiles = function coveringTiles (
options
) {
var z = this.coveringZoomLevel(options);
var actualZ = z;

if (options.minzoom !== undefined && z < options.minzoom) { return []; }
if (options.maxzoom !== undefined && z > options.maxzoom) { z = options.maxzoom; }

var centerCoord = this.pointCoordinate(this.centerPoint, z);
var centerPoint = new Point(centerCoord.column - 0.5, centerCoord.row - 0.5);
var cornerCoords = [
    this.pointCoordinate(new Point(0, 0), z, true),
    this.pointCoordinate(new Point(this.width, 0), z, true),
    this.pointCoordinate(new Point(this.width, this.height), z, true),
    this.pointCoordinate(new Point(0, this.height), z, true)
];
return tileCover(z, cornerCoords, options.reparseOverscaled ? actualZ : z, this._renderWorldCopies)
    .sort(function (a, b) { return centerPoint.dist(a.canonical) - centerPoint.dist(b.canonical); });

};

Transform.prototype.pointCoordinate = function pointCoordinate (p , zoom , forTiles) {
if (zoom === undefined) { zoom = this.tileZoom; }

var targetZ = 0;
// since we don't know the correct projected z value for the point,
// unproject two points to get a line and then find the point on that
// line with z=0

var coord0 = [p.x, p.y, 0, 1];
var coord1 = [p.x, p.y, 1, 1];
if(forTiles){
vec4.transformMat4(coord0, coord0, this.pixelPointMatrixInverse);
vec4.transformMat4(coord1, coord1, this.pixelPointMatrixInverse);
}
else{
    vec4.transformMat4(coord0, coord0, this.pixelMatrixInverse);
    vec4.transformMat4(coord1, coord1, this.pixelMatrixInverse);  
}

var w0 = coord0[3];
var w1 = coord1[3];
var x0 = coord0[0] / w0;
var x1 = coord1[0] / w1;
var y0 = coord0[1] / w0;
var y1 = coord1[1] / w1;
var z0 = coord0[2] / w0;
var z1 = coord1[2] / w1;

var t = z0 === z1 ? 0 : (targetZ - z0) / (z1 - z0);

return new Coordinate(
    interp(x0, x1, t) / this.tileSize,
    interp(y0, y1, t) / this.tileSize,
    this.zoom)._zoomTo(zoom);

};

Any news on that? It would be really amazing to go beyond 60 degrees limit.

Agreed ! I'm wondering where the progress is for this feature... To reiterate an earlier point, even just having some color for the distant tiles and disregarding any annotations etc would probably suffice for now!

Thank you.

On the native side, mapbox/mapbox-gl-native#12310 would increase the maximum pitch to 67.5° unconditionally, across all zoom levels. There’s also discussion in mapbox/mapbox-gl-native#6908 about allowing the maximum pitch to vary by zoom level, since that threshold is particularly constraining at high zoom levels.

I have tried a currently feasible method.
It's to limit high pitch(pitch>60) covering tiles loading.

the mapbox-gl version i used is [email protected].

  1. set max pitch
prototypeAccessors.pitch.set = function(pitch) {
    var MAX_PITCH = 85;
    var MIN_PITCH = 0;
    var p = util.clamp(pitch, MIN_PITCH, MAX_PITCH) / 180 * Math.PI;
    if (this._pitch === p) {
        return;
    }
    this._unmodified = false;
    this._pitch = p;
    this._calcMatrices();
};
  1. limit high pitch covering tiles loading
Transform.prototype.coveringTiles = function coveringTiles(
    options
) {
    var z = this.coveringZoomLevel(options);
    var actualZ = z;

    if (options.minzoom !== undefined && z < options.minzoom) {
        return [];
    }
    if (options.maxzoom !== undefined && z > options.maxzoom) {
        z = options.maxzoom;
    }

    var centerCoord = this.pointCoordinate(this.centerPoint, z);
    var centerPoint = new Point(centerCoord.column - 0.5, centerCoord.row - 0.5);

    // limit high pitch(pitch>60) covering tiles loading
    var initHeight = 0;
    var calHeight = initHeight;
    var HIGH_PITCH = 60;
    var MAX_PITCH = 85;
    if (this.pitch > HIGH_PITCH) {
        var CLIP_HEIGHT = this.height / 2 / 1.07;
        var CLIP_HEIGHT_ADJUST = 0.08;

        var pitchPercent = (this.pitch - HIGH_PITCH) / (MAX_PITCH - HIGH_PITCH);
        var zoomPercent = (this.zoom - this.minZoom) / (this.maxZoom - this.minZoom);
        var adjustAcordingZoom = 1 - zoomPercent;
        var adjustPercent = 1 + adjustAcordingZoom * CLIP_HEIGHT_ADJUST;

        calHeight = pitchPercent * CLIP_HEIGHT * adjustPercent;
    }

    var cornerCoords = [
        this.pointCoordinate(new Point(0, calHeight), z),
        this.pointCoordinate(new Point(this.width, calHeight), z),
        this.pointCoordinate(new Point(this.width, this.height), z),
        this.pointCoordinate(new Point(0, this.height), z)
    ];
    return tileCover(z, cornerCoords, options.reparseOverscaled ? actualZ : z, this._renderWorldCopies)
        .sort(function(a, b) {
            return centerPoint.dist(a.canonical) - centerPoint.dist(b.canonical);
        });
};
  1. and then you can see that.

    1. pitch == 60

      pitch60

    2. pitch == 70

      pitch70

    3. pitch == 80

      pitch80

that is a way i using now, hope that can help you.

@web-wyj Thanks. This is just what I needed

@areknawo May I ask, what version number of maxbox-gl-js are you using for your code snippet?

Latest for the time being - that is v0.44.1.

Any progress by now?

react-map-gl already supports it in the v3 version:
uber/react-map-gl#156
https://uber.github.io/react-map-gl/#/Documentation/api-reference/static-map?section=properties

But I want to use pure JS, this feature is important in the 3d building.

No new progress to report -- this is still on our internal wishlist, but not on our immediate backlog. Specifically, the next thing we'd like to do here is introduce level-of-detail tile loading logic.

@ChrisLoer Thank you for your explanation.

looking forward to the freedom of setting pitch.

I have tried a currently feasible method.
It's to limit high pitch(pitch>60) covering tiles loading.

the mapbox-gl version i used is [email protected].

  1. set max pitch
prototypeAccessors.pitch.set = function(pitch) {
    var MAX_PITCH = 85;
    var MIN_PITCH = 0;
    var p = util.clamp(pitch, MIN_PITCH, MAX_PITCH) / 180 * Math.PI;
    if (this._pitch === p) {
        return;
    }
    this._unmodified = false;
    this._pitch = p;
    this._calcMatrices();
};
  1. limit high pitch covering tiles loading
Transform.prototype.coveringTiles = function coveringTiles(
    options
) {
    var z = this.coveringZoomLevel(options);
    var actualZ = z;

    if (options.minzoom !== undefined && z < options.minzoom) {
        return [];
    }
    if (options.maxzoom !== undefined && z > options.maxzoom) {
        z = options.maxzoom;
    }

    var centerCoord = this.pointCoordinate(this.centerPoint, z);
    var centerPoint = new Point(centerCoord.column - 0.5, centerCoord.row - 0.5);

    // limit high pitch(pitch>60) covering tiles loading
    var initHeight = 0;
    var calHeight = initHeight;
    var HIGH_PITCH = 60;
    var MAX_PITCH = 85;
    if (this.pitch > HIGH_PITCH) {
        var CLIP_HEIGHT = this.height / 2 / 1.07;
        var CLIP_HEIGHT_ADJUST = 0.08;

        var pitchPercent = (this.pitch - HIGH_PITCH) / (MAX_PITCH - HIGH_PITCH);
        var zoomPercent = (this.zoom - this.minZoom) / (this.maxZoom - this.minZoom);
        var adjustAcordingZoom = 1 - zoomPercent;
        var adjustPercent = 1 + adjustAcordingZoom * CLIP_HEIGHT_ADJUST;

        calHeight = pitchPercent * CLIP_HEIGHT * adjustPercent;
    }

    var cornerCoords = [
        this.pointCoordinate(new Point(0, calHeight), z),
        this.pointCoordinate(new Point(this.width, calHeight), z),
        this.pointCoordinate(new Point(this.width, this.height), z),
        this.pointCoordinate(new Point(0, this.height), z)
    ];
    return tileCover(z, cornerCoords, options.reparseOverscaled ? actualZ : z, this._renderWorldCopies)
        .sort(function(a, b) {
            return centerPoint.dist(a.canonical) - centerPoint.dist(b.canonical);
        });
};
  1. and then you can see that.

    1. pitch == 60
      pitch60
    2. pitch == 70
      pitch70
    3. pitch == 80
      pitch80

that is a way i using now, hope that can help you.

Hi, can you help me where to put this code exactly... Sorry for the basic question :)

@web-wyj
I mean prototypeAccessors is not defined globally, Do I need to have the mapbox code locally and modify the code within?

@web-wyj
I mean prototypeAccessors is not defined globally, Do I need to have the mapbox code locally and modify the code within?

yes

@web-wyj
I mean prototypeAccessors is not defined globally, Do I need to have the mapbox code locally and modify the code within?

yes

@web-wyj
Thanks a million. Can you be a bit more specific about where to put the snippets? File, position?
I might be able to find out with two thousand trials and errors... but :)

@web-wyj
I mean prototypeAccessors is not defined globally, Do I need to have the mapbox code locally and modify the code within?

yes

@web-wyj
Thanks a million. Can you be a bit more specific about where to put the snippets? File, position?
I might be able to find out with two thousand trials and errors... but :)

You can search the function name 'prototypeAccessors.pitch.set' and 'Transform.prototype.coveringTiles' in [email protected] .

@web-wyj
okjay, I feel from your answers that I am a nuisance, but it is really above my level.

  1. tried to find 43 dev, but couldn't so I downloaded this one, risking it will not work: https://github.com/mapbox/mapbox-gl-js/releases/tag/v0.43.0

  2. I have found the code parts and managed to replace in js\mapbox-gl-js-0.43.0\bench\benchmarks_generated-3d30c4b.js

  3. I realised that there are no dist/ .js and I need to build the whole stuff, which I really cannot. I have never managed to understand npm even, not talking about webpack or whatever...

  4. now after f.cking my whole morning, can anyone attach a build mapbox-gl.js with these changes?

Thanks a lot,
Peter

@web-wyj
okjay, I feel from your answers that I am a nuisance, but it is really above my level.

  1. tried to find 43 dev, but couldn't so I downloaded this one, risking it will not work: https://github.com/mapbox/mapbox-gl-js/releases/tag/v0.43.0
  2. I have found the code parts and managed to replace in js\mapbox-gl-js-0.43.0\bench\benchmarks_generated-3d30c4b.js
  3. I realised that there are no dist/ .js and I need to build the whole stuff, which I really cannot. I have never managed to understand npm even, not talking about webpack or whatever...
  4. now after f.cking my whole morning, can anyone attach a build mapbox-gl.js with these changes?

Thanks a lot,
Peter

You misunderstood me. I'm just not good at speaking English.
You can get js and download from https://api.tiles.mapbox.com/mapbox-gl-js/v0.43.0/mapbox-gl-dev.js.
And then find 'prototypeAccessors.pitch.set' at line 13097.
And then edit it and save to use.

image

Quite cool... Certainly I need to do something with labels, which also float in the air, where otherwise tiles are not visible.

Hello everyone! Thanks for this thread! I used your snippets and it worked like a charm.

I am wondering if, maybe, you would have some clues on where to look to be able to either: completely control the camera (taking over the camera in three js so I can manipulate it the way I want, even if that means not rendering the map in specific cases), or to just be able to turn the camera so it could 'look at the sky'?

Thanks!

Given this ticket is more about setting a pitch above the current limit of 60, I've renamed this ticket. Since #8834 lets you configure max pitch currently, just not beyond 60.

FWIW @web-wyj's hack from last year no longer works because coveringTiles was refactored. #8975 seems like the best solution, but until that's merged, does anyone have a new-and-improved hack? :)

So now that we have @mpulkki-mapbox's awesome work from #8975 merged, are there any issues with flicking the switch and increasing the maximum allowable pitch (https://github.com/mapbox/mapbox-gl-js/blob/51d75fc7d67a6158e69af5384fa17bee29c39a0b/src/ui/map.js#L111) to something > 60?

From my testing it seems to be working great after changing the defaultMaxPitch to 85. Even setting to 90 nothing crashes!

@andrewharvey we want to do some improvements to label placement & collision behavior before we can increase the default limit — stay tuned for news from @mpulkki-mapbox on that front!

image

Quite cool... Certainly I need to do something with labels, which also float in the air, where otherwise tiles are not visible.

this is awesome! did you solve this label placment problem now?

So now that we have @mpulkki-mapbox's awesome work from #8975 merged, are there any issues with flicking the switch and increasing the maximum allowable pitch (

https://github.com/mapbox/mapbox-gl-js/blob/51d75fc7d67a6158e69af5384fa17bee29c39a0b/src/ui/map.js#L111

) to something > 60?
From my testing it seems to be working great after changing the defaultMaxPitch to 85. Even setting to 90 nothing crashes!

Hi @andrewharvey so, if I need to use a little more pitch angle I just need to replace the .js on that link instead the 1.12.0 version that one's normally use? Sorry if it's a silly question but I'm totally new on this. I tried before with the other .js that someone posted but then the browser said that there was a missin .css file even when in my code there was still the link to the regular.css (the one from mapbox site) so that's why I'm not sure how to include a new .js on my code.

Thanks,

So now that we have @mpulkki-mapbox's awesome work from #8975 merged, are there any issues with flicking the switch and increasing the maximum allowable pitch (

https://github.com/mapbox/mapbox-gl-js/blob/51d75fc7d67a6158e69af5384fa17bee29c39a0b/src/ui/map.js#L111
) to something > 60?

From my testing it seems to be working great after changing the defaultMaxPitch to 85. Even setting to 90 nothing crashes!

I changed defaultMaxPitch to 85/90 in mapbox-gl-js/src/ui/map.js and it did not have any effect on the max pitch for me.
I could not get to a higher pitch by setting 85/90 when initlizing the map or by a right mouse drag pitch increase.
Am I missing anything? Do I need to include further code? I am currently using version 1.12.0.

As a workaround, you can use TerrainLayer - that will go > 90 pitch no problem.

As a workaround, you can use TerrainLayer - that will go > 90 pitch no problem.

It does not seem like that is an initial functionality:
https://docs.mapbox.com/vector-tiles/reference/mapbox-terrain-v2/
Just adding one and tying to pitch > 90 or set the map pitch to > 90 does not work for me.
@neon-ninja can you provide example?

As a workaround, you can use TerrainLayer - that will go > 90 pitch no problem.

It does not seem like that is an initial functionality:
https://docs.mapbox.com/vector-tiles/reference/mapbox-terrain-v2/
Just adding one and tying to pitch > 90 or set the map pitch to > 90 does not work for me.
@neon-ninja can you provide example?

Sure - here's a codepen https://codepen.io/neonninja/pen/eYzQEQq
Hold shift or control and drag with left mouse button to tilt and go underground

As a workaround, you can use TerrainLayer - that will go > 90 pitch no problem.

It does not seem like that is an initial functionality:
https://docs.mapbox.com/vector-tiles/reference/mapbox-terrain-v2/
Just adding one and tying to pitch > 90 or set the map pitch to > 90 does not work for me.
@neon-ninja can you provide example?

Sure - here's a codepen https://codepen.io/neonninja/pen/eYzQEQq
Hold shift or control and drag with left mouse button to tilt and go underground

Thanks a lot for the example. It seems that this is then a deckGL mapbox implementation?
I suppose adding a TerrainLayer to the classic new mapboxgl.Map wouldnt work with the pitch > 90, because that does not provide the atribute of initialViewState? Combinations then gets problematic when pitching > 90: https://codepen.io/illsio/pen/VwjqzWL

As a workaround, you can use TerrainLayer - that will go > 90 pitch no problem.

It does not seem like that is an initial functionality:
https://docs.mapbox.com/vector-tiles/reference/mapbox-terrain-v2/
Just adding one and tying to pitch > 90 or set the map pitch to > 90 does not work for me.
@neon-ninja can you provide example?

Sure - here's a codepen https://codepen.io/neonninja/pen/eYzQEQq
Hold shift or control and drag with left mouse button to tilt and go underground

Thanks a lot for the example. It seems that this is then a deckGL mapbox implementation?
I suppose adding a TerrainLayer to the classic new mapboxgl.Map wouldnt work with the pitch > 90, because that does not provide the atribute of initialViewState? Combinations then gets problematic when pitching > 90: https://codepen.io/illsio/pen/VwjqzWL

I don't think TerrainLayer relies on mapbox at all, except as a tile provider. To clarify, my suggested workaround was to use TerrainLayer as your basemap, and disable the mapbox.gl basemap. I think the more imminent problem there is that you're hitting the hardcoded limit of 60. The deck.gl layer can then go beyond while the map stays stuck at 60.
image

Unlocked pitch to up to 85 degrees was added as part of the v2 release: https://github.com/mapbox/mapbox-gl-js/pull/10160.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Scarysize picture Scarysize  Â·  3Comments

BernhardRode picture BernhardRode  Â·  3Comments

aderaaij picture aderaaij  Â·  3Comments

shotor picture shotor  Â·  3Comments

PBrockmann picture PBrockmann  Â·  3Comments