@movk/maplibre 1.0.0 → 1.2.0

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 (202) hide show
  1. package/README.en.md +2 -2
  2. package/README.md +2 -2
  3. package/dist/module.d.mts +12 -3
  4. package/dist/module.d.ts +12 -3
  5. package/dist/module.json +1 -1
  6. package/dist/module.mjs +26 -11
  7. package/dist/runtime/components/CustomLayer.d.vue.ts +1 -1
  8. package/dist/runtime/components/CustomLayer.vue +18 -4
  9. package/dist/runtime/components/CustomLayer.vue.d.ts +1 -1
  10. package/dist/runtime/components/Layer.d.vue.ts +4 -4
  11. package/dist/runtime/components/Layer.vue +43 -18
  12. package/dist/runtime/components/Layer.vue.d.ts +4 -4
  13. package/dist/runtime/components/LayerGroup.d.vue.ts +23 -10
  14. package/dist/runtime/components/LayerGroup.vue +44 -4
  15. package/dist/runtime/components/LayerGroup.vue.d.ts +23 -10
  16. package/dist/runtime/components/LottieMarker.d.vue.ts +3 -3
  17. package/dist/runtime/components/LottieMarker.vue +6 -2
  18. package/dist/runtime/components/LottieMarker.vue.d.ts +3 -3
  19. package/dist/runtime/components/Map.d.vue.ts +2 -1
  20. package/dist/runtime/components/Map.vue +2 -6
  21. package/dist/runtime/components/Map.vue.d.ts +2 -1
  22. package/dist/runtime/components/Marker.d.vue.ts +2 -1
  23. package/dist/runtime/components/Marker.vue +33 -9
  24. package/dist/runtime/components/Marker.vue.d.ts +2 -1
  25. package/dist/runtime/components/Popup.d.vue.ts +1 -1
  26. package/dist/runtime/components/Popup.vue +23 -4
  27. package/dist/runtime/components/Popup.vue.d.ts +1 -1
  28. package/dist/runtime/components/Source.d.vue.ts +2 -2
  29. package/dist/runtime/components/Source.vue +3 -15
  30. package/dist/runtime/components/Source.vue.d.ts +2 -2
  31. package/dist/runtime/components/Tooltip.d.vue.ts +2 -2
  32. package/dist/runtime/components/Tooltip.vue +47 -19
  33. package/dist/runtime/components/Tooltip.vue.d.ts +2 -2
  34. package/dist/runtime/components/buffers/BufferCircle.d.vue.ts +1 -1
  35. package/dist/runtime/components/buffers/BufferCircle.vue.d.ts +1 -1
  36. package/dist/runtime/components/buffers/BufferEllipse.d.vue.ts +1 -1
  37. package/dist/runtime/components/buffers/BufferEllipse.vue.d.ts +1 -1
  38. package/dist/runtime/components/buffers/BufferLine.d.vue.ts +1 -1
  39. package/dist/runtime/components/buffers/BufferLine.vue.d.ts +1 -1
  40. package/dist/runtime/components/buffers/BufferPolygon.d.vue.ts +1 -1
  41. package/dist/runtime/components/buffers/BufferPolygon.vue.d.ts +1 -1
  42. package/dist/runtime/components/buffers/BufferSector.d.vue.ts +1 -1
  43. package/dist/runtime/components/buffers/BufferSector.vue.d.ts +1 -1
  44. package/dist/runtime/components/controls/BasemapControl.d.vue.ts +35 -0
  45. package/dist/runtime/components/controls/BasemapControl.vue +60 -0
  46. package/dist/runtime/components/controls/BasemapControl.vue.d.ts +35 -0
  47. package/dist/runtime/components/controls/Control.d.vue.ts +51 -0
  48. package/dist/runtime/components/controls/Control.vue +95 -0
  49. package/dist/runtime/components/controls/Control.vue.d.ts +51 -0
  50. package/dist/runtime/components/controls/GlobeControl.d.vue.ts +18 -0
  51. package/dist/runtime/components/controls/GlobeControl.vue +15 -0
  52. package/dist/runtime/components/controls/GlobeControl.vue.d.ts +18 -0
  53. package/dist/runtime/components/controls/LayerControl.d.vue.ts +44 -0
  54. package/dist/runtime/components/controls/LayerControl.vue +63 -0
  55. package/dist/runtime/components/controls/LayerControl.vue.d.ts +44 -0
  56. package/dist/runtime/components/controls/Legend.d.vue.ts +47 -0
  57. package/dist/runtime/components/controls/Legend.vue +69 -0
  58. package/dist/runtime/components/controls/Legend.vue.d.ts +47 -0
  59. package/dist/runtime/components/controls/Minimap.d.vue.ts +45 -0
  60. package/dist/runtime/components/controls/Minimap.vue +31 -0
  61. package/dist/runtime/components/controls/Minimap.vue.d.ts +45 -0
  62. package/dist/runtime/components/effects/AnimatedImage.d.vue.ts +1 -1
  63. package/dist/runtime/components/effects/AnimatedImage.vue +9 -6
  64. package/dist/runtime/components/effects/AnimatedImage.vue.d.ts +1 -1
  65. package/dist/runtime/components/effects/DiffusionCircle.d.vue.ts +1 -1
  66. package/dist/runtime/components/effects/DiffusionCircle.vue.d.ts +1 -1
  67. package/dist/runtime/components/effects/FlowBuilding.d.vue.ts +1 -1
  68. package/dist/runtime/components/effects/FlowBuilding.vue.d.ts +1 -1
  69. package/dist/runtime/components/effects/GlowCircle.d.vue.ts +1 -1
  70. package/dist/runtime/components/effects/GlowCircle.vue.d.ts +1 -1
  71. package/dist/runtime/components/effects/GradientBuilding.d.vue.ts +1 -1
  72. package/dist/runtime/components/effects/GradientBuilding.vue.d.ts +1 -1
  73. package/dist/runtime/components/effects/Migration.d.vue.ts +1 -1
  74. package/dist/runtime/components/effects/Migration.vue.d.ts +1 -1
  75. package/dist/runtime/components/effects/Radar.d.vue.ts +1 -1
  76. package/dist/runtime/components/effects/Radar.vue.d.ts +1 -1
  77. package/dist/runtime/components/effects/SpriteImage.d.vue.ts +1 -1
  78. package/dist/runtime/components/effects/SpriteImage.vue +40 -24
  79. package/dist/runtime/components/effects/SpriteImage.vue.d.ts +1 -1
  80. package/dist/runtime/components/effects/TextureBuilding.d.vue.ts +1 -1
  81. package/dist/runtime/components/effects/TextureBuilding.vue +1 -1
  82. package/dist/runtime/components/effects/TextureBuilding.vue.d.ts +1 -1
  83. package/dist/runtime/components/effects/Trail.d.vue.ts +1 -1
  84. package/dist/runtime/components/effects/Trail.vue.d.ts +1 -1
  85. package/dist/runtime/components/effects/WaveCircle.d.vue.ts +1 -1
  86. package/dist/runtime/components/effects/WaveCircle.vue.d.ts +1 -1
  87. package/dist/runtime/components/effects/WindowBuilding.d.vue.ts +1 -1
  88. package/dist/runtime/components/effects/WindowBuilding.vue.d.ts +1 -1
  89. package/dist/runtime/components/environment/Projection.d.vue.ts +28 -0
  90. package/dist/runtime/components/environment/Projection.vue +27 -0
  91. package/dist/runtime/components/environment/Projection.vue.d.ts +28 -0
  92. package/dist/runtime/components/environment/Temperature.d.vue.ts +1 -1
  93. package/dist/runtime/components/environment/Temperature.vue.d.ts +1 -1
  94. package/dist/runtime/components/environment/Terrain.d.vue.ts +1 -1
  95. package/dist/runtime/components/environment/Terrain.vue +5 -0
  96. package/dist/runtime/components/environment/Terrain.vue.d.ts +1 -1
  97. package/dist/runtime/components/extensions/DrawControl.vue +23 -19
  98. package/dist/runtime/components/extensions/Swipe.d.vue.ts +48 -0
  99. package/dist/runtime/components/extensions/Swipe.vue +141 -0
  100. package/dist/runtime/components/extensions/Swipe.vue.d.ts +48 -0
  101. package/dist/runtime/components/layers/BuildingLayer.d.vue.ts +1 -1
  102. package/dist/runtime/components/layers/BuildingLayer.vue.d.ts +1 -1
  103. package/dist/runtime/components/layers/ClusterLayer.d.vue.ts +1 -1
  104. package/dist/runtime/components/layers/ClusterLayer.vue.d.ts +1 -1
  105. package/dist/runtime/components/layers/ContourLayer.d.vue.ts +59 -0
  106. package/dist/runtime/components/layers/ContourLayer.vue +84 -0
  107. package/dist/runtime/components/layers/ContourLayer.vue.d.ts +59 -0
  108. package/dist/runtime/components/layers/GraticuleLayer.d.vue.ts +31 -0
  109. package/dist/runtime/components/layers/GraticuleLayer.vue +88 -0
  110. package/dist/runtime/components/layers/GraticuleLayer.vue.d.ts +31 -0
  111. package/dist/runtime/components/layers/ImageLayer.d.vue.ts +1 -1
  112. package/dist/runtime/components/layers/ImageLayer.vue.d.ts +1 -1
  113. package/dist/runtime/components/layers/MaskLayer.d.vue.ts +44 -0
  114. package/dist/runtime/components/layers/MaskLayer.vue +32 -0
  115. package/dist/runtime/components/layers/MaskLayer.vue.d.ts +44 -0
  116. package/dist/runtime/components/layers/RasterLayer.d.vue.ts +5 -3
  117. package/dist/runtime/components/layers/RasterLayer.vue +9 -2
  118. package/dist/runtime/components/layers/RasterLayer.vue.d.ts +5 -3
  119. package/dist/runtime/components/layers/VideoLayer.d.vue.ts +1 -1
  120. package/dist/runtime/components/layers/VideoLayer.vue.d.ts +1 -1
  121. package/dist/runtime/composables/useFeatureState.js +27 -5
  122. package/dist/runtime/composables/useFrameIcon.d.ts +4 -3
  123. package/dist/runtime/composables/useFrameIcon.js +18 -8
  124. package/dist/runtime/composables/useLayerTree.d.ts +11 -0
  125. package/dist/runtime/composables/useLayerTree.js +12 -0
  126. package/dist/runtime/composables/useMapAnimation.d.ts +4 -2
  127. package/dist/runtime/composables/useMapAnimation.js +5 -4
  128. package/dist/runtime/composables/useMapExport.js +2 -5
  129. package/dist/runtime/composables/useMapSync.d.ts +16 -0
  130. package/dist/runtime/composables/useMapSync.js +42 -0
  131. package/dist/runtime/composables/useMaplibreCamera.d.ts +1 -1
  132. package/dist/runtime/composables/useMaplibreCamera.js +1 -1
  133. package/dist/runtime/composables/useMaplibreImage.d.ts +3 -3
  134. package/dist/runtime/composables/useMaplibreImage.js +26 -5
  135. package/dist/runtime/domains/map/config.js +2 -3
  136. package/dist/runtime/domains/map/context.js +15 -0
  137. package/dist/runtime/domains/map/control.d.ts +1 -1
  138. package/dist/runtime/domains/map/control.js +1 -1
  139. package/dist/runtime/domains/map/draw-modes.d.ts +9 -0
  140. package/dist/runtime/domains/map/draw-modes.js +53 -0
  141. package/dist/runtime/domains/map/draw-registry.d.ts +2 -3
  142. package/dist/runtime/domains/map/draw-registry.js +6 -9
  143. package/dist/runtime/domains/map/draw-theme.d.ts +12 -0
  144. package/dist/runtime/domains/map/draw-toolbar.js +11 -10
  145. package/dist/runtime/domains/map/layer-group.d.ts +15 -4
  146. package/dist/runtime/domains/map/layer-tree.d.ts +3 -0
  147. package/dist/runtime/domains/map/layer-tree.js +10 -0
  148. package/dist/runtime/domains/map/minimap.d.ts +18 -0
  149. package/dist/runtime/domains/map/minimap.js +86 -0
  150. package/dist/runtime/domains/map/registry.js +4 -3
  151. package/dist/runtime/domains/map/style-layers.d.ts +7 -0
  152. package/dist/runtime/domains/map/style-layers.js +54 -0
  153. package/dist/runtime/domains/map/style.d.ts +3 -0
  154. package/dist/runtime/domains/map/style.js +5 -0
  155. package/dist/runtime/domains/map/swipe.d.ts +9 -0
  156. package/dist/runtime/domains/map/swipe.js +62 -0
  157. package/dist/runtime/index.css +1 -1
  158. package/dist/runtime/types/draw.d.ts +34 -1
  159. package/dist/runtime/types/index.d.ts +1 -0
  160. package/dist/runtime/types/layer.d.ts +40 -0
  161. package/dist/runtime/types/layer.js +0 -0
  162. package/dist/runtime/types/map.d.ts +6 -0
  163. package/dist/runtime/utils/cog.d.ts +2 -0
  164. package/dist/runtime/utils/cog.js +9 -0
  165. package/dist/runtime/utils/effects.js +2 -1
  166. package/dist/runtime/utils/events.d.ts +6 -0
  167. package/dist/runtime/utils/events.js +25 -0
  168. package/dist/runtime/utils/frame-icon.d.ts +2 -5
  169. package/dist/runtime/utils/frame-icon.js +10 -4
  170. package/dist/runtime/utils/graticule.d.ts +19 -0
  171. package/dist/runtime/utils/graticule.js +62 -0
  172. package/dist/runtime/utils/layer-opacity.d.ts +7 -0
  173. package/dist/runtime/utils/layer-opacity.js +59 -0
  174. package/dist/runtime/utils/layer.js +2 -1
  175. package/dist/runtime/utils/legend.d.ts +9 -0
  176. package/dist/runtime/utils/legend.js +52 -0
  177. package/dist/runtime/utils/marker.d.ts +11 -0
  178. package/dist/runtime/utils/marker.js +28 -0
  179. package/dist/runtime/utils/mask.d.ts +8 -0
  180. package/dist/runtime/utils/mask.js +33 -0
  181. package/dist/runtime/utils/minimap.d.ts +6 -0
  182. package/dist/runtime/utils/minimap.js +15 -0
  183. package/dist/runtime/utils/pmtiles.d.ts +3 -0
  184. package/dist/runtime/utils/pmtiles.js +10 -0
  185. package/dist/runtime/utils/source.d.ts +7 -0
  186. package/dist/runtime/utils/source.js +35 -0
  187. package/dist/runtime/utils/swipe.d.ts +32 -0
  188. package/dist/runtime/utils/swipe.js +18 -0
  189. package/dist/runtime/utils/tianditu.d.ts +10 -1
  190. package/dist/runtime/utils/tianditu.js +11 -0
  191. package/dist/runtime/utils/zzts-tile.d.ts +54 -0
  192. package/dist/runtime/utils/zzts-tile.js +85 -0
  193. package/dist/runtime/utils/zzts.d.ts +14 -0
  194. package/dist/runtime/utils/zzts.js +72 -0
  195. package/dist/unplugin.d.mts +1 -1
  196. package/dist/unplugin.d.ts +1 -1
  197. package/dist/unplugin.mjs +1 -7
  198. package/package.json +29 -21
  199. package/dist/runtime/draw-modes/index.d.ts +0 -16
  200. package/dist/runtime/draw-modes/index.js +0 -32
  201. package/dist/runtime/utils/draw-theme.d.ts +0 -47
  202. /package/dist/runtime/{utils → domains/map}/draw-theme.js +0 -0
