@deck.gl/layers
Version:
deck.gl core layers
1,450 lines (1,353 loc) • 279 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if (typeof define === 'function' && define.amd) define([], factory);
else if (typeof exports === 'object') exports['deck'] = factory();
else root['deck'] = factory();})(globalThis, function () {
"use strict";
var __exports__ = (() => {
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod2) => function __require() {
return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __reExport = (target, mod2, secondTarget) => (__copyProps(target, mod2, "default"), secondTarget && __copyProps(secondTarget, mod2, "default"));
var __toESM = (mod2, isNodeMode, target) => (target = mod2 != null ? __create(__getProtoOf(mod2)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod2 || !mod2.__esModule ? __defProp(target, "default", { value: mod2, enumerable: true }) : target,
mod2
));
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
// external-global-plugin:@deck.gl/core
var require_core = __commonJS({
"external-global-plugin:@deck.gl/core"(exports, module) {
module.exports = globalThis.deck;
}
});
// external-global-plugin:@luma.gl/engine
var require_engine = __commonJS({
"external-global-plugin:@luma.gl/engine"(exports, module) {
module.exports = globalThis.luma;
}
});
// external-global-plugin:@loaders.gl/core
var require_core2 = __commonJS({
"external-global-plugin:@loaders.gl/core"(exports, module) {
module.exports = globalThis.loaders;
}
});
// external-global-plugin:@luma.gl/core
var require_core3 = __commonJS({
"external-global-plugin:@luma.gl/core"(exports, module) {
module.exports = globalThis.luma;
}
});
// ../../node_modules/earcut/src/earcut.js
var require_earcut = __commonJS({
"../../node_modules/earcut/src/earcut.js"(exports, module) {
"use strict";
module.exports = earcut3;
module.exports.default = earcut3;
function earcut3(data, holeIndices, dim) {
dim = dim || 2;
var hasHoles = holeIndices && holeIndices.length, outerLen = hasHoles ? holeIndices[0] * dim : data.length, outerNode = linkedList(data, 0, outerLen, dim, true), triangles = [];
if (!outerNode || outerNode.next === outerNode.prev)
return triangles;
var minX, minY, maxX, maxY, x, y, invSize;
if (hasHoles)
outerNode = eliminateHoles(data, holeIndices, outerNode, dim);
if (data.length > 80 * dim) {
minX = maxX = data[0];
minY = maxY = data[1];
for (var i = dim; i < outerLen; i += dim) {
x = data[i];
y = data[i + 1];
if (x < minX)
minX = x;
if (y < minY)
minY = y;
if (x > maxX)
maxX = x;
if (y > maxY)
maxY = y;
}
invSize = Math.max(maxX - minX, maxY - minY);
invSize = invSize !== 0 ? 32767 / invSize : 0;
}
earcutLinked(outerNode, triangles, dim, minX, minY, invSize, 0);
return triangles;
}
function linkedList(data, start, end, dim, clockwise) {
var i, last;
if (clockwise === signedArea(data, start, end, dim) > 0) {
for (i = start; i < end; i += dim)
last = insertNode(i, data[i], data[i + 1], last);
} else {
for (i = end - dim; i >= start; i -= dim)
last = insertNode(i, data[i], data[i + 1], last);
}
if (last && equals2(last, last.next)) {
removeNode(last);
last = last.next;
}
return last;
}
function filterPoints(start, end) {
if (!start)
return start;
if (!end)
end = start;
var p = start, again;
do {
again = false;
if (!p.steiner && (equals2(p, p.next) || area(p.prev, p, p.next) === 0)) {
removeNode(p);
p = end = p.prev;
if (p === p.next)
break;
again = true;
} else {
p = p.next;
}
} while (again || p !== end);
return end;
}
function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
if (!ear)
return;
if (!pass && invSize)
indexCurve(ear, minX, minY, invSize);
var stop = ear, prev, next;
while (ear.prev !== ear.next) {
prev = ear.prev;
next = ear.next;
if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
triangles.push(prev.i / dim | 0);
triangles.push(ear.i / dim | 0);
triangles.push(next.i / dim | 0);
removeNode(ear);
ear = next.next;
stop = next.next;
continue;
}
ear = next;
if (ear === stop) {
if (!pass) {
earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1);
} else if (pass === 1) {
ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
earcutLinked(ear, triangles, dim, minX, minY, invSize, 2);
} else if (pass === 2) {
splitEarcut(ear, triangles, dim, minX, minY, invSize);
}
break;
}
}
}
function isEar(ear) {
var a = ear.prev, b = ear, c = ear.next;
if (area(a, b, c) >= 0)
return false;
var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
var x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
var p = c.next;
while (p !== a) {
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
return false;
p = p.next;
}
return true;
}
function isEarHashed(ear, minX, minY, invSize) {
var a = ear.prev, b = ear, c = ear.next;
if (area(a, b, c) >= 0)
return false;
var ax = a.x, bx = b.x, cx = c.x, ay = a.y, by = b.y, cy = c.y;
var x0 = ax < bx ? ax < cx ? ax : cx : bx < cx ? bx : cx, y0 = ay < by ? ay < cy ? ay : cy : by < cy ? by : cy, x1 = ax > bx ? ax > cx ? ax : cx : bx > cx ? bx : cx, y1 = ay > by ? ay > cy ? ay : cy : by > cy ? by : cy;
var minZ = zOrder(x0, y0, minX, minY, invSize), maxZ = zOrder(x1, y1, minX, minY, invSize);
var p = ear.prevZ, n = ear.nextZ;
while (p && p.z >= minZ && n && n.z <= maxZ) {
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
return false;
p = p.prevZ;
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
return false;
n = n.nextZ;
}
while (p && p.z >= minZ) {
if (p.x >= x0 && p.x <= x1 && p.y >= y0 && p.y <= y1 && p !== a && p !== c && pointInTriangle(ax, ay, bx, by, cx, cy, p.x, p.y) && area(p.prev, p, p.next) >= 0)
return false;
p = p.prevZ;
}
while (n && n.z <= maxZ) {
if (n.x >= x0 && n.x <= x1 && n.y >= y0 && n.y <= y1 && n !== a && n !== c && pointInTriangle(ax, ay, bx, by, cx, cy, n.x, n.y) && area(n.prev, n, n.next) >= 0)
return false;
n = n.nextZ;
}
return true;
}
function cureLocalIntersections(start, triangles, dim) {
var p = start;
do {
var a = p.prev, b = p.next.next;
if (!equals2(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
triangles.push(a.i / dim | 0);
triangles.push(p.i / dim | 0);
triangles.push(b.i / dim | 0);
removeNode(p);
removeNode(p.next);
p = start = b;
}
p = p.next;
} while (p !== start);
return filterPoints(p);
}
function splitEarcut(start, triangles, dim, minX, minY, invSize) {
var a = start;
do {
var b = a.next.next;
while (b !== a.prev) {
if (a.i !== b.i && isValidDiagonal(a, b)) {
var c = splitPolygon(a, b);
a = filterPoints(a, a.next);
c = filterPoints(c, c.next);
earcutLinked(a, triangles, dim, minX, minY, invSize, 0);
earcutLinked(c, triangles, dim, minX, minY, invSize, 0);
return;
}
b = b.next;
}
a = a.next;
} while (a !== start);
}
function eliminateHoles(data, holeIndices, outerNode, dim) {
var queue = [], i, len, start, end, list;
for (i = 0, len = holeIndices.length; i < len; i++) {
start = holeIndices[i] * dim;
end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
list = linkedList(data, start, end, dim, false);
if (list === list.next)
list.steiner = true;
queue.push(getLeftmost(list));
}
queue.sort(compareX);
for (i = 0; i < queue.length; i++) {
outerNode = eliminateHole(queue[i], outerNode);
}
return outerNode;
}
function compareX(a, b) {
return a.x - b.x;
}
function eliminateHole(hole, outerNode) {
var bridge = findHoleBridge(hole, outerNode);
if (!bridge) {
return outerNode;
}
var bridgeReverse = splitPolygon(bridge, hole);
filterPoints(bridgeReverse, bridgeReverse.next);
return filterPoints(bridge, bridge.next);
}
function findHoleBridge(hole, outerNode) {
var p = outerNode, hx = hole.x, hy = hole.y, qx = -Infinity, m;
do {
if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
if (x <= hx && x > qx) {
qx = x;
m = p.x < p.next.x ? p : p.next;
if (x === hx)
return m;
}
}
p = p.next;
} while (p !== outerNode);
if (!m)
return null;
var stop = m, mx = m.x, my = m.y, tanMin = Infinity, tan2;
p = m;
do {
if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
tan2 = Math.abs(hy - p.y) / (hx - p.x);
if (locallyInside(p, hole) && (tan2 < tanMin || tan2 === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
m = p;
tanMin = tan2;
}
}
p = p.next;
} while (p !== stop);
return m;
}
function sectorContainsSector(m, p) {
return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
}
function indexCurve(start, minX, minY, invSize) {
var p = start;
do {
if (p.z === 0)
p.z = zOrder(p.x, p.y, minX, minY, invSize);
p.prevZ = p.prev;
p.nextZ = p.next;
p = p.next;
} while (p !== start);
p.prevZ.nextZ = null;
p.prevZ = null;
sortLinked(p);
}
function sortLinked(list) {
var i, p, q, e, tail, numMerges, pSize, qSize, inSize = 1;
do {
p = list;
list = null;
tail = null;
numMerges = 0;
while (p) {
numMerges++;
q = p;
pSize = 0;
for (i = 0; i < inSize; i++) {
pSize++;
q = q.nextZ;
if (!q)
break;
}
qSize = inSize;
while (pSize > 0 || qSize > 0 && q) {
if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
e = p;
p = p.nextZ;
pSize--;
} else {
e = q;
q = q.nextZ;
qSize--;
}
if (tail)
tail.nextZ = e;
else
list = e;
e.prevZ = tail;
tail = e;
}
p = q;
}
tail.nextZ = null;
inSize *= 2;
} while (numMerges > 1);
return list;
}
function zOrder(x, y, minX, minY, invSize) {
x = (x - minX) * invSize | 0;
y = (y - minY) * invSize | 0;
x = (x | x << 8) & 16711935;
x = (x | x << 4) & 252645135;
x = (x | x << 2) & 858993459;
x = (x | x << 1) & 1431655765;
y = (y | y << 8) & 16711935;
y = (y | y << 4) & 252645135;
y = (y | y << 2) & 858993459;
y = (y | y << 1) & 1431655765;
return x | y << 1;
}
function getLeftmost(start) {
var p = start, leftmost = start;
do {
if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y)
leftmost = p;
p = p.next;
} while (p !== start);
return leftmost;
}
function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
return (cx - px) * (ay - py) >= (ax - px) * (cy - py) && (ax - px) * (by - py) >= (bx - px) * (ay - py) && (bx - px) * (cy - py) >= (cx - px) * (by - py);
}
function isValidDiagonal(a, b) {
return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && // dones't intersect other edges
(locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && // locally visible
(area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
equals2(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0);
}
function area(p, q, r) {
return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
}
function equals2(p1, p2) {
return p1.x === p2.x && p1.y === p2.y;
}
function intersects(p1, q1, p2, q2) {
var o1 = sign(area(p1, q1, p2));
var o2 = sign(area(p1, q1, q2));
var o3 = sign(area(p2, q2, p1));
var o4 = sign(area(p2, q2, q1));
if (o1 !== o2 && o3 !== o4)
return true;
if (o1 === 0 && onSegment(p1, p2, q1))
return true;
if (o2 === 0 && onSegment(p1, q2, q1))
return true;
if (o3 === 0 && onSegment(p2, p1, q2))
return true;
if (o4 === 0 && onSegment(p2, q1, q2))
return true;
return false;
}
function onSegment(p, q, r) {
return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
}
function sign(num) {
return num > 0 ? 1 : num < 0 ? -1 : 0;
}
function intersectsPolygon(a, b) {
var p = a;
do {
if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b))
return true;
p = p.next;
} while (p !== a);
return false;
}
function locallyInside(a, b) {
return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
}
function middleInside(a, b) {
var p = a, inside = false, px = (a.x + b.x) / 2, py = (a.y + b.y) / 2;
do {
if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)
inside = !inside;
p = p.next;
} while (p !== a);
return inside;
}
function splitPolygon(a, b) {
var a2 = new Node(a.i, a.x, a.y), b2 = new Node(b.i, b.x, b.y), an = a.next, bp = b.prev;
a.next = b;
b.prev = a;
a2.next = an;
an.prev = a2;
b2.next = a2;
a2.prev = b2;
bp.next = b2;
b2.prev = bp;
return b2;
}
function insertNode(i, x, y, last) {
var p = new Node(i, x, y);
if (!last) {
p.prev = p;
p.next = p;
} else {
p.next = last.next;
p.prev = last;
last.next.prev = p;
last.next = p;
}
return p;
}
function removeNode(p) {
p.next.prev = p.prev;
p.prev.next = p.next;
if (p.prevZ)
p.prevZ.nextZ = p.nextZ;
if (p.nextZ)
p.nextZ.prevZ = p.prevZ;
}
function Node(i, x, y) {
this.i = i;
this.x = x;
this.y = y;
this.prev = null;
this.next = null;
this.z = 0;
this.prevZ = null;
this.nextZ = null;
this.steiner = false;
}
earcut3.deviation = function(data, holeIndices, dim, triangles) {
var hasHoles = holeIndices && holeIndices.length;
var outerLen = hasHoles ? holeIndices[0] * dim : data.length;
var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));
if (hasHoles) {
for (var i = 0, len = holeIndices.length; i < len; i++) {
var start = holeIndices[i] * dim;
var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
polygonArea -= Math.abs(signedArea(data, start, end, dim));
}
}
var trianglesArea = 0;
for (i = 0; i < triangles.length; i += 3) {
var a = triangles[i] * dim;
var b = triangles[i + 1] * dim;
var c = triangles[i + 2] * dim;
trianglesArea += Math.abs(
(data[a] - data[c]) * (data[b + 1] - data[a + 1]) - (data[a] - data[b]) * (data[c + 1] - data[a + 1])
);
}
return polygonArea === 0 && trianglesArea === 0 ? 0 : Math.abs((trianglesArea - polygonArea) / polygonArea);
};
function signedArea(data, start, end, dim) {
var sum = 0;
for (var i = start, j = end - dim; i < end; i += dim) {
sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
j = i;
}
return sum;
}
earcut3.flatten = function(data) {
var dim = data[0][0].length, result = { vertices: [], holes: [], dimensions: dim }, holeIndex = 0;
for (var i = 0; i < data.length; i++) {
for (var j = 0; j < data[i].length; j++) {
for (var d = 0; d < dim; d++)
result.vertices.push(data[i][j][d]);
}
if (i > 0) {
holeIndex += data[i - 1].length;
result.holes.push(holeIndex);
}
}
return result;
};
}
});
// bundle/index.ts
var bundle_exports = {};
__export(bundle_exports, {
ArcLayer: () => ArcLayer,
BitmapLayer: () => BitmapLayer,
ColumnLayer: () => ColumnLayer,
GeoJsonLayer: () => GeoJsonLayer,
GridCellLayer: () => GridCellLayer,
IconLayer: () => IconLayer,
LineLayer: () => LineLayer,
PathLayer: () => PathLayer,
PointCloudLayer: () => PointCloudLayer,
PolygonLayer: () => PolygonLayer,
ScatterplotLayer: () => ScatterplotLayer,
SolidPolygonLayer: () => SolidPolygonLayer,
TextLayer: () => TextLayer,
_MultiIconLayer: () => MultiIconLayer,
_TextBackgroundLayer: () => TextBackgroundLayer
});
// ../core/bundle/peer-dependency.ts
var peer_dependency_exports = {};
var import_core = __toESM(require_core(), 1);
__reExport(peer_dependency_exports, __toESM(require_core(), 1));
if (!import_core.Layer) {
throw new Error("@deck.gl/core is not found");
}
// bundle/index.ts
__reExport(bundle_exports, peer_dependency_exports);
// src/arc-layer/arc-layer.ts
var import_core2 = __toESM(require_core(), 1);
var import_engine = __toESM(require_engine(), 1);
// src/arc-layer/arc-layer-uniforms.ts
var uniformBlock = `uniform arcUniforms {
bool greatCircle;
bool useShortestPath;
float numSegments;
float widthScale;
float widthMinPixels;
float widthMaxPixels;
highp int widthUnits;
} arc;
`;
var arcUniforms = {
name: "arc",
vs: uniformBlock,
fs: uniformBlock,
uniformTypes: {
greatCircle: "f32",
useShortestPath: "f32",
numSegments: "f32",
widthScale: "f32",
widthMinPixels: "f32",
widthMaxPixels: "f32",
widthUnits: "i32"
}
};
// src/arc-layer/arc-layer-vertex.glsl.ts
var arc_layer_vertex_glsl_default = `#version 300 es
#define SHADER_NAME arc-layer-vertex-shader
in vec4 instanceSourceColors;
in vec4 instanceTargetColors;
in vec3 instanceSourcePositions;
in vec3 instanceSourcePositions64Low;
in vec3 instanceTargetPositions;
in vec3 instanceTargetPositions64Low;
in vec3 instancePickingColors;
in float instanceWidths;
in float instanceHeights;
in float instanceTilts;
out vec4 vColor;
out vec2 uv;
out float isValid;
float paraboloid(float distance, float sourceZ, float targetZ, float ratio) {
// d: distance on the xy plane
// r: ratio of the current point
// p: ratio of the peak of the arc
// h: height multiplier
// z = f(r) = sqrt(r * (p * 2 - r)) * d * h
// f(0) = 0
// f(1) = dz
float deltaZ = targetZ - sourceZ;
float dh = distance * instanceHeights;
if (dh == 0.0) {
return sourceZ + deltaZ * ratio;
}
float unitZ = deltaZ / dh;
float p2 = unitZ * unitZ + 1.0;
// sqrt does not deal with negative values, manually flip source and target if delta.z < 0
float dir = step(deltaZ, 0.0);
float z0 = mix(sourceZ, targetZ, dir);
float r = mix(ratio, 1.0 - ratio, dir);
return sqrt(r * (p2 - r)) * dh + z0;
}
// offset vector by strokeWidth pixels
// offset_direction is -1 (left) or 1 (right)
vec2 getExtrusionOffset(vec2 line_clipspace, float offset_direction, float width) {
// normalized direction of the line
vec2 dir_screenspace = normalize(line_clipspace * project.viewportSize);
// rotate by 90 degrees
dir_screenspace = vec2(-dir_screenspace.y, dir_screenspace.x);
return dir_screenspace * offset_direction * width / 2.0;
}
float getSegmentRatio(float index) {
return smoothstep(0.0, 1.0, index / (arc.numSegments - 1.0));
}
vec3 interpolateFlat(vec3 source, vec3 target, float segmentRatio) {
float distance = length(source.xy - target.xy);
float z = paraboloid(distance, source.z, target.z, segmentRatio);
float tiltAngle = radians(instanceTilts);
vec2 tiltDirection = normalize(target.xy - source.xy);
vec2 tilt = vec2(-tiltDirection.y, tiltDirection.x) * z * sin(tiltAngle);
return vec3(
mix(source.xy, target.xy, segmentRatio) + tilt,
z * cos(tiltAngle)
);
}
/* Great circle interpolation
* http://www.movable-type.co.uk/scripts/latlong.html
*/
float getAngularDist (vec2 source, vec2 target) {
vec2 sourceRadians = radians(source);
vec2 targetRadians = radians(target);
vec2 sin_half_delta = sin((sourceRadians - targetRadians) / 2.0);
vec2 shd_sq = sin_half_delta * sin_half_delta;
float a = shd_sq.y + cos(sourceRadians.y) * cos(targetRadians.y) * shd_sq.x;
return 2.0 * asin(sqrt(a));
}
vec3 interpolateGreatCircle(vec3 source, vec3 target, vec3 source3D, vec3 target3D, float angularDist, float t) {
vec2 lngLat;
// if the angularDist is PI, linear interpolation is applied. otherwise, use spherical interpolation
if(abs(angularDist - PI) < 0.001) {
lngLat = (1.0 - t) * source.xy + t * target.xy;
} else {
float a = sin((1.0 - t) * angularDist);
float b = sin(t * angularDist);
vec3 p = source3D.yxz * a + target3D.yxz * b;
lngLat = degrees(vec2(atan(p.y, -p.x), atan(p.z, length(p.xy))));
}
float z = paraboloid(angularDist * EARTH_RADIUS, source.z, target.z, t);
return vec3(lngLat, z);
}
/* END GREAT CIRCLE */
void main(void) {
geometry.worldPosition = instanceSourcePositions;
geometry.worldPositionAlt = instanceTargetPositions;
/*
* --(i, -1)-----------_(i+1, -1)--
* | _,-" |
* o _,-" o
* | _,-" |
* --(i, 1)"-------------(i+1, 1)--
*/
float segmentIndex = float(gl_VertexID / 2);
float segmentSide = mod(float(gl_VertexID), 2.) == 0. ? -1. : 1.;
float segmentRatio = getSegmentRatio(segmentIndex);
float prevSegmentRatio = getSegmentRatio(max(0.0, segmentIndex - 1.0));
float nextSegmentRatio = getSegmentRatio(min(arc.numSegments - 1.0, segmentIndex + 1.0));
// if it's the first point, use next - current as direction
// otherwise use current - prev
float indexDir = mix(-1.0, 1.0, step(segmentIndex, 0.0));
isValid = 1.0;
uv = vec2(segmentRatio, segmentSide);
geometry.uv = uv;
geometry.pickingColor = instancePickingColors;
vec4 curr;
vec4 next;
vec3 source;
vec3 target;
if ((arc.greatCircle || project.projectionMode == PROJECTION_MODE_GLOBE) && project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
source = project_globe_(vec3(instanceSourcePositions.xy, 0.0));
target = project_globe_(vec3(instanceTargetPositions.xy, 0.0));
float angularDist = getAngularDist(instanceSourcePositions.xy, instanceTargetPositions.xy);
vec3 prevPos = interpolateGreatCircle(instanceSourcePositions, instanceTargetPositions, source, target, angularDist, prevSegmentRatio);
vec3 currPos = interpolateGreatCircle(instanceSourcePositions, instanceTargetPositions, source, target, angularDist, segmentRatio);
vec3 nextPos = interpolateGreatCircle(instanceSourcePositions, instanceTargetPositions, source, target, angularDist, nextSegmentRatio);
if (abs(currPos.x - prevPos.x) > 180.0) {
indexDir = -1.0;
isValid = 0.0;
} else if (abs(currPos.x - nextPos.x) > 180.0) {
indexDir = 1.0;
isValid = 0.0;
}
nextPos = indexDir < 0.0 ? prevPos : nextPos;
nextSegmentRatio = indexDir < 0.0 ? prevSegmentRatio : nextSegmentRatio;
if (isValid == 0.0) {
// split at the 180th meridian
nextPos.x += nextPos.x > 0.0 ? -360.0 : 360.0;
float t = ((currPos.x > 0.0 ? 180.0 : -180.0) - currPos.x) / (nextPos.x - currPos.x);
currPos = mix(currPos, nextPos, t);
segmentRatio = mix(segmentRatio, nextSegmentRatio, t);
}
vec3 currPos64Low = mix(instanceSourcePositions64Low, instanceTargetPositions64Low, segmentRatio);
vec3 nextPos64Low = mix(instanceSourcePositions64Low, instanceTargetPositions64Low, nextSegmentRatio);
curr = project_position_to_clipspace(currPos, currPos64Low, vec3(0.0), geometry.position);
next = project_position_to_clipspace(nextPos, nextPos64Low, vec3(0.0));
} else {
vec3 source_world = instanceSourcePositions;
vec3 target_world = instanceTargetPositions;
if (arc.useShortestPath) {
source_world.x = mod(source_world.x + 180., 360.0) - 180.;
target_world.x = mod(target_world.x + 180., 360.0) - 180.;
float deltaLng = target_world.x - source_world.x;
if (deltaLng > 180.) target_world.x -= 360.;
if (deltaLng < -180.) source_world.x -= 360.;
}
source = project_position(source_world, instanceSourcePositions64Low);
target = project_position(target_world, instanceTargetPositions64Low);
// common x at longitude=-180
float antiMeridianX = 0.0;
if (arc.useShortestPath) {
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
antiMeridianX = -(project.coordinateOrigin.x + 180.) / 360. * TILE_SIZE;
}
float thresholdRatio = (antiMeridianX - source.x) / (target.x - source.x);
if (prevSegmentRatio <= thresholdRatio && nextSegmentRatio > thresholdRatio) {
isValid = 0.0;
indexDir = sign(segmentRatio - thresholdRatio);
segmentRatio = thresholdRatio;
}
}
nextSegmentRatio = indexDir < 0.0 ? prevSegmentRatio : nextSegmentRatio;
vec3 currPos = interpolateFlat(source, target, segmentRatio);
vec3 nextPos = interpolateFlat(source, target, nextSegmentRatio);
if (arc.useShortestPath) {
if (nextPos.x < antiMeridianX) {
currPos.x += TILE_SIZE;
nextPos.x += TILE_SIZE;
}
}
curr = project_common_position_to_clipspace(vec4(currPos, 1.0));
next = project_common_position_to_clipspace(vec4(nextPos, 1.0));
geometry.position = vec4(currPos, 1.0);
}
// Multiply out width and clamp to limits
// mercator pixels are interpreted as screen pixels
float widthPixels = clamp(
project_size_to_pixel(instanceWidths * arc.widthScale, arc.widthUnits),
arc.widthMinPixels, arc.widthMaxPixels
);
// extrude
vec3 offset = vec3(
getExtrusionOffset((next.xy - curr.xy) * indexDir, segmentSide, widthPixels),
0.0);
DECKGL_FILTER_SIZE(offset, geometry);
DECKGL_FILTER_GL_POSITION(curr, geometry);
gl_Position = curr + vec4(project_pixel_size_to_clipspace(offset.xy), 0.0, 0.0);
vec4 color = mix(instanceSourceColors, instanceTargetColors, segmentRatio);
vColor = vec4(color.rgb, color.a * layer.opacity);
DECKGL_FILTER_COLOR(vColor, geometry);
}
`;
// src/arc-layer/arc-layer-fragment.glsl.ts
var arc_layer_fragment_glsl_default = `#version 300 es
#define SHADER_NAME arc-layer-fragment-shader
precision highp float;
in vec4 vColor;
in vec2 uv;
in float isValid;
out vec4 fragColor;
void main(void) {
if (isValid == 0.0) {
discard;
}
fragColor = vColor;
geometry.uv = uv;
DECKGL_FILTER_COLOR(fragColor, geometry);
}
`;
// src/arc-layer/arc-layer.ts
var DEFAULT_COLOR = [0, 0, 0, 255];
var defaultProps = {
getSourcePosition: { type: "accessor", value: (x) => x.sourcePosition },
getTargetPosition: { type: "accessor", value: (x) => x.targetPosition },
getSourceColor: { type: "accessor", value: DEFAULT_COLOR },
getTargetColor: { type: "accessor", value: DEFAULT_COLOR },
getWidth: { type: "accessor", value: 1 },
getHeight: { type: "accessor", value: 1 },
getTilt: { type: "accessor", value: 0 },
greatCircle: false,
numSegments: { type: "number", value: 50, min: 1 },
widthUnits: "pixels",
widthScale: { type: "number", value: 1, min: 0 },
widthMinPixels: { type: "number", value: 0, min: 0 },
widthMaxPixels: { type: "number", value: Number.MAX_SAFE_INTEGER, min: 0 }
};
var ArcLayer = class extends import_core2.Layer {
getBounds() {
return this.getAttributeManager()?.getBounds([
"instanceSourcePositions",
"instanceTargetPositions"
]);
}
getShaders() {
return super.getShaders({ vs: arc_layer_vertex_glsl_default, fs: arc_layer_fragment_glsl_default, modules: [import_core2.project32, import_core2.picking, arcUniforms] });
}
// This layer has its own wrapLongitude logic
get wrapLongitude() {
return false;
}
initializeState() {
const attributeManager = this.getAttributeManager();
attributeManager.addInstanced({
instanceSourcePositions: {
size: 3,
type: "float64",
fp64: this.use64bitPositions(),
transition: true,
accessor: "getSourcePosition"
},
instanceTargetPositions: {
size: 3,
type: "float64",
fp64: this.use64bitPositions(),
transition: true,
accessor: "getTargetPosition"
},
instanceSourceColors: {
size: this.props.colorFormat.length,
type: "unorm8",
transition: true,
accessor: "getSourceColor",
defaultValue: DEFAULT_COLOR
},
instanceTargetColors: {
size: this.props.colorFormat.length,
type: "unorm8",
transition: true,
accessor: "getTargetColor",
defaultValue: DEFAULT_COLOR
},
instanceWidths: {
size: 1,
transition: true,
accessor: "getWidth",
defaultValue: 1
},
instanceHeights: {
size: 1,
transition: true,
accessor: "getHeight",
defaultValue: 1
},
instanceTilts: {
size: 1,
transition: true,
accessor: "getTilt",
defaultValue: 0
}
});
}
updateState(params) {
super.updateState(params);
if (params.changeFlags.extensionsChanged) {
this.state.model?.destroy();
this.state.model = this._getModel();
this.getAttributeManager().invalidateAll();
}
}
draw({ uniforms }) {
const {
widthUnits,
widthScale,
widthMinPixels,
widthMaxPixels,
greatCircle,
wrapLongitude,
numSegments
} = this.props;
const arcProps = {
numSegments,
widthUnits: import_core2.UNIT[widthUnits],
widthScale,
widthMinPixels,
widthMaxPixels,
greatCircle,
useShortestPath: wrapLongitude
};
const model = this.state.model;
model.shaderInputs.setProps({ arc: arcProps });
model.setVertexCount(numSegments * 2);
model.draw(this.context.renderPass);
}
_getModel() {
return new import_engine.Model(this.context.device, {
...this.getShaders(),
id: this.props.id,
bufferLayout: this.getAttributeManager().getBufferLayouts(),
topology: "triangle-strip",
isInstanced: true
});
}
};
ArcLayer.layerName = "ArcLayer";
ArcLayer.defaultProps = defaultProps;
// src/bitmap-layer/bitmap-layer.ts
var import_core4 = __toESM(require_core(), 1);
var import_engine2 = __toESM(require_engine(), 1);
// ../../node_modules/@math.gl/core/dist/lib/common.js
var RADIANS_TO_DEGREES = 1 / Math.PI * 180;
var DEGREES_TO_RADIANS = 1 / 180 * Math.PI;
var DEFAULT_CONFIG = {
EPSILON: 1e-12,
debug: false,
precision: 4,
printTypes: false,
printDegrees: false,
printRowMajor: true,
_cartographicRadians: false
};
globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
var config = globalThis.mathgl.config;
function isArray(value) {
return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
}
function lerp(a, b, t) {
if (isArray(a)) {
return a.map((ai, i) => lerp(ai, b[i], t));
}
return t * b + (1 - t) * a;
}
// ../../node_modules/@math.gl/web-mercator/dist/assert.js
function assert(condition, message) {
if (!condition) {
throw new Error(message || "@math.gl/web-mercator: assertion failed.");
}
}
// ../../node_modules/@math.gl/web-mercator/dist/web-mercator-utils.js
var PI = Math.PI;
var PI_4 = PI / 4;
var DEGREES_TO_RADIANS2 = PI / 180;
var RADIANS_TO_DEGREES2 = 180 / PI;
var TILE_SIZE = 512;
function lngLatToWorld(lngLat) {
const [lng, lat] = lngLat;
assert(Number.isFinite(lng));
assert(Number.isFinite(lat) && lat >= -90 && lat <= 90, "invalid latitude");
const lambda2 = lng * DEGREES_TO_RADIANS2;
const phi2 = lat * DEGREES_TO_RADIANS2;
const x = TILE_SIZE * (lambda2 + PI) / (2 * PI);
const y = TILE_SIZE * (PI + Math.log(Math.tan(PI_4 + phi2 * 0.5))) / (2 * PI);
return [x, y];
}
// ../../node_modules/@math.gl/web-mercator/dist/get-bounds.js
var DEGREES_TO_RADIANS3 = Math.PI / 180;
// src/bitmap-layer/create-mesh.ts
var DEFAULT_INDICES = new Uint32Array([0, 2, 1, 0, 3, 2]);
var DEFAULT_TEX_COORDS = new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]);
function createMesh(bounds, resolution) {
if (!resolution) {
return createQuad(bounds);
}
const maxXSpan = Math.max(
Math.abs(bounds[0][0] - bounds[3][0]),
Math.abs(bounds[1][0] - bounds[2][0])
);
const maxYSpan = Math.max(
Math.abs(bounds[1][1] - bounds[0][1]),
Math.abs(bounds[2][1] - bounds[3][1])
);
const uCount = Math.ceil(maxXSpan / resolution) + 1;
const vCount = Math.ceil(maxYSpan / resolution) + 1;
const vertexCount = (uCount - 1) * (vCount - 1) * 6;
const indices = new Uint32Array(vertexCount);
const texCoords = new Float32Array(uCount * vCount * 2);
const positions = new Float64Array(uCount * vCount * 3);
let vertex = 0;
let index = 0;
for (let u = 0; u < uCount; u++) {
const ut = u / (uCount - 1);
for (let v = 0; v < vCount; v++) {
const vt = v / (vCount - 1);
const p = interpolateQuad(bounds, ut, vt);
positions[vertex * 3 + 0] = p[0];
positions[vertex * 3 + 1] = p[1];
positions[vertex * 3 + 2] = p[2] || 0;
texCoords[vertex * 2 + 0] = ut;
texCoords[vertex * 2 + 1] = 1 - vt;
if (u > 0 && v > 0) {
indices[index++] = vertex - vCount;
indices[index++] = vertex - vCount - 1;
indices[index++] = vertex - 1;
indices[index++] = vertex - vCount;
indices[index++] = vertex - 1;
indices[index++] = vertex;
}
vertex++;
}
}
return {
vertexCount,
positions,
indices,
texCoords
};
}
function createQuad(bounds) {
const positions = new Float64Array(12);
for (let i = 0; i < bounds.length; i++) {
positions[i * 3 + 0] = bounds[i][0];
positions[i * 3 + 1] = bounds[i][1];
positions[i * 3 + 2] = bounds[i][2] || 0;
}
return {
vertexCount: 6,
positions,
indices: DEFAULT_INDICES,
texCoords: DEFAULT_TEX_COORDS
};
}
function interpolateQuad(quad, ut, vt) {
return lerp(lerp(quad[0], quad[1], vt), lerp(quad[3], quad[2], vt), ut);
}
// src/bitmap-layer/bitmap-layer-uniforms.ts
var uniformBlock2 = `uniform bitmapUniforms {
vec4 bounds;
float coordinateConversion;
float desaturate;
vec3 tintColor;
vec4 transparentColor;
} bitmap;
`;
var bitmapUniforms = {
name: "bitmap",
vs: uniformBlock2,
fs: uniformBlock2,
uniformTypes: {
bounds: "vec4<f32>",
coordinateConversion: "f32",
desaturate: "f32",
tintColor: "vec3<f32>",
transparentColor: "vec4<f32>"
}
};
// src/bitmap-layer/bitmap-layer-vertex.ts
var bitmap_layer_vertex_default = `#version 300 es
#define SHADER_NAME bitmap-layer-vertex-shader
in vec2 texCoords;
in vec3 positions;
in vec3 positions64Low;
out vec2 vTexCoord;
out vec2 vTexPos;
const vec3 pickingColor = vec3(1.0, 0.0, 0.0);
void main(void) {
geometry.worldPosition = positions;
geometry.uv = texCoords;
geometry.pickingColor = pickingColor;
gl_Position = project_position_to_clipspace(positions, positions64Low, vec3(0.0), geometry.position);
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
vTexCoord = texCoords;
if (bitmap.coordinateConversion < -0.5) {
vTexPos = geometry.position.xy + project.commonOrigin.xy;
} else if (bitmap.coordinateConversion > 0.5) {
vTexPos = geometry.worldPosition.xy;
}
vec4 color = vec4(0.0);
DECKGL_FILTER_COLOR(color, geometry);
}
`;
// src/bitmap-layer/bitmap-layer-fragment.ts
var packUVsIntoRGB = `
vec3 packUVsIntoRGB(vec2 uv) {
// Extract the top 8 bits. We want values to be truncated down so we can add a fraction
vec2 uv8bit = floor(uv * 256.);
// Calculate the normalized remainders of u and v parts that do not fit into 8 bits
// Scale and clamp to 0-1 range
vec2 uvFraction = fract(uv * 256.);
vec2 uvFraction4bit = floor(uvFraction * 16.);
// Remainder can be encoded in blue channel, encode as 4 bits for pixel coordinates
float fractions = uvFraction4bit.x + uvFraction4bit.y * 16.;
return vec3(uv8bit, fractions) / 255.;
}
`;
var bitmap_layer_fragment_default = `#version 300 es
#define SHADER_NAME bitmap-layer-fragment-shader
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D bitmapTexture;
in vec2 vTexCoord;
in vec2 vTexPos;
out vec4 fragColor;
/* projection utils */
const float TILE_SIZE = 512.0;
const float PI = 3.1415926536;
const float WORLD_SCALE = TILE_SIZE / PI / 2.0;
// from degrees to Web Mercator
vec2 lnglat_to_mercator(vec2 lnglat) {
float x = lnglat.x;
float y = clamp(lnglat.y, -89.9, 89.9);
return vec2(
radians(x) + PI,
PI + log(tan(PI * 0.25 + radians(y) * 0.5))
) * WORLD_SCALE;
}
// from Web Mercator to degrees
vec2 mercator_to_lnglat(vec2 xy) {
xy /= WORLD_SCALE;
return degrees(vec2(
xy.x - PI,
atan(exp(xy.y - PI)) * 2.0 - PI * 0.5
));
}
/* End projection utils */
// apply desaturation
vec3 color_desaturate(vec3 color) {
float luminance = (color.r + color.g + color.b) * 0.333333333;
return mix(color, vec3(luminance), bitmap.desaturate);
}
// apply tint
vec3 color_tint(vec3 color) {
return color * bitmap.tintColor;
}
// blend with background color
vec4 apply_opacity(vec3 color, float alpha) {
if (bitmap.transparentColor.a == 0.0) {
return vec4(color, alpha);
}
float blendedAlpha = alpha + bitmap.transparentColor.a * (1.0 - alpha);
float highLightRatio = alpha / blendedAlpha;
vec3 blendedRGB = mix(bitmap.transparentColor.rgb, color, highLightRatio);
return vec4(blendedRGB, blendedAlpha);
}
vec2 getUV(vec2 pos) {
return vec2(
(pos.x - bitmap.bounds[0]) / (bitmap.bounds[2] - bitmap.bounds[0]),
(pos.y - bitmap.bounds[3]) / (bitmap.bounds[1] - bitmap.bounds[3])
);
}
${packUVsIntoRGB}
void main(void) {
vec2 uv = vTexCoord;
if (bitmap.coordinateConversion < -0.5) {
vec2 lnglat = mercator_to_lnglat(vTexPos);
uv = getUV(lnglat);
} else if (bitmap.coordinateConversion > 0.5) {
vec2 commonPos = lnglat_to_mercator(vTexPos);
uv = getUV(commonPos);
}
vec4 bitmapColor = texture(bitmapTexture, uv);
fragColor = apply_opacity(color_tint(color_desaturate(bitmapColor.rgb)), bitmapColor.a * layer.opacity);
geometry.uv = uv;
DECKGL_FILTER_COLOR(fragColor, geometry);
if (bool(picking.isActive) && !bool(picking.isAttribute)) {
// Since instance information is not used, we can use picking color for pixel index
fragColor.rgb = packUVsIntoRGB(uv);
}
}
`;
// src/bitmap-layer/bitmap-layer.ts
var defaultProps2 = {
image: { type: "image", value: null, async: true },
bounds: { type: "array", value: [1, 0, 0, 1], compare: true },
_imageCoordinateSystem: import_core4.COORDINATE_SYSTEM.DEFAULT,
desaturate: { type: "number", min: 0, max: 1, value: 0 },
// More context: because of the blending mode we're using for ground imagery,
// alpha is not effective when blending the bitmap layers with the base map.
// Instead we need to manually dim/blend rgb values with a background color.
transparentColor: { type: "color", value: [0, 0, 0, 0] },
tintColor: { type: "color", value: [255, 255, 255] },
textureParameters: { type: "object", ignore: true, value: null }
};
var BitmapLayer = class extends import_core4.Layer {
getShaders() {
return super.getShaders({ vs: bitmap_layer_vertex_default, fs: bitmap_layer_fragment_default, modules: [import_core4.project32, import_core4.picking, bitmapUniforms] });
}
initializeState() {
const attributeManager = this.getAttributeManager();
attributeManager.remove(["instancePickingColors"]);
const noAlloc = true;
attributeManager.add({
indices: {
size: 1,
isIndexed: true,
update: (attribute) => attribute.value = this.state.mesh.indices,
noAlloc
},
positions: {
size: 3,
type: "float64",
fp64: this.use64bitPositions(),
update: (attribute) => attribute.value = this.state.mesh.positions,
noAlloc
},
texCoords: {
size: 2,
update: (attribute) => attribute.value = this.state.mesh.texCoords,
noAlloc
}
});
}
updateState({ props, oldProps, changeFlags }) {
const attributeManager = this.getAttributeManager();
if (changeFlags.extensionsChanged) {
this.state.model?.destroy();
this.state.model = this._getModel();
attributeManager.invalidateAll();
}
if (props.bounds !== oldProps.bounds) {
const oldMesh = this.state.mesh;
const mesh = this._createMesh();
this.state.model.setVertexCount(mesh.vertexCount);
for (const key in mesh) {
if (oldMesh && oldMesh[key] !== mesh[key]) {
attributeManager.invalidate(key);
}
}
this.setState({ mesh, ...this._getCoordinateUniforms() });
} else if (props._imageCoordinateSystem !== oldProps._imageCoordinateSystem) {
this.setState(this._getCoordinateUniforms());
}
}
getPickingInfo(params) {
const { image } = this.props;
const info = params.info;
if (!info.color || !image) {
info.bitmap = null;
return info;
}
const { width, height } = image;
info.index = 0;
const uv = unpackUVsFromRGB(info.color);
info.bitmap = {
size: { width, height },
uv,
pixel: [Math.floor(uv[0] * width), Math.floor(uv[1] * height)]
};
return info;
}
// Override base Layer multi-depth picking logic
disablePickingIndex() {
this.setState({ disablePicking: true });
}
restorePickingColors() {
this.setState({ disablePicking: false });
}
_updateAutoHighlight(info) {
super._updateAutoHighlight({
...info,
color: this.encodePickingColor(0)
});
}
_createMesh() {
const { bounds } = this.props;
let normalizedBounds = bounds;
if (isRectangularBounds(bounds)) {
normalizedBounds = [
[bounds[0], bounds[1]],
[bounds[0], bounds[3]],
[bounds[2], bounds[3]],
[bounds[2], bounds[1]]
];
}
return createMesh(normalizedBounds, this.context.viewport.resolution);
}
_getModel() {
return new import_engine2.Model(this.context.device, {
...this.getShaders(),
id: this.props.id,
bufferLayout: this.getAttributeManager().getBufferLayouts(),
topology: "triangle-list",
isInstanced: false
});
}
draw(opts) {
const { shaderModuleProps } = opts;
const { model, coordinateConversion, bounds, disablePicking } = this.state;
const { image, desaturate, transparentColor, tintColor } = this.props;
if (shaderModuleProps.picking.isActive && disablePicking) {
return;
}
if (image && model) {
const bitmapProps = {
bitmapTexture: image,
bounds,
coordinateConversion,
desaturate,
tintColor: tintColor.slice(0, 3).map((x) => x / 255),
transparentColor: transparentColor.map((x) => x / 255)
};
model.shaderInputs.setProps({ bitmap: bitmapProps });
model.draw(this.context.renderPass);
}
}
_getCoordinateUniforms() {
const { LNGLAT, CARTESIAN, DEFAULT } = import_core4.COORDINATE_SYSTEM;
let { _imageCoordinateSystem: imageCoordinateSystem } = this.props;
if (imageCoordinateSystem !== DEFAULT) {
const { bounds } = this.props;
if (!isRectangularBounds(bounds)) {
throw new Error("_imageCoordinateSystem only supports rectangular bounds");
}
const defaultImageCoordinateSystem = this.context.viewport.resolution ? LNGLAT : CARTESIAN;
imageCoordinateSystem = imageCoordinateSystem === LNGLAT ? LNGLAT : CARTESIAN;
if (imageCoordinateSystem === LNGLAT && defaultImageCoordinateSystem === CARTESIAN) {
return { coordinateConversion: -1, bounds };
}
if (imageCoordinateSystem === CARTESIAN && defaultImageCoordinateSystem === LNGLAT) {
const bottomLeft = lngLatToWorld([bounds[0], bounds[1]]);
const topRight = lngLatToWorld([bounds[2], bounds[3]]);
return {
coordinateConversion: 1,
bounds: [bottomLeft[0], bottomLeft[1], topRight[0], topRight[1]]
};
}
}
return {
coordinateConversion: 0,
bounds: [0, 0, 0, 0]
};
}
};
BitmapLayer.layerName = "BitmapLayer";
BitmapLayer.defaultProps = defaultProps2;
function unpackUVsFromRGB(color) {
const [u, v, fracUV] = color;
const vFrac = (fracUV & 240) / 256;
const uFrac = (fracUV & 15) / 16;
return [(u + uFrac) / 256, (v + vFrac) / 256];
}
function isRectangularBounds(bounds) {
return Number.isFinite(bounds[0]);
}
// src/icon-layer/icon-layer.ts
var import_core7 = __toESM(require_core(), 1);
var import_engine3 = __toESM(require_engine