@mapless/core 1.0.20 → 1.0.22

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
@@ -1072,9 +1072,68 @@ const sdfs = {
1072
1072
  const icons_icons = icons;
1073
1073
  class Singleton {
1074
1074
  customIcons = null;
1075
+ loadingPromises = new Map();
1075
1076
  getIconUrl(name) {
1076
1077
  return this.customIcons?.[name] || null;
1077
1078
  }
1079
+ handleMissingImage = (map, id)=>{
1080
+ if (this.loadingPromises.has(id)) return;
1081
+ const url = this.customIcons?.[id];
1082
+ if (url) return void this.loadMissingIcon(map, id, url);
1083
+ const parsedIcon = this.parseDynamicIconName(id);
1084
+ if (parsedIcon) this.loadDynamicIcon(map, id, parsedIcon.baseName, parsedIcon.state);
1085
+ };
1086
+ parseDynamicIconName(id) {
1087
+ const match = id.match(/^(.+)_(normal|busy|fault|offline|disable|idle)$/);
1088
+ if (match) return {
1089
+ baseName: match[1],
1090
+ state: match[2]
1091
+ };
1092
+ return null;
1093
+ }
1094
+ async loadMissingIcon(map, name, url) {
1095
+ if (map.hasImage(name)) return;
1096
+ const promise = this.loadCustomIcon(map, name, url, false);
1097
+ this.loadingPromises.set(name, promise);
1098
+ try {
1099
+ await promise;
1100
+ } finally{
1101
+ this.loadingPromises.delete(name);
1102
+ }
1103
+ }
1104
+ async loadDynamicIcon(map, fullId, baseName, state) {
1105
+ if (map.hasImage(fullId)) return;
1106
+ const baseUrl = this.customIcons?.[baseName];
1107
+ if (!baseUrl) return;
1108
+ const promise = new Promise((resolve)=>{
1109
+ map.loadImage(baseUrl, async (err, image)=>{
1110
+ if (err || !image) return void resolve();
1111
+ const stateColors = {
1112
+ normal: COLOR_PRESETS.normal || '#4CAF50',
1113
+ busy: COLOR_PRESETS.busy || '#FF9800',
1114
+ fault: COLOR_PRESETS.fault || '#F44336',
1115
+ offline: COLOR_PRESETS.offline || '#9E9E9E',
1116
+ disable: COLOR_PRESETS.disable || '#212121',
1117
+ idle: COLOR_PRESETS.idle || '#2196F3'
1118
+ };
1119
+ const color = stateColors[state] || stateColors.normal;
1120
+ try {
1121
+ const coloredIcons = await addColoredIcons(image, {
1122
+ [state]: color
1123
+ }, 0.8, null);
1124
+ const coloredImage = coloredIcons[state];
1125
+ if (coloredImage && !map.hasImage(fullId)) map.addImage(fullId, coloredImage);
1126
+ } catch {}
1127
+ resolve();
1128
+ });
1129
+ });
1130
+ this.loadingPromises.set(fullId, promise);
1131
+ try {
1132
+ await promise;
1133
+ } finally{
1134
+ this.loadingPromises.delete(fullId);
1135
+ }
1136
+ }
1078
1137
  async loadDefaultIcons(map) {
1079
1138
  if (!map) return;
1080
1139
  if (null !== this.customIcons) {
@@ -1097,16 +1156,20 @@ class Singleton {
1097
1156
  if (!map) return;
1098
1157
  if (map.hasImage(name)) map.removeImage(name);
1099
1158
  map?.loadImage(url, async (err, image)=>{
1100
- if (!err && image && this.customIcons) {
1101
- if (map?.hasImage(name) === false) map?.addImage(name, image);
1102
- this.customIcons[name] = url;
1103
- if (genColoredImg) {
1104
- const coloredIcons = await addColoredIcons(image, COLOR_PRESETS, 0.8, type);
1105
- Object.entries(coloredIcons).forEach(([colorName, coloredImage])=>{
1106
- if (colorName.startsWith('dataurl_') && this.customIcons) this.customIcons[`${name}_${colorName.replace('dataurl_', '')}`] = coloredImage;
1107
- else map?.addImage(`${name}_${colorName}`, coloredImage);
1108
- });
1109
- }
1159
+ if (err) {
1160
+ console.warn(`[Mapless] Failed to load icon "${name}" from ${url}:`, err);
1161
+ resolve();
1162
+ return;
1163
+ }
1164
+ if (!image || !this.customIcons) return void resolve();
1165
+ if (map?.hasImage(name) === false) map?.addImage(name, image);
1166
+ this.customIcons[name] = url;
1167
+ if (genColoredImg) {
1168
+ const coloredIcons = await addColoredIcons(image, COLOR_PRESETS, 0.8, type);
1169
+ Object.entries(coloredIcons).forEach(([colorName, coloredImage])=>{
1170
+ if (colorName.startsWith('dataurl_') && this.customIcons) this.customIcons[`${name}_${colorName.replace('dataurl_', '')}`] = coloredImage;
1171
+ else map?.addImage(`${name}_${colorName}`, coloredImage);
1172
+ });
1110
1173
  }
1111
1174
  resolve();
1112
1175
  });
@@ -11307,6 +11370,9 @@ class Mapless extends Base {
11307
11370
  reqHandler.setupMapboxInterceptor(this.map);
11308
11371
  this.map.on('zoom', this.mapZoomHandler);
11309
11372
  this.map.on('load', this.initCtrls);
11373
+ this.map.on('styleimagemissing', (e)=>{
11374
+ if (this.map) icons_Singleton.handleMissingImage(this.map, e.id);
11375
+ });
11310
11376
  Promise.resolve().then(()=>{
11311
11377
  this.map && this.onInit?.(this.map);
11312
11378
  });
@@ -11466,9 +11532,12 @@ class Mapless extends Base {
11466
11532
  const mana = manager;
11467
11533
  if ('function' == typeof mana.onStyleChanged) mana.onStyleChanged?.(style);
11468
11534
  });
11469
- this.map.once('style.load', async ()=>{
11470
- await icons_Singleton.loadDefaultIcons(this.map);
11471
- this.toggleMode(this._mapMode);
11535
+ await new Promise((resolve)=>{
11536
+ this.map?.once('style.load', async ()=>{
11537
+ await icons_Singleton.loadDefaultIcons(this.map);
11538
+ this.toggleMode(this._mapMode);
11539
+ resolve();
11540
+ });
11472
11541
  });
11473
11542
  }
11474
11543
  keepSpecialLayers = (prefix = 'dzmap-')=>{
@@ -1 +1 @@
1
- {"version":3,"file":"Base.d.ts","sourceRoot":"","sources":["../../../src/Mapless/Base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Base.d.ts","sourceRoot":"","sources":["../../../src/Mapless/Base.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,24 @@
1
1
  declare class Singleton {
2
2
  private customIcons;
3
+ private loadingPromises;
3
4
  getIconUrl(name: string): string | null;
5
+ /**
6
+ * 处理 styleimagemissing 事件,动态加载缺失的图标
7
+ * 作为兜底机制,防止因竞态条件导致的图标缺失警告
8
+ */
9
+ handleMissingImage: (map: mapboxgl.Map, id: string) => void;
10
+ /**
11
+ * 解析动态图标名称,如 "fixedRect_normal" -> { baseName: "fixedRect", state: "normal" }
12
+ */
13
+ private parseDynamicIconName;
14
+ /**
15
+ * 加载缺失的基础图标
16
+ */
17
+ private loadMissingIcon;
18
+ /**
19
+ * 动态生成带状态的图标(如 fixedRect_normal)
20
+ */
21
+ private loadDynamicIcon;
4
22
  loadDefaultIcons(map: mapboxgl.Map | null): Promise<void>;
5
23
  loadCustomIcon(map: mapboxgl.Map, name: string, url: string, genColoredImg?: boolean, type?: 'circle' | 'roundRect' | 'circle_dark' | 'roundRect_dark' | null): Promise<void>;
6
24
  loadSdf(map: mapboxgl.Map, name: string, url: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"Singleton.d.ts","sourceRoot":"","sources":["../../../../src/Mapless/icons/Singleton.ts"],"names":[],"mappings":"AAGA,cAAM,SAAS;IACb,OAAO,CAAC,WAAW,CAAuC;IAE1D,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIjC,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,GAAG,IAAI;IA4CzC,cAAc,CAClB,GAAG,EAAE,QAAQ,CAAC,GAAG,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,aAAa,UAAO,EACpB,IAAI,GACA,QAAQ,GACR,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,IAAW,GACd,OAAO,CAAC,IAAI,CAAC;IA4CV,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3E;;AAED,wBAA+B"}
1
+ {"version":3,"file":"Singleton.d.ts","sourceRoot":"","sources":["../../../../src/Mapless/icons/Singleton.ts"],"names":[],"mappings":"AAGA,cAAM,SAAS;IACb,OAAO,CAAC,WAAW,CAAuC;IAC1D,OAAO,CAAC,eAAe,CAAyC;IAEhE,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIvC;;;OAGG;IACH,kBAAkB,GAAI,KAAK,QAAQ,CAAC,GAAG,EAAE,IAAI,MAAM,UAkBjD;IAEF;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAS5B;;OAEG;YACW,eAAe;IAY7B;;OAEG;YACW,eAAe;IAkDvB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,GAAG,IAAI;IA4CzC,cAAc,CAClB,GAAG,EAAE,QAAQ,CAAC,GAAG,EACjB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,aAAa,UAAO,EACpB,IAAI,GACA,QAAQ,GACR,WAAW,GACX,aAAa,GACb,gBAAgB,GAChB,IAAW,GACd,OAAO,CAAC,IAAI,CAAC;IAoDV,OAAO,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAiB3E;;AAED,wBAA+B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mapless/core",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "type": "module",
5
5
  "description": "Mapbox wrapper library without React dependencies",
6
6
  "source": "src/index.ts",