mahal_map 1.6.20 → 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
@@ -18,30 +18,6 @@ npm install mahal_map maplibre-gl
18
18
  npm i @grammaps/maps3d-web maplibre-gl
19
19
  ```
20
20
 
21
- `three` идёт зависимостью SDK, `maplibre-gl` — peer (экземпляр карты создаёте вы через `mahal_map`).
22
-
23
- Оффлайн-вариант: в стартере со страницы платформы лежит папка `libs/maps3d-web` со собранным `dist/` — ставится как локальная зависимость:
24
-
25
- ```sh
26
- npm i ./libs/maps3d-web maplibre-gl
27
- ```
28
-
29
- `package.json` в этом случае запишет ссылку на локальную папку:
30
-
31
- ```json
32
- "@grammaps/maps3d-web": "file:./libs/maps3d-web"
33
- ```
34
-
35
- Без сборщика возьмите `lib/maps3d.global.js` из скачанного стартера (IIFE-глобал `Maps3D`, three бандлится внутрь) и подключите скриптом после `maplibre-gl`:
36
-
37
- ```html
38
- <script src="https://cdn.jsdelivr.net/npm/maplibre-gl@4.7.1/dist/maplibre-gl.js"></script>
39
- <script src="./lib/maps3d.global.js"></script>
40
- <script src="https://cp.mahal.tj/sdk/mahal_map.sdk.js?apikey=YOUR_MAP_API_KEY"></script>
41
- ```
42
-
43
- SDK сам найдёт конструктор в `window.Maps3D.Maps3D` — передавать его вручную не нужно.
44
-
45
21
  ## Быстрый старт через NPM
46
22
 
47
23
  ```ts
@@ -264,6 +240,180 @@ map.toggle3DBuildings(true); // вкл обратно
264
240
  MahalMap.toggle3DBuildings(map, false);
265
241
  ```
266
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
+
267
417
  ### Пробки
268
418
 
269
419
  ```ts
@@ -496,6 +646,7 @@ MahalMap.setCenter(map, [69.624024, 40.279687]);
496
646
  MahalMap.setZoom(map, 14);
497
647
  MahalMap.addMarker(map, marker);
498
648
  MahalMap.getMaps3DLayer(map);
649
+ MahalMap.whenMaps3DReady(map);
499
650
  MahalMap.toggle3DBuildings(map, false);
500
651
  MahalMap.destroy(map);
501
652
  ```
@@ -535,6 +686,7 @@ MahalMap.setZoom(map, 14);
535
686
  | `setZoom(instance, zoom)` | Меняет zoom карты. |
536
687
  | `addMarker(instance, marker)` | Добавляет маркер. |
537
688
  | `getMaps3DLayer(instance)` | Возвращает инстанс слоя Maps3D (только `engine: "3d"`). |
689
+ | `whenMaps3DReady(instance)` | Промис слоя Maps3D после `attach()` (готов `layer.buildings`). |
538
690
  | `toggle3DBuildings(instance, enabled)` | Вкл/выкл детальные 3D-здания на лету (только `engine: "3d"`). |
539
691
  | `destroy(instance)` | Полностью удаляет карту. |
540
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;