@caoguo/maplibre 0.0.6 → 0.0.7

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.
Files changed (64) hide show
  1. package/dist/chunk-DENQSIV2.js +81 -0
  2. package/dist/chunk-DENQSIV2.js.map +1 -0
  3. package/dist/chunk-G7VY42ZG.js +210 -0
  4. package/dist/chunk-G7VY42ZG.js.map +1 -0
  5. package/dist/chunk-MLLIAWVI.js +214 -0
  6. package/dist/chunk-MLLIAWVI.js.map +1 -0
  7. package/dist/chunk-OLS4DD3F.js +27 -0
  8. package/dist/chunk-OLS4DD3F.js.map +1 -0
  9. package/dist/chunk-OUEPE6JT.js +26 -0
  10. package/dist/chunk-OUEPE6JT.js.map +1 -0
  11. package/dist/chunk-SKXL3DKL.js +125 -0
  12. package/dist/chunk-SKXL3DKL.js.map +1 -0
  13. package/dist/chunk-Y3JNDOHU.js +56 -0
  14. package/dist/chunk-Y3JNDOHU.js.map +1 -0
  15. package/dist/controls/index.cjs +227 -0
  16. package/dist/controls/index.cjs.map +1 -0
  17. package/dist/controls/index.d.cts +171 -0
  18. package/dist/controls/index.d.ts +171 -0
  19. package/dist/controls/index.js +4 -0
  20. package/dist/controls/index.js.map +1 -0
  21. package/dist/crs/index.cjs +137 -0
  22. package/dist/crs/index.cjs.map +1 -0
  23. package/dist/crs/index.d.cts +80 -0
  24. package/dist/crs/index.d.ts +80 -0
  25. package/dist/crs/index.js +3 -0
  26. package/dist/crs/index.js.map +1 -0
  27. package/dist/index.cjs +48 -13
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +11 -499
  30. package/dist/index.d.ts +11 -499
  31. package/dist/index.js +14 -643
  32. package/dist/index.js.map +1 -1
  33. package/dist/lod/index.cjs +60 -0
  34. package/dist/lod/index.cjs.map +1 -0
  35. package/dist/lod/index.d.cts +62 -0
  36. package/dist/lod/index.d.ts +62 -0
  37. package/dist/lod/index.js +3 -0
  38. package/dist/lod/index.js.map +1 -0
  39. package/dist/shaders/index.cjs +215 -0
  40. package/dist/shaders/index.cjs.map +1 -0
  41. package/dist/shaders/index.d.cts +131 -0
  42. package/dist/shaders/index.d.ts +131 -0
  43. package/dist/shaders/index.js +3 -0
  44. package/dist/shaders/index.js.map +1 -0
  45. package/dist/sourceUtils.cjs +30 -0
  46. package/dist/sourceUtils.cjs.map +1 -0
  47. package/dist/sourceUtils.d.cts +60 -0
  48. package/dist/sourceUtils.d.ts +60 -0
  49. package/dist/sourceUtils.js +3 -0
  50. package/dist/sourceUtils.js.map +1 -0
  51. package/dist/styles.cjs +47 -12
  52. package/dist/styles.cjs.map +1 -1
  53. package/dist/styles.d.cts +13 -4
  54. package/dist/styles.d.ts +13 -4
  55. package/dist/styles.js +1 -1
  56. package/dist/terrain.cjs +31 -0
  57. package/dist/terrain.cjs.map +1 -0
  58. package/dist/terrain.d.cts +28 -0
  59. package/dist/terrain.d.ts +28 -0
  60. package/dist/terrain.js +3 -0
  61. package/dist/terrain.js.map +1 -0
  62. package/package.json +31 -1
  63. package/dist/chunk-DNEF4DHG.js +0 -48
  64. package/dist/chunk-DNEF4DHG.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,652 +1,23 @@
