mahal_map 1.6.21 → 1.6.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/README.md CHANGED
@@ -240,6 +240,180 @@ map.toggle3DBuildings(true); // вкл обратно
240
240
  MahalMap.toggle3DBuildings(map, false);
241
241
  ```
242
242
 
243
+ #### `map.whenMaps3DReady()`
244
+
245
+ `attach()` слоя асинхронный: сразу после `create()` слой уже есть, но `layer.buildings` (окна, свет, кромки) появляется только после attach. Чтобы не гадать — дождитесь готовности:
246
+
247
+ ```ts
248
+ const layer = await map.whenMaps3DReady();
249
+
250
+ layer?.buildings?.setWindowStyle(4);
251
+ ```
252
+
253
+ Промис резолвится в `undefined`, если движок не `"3d"`, слой выключен (`enable3D: false`) или attach упал — ошибка при этом уходит в `console.error`, а карта остаётся живой со штатными зданиями стиля.
254
+
255
+ ### Подключение и выключение 3D-слоя: полный пример (Vue 3)
256
+
257
+ Кнопка-переключатель «3D ⇄ контуры», тонкая настройка окон и корректная очистка при размонтировании. Слой `Maps3D` поднимает и цепляет сама библиотека — вручную `new Maps3D(...)`, `transformRequest` и `attach()` писать не нужно.
258
+
259
+ ```vue
260
+ <script setup lang="ts">
261
+ import { computed, onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
262
+ import maplibregl from "maplibre-gl";
263
+ import "maplibre-gl/dist/maplibre-gl.css";
264
+ import { Maps3D } from "@grammaps/maps3d-web";
265
+ import { MahalMap, keyUtils } from "mahal_map";
266
+
267
+ const API_KEY = "YOUR_MAP_API_KEY";
268
+
269
+ const mahalMap = shallowRef<MahalMap | null>(null);
270
+ const is3dEnabled = ref(true);
271
+ const isLayerReady = ref(false);
272
+
273
+ const buildingModeText = computed(() =>
274
+ is3dEnabled.value ? "3D включено" : "Контуры",
275
+ );
276
+ const buildingToggleText = computed(() =>
277
+ is3dEnabled.value ? "Выключить 3D" : "Включить 3D",
278
+ );
279
+
280
+ function toggle3dBuildings() {
281
+ is3dEnabled.value = !is3dEnabled.value;
282
+ // Вкл/выкл детальных 3D-зданий: библиотека сама вернёт/спрячет плоские здания стиля.
283
+ mahalMap.value?.toggle3DBuildings(is3dEnabled.value);
284
+ }
285
+
286
+ onMounted(async () => {
287
+ // Токен — один на всё (стиль, тайлы, Maps3D). Отдельный apiKey слою передавать не нужно.
288
+ keyUtils.saveKey(API_KEY);
289
+
290
+ const map = MahalMap.create(
291
+ {
292
+ container: "map",
293
+ engine: "3d", // платформа GramMaps вместо legacy-стилей
294
+ theme: "dark", // preset standard-night; "light" → road-urban-lab-v2
295
+ center: [68.787, 38.573],
296
+ zoom: 16.6,
297
+ pitch: 58, // без наклона экструзия не видна
298
+ bearing: -20,
299
+ enable3D: true, // значение по умолчанию для engine: "3d"
300
+ maps3d: { minZoom: 16, lodBias: 0 },
301
+ },
302
+ maplibregl,
303
+ Maps3D,
304
+ );
305
+
306
+ mahalMap.value = map;
307
+
308
+ // Дожидаемся attach(): до него layer.buildings ещё нет.
309
+ const layer = await map.whenMaps3DReady();
310
+ const buildings = layer?.buildings;
311
+
312
+ if (!buildings) {
313
+ return;
314
+ }
315
+
316
+ buildings.setWindowMinZoom(16);
317
+ buildings.setWindowStyle(4);
318
+ buildings.setWindowDepth(0.85);
319
+ buildings.setWindowColor("#6b9ed1");
320
+ buildings.setWindowFrameColor("#f2f2f4");
321
+ buildings.setWindowGlow(0.22);
322
+ buildings.setEdgeRadius(1.2);
323
+
324
+ isLayerReady.value = true;
325
+ });
326
+
327
+ onBeforeUnmount(() => {
328
+ isLayerReady.value = false;
329
+ // destroy() сам снимает слой Maps3D и удаляет карту MapLibre.
330
+ mahalMap.value?.destroy();
331
+ mahalMap.value = null;
332
+ });
333
+ </script>
334
+
335
+ <template>
336
+ <main class="map-page">
337
+ <div id="map" class="map" />
338
+
339
+ <section class="panel" aria-label="GramMaps 3D">
340
+ <span class="mode-label">{{ buildingModeText }}</span>
341
+ <button
342
+ type="button"
343
+ :aria-pressed="is3dEnabled"
344
+ :disabled="!isLayerReady"
345
+ @click="toggle3dBuildings"
346
+ >
347
+ {{ buildingToggleText }}
348
+ </button>
349
+ </section>
350
+ </main>
351
+ </template>
352
+
353
+ <style>
354
+ .map-page,
355
+ .map {
356
+ position: absolute;
357
+ inset: 0;
358
+ }
359
+
360
+ .panel {
361
+ position: absolute;
362
+ top: 12px;
363
+ left: 12px;
364
+ z-index: 2;
365
+ }
366
+ </style>
367
+ ```
368
+
369
+ Что библиотека делает за вас против ручного подключения `@grammaps/maps3d-web`:
370
+
371
+ | Ручной код | Через `mahal_map` |
372
+ | ----------------------------------------------- | ----------------------------------------------------------------- |
373
+ | `style: base + "/maps/standard-night.json"` | `engine: "3d"` + `theme` (или `preset` / `base` явно) |
374
+ | `transformRequest: Maps3D.transformRequest(..)` | ставится автоматически (и без Maps3D — своим фолбэком с `?key=`) |
375
+ | `new Maps3D({...}); await layer.attach(map)` | `enable3D: true` + `maps3d: {...}`, `await map.whenMaps3DReady()` |
376
+ | `setBuildingsEnabled` + `buildings.setWindows` | `map.toggle3DBuildings(enabled)` — оба вызова разом |
377
+ | Плоские здания стиля поверх 3D после `setStyle` | скрываются сами на каждой загрузке стиля |
378
+ | `layer.destroy(); map.remove()` | `map.destroy()` |
379
+
380
+ #### То же самое без сборщика (browser SDK)
381
+
382
+ ```html
383
+ <script src="https://unpkg.com/maplibre-gl@5.3.0/dist/maplibre-gl.js"></script>
384
+ <script src="https://cdn.jsdelivr.net/npm/@grammaps/maps3d-web/dist/maps3d.global.js"></script>
385
+ <script src="https://cp.mahal.tj/sdk/mahal_map.sdk.js?apikey=YOUR_MAP_API_KEY"></script>
386
+
387
+ <div id="map" style="width: 100%; height: 500px"></div>
388
+ <button id="toggle3d" type="button">Выключить 3D</button>
389
+
390
+ <script>
391
+ // Maps3D берётся из window.Maps3D — третий аргумент передавать не нужно.
392
+ const map = MahalMap.create({
393
+ container: "map",
394
+ engine: "3d",
395
+ theme: "dark",
396
+ center: [68.787, 38.573],
397
+ zoom: 16.6,
398
+ pitch: 58,
399
+ });
400
+
401
+ let enabled = true;
402
+
403
+ document.getElementById("toggle3d").addEventListener("click", () => {
404
+ enabled = !enabled;
405
+ MahalMap.toggle3DBuildings(map, enabled);
406
+ document.getElementById("toggle3d").textContent = enabled
407
+ ? "Выключить 3D"
408
+ : "Включить 3D";
409
+ });
410
+
411
+ MahalMap.whenMaps3DReady(map).then((layer) => {
412
+ layer?.buildings?.setWindowStyle(4);
413
+ });
414
+ </script>
415
+ ```
416
+
243
417
  ### Пробки
244
418
 
245
419
  ```ts
@@ -472,6 +646,7 @@ MahalMap.setCenter(map, [69.624024, 40.279687]);
472
646
  MahalMap.setZoom(map, 14);
473
647
  MahalMap.addMarker(map, marker);
474
648
  MahalMap.getMaps3DLayer(map);
649
+ MahalMap.whenMaps3DReady(map);
475
650
  MahalMap.toggle3DBuildings(map, false);
476
651
  MahalMap.destroy(map);
477
652
  ```
@@ -511,6 +686,7 @@ MahalMap.setZoom(map, 14);
511
686
  | `setZoom(instance, zoom)` | Меняет zoom карты. |
512
687
  | `addMarker(instance, marker)` | Добавляет маркер. |
513
688
  | `getMaps3DLayer(instance)` | Возвращает инстанс слоя Maps3D (только `engine: "3d"`). |
689
+ | `whenMaps3DReady(instance)` | Промис слоя Maps3D после `attach()` (готов `layer.buildings`). |
514
690
  | `toggle3DBuildings(instance, enabled)` | Вкл/выкл детальные 3D-здания на лету (только `engine: "3d"`). |
515
691
  | `destroy(instance)` | Полностью удаляет карту. |
516
692
  | `loadKeyFromScriptUrl()` | Читает `apikey` из URL SDK скрипта. |
package/dist/index.d.mts CHANGED
@@ -233,8 +233,7 @@ declare class MahalMap {
233
233
  private presetIsExplicit;
234
234
  private maps3dCtor?;
235
235
  private maps3dLayer?;
236
- private maps3dLayerReady;
237
- private maps3dLayerAttachPending;
236
+ private maps3dReady?;
238
237
  private buildingsEnabled;
239
238
  private constructor();
240
239
  private static getInstanceKey;
@@ -254,6 +253,7 @@ declare class MahalMap {
254
253
  static getMap(instance: MahalMap): Map;
255
254
  static setStyle(instance: MahalMap, theme: Theme): void;
256
255
  static getMaps3DLayer(instance: MahalMap): IMaps3DLayer | undefined;
256
+ static whenMaps3DReady(instance: MahalMap): Promise<IMaps3DLayer | undefined>;
257
257
  static toggle3DBuildings(instance: MahalMap, enabled: boolean): void;
258
258
  static setLanguage(instance: MahalMap, lang: MapLanguage): void;
259
259
  static setCenter(instance: MahalMap, center: [number, number]): void;
@@ -268,12 +268,20 @@ declare class MahalMap {
268
268
  getMaps3DLayer(): IMaps3DLayer | undefined;
269
269
  /** Вкл/выкл детальные 3D-здания (Maps3D). Работает только для engine: "3d". */
270
270
  toggle3DBuildings(enabled: boolean): void;
271
+ /**
272
+ * Промис готовности слоя Maps3D: резолвится после attach(), когда доступен layer.buildings.
273
+ * Нужен для тонкой настройки окон/света — до attach контроллера зданий ещё нет.
274
+ * Резолвится в undefined, если движок не "3d", слой выключен или attach упал.
275
+ */
276
+ whenMaps3DReady(): Promise<IMaps3DLayer | undefined>;
271
277
  private attachMaps3DLayer;
272
278
  private applyMaps3DBuildingMode;
273
279
  /**
274
- * Прячет/показывает нативные здания стиля GramMaps ("building-3d" и любые fill-extrusion /
275
- * fill+source-layer=building), не задевая слои самого Maps3D. Нужно, иначе плоский слой стиля
276
- * рисуется поверх процедурных 3D-зданий и визуально их перекрывает.
280
+ * Прячет/показывает нативные здания стиля GramMaps ("building-3d" и прочие
281
+ * fill/fill-extrusion слои зданий), не задевая слои самого Maps3D. Нужно, иначе плоский слой
282
+ * стиля рисуется поверх процедурных 3D-зданий и визуально их перекрывает.
283
+ * Проверяем именно "здание" (id или source-layer), чтобы не гасить чужую экструзию
284
+ * в пользовательском стиле.
277
285
  */
278
286
  private setNativeBuildingsVisible;
279
287
  setCenter(center: [number, number]): void;
package/dist/index.d.ts CHANGED
@@ -233,8 +233,7 @@ declare class MahalMap {
233
233
  private presetIsExplicit;
234
234
  private maps3dCtor?;
235
235
  private maps3dLayer?;
236
- private maps3dLayerReady;
237
- private maps3dLayerAttachPending;
236
+ private maps3dReady?;
238
237
  private buildingsEnabled;
239
238
  private constructor();
240
239
  private static getInstanceKey;
@@ -254,6 +253,7 @@ declare class MahalMap {
254
253
  static getMap(instance: MahalMap): Map;
255
254
  static setStyle(instance: MahalMap, theme: Theme): void;
256
255
  static getMaps3DLayer(instance: MahalMap): IMaps3DLayer | undefined;
256
+ static whenMaps3DReady(instance: MahalMap): Promise<IMaps3DLayer | undefined>;
257
257
  static toggle3DBuildings(instance: MahalMap, enabled: boolean): void;
258
258
  static setLanguage(instance: MahalMap, lang: MapLanguage): void;
259
259
  static setCenter(instance: MahalMap, center: [number, number]): void;
@@ -268,12 +268,20 @@ declare class MahalMap {
268
268
  getMaps3DLayer(): IMaps3DLayer | undefined;
269
269
  /** Вкл/выкл детальные 3D-здания (Maps3D). Работает только для engine: "3d". */
270
270
  toggle3DBuildings(enabled: boolean): void;
271
+ /**
272
+ * Промис готовности слоя Maps3D: резолвится после attach(), когда доступен layer.buildings.
273
+ * Нужен для тонкой настройки окон/света — до attach контроллера зданий ещё нет.
274
+ * Резолвится в undefined, если движок не "3d", слой выключен или attach упал.
275
+ */
276
+ whenMaps3DReady(): Promise<IMaps3DLayer | undefined>;
271
277
  private attachMaps3DLayer;
272
278
  private applyMaps3DBuildingMode;
273
279
  /**
274
- * Прячет/показывает нативные здания стиля GramMaps ("building-3d" и любые fill-extrusion /
275
- * fill+source-layer=building), не задевая слои самого Maps3D. Нужно, иначе плоский слой стиля
276
- * рисуется поверх процедурных 3D-зданий и визуально их перекрывает.
280
+ * Прячет/показывает нативные здания стиля GramMaps ("building-3d" и прочие
281
+ * fill/fill-extrusion слои зданий), не задевая слои самого Maps3D. Нужно, иначе плоский слой
282
+ * стиля рисуется поверх процедурных 3D-зданий и визуально их перекрывает.
283
+ * Проверяем именно "здание" (id или source-layer), чтобы не гасить чужую экструзию
284
+ * в пользовательском стиле.
277
285
  */
278
286
  private setNativeBuildingsVisible;
279
287
  setCenter(center: [number, number]): void;