UNPKG

14 kBPlain TextView Raw
1import Point from '@mapbox/point-geometry';
2import Transform from './transform';
3import LngLat from './lng_lat';
4import {OverscaledTileID, CanonicalTileID} from '../source/tile_id';
5import {fixedLngLat, fixedCoord} from '../../test/unit/lib/fixed';
6
7describe('transform', () => {
8 test('creates a transform', () => {
9 const transform = new Transform(0, 22, 0, 60, true);
10 transform.resize(500, 500);
11 expect(transform.unmodified).toBe(true);
12 expect(transform.maxValidLatitude).toBe(85.051129);
13 expect(transform.tileSize).toBe(512);
14 expect(transform.worldSize).toBe(512);
15 expect(transform.width).toBe(500);
16 expect(transform.minZoom).toBe(0);
17 expect(transform.minPitch).toBe(0);
18 // Support signed zero
19 expect(transform.bearing === 0 ? 0 : transform.bearing).toBe(0);
20 expect(transform.bearing = 1).toBe(1);
21 expect(transform.bearing).toBe(1);
22 expect(transform.bearing = 0).toBe(0);
23 expect(transform.unmodified).toBe(false);
24 expect(transform.minZoom = 10).toBe(10);
25 expect(transform.maxZoom = 10).toBe(10);
26 expect(transform.minZoom).toBe(10);
27 expect(transform.center).toEqual({lng: 0, lat: 0});
28 expect(transform.maxZoom).toBe(10);
29 expect(transform.minPitch = 10).toBe(10);
30 expect(transform.maxPitch = 10).toBe(10);
31 expect(transform.size.equals(new Point(500, 500))).toBe(true);
32 expect(transform.centerPoint.equals(new Point(250, 250))).toBe(true);
33 expect(transform.scaleZoom(0)).toBe(-Infinity);
34 expect(transform.scaleZoom(10)).toBe(3.3219280948873626);
35 expect(transform.point).toEqual(new Point(262144, 262144));
36 expect(transform.height).toBe(500);
37 expect(fixedLngLat(transform.pointLocation(new Point(250, 250)))).toEqual({lng: 0, lat: 0});
38 expect(fixedCoord(transform.pointCoordinate(new Point(250, 250)))).toEqual({x: 0.5, y: 0.5, z: 0});
39 expect(transform.locationPoint(new LngLat(0, 0))).toEqual({x: 250, y: 250});
40 expect(transform.locationCoordinate(new LngLat(0, 0))).toEqual({x: 0.5, y: 0.5, z: 0});
41 });
42
43 test('does not throw on bad center', () => {
44 expect(() => {
45 const transform = new Transform(0, 22, 0, 60, true);
46 transform.resize(500, 500);
47 transform.center = new LngLat(50, -90);
48 }).not.toThrow();
49 });
50
51 test('setLocationAt', () => {
52 const transform = new Transform(0, 22, 0, 60, true);
53 transform.resize(500, 500);
54 transform.zoom = 4;
55 expect(transform.center).toEqual({lng: 0, lat: 0});
56 transform.setLocationAtPoint(new LngLat(13, 10), new Point(15, 45));
57 expect(fixedLngLat(transform.pointLocation(new Point(15, 45)))).toEqual({lng: 13, lat: 10});
58 });
59
60 test('setLocationAt tilted', () => {
61 const transform = new Transform(0, 22, 0, 60, true);
62 transform.resize(500, 500);
63 transform.zoom = 4;
64 transform.pitch = 50;
65 expect(transform.center).toEqual({lng: 0, lat: 0});
66 transform.setLocationAtPoint(new LngLat(13, 10), new Point(15, 45));
67 expect(fixedLngLat(transform.pointLocation(new Point(15, 45)))).toEqual({lng: 13, lat: 10});
68 });
69
70 test('has a default zoom', () => {
71 const transform = new Transform(0, 22, 0, 60, true);
72 transform.resize(500, 500);
73 expect(transform.tileZoom).toBe(0);
74 expect(transform.tileZoom).toBe(transform.zoom);
75 });
76
77 test('set fov', () => {
78 const transform = new Transform(0, 22, 0, 60, true);
79 transform.fov = 10;
80 expect(transform.fov).toBe(10);
81 transform.fov = 10;
82 expect(transform.fov).toBe(10);
83 });
84
85 test('lngRange & latRange constrain zoom and center', () => {
86 const transform = new Transform(0, 22, 0, 60, true);
87 transform.center = new LngLat(0, 0);
88 transform.zoom = 10;
89 transform.resize(500, 500);
90
91 transform.lngRange = [-5, 5];
92 transform.latRange = [-5, 5];
93
94 transform.zoom = 0;
95 expect(transform.zoom).toBe(5.135709286104402);
96
97 transform.center = new LngLat(-50, -30);
98 expect(transform.center).toEqual(new LngLat(0, -0.0063583052861417855));
99
100 transform.zoom = 10;
101 transform.center = new LngLat(-50, -30);
102 expect(transform.center).toEqual(new LngLat(-4.828338623046875, -4.828969771321582));
103 });
104
105 describe('coveringTiles', () => {
106 const options = {
107 minzoom: 1,
108 maxzoom: 10,
109 tileSize: 512
110 };
111
112 const transform = new Transform(0, 22, 0, 60, true);
113 transform.resize(200, 200);
114
115 test('generell', () => {
116
117 // make slightly off center so that sort order is not subject to precision issues
118 transform.center = new LngLat(-0.01, 0.01);
119
120 transform.zoom = 0;
121 expect(transform.coveringTiles(options)).toEqual([]);
122
123 transform.zoom = 1;
124 expect(transform.coveringTiles(options)).toEqual([
125 new OverscaledTileID(1, 0, 1, 0, 0),
126 new OverscaledTileID(1, 0, 1, 1, 0),
127 new OverscaledTileID(1, 0, 1, 0, 1),
128 new OverscaledTileID(1, 0, 1, 1, 1)]);
129
130 transform.zoom = 2.4;
131 expect(transform.coveringTiles(options)).toEqual([
132 new OverscaledTileID(2, 0, 2, 1, 1),
133 new OverscaledTileID(2, 0, 2, 2, 1),
134 new OverscaledTileID(2, 0, 2, 1, 2),
135 new OverscaledTileID(2, 0, 2, 2, 2)]);
136
137 transform.zoom = 10;
138 expect(transform.coveringTiles(options)).toEqual([
139 new OverscaledTileID(10, 0, 10, 511, 511),
140 new OverscaledTileID(10, 0, 10, 512, 511),
141 new OverscaledTileID(10, 0, 10, 511, 512),
142 new OverscaledTileID(10, 0, 10, 512, 512)]);
143
144 transform.zoom = 11;
145 expect(transform.coveringTiles(options)).toEqual([
146 new OverscaledTileID(10, 0, 10, 511, 511),
147 new OverscaledTileID(10, 0, 10, 512, 511),
148 new OverscaledTileID(10, 0, 10, 511, 512),
149 new OverscaledTileID(10, 0, 10, 512, 512)]);
150
151 transform.zoom = 5.1;
152 transform.pitch = 60.0;
153 transform.bearing = 32.0;
154 transform.center = new LngLat(56.90, 48.20);
155 transform.resize(1024, 768);
156 expect(transform.coveringTiles(options)).toEqual([
157 new OverscaledTileID(5, 0, 5, 21, 11),
158 new OverscaledTileID(5, 0, 5, 20, 11),
159 new OverscaledTileID(5, 0, 5, 21, 10),
160 new OverscaledTileID(5, 0, 5, 20, 10),
161 new OverscaledTileID(5, 0, 5, 21, 12),
162 new OverscaledTileID(5, 0, 5, 22, 11),
163 new OverscaledTileID(5, 0, 5, 20, 12),
164 new OverscaledTileID(5, 0, 5, 22, 10),
165 new OverscaledTileID(5, 0, 5, 21, 9),
166 new OverscaledTileID(5, 0, 5, 20, 9),
167 new OverscaledTileID(5, 0, 5, 22, 9),
168 new OverscaledTileID(5, 0, 5, 23, 10),
169 new OverscaledTileID(5, 0, 5, 21, 8),
170 new OverscaledTileID(5, 0, 5, 20, 8),
171 new OverscaledTileID(5, 0, 5, 23, 9),
172 new OverscaledTileID(5, 0, 5, 22, 8),
173 new OverscaledTileID(5, 0, 5, 23, 8),
174 new OverscaledTileID(5, 0, 5, 21, 7),
175 new OverscaledTileID(5, 0, 5, 20, 7),
176 new OverscaledTileID(5, 0, 5, 24, 9),
177 new OverscaledTileID(5, 0, 5, 22, 7)
178 ]);
179
180 transform.zoom = 8;
181 transform.pitch = 60;
182 transform.bearing = 45.0;
183 transform.center = new LngLat(25.02, 60.15);
184 transform.resize(300, 50);
185 expect(transform.coveringTiles(options)).toEqual([
186 new OverscaledTileID(8, 0, 8, 145, 74),
187 new OverscaledTileID(8, 0, 8, 145, 73),
188 new OverscaledTileID(8, 0, 8, 146, 74)
189 ]);
190
191 transform.resize(50, 300);
192 expect(transform.coveringTiles(options)).toEqual([
193 new OverscaledTileID(8, 0, 8, 145, 74),
194 new OverscaledTileID(8, 0, 8, 145, 73),
195 new OverscaledTileID(8, 0, 8, 146, 74),
196 new OverscaledTileID(8, 0, 8, 146, 73)
197 ]);
198
199 transform.zoom = 2;
200 transform.pitch = 0;
201 transform.bearing = 0;
202 transform.resize(300, 300);
203 });
204
205 test('calculates tile coverage at w > 0', () => {
206 transform.center = new LngLat(630.01, 0.01);
207 expect(transform.coveringTiles(options)).toEqual([
208 new OverscaledTileID(2, 2, 2, 1, 1),
209 new OverscaledTileID(2, 2, 2, 1, 2),
210 new OverscaledTileID(2, 2, 2, 0, 1),
211 new OverscaledTileID(2, 2, 2, 0, 2)
212 ]);
213 });
214
215 test('calculates tile coverage at w = -1', () => {
216 transform.center = new LngLat(-360.01, 0.01);
217 expect(transform.coveringTiles(options)).toEqual([
218 new OverscaledTileID(2, -1, 2, 1, 1),
219 new OverscaledTileID(2, -1, 2, 1, 2),
220 new OverscaledTileID(2, -1, 2, 2, 1),
221 new OverscaledTileID(2, -1, 2, 2, 2)
222 ]);
223 });
224
225 test('calculates tile coverage across meridian', () => {
226 transform.zoom = 1;
227 transform.center = new LngLat(-180.01, 0.01);
228 expect(transform.coveringTiles(options)).toEqual([
229 new OverscaledTileID(1, 0, 1, 0, 0),
230 new OverscaledTileID(1, 0, 1, 0, 1),
231 new OverscaledTileID(1, -1, 1, 1, 0),
232 new OverscaledTileID(1, -1, 1, 1, 1)
233 ]);
234 });
235
236 test('only includes tiles for a single world, if renderWorldCopies is set to false', () => {
237 transform.zoom = 1;
238 transform.center = new LngLat(-180.01, 0.01);
239 transform.renderWorldCopies = false;
240 expect(transform.coveringTiles(options)).toEqual([
241 new OverscaledTileID(1, 0, 1, 0, 0),
242 new OverscaledTileID(1, 0, 1, 0, 1)
243 ]);
244 });
245
246 });
247
248 test('coveringZoomLevel', () => {
249 const options = {
250 minzoom: 1,
251 maxzoom: 10,
252 tileSize: 512,
253 roundZoom: false,
254 };
255
256 const transform = new Transform(0, 22, 0, 60, true);
257
258 transform.zoom = 0;
259 expect(transform.coveringZoomLevel(options)).toBe(0);
260
261 transform.zoom = 0.1;
262 expect(transform.coveringZoomLevel(options)).toBe(0);
263
264 transform.zoom = 1;
265 expect(transform.coveringZoomLevel(options)).toBe(1);
266
267 transform.zoom = 2.4;
268 expect(transform.coveringZoomLevel(options)).toBe(2);
269
270 transform.zoom = 10;
271 expect(transform.coveringZoomLevel(options)).toBe(10);
272
273 transform.zoom = 11;
274 expect(transform.coveringZoomLevel(options)).toBe(11);
275
276 transform.zoom = 11.5;
277 expect(transform.coveringZoomLevel(options)).toBe(11);
278
279 options.tileSize = 256;
280
281 transform.zoom = 0;
282 expect(transform.coveringZoomLevel(options)).toBe(1);
283
284 transform.zoom = 0.1;
285 expect(transform.coveringZoomLevel(options)).toBe(1);
286
287 transform.zoom = 1;
288 expect(transform.coveringZoomLevel(options)).toBe(2);
289
290 transform.zoom = 2.4;
291 expect(transform.coveringZoomLevel(options)).toBe(3);
292
293 transform.zoom = 10;
294 expect(transform.coveringZoomLevel(options)).toBe(11);
295
296 transform.zoom = 11;
297 expect(transform.coveringZoomLevel(options)).toBe(12);
298
299 transform.zoom = 11.5;
300 expect(transform.coveringZoomLevel(options)).toBe(12);
301
302 options.roundZoom = true;
303
304 expect(transform.coveringZoomLevel(options)).toBe(13);
305 });
306
307 test('clamps latitude', () => {
308 const transform = new Transform(0, 22, 0, 60, true);
309
310 expect(transform.project(new LngLat(0, -90))).toEqual(transform.project(new LngLat(0, -transform.maxValidLatitude)));
311 expect(transform.project(new LngLat(0, 90))).toEqual(transform.project(new LngLat(0, transform.maxValidLatitude)));
312 });
313
314 test('clamps pitch', () => {
315 const transform = new Transform(0, 22, 0, 60, true);
316
317 transform.pitch = 45;
318 expect(transform.pitch).toBe(45);
319
320 transform.pitch = -10;
321 expect(transform.pitch).toBe(0);
322
323 transform.pitch = 90;
324 expect(transform.pitch).toBe(60);
325 });
326
327 test('visibleUnwrappedCoordinates', () => {
328 const transform = new Transform(0, 22, 0, 60, true);
329 transform.resize(200, 200);
330 transform.zoom = 0;
331 transform.center = new LngLat(-170.01, 0.01);
332
333 let unwrappedCoords = transform.getVisibleUnwrappedCoordinates(new CanonicalTileID(0, 0, 0));
334 expect(unwrappedCoords).toHaveLength(4);
335
336 //getVisibleUnwrappedCoordinates should honor _renderWorldCopies
337 transform._renderWorldCopies = false;
338 unwrappedCoords = transform.getVisibleUnwrappedCoordinates(new CanonicalTileID(0, 0, 0));
339 expect(unwrappedCoords).toHaveLength(1);
340 });
341
342 test('maintains high float precision when calculating matrices', () => {
343
344 const transform = new Transform(0, 22, 0, 60, true);
345 transform.resize(200.25, 200.25);
346 transform.zoom = 20.25;
347 transform.pitch = 67.25;
348 transform.center = new LngLat(0.0, 0.0);
349 transform._calcMatrices();
350
351 expect(transform.customLayerMatrix()[0].toString().length).toBeGreaterThan(10);
352 expect(transform.glCoordMatrix[0].toString().length).toBeGreaterThan(10);
353 expect(transform.maxPitchScaleFactor()).toBeCloseTo(2.366025418080343, 10);
354 });
355});