1
- import { caoguoStyle, osmRasterStyle, WUHAN_ZOOM, WUHAN_CENTER } from './chunk-DNEF4DHG.js';
2
- export { WUHAN_CENTER, WUHAN_ZOOM, osmRasterStyle } from './chunk-DNEF4DHG.js';
1
+ import { applyTerrain, removeTerrain } from './chunk-OLS4DD3F.js';
2
+ export { removeSourceSafe, removeSourcesSafe, upsertSource } from './chunk-OUEPE6JT.js';
3
3
  import { MissingTokenError, tiandituStyle, addTiandituBaseMap } from './chunk-QGVXYR2I.js';
4
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
+ import { ScaleControl, ThemeSwitcher, LegendControl, ExportControl } from './chunk-MLLIAWVI.js';
8
+ export { ExportControl, LegendControl, ScaleControl, ThemeSwitcher, computeScaleBar, oppositeTheme, renderLegendHtml, themeFromStyle, triggerDownload } from './chunk-MLLIAWVI.js';
9
+ import { localBasemapStyle, WUHAN_ZOOM, WUHAN_CENTER } from './chunk-DENQSIV2.js';
10
+ export { WUHAN_CENTER, WUHAN_ZOOM, geoqRasterStyle, localBasemapStyle, osmRasterStyle } from './chunk-DENQSIV2.js';
11
+ import { toWgs84, createTransformer } from './chunk-SKXL3DKL.js';
12
+ export { cgcs2000ToWgs84, createTransformer, fromWgs84, gcj02ToWgs84, isInChina, setCgcs2000GridShift, toWgs84, transformBounds, transformPoint, wgs84ToCgcs2000, wgs84ToGcj02 } from './chunk-SKXL3DKL.js';
13
+ import { LodController } from './chunk-Y3JNDOHU.js';
14
+ export { LodController, resolveLod, suggestDensity } from './chunk-Y3JNDOHU.js';
15
+ import { CustomLineLayer } from './chunk-G7VY42ZG.js';
16
+ export { CustomLineLayer, buildGlowGeometry, glowPasses, projectSimple } from './chunk-G7VY42ZG.js';
7
17
  import maplibregl from 'maplibre-gl';
8
18
  export { default as maplibregl } from 'maplibre-gl';
9
19
  import 'maplibre-gl/dist/maplibre-gl.css';
10
20
 
