maplibre-gl
Version:
BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
172 lines (154 loc) • 6.12 kB
text/typescript
import {SymbolProjectionContext, ProjectionSyntheticVertexArgs, findOffsetIntersectionPoint, project, projectVertexToViewport, transformToOffsetNormal} from './projection';
import Point from '@mapbox/point-geometry';
import {mat4} from 'gl-matrix';
import {SymbolLineVertexArray} from '../data/array_types.g';
describe('Projection', () => {
test('matrix float precision', () => {
const point = new Point(10.000000005, 0);
const matrix = mat4.create();
expect(project(point.x, point.y, matrix).point.x).toBeCloseTo(point.x, 10);
});
});
describe('Vertex to viewport projection', () => {
// A three point line along the x axis
const lineVertexArray = new SymbolLineVertexArray();
lineVertexArray.emplaceBack(-10, 0, -10);
lineVertexArray.emplaceBack(0, 0, 0);
lineVertexArray.emplaceBack(10, 0, 10);
test('projecting with null matrix', () => {
const projectionContext: SymbolProjectionContext = {
projectionCache: {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false},
lineVertexArray,
labelPlaneMatrix: mat4.create(),
getElevation: (_x, _y) => 0,
// Only relevant in "behind the camera" case, can't happen with null projection matrix
tileAnchorPoint: new Point(0, 0),
pitchWithMap: true,
projection: null,
unwrappedTileID: null,
width: 1,
height: 1,
translation: [0, 0]
};
const syntheticVertexArgs: ProjectionSyntheticVertexArgs = {
distanceFromAnchor: 0,
previousVertex: new Point(0, 0),
direction: 1,
absOffsetX: 0
};
const first = projectVertexToViewport(0, projectionContext, syntheticVertexArgs);
const second = projectVertexToViewport(1, projectionContext, syntheticVertexArgs);
const third = projectVertexToViewport(2, projectionContext, syntheticVertexArgs);
expect(first.x).toBeCloseTo(-10);
expect(second.x).toBeCloseTo(0);
expect(third.x).toBeCloseTo(10);
});
});
describe('Find offset line intersections', () => {
const lineVertexArray = new SymbolLineVertexArray();
// A three point line along x axis, to origin, and then up y axis
lineVertexArray.emplaceBack(-10, 0, -10);
lineVertexArray.emplaceBack(0, 0, 0);
lineVertexArray.emplaceBack(0, 10, 10);
// A three point line along the x axis
lineVertexArray.emplaceBack(-10, 0, -10);
lineVertexArray.emplaceBack(0, 0, 0);
lineVertexArray.emplaceBack(10, 0, 10);
const projectionContext: SymbolProjectionContext = {
projectionCache: {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false},
lineVertexArray,
labelPlaneMatrix: mat4.create(),
getElevation: (_x, _y) => 0,
tileAnchorPoint: new Point(0, 0),
pitchWithMap: true,
projection: null,
unwrappedTileID: null,
width: 1,
height: 1,
translation: [0, 0]
};
// Only relevant in "behind the camera" case, can't happen with null projection matrix
const syntheticVertexArgs: ProjectionSyntheticVertexArgs = {
direction: 1,
distanceFromAnchor: 0,
previousVertex: new Point(0, 0),
absOffsetX: 0
};
test('concave', () => {
/*
| |
| |
________| |
__________| <- origin
*/
projectionContext.projectionCache = {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false};
const lineOffsetY = 1;
const prevToCurrent = new Point(10, 0);
const normal = transformToOffsetNormal(prevToCurrent, lineOffsetY, syntheticVertexArgs.direction);
expect(normal.y).toBeCloseTo(1);
expect(normal.x).toBeCloseTo(0);
const intersectionPoint = findOffsetIntersectionPoint(
1,
normal,
new Point(0, 0),
0,
3,
new Point(-10, 1),
lineOffsetY,
projectionContext,
syntheticVertexArgs
);
expect(intersectionPoint.y).toBeCloseTo(1);
expect(intersectionPoint.x).toBeCloseTo(-1);
});
test('convex', () => {
/*
| |
| |
origin \ | |
__________| |
____________|
*/
projectionContext.projectionCache = {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false};
const lineOffsetY = -1;
const prevToCurrent = new Point(10, 0);
const normal = transformToOffsetNormal(prevToCurrent, lineOffsetY, syntheticVertexArgs.direction);
expect(normal.y).toBeCloseTo(-1);
expect(normal.x).toBeCloseTo(0);
const intersectionPoint = findOffsetIntersectionPoint(
1,
normal,
new Point(0, 0),
0,
3,
new Point(-10, -1),
lineOffsetY,
projectionContext,
syntheticVertexArgs
);
expect(intersectionPoint.y).toBeCloseTo(-1);
expect(intersectionPoint.x).toBeCloseTo(1);
});
test('parallel', () => {
/*
______._____
______|_____
*/
projectionContext.projectionCache = {projections: {}, offsets: {}, cachedAnchorPoint: undefined, anyProjectionOccluded: false};
const lineOffsetY = 1;
const prevToCurrent = new Point(10, 0);
const intersectionPoint = findOffsetIntersectionPoint(
1,
transformToOffsetNormal(prevToCurrent, lineOffsetY, syntheticVertexArgs.direction),
new Point(0, 0),
3,
5,
new Point(-10, 1),
lineOffsetY,
projectionContext,
syntheticVertexArgs
);
expect(intersectionPoint.x).toBeCloseTo(0);
expect(intersectionPoint.y).toBeCloseTo(1);
});
});