@@ -26,21 +26,24 @@ const frames = ref([]);
26
26
  const durations = ref([]);
27
27
  useFrameIcon({
28
28
  imageName,
29
- size: props.size,
29
+ size: () => props.size,
30
30
  frames: () => frames.value,
31
- fps: props.fps,
31
+ fps: () => props.fps,
32
32
  durations: () => durations.value
33
33
  });
34
- async function load(url) {
34
+ let loadToken = 0;
35
+ async function load() {
36
+ const token = ++loadToken;
35
37
  frames.value = [];
36
38
  durations.value = [];
37
- const decoded = await decodeAnimatedImage(url, props.size);
39
+ const decoded = await decodeAnimatedImage(props.image, props.size);
40
+ if (token !== loadToken) return;
38
41
  frames.value = decoded.frames;
39
42
  durations.value = decoded.durations;
40
43
  ctx.map.value?.triggerRepaint();
41
44
  }
42
- onMounted(() => load(props.image));
43
- watch(() => props.image, (url) => load(url));
45
+ onMounted(load);
46
+ watch([() => props.image, () => props.size], load);
44
47
  </script>
45
48
 
46
49
  <template>
@@ -15,7 +15,7 @@ type __VLS_Props = {
15
15
  * @defaultValue 12
16
16
  */
17
17
  fps?: number;
18
- /** 图层 id;省略时自动生成 */
18
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
19
19
  layerId?: string;
20
20
  /** 插入到该图层之前 */
21
21
  beforeId?: string;
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -1,7 +1,7 @@
1
1
  import type { BuildingSourceOptions } from '../../utils/building';
2
2
  /** 流动建筑:渐变着色 + 高亮带沿建筑高度循环流动。 */
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
- /** 图层 id;省略时自动生成 */
4
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
5
5
  layerId?: string;
6
6
  /**
7
7
  * 基色
@@ -1,7 +1,7 @@
1
1
  import type { BuildingSourceOptions } from '../../utils/building';
2
2
  /** 流动建筑:渐变着色 + 高亮带沿建筑高度循环流动。 */
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
- /** 图层 id;省略时自动生成 */
4
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
5
5
  layerId?: string;
6
6
  /**
7
7
  * 基色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -1,7 +1,7 @@
1
1
  import type { BuildingSourceOptions } from '../../utils/building';
2
2
  /** 渐变建筑:按高度插值着色的 3D 建筑。 */
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
- /** 图层 id;省略时自动生成 */
4
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
5
5
  layerId?: string;
6
6
  /** 高度-颜色断点 */
7
7
  stops?: [number, string][];
@@ -1,7 +1,7 @@
1
1
  import type { BuildingSourceOptions } from '../../utils/building';
2
2
  /** 渐变建筑:按高度插值着色的 3D 建筑。 */
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
- /** 图层 id;省略时自动生成 */
4
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
5
5
  layerId?: string;
6
6
  /** 高度-颜色断点 */
7
7
  stops?: [number, string][];
@@ -9,7 +9,7 @@ export interface MigrationRoute {
9
9
  type __VLS_Props = {
10
10
  /** 起讫点对列表 */
11
11
  data: MigrationRoute[];
12
- /** 图层 id 前缀;省略时自动生成 */
12
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
13
13
  layerId?: string;
14
14
  /**
15
15
  * 主色
@@ -9,7 +9,7 @@ export interface MigrationRoute {
9
9
  type __VLS_Props = {
10
10
  /** 起讫点对列表 */
11
11
  data: MigrationRoute[];
12
- /** 图层 id 前缀;省略时自动生成 */
12
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
13
13
  layerId?: string;
14
14
  /**
15
15
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -28,7 +28,7 @@ type __VLS_Props = {
28
28
  * @defaultValue 64
29
29
  */
30
30
  size?: number;
31
- /** 图层 id;省略时自动生成 */
31
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
32
32
  layerId?: string;
33
33
  /** 插入到该图层之前 */
34
34
  beforeId?: string;
@@ -3,6 +3,7 @@ import { computed, ref, useId, watch } from "vue";
3
3
  import { spriteFrame, spriteFrameRect } from "../../utils/sprite";
4
4
  import { useMap } from "../../composables/useMap";
5
5
  import { useFrameIcon } from "../../composables/useFrameIcon";
6
+ import { logger } from "../../utils/logger";
6
7
  import MaplibreSource from "../Source.vue";
7
8
  import MaplibreLayer from "../Layer.vue";
8
9
  const props = defineProps({
@@ -28,36 +29,51 @@ const layout = computed(() => ({
28
29
  "icon-ignore-placement": true
29
30
  }));
30
31
  const sliced = ref([]);
31
- useFrameIcon({ imageName, size: props.size, frames: () => sliced.value, fps: props.fps });
32
- function prepareFrames() {
32
+ let sheet;
33
+ let loadToken = 0;
34
+ useFrameIcon({ imageName, size: () => props.size, frames: () => sliced.value, fps: () => props.fps });
35
+ function sliceFrames() {
36
+ if (!sheet) return;
37
+ const columns = props.columns ?? props.frames;
38
+ const rows = props.rows ?? 1;
39
+ const grid = {
40
+ columns,
41
+ rows,
42
+ frameWidth: props.frameWidth ?? sheet.width / columns,
43
+ frameHeight: props.frameHeight ?? sheet.height / rows,
44
+ frames: props.frames
45
+ };
46
+ const next = [];
47
+ for (let i = 0; i < props.frames; i++) {
48
+ const frame = spriteFrame(sheet, spriteFrameRect(i, grid), props.size);
49
+ if (frame) next.push(frame);
50
+ }
51
+ sliced.value = next;
52
+ ctx.map.value?.triggerRepaint();
53
+ }
54
+ function loadSheet(url) {
55
+ sheet = void 0;
56
+ sliced.value = [];
33
57
  if (typeof Image === "undefined") return;
58
+ const token = ++loadToken;
34
59
  const img = new Image();
35
60
  img.crossOrigin = "anonymous";
36
61
  img.onload = () => {
37
- const columns = props.columns ?? props.frames;
38
- const rows = props.rows ?? 1;
39
- const grid = {
40
- columns,
41
- rows,
42
- frameWidth: props.frameWidth ?? img.width / columns,
43
- frameHeight: props.frameHeight ?? img.height / rows,
44
- frames: props.frames
45
- };
46
- const next = [];
47
- for (let i = 0; i < props.frames; i++) {
48
- const frame = spriteFrame(img, spriteFrameRect(i, grid), props.size);
49
- if (frame) next.push(frame);
50
- }
51
- sliced.value = next;
52
- ctx.map.value?.triggerRepaint();
62
+ if (token !== loadToken) return;
63
+ sheet = img;
64
+ sliceFrames();
53
65
  };
54
- img.src = props.image;
66
+ img.onerror = () => {
67
+ if (token === loadToken) logger.warn(`SpriteImage: failed to load sprite sheet "${url}".`);
68
+ };
69
+ img.src = url;
55
70
  }
56
- prepareFrames();
57
- watch(() => props.image, () => {
58
- sliced.value = [];
59
- prepareFrames();
60
- });
71
+ loadSheet(props.image);
72
+ watch(() => props.image, loadSheet);
73
+ watch(
74
+ [() => props.frames, () => props.columns, () => props.rows, () => props.frameWidth, () => props.frameHeight, () => props.size],
75
+ sliceFrames
76
+ );
61
77
  </script>
62
78
 
63
79
  <template>
@@ -28,7 +28,7 @@ type __VLS_Props = {
28
28
  * @defaultValue 64
29
29
  */
30
30
  size?: number;
31
- /** 图层 id;省略时自动生成 */
31
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
32
32
  layerId?: string;
33
33
  /** 插入到该图层之前 */
34
34
  beforeId?: string;
@@ -3,7 +3,7 @@ import type { BuildingSourceOptions } from '../../utils/building';
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
4
  /** 贴图地址 */
5
5
  url: string;
6
- /** 图层 id;省略时自动生成 */
6
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 整体透明度
@@ -16,7 +16,7 @@ const props = defineProps({
16
16
  });
17
17
  const id = props.layerId ?? `movk-texture-building-${useId()}`;
18
18
  const imageName = `${id}-texture`;
19
- const { loaded } = useMaplibreImage(imageName, props.url);
19
+ const { loaded } = useMaplibreImage(imageName, () => props.url);
20
20
  const paint = computed(() => ({
21
21
  "fill-extrusion-pattern": imageName,
22
22
  ...buildingExtrusionPaint({ minzoom: props.minzoom, heightProperty: props.heightProperty, baseProperty: props.baseProperty }),
@@ -3,7 +3,7 @@ import type { BuildingSourceOptions } from '../../utils/building';
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
4
  /** 贴图地址 */
5
5
  url: string;
6
- /** 图层 id;省略时自动生成 */
6
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 整体透明度
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 线要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 线要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id 前缀;省略时自动生成 */
6
+ /** 图层 id 前缀;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 主色
@@ -1,7 +1,7 @@
1
1
  import type { BuildingSourceOptions } from '../../utils/building';
2
2
  /** 窗户建筑:程序生成窗户点阵贴图 fill-extrusion-pattern。 */
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
- /** 图层 id;省略时自动生成 */
4
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
5
5
  layerId?: string;
6
6
  /**
7
7
  * 窗户行数
@@ -1,7 +1,7 @@
1
1
  import type { BuildingSourceOptions } from '../../utils/building';
2
2
  /** 窗户建筑:程序生成窗户点阵贴图 fill-extrusion-pattern。 */
3
3
  type __VLS_Props = BuildingSourceOptions & {
4
- /** 图层 id;省略时自动生成 */
4
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
5
5
  layerId?: string;
6
6
  /**
7
7
  * 窗户行数
@@ -0,0 +1,28 @@
1
+ import type { ProjectionDefinitionSpecification, ProjectionSpecification } from '@maplibre/maplibre-gl-style-spec';
2
+ type __VLS_Props = {
3
+ /**
4
+ * 投影类型:'mercator' / 'globe' / 'vertical-perspective',或按 zoom 插值的表达式(如 `['interpolate', ['linear'], ['zoom'], 10, 'vertical-perspective', 12, 'mercator']`)
5
+ * @defaultValue 'globe'
6
+ */
7
+ type?: ProjectionDefinitionSpecification;
8
+ /**
9
+ * 完整投影规格,优先级高于 type
10
+ * @see https://maplibre.org/maplibre-style-spec/projection/
11
+ */
12
+ options?: ProjectionSpecification;
13
+ };
14
+ declare var __VLS_1: {};
15
+ type __VLS_Slots = {} & {
16
+ default?: (props: typeof __VLS_1) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
19
+ type: ProjectionDefinitionSpecification;
20
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
24
+ type __VLS_WithSlots<T, S> = T & {
25
+ new (): {
26
+ $slots: S;
27
+ };
28
+ };
@@ -0,0 +1,27 @@
1
+ <script setup>
2
+ import { onUnmounted } from "vue";
3
+ import { useMap } from "../../composables/useMap";
4
+ import { useStyleEffect } from "../../domains/map/style-effect";
5
+ import { isDeepEqual } from "@movk/core";
6
+ const props = defineProps({
7
+ type: { type: [String, Array, Object], required: false, default: "globe" },
8
+ options: { type: Object, required: false }
9
+ });
10
+ const ctx = useMap();
11
+ let baseline;
12
+ const stopCapture = ctx.onReady((map) => {
13
+ baseline = map.getProjection();
14
+ });
15
+ useStyleEffect(
16
+ () => props.options ?? { type: props.type },
17
+ (map, value) => {
18
+ if (!isDeepEqual(map.getProjection(), value)) map.setProjection(value);
19
+ },
20
+ (map) => map.setProjection(baseline ?? { type: "mercator" })
21
+ );
22
+ onUnmounted(stopCapture);
23
+ </script>
24
+
25
+ <template>
26
+ <slot />
27
+ </template>
@@ -0,0 +1,28 @@
1
+ import type { ProjectionDefinitionSpecification, ProjectionSpecification } from '@maplibre/maplibre-gl-style-spec';
2
+ type __VLS_Props = {
3
+ /**
4
+ * 投影类型:'mercator' / 'globe' / 'vertical-perspective',或按 zoom 插值的表达式(如 `['interpolate', ['linear'], ['zoom'], 10, 'vertical-perspective', 12, 'mercator']`)
5
+ * @defaultValue 'globe'
6
+ */
7
+ type?: ProjectionDefinitionSpecification;
8
+ /**
9
+ * 完整投影规格,优先级高于 type
10
+ * @see https://maplibre.org/maplibre-style-spec/projection/
11
+ */
12
+ options?: ProjectionSpecification;
13
+ };
14
+ declare var __VLS_1: {};
15
+ type __VLS_Slots = {} & {
16
+ default?: (props: typeof __VLS_1) => any;
17
+ };
18
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
19
+ type: ProjectionDefinitionSpecification;
20
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
24
+ type __VLS_WithSlots<T, S> = T & {
25
+ new (): {
26
+ $slots: S;
27
+ };
28
+ };
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id;省略时自动生成 */
6
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 权重取值的要素属性
@@ -3,7 +3,7 @@ import type { GeoJSONSourceSpecification } from '@maplibre/maplibre-gl-style-spe
3
3
  type __VLS_Props = {
4
4
  /** 点要素数据(GeoJSON 或其 URL) */
5
5
  data: GeoJSONSourceSpecification['data'];
6
- /** 图层 id;省略时自动生成 */
6
+ /** 图层 id;省略时自动生成,变更需配合 `:key` 重建 */
7
7
  layerId?: string;
8
8
  /**
9
9
  * 权重取值的要素属性
@@ -6,7 +6,7 @@ type __VLS_Props = {
6
6
  */
7
7
  exaggeration?: number;
8
8
  /**
9
- * DEM 数据源,如 Terrarium / Mapbox 编码的 raster-dem 瓦片
9
+ * DEM 数据源,如 Terrarium / Mapbox 编码的 raster-dem 瓦片;url / tiles 变化时原地更新
10
10
  * @see https://maplibre.org/maplibre-style-spec/sources/#raster-dem
11
11
  */
12
12
  source: RasterDEMSourceSpecification;
@@ -2,6 +2,7 @@
2
2
  import { onUnmounted, watch } from "vue";
3
3
  import { useMap } from "../../composables/useMap";
4
4
  import { logger } from "../../utils/logger";
5
+ import { updateSource } from "../../utils/source";
5
6
  const props = defineProps({
6
7
  exaggeration: { type: Number, required: false, default: 1 },
7
8
  source: { type: Object, required: true },
@@ -25,6 +26,10 @@ watch(() => props.exaggeration, (value) => {
25
26
  map.setTerrain({ source: props.sourceId, exaggeration: value });
26
27
  }
27
28
  });
29
+ watch(() => props.source, (next, prev) => {
30
+ const source = ctx.map.value?.getSource(props.sourceId);
31
+ if (source && next) updateSource(source, next, prev);
32
+ }, { deep: true });
28
33
  onUnmounted(() => {
29
34
  stopReady();
30
35
  const map = ctx.map.value;
@@ -6,7 +6,7 @@ type __VLS_Props = {
6
6
  */
7
7
  exaggeration?: number;
8
8
  /**
9
- * DEM 数据源,如 Terrarium / Mapbox 编码的 raster-dem 瓦片
9
+ * DEM 数据源,如 Terrarium / Mapbox 编码的 raster-dem 瓦片;url / tiles 变化时原地更新
10
10
  * @see https://maplibre.org/maplibre-style-spec/sources/#raster-dem
11
11
  */
12
12
  source: RasterDEMSourceSpecification;
@@ -2,18 +2,20 @@
2
2
  import { onMounted, onUnmounted, provide, watch } from "vue";
3
3
  import { TerraDraw } from "terra-draw";
4
4
  import { TerraDrawMapLibreGLAdapter } from "terra-draw-maplibre-gl-adapter";
5
+ import { isDeepEqual } from "@movk/core";
5
6
  import { useMap } from "../../composables/useMap";
6
7
  import { DrawKey } from "../../domains/map/draw";
7
8
  import { addStoreFeatures, committedFeatures, createDrawContext, toStoreFeatures } from "../../domains/map/draw-context";
8
- import { registerDraw, unregisterDraw } from "../../domains/map/draw-registry";
9
+ import { registerDraw } from "../../domains/map/draw-registry";
9
10
  import { createDrawToolbar } from "../../domains/map/draw-toolbar";
11
+ import { DRAW_MODE_NAMES, isDrawModeName, resolveDrawModes } from "../../domains/map/draw-modes";
12
+ import { drawThemeStyles } from "../../domains/map/draw-theme";
10
13
  import { getMapContext } from "../../domains/map/registry";
11
- import { movkDrawModes } from "../../draw-modes";
12
14
  const props = defineProps({
13
15
  position: { type: String, required: false },
14
16
  modes: { type: Array, required: false },
15
17
  theme: { type: Object, required: false },
16
- controls: { type: [Boolean, Array], required: false, default: true },
18
+ toolbar: { type: Boolean, required: false, default: true },
17
19
  renderBelowLayerId: { type: String, required: false }
18
20
  });
19
21
  const emit = defineEmits(["finish", "delete", "select", "deselect", "modechange"]);
@@ -28,7 +30,7 @@ function applyFeatures(list) {
28
30
  }
29
31
  function applyMode(value) {
30
32
  mode.value = value;
31
- toolbar?.setActive(value);
33
+ toolbarControl?.setActive(value);
32
34
  emit("modechange", value);
33
35
  }
34
36
  const { context: drawContext, attach } = createDrawContext(ctx.id, {
@@ -37,11 +39,10 @@ const { context: drawContext, attach } = createDrawContext(ctx.id, {
37
39
  });
38
40
  const draw = drawContext.draw;
39
41
  provide(DrawKey, drawContext);
40
- const addressable = getMapContext(ctx.id) === ctx;
41
- if (addressable) registerDraw(drawContext);
42
+ const disposeDraw = getMapContext(ctx.id) === ctx ? registerDraw(drawContext) : void 0;
42
43
  let instance;
43
44
  let boundMap;
44
- let toolbar;
45
+ let toolbarControl;
45
46
  let selectedId;
46
47
  function syncFeatures() {
47
48
  if (instance && !applying) applyFeatures(committedFeatures(instance));
@@ -94,12 +95,10 @@ function onStyleLoad() {
94
95
  applying = false;
95
96
  instance.setMode(current);
96
97
  }
97
- const modes = props.modes ?? movkDrawModes({ theme: props.theme });
98
+ const entries = props.modes ?? DRAW_MODE_NAMES;
99
+ const modes = resolveDrawModes(entries, props.theme);
98
100
  const modeNames = modes.map((m) => m.mode);
99
- function toolbarModes() {
100
- if (props.controls === false) return [];
101
- return props.controls === true ? modeNames : props.controls.filter((name) => modeNames.includes(name));
102
- }
101
+ const themedNames = entries.filter(isDrawModeName);
103
102
  onMounted(async () => {
104
103
  const map = await ctx.whenLoaded();
105
104
  boundMap = map;
@@ -113,20 +112,20 @@ onMounted(async () => {
113
112
  instance.on("select", onSelect);
114
113
  instance.on("deselect", onDeselect);
115
114
  map.on("style.load", onStyleLoad);
116
- if (props.controls !== false) {
117
- toolbar = createDrawToolbar({
118
- modes: toolbarModes(),
115
+ if (props.toolbar) {
116
+ toolbarControl = createDrawToolbar({
117
+ modes: modeNames,
119
118
  // 再次点击当前绘制模式回到选择模式,与常见绘图工具一致
120
119
  onMode: (name) => setMode(name === instance?.getMode() && hasMode("select") ? "select" : name),
121
120
  onTrash: () => {
122
121
  if (selectedId !== void 0 && instance?.hasFeature(selectedId)) instance.removeFeatures([selectedId]);
123
122
  }
124
123
  });
125
- map.addControl(toolbar, props.position);
124
+ map.addControl(toolbarControl, props.position);
126
125
  }
127
126
  attach(instance);
128
127
  if (features.value?.length) setFeatures(features.value);
129
- const initial = mode.value ?? (modeNames.includes("select") ? "select" : instance.getMode());
128
+ const initial = mode.value ?? (hasMode("select") ? "select" : modeNames[0] ?? instance.getMode());
130
129
  instance.setMode(initial);
131
130
  applyMode(initial);
132
131
  });
@@ -138,10 +137,15 @@ watch(features, (value) => {
138
137
  watch(mode, (value) => {
139
138
  if (value) setMode(value);
140
139
  });
140
+ watch(() => props.theme, (theme, previous) => {
141
+ if (!instance || isDeepEqual(theme, previous)) return;
142
+ const styles = drawThemeStyles(theme);
143
+ for (const name of themedNames) instance.updateModeOptions(name, { styles: styles[name] });
144
+ }, { deep: true });
141
145
  onUnmounted(() => {
142
- if (addressable) unregisterDraw(drawContext);
146
+ disposeDraw?.();
143
147
  boundMap?.off("style.load", onStyleLoad);
144
- if (toolbar) boundMap?.removeControl(toolbar);
148
+ if (toolbarControl) boundMap?.removeControl(toolbarControl);
145
149
  if (!instance) return;
146
150
  instance.off("change", onChange);
147
151
  instance.off("finish", onFinish);