@caoguo/maplibre 0.0.3 → 0.0.6
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 +361 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +269 -27
- package/dist/index.d.ts +269 -27
- package/dist/index.js +353 -42
- 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 +5 -5
|
@@ -20,7 +20,7 @@ function buildTiandituSources(type, opts) {
|
|
|
20
20
|
const { base, label } = LAYER_MAP[type];
|
|
21
21
|
const tileSize = opts.tileSize ?? 256;
|
|
22
22
|
const maxzoom = opts.maxzoom ?? 18;
|
|
23
|
-
const attr = "\xA9 \u5929\u5730\u56FE GS(2023)3295\u53F7";
|
|
23
|
+
const attr = "\xA9 \u5929\u5730\u56FE GS(2023)3295\u53F7 \xB7 \u8349\u679C\u5730\u56FE";
|
|
24
24
|
return [
|
|
25
25
|
{
|
|
26
26
|
id: `tianditu-${base}`,
|
|
@@ -92,5 +92,5 @@ function addTiandituBaseMap(opts) {
|
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
export { MissingTokenError, addTiandituBaseMap, buildTiandituSources, tiandituStyle, tiandituTileUrls };
|
|
95
|
-
//# sourceMappingURL=chunk-
|
|
96
|
-
//# sourceMappingURL=chunk-
|
|
95
|
+
//# sourceMappingURL=chunk-QGVXYR2I.js.map
|
|
96
|
+
//# sourceMappingURL=chunk-QGVXYR2I.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sources/tianditu.ts","../src/sources/addTianditu.ts"],"names":[],"mappings":";AA4CA,IAAM,SAAA,GAAiF;AAAA,EACrF,MAAA,EAAQ,EAAE,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,EAAM;AAAA,EACpC,SAAA,EAAW,EAAE,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA,EAAM;AAAA,EACvC,OAAA,EAAS,EAAE,IAAA,EAAM,KAAA,EAAO,OAAO,KAAA;AACjC,CAAA;AAEA,IAAM,cAAA,GAAgE;AAAA,EACpE,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK,KAAA;AAAA,EACL,GAAA,EAAK;AACP,CAAA;AAGO,SAAS,gBAAA,CACd,OACA,IAAA,EACU;AACV,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,UAAA,IAAc,CAAC,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACtD,EAAA,MAAM,aAAa,IAAA,CAAK,IAAA,KAAS,OAAO,cAAA,CAAe,KAAK,KAAK,KAAA,GAAQ,KAAA;AACzE,EAAA,OAAO,GAAA,CAAI,GAAA;AAAA,IACT,CAAC,CAAA,KACC,CAAA,SAAA,EAAY,CAAC,CAAA,iBAAA,EAAoB,UAAU,CAAA,yDAAA,EAA4D,UAAU,CAAA,sFAAA,EAAyF,kBAAA,CAAmB,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,GAC5O;AACF;AAgBO,SAAS,oBAAA,CACd,MACA,IAAA,EACsB;AACtB,EAAA,MAAM,EAAE,IAAA,EAAM,KAAA,EAAM,GAAI,UAAU,IAAI,CAAA;AACtC,EAAA,MAAM,QAAA,GAAW,KAAK,QAAA,IAAY,GAAA;AAClC,EAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,EAAA;AAChC,EAAA,MAAM,IAAA,GAAO,
|
|
1
|
+
{"version":3,"sources":["../src/sources/tianditu.ts","../src/sources/addTianditu.ts"],"names":[],"mappings":"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","file":"chunk-QGVXYR2I.js","sourcesContent":["/**\n * 天地图(Tianditu)WMTS 底图源(F-1.2)。\n *\n * 天地图为国内权威底图,坐标系为 CGCS2000 / Web Mercator(显示尺度等价于 WGS84)。\n * token 必须由调用方在运行时注入,**绝不硬编码**;缺失时抛出明确错误。\n *\n * 文档:https://lbs.tianditu.gov.cn/server/MapService.html\n */\n\nexport type TiandituLayer =\n /** 矢量底图(含道路/注记基础) */\n | 'vec'\n /** 影像底图 */\n | 'img'\n /** 地形底图 */\n | 'ter'\n /** 矢量注记(道路/地名) */\n | 'cva'\n /** 影像注记 */\n | 'cia'\n /** 地形注记 */\n | 'cta'\n /** 矢量注记(英文) */\n | 'eva'\n /** 影像注记(英文) */\n | 'eia'\n /** 地形注记(英文) */\n | 'eta';\n\nexport type TiandituType = 'vector' | 'satellite' | 'terrain';\n\nexport interface TiandituOptions {\n /** 天地图授权 token(必填,运行时注入) */\n token: string;\n /** 语言:中文 cva/cia/cta 或英文 eva/eia/eta */\n lang?: 'zh' | 'en';\n /** 瓦片服务子域,默认 0-7 */\n subdomains?: number[];\n /** 瓦片尺寸,默认 256 */\n tileSize?: number;\n /** 最大层级,默认 18 */\n maxzoom?: number;\n}\n\nconst LAYER_MAP: Record<TiandituType, { base: TiandituLayer; label: TiandituLayer }> = {\n vector: { base: 'vec', label: 'cva' },\n satellite: { base: 'img', label: 'cia' },\n terrain: { base: 'ter', label: 'cta' },\n};\n\nconst LAYER_LABEL_EN: Partial<Record<TiandituLayer, TiandituLayer>> = {\n cva: 'eva',\n cia: 'eia',\n cta: 'eta',\n};\n\n/** 构建单张 WMTS 栅格源的 tiles URL 列表(含子域与 token) */\nexport function tiandituTileUrls(\n layer: TiandituLayer,\n opts: TiandituOptions\n): string[] {\n const sub = opts.subdomains ?? [0, 1, 2, 3, 4, 5, 6, 7];\n const labelLayer = opts.lang === 'en' ? LAYER_LABEL_EN[layer] ?? layer : layer;\n return sub.map(\n (s) =>\n `https://t${s}.tianditu.gov.cn/${labelLayer}_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=${labelLayer}&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${encodeURIComponent(opts.token)}`\n );\n}\n\nexport interface TiandituSourceSpec {\n id: string;\n source: {\n type: 'raster';\n tiles: string[];\n tileSize: number;\n maxzoom: number;\n attribution: string;\n };\n /** 是否注记层(绘制于底图之上) */\n isLabel: boolean;\n}\n\n/** 生成一组天地图源(底图 + 注记) */\nexport function buildTiandituSources(\n type: TiandituType,\n opts: TiandituOptions\n): TiandituSourceSpec[] {\n const { base, label } = LAYER_MAP[type];\n const tileSize = opts.tileSize ?? 256;\n const maxzoom = opts.maxzoom ?? 18;\n const attr = '© 天地图 GS(2023)3295号 · 草果地图';\n return [\n {\n id: `tianditu-${base}`,\n isLabel: false,\n source: {\n type: 'raster',\n tiles: tiandituTileUrls(base, opts),\n tileSize,\n maxzoom,\n attribution: attr,\n },\n },\n {\n id: `tianditu-${label}`,\n isLabel: true,\n source: {\n type: 'raster',\n tiles: tiandituTileUrls(label, opts),\n tileSize,\n maxzoom,\n attribution: attr,\n },\n },\n ];\n}\n\nexport class MissingTokenError extends Error {\n constructor() {\n super('天地图 token 缺失:调用 addTiandituBaseMap 必须传入 tianditu: { token } 选项。');\n this.name = 'MissingTokenError';\n }\n}\n","/**\n * 把天地图底图(底图 + 注记)作为源/图层添加到 MapLibre 地图实例。\n *\n * 由于天地图为栅格底图,推荐作为「无 style 背景」的地图底层:\n * 直接通过 setStyle 注入最小 style,或先 addSource + addLayer。\n * 这里提供低侵入的「注入已有 map」方式,业务可叠加自有矢量图层。\n */\n\nimport type { Map as MlMap, StyleSpecification } from 'maplibre-gl';\nimport {\n buildTiandituSources,\n MissingTokenError,\n type TiandituOptions,\n type TiandituType,\n} from './tianditu';\n\nexport interface AddTiandituOptions extends TiandituOptions {\n type?: TiandituType;\n /** 添加到指定地图实例 */\n map: MlMap;\n /** 注入为 style 的源/图层还是 addSource(默认 addSource + addLayer) */\n asStyle?: false;\n}\n\n/** 生成可直接作为 Map style 的天地图 Style JSON(含底图+注记两层) */\nexport function tiandituStyle(\n type: TiandituType,\n opts: TiandituOptions\n): StyleSpecification {\n if (!opts.token) throw new MissingTokenError();\n const sources = buildTiandituSources(type, opts);\n return {\n version: 8,\n glyphs: 'https://demotiles.maplibre.org/font/{fontstack}/{range}.pbf',\n sources: Object.fromEntries(\n sources.map((s) => [s.id, s.source])\n ) as StyleSpecification['sources'],\n layers: sources.map((s) => ({\n id: s.id,\n type: 'raster' as const,\n source: s.id,\n // 注记层置于底图之上\n ...(s.isLabel ? { minzoom: 0 } : {}),\n })),\n };\n}\n\n/** 向已存在的地图实例注入天地图底图(底图 + 注记) */\nexport function addTiandituBaseMap(opts: AddTiandituOptions): void {\n if (!opts.token) throw new MissingTokenError();\n const type = opts.type ?? 'vector';\n const sources = buildTiandituSources(type, opts);\n const map = opts.map;\n for (const s of sources) {\n if (!map.getSource(s.id)) {\n map.addSource(s.id, s.source as never);\n }\n if (!map.getLayer(s.id)) {\n map.addLayer({\n id: s.id,\n type: 'raster',\n source: s.id,\n } as never);\n }\n }\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -197,7 +197,7 @@ function buildTiandituSources(type, opts) {
|
|
|
197
197
|
const { base, label } = LAYER_MAP[type];
|
|
198
198
|
const tileSize = opts.tileSize ?? 256;
|
|
199
199
|
const maxzoom = opts.maxzoom ?? 18;
|
|
200
|
-
const attr = "\xA9 \u5929\u5730\u56FE GS(2023)3295\u53F7";
|
|
200
|
+
const attr = "\xA9 \u5929\u5730\u56FE GS(2023)3295\u53F7 \xB7 \u8349\u679C\u5730\u56FE";
|
|
201
201
|
return [
|
|
202
202
|
{
|
|
203
203
|
id: `tianditu-${base}`,
|
|
@@ -765,15 +765,96 @@ var ThemeSwitcher = class {
|
|
|
765
765
|
}
|
|
766
766
|
};
|
|
767
767
|
|
|
768
|
+
// src/controls/LegendControl.ts
|
|
769
|
+
function escapeHtml(s) {
|
|
770
|
+
return s.replace(
|
|
771
|
+
/[&<>"']/g,
|
|
772
|
+
(c) => c === "&" ? "&" : c === "<" ? "<" : c === ">" ? ">" : c === '"' ? """ : "'"
|
|
773
|
+
);
|
|
774
|
+
}
|
|
775
|
+
function renderLegendHtml(items, title) {
|
|
776
|
+
const titleHtml = title ? `<div class="cg-legend-title">${escapeHtml(title)}</div>` : "";
|
|
777
|
+
const itemsHtml = items.map((it) => {
|
|
778
|
+
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>`;
|
|
779
|
+
return `<div class="cg-legend-item">${swatch}<span>${escapeHtml(it.label)}</span></div>`;
|
|
780
|
+
}).join("");
|
|
781
|
+
return `<div class="cg-legend-body">${titleHtml}${itemsHtml}</div>`;
|
|
782
|
+
}
|
|
783
|
+
var LegendControl = class {
|
|
784
|
+
constructor(options) {
|
|
785
|
+
this.opts = { title: options.title ?? "", items: options.items };
|
|
786
|
+
this.el = options.container ?? document.createElement("div");
|
|
787
|
+
this.el.className = "caoguo-legend-control";
|
|
788
|
+
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;";
|
|
789
|
+
this.bodyEl = document.createElement("div");
|
|
790
|
+
this.el.appendChild(this.bodyEl);
|
|
791
|
+
this.render();
|
|
792
|
+
}
|
|
793
|
+
render() {
|
|
794
|
+
this.bodyEl.innerHTML = renderLegendHtml(this.opts.items, this.opts.title || void 0);
|
|
795
|
+
}
|
|
796
|
+
/** 运行时更新图例项(随图层切换重新渲染) */
|
|
797
|
+
setItems(items, title) {
|
|
798
|
+
if (title !== void 0) this.opts.title = title;
|
|
799
|
+
this.opts.items = items;
|
|
800
|
+
this.render();
|
|
801
|
+
}
|
|
802
|
+
/** 挂载到容器 */
|
|
803
|
+
addTo(container) {
|
|
804
|
+
if (!this.el.parentElement) container.appendChild(this.el);
|
|
805
|
+
return this;
|
|
806
|
+
}
|
|
807
|
+
remove() {
|
|
808
|
+
this.el.remove();
|
|
809
|
+
}
|
|
810
|
+
};
|
|
811
|
+
|
|
812
|
+
// src/controls/ExportControl.ts
|
|
813
|
+
function triggerDownload(dataUrl, filename) {
|
|
814
|
+
const a = document.createElement("a");
|
|
815
|
+
a.href = dataUrl;
|
|
816
|
+
a.download = filename.endsWith(".png") ? filename : `${filename}.png`;
|
|
817
|
+
document.body.appendChild(a);
|
|
818
|
+
a.click();
|
|
819
|
+
a.remove();
|
|
820
|
+
}
|
|
821
|
+
var ExportControl = class {
|
|
822
|
+
constructor(map, options = {}) {
|
|
823
|
+
this.onClick = () => this.export();
|
|
824
|
+
this.map = map;
|
|
825
|
+
this.filename = options.filename ?? "caoguo-map";
|
|
826
|
+
this.el = options.container ?? document.createElement("button");
|
|
827
|
+
this.el.className = "caoguo-export-control";
|
|
828
|
+
this.el.textContent = options.buttonText ?? "\u5BFC\u51FA PNG";
|
|
829
|
+
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;";
|
|
830
|
+
this.el.addEventListener("click", this.onClick);
|
|
831
|
+
}
|
|
832
|
+
/** 导出当前地图视图为 PNG 并下载 */
|
|
833
|
+
export() {
|
|
834
|
+
const canvas = this.map.getCanvas();
|
|
835
|
+
const url = canvas.toDataURL("image/png");
|
|
836
|
+
triggerDownload(url, this.filename);
|
|
837
|
+
}
|
|
838
|
+
/** 挂载到容器 */
|
|
839
|
+
addTo(container) {
|
|
840
|
+
if (!this.el.parentElement) container.appendChild(this.el);
|
|
841
|
+
return this;
|
|
842
|
+
}
|
|
843
|
+
remove() {
|
|
844
|
+
this.el.removeEventListener("click", this.onClick);
|
|
845
|
+
this.el.remove();
|
|
846
|
+
}
|
|
847
|
+
};
|
|
848
|
+
|
|
768
849
|
// src/shaders/glowGeometry.ts
|
|
769
|
-
function glowPasses(passes = 4,
|
|
850
|
+
function glowPasses(passes = 4, baseWidth = 3) {
|
|
770
851
|
if (passes < 1) passes = 1;
|
|
771
852
|
const out = [];
|
|
772
853
|
for (let i = 0; i < passes; i++) {
|
|
773
854
|
const t = passes === 1 ? 1 : 1 - i / (passes - 1);
|
|
774
855
|
out.push({
|
|
775
|
-
|
|
776
|
-
opacity:
|
|
856
|
+
width: baseWidth * (1 + (1 - t) * (passes - 1) * 1.8),
|
|
857
|
+
opacity: 0.1 + 0.9 * t * t
|
|
777
858
|
});
|
|
778
859
|
}
|
|
779
860
|
return out;
|
|
@@ -781,20 +862,58 @@ function glowPasses(passes = 4, coreOpacity = 1) {
|
|
|
781
862
|
function projectSimple(lng, lat) {
|
|
782
863
|
const x = lng / 180;
|
|
783
864
|
const y = Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360)) / Math.PI;
|
|
784
|
-
return [x, Math.max(-1, Math.min(1, y))];
|
|
865
|
+
return [x, Math.max(-1, Math.min(1, y / Math.PI))];
|
|
785
866
|
}
|
|
786
867
|
function buildGlowGeometry(lines, opts = {}) {
|
|
787
|
-
const passes = glowPasses(opts.passes ?? 4, opts.
|
|
788
|
-
|
|
789
|
-
const
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
868
|
+
const passes = glowPasses(opts.passes ?? 4, opts.baseWidth ?? 3);
|
|
869
|
+
const stride = 6;
|
|
870
|
+
const verts = [];
|
|
871
|
+
const passRanges = [];
|
|
872
|
+
const renderGroups = [];
|
|
873
|
+
const groups = [];
|
|
874
|
+
for (const line of lines) {
|
|
875
|
+
const g = line.group ?? "default";
|
|
876
|
+
if (!groups.includes(g)) groups.push(g);
|
|
877
|
+
}
|
|
878
|
+
for (let p = 0; p < passes.length; p++) {
|
|
879
|
+
passes[p];
|
|
880
|
+
const start = verts.length / stride;
|
|
881
|
+
for (const group of groups) {
|
|
882
|
+
const groupStart = verts.length / stride;
|
|
883
|
+
const groupIndex = groups.indexOf(group);
|
|
884
|
+
for (const line of lines) {
|
|
885
|
+
if ((line.group ?? "default") !== group) continue;
|
|
886
|
+
const pts = line.coordinates.map(([lng, lat]) => projectSimple(lng, lat));
|
|
887
|
+
if (pts.length < 2) continue;
|
|
888
|
+
for (let i = 0; i < pts.length - 1; i++) {
|
|
889
|
+
const a = pts[i];
|
|
890
|
+
const b = pts[i + 1];
|
|
891
|
+
const dx = b[0] - a[0];
|
|
892
|
+
const dy = b[1] - a[1];
|
|
893
|
+
const quad = [
|
|
894
|
+
[a[0], a[1], dx, dy, 1, groupIndex],
|
|
895
|
+
[a[0], a[1], dx, dy, -1, groupIndex],
|
|
896
|
+
[b[0], b[1], dx, dy, 1, groupIndex],
|
|
897
|
+
[b[0], b[1], dx, dy, -1, groupIndex]
|
|
898
|
+
];
|
|
899
|
+
const idx = [0, 1, 2, 2, 1, 3];
|
|
900
|
+
for (const k of idx) {
|
|
901
|
+
const v = quad[k];
|
|
902
|
+
verts.push(v[0], v[1], v[2], v[3], v[4], v[5]);
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
const count2 = verts.length / stride - groupStart;
|
|
907
|
+
if (count2 > 0) renderGroups.push({ passIndex: p, group, start: groupStart, count: count2 });
|
|
908
|
+
}
|
|
909
|
+
const count = verts.length / stride - start;
|
|
910
|
+
passRanges.push({ start, count });
|
|
911
|
+
}
|
|
912
|
+
return { vertices: new Float32Array(verts), passRanges, passes, stride, groups, renderGroups };
|
|
795
913
|
}
|
|
796
914
|
|
|
797
915
|
// src/shaders/CustomLineLayer.ts
|
|
916
|
+
var FALLBACK_COLOR = [0.6, 0.7, 0.9];
|
|
798
917
|
var DEFAULT_COLORS = {
|
|
799
918
|
pipe: [0.2, 0.85, 1],
|
|
800
919
|
// 青蓝:管线
|
|
@@ -805,17 +924,21 @@ var DEFAULT_COLORS = {
|
|
|
805
924
|
};
|
|
806
925
|
var VERT = `
|
|
807
926
|
attribute vec2 aPos;
|
|
808
|
-
attribute
|
|
927
|
+
attribute vec2 aDir;
|
|
928
|
+
attribute float aSide;
|
|
809
929
|
uniform mat4 uMatrix;
|
|
810
930
|
uniform float uWidth;
|
|
811
931
|
uniform vec2 uResolution;
|
|
812
932
|
void main() {
|
|
813
|
-
// \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
|
|
814
933
|
vec4 clip = uMatrix * vec4(aPos, 0.0, 1.0);
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
vec2
|
|
818
|
-
|
|
934
|
+
// \u6BB5\u65B9\u5411\u4E5F\u6295\u5F71\uFF0C\u6C42\u5C4F\u5E55\u7A7A\u95F4\u65B9\u5411
|
|
935
|
+
vec4 clipDir = uMatrix * vec4(aPos + aDir, 0.0, 1.0);
|
|
936
|
+
vec2 s0 = clip.xy / clip.w;
|
|
937
|
+
vec2 s1 = clipDir.xy / clipDir.w;
|
|
938
|
+
vec2 dir = normalize(s1 - s0 + vec2(1e-6));
|
|
939
|
+
vec2 normal = vec2(-dir.y, dir.x);
|
|
940
|
+
vec2 offset = normal * aSide * (uWidth / uResolution * 2.0);
|
|
941
|
+
gl_Position = vec4(s0 + offset * clip.w, clip.z, clip.w);
|
|
819
942
|
}
|
|
820
943
|
`;
|
|
821
944
|
var FRAG = `
|
|
@@ -830,6 +953,9 @@ function compile(gl, type, src) {
|
|
|
830
953
|
const sh = gl.createShader(type);
|
|
831
954
|
gl.shaderSource(sh, src);
|
|
832
955
|
gl.compileShader(sh);
|
|
956
|
+
if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
|
|
957
|
+
console.error("[CustomLineLayer] shader \u7F16\u8BD1\u5931\u8D25:", gl.getShaderInfoLog(sh));
|
|
958
|
+
}
|
|
833
959
|
return sh;
|
|
834
960
|
}
|
|
835
961
|
var CustomLineLayer = class {
|
|
@@ -840,40 +966,48 @@ var CustomLineLayer = class {
|
|
|
840
966
|
this.lines = opts.lines;
|
|
841
967
|
this.colors = { ...DEFAULT_COLORS, ...opts.colors };
|
|
842
968
|
this.baseWidth = opts.baseWidth ?? 3;
|
|
843
|
-
this.
|
|
844
|
-
|
|
969
|
+
this.geometry = buildGlowGeometry(this.lines, { passes: opts.passes ?? 4, baseWidth: this.baseWidth });
|
|
970
|
+
for (const g of this.geometry.groups) {
|
|
971
|
+
if (!(g in this.colors)) this.colors[g] = FALLBACK_COLOR;
|
|
972
|
+
}
|
|
845
973
|
}
|
|
846
974
|
onAdd(map, gl) {
|
|
847
975
|
this.map = map;
|
|
976
|
+
this.gl = gl;
|
|
848
977
|
const vs = compile(gl, gl.VERTEX_SHADER, VERT);
|
|
849
978
|
const fs = compile(gl, gl.FRAGMENT_SHADER, FRAG);
|
|
850
979
|
const prog = gl.createProgram();
|
|
851
980
|
gl.attachShader(prog, vs);
|
|
852
981
|
gl.attachShader(prog, fs);
|
|
853
982
|
gl.linkProgram(prog);
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
for (const line of this.geometry.lines) {
|
|
857
|
-
const pts = line.points;
|
|
858
|
-
for (let i = 0; i < pts.length - 1; i++) {
|
|
859
|
-
verts.push(pts[i][0], pts[i][1], 0, pts[i + 1][0], pts[i + 1][1], 0);
|
|
860
|
-
}
|
|
983
|
+
if (!gl.getProgramParameter(prog, gl.LINK_STATUS)) {
|
|
984
|
+
console.error("[CustomLineLayer] program \u94FE\u63A5\u5931\u8D25:", gl.getProgramInfoLog(prog));
|
|
861
985
|
}
|
|
986
|
+
this.program = prog;
|
|
862
987
|
const buf = gl.createBuffer();
|
|
863
988
|
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
|
|
864
|
-
gl.bufferData(gl.ARRAY_BUFFER,
|
|
989
|
+
gl.bufferData(gl.ARRAY_BUFFER, this.geometry.vertices, gl.STATIC_DRAW);
|
|
865
990
|
this.buffer = buf;
|
|
866
991
|
}
|
|
867
992
|
render(gl, matrix) {
|
|
868
993
|
if (!this.program || !this.buffer) return;
|
|
869
994
|
gl.useProgram(this.program);
|
|
870
995
|
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
|
|
996
|
+
const stride = this.geometry.stride * 4;
|
|
871
997
|
const aPos = gl.getAttribLocation(this.program, "aPos");
|
|
872
|
-
const
|
|
998
|
+
const aDir = gl.getAttribLocation(this.program, "aDir");
|
|
999
|
+
const aSide = gl.getAttribLocation(this.program, "aSide");
|
|
1000
|
+
const aGroup = gl.getAttribLocation(this.program, "aGroup");
|
|
873
1001
|
gl.enableVertexAttribArray(aPos);
|
|
874
|
-
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false,
|
|
875
|
-
gl.enableVertexAttribArray(
|
|
876
|
-
gl.vertexAttribPointer(
|
|
1002
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, stride, 0);
|
|
1003
|
+
gl.enableVertexAttribArray(aDir);
|
|
1004
|
+
gl.vertexAttribPointer(aDir, 2, gl.FLOAT, false, stride, 8);
|
|
1005
|
+
gl.enableVertexAttribArray(aSide);
|
|
1006
|
+
gl.vertexAttribPointer(aSide, 1, gl.FLOAT, false, stride, 16);
|
|
1007
|
+
if (aGroup >= 0) {
|
|
1008
|
+
gl.enableVertexAttribArray(aGroup);
|
|
1009
|
+
gl.vertexAttribPointer(aGroup, 1, gl.FLOAT, false, stride, 20);
|
|
1010
|
+
}
|
|
877
1011
|
const uMatrix = gl.getUniformLocation(this.program, "uMatrix");
|
|
878
1012
|
gl.uniformMatrix4fv(uMatrix, false, new Float32Array(matrix));
|
|
879
1013
|
const uWidth = gl.getUniformLocation(this.program, "uWidth");
|
|
@@ -884,12 +1018,31 @@ var CustomLineLayer = class {
|
|
|
884
1018
|
gl.uniform2f(uRes, canvas?.width ?? 1024, canvas?.height ?? 768);
|
|
885
1019
|
gl.enable(gl.BLEND);
|
|
886
1020
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
|
887
|
-
const
|
|
888
|
-
|
|
889
|
-
|
|
1021
|
+
for (const rg of this.geometry.renderGroups) {
|
|
1022
|
+
const pass = this.geometry.passes[rg.passIndex];
|
|
1023
|
+
const color = this.colors[rg.group] ?? FALLBACK_COLOR;
|
|
1024
|
+
gl.uniform1f(uWidth, pass.width);
|
|
890
1025
|
gl.uniform3f(uColor, color[0], color[1], color[2]);
|
|
891
1026
|
gl.uniform1f(uOpacity, pass.opacity);
|
|
892
|
-
gl.drawArrays(gl.
|
|
1027
|
+
gl.drawArrays(gl.TRIANGLES, rg.start, rg.count);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
/**
|
|
1031
|
+
* 动态更新线集合(高亮选中、切换数据等无需重建图层)。
|
|
1032
|
+
* 浏览器环境会刷新 GPU 缓冲;纯逻辑/测试环境仅更新几何与数据。
|
|
1033
|
+
*/
|
|
1034
|
+
setLines(lines) {
|
|
1035
|
+
this.lines = lines;
|
|
1036
|
+
this.geometry = buildGlowGeometry(this.lines, {
|
|
1037
|
+
passes: this.geometry.passes.length,
|
|
1038
|
+
baseWidth: this.baseWidth
|
|
1039
|
+
});
|
|
1040
|
+
for (const g of this.geometry.groups) {
|
|
1041
|
+
if (!(g in this.colors)) this.colors[g] = FALLBACK_COLOR;
|
|
1042
|
+
}
|
|
1043
|
+
if (this.buffer && this.gl) {
|
|
1044
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
|
|
1045
|
+
this.gl.bufferData(this.gl.ARRAY_BUFFER, this.geometry.vertices, this.gl.STATIC_DRAW);
|
|
893
1046
|
}
|
|
894
1047
|
}
|
|
895
1048
|
onRemove(_map, gl) {
|
|
@@ -953,17 +1106,119 @@ var LodController = class {
|
|
|
953
1106
|
}
|
|
954
1107
|
};
|
|
955
1108
|
|
|
1109
|
+
// src/terrain.ts
|
|
1110
|
+
var DEFAULT_TERRAIN_TILES = [
|
|
1111
|
+
"https://elevation-tiles-prod.s3.amazonaws.com/terrarium/{z}/{x}/{y}.png"
|
|
1112
|
+
];
|
|
1113
|
+
function applyTerrain(mlMap, opts = {}) {
|
|
1114
|
+
const sourceId = opts.sourceId ?? "cg-dem";
|
|
1115
|
+
if (!mlMap.getSource(sourceId)) {
|
|
1116
|
+
mlMap.addSource(sourceId, {
|
|
1117
|
+
type: "raster-dem",
|
|
1118
|
+
tiles: opts.tiles ?? DEFAULT_TERRAIN_TILES,
|
|
1119
|
+
encoding: opts.encoding ?? "terrarium",
|
|
1120
|
+
tileSize: 256,
|
|
1121
|
+
maxzoom: opts.maxzoom ?? 15
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
mlMap.setTerrain({ source: sourceId, exaggeration: opts.exaggeration ?? 1.5 });
|
|
1125
|
+
}
|
|
1126
|
+
function removeTerrain(mlMap, sourceId = "cg-dem") {
|
|
1127
|
+
mlMap.setTerrain(null);
|
|
1128
|
+
if (mlMap.getSource(sourceId)) {
|
|
1129
|
+
mlMap.removeSource(sourceId);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
// src/sourceUtils.ts
|
|
1134
|
+
function upsertSource(mlMap, id, data) {
|
|
1135
|
+
if (mlMap.getSource(id)) {
|
|
1136
|
+
if (mlMap.setData) {
|
|
1137
|
+
mlMap.setData(id, data);
|
|
1138
|
+
} else if (mlMap.addSource) {
|
|
1139
|
+
mlMap.addSource(id, data);
|
|
1140
|
+
}
|
|
1141
|
+
} else if (mlMap.addSource) {
|
|
1142
|
+
mlMap.addSource(id, data);
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
function removeSourceSafe(mlMap, id) {
|
|
1146
|
+
if (mlMap.getSource(id) && mlMap.removeSource) {
|
|
1147
|
+
mlMap.removeSource(id);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
function removeSourcesSafe(mlMap, ids) {
|
|
1151
|
+
for (const id of ids) {
|
|
1152
|
+
removeSourceSafe(mlMap, id);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
956
1156
|
// src/index.ts
|
|
1157
|
+
var WebGLUnavailableError = class extends Error {
|
|
1158
|
+
constructor(message = "\u5F53\u524D\u73AF\u5883\u4E0D\u652F\u6301 WebGL\uFF0C\u65E0\u6CD5\u6E32\u67D3\u5730\u56FE") {
|
|
1159
|
+
super(message);
|
|
1160
|
+
this.name = "WebGLUnavailableError";
|
|
1161
|
+
}
|
|
1162
|
+
};
|
|
1163
|
+
function isWebGLAvailable() {
|
|
1164
|
+
try {
|
|
1165
|
+
const canvas = document.createElement("canvas");
|
|
1166
|
+
let failed = false;
|
|
1167
|
+
const onErr = () => {
|
|
1168
|
+
failed = true;
|
|
1169
|
+
};
|
|
1170
|
+
canvas.addEventListener("webglcontextcreationerror", onErr, { once: true });
|
|
1171
|
+
const gl = canvas.getContext("webgl2") || canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
|
|
1172
|
+
canvas.removeEventListener("webglcontextcreationerror", onErr);
|
|
1173
|
+
if (failed || !gl) return false;
|
|
1174
|
+
const vendor = gl.getParameter(gl.VERSION);
|
|
1175
|
+
if (!vendor) return false;
|
|
1176
|
+
const vs = gl.createShader(gl.VERTEX_SHADER);
|
|
1177
|
+
if (!vs) return false;
|
|
1178
|
+
gl.shaderSource(vs, "attribute vec2 p; void main(){ gl_Position = vec4(p,0.0,1.0); }");
|
|
1179
|
+
gl.compileShader(vs);
|
|
1180
|
+
if (!gl.getShaderParameter(vs, gl.COMPILE_STATUS)) return false;
|
|
1181
|
+
return true;
|
|
1182
|
+
} catch {
|
|
1183
|
+
return false;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
var GLOBAL_KEY = "__caoguoMapConfig__";
|
|
1187
|
+
function setGlobalConfig(cfg) {
|
|
1188
|
+
const prev = getGlobalConfig();
|
|
1189
|
+
globalThis[GLOBAL_KEY] = { ...prev, ...cfg };
|
|
1190
|
+
}
|
|
1191
|
+
function getGlobalConfig() {
|
|
1192
|
+
return globalThis[GLOBAL_KEY] ?? {};
|
|
1193
|
+
}
|
|
957
1194
|
var Map2 = class {
|
|
958
1195
|
constructor(options) {
|
|
959
1196
|
/** 离线瓦片后端(默认浏览器 IndexedDB / Node 内存) */
|
|
960
1197
|
this._store = createDefaultStore();
|
|
961
1198
|
this._dataCRS = options.dataCRS ?? "WGS84";
|
|
1199
|
+
if (!isWebGLAvailable()) {
|
|
1200
|
+
throw new WebGLUnavailableError();
|
|
1201
|
+
}
|
|
1202
|
+
let style = osmRasterStyle();
|
|
1203
|
+
if (options.style) {
|
|
1204
|
+
style = options.style;
|
|
1205
|
+
} else if (options.tianditu) {
|
|
1206
|
+
if (!options.tianditu.token) throw new MissingTokenError();
|
|
1207
|
+
style = tiandituStyle(
|
|
1208
|
+
options.tianditu.type ?? "vector",
|
|
1209
|
+
options.tianditu
|
|
1210
|
+
);
|
|
1211
|
+
} else {
|
|
1212
|
+
const g = getGlobalConfig();
|
|
1213
|
+
if (g.tiandituToken) {
|
|
1214
|
+
style = tiandituStyle("vector", { token: g.tiandituToken });
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
962
1217
|
this._map = new maplibregl__default.default.Map({
|
|
963
1218
|
container: options.container,
|
|
964
1219
|
center: options.center ?? WUHAN_CENTER,
|
|
965
1220
|
zoom: options.zoom ?? WUHAN_ZOOM,
|
|
966
|
-
style
|
|
1221
|
+
style,
|
|
967
1222
|
pitch: options.pitch ?? 0,
|
|
968
1223
|
bearing: options.bearing ?? 0,
|
|
969
1224
|
attributionControl: { compact: true }
|
|
@@ -1032,8 +1287,23 @@ var Map2 = class {
|
|
|
1032
1287
|
else this._map.on(event, cb);
|
|
1033
1288
|
}
|
|
1034
1289
|
addSource(id, source) {
|
|
1290
|
+
if (this._map.getSource(id)) {
|
|
1291
|
+
try {
|
|
1292
|
+
this._map.removeSource(id);
|
|
1293
|
+
} catch {
|
|
1294
|
+
}
|
|
1295
|
+
}
|
|
1035
1296
|
this._map.addSource(id, source);
|
|
1036
1297
|
}
|
|
1298
|
+
/** 安全移除 source(不存在时静默忽略) */
|
|
1299
|
+
removeSource(id) {
|
|
1300
|
+
if (this._map.getSource(id)) {
|
|
1301
|
+
try {
|
|
1302
|
+
this._map.removeSource(id);
|
|
1303
|
+
} catch {
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1037
1307
|
getSource(id) {
|
|
1038
1308
|
return this._map.getSource(id);
|
|
1039
1309
|
}
|
|
@@ -1063,6 +1333,26 @@ var Map2 = class {
|
|
|
1063
1333
|
ctrl.addTo(container);
|
|
1064
1334
|
return ctrl;
|
|
1065
1335
|
}
|
|
1336
|
+
/**
|
|
1337
|
+
* 挂载图例控件(通用):渲染数据驱动的色块/线段图例,说明专题图层语义。
|
|
1338
|
+
* 返回控件实例,可调用 .setItems() 随图层切换更新、.remove() 卸载。
|
|
1339
|
+
*/
|
|
1340
|
+
addLegendControl(options) {
|
|
1341
|
+
const ctrl = new LegendControl(options);
|
|
1342
|
+
const container = this._map.getContainer();
|
|
1343
|
+
ctrl.addTo(container);
|
|
1344
|
+
return ctrl;
|
|
1345
|
+
}
|
|
1346
|
+
/**
|
|
1347
|
+
* 挂载地图导出控件(通用):点击按钮将当前视图导出为 PNG 下载。
|
|
1348
|
+
* 返回控件实例,可调用 .remove() 卸载。
|
|
1349
|
+
*/
|
|
1350
|
+
addExportControl(options = {}) {
|
|
1351
|
+
const ctrl = new ExportControl(this._map, options);
|
|
1352
|
+
const container = this._map.getContainer();
|
|
1353
|
+
ctrl.addTo(container);
|
|
1354
|
+
return ctrl;
|
|
1355
|
+
}
|
|
1066
1356
|
/**
|
|
1067
1357
|
* 挂载辉光管线 Custom Layer(T6 / F-1.3)。
|
|
1068
1358
|
* 传入 GeoJSON 线集合,叠加渲染管线/路网/水系辉光效果。
|
|
@@ -1071,7 +1361,10 @@ var Map2 = class {
|
|
|
1071
1361
|
addGlowLayer(opts) {
|
|
1072
1362
|
const layer = new CustomLineLayer(opts);
|
|
1073
1363
|
this._map.addLayer(layer);
|
|
1074
|
-
return
|
|
1364
|
+
return {
|
|
1365
|
+
id: layer.id,
|
|
1366
|
+
setLines: (lines) => layer.setLines(lines)
|
|
1367
|
+
};
|
|
1075
1368
|
}
|
|
1076
1369
|
/**
|
|
1077
1370
|
* 挂载 LOD 控制器(T7 / F-1.7)。
|
|
@@ -1083,6 +1376,24 @@ var Map2 = class {
|
|
|
1083
1376
|
ctrl.evaluate(true);
|
|
1084
1377
|
return ctrl;
|
|
1085
1378
|
}
|
|
1379
|
+
/**
|
|
1380
|
+
* 启用 3D 地形渲染(F-1.5)。
|
|
1381
|
+
*
|
|
1382
|
+
* 注入 raster-dem 高程源并调用 maplibre-gl 原生 `setTerrain`,使地图呈现地形起伏。
|
|
1383
|
+
* DEM 瓦片默认使用公共 Terrarium 源(elevation-tiles-prod,Terrain-RGB 编码,支持 CORS),
|
|
1384
|
+
* 可在 opts.tiles 覆盖为私有瓦片服务(如 MinIO / 本地 MBTiles 服务)。
|
|
1385
|
+
*
|
|
1386
|
+
* @param opts.exaggeration 地形夸张系数(默认 1.5)
|
|
1387
|
+
* @param opts.tiles DEM 瓦片模板,{z}/{x}/{y} 占位
|
|
1388
|
+
* @param opts.encoding 'terrarium'(默认,Mapzen)| 'mapbox'
|
|
1389
|
+
*/
|
|
1390
|
+
enableTerrain(opts = {}) {
|
|
1391
|
+
applyTerrain(this._map, opts);
|
|
1392
|
+
}
|
|
1393
|
+
/** 关闭 3D 地形渲染(F-1.5),并移除 DEM 源 */
|
|
1394
|
+
disableTerrain(sourceId = "cg-dem") {
|
|
1395
|
+
removeTerrain(this._map, sourceId);
|
|
1396
|
+
}
|
|
1086
1397
|
get instance() {
|
|
1087
1398
|
return this._map;
|
|
1088
1399
|
}
|
|
@@ -1096,7 +1407,9 @@ Object.defineProperty(exports, "maplibregl", {
|
|
|
1096
1407
|
exports.CACHEABLE_HOSTS = CACHEABLE_HOSTS;
|
|
1097
1408
|
exports.CACHE_NAME = CACHE_NAME;
|
|
1098
1409
|
exports.CustomLineLayer = CustomLineLayer;
|
|
1410
|
+
exports.ExportControl = ExportControl;
|
|
1099
1411
|
exports.IdbTileStore = IdbTileStore;
|
|
1412
|
+
exports.LegendControl = LegendControl;
|
|
1100
1413
|
exports.LodController = LodController;
|
|
1101
1414
|
exports.MSG_AIRGAP = MSG_AIRGAP;
|
|
1102
1415
|
exports.Map = Map2;
|
|
@@ -1108,6 +1421,7 @@ exports.ScaleControl = ScaleControl;
|
|
|
1108
1421
|
exports.ThemeSwitcher = ThemeSwitcher;
|
|
1109
1422
|
exports.WUHAN_CENTER = WUHAN_CENTER;
|
|
1110
1423
|
exports.WUHAN_ZOOM = WUHAN_ZOOM;
|
|
1424
|
+
exports.WebGLUnavailableError = WebGLUnavailableError;
|
|
1111
1425
|
exports.addTiandituBaseMap = addTiandituBaseMap;
|
|
1112
1426
|
exports.buildGlowGeometry = buildGlowGeometry;
|
|
1113
1427
|
exports.buildTiandituSources = buildTiandituSources;
|
|
@@ -1120,9 +1434,11 @@ exports.createTransformer = createTransformer;
|
|
|
1120
1434
|
exports.default = src_default;
|
|
1121
1435
|
exports.fromWgs84 = fromWgs84;
|
|
1122
1436
|
exports.gcj02ToWgs84 = gcj02ToWgs84;
|
|
1437
|
+
exports.getGlobalConfig = getGlobalConfig;
|
|
1123
1438
|
exports.glowPasses = glowPasses;
|
|
1124
1439
|
exports.installServiceWorker = installServiceWorker;
|
|
1125
1440
|
exports.isInChina = isInChina;
|
|
1441
|
+
exports.isWebGLAvailable = isWebGLAvailable;
|
|
1126
1442
|
exports.offlineGeoJSONSource = offlineGeoJSONSource;
|
|
1127
1443
|
exports.offlineSourceTiles = offlineSourceTiles;
|
|
1128
1444
|
exports.offlineTileUrl = offlineTileUrl;
|
|
@@ -1133,12 +1449,16 @@ exports.parseOfflineUrl = parseOfflineUrl;
|
|
|
1133
1449
|
exports.projectSimple = projectSimple;
|
|
1134
1450
|
exports.registerOfflineProtocol = registerOfflineProtocol;
|
|
1135
1451
|
exports.registerOfflineServiceWorker = registerOfflineServiceWorker;
|
|
1452
|
+
exports.removeSourceSafe = removeSourceSafe;
|
|
1453
|
+
exports.removeSourcesSafe = removeSourcesSafe;
|
|
1454
|
+
exports.renderLegendHtml = renderLegendHtml;
|
|
1136
1455
|
exports.resolveCacheKey = resolveCacheKey;
|
|
1137
1456
|
exports.resolveFromStore = resolveFromStore;
|
|
1138
1457
|
exports.resolveLod = resolveLod;
|
|
1139
1458
|
exports.resolveResponse = resolveResponse;
|
|
1140
1459
|
exports.setAirgap = setAirgap;
|
|
1141
1460
|
exports.setCgcs2000GridShift = setCgcs2000GridShift;
|
|
1461
|
+
exports.setGlobalConfig = setGlobalConfig;
|
|
1142
1462
|
exports.shouldCache = shouldCache;
|
|
1143
1463
|
exports.suggestDensity = suggestDensity;
|
|
1144
1464
|
exports.themeFromStyle = themeFromStyle;
|
|
@@ -1148,6 +1468,8 @@ exports.tileKey = tileKey;
|
|
|
1148
1468
|
exports.toWgs84 = toWgs84;
|
|
1149
1469
|
exports.transformBounds = transformBounds;
|
|
1150
1470
|
exports.transformPoint = transformPoint;
|
|
1471
|
+
exports.triggerDownload = triggerDownload;
|
|
1472
|
+
exports.upsertSource = upsertSource;
|
|
1151
1473
|
exports.wgs84ToCgcs2000 = wgs84ToCgcs2000;
|
|
1152
1474
|
exports.wgs84ToGcj02 = wgs84ToGcj02;
|
|
1153
1475
|
//# sourceMappingURL=index.cjs.map
|