11
- // src/crs/gcj02.ts
12
- var PI = Math.PI;
13
- var A = 6378245;
14
- var EE = 0.006693421622965943;
15
- function outOfChina(lng, lat) {
16
- return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271;
17
- }
18
- function transformLat(lng, lat) {
19
- let ret = -100 + 2 * lng + 3 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
20
- ret += (20 * Math.sin(6 * lng * PI) + 20 * Math.sin(2 * lng * PI)) * 2 / 3;
21
- ret += (20 * Math.sin(lat * PI) + 40 * Math.sin(lat / 3 * PI)) * 2 / 3;
22
- ret += (160 * Math.sin(lat / 12 * PI) + 320 * Math.sin(lat * PI / 30)) * 2 / 3;
23
- return ret;
24
- }
25
- function transformLng(lng, lat) {
26
- let ret = 300 + lng + 2 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
27
- ret += (20 * Math.sin(6 * lng * PI) + 20 * Math.sin(2 * lng * PI)) * 2 / 3;
28
- ret += (20 * Math.sin(lng * PI) + 40 * Math.sin(lng / 3 * PI)) * 2 / 3;
29
- ret += (150 * Math.sin(lng / 12 * PI) + 300 * Math.sin(lng / 30 * PI)) * 2 / 3;
30
- return ret;
31
- }
32
- function wgs84ToGcj02(lng, lat) {
33
- if (outOfChina(lng, lat)) return [lng, lat];
34
- let dLat = transformLat(lng - 105, lat - 35);
35
- let dLng = transformLng(lng - 105, lat - 35);
36
- const radLat = lat / 180 * PI;
37
- let magic = Math.sin(radLat);
38
- magic = 1 - EE * magic * magic;
39
- const sqrtMagic = Math.sqrt(magic);
40
- dLat = dLat * 180 / (A * (1 - EE) / (magic * sqrtMagic) * PI);
41
- dLng = dLng * 180 / (A / sqrtMagic * Math.cos(radLat) * PI);
42
- return [lng + dLng, lat + dLat];
43
- }
44
- function gcj02ToWgs84(lng, lat) {
45
- if (outOfChina(lng, lat)) return [lng, lat];
46
- let [mlng, mlat] = wgs84ToGcj02(lng, lat);
47
- let dlng = mlng - lng;
48
- let dlat = mlat - lat;
49
- [mlng, mlat] = wgs84ToGcj02(lng - dlng, lat - dlat);
50
- dlng = mlng - lng;
51
- dlat = mlat - lat;
52
- [mlng, mlat] = wgs84ToGcj02(lng - dlng, lat - dlat);
53
- dlng = mlng - lng;
54
- dlat = mlat - lat;
55
- return [lng - dlng, lat - dlat];
56
- }
57
- function isInChina(lng, lat) {
58
- return !outOfChina(lng, lat);
59
- }
60
-
61
- // src/crs/cgcs2000.ts
62
- var gridShift = null;
63
- function setCgcs2000GridShift(provider) {
64
- gridShift = provider;
65
- }
66
- function wgs84ToCgcs2000(lng, lat) {
67
- if (!gridShift) return [lng, lat];
68
- const [dLng, dLat] = gridShift.shift(lng, lat);
69
- return [lng + dLng, lat + dLat];
70
- }
71
- function cgcs2000ToWgs84(lng, lat) {
72
- if (!gridShift) return [lng, lat];
73
- const [dLng, dLat] = gridShift.shift(lng, lat);
74
- return [lng - dLng, lat - dLat];
75
- }
76
-
77
- // src/crs/transform.ts
78
- function toWgs84(crs, lng, lat) {
79
- switch (crs) {
80
- case "WGS84":
81
- return [lng, lat];
82
- case "GCJ02":
83
- return gcj02ToWgs84(lng, lat);
84
- case "CGCS2000":
85
- return cgcs2000ToWgs84(lng, lat);
86
- }
87
- }
88
- function fromWgs84(crs, lng, lat) {
89
- switch (crs) {
90
- case "WGS84":
91
- return [lng, lat];
92
- case "GCJ02":
93
- return wgs84ToGcj02(lng, lat);
94
- case "CGCS2000":
95
- return wgs84ToCgcs2000(lng, lat);
96
- }
97
- }
98
- function createTransformer(from, to) {
99
- if (from === to) {
100
- const identity = (lng, lat) => [lng, lat];
101
- return { forward: identity, inverse: identity };
102
- }
103
- const forward = (lng, lat) => {
104
- const [wLng, wLat] = toWgs84(from, lng, lat);
105
- return fromWgs84(to, wLng, wLat);
106
- };
107
- const inverse = (lng, lat) => {
108
- const [wLng, wLat] = toWgs84(to, lng, lat);
109
- return fromWgs84(from, wLng, wLat);
110
- };
111
- return { forward, inverse };
112
- }
113
- function transformPoint(lng, lat, from, to) {
114
- return createTransformer(from, to).forward(lng, lat);
115
- }
116
- function transformBounds(b, from, to) {
117
- const t = createTransformer(from, to);
118
- const xs = [];
119
- const ys = [];
120
- for (const [x, y] of [
121
- [b[0], b[1]],
122
- [b[2], b[1]],
123
- [b[0], b[3]],
124
- [b[2], b[3]]
125
- ]) {
126
- const [nx, ny] = t.forward(x, y);
127
- xs.push(nx);
128
- ys.push(ny);
129
- }
130
- return [Math.min(...xs), Math.min(...ys), Math.max(...xs), Math.max(...ys)];
131
- }
132
-
133
- // src/controls/ScaleControl.ts
134
- var EARTH_RADIUS = 6378137;
135
- function computeScaleBar(latitude, zoom, opts = {}) {
136
- const dpiScale = opts.dpiScale ?? 1;
137
- const maxWidth = opts.maxWidth ?? 100;
138
- const tileSize = opts.tileSize ?? 512;
139
- const latRad = latitude * Math.PI / 180;
140
- const metersPerPixel = Math.cos(latRad) * 2 * Math.PI * EARTH_RADIUS / (tileSize * Math.pow(2, zoom) * dpiScale);
141
- let meters = metersPerPixel * maxWidth;
142
- const pow = Math.pow(10, Math.floor(Math.log10(meters)));
143
- const base = meters / pow;
144
- const step = base >= 5 ? 5 : base >= 2 ? 2 : 1;
145
- meters = step * pow;
146
- const pixels = meters / metersPerPixel;
147
- const label = meters >= 1e3 ? `${(meters / 1e3).toLocaleString()} km` : `${Math.round(meters)} m`;
148
- return { meters, pixels, label };
149
- }
150
- var ScaleControl = class {
151
- constructor(map, options = {}) {
152
- this.onMove = (ev) => this.handleMove(ev);
153
- this.onZoom = () => this.update();
154
- this.map = map;
155
- this.opts = {
156
- showCoordinate: options.showCoordinate ?? true,
157
- maxWidth: options.maxWidth ?? 100
158
- };
159
- this.el = options.container ?? document.createElement("div");
160
- this.el.className = "caoguo-scale-control";
161
- this.el.style.cssText = "position:absolute;left:10px;bottom:24px;padding:4px 8px;background:rgba(10,15,30,.7);color:#cfe;border-radius:4px;font:12px/1.4 system-ui,sans-serif;pointer-events:none;z-index:2;";
162
- this.barEl = document.createElement("div");
163
- this.barEl.style.cssText = "height:6px;border:1px solid #cfe;border-top:none;margin-bottom:2px;";
164
- this.labelEl = document.createElement("div");
165
- if (this.opts.showCoordinate) {
166
- this.coordEl = document.createElement("div");
167
- this.coordEl.style.cssText = "opacity:.85;margin-top:2px;";
168
- this.el.append(this.barEl, this.labelEl, this.coordEl);
169
- } else {
170
- this.el.append(this.barEl, this.labelEl);
171
- }
172
- map.on("zoom", this.onZoom);
173
- map.on("move", this.onZoom);
174
- const canvas = map.getCanvas?.();
175
- canvas?.addEventListener("mousemove", this.onMove);
176
- }
177
- /** 把控件挂到地图容器(无预设容器时调用) */
178
- addTo(container) {
179
- if (!this.el.parentElement) container.appendChild(this.el);
180
- this.update();
181
- return this;
182
- }
183
- /** 计算并刷新显示 */
184
- update() {
185
- const center = this.map.getCenter();
186
- const bar = computeScaleBar(center.lat, this.map.getZoom(), { maxWidth: this.opts.maxWidth });
187
- this.barEl.style.width = `${Math.round(bar.pixels)}px`;
188
- this.labelEl.textContent = bar.label;
189
- }
190
- handleMove(ev) {
191
- if (!this.coordEl) return;
192
- const e = ev;
193
- const ll = e.lngLat;
194
- if (!ll) return;
195
- this.coordEl.textContent = `${ll.lng.toFixed(5)}, ${ll.lat.toFixed(5)}`;
196
- }
197
- /** 移除控件与事件监听 */
198
- remove() {
199
- this.map.off("zoom", this.onZoom);
200
- this.map.off("move", this.onZoom);
201
- const canvas = this.map.getCanvas?.();
202
- canvas?.removeEventListener("mousemove", this.onMove);
203
- this.el.remove();
204
- }
205
- };
206
-
207
- // src/controls/ThemeSwitcher.ts
208
- function oppositeTheme(theme) {
209
- return theme === "caoguo-dark" ? "caoguo-light" : "caoguo-dark";
210
- }
211
- function themeFromStyle(style, fallback = "caoguo-dark") {
212
- if (!style) return fallback;
213
- const name = typeof style === "string" ? style : style.name;
214
- if (name === "caoguo-dark" || name === "caoguo-light") return name;
215
- return fallback;
216
- }
217
- var ThemeSwitcher = class {
218
- constructor(map, options = {}) {
219
- this.map = map;
220
- this.current = options.initial ?? themeFromStyle(map.getStyle?.(), "caoguo-dark");
221
- this.el = options.container ?? document.createElement("div");
222
- this.el.className = "caoguo-theme-switcher";
223
- this.el.style.cssText = "position:absolute;right:10px;top:10px;z-index:3;";
224
- this.btn = document.createElement("button");
225
- this.btn.type = "button";
226
- this.applyLabel();
227
- this.btn.style.cssText = "cursor:pointer;padding:4px 10px;border:1px solid #2a3550;border-radius:6px;background:rgba(10,15,30,.7);color:#cfe;font:12px system-ui,sans-serif;";
228
- this.btn.addEventListener("click", () => this.toggle());
229
- this.el.append(this.btn);
230
- }
231
- applyLabel() {
232
- this.btn.textContent = this.current === "caoguo-dark" ? "\u{1F319} \u6697\u8272" : "\u2600 \u4EAE\u8272";
233
- }
234
- /** 当前主题 */
235
- getTheme() {
236
- return this.current;
237
- }
238
- /** 切换到指定主题(保留视图,diff 模式避免闪烁) */
239
- setTheme(theme) {
240
- if (theme === this.current) return;
241
- this.current = theme;
242
- this.applyLabel();
243
- this.map.setStyle(caoguoStyle(theme), { diff: true });
244
- }
245
- /** 在明暗之间切换 */
246
- toggle() {
247
- this.setTheme(oppositeTheme(this.current));
248
- }
249
- /** 挂到容器 */
250
- addTo(container) {
251
- if (!this.el.parentElement) container.appendChild(this.el);
252
- return this;
253
- }
254
- /** 移除 */
255
- remove() {
256
- this.btn.removeEventListener("click", () => this.toggle());
257
- this.el.remove();
258
- }
259
- };
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
-
342
- // src/shaders/glowGeometry.ts
343
- function glowPasses(passes = 4, baseWidth = 3) {
344
- if (passes < 1) passes = 1;
345
- const out = [];
346
- for (let i = 0; i < passes; i++) {
347
- const t = passes === 1 ? 1 : 1 - i / (passes - 1);
348
- out.push({
349
- width: baseWidth * (1 + (1 - t) * (passes - 1) * 1.8),
350
- opacity: 0.1 + 0.9 * t * t
351
- });
352
- }
353
- return out;
354
- }
355
- function projectSimple(lng, lat) {
356
- const x = lng / 180;
357
- const y = Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)) / Math.PI;
358
- return [x, Math.max(-1, Math.min(1, y / Math.PI))];
359
- }
360
- function buildGlowGeometry(lines, opts = {}) {
361
- const passes = glowPasses(opts.passes ?? 4, opts.baseWidth ?? 3);
362
- const stride = 6;
363
- const verts = [];
364
- const passRanges = [];
365
- const renderGroups = [];
366
- const groups = [];
367
- for (const line of lines) {
368
- const g = line.group ?? "default";
369
- if (!groups.includes(g)) groups.push(g);
370
- }
371
- for (let p = 0; p < passes.length; p++) {
372
- passes[p];
373
- const start = verts.length / stride;
374
- for (const group of groups) {
375
- const groupStart = verts.length / stride;
376
- const groupIndex = groups.indexOf(group);
377
- for (const line of lines) {
378
- if ((line.group ?? "default") !== group) continue;
379
- const pts = line.coordinates.map(([lng, lat]) => projectSimple(lng, lat));
380
- if (pts.length < 2) continue;
381
- for (let i = 0; i < pts.length - 1; i++) {
382
- const a = pts[i];
383
- const b = pts[i + 1];
384
- const dx = b[0] - a[0];
385
- const dy = b[1] - a[1];
386
- const quad = [
387
- [a[0], a[1], dx, dy, 1, groupIndex],
388
- [a[0], a[1], dx, dy, -1, groupIndex],
389
- [b[0], b[1], dx, dy, 1, groupIndex],
390
- [b[0], b[1], dx, dy, -1, groupIndex]
391
- ];
392
- const idx = [0, 1, 2, 2, 1, 3];
393
- for (const k of idx) {
394
- const v = quad[k];
395
- verts.push(v[0], v[1], v[2], v[3], v[4], v[5]);
396
- }
397
- }
398
- }
399
- const count2 = verts.length / stride - groupStart;
400
- if (count2 > 0) renderGroups.push({ passIndex: p, group, start: groupStart, count: count2 });
401
- }
402
- const count = verts.length / stride - start;
403
- passRanges.push({ start, count });
404
- }
405
- return { vertices: new Float32Array(verts), passRanges, passes, stride, groups, renderGroups };
406
- }
407
-
408
- // src/shaders/CustomLineLayer.ts
409
- var FALLBACK_COLOR = [0.6, 0.7, 0.9];
410
- var DEFAULT_COLORS = {
411
- pipe: [0.2, 0.85, 1],
412
- // 青蓝:管线
413
- road: [0.6, 0.7, 0.9],
414
- // 灰蓝:路网
415
- water: [0.25, 0.55, 0.95]
416
- // 深蓝:水系
417
- };
418
- var VERT = `
419
- attribute vec2 aPos;
420
- attribute vec2 aDir;
421
- attribute float aSide;
422
- uniform mat4 uMatrix;
423
- uniform float uWidth;
424
- uniform vec2 uResolution;
425
- void main() {
426
- vec4 clip = uMatrix * vec4(aPos, 0.0, 1.0);
427
- // \u6BB5\u65B9\u5411\u4E5F\u6295\u5F71\uFF0C\u6C42\u5C4F\u5E55\u7A7A\u95F4\u65B9\u5411
428
- vec4 clipDir = uMatrix * vec4(aPos + aDir, 0.0, 1.0);
429
- vec2 s0 = clip.xy / clip.w;
430
- vec2 s1 = clipDir.xy / clipDir.w;
431
- vec2 dir = normalize(s1 - s0 + vec2(1e-6));
432
- vec2 normal = vec2(-dir.y, dir.x);
433
- vec2 offset = normal * aSide * (uWidth / uResolution * 2.0);
434
- gl_Position = vec4(s0 + offset * clip.w, clip.z, clip.w);
435
- }
436
- `;
437
- var FRAG = `
438
- precision mediump float;
439
- uniform vec3 uColor;
440
- uniform float uOpacity;
441
- void main() {
442
- gl_FragColor = vec4(uColor, uOpacity);
443
- }
444
- `;
445
- function compile(gl, type, src) {
446
- const sh = gl.createShader(type);
447
- gl.shaderSource(sh, src);
448
- gl.compileShader(sh);
449
- if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
450
- console.error("[CustomLineLayer] shader \u7F16\u8BD1\u5931\u8D25:", gl.getShaderInfoLog(sh));
451
- }
452
- return sh;
453
- }
454
- var CustomLineLayer = class {
455
- constructor(opts) {
456
- this.type = "custom";
457
- this.renderingMode = "2d";
458
- this.id = opts.id ?? "caoguo-glow-line";
459
- this.lines = opts.lines;
460
- this.colors = { ...DEFAULT_COLORS, ...opts.colors };
461
- this.baseWidth = opts.baseWidth ?? 3;
462
- this.geometry = buildGlowGeometry(this.lines, { passes: opts.passes ?? 4, baseWidth: this.baseWidth });
463
- for (const g of this.geometry.groups) {
464
- if (!(g in this.colors)) this.colors[g] = FALLBACK_COLOR;
465
- }
466
- }
467
- onAdd(map, gl) {
468
- this.map = map;
469
- this.gl = gl;
470
- const vs = compile(gl, gl.VERTEX_SHADER, VERT);
471
- const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);
472
- const prog = gl.createProgram();
473
- gl.attachShader(prog, vs);
474
- gl.attachShader(prog, fs);
475
- gl.linkProgram(prog);
476
- if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
477
- console.error("[CustomLineLayer] program \u94FE\u63A5\u5931\u8D25:", gl.getProgramInfoLog(prog));
478
- }
479
- this.program = prog;
480
- const buf = gl.createBuffer();
481
- gl.bindBuffer(gl.ARRAY_BUFFER, buf);
482
- gl.bufferData(gl.ARRAY_BUFFER, this.geometry.vertices, gl.STATIC_DRAW);
483
- this.buffer = buf;
484
- }
485
- render(gl, matrix) {
486
- if (!this.program || !this.buffer) return;
487
- gl.useProgram(this.program);
488
- gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
489
- const stride = this.geometry.stride * 4;
490
- const aPos = gl.getAttribLocation(this.program, "aPos");
491
- const aDir = gl.getAttribLocation(this.program, "aDir");
492
- const aSide = gl.getAttribLocation(this.program, "aSide");
493
- const aGroup = gl.getAttribLocation(this.program, "aGroup");
494
- gl.enableVertexAttribArray(aPos);
495
- gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, stride, 0);
496
- gl.enableVertexAttribArray(aDir);
497
- gl.vertexAttribPointer(aDir, 2, gl.FLOAT, false, stride, 8);
498
- gl.enableVertexAttribArray(aSide);
499
- gl.vertexAttribPointer(aSide, 1, gl.FLOAT, false, stride, 16);
500
- if (aGroup >= 0) {
501
- gl.enableVertexAttribArray(aGroup);
502
- gl.vertexAttribPointer(aGroup, 1, gl.FLOAT, false, stride, 20);
503
- }
504
- const uMatrix = gl.getUniformLocation(this.program, "uMatrix");
505
- gl.uniformMatrix4fv(uMatrix, false, new Float32Array(matrix));
506
- const uWidth = gl.getUniformLocation(this.program, "uWidth");
507
- const uColor = gl.getUniformLocation(this.program, "uColor");
508
- const uOpacity = gl.getUniformLocation(this.program, "uOpacity");
509
- const uRes = gl.getUniformLocation(this.program, "uResolution");
510
- const canvas = this.map?.getCanvas();
511
- gl.uniform2f(uRes, canvas?.width ?? 1024, canvas?.height ?? 768);
512
- gl.enable(gl.BLEND);
513
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
514
- for (const rg of this.geometry.renderGroups) {
515
- const pass = this.geometry.passes[rg.passIndex];
516
- const color = this.colors[rg.group] ?? FALLBACK_COLOR;
517
- gl.uniform1f(uWidth, pass.width);
518
- gl.uniform3f(uColor, color[0], color[1], color[2]);
519
- gl.uniform1f(uOpacity, pass.opacity);
520
- gl.drawArrays(gl.TRIANGLES, rg.start, rg.count);
521
- }
522
- }
523
- /**
524
- * 动态更新线集合(高亮选中、切换数据等无需重建图层)。
525
- * 浏览器环境会刷新 GPU 缓冲;纯逻辑/测试环境仅更新几何与数据。
526
- */
527
- setLines(lines) {
528
- this.lines = lines;
529
- this.geometry = buildGlowGeometry(this.lines, {
530
- passes: this.geometry.passes.length,
531
- baseWidth: this.baseWidth
532
- });
533
- for (const g of this.geometry.groups) {
534
- if (!(g in this.colors)) this.colors[g] = FALLBACK_COLOR;
535
- }
536
- if (this.buffer && this.gl) {
537
- this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
538
- this.gl.bufferData(this.gl.ARRAY_BUFFER, this.geometry.vertices, this.gl.STATIC_DRAW);
539
- }
540
- }
541
- onRemove(_map, gl) {
542
- if (this.buffer) gl.deleteBuffer(this.buffer);
543
- if (this.program) gl.deleteProgram(this.program);
544
- this.buffer = void 0;
545
- this.program = void 0;
546
- }
547
- };
548
-
549
- // src/lod/lodController.ts
550
- function resolveLod(zoom, levels) {
551
- let best = null;
552
- for (const lv of levels) {
553
- const max = lv.maxZoom ?? Infinity;
554
- if (zoom >= lv.minZoom && zoom <= max) {
555
- if (!best || lv.minZoom > best.minZoom) best = lv;
556
- }
557
- }
558
- return best;
559
- }
560
- function suggestDensity(zoom, basePerTile = 200, tileCountFactor = 1) {
561
- const z = Math.max(0, zoom);
562
- return Math.round(basePerTile * Math.pow(2, Math.max(0, z - 8)) * tileCountFactor);
563
- }
564
- var LodController = class {
565
- constructor(map, levels, onChange) {
566
- this.current = null;
567
- this.map = map;
568
- this.levels = levels;
569
- this.onChange = onChange;
570
- this.handler = () => this.evaluate(false);
571
- map.on("zoom", this.handler);
572
- map.on("move", this.handler);
573
- }
574
- /** 立即评估当前 zoom 并(按需)触发回调 */
575
- evaluate(force = false) {
576
- const zoom = this.map.getZoom();
577
- const next = resolveLod(zoom, this.levels);
578
- if (!next) return this.current;
579
- const changed = force || next.id !== this.current?.id;
580
- if (changed || force) {
581
- this.current = next;
582
- this.onChange({ level: next, changed, zoom });
583
- }
584
- return next;
585
- }
586
- /** 当前等级 */
587
- getLevel() {
588
- return this.current;
589
- }
590
- /** 更新分级配置(如权限/数据就绪后) */
591
- setLevels(levels) {
592
- this.levels = levels;
593
- this.evaluate(false);
594
- }
595
- /** 卸载监听 */
596
- remove() {
597
- this.map.off("zoom", this.handler);
598
- this.map.off("move", this.handler);
599
- }
600
- };
601
-
602
- // src/terrain.ts
603
- var DEFAULT_TERRAIN_TILES = [
604
- "https://elevation-tiles-prod.s3.amazonaws.com/terrarium/{z}/{x}/{y}.png"
605
- ];
606
- function applyTerrain(mlMap, opts = {}) {
607
- const sourceId = opts.sourceId ?? "cg-dem";
608
- if (!mlMap.getSource(sourceId)) {
609
- mlMap.addSource(sourceId, {
610
- type: "raster-dem",
611
- tiles: opts.tiles ?? DEFAULT_TERRAIN_TILES,
612
- encoding: opts.encoding ?? "terrarium",
613
- tileSize: 256,
614
- maxzoom: opts.maxzoom ?? 15
615
- });
616
- }
617
- mlMap.setTerrain({ source: sourceId, exaggeration: opts.exaggeration ?? 1.5 });
618
- }
619
- function removeTerrain(mlMap, sourceId = "cg-dem") {
620
- mlMap.setTerrain(null);
621
- if (mlMap.getSource(sourceId)) {
622
- mlMap.removeSource(sourceId);
623
- }
624
- }
625
-
626
- // src/sourceUtils.ts
627
- function upsertSource(mlMap, id, data) {
628
- if (mlMap.getSource(id)) {
629
- if (mlMap.setData) {
630
- mlMap.setData(id, data);
631
- } else if (mlMap.addSource) {
632
- mlMap.addSource(id, data);
633
- }
634
- } else if (mlMap.addSource) {
635
- mlMap.addSource(id, data);
636
- }
637
- }
638
- function removeSourceSafe(mlMap, id) {
639
- if (mlMap.getSource(id) && mlMap.removeSource) {
640
- mlMap.removeSource(id);
641
- }
642
- }
643
- function removeSourcesSafe(mlMap, ids) {
644
- for (const id of ids) {
645
- removeSourceSafe(mlMap, id);
646
- }
647
- }
648
-
649
- // src/index.ts
650
21
  var WebGLUnavailableError = class extends Error {
651
22
  constructor(message = "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 WebGL\uFF0C\u65E0\u6CD5\u6E32\u67D3\u5730\u56FE") {
652
23
  super(message);
@@ -692,7 +63,7 @@ var Map = class {
692
63
  if (!isWebGLAvailable()) {
693
64
  throw new WebGLUnavailableError();
694
65
  }
695
- let style = osmRasterStyle();
66
+ let style = localBasemapStyle();
696
67
  if (options.style) {
697
68
  style = options.style;
698
69
  } else if (options.tianditu) {
@@ -893,6 +264,6 @@ var Map = class {
893
264
  };
894
265
  var src_default = Map;
895
266
 
896
- 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 };
267
+ export { Map, WebGLUnavailableError, src_default as default, getGlobalConfig, isWebGLAvailable, setGlobalConfig };
897
268
  //# sourceMappingURL=index.js.map
898
269
  //# sourceMappingURL=index.js.map