You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
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.
The text was updated successfully, but these errors were encountered:
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:
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.
The text was updated successfully, but these errors were encountered: