@caoguo/maplibre 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-EZOV5O2M.js → chunk-QGVXYR2I.js} +3 -3
- package/dist/{chunk-EZOV5O2M.js.map → chunk-QGVXYR2I.js.map} +1 -1
- package/dist/index.cjs +316 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +244 -25
- package/dist/index.d.ts +244 -25
- package/dist/index.js +308 -40
- package/dist/index.js.map +1 -1
- package/dist/sources/index.cjs +1 -1
- package/dist/sources/index.cjs.map +1 -1
- package/dist/sources/index.js +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { caoguoStyle, WUHAN_ZOOM, WUHAN_CENTER
|
|
1
|
+
import { caoguoStyle, osmRasterStyle, WUHAN_ZOOM, WUHAN_CENTER } from './chunk-DNEF4DHG.js';
|
|
2
2
|
export { WUHAN_CENTER, WUHAN_ZOOM, osmRasterStyle } from './chunk-DNEF4DHG.js';
|
|
3
|
-
import { tiandituStyle, addTiandituBaseMap } from './chunk-
|
|
4
|
-
export { MissingTokenError, addTiandituBaseMap, buildTiandituSources, tiandituStyle, tiandituTileUrls } from './chunk-
|
|
3
|
+
import { MissingTokenError, tiandituStyle, addTiandituBaseMap } from './chunk-QGVXYR2I.js';
|
|
4
|
+
export { MissingTokenError, addTiandituBaseMap, buildTiandituSources, tiandituStyle, tiandituTileUrls } from './chunk-QGVXYR2I.js';
|
|
5
5
|
import { createDefaultStore, registerOfflineProtocol, offlineSourceTiles, packGeoJSONToStore } from './chunk-MNUQZUQA.js';
|
|
6
6
|
export { CACHEABLE_HOSTS, CACHE_NAME, IdbTileStore, MSG_AIRGAP, MemoryTileStore, OFFLINE_PROTOCOL, SW_TEMPLATE_HINT, createDefaultStore, createFetchHandler, createOfflineLoader, installServiceWorker, offlineGeoJSONSource, offlineSourceTiles, offlineTileUrl, packGeoJSONToStore, parseOfflineUrl, registerOfflineProtocol, registerOfflineServiceWorker, resolveCacheKey, resolveFromStore, resolveResponse, setAirgap, shouldCache, tileKey } from './chunk-MNUQZUQA.js';
|
|
7
7
|
import maplibregl from 'maplibre-gl';
|
|
@@ -258,15 +258,96 @@ var ThemeSwitcher = class {
|
|
|
258
258
|
}
|
|
259
259
|
};
|
|
260
260
|
|
|
261
|
+
// src/controls/LegendControl.ts
|
|
262
|
+
function escapeHtml(s) {
|
|
263
|
+
return s.replace(
|
|
264
|
+
/[&<>"']/g,
|
|
265
|
+
(c) => c === "&" ? "&" : c === "<" ? "<" : c === ">" ? ">" : c === '"' ? """ : "'"
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
function renderLegendHtml(items, title) {
|
|
269
|
+
const titleHtml = title ? `<div class="cg-legend-title">${escapeHtml(title)}</div>` : "";
|
|
270
|
+
const itemsHtml = items.map((it) => {
|
|
271
|
+
const swatch = it.shape === "line" ? `<span class="cg-legend-swatch cg-legend-swatch--line" style="background:${it.color}"></span>` : `<span class="cg-legend-swatch" style="background:${it.color}"></span>`;
|
|
272
|
+
return `<div class="cg-legend-item">${swatch}<span>${escapeHtml(it.label)}</span></div>`;
|
|
273
|
+
}).join("");
|
|
274
|
+
return `<div class="cg-legend-body">${titleHtml}${itemsHtml}</div>`;
|
|
275
|
+
}
|
|
276
|
+
var LegendControl = class {
|
|
277
|
+
constructor(options) {
|
|
278
|
+
this.opts = { title: options.title ?? "", items: options.items };
|
|
279
|
+
this.el = options.container ?? document.createElement("div");
|
|
280
|
+
this.el.className = "caoguo-legend-control";
|
|
281
|
+
this.el.style.cssText = "position:absolute;right:10px;top:10px;padding:8px 10px;background:rgba(10,15,30,.72);color:#cfe;border-radius:6px;font:12px/1.5 system-ui,sans-serif;z-index:2;max-width:220px;";
|
|
282
|
+
this.bodyEl = document.createElement("div");
|
|
283
|
+
this.el.appendChild(this.bodyEl);
|
|
284
|
+
this.render();
|
|
285
|
+
}
|
|
286
|
+
render() {
|
|
287
|
+
this.bodyEl.innerHTML = renderLegendHtml(this.opts.items, this.opts.title || void 0);
|
|
288
|
+
}
|
|
289
|
+
/** 运行时更新图例项(随图层切换重新渲染) */
|
|
290
|
+
setItems(items, title) {
|
|
291
|
+
if (title !== void 0) this.opts.title = title;
|
|
292
|
+
this.opts.items = items;
|
|
293
|
+
this.render();
|
|
294
|
+
}
|
|
295
|
+
/** 挂载到容器 */
|
|
296
|
+
addTo(container) {
|
|
297
|
+
if (!this.el.parentElement) container.appendChild(this.el);
|
|
298
|
+
return this;
|
|
299
|
+
}
|
|
300
|
+
remove() {
|
|
301
|
+
this.el.remove();
|
|
302
|
+
}
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// src/controls/ExportControl.ts
|
|
306
|
+
function triggerDownload(dataUrl, filename) {
|
|
307
|
+
const a = document.createElement("a");
|
|
308
|
+
a.href = dataUrl;
|
|
309
|
+
a.download = filename.endsWith(".png") ? filename : `${filename}.png`;
|
|
310
|
+
document.body.appendChild(a);
|
|
311
|
+
a.click();
|
|
312
|
+
a.remove();
|
|
313
|
+
}
|
|
314
|
+
var ExportControl = class {
|
|
315
|
+
constructor(map, options = {}) {
|
|
316
|
+
this.onClick = () => this.export();
|
|
317
|
+
this.map = map;
|
|
318
|
+
this.filename = options.filename ?? "caoguo-map";
|
|
319
|
+
this.el = options.container ?? document.createElement("button");
|
|
320
|
+
this.el.className = "caoguo-export-control";
|
|
321
|
+
this.el.textContent = options.buttonText ?? "\u5BFC\u51FA PNG";
|
|
322
|
+
this.el.style.cssText = "position:absolute;right:10px;top:10px;padding:5px 10px;background:rgba(10,15,30,.72);color:#cfe;border:1px solid #2a3550;border-radius:4px;font:12px system-ui,sans-serif;cursor:pointer;z-index:3;";
|
|
323
|
+
this.el.addEventListener("click", this.onClick);
|
|
324
|
+
}
|
|
325
|
+
/** 导出当前地图视图为 PNG 并下载 */
|
|
326
|
+
export() {
|
|
327
|
+
const canvas = this.map.getCanvas();
|
|
328
|
+
const url = canvas.toDataURL("image/png");
|
|
329
|
+
triggerDownload(url, this.filename);
|
|
330
|
+
}
|
|
331
|
+
/** 挂载到容器 */
|
|
332
|
+
addTo(container) {
|
|
333
|
+
if (!this.el.parentElement) container.appendChild(this.el);
|
|
334
|
+
return this;
|
|
335
|
+
}
|
|
336
|
+
remove() {
|
|
337
|
+
this.el.removeEventListener("click", this.onClick);
|
|
338
|
+
this.el.remove();
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
|
|
261
342
|
// src/shaders/glowGeometry.ts
|
|
262
|
-
function glowPasses(passes = 4,
|
|
343
|
+
function glowPasses(passes = 4, baseWidth = 3) {
|
|
263
344
|
if (passes < 1) passes = 1;
|
|
264
345
|
const out = [];
|
|
265
346
|
for (let i = 0; i < passes; i++) {
|
|
266
347
|
const t = passes === 1 ? 1 : 1 - i / (passes - 1);
|
|
267
348
|
out.push({
|
|
268
|
-
|
|
269
|
-
opacity:
|
|
349
|
+
width: baseWidth * (1 + (1 - t) * (passes - 1) * 1.8),
|
|
350
|
+
opacity: 0.1 + 0.9 * t * t
|
|
270
351
|
});
|
|
271
352
|
}
|
|
272
353
|
return out;
|
|
@@ -274,17 +355,40 @@ function glowPasses(passes = 4, coreOpacity = 1) {
|
|
|
274
355
|
function projectSimple(lng, lat) {
|
|
275
356
|
const x = lng / 180;
|
|
276
357
|
const y = Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)) / Math.PI;
|
|
277
|
-
return [x, Math.max(-1, Math.min(1, y))];
|
|
358
|
+
return [x, Math.max(-1, Math.min(1, y / Math.PI))];
|
|
278
359
|
}
|
|
279
360
|
function buildGlowGeometry(lines, opts = {}) {
|
|
280
|
-
const passes = glowPasses(opts.passes ?? 4, opts.
|
|
281
|
-
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
361
|
+
const passes = glowPasses(opts.passes ?? 4, opts.baseWidth ?? 3);
|
|
362
|
+
const stride = 5;
|
|
363
|
+
const verts = [];
|
|
364
|
+
const passRanges = [];
|
|
365
|
+
for (const pass of passes) {
|
|
366
|
+
const start = verts.length / stride;
|
|
367
|
+
for (const line of lines) {
|
|
368
|
+
const pts = line.coordinates.map(([lng, lat]) => projectSimple(lng, lat));
|
|
369
|
+
if (pts.length < 2) continue;
|
|
370
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
371
|
+
const a = pts[i];
|
|
372
|
+
const b = pts[i + 1];
|
|
373
|
+
const dx = b[0] - a[0];
|
|
374
|
+
const dy = b[1] - a[1];
|
|
375
|
+
const quad = [
|
|
376
|
+
[a[0], a[1], dx, dy, 1],
|
|
377
|
+
[a[0], a[1], dx, dy, -1],
|
|
378
|
+
[b[0], b[1], dx, dy, 1],
|
|
379
|
+
[b[0], b[1], dx, dy, -1]
|
|
380
|
+
];
|
|
381
|
+
const idx = [0, 1, 2, 2, 1, 3];
|
|
382
|
+
for (const k of idx) {
|
|
383
|
+
const v = quad[k];
|
|
384
|
+
verts.push(v[0], v[1], v[2], v[3], v[4]);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
const count = verts.length / stride - start;
|
|
389
|
+
passRanges.push({ start, count });
|
|
390
|
+
}
|
|
391
|
+
return { vertices: new Float32Array(verts), passRanges, passes, stride };
|
|
288
392
|
}
|
|
289
393
|
|
|
290
394
|
// src/shaders/CustomLineLayer.ts
|
|
@@ -298,17 +402,21 @@ var DEFAULT_COLORS = {
|
|
|
298
402
|
};
|
|
299
403
|
var VERT = `
|
|
300
404
|
attribute vec2 aPos;
|
|
301
|
-
attribute
|
|
405
|
+
attribute vec2 aDir;
|
|
406
|
+
attribute float aSide;
|
|
302
407
|
uniform mat4 uMatrix;
|
|
303
408
|
uniform float uWidth;
|
|
304
409
|
uniform vec2 uResolution;
|
|
305
410
|
void main() {
|
|
306
|
-
// \u7B80\u5316\uFF1A\u6CBF\u6CD5\u7EBF\u65B9\u5411\u504F\u79FB width\uFF08\u5C4F\u5E55\u7A7A\u95F4\uFF09\uFF0C\u8FD9\u91CC\u4EC5\u6F14\u793A\u6838\u5FC3\u6295\u5F71
|
|
307
411
|
vec4 clip = uMatrix * vec4(aPos, 0.0, 1.0);
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
vec2
|
|
311
|
-
|
|
412
|
+
// \u6BB5\u65B9\u5411\u4E5F\u6295\u5F71\uFF0C\u6C42\u5C4F\u5E55\u7A7A\u95F4\u65B9\u5411
|
|
413
|
+
vec4 clipDir = uMatrix * vec4(aPos + aDir, 0.0, 1.0);
|
|
414
|
+
vec2 s0 = clip.xy / clip.w;
|
|
415
|
+
vec2 s1 = clipDir.xy / clipDir.w;
|
|
416
|
+
vec2 dir = normalize(s1 - s0 + vec2(1e-6));
|
|
417
|
+
vec2 normal = vec2(-dir.y, dir.x);
|
|
418
|
+
vec2 offset = normal * aSide * (uWidth / uResolution * 2.0);
|
|
419
|
+
gl_Position = vec4(s0 + offset * clip.w, clip.z, clip.w);
|
|
312
420
|
}
|
|
313
421
|
`;
|
|
314
422
|
var FRAG = `
|
|
@@ -323,6 +431,9 @@ function compile(gl, type, src) {
|
|
|
323
431
|
const sh = gl.createShader(type);
|
|
324
432
|
gl.shaderSource(sh, src);
|
|
325
433
|
gl.compileShader(sh);
|
|
434
|
+
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
|
|
435
|
+
console.error("[CustomLineLayer] shader \u7F16\u8BD1\u5931\u8D25:", gl.getShaderInfoLog(sh));
|
|
436
|
+
}
|
|
326
437
|
return sh;
|
|
327
438
|
}
|
|
328
439
|
var CustomLineLayer = class {
|
|
@@ -333,8 +444,7 @@ var CustomLineLayer = class {
|
|
|
333
444
|
this.lines = opts.lines;
|
|
334
445
|
this.colors = { ...DEFAULT_COLORS, ...opts.colors };
|
|
335
446
|
this.baseWidth = opts.baseWidth ?? 3;
|
|
336
|
-
this.
|
|
337
|
-
this.geometry = buildGlowGeometry(this.lines, { passes: this.passes });
|
|
447
|
+
this.geometry = buildGlowGeometry(this.lines, { passes: opts.passes ?? 4, baseWidth: this.baseWidth });
|
|
338
448
|
}
|
|
339
449
|
onAdd(map, gl) {
|
|
340
450
|
this.map = map;
|
|
@@ -344,29 +454,29 @@ var CustomLineLayer = class {
|
|
|
344
454
|
gl.attachShader(prog, vs);
|
|
345
455
|
gl.attachShader(prog, fs);
|
|
346
456
|
gl.linkProgram(prog);
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
for (const line of this.geometry.lines) {
|
|
350
|
-
const pts = line.points;
|
|
351
|
-
for (let i = 0; i < pts.length - 1; i++) {
|
|
352
|
-
verts.push(pts[i][0], pts[i][1], 0, pts[i + 1][0], pts[i + 1][1], 0);
|
|
353
|
-
}
|
|
457
|
+
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
|
|
458
|
+
console.error("[CustomLineLayer] program \u94FE\u63A5\u5931\u8D25:", gl.getProgramInfoLog(prog));
|
|
354
459
|
}
|
|
460
|
+
this.program = prog;
|
|
355
461
|
const buf = gl.createBuffer();
|
|
356
462
|
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
|
357
|
-
gl.bufferData(gl.ARRAY_BUFFER,
|
|
463
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.geometry.vertices, gl.STATIC_DRAW);
|
|
358
464
|
this.buffer = buf;
|
|
359
465
|
}
|
|
360
466
|
render(gl, matrix) {
|
|
361
467
|
if (!this.program || !this.buffer) return;
|
|
362
468
|
gl.useProgram(this.program);
|
|
363
469
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
470
|
+
const stride = this.geometry.stride * 4;
|
|
364
471
|
const aPos = gl.getAttribLocation(this.program, "aPos");
|
|
365
|
-
const
|
|
472
|
+
const aDir = gl.getAttribLocation(this.program, "aDir");
|
|
473
|
+
const aSide = gl.getAttribLocation(this.program, "aSide");
|
|
366
474
|
gl.enableVertexAttribArray(aPos);
|
|
367
|
-
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false,
|
|
368
|
-
gl.enableVertexAttribArray(
|
|
369
|
-
gl.vertexAttribPointer(
|
|
475
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, stride, 0);
|
|
476
|
+
gl.enableVertexAttribArray(aDir);
|
|
477
|
+
gl.vertexAttribPointer(aDir, 2, gl.FLOAT, false, stride, 8);
|
|
478
|
+
gl.enableVertexAttribArray(aSide);
|
|
479
|
+
gl.vertexAttribPointer(aSide, 1, gl.FLOAT, false, stride, 16);
|
|
370
480
|
const uMatrix = gl.getUniformLocation(this.program, "uMatrix");
|
|
371
481
|
gl.uniformMatrix4fv(uMatrix, false, new Float32Array(matrix));
|
|
372
482
|
const uWidth = gl.getUniformLocation(this.program, "uWidth");
|
|
@@ -378,11 +488,14 @@ var CustomLineLayer = class {
|
|
|
378
488
|
gl.enable(gl.BLEND);
|
|
379
489
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
|
380
490
|
const color = this.colors[this.lines[0]?.group ?? "pipe"] ?? this.colors.pipe;
|
|
381
|
-
for (
|
|
382
|
-
|
|
491
|
+
for (let p = 0; p < this.geometry.passes.length; p++) {
|
|
492
|
+
const pass = this.geometry.passes[p];
|
|
493
|
+
const range = this.geometry.passRanges[p];
|
|
494
|
+
if (range.count <= 0) continue;
|
|
495
|
+
gl.uniform1f(uWidth, pass.width);
|
|
383
496
|
gl.uniform3f(uColor, color[0], color[1], color[2]);
|
|
384
497
|
gl.uniform1f(uOpacity, pass.opacity);
|
|
385
|
-
gl.drawArrays(gl.
|
|
498
|
+
gl.drawArrays(gl.TRIANGLES, range.start, range.count);
|
|
386
499
|
}
|
|
387
500
|
}
|
|
388
501
|
onRemove(_map, gl) {
|
|
@@ -446,17 +559,119 @@ var LodController = class {
|
|
|
446
559
|
}
|
|
447
560
|
};
|
|
448
561
|
|
|
562
|
+
// src/terrain.ts
|
|
563
|
+
var DEFAULT_TERRAIN_TILES = [
|
|
564
|
+
"https://elevation-tiles-prod.s3.amazonaws.com/terrarium/{z}/{x}/{y}.png"
|
|
565
|
+
];
|
|
566
|
+
function applyTerrain(mlMap, opts = {}) {
|
|
567
|
+
const sourceId = opts.sourceId ?? "cg-dem";
|
|
568
|
+
if (!mlMap.getSource(sourceId)) {
|
|
569
|
+
mlMap.addSource(sourceId, {
|
|
570
|
+
type: "raster-dem",
|
|
571
|
+
tiles: opts.tiles ?? DEFAULT_TERRAIN_TILES,
|
|
572
|
+
encoding: opts.encoding ?? "terrarium",
|
|
573
|
+
tileSize: 256,
|
|
574
|
+
maxzoom: opts.maxzoom ?? 15
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
mlMap.setTerrain({ source: sourceId, exaggeration: opts.exaggeration ?? 1.5 });
|
|
578
|
+
}
|
|
579
|
+
function removeTerrain(mlMap, sourceId = "cg-dem") {
|
|
580
|
+
mlMap.setTerrain(null);
|
|
581
|
+
if (mlMap.getSource(sourceId)) {
|
|
582
|
+
mlMap.removeSource(sourceId);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// src/sourceUtils.ts
|
|
587
|
+
function upsertSource(mlMap, id, data) {
|
|
588
|
+
if (mlMap.getSource(id)) {
|
|
589
|
+
if (mlMap.setData) {
|
|
590
|
+
mlMap.setData(id, data);
|
|
591
|
+
} else if (mlMap.addSource) {
|
|
592
|
+
mlMap.addSource(id, data);
|
|
593
|
+
}
|
|
594
|
+
} else if (mlMap.addSource) {
|
|
595
|
+
mlMap.addSource(id, data);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
function removeSourceSafe(mlMap, id) {
|
|
599
|
+
if (mlMap.getSource(id) && mlMap.removeSource) {
|
|
600
|
+
mlMap.removeSource(id);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
function removeSourcesSafe(mlMap, ids) {
|
|
604
|
+
for (const id of ids) {
|
|
605
|
+
removeSourceSafe(mlMap, id);
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
|
|
449
609
|
// src/index.ts
|
|
610
|
+
var WebGLUnavailableError = class extends Error {
|
|
611
|
+
constructor(message = "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 WebGL\uFF0C\u65E0\u6CD5\u6E32\u67D3\u5730\u56FE") {
|
|
612
|
+
super(message);
|
|
613
|
+
this.name = "WebGLUnavailableError";
|
|
614
|
+
}
|
|
615
|
+
};
|
|
616
|
+
function isWebGLAvailable() {
|
|
617
|
+
try {
|
|
618
|
+
const canvas = document.createElement("canvas");
|
|
619
|
+
let failed = false;
|
|
620
|
+
const onErr = () => {
|
|
621
|
+
failed = true;
|
|
622
|
+
};
|
|
623
|
+
canvas.addEventListener("webglcontextcreationerror", onErr, { once: true });
|
|
624
|
+
const gl = canvas.getContext("webgl2") || canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
|
625
|
+
canvas.removeEventListener("webglcontextcreationerror", onErr);
|
|
626
|
+
if (failed || !gl) return false;
|
|
627
|
+
const vendor = gl.getParameter(gl.VERSION);
|
|
628
|
+
if (!vendor) return false;
|
|
629
|
+
const vs = gl.createShader(gl.VERTEX_SHADER);
|
|
630
|
+
if (!vs) return false;
|
|
631
|
+
gl.shaderSource(vs, "attribute vec2 p; void main(){ gl_Position = vec4(p,0.0,1.0); }");
|
|
632
|
+
gl.compileShader(vs);
|
|
633
|
+
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) return false;
|
|
634
|
+
return true;
|
|
635
|
+
} catch {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
var GLOBAL_KEY = "__caoguoMapConfig__";
|
|
640
|
+
function setGlobalConfig(cfg) {
|
|
641
|
+
const prev = getGlobalConfig();
|
|
642
|
+
globalThis[GLOBAL_KEY] = { ...prev, ...cfg };
|
|
643
|
+
}
|
|
644
|
+
function getGlobalConfig() {
|
|
645
|
+
return globalThis[GLOBAL_KEY] ?? {};
|
|
646
|
+
}
|
|
450
647
|
var Map = class {
|
|
451
648
|
constructor(options) {
|
|
452
649
|
/** 离线瓦片后端(默认浏览器 IndexedDB / Node 内存) */
|
|
453
650
|
this._store = createDefaultStore();
|
|
454
651
|
this._dataCRS = options.dataCRS ?? "WGS84";
|
|
652
|
+
if (!isWebGLAvailable()) {
|
|
653
|
+
throw new WebGLUnavailableError();
|
|
654
|
+
}
|
|
655
|
+
let style = osmRasterStyle();
|
|
656
|
+
if (options.style) {
|
|
657
|
+
style = options.style;
|
|
658
|
+
} else if (options.tianditu) {
|
|
659
|
+
if (!options.tianditu.token) throw new MissingTokenError();
|
|
660
|
+
style = tiandituStyle(
|
|
661
|
+
options.tianditu.type ?? "vector",
|
|
662
|
+
options.tianditu
|
|
663
|
+
);
|
|
664
|
+
} else {
|
|
665
|
+
const g = getGlobalConfig();
|
|
666
|
+
if (g.tiandituToken) {
|
|
667
|
+
style = tiandituStyle("vector", { token: g.tiandituToken });
|
|
668
|
+
}
|
|
669
|
+
}
|
|
455
670
|
this._map = new maplibregl.Map({
|
|
456
671
|
container: options.container,
|
|
457
672
|
center: options.center ?? WUHAN_CENTER,
|
|
458
673
|
zoom: options.zoom ?? WUHAN_ZOOM,
|
|
459
|
-
style
|
|
674
|
+
style,
|
|
460
675
|
pitch: options.pitch ?? 0,
|
|
461
676
|
bearing: options.bearing ?? 0,
|
|
462
677
|
attributionControl: { compact: true }
|
|
@@ -525,8 +740,23 @@ var Map = class {
|
|
|
525
740
|
else this._map.on(event, cb);
|
|
526
741
|
}
|
|
527
742
|
addSource(id, source) {
|
|
743
|
+
if (this._map.getSource(id)) {
|
|
744
|
+
try {
|
|
745
|
+
this._map.removeSource(id);
|
|
746
|
+
} catch {
|
|
747
|
+
}
|
|
748
|
+
}
|
|
528
749
|
this._map.addSource(id, source);
|
|
529
750
|
}
|
|
751
|
+
/** 安全移除 source(不存在时静默忽略) */
|
|
752
|
+
removeSource(id) {
|
|
753
|
+
if (this._map.getSource(id)) {
|
|
754
|
+
try {
|
|
755
|
+
this._map.removeSource(id);
|
|
756
|
+
} catch {
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
530
760
|
getSource(id) {
|
|
531
761
|
return this._map.getSource(id);
|
|
532
762
|
}
|
|
@@ -556,6 +786,26 @@ var Map = class {
|
|
|
556
786
|
ctrl.addTo(container);
|
|
557
787
|
return ctrl;
|
|
558
788
|
}
|
|
789
|
+
/**
|
|
790
|
+
* 挂载图例控件(通用):渲染数据驱动的色块/线段图例,说明专题图层语义。
|
|
791
|
+
* 返回控件实例,可调用 .setItems() 随图层切换更新、.remove() 卸载。
|
|
792
|
+
*/
|
|
793
|
+
addLegendControl(options) {
|
|
794
|
+
const ctrl = new LegendControl(options);
|
|
795
|
+
const container = this._map.getContainer();
|
|
796
|
+
ctrl.addTo(container);
|
|
797
|
+
return ctrl;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* 挂载地图导出控件(通用):点击按钮将当前视图导出为 PNG 下载。
|
|
801
|
+
* 返回控件实例,可调用 .remove() 卸载。
|
|
802
|
+
*/
|
|
803
|
+
addExportControl(options = {}) {
|
|
804
|
+
const ctrl = new ExportControl(this._map, options);
|
|
805
|
+
const container = this._map.getContainer();
|
|
806
|
+
ctrl.addTo(container);
|
|
807
|
+
return ctrl;
|
|
808
|
+
}
|
|
559
809
|
/**
|
|
560
810
|
* 挂载辉光管线 Custom Layer(T6 / F-1.3)。
|
|
561
811
|
* 传入 GeoJSON 线集合,叠加渲染管线/路网/水系辉光效果。
|
|
@@ -576,12 +826,30 @@ var Map = class {
|
|
|
576
826
|
ctrl.evaluate(true);
|
|
577
827
|
return ctrl;
|
|
578
828
|
}
|
|
829
|
+
/**
|
|
830
|
+
* 启用 3D 地形渲染(F-1.5)。
|
|
831
|
+
*
|
|
832
|
+
* 注入 raster-dem 高程源并调用 maplibre-gl 原生 `setTerrain`,使地图呈现地形起伏。
|
|
833
|
+
* DEM 瓦片默认使用公共 Terrarium 源(elevation-tiles-prod,Terrain-RGB 编码,支持 CORS),
|
|
834
|
+
* 可在 opts.tiles 覆盖为私有瓦片服务(如 MinIO / 本地 MBTiles 服务)。
|
|
835
|
+
*
|
|
836
|
+
* @param opts.exaggeration 地形夸张系数(默认 1.5)
|
|
837
|
+
* @param opts.tiles DEM 瓦片模板,{z}/{x}/{y} 占位
|
|
838
|
+
* @param opts.encoding 'terrarium'(默认,Mapzen)| 'mapbox'
|
|
839
|
+
*/
|
|
840
|
+
enableTerrain(opts = {}) {
|
|
841
|
+
applyTerrain(this._map, opts);
|
|
842
|
+
}
|
|
843
|
+
/** 关闭 3D 地形渲染(F-1.5),并移除 DEM 源 */
|
|
844
|
+
disableTerrain(sourceId = "cg-dem") {
|
|
845
|
+
removeTerrain(this._map, sourceId);
|
|
846
|
+
}
|
|
579
847
|
get instance() {
|
|
580
848
|
return this._map;
|
|
581
849
|
}
|
|
582
850
|
};
|
|
583
851
|
var src_default = Map;
|
|
584
852
|
|
|
585
|
-
export { CustomLineLayer, LodController, Map, ScaleControl, ThemeSwitcher, buildGlowGeometry, cgcs2000ToWgs84, computeScaleBar, createTransformer, src_default as default, fromWgs84, gcj02ToWgs84, glowPasses, isInChina, oppositeTheme, projectSimple, resolveLod, setCgcs2000GridShift, suggestDensity, themeFromStyle, toWgs84, transformBounds, transformPoint, wgs84ToCgcs2000, wgs84ToGcj02 };
|
|
853
|
+
export { CustomLineLayer, ExportControl, LegendControl, LodController, Map, ScaleControl, ThemeSwitcher, WebGLUnavailableError, buildGlowGeometry, cgcs2000ToWgs84, computeScaleBar, createTransformer, src_default as default, fromWgs84, gcj02ToWgs84, getGlobalConfig, glowPasses, isInChina, isWebGLAvailable, oppositeTheme, projectSimple, removeSourceSafe, removeSourcesSafe, renderLegendHtml, resolveLod, setCgcs2000GridShift, setGlobalConfig, suggestDensity, themeFromStyle, toWgs84, transformBounds, transformPoint, triggerDownload, upsertSource, wgs84ToCgcs2000, wgs84ToGcj02 };
|
|
586
854
|
//# sourceMappingURL=index.js.map
|
|
587
855
|
//# sourceMappingURL=index.js.map
|