Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[new feature] support centre offset #4299

Closed
remster opened this issue Feb 20, 2017 · 1 comment
Closed

[new feature] support centre offset #4299

remster opened this issue Feb 20, 2017 · 1 comment

Comments

@remster
Copy link
Contributor

remster commented Feb 20, 2017

Motivation

With the vector map that supports the pitch it is often (in navigation solutions) desirable to offset the map centre closer the user's point of view as shown here:
centeroffset

In other words, to allow map.flyTo render the requested center away from the map container center.
The away could be specified as pix or percentage offset from the map container center.

Design Alternatives

I achieve this today as follows:
(I am sorry, i can't paste the code w/o losing line breaks)
let transform = new map.transform.constructor();
transform.resize(map.transform.width, map.transform.height);
transform.zoom = options.zoom;
transform.bearing = options.bearing;
transform.pitch = options.pitch;
transform.center = options.center;
let screenBottom = transform.pointLocation(
new mapboxgl.Point(map.transform.width/2, map.transform.height)
);
options.center = new mapboxgl.LngLat(
options.center.lng - (screenBottom.lng - options.center.lng)/2,
options.center.lat - (screenBottom.lat - options.center.lat)/2
);

Namely:
(1) i speculate the transform as if with the centre matching the container.
(2) i calculate a LngLat vector between that center and screen's bottom.
(3) adjust the center with the half of said vector.

but this really isn't the right way of going about it. This just needs some extra maths offered by the Transform class.

I think it is here in Transform._calcMatrices:
// 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])
const halfFov = this._fov / 2;
const groundAngle = Math.PI / 2 + this._pitch;
const topHalfSurfaceDistance = Math.sin(halfFov) * this.cameraToCenterDistance /
Math.sin(Math.PI - groundAngle - halfFov);

where it assumes the center point.

Design

(1) add centerOffset to the Transform (defaulting to [0,0]) which Transform._calcMatrices could use to adjust the assumed container center.
(2) allow centerOffset in the options for flyTo/easeTo and propagate to transform
(3) it strikes me that _calcMatrices (not a trivially cheap op) is called for every parameter individually. Perhaps it would be worth to change the design of the Tranform class to allow bulk changes like so:
transofrm.center(newCenter).pitch(newPitch).zoom(newZoom).execute();

Before i speculate/scrutinise the remaining aspects of this design i wanted to at least verify that this is something the community would welcome.

@lucaswoj
Copy link
Contributor

This is a duplicate of #4268 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants