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

MapLibre 4 custom modifications #2

Closed
wants to merge 1,120 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1120 commits
Select commit Hold shift + click to select a range
b62a6d0
Move angleToRotateBetweenVectors2D to utils
kubapelc Jul 11, 2024
5c48f38
Refactor _globeness usage
kubapelc Jul 11, 2024
aeece24
Remove _initialized from GlobeTransform
kubapelc Jul 11, 2024
8b79d16
Remove translatePosition from transform interface
kubapelc Jul 11, 2024
d0c40fe
Add IReadonlyTransform interface
kubapelc Jul 11, 2024
d002f61
Update build size
kubapelc Jul 11, 2024
639ed7f
Remove unneeded comment
kubapelc Jul 11, 2024
9e72755
Globe - transform+projection changes (#4341)
kubapelc Jul 12, 2024
172b714
Merge branch 'kubapelc/globe-vector' into merge-tmp
kubapelc Jul 15, 2024
1faaada
Merge remote-tracking branch 'upstream/globe' into merge-tmp
kubapelc Jul 15, 2024
01e39fd
Fix merge
kubapelc Jul 15, 2024
7dcc220
Better param comments for coveringZoom and coveringTiles
kubapelc Jul 15, 2024
52b4294
Camera controls changes from dev branch
kubapelc Jul 15, 2024
36098ca
Move stuff from globe_control_utils to globe_utils
kubapelc Jul 15, 2024
aa8959d
Merge commit '52b42945af6b922291d78d6c718ac89e7f9acc10' into kubapelc…
kubapelc Jul 15, 2024
ba6019d
Merge branch 'kubapelc/globe-pr-controls' into kubapelc/globe-vector-dev
kubapelc Jul 15, 2024
dfb833c
Better globe_utils comments
kubapelc Jul 15, 2024
c65cb17
Fix markers not being updated when globe is toggled
kubapelc Jul 15, 2024
0a53926
Fix globe tests
kubapelc Jul 15, 2024
4123e14
Update build size
kubapelc Jul 15, 2024
0cdbdd7
Merge branch 'kubapelc/globe-pr-controls' into kubapelc/globe-vector-dev
kubapelc Jul 15, 2024
3f7ff10
Better comments for camera helper functions
kubapelc Jul 15, 2024
2548bae
Move camera helper functions to beginning of file
kubapelc Jul 15, 2024
2b20bad
Camera: more and better comments
kubapelc Jul 15, 2024
0a5e601
Update build size
kubapelc Jul 15, 2024
4992d10
Fix globe transform error correction handling
kubapelc Jul 17, 2024
f2b3257
Better comments for _last* fields in globe transform
kubapelc Jul 17, 2024
d6097bd
Refactor newFrameUpdate
kubapelc Jul 17, 2024
e0b6f0b
Better comments for CoveringTilesOptions type members.
kubapelc Jul 17, 2024
138c42e
Refactor globe camera tests to use more describe statements
kubapelc Jul 17, 2024
9353096
Remove isTilePositionOccluded function from transform interface
kubapelc Jul 17, 2024
ad70291
Fix camera tests
kubapelc Jul 19, 2024
b619352
Add more mercator_utils test
kubapelc Jul 19, 2024
4998218
Add more globe_transform tests
kubapelc Jul 19, 2024
96fec9c
Fix failing render tests
kubapelc Jul 19, 2024
4831167
Make camera helper functions static
kubapelc Jul 19, 2024
c559504
Remove `around` from flyTo options.
kubapelc Jul 19, 2024
54eae63
Update build size
kubapelc Jul 19, 2024
5cd1273
Fix globe examples
kubapelc Jul 20, 2024
9e42d64
Merge branch 'kubapelc/globe-pr-controls' into kubapelc/globe-vector-dev
kubapelc Jul 20, 2024
1cb86be
Globe coveringTiles attempt
kubapelc Jul 20, 2024
5cd9eb0
CameraHelper: initial implementation, inertia handling
kubapelc Jul 21, 2024
a607c17
Move createVec* functions to util.ts
kubapelc Jul 21, 2024
3c50b0f
CameraHelper: panning and zooming
kubapelc Jul 21, 2024
203aa8e
CameraHelpers: implement cameraForBounds
kubapelc Jul 21, 2024
815aab3
CoveringTiles: use frustum+AABB test for globe
kubapelc Jul 22, 2024
ab054db
CoveringTiles: works well for globe
kubapelc Jul 22, 2024
1e9da3a
Fix mercator coveringTiles
kubapelc Jul 22, 2024
d8bbe32
CoveringTiles: proper tile LOD for globe
kubapelc Jul 22, 2024
595d1a1
CoveringTiles: fix LOD, add comments
kubapelc Jul 22, 2024
de7ea0d
Rename globe custom layer example
kubapelc Jul 25, 2024
ce338b4
Globe custom: add explanation of horizon clipping
kubapelc Jul 25, 2024
e84f277
Globe custom: tiles example (WIP)
kubapelc Jul 25, 2024
a849cd8
Globe custom: tile example done
kubapelc Jul 26, 2024
90d8727
Merge branch 'main' into globe
HarelM Jul 27, 2024
b83bee8
Fix painter test
HarelM Jul 27, 2024
5fea74a
Merge branch 'main' into globe
HarelM Jul 27, 2024
b655ef3
CameraHelpers: handle jumpTo
kubapelc Jul 28, 2024
d7ecf37
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-pr-…
kubapelc Jul 28, 2024
97ec4db
Merge branch 'kubapelc/globe-pr-controls' into kubapelc/globe-pr-cont…
kubapelc Jul 28, 2024
b50dee6
CameraHelper: easeTo
kubapelc Jul 28, 2024
e8a588a
CameraHelper: flyTo
kubapelc Jul 28, 2024
0240d08
Projection event contains new projection name and is fired by changin…
kubapelc Jul 28, 2024
465b178
Fix lint
kubapelc Jul 29, 2024
d422416
Fix test camera/map not having proper CameraHelper
kubapelc Jul 29, 2024
836be51
Fix easeTo not emitting zoom events
kubapelc Jul 29, 2024
6b02e78
Fix cameraForBoxAndBearing globe not returning anything, rename camer…
kubapelc Jul 29, 2024
36a8533
Fix globe easeTo ignoring offset
kubapelc Jul 29, 2024
7eb0205
Fix one flyTo test not creating camera properly
kubapelc Jul 29, 2024
2682810
Update build size
kubapelc Jul 29, 2024
d5b6819
Add projection transition event tests
kubapelc Jul 29, 2024
cddb58e
Globe 3D model example init
kubapelc Jul 28, 2024
7f93413
Merge remote-tracking branch 'upstream/globe' into kubapelc/fix
kubapelc Jul 29, 2024
5ae987d
Merge branch 'kubapelc/globe-pr-controls' into kubapelc/fix
kubapelc Jul 29, 2024
a535aef
Fix merge
kubapelc Jul 29, 2024
c5f9d48
Custom 3D model: mercator returns correct matrix
kubapelc Jul 29, 2024
599158d
Custom 3D model: globe returns proper matrix
kubapelc Jul 29, 2024
9979f14
Fix globe examples descriptions and other misc
kubapelc Jul 29, 2024
27e5b80
Add example on how to compensate for how globe size changes with lati…
kubapelc Jul 29, 2024
d5709cd
Merge branch 'main' into globe
HarelM Aug 1, 2024
6973a03
Fix lint
HarelM Aug 1, 2024
3e67533
Merge branch 'main' into globe
HarelM Aug 1, 2024
f4d7926
Update test/build/min.test.ts
HarelM Aug 1, 2024
8c6145b
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-pr-…
kubapelc Aug 2, 2024
15a8650
Revert scrollzoom delete removal
kubapelc Aug 2, 2024
6b6463d
Remove apparentZoom parameter
kubapelc Aug 2, 2024
410d2e5
CameraHelper is set in camera constuctor
kubapelc Aug 2, 2024
b8b8433
Update build size
kubapelc Aug 3, 2024
aa964a5
Merge branch 'kubapelc/globe-pr-controls-dev' into kubapelc/globe-pre…
kubapelc Aug 3, 2024
d3e6374
Merge branch 'main' into globe
HarelM Aug 4, 2024
c181cb4
Update changelog
HarelM Aug 4, 2024
cf81cc8
Fix failing seams render test
kubapelc Aug 4, 2024
4d3eaed
Fix projection change not updating visible tiles
kubapelc Aug 4, 2024
1343c56
Update build size
kubapelc Aug 4, 2024
c20d5c8
Improve example comment
kubapelc Aug 5, 2024
df103ef
Cleanup example
kubapelc Aug 5, 2024
47286e9
Merge branch 'kubapelc/globe-presentable' into kubapelc/globe-vector-dev
kubapelc Aug 5, 2024
f6dd27e
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-pr-…
kubapelc Aug 5, 2024
151b071
Merge branch 'kubapelc/globe-pr-controls-dev' into kubapelc/globe-vec…
kubapelc Aug 5, 2024
aee09ff
Use spy for projection event unit tests
kubapelc Aug 6, 2024
30937cf
Remove unnecessary done() in tests
kubapelc Aug 6, 2024
9c2a466
Update build size
kubapelc Aug 6, 2024
8d72e77
Remove more unneeded done() calls
kubapelc Aug 6, 2024
cc24dd8
Merge branch 'main' into globe
HarelM Aug 6, 2024
41e0b02
Do not use map.once callback in projection events tests
kubapelc Aug 7, 2024
e5356ad
Better zoom delta example title and description
kubapelc Aug 7, 2024
dc9b158
Rename globe zoom delta and planet size function example
kubapelc Aug 7, 2024
73e0201
Add zoom planet size function example image
kubapelc Aug 7, 2024
5e1e774
Reduce size of some globe example images using compresspng
kubapelc Aug 7, 2024
2f81dd7
Globe - camera controls (#4408)
kubapelc Aug 7, 2024
7c5970c
Merge branch 'kubapelc/globe-pr-controls' into kubapelc/globe-vector-dev
kubapelc Aug 7, 2024
2014685
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-vec…
kubapelc Aug 7, 2024
316a167
Better example comments
kubapelc Aug 9, 2024
584f876
Fix raster tiles sometimes being warped under globe projection
kubapelc Aug 12, 2024
46f511b
Port bugfix changes
kubapelc Aug 12, 2024
472a692
Update build size
kubapelc Aug 12, 2024
52d0c53
Make globe custom example triangle more visible
kubapelc Aug 12, 2024
93990bb
Add example image for globe custom simple
kubapelc Aug 12, 2024
8bfd9df
Fix render tests
kubapelc Aug 12, 2024
398f0d1
Add render test result for debian
kubapelc Aug 12, 2024
f062c42
Increase raster tile granularity some more
kubapelc Aug 12, 2024
71807f2
Adjust warped raster tile render test
kubapelc Aug 12, 2024
b288e18
Merge branch 'kubapelc/globe-pr-bugfixes' into kubapelc/globe-vector-dev
kubapelc Aug 12, 2024
d1df761
Add more expected images to raster-warped test
kubapelc Aug 12, 2024
1064d12
Add image for globe custom tiles example
kubapelc Aug 12, 2024
324b3c8
Adjust globe 3D model example default map center, zoom & pitch
kubapelc Aug 12, 2024
98ffaf2
Add globe 3D model example image
kubapelc Aug 12, 2024
f317aac
Improve 3D model example comments
kubapelc Aug 12, 2024
06c19e0
Merge branch 'main' into globe
HarelM Aug 12, 2024
5f0630f
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-pr-…
kubapelc Aug 12, 2024
c3bd00e
Add missing tsdoc param
kubapelc Aug 12, 2024
2b39cfe
Use single checkerboard image for render test
kubapelc Aug 12, 2024
364b1f4
Globe examples now use setProjection
kubapelc Aug 12, 2024
061c674
Add new raster-pole render test image
kubapelc Aug 12, 2024
4929fe7
Add another raster-warped expected image
kubapelc Aug 12, 2024
f393259
Merge branch 'kubapelc/globe-pr-bugfixes' into kubapelc/globe-vector-dev
kubapelc Aug 12, 2024
4782c24
Custom layer args code deduplication WIP
kubapelc Aug 12, 2024
24d3ab7
Globe custom tiles example projection toggle button
kubapelc Aug 12, 2024
fad22fe
Refactor custom layer args generation, custom tiles support mercator
kubapelc Aug 13, 2024
88187c7
Refactor examples to not use fetch
kubapelc Aug 13, 2024
dd9c0c7
Use "style.load" event on map instead of on style
kubapelc Aug 13, 2024
1101899
Merge branch 'kubapelc/globe-pr-bugfixes' into kubapelc/globe-vector-dev
kubapelc Aug 13, 2024
545d711
Add note about globe to 3D model example
kubapelc Aug 13, 2024
7f3220f
Globe: bugfixes: raster layer & projection change (#4546)
kubapelc Aug 13, 2024
3212a7b
Globe docs - init
kubapelc Aug 13, 2024
d07d97a
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-vec…
kubapelc Aug 13, 2024
a109465
Another piece of docs
kubapelc Aug 13, 2024
b3f6d27
Write more globe docs
kubapelc Aug 17, 2024
b70e485
Fix typos
kubapelc Aug 19, 2024
616bba6
More comments for custom layer args
kubapelc Aug 19, 2024
645e7f6
Port custom layer changes and globe docs
kubapelc Aug 19, 2024
77b1a46
Port transform changes
kubapelc Aug 19, 2024
0081170
Fix custom layer unit test
kubapelc Aug 19, 2024
2a068f3
Fix failing render tests
kubapelc Aug 19, 2024
51d0a58
Update build size
kubapelc Aug 19, 2024
0fbf464
Update globe custom layer example descritions, remove forgotten code
kubapelc Aug 19, 2024
bd10a02
Remove unused util function
kubapelc Aug 19, 2024
18f5d88
Incorporate globe docs feedback
kubapelc Aug 20, 2024
f8b46aa
Refactor and expose tile mesh generation
kubapelc Aug 20, 2024
d5d90f6
Refactor custom layers to get smaller args object and access map tran…
kubapelc Aug 20, 2024
f777b06
Simplify more of the custom layer API
kubapelc Aug 20, 2024
0148b2e
Clean up and adapt more examples
kubapelc Aug 20, 2024
11f2786
Fix mercator matrix precision
kubapelc Aug 20, 2024
4be9b35
Fix 3D model on terrain example
kubapelc Aug 20, 2024
3366971
Rename projectionDataForMercatorCoords to defaultProjectionData
kubapelc Aug 20, 2024
436ba55
Document ProjectionData type
kubapelc Aug 20, 2024
37cce84
Update build size
kubapelc Aug 20, 2024
705c8bf
Update developer-guides/globe.md
kubapelc Aug 20, 2024
8c45af4
Merge branch 'main' into globe
HarelM Aug 22, 2024
588cad2
Decouple ProjectionData from rendering code
kubapelc Aug 26, 2024
e9a2730
Rename ProjectionData members
kubapelc Aug 26, 2024
5644e85
Fix mercator transform unit tests
kubapelc Aug 26, 2024
c101948
Add an example to createTileMesh
kubapelc Aug 26, 2024
082c3e9
Rename CustomRenderMethodInput.shader to shaderData
kubapelc Aug 26, 2024
0a0ec88
Add shaderData examples
kubapelc Aug 26, 2024
15b0d08
Document TileMesh and CreateTileMeshOptions types
kubapelc Aug 26, 2024
49fbf18
Fix custom layers in render tests
kubapelc Aug 26, 2024
18105dc
Update render tests
kubapelc Aug 26, 2024
ccad6e8
Add render test result from linux
kubapelc Aug 26, 2024
541f5f6
Update build size
kubapelc Aug 26, 2024
778b325
Update src/render/program/projection_program.ts
kubapelc Aug 26, 2024
02c2334
Rename createTileMeshInternal to createTileMeshWithBuffers
kubapelc Aug 26, 2024
359da6c
Merge branch 'main' into globe
kubapelc Aug 26, 2024
0ffbbba
Adapt new heatmap code for globe, update build size
kubapelc Aug 26, 2024
b2a98b7
Fix render tests
kubapelc Aug 26, 2024
3a2fffc
Merge remote-tracking branch 'upstream/globe' into globe-pr-custom
kubapelc Aug 26, 2024
8222f48
Update build size
kubapelc Aug 26, 2024
ed1437e
Merge branch 'main' into globe
HarelM Aug 26, 2024
cf17bb6
Improve doc comments
kubapelc Aug 27, 2024
80fb24a
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-vec…
kubapelc Aug 27, 2024
2b0b120
Merge branch 'globe-pr-custom' into kubapelc/globe-vector-dev
kubapelc Aug 27, 2024
b859df9
Globe - custom layers API and examples, globe dev guide (#4577)
kubapelc Aug 27, 2024
d2f0abc
Merge branch 'globe' into kubapelc/globe-vector-dev
kubapelc Aug 27, 2024
2f8e566
Import coveringTiles changes from dev branch
kubapelc Aug 27, 2024
21b99fa
Remove duplicated tiles used in render tests
kubapelc Aug 27, 2024
1fce5b3
Remove unused function
kubapelc Aug 27, 2024
c732c26
Fix typo
kubapelc Aug 27, 2024
023c358
Properly handle tile wraps and LOD across antimeridian
kubapelc Aug 27, 2024
0d22a6f
Discard previous changes and use custom wrap values instead
kubapelc Aug 27, 2024
2391f77
Merge branch 'kubapelc/globe-pr-covering-tiles' into kubapelc/globe-v…
kubapelc Aug 27, 2024
a82ff69
Update build size
kubapelc Aug 27, 2024
a6ffb4a
Add render test for LOD at antimeridian
kubapelc Aug 27, 2024
decd85c
Merge branch 'main' into globe
HarelM Aug 29, 2024
ddd2ba6
Convert visibility numbers to enum
kubapelc Sep 2, 2024
d791658
Refactor globe covering tiles into a separate file
kubapelc Sep 2, 2024
5fc9e8b
Add yet another raster-warped expected image
kubapelc Sep 2, 2024
362aecf
Add unit tests for globe covering tiles
kubapelc Sep 2, 2024
6eb0267
Refactor globe coveringTiles math to assume worldSize=1 instead of ti…
kubapelc Sep 2, 2024
87f54bf
Split globe coveringTiles into more functions
kubapelc Sep 2, 2024
8f28868
Explain radiusOfMaxLvlLodInTiles value
kubapelc Sep 2, 2024
3f9c6b9
Explain why checking 4 tile corners is (mostly) enough to construct a…
kubapelc Sep 2, 2024
906db04
Move mercator coveringTiles into a separate file
kubapelc Sep 2, 2024
1658525
Yet another raster-warped expected image
kubapelc Sep 2, 2024
6c030cb
Merge branch 'kubapelc/globe-pr-covering-tiles' into kubapelc/globe-v…
kubapelc Sep 2, 2024
3d9ca2c
Symbol placement optimizations
kubapelc Sep 2, 2024
f7b577b
Remove ITileVisibilityProvider interface
kubapelc Sep 2, 2024
bbc6800
Use explicit types
kubapelc Sep 2, 2024
73d9fc6
PR feedback
kubapelc Sep 2, 2024
17c2e19
Rename coveringTiles stack types
kubapelc Sep 3, 2024
353f830
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-pr-…
kubapelc Sep 3, 2024
86b9fc3
Globe - Covering tiles (#4615)
kubapelc Sep 3, 2024
4243462
Merge branch 'kubapelc/globe-pr-covering-tiles' into kubapelc/globe-v…
kubapelc Sep 3, 2024
1380544
Merge remote-tracking branch 'upstream/globe' into kubapelc/globe-vec…
kubapelc Sep 3, 2024
3e875b2
Fix slow matrix assignment / revert 64bit matrices everywhere
kubapelc Sep 3, 2024
59f5785
Additional matrix precision fix
kubapelc Sep 3, 2024
38cf5a8
Merge branch 'main' into globe
HarelM Sep 4, 2024
798b7e8
Merge branch 'main' into globe
HarelM Sep 4, 2024
f3b7d32
Merge branch 'main' into globe
HarelM Sep 11, 2024
5a6d815
fix typo
HarelM Sep 11, 2024
97dcd88
Merge branch 'main' into globe
HarelM Sep 12, 2024
471c996
Remove sky disabling in examples as this is no longer needed.
HarelM Sep 12, 2024
99d58a8
Merge branch 'main' into globe
HarelM Sep 12, 2024
555ce7b
Fix spelling
HarelM Sep 12, 2024
aba2735
Fix spelling - unencode
HarelM Sep 23, 2024
ebd791f
Fix more spelling
HarelM Sep 23, 2024
3a1be48
Merge branch 'main' into globe
HarelM Sep 23, 2024
d0981a0
Fix lint
HarelM Sep 23, 2024
de5c024
Merge branch 'globe' into kubapelc/globe-vector-dev
kubapelc Sep 23, 2024
20e5647
Optimize coveringTiles, optimize placeCollisionBox by inlining globe …
kubapelc Sep 23, 2024
10ae0fd
Update render tests
kubapelc Sep 23, 2024
291fd41
Merge remote-tracking branch 'upstream/main' into kubapelc/globe-vect…
kubapelc Sep 25, 2024
c994e01
Allow maxBounds to only limit latitude
wschilpat Sep 25, 2024
070842f
Add support for custom texture formats in raster-tile-source
wschilpat Jul 31, 2024
473baf6
Fix setting of texture format
wschilpat Sep 4, 2024
af2ba0d
Add exports for Event, Tile, and SourceCache
wschilpat Sep 26, 2024
b64ce21
Rename package
wschilpat Oct 1, 2024
775c3ba
Reset package.json formatting
wschilpat Oct 1, 2024
cbbc3e4
Update readme
wschilpat Oct 1, 2024
e6e91ff
Remove anotation, add WebGL2 check
wschilpat Oct 1, 2024
fcc0b44
Fix lint
kubapelc Oct 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 4.7.1-beta.1

- Added custom features that were not part of the main branch
- viewport tile padding
- latitude bounds
- support for texture formats other than gl.RGBA used by raster tile sources
- exports for Event, Tile, SourceCache, and OverscaledTileID

# === LeafletGL follows ===

## main

### ✨ Features and improvements
Expand Down Expand Up @@ -50,6 +60,8 @@ using `transformCameraUpdate` caused the `maxBounds` to stop working just for ea

### ✨ Features and improvements

- Merge atmosphere an sky implementation ([#3888](https://github.com/maplibre/maplibre-gl-js/issues/3888))
- Add option to display a realistic atmosphere when using a Globe projection ([#3888](https://github.com/maplibre/maplibre-gl-js/issues/3888))
- Emit events when the cooperative gestures option has prevented a gesture. ([#4470](https://github.com/maplibre/maplibre-gl-js/pull/4470))
- Enable anisotropic filtering only when the pitch is greater than 20 degrees to preserve image sharpness on flat or slightly tilted maps.

Expand Down
2 changes: 1 addition & 1 deletion build/generate-doc-images.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ async function createImage(exampleName) {
try {
await page.waitForFunction('map.loaded()');
// Wait for 5 seconds on 3d model examples, since this takes longer to load.
const waitTime = exampleName.includes('3d-model') ? 5000 : 1500;
const waitTime = (exampleName.includes('3d-model') || exampleName.includes('globe')) ? 5000 : 1500;
console.log(`waiting for ${waitTime} ms`);
await new Promise(resolve => setTimeout(resolve, waitTime));
} catch (err) {
Expand Down
Binary file added developer-guides/assets/floats.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added developer-guides/assets/no_subdivision.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added developer-guides/assets/wireframe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
195 changes: 195 additions & 0 deletions developer-guides/globe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
# Globe projection

This guide describes the inner workings of globe projection.
Globe draws the same vector polygons and lines as mercator projection,
ensuring a clear, unstretched image at all view angles and support for dynamic layers and geometry.

The actual projection is done in three steps:

- compute angular spherical coordinates from source web mercator tile data
- convert spherical coordinates to a 3D vector - a point on the surface of a unit sphere
- project the 3D vector using a common perspective projection matrix

So the globe is a unit sphere from the point of view of projection.
This also simplifies a lot of math, and is used extensively in the globe transform class.

Geometry is projected to the sphere in the vertex shader.

## Zoom behavior

To stay consistent with web mercator maps, globe is automatically enlarged when map center is nearing the poles.
This keeps the map center visually similar to a mercator map with the same x,y and zoom.
However, when panning the globe or performing camera animations,
we do not want the planet to get larger or smaller when changing latitudes.
Map movement thus compensates for the planet size change by also
changing zoom level along with latitude changes.

This behavior is completely automatic and transparent to the user.
The only case when the user needs to be aware of this is when
programmatically triggering animations such as `flyTo` and `easeTo`
and using them to both change the map center's latitude and *at the same time*
changing the map's zoom to an amount based on the map's starting zoom.
The example [globe-zoom-planet-size-function](https://maplibre.org/maplibre-gl-js/docs/examples/globe-zoom-planet-size-function/) demonstrates how to
compensate for planet size changes in this case.
All other camera animations (that either specify target zoom
that is not based on current zoom or do not specify zoom at all) will work as expected.

## Shaders

Most vertex shaders use the `projectTile` function, which
accepts a 2D vector of coordinates inside the currently drawn tile,
in range 0..EXTENT (8192), and returns its final projection that can
be directly passed to `gl_Position`.
When drawing a tile, proper uniforms must be set to convert from
these tile-local coordinates to web mercator.

The implementation of `projectTile` is automatically injected into the shader source code.
Different implementations can be injected, depending on the currently active projection.
Thanks to this many shaders use the exact same code for both mercator and globe,
although there are shaders that use `#ifdef GLOBE` for globe-specific code.

## Subdivision

If we were to draw mercator tiles with globe shaders directly, we would end up with a deformed sphere.
This is due to how polygons and lines are triangulated in MapLibre - the earcut algorithm
creates as few triangles as possible, which can sometimes result in huge triangles, for example in the oceans.
This behavior is desirable in mercator maps, but if we were to project the vertices of such large triangles to globe directly,
we would not get curved horizons, lines, etc.
For this reason, before a tile is finished loading, its geometry (both polygons and lines) is further subdivided.

The figure below demonstrates how globe would look without subdivision.
Note the deformed oceans, and the USA-Canada border that is not properly curved.

![](assets/no_subdivision.png)

It is critical that subdivision is as fast as possible, otherwise it would significantly slow down tile loading.
Currently the fastest approach seems to be taking the output geometry from `earcut` and subdividing that further.

When modifying subdivision, beware that it is very prone to subtle errors, resulting in single-pixel seams.
Subdivision should also split the geometry in consistent places,
so that polygons and lines match up correctly when projected.

We use subdivision that results in a square grid, visible in the figure below.

![](assets/wireframe.png)

Subdivision is configured in the Projection object.
Subdivision granularity is defined by the base tile granularity and minimal allowed granularity.
The tile for zoom level 0 will have base granularity, tile for zoom 1 will have half that, etc.,
but never less than minimal granularity.

The maximal subdivision granularity of 128 for fill layers is enough to get nicely curved horizons,
while also not generating too much new geometry and not overflowing the 16 bit vertex indices used throughout MapLibre.

Raster tiles in particular need a relative high base granularity, as otherwise they would exhibit
visible warping and deformations when changing zoom levels.

## Floating point precision & transitioning to mercator

Shaders work with 32 bit floating point numbers (64 bit are possible on some platforms, but very slow).
The 23 bits of mantissa and 1 sign bit can represent at most around 16 million values,
but the circumference of the earth is roughly 40 000 km, which works out to
about one float32 value per 2.5 meters, which is insufficient for a map.
Thus if we were to use globe projection at all zoom levels, we would unsurprisingly encounter precision issues.

![](assets/floats.png)

To combat this, globe projection automatically switches to mercator projection around zoom level 12.
This transition is smooth, animated and can only be noticed if you look very closely,
because globe and mercator projections converge at high zoom levels, and around level 12
they are already very close.

The transition animation is implemented in the shader's projection function,
and is controlled by a "globeness" parameter passed from the transform.

## GPU "atan" error correction

When implementing globe, we noticed that globe projection did not match mercator projection
after the automatic transition described in previous section.
This mismatch was very visible at certain latitudes, the globe map was shifted north/south by hundreds of meters,
but at other latitudes the shift was much smaller. This behavior was also inconsistent - one would
expect the shift to gradually increase or decrease with distance from equator, but that was not the case.

Eventually, we tracked this down to an issue in the projection shader, specifically the `atan` function.
On some GPU vendors, the function is inaccurate in a way that matches the observed projection shifts.

To combat this, every second we draw a 1x1 pixel framebuffer and store the `atan` value
for the current latitude, asynchronously download the pixel's value, compare it with `Math.atan`
reference, and shift the globe projection matrix to compensate.
This approach works, because the error is continuous and doesn't change too quickly with latitude.

This approach also has the advantage that it works regardless of the actual error of the `atan`,
so MapLibre should work fine even if it runs on some new GPU in the future with different
`atan` inaccuracies.

## Clipping

When drawing a planet, we need to somehow clip the geometry that is on its backfacing side.
Since MapLibre uses the Z-buffer for optimizing transparency drawing, filling it with custom
values, we cannot use it for this purpose.

Instead, we compute a plane that intersects the horizons, and for each vertex
we compute the distance from this plane and store it in `gl_Position.z`.
This forces the GPU's clipping hardware to clip geometry beyond the planet's horizon.
This does not affect MapLibre's custom Z values, since they are set later using
`glDepthRange`.

However this approach does not work on some phones due to what is likely a driver bug,
which applies `glDepthRange` and clipping in the wrong order.
So additionally, face culling is used for fill and raster layers
(earcut does not result in consistent winding order, this is ensured during subdivision)
and line layers (which have inconsistent winding order) discard beyond-horizon
pixels in the fragment shader.

## Raster tiles

Drawing raster tiles under globe is somewhat more complex than under mercator,
since under globe they are much more prone to having slight seams between tiles.
Tile are drawn as subdivided meshes instead of simple quads, and the curvature
near the edges can cause seams, especially in cases when two tiles of different
zoom levels are next to each other.

To make sure that there are both no seams and that every pixel is covered by
valid tile texture (as opposed to a stretched border of a neighboring tile),
we first draw all tiles *without* border, marking all drawn pixels in stencil.
Then, we draw all tiles *with* borders, but set stencil to discard all pixels
that were drawn in the first pass.

This ensures that no pixel is drawn twice, and that the stretched borders
are only drawn in regions between tiles.

## Symbols

Symbol rendering also had to be adapted for globe, as well as collision detection and placement.
MapLibre computed well-fitting bounding boxes even for curved symbols under globe projection
by computing the AABB from a projection of the symbol's box' corners and box edge midpoints.
This is an approximation, but works well in practice.

## Transformations and unproject

Most projection and unproject functions from the transform interface are adapted for globe,
with some caveats.
The `setLocationAtPoint`function may sometimes not find a valid solution
for the given parameters.
Globe transform currently does not support constraining the map's center.

## Controls

Globe uses slightly different controls than mercator map.
Panning, zooming, etc. is aware of the sphere and should work intuitively,
as well as camera animations such as `flyTo` and `easeTo`.

Specifically, when zooming, the location under the cursor stays under the cursor,
just like it does on a mercator map.
However this behavior has some limitations on the globe.
In some scenarios, such as zooming to the edge of the planet,
this way of zooming would result in rapid and unpleasant map panning.
Thus this behavior is slowly faded out at low zooms and replaced with an approximation.

There are also other edge cases, such as when looking at the planet's poles
and trying to zoom in to a location that is on the other hemisphere ("behind the pole").
MapLibre does not support moving the camera across poles, so instead we need to rotate around.
In this case, an approximation instead of exact zooming is used as well.

Globe controls also use panning inertia, just like mercator.
Special care was taken to keep the movement speed of inertia consistent.
Binary file added docs/assets/examples/globe-3d-model.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/examples/globe-atmosphere.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/examples/globe-custom-simple.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/examples/globe-custom-tiles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/examples/globe-fill-extrusion.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/assets/examples/globe-vector-tiles.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "maplibre-gl",
"name": "@windycom/maplibre-gl",
"description": "BSD licensed community fork of mapbox-gl, a WebGL interactive maps library",
"version": "4.7.1",
"main": "dist/maplibre-gl.js",
Expand Down Expand Up @@ -189,4 +189,4 @@
"npm": ">=8.1.0",
"node": ">=16.14.0"
}
}
}
2 changes: 2 additions & 0 deletions src/data/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type {ImagePosition} from '../render/image_atlas';
import type {CanonicalTileID} from '../source/tile_id';
import type {VectorTileFeature, VectorTileLayer} from '@mapbox/vector-tile';
import Point from '@mapbox/point-geometry';
import type {SubdivisionGranularitySetting} from '../render/subdivision_granularity_settings';

export type BucketParameters<Layer extends TypedStyleLayer> = {
index: number;
Expand All @@ -26,6 +27,7 @@ export type PopulateParameters = {
patternDependencies: {};
glyphDependencies: {};
availableImages: Array<string>;
subdivisionGranularity: SubdivisionGranularitySetting;
};

export type IndexedFeature = {
Expand Down
98 changes: 69 additions & 29 deletions src/data/bucket/circle_bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,16 @@ import type Point from '@mapbox/point-geometry';
import type {FeatureStates} from '../../source/source_state';
import type {ImagePosition} from '../../render/image_atlas';
import type {VectorTileLayer} from '@mapbox/vector-tile';
import {CircleGranularity} from '../../render/subdivision_granularity_settings';

const VERTEX_MIN_VALUE = -32768; // -(2^15)

// Extrude is in range 0..7, which will be mapped to -1..1 in the shader.
function addCircleVertex(layoutVertexArray, x, y, extrudeX, extrudeY) {
// We pack circle position and extrude into range 0..65535, but vertices are stored as *signed* 16-bit integers, so we need to offset the number by 2^15.
layoutVertexArray.emplaceBack(
(x * 2) + ((extrudeX + 1) / 2),
(y * 2) + ((extrudeY + 1) / 2));
VERTEX_MIN_VALUE + (x * 8) + extrudeX,
VERTEX_MIN_VALUE + (y * 8) + extrudeY);
}

/**
Expand Down Expand Up @@ -82,12 +87,21 @@ export class CircleBucket<Layer extends CircleStyleLayer | HeatmapStyleLayer> im
let circleSortKey = null;
let sortFeaturesByKey = false;

// Heatmap circles are usually large (and map-pitch-aligned), tessellate them to allow curvature along the globe.
let subdivide = styleLayer.type === 'heatmap';

// Heatmap layers are handled in this bucket and have no evaluated properties, so we check our access
if (styleLayer.type === 'circle') {
circleSortKey = (styleLayer as CircleStyleLayer).layout.get('circle-sort-key');
const circleStyle = (styleLayer as CircleStyleLayer);
circleSortKey = circleStyle.layout.get('circle-sort-key');
sortFeaturesByKey = !circleSortKey.isConstant();

// Circles that are "printed" onto the map surface should be tessellated to follow the globe's curvature.
subdivide = subdivide || circleStyle.paint.get('circle-pitch-alignment') === 'map';
}

const granularity = subdivide ? options.subdivisionGranularity.circle : 1;

for (const {feature, id, index, sourceLayerIndex} of features) {
const needGeometry = this.layers[0]._featureFilter.needGeometry;
const evaluationFeature = toEvaluationFeature(feature, needGeometry);
Expand Down Expand Up @@ -121,7 +135,7 @@ export class CircleBucket<Layer extends CircleStyleLayer | HeatmapStyleLayer> im
const {geometry, index, sourceLayerIndex} = bucketFeature;
const feature = features[index].feature;

this.addFeature(bucketFeature, geometry, index, canonical);
this.addFeature(bucketFeature, geometry, index, canonical, granularity);
options.featureIndex.insert(feature, geometry, index, sourceLayerIndex, this.index);
}
}
Expand Down Expand Up @@ -156,37 +170,63 @@ export class CircleBucket<Layer extends CircleStyleLayer | HeatmapStyleLayer> im
this.segments.destroy();
}

addFeature(feature: BucketFeature, geometry: Array<Array<Point>>, index: number, canonical: CanonicalTileID) {
addFeature(feature: BucketFeature, geometry: Array<Array<Point>>, index: number, canonical: CanonicalTileID, granularity: CircleGranularity = 1) {
// Since we store the circle's center in each vertex, we only have 3 bits for actual vertex position in each axis.
// Thus the valid range of positions is 0..7.
// This gives us 4 possible granularity settings that are symmetrical.

// This array stores vertex positions that should by used by the tessellated quad.
let extrudes: Array<number>;

switch (granularity) {
case 1:
extrudes = [0, 7];
break;
case 3:
extrudes = [0, 2, 5, 7];
break;
case 5:
extrudes = [0, 1, 3, 4, 6, 7];
break;
case 7:
extrudes = [0, 1, 2, 3, 4, 5, 6, 7];
break;
default:
throw new Error(`Invalid circle bucket granularity: ${granularity}; valid values are 1, 3, 5, 7.`);
}

const verticesPerAxis = extrudes.length;

for (const ring of geometry) {
for (const point of ring) {
const x = point.x;
const y = point.y;
const vx = point.x;
const vy = point.y;

// Do not include points that are outside the tile boundaries.
if (x < 0 || x >= EXTENT || y < 0 || y >= EXTENT) continue;

// this geometry will be of the Point type, and we'll derive
// two triangles from it.
//
// ┌─────────┐
// │ 3 2 │
// │ │
// │ 0 1 │
// └─────────┘

const segment = this.segments.prepareSegment(4, this.layoutVertexArray, this.indexArray, feature.sortKey);
const index = segment.vertexLength;
if (vx < 0 || vx >= EXTENT || vy < 0 || vy >= EXTENT) {
continue;
}

addCircleVertex(this.layoutVertexArray, x, y, -1, -1);
addCircleVertex(this.layoutVertexArray, x, y, 1, -1);
addCircleVertex(this.layoutVertexArray, x, y, 1, 1);
addCircleVertex(this.layoutVertexArray, x, y, -1, 1);

this.indexArray.emplaceBack(index, index + 1, index + 2);
this.indexArray.emplaceBack(index, index + 3, index + 2);
const segment = this.segments.prepareSegment(verticesPerAxis * verticesPerAxis, this.layoutVertexArray, this.indexArray, feature.sortKey);
const index = segment.vertexLength;

segment.vertexLength += 4;
segment.primitiveLength += 2;
for (let y = 0; y < verticesPerAxis; y++) {
for (let x = 0; x < verticesPerAxis; x++) {
addCircleVertex(this.layoutVertexArray, vx, vy, extrudes[x], extrudes[y]);
}
}

for (let y = 0; y < verticesPerAxis - 1; y++) {
for (let x = 0; x < verticesPerAxis - 1; x++) {
const lowerIndex = index + y * verticesPerAxis + x;
const upperIndex = index + (y + 1) * verticesPerAxis + x;
this.indexArray.emplaceBack(lowerIndex, upperIndex + 1, lowerIndex + 1);
this.indexArray.emplaceBack(lowerIndex, upperIndex, upperIndex + 1);
}
}

segment.vertexLength += verticesPerAxis * verticesPerAxis;
segment.primitiveLength += (verticesPerAxis - 1) * (verticesPerAxis - 1) * 2;
}
}

Expand Down
Loading
Loading