mahal_map 2.0.0 → 2.0.2
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 +408 -173
- package/dist/index.d.mts +127 -12
- package/dist/index.d.ts +127 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8 -3
- package/dist/index.mjs.map +1 -1
- package/dist/mahal_map.sdk.js +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ npm install mahal_map maplibre-gl @grammaps/maps3d-web
|
|
|
12
12
|
|
|
13
13
|
Обе зависимости — `peerDependencies`, в бандл `mahal_map` они не входят. Библиотека их не импортирует: MapLibre и `Maps3D` приходят снаружи, аргументами `create()` либо через `window`.
|
|
14
14
|
|
|
15
|
-
- `maplibre-gl` (
|
|
15
|
+
- `maplibre-gl` (`^6.10.0`) — обязателен всегда.
|
|
16
16
|
- `@grammaps/maps3d-web` (>=0.5.0) — даёт стили, тайлы, объём, пробки, рельеф, планы этажей, клик по объектам. Помечен `optional`: без него карта поднимется на запасном векторном стиле, но 3D и слоёв платформы на ней не будет.
|
|
17
17
|
|
|
18
18
|
MapLibre можно не класть в свою сборку вовсе — платформа отдаёт согласованную версию вместе с веб-воркером:
|
|
@@ -21,19 +21,62 @@ MapLibre можно не класть в свою сборку вовсе — п
|
|
|
21
21
|
const maplibregl = await Maps3D.maplibre({ base: "https://navi.gram.tj" });
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
## Веб-воркер MapLibre
|
|
25
|
+
|
|
26
|
+
MapLibre разбирает векторные тайлы в веб-воркере и ищет его файл рядом со своим модулем. Сборщик складывает библиотеку в общий бандл, рядом файла не оказывается, и вместо скрипта сервер отдаёт `index.html`.
|
|
27
|
+
|
|
28
|
+
Симптом обманчивый: **карта показывает пустой фон, ошибок про карту нет**. В консоли лежит только `Uncaught SyntaxError: Unexpected token '<'` — ни слова ни про MapLibre, ни про воркер, ни про тайлы.
|
|
29
|
+
|
|
30
|
+
`mahal_map` это распознаёт сам. Если через 8 с после создания карты не разобран ни один векторный тайл, в консоль уходит предупреждение с причиной и обоими решениями:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
[MahalMap SDK] Карта пуста: ни один векторный тайл не разобран — похоже, не запустился веб-воркер MapLibre.
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Проверка молчит на растровых стилях (им воркер не нужен), в фоновой вкладке (там MapLibre приостановлен) и когда фичи отрисованы. Отключается через `workerCheck: false`, своя задержка — `workerCheck: 12000`.
|
|
37
|
+
|
|
38
|
+
### Решение 1 — взять библиотеку у платформы
|
|
39
|
+
|
|
40
|
+
Версия согласована с Maps3D, веб-воркер приезжает вместе с ней, настраивать нечего:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
const maplibregl = await Maps3D.maplibre({ base: "https://navi.gram.tj" });
|
|
44
|
+
|
|
45
|
+
const map = MahalMap.create({ container: "map" }, maplibregl, Maps3D);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Решение 2 — оставить свою сборку
|
|
49
|
+
|
|
50
|
+
Тогда адрес воркера нужно свести с реальным файлом — и в разработке, и в собранной версии:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// vite.config.ts — чтобы адрес воркера совпал с файлом во время разработки
|
|
54
|
+
export default defineConfig({ optimizeDeps: { exclude: ["maplibre-gl"] } });
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
// в приложении — чтобы адрес совпал и в собранной версии
|
|
59
|
+
import * as maplibregl from "maplibre-gl";
|
|
60
|
+
import "maplibre-gl/dist/maplibre-gl.css";
|
|
61
|
+
|
|
62
|
+
maplibregl.setWorkerUrl("/maplibre-gl-worker.mjs"); // файл скопирован в public/ из maplibre-gl/dist
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
> `import * as maplibregl` — не случайность: в MapLibre 6 default-экспорта нет, `import maplibregl from "maplibre-gl"` даёт `undefined`.
|
|
66
|
+
|
|
24
67
|
## Миграция с 1.x на 2.0
|
|
25
68
|
|
|
26
69
|
Собственных URL стилей у `mahal_map` больше нет — их целиком отдаёт `@grammaps/maps3d-web`.
|
|
27
70
|
|
|
28
|
-
| 1.x
|
|
29
|
-
|
|
|
30
|
-
| `engine: "legacy"` (по умолчанию)
|
|
31
|
-
| `engine: "3d"`
|
|
32
|
-
| `autoAddVectorSource: true`
|
|
33
|
-
| `preset: "standard-night"`
|
|
34
|
-
| `preset: "road-urban-lab-v2"`
|
|
35
|
-
| `lang` менял URL стиля
|
|
36
|
-
| `layer.setBuildingsEnabled(...)` напрямую
|
|
71
|
+
| 1.x | 2.0 |
|
|
72
|
+
| ----------------------------------------- | ------------------------------------------------------------------- |
|
|
73
|
+
| `engine: "legacy"` (по умолчанию) | Удалён. Единственный путь — платформа через `Maps3D`. |
|
|
74
|
+
| `engine: "3d"` | Больше не нужен, опция игнорируется. |
|
|
75
|
+
| `autoAddVectorSource: true` | Удалён. Тот же векторный стиль применяется сам, когда нет `Maps3D`. |
|
|
76
|
+
| `preset: "standard-night"` | `theme: "dark"`, либо полный URL в `style`. |
|
|
77
|
+
| `preset: "road-urban-lab-v2"` | `theme: "light"`, либо полный URL в `style`. |
|
|
78
|
+
| `lang` менял URL стиля | Стиль не трогает — язык подписей приходит из самого стиля. |
|
|
79
|
+
| `layer.setBuildingsEnabled(...)` напрямую | `map.toggle3DBuildings(...)` или `map.setLayer("buildings", ...)`. |
|
|
37
80
|
|
|
38
81
|
`engine` и `autoAddVectorSource` оставлены в типах как `@deprecated`, чтобы не ломать компиляцию, но на поведение не влияют.
|
|
39
82
|
|
|
@@ -58,7 +101,7 @@ const maplibregl = await Maps3D.maplibre({ base: "https://navi.gram.tj" });
|
|
|
58
101
|
## Быстрый старт через NPM
|
|
59
102
|
|
|
60
103
|
```ts
|
|
61
|
-
import maplibregl from "maplibre-gl";
|
|
104
|
+
import * as maplibregl from "maplibre-gl";
|
|
62
105
|
import "maplibre-gl/dist/maplibre-gl.css";
|
|
63
106
|
import { Maps3D } from "@grammaps/maps3d-web";
|
|
64
107
|
import { MahalMap, keyUtils } from "mahal_map";
|
|
@@ -87,28 +130,30 @@ const map = MahalMap.create(
|
|
|
87
130
|
|
|
88
131
|
## Быстрый старт через Browser SDK
|
|
89
132
|
|
|
90
|
-
|
|
133
|
+
Для browser SDK параметр `apikey` обязателен: без него карта не инициализируется.
|
|
134
|
+
|
|
135
|
+
**MapLibre 6 поставляется только как ESM** — классической сборки `dist/maplibre-gl.js` для `<script src>` в ней больше нет. Поэтому библиотеку карты подключают модульным скриптом и передают в `create()` вторым аргументом:
|
|
91
136
|
|
|
92
137
|
```html
|
|
93
138
|
<link
|
|
94
139
|
rel="stylesheet"
|
|
95
|
-
href="https://
|
|
140
|
+
href="https://cdn.jsdelivr.net/npm/maplibre-gl@6.10.0/dist/maplibre-gl.css"
|
|
96
141
|
/>
|
|
97
|
-
<script src="https://unpkg.com/maplibre-gl@5.3.0/dist/maplibre-gl.js"></script>
|
|
98
142
|
<script src="https://cp.mahal.tj/sdk/mahal_map.sdk.js?apikey=YOUR_MAP_API_KEY"></script>
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
После этого глобальный объект `MahalMap` доступен в `window`:
|
|
102
143
|
|
|
103
|
-
```html
|
|
104
144
|
<div id="map" style="width: 100%; height: 500px"></div>
|
|
105
145
|
|
|
106
|
-
<script>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
146
|
+
<script type="module">
|
|
147
|
+
import * as maplibregl from "https://cdn.jsdelivr.net/npm/maplibre-gl@6.10.0/+esm";
|
|
148
|
+
|
|
149
|
+
const map = MahalMap.create(
|
|
150
|
+
{
|
|
151
|
+
container: "map",
|
|
152
|
+
center: [69.624024, 40.279687],
|
|
153
|
+
zoom: 12,
|
|
154
|
+
},
|
|
155
|
+
maplibregl,
|
|
156
|
+
);
|
|
112
157
|
</script>
|
|
113
158
|
```
|
|
114
159
|
|
|
@@ -131,7 +176,7 @@ const map = MahalMap.create(
|
|
|
131
176
|
<script src="https://cp.mahal.tj/sdk/mahal_map.sdk.js?apikey=YOUR_MAP_API_KEY&lang=ru"></script>
|
|
132
177
|
```
|
|
133
178
|
|
|
134
|
-
|
|
179
|
+
`lang` влияет на поиск и роутинг, но не на стиль: подписи на карте приходят из самого стиля платформы.
|
|
135
180
|
|
|
136
181
|
## Параметры создания карты
|
|
137
182
|
|
|
@@ -156,42 +201,52 @@ interface IMahalMapOptions {
|
|
|
156
201
|
family?: "default" | "navigator" | "mobile";
|
|
157
202
|
preset?: Maps3DThemeName | string;
|
|
158
203
|
antialias?: boolean;
|
|
204
|
+
workerCheck?: boolean | number;
|
|
159
205
|
maps3d?: Omit<IMaps3DLayerOptions, "apiKey" | "base">;
|
|
206
|
+
/** @deprecated Оставлена для совместимости, на поведение не влияет. */
|
|
207
|
+
engine?: "legacy" | "3d";
|
|
208
|
+
/** @deprecated Оставлена для совместимости, на поведение не влияет. */
|
|
209
|
+
autoAddVectorSource?: boolean;
|
|
160
210
|
}
|
|
161
211
|
```
|
|
162
212
|
|
|
163
|
-
| Параметр
|
|
164
|
-
|
|
|
165
|
-
| `container`
|
|
166
|
-
| `style`
|
|
167
|
-
| `theme`
|
|
168
|
-
| `lang`
|
|
169
|
-
| `center`
|
|
170
|
-
| `zoom`
|
|
171
|
-
| `pitch`
|
|
172
|
-
| `bearing`
|
|
173
|
-
| `enable3D`
|
|
174
|
-
| `base`
|
|
175
|
-
| `family`
|
|
176
|
-
| `preset`
|
|
177
|
-
| `antialias`
|
|
178
|
-
| `
|
|
213
|
+
| Параметр | Тип | Описание |
|
|
214
|
+
| ------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
215
|
+
| `container` | `string \| HTMLElement` | ID контейнера или DOM-элемент. Не передан — берётся `"map"`. |
|
|
216
|
+
| `style` | `string` | Полный URL своего стиля. Задан — стиль зафиксирован, `setStyle()` его не меняет. |
|
|
217
|
+
| `theme` | `"dark" \| "light"` | Светлая/тёмная внутри выбранного `family`. По умолчанию `light`. |
|
|
218
|
+
| `lang` | `"tj" \| "ru"` | Язык для поиска и роутинга. На стиль не влияет — подписи приходят из самого стиля платформы. |
|
|
219
|
+
| `center` | `[number, number]` | Центр карты в формате `[lng, lat]`. |
|
|
220
|
+
| `zoom` | `number` | Начальный zoom. |
|
|
221
|
+
| `pitch` | `number` | Начальный наклон камеры. Не задан и 3D включено — авто `58`: при `pitch: 0` объём зданий не виден, камера смотрит строго сверху. |
|
|
222
|
+
| `bearing` | `number` | Начальный поворот камеры. |
|
|
223
|
+
| `enable3D` | `boolean` | Подключает Maps3D. По умолчанию `true`, когда `Maps3D` доступен. |
|
|
224
|
+
| `base` | `string` | Домен платформы. По умолчанию `https://navi.gram.tj`. |
|
|
225
|
+
| `family` | `"default" \| "navigator" \| "mobile"` | Семейство стилей. `theme` выбирает внутри него: `default` → `light`/`dark`, `navigator` → `navigator-light`/`navigator-dark`, `mobile` → `mobile-*`. |
|
|
226
|
+
| `preset` | `Maps3DThemeName \| string` | Явное имя темы платформы или полный URL стиля вместо пары `family` + `theme`. Задан — стиль зафиксирован. |
|
|
227
|
+
| `antialias` | `boolean` | Сглаживание сцены. По умолчанию `true` при включённом 3D: без него тонкая геометрия (перила, мачты, ряды сидений) на отдалении рассыпается в рябь. |
|
|
228
|
+
| `workerCheck` | `boolean \| number` | Диагностика неработающего веб-воркера MapLibre через 8 с после создания карты. `false` отключает, число задаёт свою задержку в мс. См. [Веб-воркер MapLibre](#веб-воркер-maplibre). |
|
|
229
|
+
| `maps3d` | `object` | Опции Maps3D: `buildings`, `traffic`, `indoor`, `closures`, `places`, `minZoom`, `lodBias`, `memoryBudget`, `maskReplaced`, `typeReplacements`. |
|
|
179
230
|
|
|
180
231
|
### Стили и темы
|
|
181
232
|
|
|
182
233
|
Стили целиком приходят из `@grammaps/maps3d-web` — своего списка URL у `mahal_map` больше нет. Словарь тем один и тот же у SDK и у библиотеки:
|
|
183
234
|
|
|
184
|
-
| `family` | `theme: "light"`
|
|
185
|
-
| ------------- |
|
|
186
|
-
| `"default"` | `light`
|
|
187
|
-
| `"navigator"` | `navigator-light`
|
|
188
|
-
| `"mobile"` | `mobile-light`
|
|
235
|
+
| `family` | `theme: "light"` | `theme: "dark"` |
|
|
236
|
+
| ------------- | ----------------- | ---------------- |
|
|
237
|
+
| `"default"` | `light` | `dark` |
|
|
238
|
+
| `"navigator"` | `navigator-light` | `navigator-dark` |
|
|
239
|
+
| `"mobile"` | `mobile-light` | `mobile-dark` |
|
|
189
240
|
|
|
190
241
|
Имя темы уходит в `Maps3D.styleUrl()`, адрес строит сам SDK. Неизвестное имя — явная ошибка с префиксом `[MahalMap SDK]`, а не пустая карта.
|
|
191
242
|
|
|
192
243
|
```ts
|
|
193
244
|
// Навигаторная тёмная тема
|
|
194
|
-
MahalMap.create(
|
|
245
|
+
MahalMap.create(
|
|
246
|
+
{ container: "map", family: "navigator", theme: "dark" },
|
|
247
|
+
maplibregl,
|
|
248
|
+
Maps3D,
|
|
249
|
+
);
|
|
195
250
|
|
|
196
251
|
// Смена темы внутри того же семейства
|
|
197
252
|
map.setStyle("light"); // → navigator-light
|
|
@@ -201,7 +256,10 @@ map.setStyle("light"); // → navigator-light
|
|
|
201
256
|
>
|
|
202
257
|
> ```ts
|
|
203
258
|
> MahalMap.create(
|
|
204
|
-
> {
|
|
259
|
+
> {
|
|
260
|
+
> container: "map",
|
|
261
|
+
> style: "https://navi.gram.tj/maps/standard-night.json",
|
|
262
|
+
> },
|
|
205
263
|
> maplibregl,
|
|
206
264
|
> Maps3D,
|
|
207
265
|
> );
|
|
@@ -217,55 +275,157 @@ map.setStyle("light"); // → navigator-light
|
|
|
217
275
|
|
|
218
276
|
Передаются в `MahalMap.create({ maps3d: {...} })` и уходят в `Maps3D` как есть:
|
|
219
277
|
|
|
220
|
-
| Опция | Тип
|
|
221
|
-
| ------------------ |
|
|
222
|
-
| `buildings` | `boolean \| { detail?: footprint\|volume\|roofs\|facade }`
|
|
223
|
-
| `traffic` | `boolean \| { raster?, rasterMaxZoom?, graph?, opacity?, arrows? }` | `false`
|
|
224
|
-
| `indoor` | `boolean \| { level? }`
|
|
225
|
-
| `closures` | `boolean \| object`
|
|
226
|
-
| `places` | `object`
|
|
227
|
-
| `minZoom` | `number`
|
|
228
|
-
| `lodBias` | `number`
|
|
229
|
-
| `memoryBudget` | `number`
|
|
230
|
-
| `maskReplaced` | `boolean`
|
|
231
|
-
| `typeReplacements` | `boolean`
|
|
278
|
+
| Опция | Тип | По умолч. | Описание |
|
|
279
|
+
| ------------------ | ------------------------------------------------------------------- | --------- | -------------------------------------------------------------------- |
|
|
280
|
+
| `buildings` | `boolean \| { detail?: footprint\|volume\|roofs\|facade }` | `true` | Объёмные здания; объектом — их облик. |
|
|
281
|
+
| `traffic` | `boolean \| { raster?, rasterMaxZoom?, graph?, opacity?, arrows? }` | `false` | Слой пробок. `raster: true` — картинкой вместо векторного слоя. |
|
|
282
|
+
| `indoor` | `boolean \| { level? }` | `false` | Планы этажей. |
|
|
283
|
+
| `closures` | `boolean \| object` | `false` | Перекрытия дорог. |
|
|
284
|
+
| `places` | `object` | — | Парковки, заправки, зарядки: `highlight`, `paid`, `free`, `unknown`. |
|
|
285
|
+
| `minZoom` | `number` | `16` | Зум появления объёма. |
|
|
286
|
+
| `lodBias` | `number` | `1` | `0` — всегда детальная геометрия, `1` — упрощённая вдали. |
|
|
287
|
+
| `memoryBudget` | `number` | `30` | Сколько 3D-моделей держать в памяти. |
|
|
288
|
+
| `maskReplaced` | `boolean` | `true` | Прятать заменённые OSM-объекты (`anchor=replace`). |
|
|
289
|
+
| `typeReplacements` | `boolean` | `true` | Рисовать замены по типу (`natural=tree` → 3D-дерево и т.п.). |
|
|
232
290
|
|
|
233
291
|
`apiKey` и `base` в `maps3d` передавать не нужно — их подставляет сам `MahalMap` из сохранённого ключа и `options.base`.
|
|
234
292
|
|
|
235
293
|
### Реестр слоёв
|
|
236
294
|
|
|
237
|
-
Единая дверь ко всем слоям платформы.
|
|
295
|
+
Единая дверь ко всем слоям платформы. Идентификаторы и параметры типизированы: опечатка в имени слоя или в значении параметра — ошибка компиляции, а не тихий `false` в рантайме.
|
|
238
296
|
|
|
239
297
|
```ts
|
|
240
298
|
map.setLayer("terrain", true, { mode: "on" });
|
|
241
299
|
map.setLayer("traffic", true);
|
|
242
300
|
map.setLayer("indoor", true, { level: 2 });
|
|
301
|
+
map.setLayer("buildings", true, { detail: "facade" });
|
|
302
|
+
|
|
303
|
+
map.getLayerState("terrain"); // снимок одного слоя или null
|
|
304
|
+
map.getLayers(); // снимок всех — по нему рисуется панель слоёв
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
| Слой | Параметры | По умолчанию | Откуда умолчание |
|
|
308
|
+
| ------------------ | ------------------------------------------ | ---------------------------------------------------------------------- | ----------------------- |
|
|
309
|
+
| `buildings` | `detail: footprint\|volume\|roofs\|facade` | включён | зашито |
|
|
310
|
+
| `objects` | — | включён | зашито |
|
|
311
|
+
| `terrain` | `mode: auto\|on\|off` | включён, `mode: "auto"` | зашито |
|
|
312
|
+
| `parking` | `highlight`, `paid`, `free`, `unknown` | включён, `{ highlight: false, paid: true, free: true, unknown: true }` | зашито |
|
|
313
|
+
| `fuel`, `charging` | — | включены | зашито |
|
|
314
|
+
| `traffic` | — | выключен | `maps3d.traffic` |
|
|
315
|
+
| `trafficRaster` | — | выключен | `maps3d.traffic.raster` |
|
|
316
|
+
| `indoor` | `level` | выключен | `maps3d.indoor` |
|
|
317
|
+
| `closures` | — | выключен | `maps3d.closures` |
|
|
318
|
+
|
|
319
|
+
У нижних четырёх умолчание не зашито — реестр берёт его из опций `maps3d`, переданных при создании карты. Поэтому «выключен» в таблице значит «выключен, пока вы не передали опцию», а не «выключен всегда».
|
|
320
|
+
|
|
321
|
+
Стартовое состояние можно задать сразу при создании карты — тогда первый кадр уже правильный, без моргания:
|
|
322
|
+
|
|
323
|
+
```ts
|
|
324
|
+
MahalMap.create(
|
|
325
|
+
{ container: "map", maps3d: { traffic: true, closures: true } },
|
|
326
|
+
maplibregl,
|
|
327
|
+
Maps3D,
|
|
328
|
+
);
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Полный список — в разделе [Опции `maps3d`](#опции-maps3d-расширенные).
|
|
332
|
+
|
|
333
|
+
#### `wanted`, `available`, `active` — три разных вопроса
|
|
334
|
+
|
|
335
|
+
Поля независимы, и это главная ловушка реестра:
|
|
336
|
+
|
|
337
|
+
| Поле | Вопрос |
|
|
338
|
+
| ----------- | ---------------------------- |
|
|
339
|
+
| `wanted` | чего хочет приложение |
|
|
340
|
+
| `available` | что позволяют стиль и данные |
|
|
341
|
+
| `active` | что нарисовано прямо сейчас |
|
|
342
|
+
|
|
343
|
+
Слой может быть включён и при этом не нарисован — и это не ошибка:
|
|
344
|
+
|
|
345
|
+
```ts
|
|
346
|
+
map.setLayer("terrain", true); // wanted: true
|
|
347
|
+
const state = map.getLayerState("terrain");
|
|
348
|
+
|
|
349
|
+
state?.available; // false — в стиле нет ключа maps3d:terrain
|
|
350
|
+
state?.active; // false — либо режим auto, а зум слишком близкий
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Поэтому галочку в интерфейсе рисуют по `wanted`, а пометку «сейчас не видно» — по `active`. Проверять сразу после `setLayer()` бесполезно: тайлы ещё едут. Правильный способ — подписка.
|
|
354
|
+
|
|
355
|
+
#### Панель слоёв: подписка и отписка
|
|
243
356
|
|
|
357
|
+
`onLayers()` возвращает функцию отписки. Звать её обязательно — иначе колбэк переживёт компонент и будет дёргать размонтированное состояние:
|
|
358
|
+
|
|
359
|
+
```ts
|
|
244
360
|
const unsubscribe = map.onLayers((state) => {
|
|
245
361
|
console.log(state.id, state.wanted, state.available, state.active);
|
|
246
362
|
});
|
|
247
363
|
|
|
248
|
-
|
|
249
|
-
|
|
364
|
+
// при размонтировании компонента
|
|
365
|
+
unsubscribe();
|
|
250
366
|
```
|
|
251
367
|
|
|
252
|
-
|
|
253
|
-
| ------------------ | ---------------------------------------- | ------------ |
|
|
254
|
-
| `buildings` | `detail: footprint\|volume\|roofs\|facade` | включён |
|
|
255
|
-
| `objects` | — | включён |
|
|
256
|
-
| `traffic` | — | выключен |
|
|
257
|
-
| `trafficRaster` | — | выключен |
|
|
258
|
-
| `parking` | `highlight`, `paid`, `free`, `unknown` | включён |
|
|
259
|
-
| `fuel`, `charging` | — | включены |
|
|
260
|
-
| `closures` | — | выключен |
|
|
261
|
-
| `indoor` | `level` | выключен |
|
|
262
|
-
| `terrain` | `mode: auto\|on\|off` | `auto` |
|
|
368
|
+
`map.destroy()` снимает слой Maps3D целиком, так что после него подписка всё равно мертва — но до него отписываться нужно самим.
|
|
263
369
|
|
|
264
|
-
|
|
370
|
+
#### Парковки, заправки, зарядки
|
|
265
371
|
|
|
266
|
-
|
|
372
|
+
`Maps3D` рисует их сам, забирая эти классы у POI-слоёв стиля. Поэтому выключение слоя убирает объекты с карты полностью, а не оставляет значок стиля.
|
|
267
373
|
|
|
268
|
-
|
|
374
|
+
Подтип парковки берётся из атрибута `fee`:
|
|
375
|
+
|
|
376
|
+
| Параметр | Условие |
|
|
377
|
+
| --------- | ------------ |
|
|
378
|
+
| `paid` | `fee=yes` |
|
|
379
|
+
| `free` | `fee=no` |
|
|
380
|
+
| `unknown` | атрибута нет |
|
|
381
|
+
|
|
382
|
+
```ts
|
|
383
|
+
// только платные, с подсветкой
|
|
384
|
+
map.setLayer("parking", true, {
|
|
385
|
+
paid: true,
|
|
386
|
+
free: false,
|
|
387
|
+
unknown: false,
|
|
388
|
+
highlight: true,
|
|
389
|
+
});
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
#### Рельеф
|
|
393
|
+
|
|
394
|
+
`auto` показывает рельеф на обзорных зумах, `on` — всегда. Режим `on` заметно дороже по трафику и времени кадра, чем `auto`.
|
|
395
|
+
|
|
396
|
+
```ts
|
|
397
|
+
map.setLayer("terrain", true, { mode: "auto" });
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
#### Планы этажей
|
|
401
|
+
|
|
402
|
+
Слой включается реестром, но одного этого мало — без переключения этажа он бесполезен:
|
|
403
|
+
|
|
404
|
+
```ts
|
|
405
|
+
map.setLayer("indoor", true);
|
|
406
|
+
|
|
407
|
+
const levels = map.getIndoorLevels(); // этажи в текущем виде карты, [] — данных нет
|
|
408
|
+
map.setIndoorLevel(1); // нумерация OSM: 0 — первый наземный
|
|
409
|
+
map.refreshIndoor(); // перечитать после правки картографом
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
После поиска показать найденный объект вместе с его этажом:
|
|
413
|
+
|
|
414
|
+
```ts
|
|
415
|
+
// level приходит у объектов внутри зданий; без него откроется первый этаж
|
|
416
|
+
// и метка окажется в чужом зале
|
|
417
|
+
map.showPlace(68.787, 38.573, place.level, 18);
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
#### Слой, которого нет в списке
|
|
421
|
+
|
|
422
|
+
`setLayer()` принимает только известные идентификаторы. Если в новой сборке Maps3D появится слой, которого ещё нет в типах, — он доступен напрямую через слой, там `id` остаётся строкой:
|
|
423
|
+
|
|
424
|
+
```ts
|
|
425
|
+
map.getMaps3DLayer()?.setLayer?.("новый-слой", true);
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
`setLayer()` возвращает `false`, если такого слоя в подключённой сборке Maps3D нет или Maps3D не передан вовсе. После полной смены стиля волю клиента возвращает `map.refreshLayers()` — при `setStyle()` библиотека вызывает его сама.
|
|
269
429
|
|
|
270
430
|
### 3D-здания
|
|
271
431
|
|
|
@@ -351,7 +511,15 @@ map.toggle3DBuildings(true); // вкл обратно
|
|
|
351
511
|
MahalMap.toggle3DBuildings(map, false);
|
|
352
512
|
```
|
|
353
513
|
|
|
354
|
-
|
|
514
|
+
Штатные здания стиля прячет и возвращает сам `Maps3D` — `mahal_map` их видимость не трогает, поэтому спорить за один слой некому.
|
|
515
|
+
|
|
516
|
+
Для переключения пользуйтесь именно `toggle3DBuildings()`: он поднимет слой, если его ещё не было (`enable3D: false` при создании), а на сборках Maps3D без реестра слоёв откатится на `setBuildingsEnabled()`.
|
|
517
|
+
|
|
518
|
+
```ts
|
|
519
|
+
map.toggle3DBuildings(false); // совместимо со всеми сборками
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
`map.setLayer("buildings", false)` — не замена: он ходит только в реестр и ничего не создаёт. Годится, когда вы точно знаете, что на странице Maps3D с реестром слоёв (0.7.x), и слой уже подключён.
|
|
355
523
|
|
|
356
524
|
#### `map.whenMaps3DReady()`
|
|
357
525
|
|
|
@@ -367,15 +535,16 @@ layer?.buildings?.setWindowStyle(4);
|
|
|
367
535
|
|
|
368
536
|
### Подключение и выключение 3D-слоя: полный пример (Vue 3)
|
|
369
537
|
|
|
370
|
-
Кнопка-переключатель «3D ⇄ контуры»,
|
|
538
|
+
Кнопка-переключатель «3D ⇄ контуры», панель слоёв на живом состоянии реестра и корректная очистка при размонтировании. Слой `Maps3D` поднимает и цепляет сама библиотека — вручную `Maps3D.enhance(...)`, `transformRequest` и `attach()` писать не нужно.
|
|
371
539
|
|
|
372
540
|
```vue
|
|
373
541
|
<script setup lang="ts">
|
|
374
542
|
import { computed, onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
|
|
375
|
-
import maplibregl from "maplibre-gl";
|
|
543
|
+
import * as maplibregl from "maplibre-gl";
|
|
376
544
|
import "maplibre-gl/dist/maplibre-gl.css";
|
|
377
545
|
import { Maps3D } from "@grammaps/maps3d-web";
|
|
378
546
|
import { MahalMap, keyUtils } from "mahal_map";
|
|
547
|
+
import type { IMaps3DLayerState, Maps3DLayerId } from "mahal_map";
|
|
379
548
|
|
|
380
549
|
const API_KEY = "YOUR_MAP_API_KEY";
|
|
381
550
|
|
|
@@ -383,6 +552,15 @@ const mahalMap = shallowRef<MahalMap | null>(null);
|
|
|
383
552
|
const is3dEnabled = ref(true);
|
|
384
553
|
const isLayerReady = ref(false);
|
|
385
554
|
|
|
555
|
+
// Панель слоёв рисуется по живому снимку реестра
|
|
556
|
+
const layers = ref<IMaps3DLayerState[]>([]);
|
|
557
|
+
let unsubscribeLayers: (() => void) | null = null;
|
|
558
|
+
|
|
559
|
+
function toggleLayer(id: Maps3DLayerId, on: boolean) {
|
|
560
|
+
// Опечатка в id или в параметрах не скомпилируется
|
|
561
|
+
mahalMap.value?.setLayer(id, on);
|
|
562
|
+
}
|
|
563
|
+
|
|
386
564
|
const buildingModeText = computed(() =>
|
|
387
565
|
is3dEnabled.value ? "3D включено" : "Контуры",
|
|
388
566
|
);
|
|
@@ -433,11 +611,21 @@ onMounted(async () => {
|
|
|
433
611
|
buildings.setWindowGlow?.(0.22);
|
|
434
612
|
buildings.setEdgeRadius(1.2);
|
|
435
613
|
|
|
614
|
+
// Слои: стартовый снимок плюс подписка на изменения.
|
|
615
|
+
// Состояние приходит асинхронно — сразу после setLayer() проверять бесполезно.
|
|
616
|
+
layers.value = map.getLayers();
|
|
617
|
+
unsubscribeLayers = map.onLayers(() => {
|
|
618
|
+
layers.value = map.getLayers();
|
|
619
|
+
});
|
|
620
|
+
|
|
436
621
|
isLayerReady.value = true;
|
|
437
622
|
});
|
|
438
623
|
|
|
439
624
|
onBeforeUnmount(() => {
|
|
440
625
|
isLayerReady.value = false;
|
|
626
|
+
// Отписку снимаем сами: иначе колбэк переживёт компонент.
|
|
627
|
+
unsubscribeLayers?.();
|
|
628
|
+
unsubscribeLayers = null;
|
|
441
629
|
// destroy() сам снимает слой Maps3D и удаляет карту MapLibre.
|
|
442
630
|
mahalMap.value?.destroy();
|
|
443
631
|
mahalMap.value = null;
|
|
@@ -458,6 +646,24 @@ onBeforeUnmount(() => {
|
|
|
458
646
|
>
|
|
459
647
|
{{ buildingToggleText }}
|
|
460
648
|
</button>
|
|
649
|
+
|
|
650
|
+
<ul class="layers">
|
|
651
|
+
<li v-for="layer in layers" :key="layer.id">
|
|
652
|
+
<label>
|
|
653
|
+
<!-- галочка по wanted: это воля приложения -->
|
|
654
|
+
<input
|
|
655
|
+
type="checkbox"
|
|
656
|
+
:checked="layer.wanted"
|
|
657
|
+
:disabled="!layer.available"
|
|
658
|
+
@change="toggleLayer(layer.id as Maps3DLayerId, !layer.wanted)"
|
|
659
|
+
/>
|
|
660
|
+
{{ layer.id }}
|
|
661
|
+
</label>
|
|
662
|
+
<!-- слой включён, но не нарисован — это норма, а не ошибка -->
|
|
663
|
+
<small v-if="layer.wanted && !layer.active">сейчас не видно</small>
|
|
664
|
+
<small v-else-if="!layer.available">нет в стиле</small>
|
|
665
|
+
</li>
|
|
666
|
+
</ul>
|
|
461
667
|
</section>
|
|
462
668
|
</main>
|
|
463
669
|
</template>
|
|
@@ -480,35 +686,42 @@ onBeforeUnmount(() => {
|
|
|
480
686
|
|
|
481
687
|
Что библиотека делает за вас против ручного подключения `@grammaps/maps3d-web`:
|
|
482
688
|
|
|
483
|
-
| Ручной код
|
|
484
|
-
|
|
|
485
|
-
| `...Maps3D.mapOptions({ base, apiKey, style })`
|
|
486
|
-
| `antialias: true` не забыть
|
|
487
|
-
| `Maps3D.enhance(map, opts); await maps3d.ready`
|
|
488
|
-
| `map.setStyle(Maps3D.styleUrl("dark", base))`
|
|
489
|
-
| `maps3d.refreshLayers()` после смены стиля
|
|
490
|
-
| `maps3d.destroy(); map.remove()`
|
|
491
|
-
| ключ руками в каждый вызов
|
|
689
|
+
| Ручной код | Через `mahal_map` |
|
|
690
|
+
| ----------------------------------------------- | ----------------------------------------------------------------- |
|
|
691
|
+
| `...Maps3D.mapOptions({ base, apiKey, style })` | `theme` + `family` (или `preset` / `style` / `base` явно) |
|
|
692
|
+
| `antialias: true` не забыть | ставится сам при включённом 3D |
|
|
693
|
+
| `Maps3D.enhance(map, opts); await maps3d.ready` | `enable3D: true` + `maps3d: {...}`, `await map.whenMaps3DReady()` |
|
|
694
|
+
| `map.setStyle(Maps3D.styleUrl("dark", base))` | `map.setStyle("dark")` — внутри выбранного семейства |
|
|
695
|
+
| `maps3d.refreshLayers()` после смены стиля | вызывается сам на `style.load` |
|
|
696
|
+
| `maps3d.destroy(); map.remove()` | `map.destroy()` |
|
|
697
|
+
| ключ руками в каждый вызов | один `keyUtils.saveKey()` на всё |
|
|
492
698
|
|
|
493
699
|
#### То же самое без сборщика (browser SDK)
|
|
494
700
|
|
|
701
|
+
Библиотеку карты проще взять у платформы: версия согласована с Maps3D, веб-воркер приезжает вместе с ней, про ESM-сборку думать не нужно.
|
|
702
|
+
|
|
495
703
|
```html
|
|
496
|
-
<script src="https://unpkg.com/maplibre-gl@5.3.0/dist/maplibre-gl.js"></script>
|
|
497
704
|
<script src="https://cdn.jsdelivr.net/npm/@grammaps/maps3d-web/dist/maps3d.global.js"></script>
|
|
498
705
|
<script src="https://cp.mahal.tj/sdk/mahal_map.sdk.js?apikey=YOUR_MAP_API_KEY"></script>
|
|
499
706
|
|
|
500
707
|
<div id="map" style="width: 100%; height: 500px"></div>
|
|
501
708
|
<button id="toggle3d" type="button">Выключить 3D</button>
|
|
502
709
|
|
|
503
|
-
<script>
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
710
|
+
<script type="module">
|
|
711
|
+
const maplibregl = await Maps3D.maplibre({ base: "https://navi.gram.tj" });
|
|
712
|
+
|
|
713
|
+
// maplibregl обязателен вторым аргументом: window.maplibregl здесь не появляется.
|
|
714
|
+
// Maps3D третьим можно не передавать — SDK возьмёт его из window.Maps3D.
|
|
715
|
+
const map = MahalMap.create(
|
|
716
|
+
{
|
|
717
|
+
container: "map",
|
|
718
|
+
theme: "dark",
|
|
719
|
+
center: [68.787, 38.573],
|
|
720
|
+
zoom: 16.6,
|
|
721
|
+
pitch: 58,
|
|
722
|
+
},
|
|
723
|
+
maplibregl,
|
|
724
|
+
);
|
|
512
725
|
|
|
513
726
|
let enabled = true;
|
|
514
727
|
|
|
@@ -608,13 +821,13 @@ try {
|
|
|
608
821
|
|
|
609
822
|
Правила проверки:
|
|
610
823
|
|
|
611
|
-
| Условие
|
|
612
|
-
|
|
|
613
|
-
| `Maps3D` не передан, сервис ответил `success: true`
|
|
614
|
-
| `Maps3D` не передан, сервис ответил `success: false`
|
|
615
|
-
| `Maps3D` не передан, проверка не дошла (сеть, CORS, таймаут) | Fail-open: `console.warn` и карта создаётся. Падение сервиса проверки не гасит карты.
|
|
616
|
-
| `Maps3D` передан
|
|
617
|
-
| Map token не сохранён
|
|
824
|
+
| Условие | Поведение |
|
|
825
|
+
| ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
|
|
826
|
+
| `Maps3D` не передан, сервис ответил `success: true` | Карта создаётся на запасном стиле. |
|
|
827
|
+
| `Maps3D` не передан, сервис ответил `success: false` | Карта **не** создаётся, промис отклоняется: `[MahalMap SDK] JSApi subscription is not active for this key: <message>`. |
|
|
828
|
+
| `Maps3D` не передан, проверка не дошла (сеть, CORS, таймаут) | Fail-open: `console.warn` и карта создаётся. Падение сервиса проверки не гасит карты. |
|
|
829
|
+
| `Maps3D` передан | Проверка **пропускается**, запрос не отправляется. |
|
|
830
|
+
| Map token не сохранён | Проверка пропускается, дальше срабатывает обычная ошибка про `apikey`. |
|
|
618
831
|
|
|
619
832
|
С переданным `Maps3D` вызов `createAsync()` ведёт себя ровно как `create()` — доступ к платформе контролируется параметром `?key=` на её стороне, отдельная подписка JSApi к ней отношения не имеет.
|
|
620
833
|
|
|
@@ -631,13 +844,15 @@ try {
|
|
|
631
844
|
<div ref="mapElement" class="h-[360px] w-full" />
|
|
632
845
|
</div>
|
|
633
846
|
<template #fallback>
|
|
634
|
-
<div class="flex h-[360px] items-center justify-center">
|
|
847
|
+
<div class="flex h-[360px] items-center justify-center">
|
|
848
|
+
{{ loadingLabel }}
|
|
849
|
+
</div>
|
|
635
850
|
</template>
|
|
636
851
|
</ClientOnly>
|
|
637
852
|
</template>
|
|
638
853
|
|
|
639
854
|
<script setup lang="ts">
|
|
640
|
-
import maplibregl from "maplibre-gl";
|
|
855
|
+
import * as maplibregl from "maplibre-gl";
|
|
641
856
|
import "maplibre-gl/dist/maplibre-gl.css";
|
|
642
857
|
import type { MahalMap as MahalMapInstance } from "mahal_map";
|
|
643
858
|
import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
@@ -884,6 +1099,12 @@ MahalMap.getLayers(map);
|
|
|
884
1099
|
MahalMap.onLayers(map, (state) => console.log(state.id, state.active));
|
|
885
1100
|
MahalMap.refreshLayers(map);
|
|
886
1101
|
|
|
1102
|
+
// Планы этажей
|
|
1103
|
+
MahalMap.getIndoorLevels(map);
|
|
1104
|
+
MahalMap.setIndoorLevel(map, 1);
|
|
1105
|
+
MahalMap.refreshIndoor(map);
|
|
1106
|
+
MahalMap.showPlace(map, 68.787, 38.573, 2, 18);
|
|
1107
|
+
|
|
887
1108
|
// Выделение зданий и клики
|
|
888
1109
|
MahalMap.onBuildingClick(map, (building) => console.log(building?.id));
|
|
889
1110
|
MahalMap.selectBuilding(map, 123456789);
|
|
@@ -916,39 +1137,43 @@ MahalMap.setZoom(map, 14);
|
|
|
916
1137
|
|
|
917
1138
|
Доступные функции карты в browser SDK:
|
|
918
1139
|
|
|
919
|
-
| Функция
|
|
920
|
-
|
|
|
921
|
-
| `create(options)`
|
|
922
|
-
| `createAsync(options)`
|
|
923
|
-
| `onReady(container, callback)`
|
|
924
|
-
| `getInstance(container)`
|
|
925
|
-
| `hasInstance(container)`
|
|
926
|
-
| `removeInstance(container)`
|
|
927
|
-
| `getMap(instance)`
|
|
928
|
-
| `getCamera(instance)`
|
|
929
|
-
| `setStyle(instance, theme)`
|
|
930
|
-
| `setLanguage(instance, lang)`
|
|
931
|
-
| `setCenter(instance, center)`
|
|
932
|
-
| `setZoom(instance, zoom)`
|
|
933
|
-
| `addMarker(instance, marker)`
|
|
934
|
-
| `getMaps3DLayer(instance)`
|
|
935
|
-
| `whenMaps3DReady(instance)`
|
|
936
|
-
| `toggle3DBuildings(instance, enabled)`
|
|
937
|
-
| `setLayer(instance, id, on, params?)`
|
|
938
|
-
| `getLayerState(instance, id)`
|
|
939
|
-
| `getLayers(instance)`
|
|
940
|
-
| `onLayers(instance, callback)`
|
|
941
|
-
| `refreshLayers(instance)`
|
|
942
|
-
| `
|
|
943
|
-
| `
|
|
944
|
-
| `
|
|
945
|
-
| `
|
|
946
|
-
| `
|
|
947
|
-
| `
|
|
948
|
-
| `
|
|
949
|
-
| `
|
|
950
|
-
| `
|
|
951
|
-
| `
|
|
1140
|
+
| Функция | Описание |
|
|
1141
|
+
| ---------------------------------------------- | --------------------------------------------------------------------- |
|
|
1142
|
+
| `create(options)` | Создает карту. Требует `apikey` в URL SDK скрипта. |
|
|
1143
|
+
| `createAsync(options)` | Создает карту после проверки подписки JSApi (только без Maps3D). |
|
|
1144
|
+
| `onReady(container, callback)` | Выполняет callback после загрузки карты. |
|
|
1145
|
+
| `getInstance(container)` | Возвращает инстанс карты. |
|
|
1146
|
+
| `hasInstance(container)` | Проверяет наличие инстанса. |
|
|
1147
|
+
| `removeInstance(container)` | Удаляет инстанс из реестра. |
|
|
1148
|
+
| `getMap(instance)` | Возвращает нативный MapLibre Map. |
|
|
1149
|
+
| `getCamera(instance)` | Возвращает CameraController. |
|
|
1150
|
+
| `setStyle(instance, theme)` | Переключает тему стандартного стиля. |
|
|
1151
|
+
| `setLanguage(instance, lang)` | Переключает язык стандартного стиля. |
|
|
1152
|
+
| `setCenter(instance, center)` | Меняет центр карты. |
|
|
1153
|
+
| `setZoom(instance, zoom)` | Меняет zoom карты. |
|
|
1154
|
+
| `addMarker(instance, marker)` | Добавляет маркер. |
|
|
1155
|
+
| `getMaps3DLayer(instance)` | Возвращает инстанс слоя Maps3D (`undefined`, если Maps3D не передан). |
|
|
1156
|
+
| `whenMaps3DReady(instance)` | Промис слоя Maps3D после `attach()` (готов `layer.buildings`). |
|
|
1157
|
+
| `toggle3DBuildings(instance, enabled)` | Вкл/выкл объёмные здания на лету. |
|
|
1158
|
+
| `setLayer(instance, id, on, params?)` | Включить/выключить слой платформы. |
|
|
1159
|
+
| `getLayerState(instance, id)` | Снимок состояния одного слоя. |
|
|
1160
|
+
| `getLayers(instance)` | Снимок всех слоёв. |
|
|
1161
|
+
| `onLayers(instance, callback)` | Подписка на изменения слоёв; возвращает отписку. |
|
|
1162
|
+
| `refreshLayers(instance)` | Пере-применить волю клиента ко всем слоям. |
|
|
1163
|
+
| `getIndoorLevels(instance)` | Этажи, найденные в текущем виде карты. |
|
|
1164
|
+
| `setIndoorLevel(instance, level)` | Переключить этаж (0 — первый наземный). |
|
|
1165
|
+
| `refreshIndoor(instance)` | Перечитать планы этажей. |
|
|
1166
|
+
| `showPlace(instance, lon, lat, level?, zoom?)` | Показать объект и открыть его этаж. |
|
|
1167
|
+
| `onBuildingClick(instance, callback)` | Клик по зданию. |
|
|
1168
|
+
| `selectBuilding(instance, id, style?)` | Выделить здание по `osm_id`. |
|
|
1169
|
+
| `clearSelection(instance)` | Снять выделение. |
|
|
1170
|
+
| `selectedBuilding(instance)` | Идентификатор выделенного здания или `null`. |
|
|
1171
|
+
| `setSelectionStyle(instance, style)` | Облик выделения. |
|
|
1172
|
+
| `onRoadClick(instance, callback)` | Клик по дороге. |
|
|
1173
|
+
| `roadAt(instance, point, tolPx?)` | Дорога под точкой холста. |
|
|
1174
|
+
| `destroy(instance)` | Полностью удаляет карту. |
|
|
1175
|
+
| `loadKeyFromScriptUrl()` | Читает `apikey` из URL SDK скрипта. |
|
|
1176
|
+
| `loadLanguageFromScriptUrl()` | Читает `lang` из URL SDK скрипта. |
|
|
952
1177
|
|
|
953
1178
|
## CameraController
|
|
954
1179
|
|
|
@@ -1179,19 +1404,19 @@ const measureTool = new MeasureTool(map, {
|
|
|
1179
1404
|
|
|
1180
1405
|
### Методы
|
|
1181
1406
|
|
|
1182
|
-
| Метод | Описание
|
|
1183
|
-
| ------------------------------- |
|
|
1184
|
-
| `start(mode?)` | Включает инструмент и начинает/продолжает рисование в указанном режиме.
|
|
1185
|
-
| `stop()` | Выключает инструмент, прячет активный бейдж. Сохраненные фигуры остаются на карте.
|
|
1186
|
-
| `setMode(mode)` | Переключает режим. Если фигура уже рисуется — её точки сохраняются, меняется только тип (линия ⇄ полигон), как в Яндекс.Картах.
|
|
1187
|
-
| `finishDraft()` | Завершает текущую фигуру (если валидна — от 2 точек для линии, от 3 для полигона) и начинает новую.
|
|
1188
|
-
| `removeShape(shapeId)` | Удаляет фигуру (черновик или уже сохраненную) целиком.
|
|
1189
|
-
| `removePoint(shapeId, pointId)` | Удаляет одну точку фигуры.
|
|
1190
|
-
| `clearAll()` | Удаляет все фигуры и черновик.
|
|
1191
|
-
| `getState()` | Возвращает текущий `MeasureState` (снимок, без подписки).
|
|
1407
|
+
| Метод | Описание |
|
|
1408
|
+
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1409
|
+
| `start(mode?)` | Включает инструмент и начинает/продолжает рисование в указанном режиме. |
|
|
1410
|
+
| `stop()` | Выключает инструмент, прячет активный бейдж. Сохраненные фигуры остаются на карте. |
|
|
1411
|
+
| `setMode(mode)` | Переключает режим. Если фигура уже рисуется — её точки сохраняются, меняется только тип (линия ⇄ полигон), как в Яндекс.Картах. |
|
|
1412
|
+
| `finishDraft()` | Завершает текущую фигуру (если валидна — от 2 точек для линии, от 3 для полигона) и начинает новую. |
|
|
1413
|
+
| `removeShape(shapeId)` | Удаляет фигуру (черновик или уже сохраненную) целиком. |
|
|
1414
|
+
| `removePoint(shapeId, pointId)` | Удаляет одну точку фигуры. |
|
|
1415
|
+
| `clearAll()` | Удаляет все фигуры и черновик. |
|
|
1416
|
+
| `getState()` | Возвращает текущий `MeasureState` (снимок, без подписки). |
|
|
1192
1417
|
| `setStyleOptions(style)` | Обновляет палитру (частично, `Partial<MeasureStyleOptions>`) без пересоздания инструмента: перекрашивает существующие слои и бейджи. Нужен при смене темы карты. |
|
|
1193
|
-
| `refresh()` | Пересоздает источники/слои и перерисовывает фигуры. Инструмент делает это сам после `setStyle()`; метод оставлен как страховка.
|
|
1194
|
-
| `destroy()` | Полностью снимает слои, обработчики и DOM-бейджи. Вызывать при размонтировании. Повторный вызов безопасен.
|
|
1418
|
+
| `refresh()` | Пересоздает источники/слои и перерисовывает фигуры. Инструмент делает это сам после `setStyle()`; метод оставлен как страховка. |
|
|
1419
|
+
| `destroy()` | Полностью снимает слои, обработчики и DOM-бейджи. Вызывать при размонтировании. Повторный вызов безопасен. |
|
|
1195
1420
|
|
|
1196
1421
|
### Смена стиля карты (тема, язык)
|
|
1197
1422
|
|
|
@@ -1244,7 +1469,13 @@ interface MeasureShape {
|
|
|
1244
1469
|
Сервисы работают независимо от карты: их можно вызывать без `MahalMap.create()`. Токен передаётся аргументом в каждый вызов — сохранённый через `keyUtils.saveKey()` map token для них не используется.
|
|
1245
1470
|
|
|
1246
1471
|
```ts
|
|
1247
|
-
import {
|
|
1472
|
+
import {
|
|
1473
|
+
Search,
|
|
1474
|
+
SearchPoi,
|
|
1475
|
+
SearchByLocation,
|
|
1476
|
+
CheckJSApi,
|
|
1477
|
+
Router,
|
|
1478
|
+
} from "mahal_map";
|
|
1248
1479
|
```
|
|
1249
1480
|
|
|
1250
1481
|
### `Search(text, token, additionalParam?)`
|
|
@@ -1259,13 +1490,13 @@ const results = await Search("Рудаки 33", token, {
|
|
|
1259
1490
|
});
|
|
1260
1491
|
```
|
|
1261
1492
|
|
|
1262
|
-
| Параметр
|
|
1263
|
-
|
|
|
1264
|
-
| `text`
|
|
1265
|
-
| `token`
|
|
1266
|
-
| `additionalParam.lat` / `.lng` | `string` | Точка для сортировки результатов по удалённости.
|
|
1267
|
-
| `additionalParam.limit`
|
|
1268
|
-
| `additionalParam.type`
|
|
1493
|
+
| Параметр | Тип | Описание |
|
|
1494
|
+
| ------------------------------ | -------- | --------------------------------------------------------------------------- |
|
|
1495
|
+
| `text` | `string` | Строка поиска. |
|
|
1496
|
+
| `token` | `string` | Токен сервиса. Обязателен, иначе `[MahalMap SDK] Search token is required`. |
|
|
1497
|
+
| `additionalParam.lat` / `.lng` | `string` | Точка для сортировки результатов по удалённости. |
|
|
1498
|
+
| `additionalParam.limit` | `number` | Максимум результатов. |
|
|
1499
|
+
| `additionalParam.type` | `string` | Фильтр по типу объекта. |
|
|
1269
1500
|
|
|
1270
1501
|
Возвращает `ISearchResponse[]`.
|
|
1271
1502
|
|
|
@@ -1274,7 +1505,11 @@ const results = await Search("Рудаки 33", token, {
|
|
|
1274
1505
|
Поиск POI (организации, объекты). Сигнатура и дебаунс те же, что у `Search`, таймер отдельный — параллельный ввод в двух полях не перебивает запросы друг друга.
|
|
1275
1506
|
|
|
1276
1507
|
```ts
|
|
1277
|
-
const places = await SearchPoi("кафе", token, {
|
|
1508
|
+
const places = await SearchPoi("кафе", token, {
|
|
1509
|
+
lat: "38.5598",
|
|
1510
|
+
lng: "68.7870",
|
|
1511
|
+
limit: 20,
|
|
1512
|
+
});
|
|
1278
1513
|
```
|
|
1279
1514
|
|
|
1280
1515
|
Возвращает `ISearchResponse[]`.
|
|
@@ -1291,12 +1526,12 @@ const res = await SearchByLocation({
|
|
|
1291
1526
|
});
|
|
1292
1527
|
```
|
|
1293
1528
|
|
|
1294
|
-
| Поле
|
|
1295
|
-
|
|
|
1296
|
-
| `lat`
|
|
1297
|
-
| `lng`
|
|
1298
|
-
| `token` | `string`
|
|
1299
|
-
| `type`
|
|
1529
|
+
| Поле | Тип | Обязательное |
|
|
1530
|
+
| ------- | ------------------ | ------------ |
|
|
1531
|
+
| `lat` | `string \| number` | да |
|
|
1532
|
+
| `lng` | `string \| number` | да |
|
|
1533
|
+
| `token` | `string` | да |
|
|
1534
|
+
| `type` | `string` | нет |
|
|
1300
1535
|
|
|
1301
1536
|
### `CheckJSApi(token)`
|
|
1302
1537
|
|
|
@@ -1329,11 +1564,11 @@ const routes = await Router(
|
|
|
1329
1564
|
);
|
|
1330
1565
|
```
|
|
1331
1566
|
|
|
1332
|
-
| Параметр
|
|
1333
|
-
|
|
|
1334
|
-
| `points`
|
|
1335
|
-
| `typeData` | `string`
|
|
1336
|
-
| `token`
|
|
1567
|
+
| Параметр | Тип | Описание |
|
|
1568
|
+
| ---------- | ------------ | ------------------------------------------------------------------------------------------------------------ |
|
|
1569
|
+
| `points` | `number[][]` | Точки в формате `[lng, lat]`. |
|
|
1570
|
+
| `typeData` | `string` | `"geojson"` — декодирует polyline в массив координат. Другое значение оставляет `geometry` строкой polyline. |
|
|
1571
|
+
| `token` | `string` | Токен сервиса. |
|
|
1337
1572
|
|
|
1338
1573
|
Возвращает `IRoute[]`.
|
|
1339
1574
|
|