@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/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { caoguoStyle, WUHAN_ZOOM, WUHAN_CENTER, osmRasterStyle } from './chunk-DNEF4DHG.js';
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-EZOV5O2M.js';
4
- export { MissingTokenError, addTiandituBaseMap, buildTiandituSources, tiandituStyle, tiandituTileUrls } from './chunk-EZOV5O2M.js';
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 === "&" ? "&amp;" : c === "<" ? "&lt;" : c === ">" ? "&gt;" : c === '"' ? "&quot;" : "&#39;"
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, coreOpacity = 1) {
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
- widthScale: 1 + (1 - t) * (passes - 1) * 1.5,
269
- opacity: coreOpacity * (0.12 + 0.88 * t)
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.coreOpacity ?? 1);
281
- let vertexCount = 0;
282
- const projected = lines.map((l) => {
283
- const points = l.coordinates.map(([lng, lat]) => projectSimple(lng, lat));
284
- vertexCount += Math.max(0, points.length - 1) * 2;
285
- return { points, group: l.group };
286
- });
287
- return { lines: projected, passes, vertexCount };
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 float aMiter;
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
- vec2 screen = clip.xy / clip.w;
309
- // \u6CE8\uFF1A\u7CBE\u786E\u7EBF\u5BBD\u9700\u6CD5\u7EBF\u8BA1\u7B97\uFF0C\u793A\u8303\u5C42\u7528\u70B9\u5BBD\u8FD1\u4F3C
310
- vec2 offset = vec2(aMiter * uWidth / uResolution.x * 2.0, 0.0);
311
- gl_Position = vec4(screen + offset * clip.w, clip.z, clip.w);
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.passes = opts.passes ?? 4;
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
- this.program = prog;
348
- const verts = [];
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, new Float32Array(verts), gl.STATIC_DRAW);
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 aMiter = gl.getAttribLocation(this.program, "aMiter");
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, 24, 0);
368
- gl.enableVertexAttribArray(aMiter);
369
- gl.vertexAttribPointer(aMiter, 1, gl.FLOAT, false, 24, 16);
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 (const pass of this.geometry.passes) {
382
- gl.uniform1f(uWidth, this.baseWidth * pass.widthScale);
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.LINES, 0, this.geometry.vertexCount);
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: options.style ?? osmRasterStyle(),
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