mahal_map 1.7.2 → 2.0.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.
- package/README.md +475 -126
- package/dist/index.d.mts +286 -31
- package/dist/index.d.ts +286 -31
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7 -7
- package/dist/index.mjs.map +1 -1
- package/dist/mahal_map.sdk.js +1 -1
- package/package.json +73 -73
package/README.md
CHANGED
|
@@ -7,15 +7,52 @@ Mahal Map - JavaScript/TypeScript SDK для работы с картой Mahal
|
|
|
7
7
|
## Установка
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
npm install mahal_map maplibre-gl
|
|
10
|
+
npm install mahal_map maplibre-gl @grammaps/maps3d-web
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
`
|
|
13
|
+
Обе зависимости — `peerDependencies`, в бандл `mahal_map` они не входят. Библиотека их не импортирует: MapLibre и `Maps3D` приходят снаружи, аргументами `create()` либо через `window`.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
- `maplibre-gl` (3–6) — обязателен всегда.
|
|
16
|
+
- `@grammaps/maps3d-web` (>=0.5.0) — даёт стили, тайлы, объём, пробки, рельеф, планы этажей, клик по объектам. Помечен `optional`: без него карта поднимется на запасном векторном стиле, но 3D и слоёв платформы на ней не будет.
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
MapLibre можно не класть в свою сборку вовсе — платформа отдаёт согласованную версию вместе с веб-воркером:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
const maplibregl = await Maps3D.maplibre({ base: "https://navi.gram.tj" });
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Миграция с 1.x на 2.0
|
|
25
|
+
|
|
26
|
+
Собственных URL стилей у `mahal_map` больше нет — их целиком отдаёт `@grammaps/maps3d-web`.
|
|
27
|
+
|
|
28
|
+
| 1.x | 2.0 |
|
|
29
|
+
| ---------------------------------------------- | -------------------------------------------------------------- |
|
|
30
|
+
| `engine: "legacy"` (по умолчанию) | Удалён. Единственный путь — платформа через `Maps3D`. |
|
|
31
|
+
| `engine: "3d"` | Больше не нужен, опция игнорируется. |
|
|
32
|
+
| `autoAddVectorSource: true` | Удалён. Тот же векторный стиль применяется сам, когда нет `Maps3D`. |
|
|
33
|
+
| `preset: "standard-night"` | `theme: "dark"`, либо полный URL в `style`. |
|
|
34
|
+
| `preset: "road-urban-lab-v2"` | `theme: "light"`, либо полный URL в `style`. |
|
|
35
|
+
| `lang` менял URL стиля | Стиль не трогает — язык подписей приходит из самого стиля. |
|
|
36
|
+
| `layer.setBuildingsEnabled(...)` напрямую | `map.toggle3DBuildings(...)` или `map.setLayer("buildings", ...)`. |
|
|
37
|
+
|
|
38
|
+
`engine` и `autoAddVectorSource` оставлены в типах как `@deprecated`, чтобы не ломать компиляцию, но на поведение не влияют.
|
|
39
|
+
|
|
40
|
+
Что появилось: реестр слоёв (`setLayer`/`getLayers`/`onLayers`), выделение зданий, клик по дорогам, рельеф, планы этажей, перекрытия, семейства стилей `navigator`/`mobile` и автоматический `antialias`.
|
|
41
|
+
|
|
42
|
+
Минимальный диф:
|
|
43
|
+
|
|
44
|
+
```diff
|
|
45
|
+
const map = MahalMap.create(
|
|
46
|
+
{
|
|
47
|
+
container: "map",
|
|
48
|
+
- engine: "3d",
|
|
49
|
+
theme: "dark",
|
|
50
|
+
- preset: "standard-night",
|
|
51
|
+
enable3D: true,
|
|
52
|
+
},
|
|
53
|
+
maplibregl,
|
|
54
|
+
Maps3D,
|
|
55
|
+
);
|
|
19
56
|
```
|
|
20
57
|
|
|
21
58
|
## Быстрый старт через NPM
|
|
@@ -23,6 +60,7 @@ npm i mahal_map maplibre-gl @grammaps/maps3d-web
|
|
|
23
60
|
```ts
|
|
24
61
|
import maplibregl from "maplibre-gl";
|
|
25
62
|
import "maplibre-gl/dist/maplibre-gl.css";
|
|
63
|
+
import { Maps3D } from "@grammaps/maps3d-web";
|
|
26
64
|
import { MahalMap, keyUtils } from "mahal_map";
|
|
27
65
|
|
|
28
66
|
keyUtils.saveKey("YOUR_MAP_API_KEY");
|
|
@@ -30,11 +68,12 @@ keyUtils.saveKey("YOUR_MAP_API_KEY");
|
|
|
30
68
|
const map = MahalMap.create(
|
|
31
69
|
{
|
|
32
70
|
container: "map",
|
|
33
|
-
center: [
|
|
34
|
-
zoom:
|
|
71
|
+
center: [68.787, 38.573],
|
|
72
|
+
zoom: 16.6,
|
|
35
73
|
theme: "light",
|
|
36
74
|
},
|
|
37
75
|
maplibregl,
|
|
76
|
+
Maps3D,
|
|
38
77
|
);
|
|
39
78
|
```
|
|
40
79
|
|
|
@@ -44,6 +83,8 @@ const map = MahalMap.create(
|
|
|
44
83
|
<div id="map" style="width: 100%; height: 500px"></div>
|
|
45
84
|
```
|
|
46
85
|
|
|
86
|
+
`Maps3D` — третий, необязательный аргумент: не передан — SDK возьмёт его из `window.Maps3D`. Стиль, `transformRequest` с ключом, сглаживание и подключение 3D библиотека делает сама.
|
|
87
|
+
|
|
47
88
|
## Быстрый старт через Browser SDK
|
|
48
89
|
|
|
49
90
|
Сначала подключите MapLibre, затем `mahal_map.sdk.js`. Для browser SDK параметр `apikey` обязателен: без него карта не инициализируется.
|
|
@@ -99,7 +140,7 @@ const map = MahalMap.create(
|
|
|
99
140
|
`maps3dCtor` — импортированный конструктор `Maps3D` (третий, необязательный аргумент). Если не передан, SDK ищет его в `window.Maps3D`.
|
|
100
141
|
|
|
101
142
|
```ts
|
|
102
|
-
import type { IMaps3DLayerOptions } from "mahal_map";
|
|
143
|
+
import type { IMaps3DLayerOptions, Maps3DThemeName } from "mahal_map";
|
|
103
144
|
|
|
104
145
|
interface IMahalMapOptions {
|
|
105
146
|
container?: string | HTMLElement;
|
|
@@ -110,111 +151,130 @@ interface IMahalMapOptions {
|
|
|
110
151
|
zoom?: number;
|
|
111
152
|
pitch?: number;
|
|
112
153
|
bearing?: number;
|
|
113
|
-
autoAddVectorSource?: boolean;
|
|
114
|
-
engine?: "legacy" | "3d";
|
|
115
154
|
enable3D?: boolean;
|
|
116
155
|
base?: string;
|
|
117
|
-
|
|
118
|
-
|
|
156
|
+
family?: "default" | "navigator" | "mobile";
|
|
157
|
+
preset?: Maps3DThemeName | string;
|
|
158
|
+
antialias?: boolean;
|
|
159
|
+
maps3d?: Omit<IMaps3DLayerOptions, "apiKey" | "base">;
|
|
119
160
|
}
|
|
120
161
|
```
|
|
121
162
|
|
|
122
|
-
| Параметр
|
|
123
|
-
|
|
|
124
|
-
| `container`
|
|
125
|
-
| `style`
|
|
126
|
-
| `theme`
|
|
127
|
-
| `lang`
|
|
128
|
-
| `center`
|
|
129
|
-
| `zoom`
|
|
130
|
-
| `pitch`
|
|
131
|
-
| `bearing`
|
|
132
|
-
| `
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `maps3d`
|
|
138
|
-
|
|
139
|
-
###
|
|
140
|
-
|
|
141
|
-
|
|
163
|
+
| Параметр | Тип | Описание |
|
|
164
|
+
| ----------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
165
|
+
| `container` | `string \| HTMLElement` | ID контейнера или DOM-элемент. Не передан — берётся `"map"`. |
|
|
166
|
+
| `style` | `string` | Полный URL своего стиля. Задан — стиль зафиксирован, `setStyle()` его не меняет. |
|
|
167
|
+
| `theme` | `"dark" \| "light"` | Светлая/тёмная внутри выбранного `family`. По умолчанию `light`. |
|
|
168
|
+
| `lang` | `"tj" \| "ru"` | Язык для поиска и роутинга. На стиль не влияет — подписи приходят из самого стиля платформы. |
|
|
169
|
+
| `center` | `[number, number]` | Центр карты в формате `[lng, lat]`. |
|
|
170
|
+
| `zoom` | `number` | Начальный zoom. |
|
|
171
|
+
| `pitch` | `number` | Начальный наклон камеры. Не задан и 3D включено — авто `58`: при `pitch: 0` объём зданий не виден, камера смотрит строго сверху. |
|
|
172
|
+
| `bearing` | `number` | Начальный поворот камеры. |
|
|
173
|
+
| `enable3D` | `boolean` | Подключает Maps3D. По умолчанию `true`, когда `Maps3D` доступен. |
|
|
174
|
+
| `base` | `string` | Домен платформы. По умолчанию `https://navi.gram.tj`. |
|
|
175
|
+
| `family` | `"default" \| "navigator" \| "mobile"` | Семейство стилей. `theme` выбирает внутри него: `default` → `light`/`dark`, `navigator` → `navigator-light`/`navigator-dark`, `mobile` → `mobile-*`. |
|
|
176
|
+
| `preset` | `Maps3DThemeName \| string` | Явное имя темы платформы или полный URL стиля вместо пары `family` + `theme`. Задан — стиль зафиксирован. |
|
|
177
|
+
| `antialias` | `boolean` | Сглаживание сцены. По умолчанию `true` при включённом 3D: без него тонкая геометрия (перила, мачты, ряды сидений) на отдалении рассыпается в рябь. |
|
|
178
|
+
| `maps3d` | `object` | Опции Maps3D: `buildings`, `traffic`, `indoor`, `closures`, `places`, `minZoom`, `lodBias`, `memoryBudget`, `maskReplaced`, `typeReplacements`. |
|
|
179
|
+
|
|
180
|
+
### Стили и темы
|
|
181
|
+
|
|
182
|
+
Стили целиком приходят из `@grammaps/maps3d-web` — своего списка URL у `mahal_map` больше нет. Словарь тем один и тот же у SDK и у библиотеки:
|
|
183
|
+
|
|
184
|
+
| `family` | `theme: "light"` | `theme: "dark"` |
|
|
185
|
+
| ------------- | ------------------ | ----------------- |
|
|
186
|
+
| `"default"` | `light` | `dark` |
|
|
187
|
+
| `"navigator"` | `navigator-light` | `navigator-dark` |
|
|
188
|
+
| `"mobile"` | `mobile-light` | `mobile-dark` |
|
|
189
|
+
|
|
190
|
+
Имя темы уходит в `Maps3D.styleUrl()`, адрес строит сам SDK. Неизвестное имя — явная ошибка с префиксом `[MahalMap SDK]`, а не пустая карта.
|
|
142
191
|
|
|
143
192
|
```ts
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
import { Maps3D } from "@grammaps/maps3d-web";
|
|
147
|
-
import { MahalMap, keyUtils } from "mahal_map";
|
|
148
|
-
|
|
149
|
-
keyUtils.saveKey("YOUR_MAP_API_KEY");
|
|
193
|
+
// Навигаторная тёмная тема
|
|
194
|
+
MahalMap.create({ container: "map", family: "navigator", theme: "dark" }, maplibregl, Maps3D);
|
|
150
195
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
container: "map",
|
|
154
|
-
center: [68.78, 38.56],
|
|
155
|
-
zoom: 16.6,
|
|
156
|
-
pitch: 58,
|
|
157
|
-
theme: "dark",
|
|
158
|
-
engine: "3d",
|
|
159
|
-
enable3D: true,
|
|
160
|
-
},
|
|
161
|
-
maplibregl,
|
|
162
|
-
Maps3D,
|
|
163
|
-
);
|
|
196
|
+
// Смена темы внутри того же семейства
|
|
197
|
+
map.setStyle("light"); // → navigator-light
|
|
164
198
|
```
|
|
165
199
|
|
|
166
|
-
|
|
200
|
+
> **Миграция с 1.x.** Имена пресетов прежнего поколения (`road-urban-lab-v2`, `standard-night`) больше не подставляются по умолчанию — словарь тем теперь один, платформенный. Если старый стиль всё ещё нужен, передайте его полным URL:
|
|
201
|
+
>
|
|
202
|
+
> ```ts
|
|
203
|
+
> MahalMap.create(
|
|
204
|
+
> { container: "map", style: "https://navi.gram.tj/maps/standard-night.json" },
|
|
205
|
+
> maplibregl,
|
|
206
|
+
> Maps3D,
|
|
207
|
+
> );
|
|
208
|
+
> ```
|
|
167
209
|
|
|
168
|
-
|
|
210
|
+
### Без `@grammaps/maps3d-web`
|
|
169
211
|
|
|
170
|
-
|
|
171
|
-
const layer = map.getMaps3DLayer();
|
|
172
|
-
// или
|
|
173
|
-
MahalMap.getMaps3DLayer(map);
|
|
174
|
-
```
|
|
212
|
+
Библиотека не установлена и в `window.Maps3D` ничего нет — карта всё равно поднимется: используется запасной векторный стиль `mtile.gram.tj` с подписью `?token=`, в консоль уходит предупреждение. На такой карте нет объёма, объектов, пробок, рельефа и реестра слоёв; `setStyle()` и `setLanguage()` стиль не меняют, методы реестра возвращают пустые значения (`false`, `null`, `[]`).
|
|
175
213
|
|
|
176
|
-
|
|
214
|
+
Этот путь — единственный, где ещё проверяется подписка JSApi: `createAsync()` не создаст карту, если подписки нет. С переданным `Maps3D` проверка пропускается — доступ гейтит сама платформа по `?key=`.
|
|
177
215
|
|
|
178
216
|
### Опции `maps3d` (расширенные)
|
|
179
217
|
|
|
180
|
-
Передаются в `MahalMap.create({ maps3d: {...} })`
|
|
181
|
-
|
|
182
|
-
| Опция | Тип | По умолч. | Описание |
|
|
183
|
-
| ------------------ | ------------------------------------------------ | --------- | ------------------------------------------------------------------------- |
|
|
184
|
-
| `traffic` | `boolean \| { raster?, rasterMaxZoom?, graph? }` | `false` | Слой пробок. `raster: true` — картинкой с сервера вместо векторного слоя. |
|
|
185
|
-
| `minZoom` | `number` | `16` | Зум появления детальных 3D. |
|
|
186
|
-
| `lodBias` | `number` | `1` | `0` — всегда lod0 (детальный), `1` — lod1 на дальних зумах. |
|
|
187
|
-
| `memoryBudget` | `number` | `30` | Сколько моделей держать в сцене одновременно. |
|
|
188
|
-
| `maskReplaced` | `boolean` | `true` | Прятать заменённые OSM-объекты (`anchor=replace`). |
|
|
189
|
-
| `typeReplacements` | `boolean` | `true` | Рисовать замены по типу (`natural=tree` → 3D-дерево и т.п.). |
|
|
218
|
+
Передаются в `MahalMap.create({ maps3d: {...} })` и уходят в `Maps3D` как есть:
|
|
190
219
|
|
|
191
|
-
|
|
220
|
+
| Опция | Тип | По умолч. | Описание |
|
|
221
|
+
| ------------------ | ----------------------------------------------------- | --------- | -------------------------------------------------------------------- |
|
|
222
|
+
| `buildings` | `boolean \| { detail?: footprint\|volume\|roofs\|facade }` | `true` | Объёмные здания; объектом — их облик. |
|
|
223
|
+
| `traffic` | `boolean \| { raster?, rasterMaxZoom?, graph?, opacity?, arrows? }` | `false` | Слой пробок. `raster: true` — картинкой вместо векторного слоя. |
|
|
224
|
+
| `indoor` | `boolean \| { level? }` | `false` | Планы этажей. |
|
|
225
|
+
| `closures` | `boolean \| object` | `false` | Перекрытия дорог. |
|
|
226
|
+
| `places` | `object` | — | Парковки, заправки, зарядки: `highlight`, `paid`, `free`, `unknown`. |
|
|
227
|
+
| `minZoom` | `number` | `16` | Зум появления объёма. |
|
|
228
|
+
| `lodBias` | `number` | `1` | `0` — всегда детальная геометрия, `1` — упрощённая вдали. |
|
|
229
|
+
| `memoryBudget` | `number` | `30` | Сколько 3D-моделей держать в памяти. |
|
|
230
|
+
| `maskReplaced` | `boolean` | `true` | Прятать заменённые OSM-объекты (`anchor=replace`). |
|
|
231
|
+
| `typeReplacements` | `boolean` | `true` | Рисовать замены по типу (`natural=tree` → 3D-дерево и т.п.). |
|
|
192
232
|
|
|
193
|
-
|
|
233
|
+
`apiKey` и `base` в `maps3d` передавать не нужно — их подставляет сам `MahalMap` из сохранённого ключа и `options.base`.
|
|
194
234
|
|
|
195
|
-
|
|
235
|
+
### Реестр слоёв
|
|
196
236
|
|
|
197
|
-
|
|
237
|
+
Единая дверь ко всем слоям платформы. Состояние слоя — три независимых поля: `wanted` (чего хочет приложение), `available` (что позволяют стиль и данные), `active` (что нарисовано сейчас).
|
|
198
238
|
|
|
199
239
|
```ts
|
|
200
|
-
|
|
201
|
-
|
|
240
|
+
map.setLayer("terrain", true, { mode: "on" });
|
|
241
|
+
map.setLayer("traffic", true);
|
|
242
|
+
map.setLayer("indoor", true, { level: 2 });
|
|
202
243
|
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
);
|
|
244
|
+
const unsubscribe = map.onLayers((state) => {
|
|
245
|
+
console.log(state.id, state.wanted, state.available, state.active);
|
|
246
|
+
});
|
|
207
247
|
|
|
208
|
-
|
|
209
|
-
|
|
248
|
+
map.getLayerState("terrain"); // снимок одного слоя или null
|
|
249
|
+
map.getLayers(); // снимок всех — по нему рисуется панель слоёв
|
|
210
250
|
```
|
|
211
251
|
|
|
212
|
-
|
|
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` |
|
|
213
263
|
|
|
214
|
-
|
|
264
|
+
Слой может быть включён и при этом не нарисован: рельеф в режиме `auto` появляется на обзорных зумах, перекрытия требуют своего тайлсета, планы этажей — данных по зданию. Рельеф в режиме `on` заметно дороже по трафику и времени кадра.
|
|
265
|
+
|
|
266
|
+
Парковки, заправки и зарядки `Maps3D` рисует сам, забирая эти классы у POI-слоёв стиля, — поэтому выключение слоя убирает объекты с карты полностью, а не оставляет значок стиля.
|
|
267
|
+
|
|
268
|
+
`setLayer()` возвращает `false`, если такого слоя в подключённой сборке Maps3D нет (или Maps3D не передан вовсе). После полной смены стиля волю клиента возвращает `map.refreshLayers()` — при `setStyle()` библиотека вызывает его сама.
|
|
269
|
+
|
|
270
|
+
### 3D-здания
|
|
271
|
+
|
|
272
|
+
`Maps3D` рисует процедурные 3D-здания (three.js) вместо плоской `fill-extrusion` стиля: фаска кромок, вертикальный градиент и базовый цвет берутся из стиля, окна — из `metadata` темы. Слой создаётся и подключается автоматически (`enable3D` по умолчанию `true`) — вручную поднимать `new Maps3D(...)` не нужно.
|
|
273
|
+
|
|
274
|
+
Тонкая настройка облика — через сам слой, после готовности:
|
|
215
275
|
|
|
216
276
|
```ts
|
|
217
|
-
const layer = map.
|
|
277
|
+
const layer = await map.whenMaps3DReady();
|
|
218
278
|
|
|
219
279
|
const b = layer?.buildings;
|
|
220
280
|
b?.setWindowStyle(7); // тип окна 0..9 (сетка, лента, curtain wall, ...)
|
|
@@ -227,16 +287,59 @@ b?.setSunIntensity(3.2);
|
|
|
227
287
|
b?.setAmbient(0.76);
|
|
228
288
|
b?.setSky(0.91);
|
|
229
289
|
b?.setExposure(1.5);
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Тема (окна/свет) приходит из `metadata` стиля и применяется автоматически при смене стиля — пересоздавать слой не нужно. Ручные сеттеры её перебивают.
|
|
293
|
+
|
|
294
|
+
**Ручной `Maps3D.enhance(...)` — отдельный сценарий.** Карту при этом создавайте с `enable3D: false`: второй экземпляр на занятой карте `Maps3D` отклоняет.
|
|
295
|
+
|
|
296
|
+
```ts
|
|
297
|
+
const map = MahalMap.create(
|
|
298
|
+
{ container: "map", enable3D: false },
|
|
299
|
+
maplibregl,
|
|
300
|
+
Maps3D,
|
|
301
|
+
);
|
|
302
|
+
|
|
303
|
+
const maps3d = Maps3D.enhance(map.getMap(), {
|
|
304
|
+
apiKey: "YOUR_MAP_API_KEY",
|
|
305
|
+
base: "https://navi.gram.tj",
|
|
306
|
+
});
|
|
307
|
+
await maps3d.ready; // enhance() ждёт нативную карту MapLibre, не обёртку MahalMap
|
|
308
|
+
```
|
|
230
309
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
310
|
+
### Выделение зданий и клик по дорогам
|
|
311
|
+
|
|
312
|
+
Клик по зданию и клик по дороге приходят независимо: одна точка может попасть и туда, и туда — что важнее, решает приложение.
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
map.setSelectionStyle({ color: "#e23b2f", opacity: 0.55, durationMs: 300 });
|
|
316
|
+
|
|
317
|
+
map.onBuildingClick((building) => {
|
|
318
|
+
if (!building) return;
|
|
319
|
+
// SDK уже подсветил его
|
|
320
|
+
console.log(building.props?.osm_id, building.height);
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
map.onRoadClick((road) => {
|
|
324
|
+
if (!road) return;
|
|
325
|
+
console.log(road.nameRu ?? road.name, road.class);
|
|
234
326
|
});
|
|
327
|
+
|
|
328
|
+
// Выделить здание по osm_id — например, после поиска
|
|
329
|
+
map.selectBuilding(123456789); // false, если здания нет в загруженных данных
|
|
330
|
+
map.selectedBuilding(); // текущий id или null
|
|
331
|
+
map.clearSelection();
|
|
332
|
+
|
|
333
|
+
// Дорога под точкой холста, допуск по умолчанию 12 px
|
|
334
|
+
map.roadAt({ x: 320, y: 240 });
|
|
335
|
+
map.roadsNamed; // есть ли в текущем стиле названия дорог
|
|
235
336
|
```
|
|
236
337
|
|
|
338
|
+
Подписываться можно сразу после `create()`, до готовности карты.
|
|
339
|
+
|
|
237
340
|
#### Вкл/выкл 3D-здания на лету
|
|
238
341
|
|
|
239
|
-
Переключение
|
|
342
|
+
Переключение объём ⇄ штатные здания стиля, без пересоздания карты. Умеет поднять слой, если его не было (`enable3D: false` при создании):
|
|
240
343
|
|
|
241
344
|
```ts
|
|
242
345
|
const map = MahalMap.getInstance("map");
|
|
@@ -248,11 +351,11 @@ map.toggle3DBuildings(true); // вкл обратно
|
|
|
248
351
|
MahalMap.toggle3DBuildings(map, false);
|
|
249
352
|
```
|
|
250
353
|
|
|
251
|
-
|
|
354
|
+
Под капотом это `setLayer("buildings", enabled)`. Штатные здания стиля прячет и возвращает сам `Maps3D` — `mahal_map` их видимость не трогает, поэтому спорить за один слой некому. Эквивалентная запись: `map.setLayer("buildings", false)`.
|
|
252
355
|
|
|
253
356
|
#### `map.whenMaps3DReady()`
|
|
254
357
|
|
|
255
|
-
|
|
358
|
+
Подключение слоя асинхронное: сразу после `create()` слой уже есть, но `layer.buildings` (окна, свет, кромки) появляется только после него. Чтобы не гадать — дождитесь готовности:
|
|
256
359
|
|
|
257
360
|
```ts
|
|
258
361
|
const layer = await map.whenMaps3DReady();
|
|
@@ -260,7 +363,7 @@ const layer = await map.whenMaps3DReady();
|
|
|
260
363
|
layer?.buildings?.setWindowStyle(4);
|
|
261
364
|
```
|
|
262
365
|
|
|
263
|
-
Промис резолвится в `undefined`, если
|
|
366
|
+
Промис резолвится в `undefined`, если `Maps3D` не передан, слой выключен (`enable3D: false`) или подключение упало — ошибка при этом уходит в `console.error`, а карта остаётся живой на штатных зданиях стиля.
|
|
264
367
|
|
|
265
368
|
### Подключение и выключение 3D-слоя: полный пример (Vue 3)
|
|
266
369
|
|
|
@@ -300,13 +403,12 @@ onMounted(async () => {
|
|
|
300
403
|
const map = MahalMap.create(
|
|
301
404
|
{
|
|
302
405
|
container: "map",
|
|
303
|
-
|
|
304
|
-
theme: "dark", // preset standard-night; "light" → road-urban-lab-v2
|
|
406
|
+
theme: "dark", // тема dark; "light" → тема light
|
|
305
407
|
center: [68.787, 38.573],
|
|
306
408
|
zoom: 16.6,
|
|
307
|
-
pitch: 58, // без наклона
|
|
409
|
+
pitch: 58, // без наклона объём не виден
|
|
308
410
|
bearing: -20,
|
|
309
|
-
enable3D: true, // значение по
|
|
411
|
+
enable3D: true, // значение по умолчанию, когда Maps3D передан
|
|
310
412
|
maps3d: { minZoom: 16, lodBias: 0 },
|
|
311
413
|
},
|
|
312
414
|
maplibregl,
|
|
@@ -378,14 +480,15 @@ onBeforeUnmount(() => {
|
|
|
378
480
|
|
|
379
481
|
Что библиотека делает за вас против ручного подключения `@grammaps/maps3d-web`:
|
|
380
482
|
|
|
381
|
-
| Ручной код
|
|
382
|
-
|
|
|
383
|
-
|
|
|
384
|
-
| `
|
|
385
|
-
| `
|
|
386
|
-
| `
|
|
387
|
-
|
|
|
388
|
-
| `
|
|
483
|
+
| Ручной код | Через `mahal_map` |
|
|
484
|
+
| --------------------------------------------------- | -------------------------------------------------------------- |
|
|
485
|
+
| `...Maps3D.mapOptions({ base, apiKey, style })` | `theme` + `family` (или `preset` / `style` / `base` явно) |
|
|
486
|
+
| `antialias: true` не забыть | ставится сам при включённом 3D |
|
|
487
|
+
| `Maps3D.enhance(map, opts); await maps3d.ready` | `enable3D: true` + `maps3d: {...}`, `await map.whenMaps3DReady()` |
|
|
488
|
+
| `map.setStyle(Maps3D.styleUrl("dark", base))` | `map.setStyle("dark")` — внутри выбранного семейства |
|
|
489
|
+
| `maps3d.refreshLayers()` после смены стиля | вызывается сам на `style.load` |
|
|
490
|
+
| `maps3d.destroy(); map.remove()` | `map.destroy()` |
|
|
491
|
+
| ключ руками в каждый вызов | один `keyUtils.saveKey()` на всё |
|
|
389
492
|
|
|
390
493
|
#### То же самое без сборщика (browser SDK)
|
|
391
494
|
|
|
@@ -401,7 +504,6 @@ onBeforeUnmount(() => {
|
|
|
401
504
|
// Maps3D берётся из window.Maps3D — третий аргумент передавать не нужно.
|
|
402
505
|
const map = MahalMap.create({
|
|
403
506
|
container: "map",
|
|
404
|
-
engine: "3d",
|
|
405
507
|
theme: "dark",
|
|
406
508
|
center: [68.787, 38.573],
|
|
407
509
|
zoom: 16.6,
|
|
@@ -426,30 +528,39 @@ onBeforeUnmount(() => {
|
|
|
426
528
|
|
|
427
529
|
### Пробки
|
|
428
530
|
|
|
531
|
+
Через реестр слоёв:
|
|
532
|
+
|
|
429
533
|
```ts
|
|
430
|
-
|
|
534
|
+
map.setLayer("traffic", true);
|
|
535
|
+
map.setLayer("trafficRaster", true); // растровый вариант, без клика по дороге
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
Тонкие настройки — через сам слой:
|
|
431
539
|
|
|
432
|
-
|
|
433
|
-
layer
|
|
434
|
-
layer?.setTrafficClicks(true); // попап скорости по клику
|
|
435
|
-
layer?.refreshTraffic();
|
|
540
|
+
```ts
|
|
541
|
+
const layer = map.getMaps3DLayer();
|
|
436
542
|
|
|
437
|
-
|
|
438
|
-
layer?.
|
|
543
|
+
layer?.setTrafficOpacity?.(0.85);
|
|
544
|
+
layer?.setTrafficClicks?.(true); // попап скорости по клику
|
|
545
|
+
layer?.setTrafficGraph?.("yandex"); // osm | yandex | gis2 | mahal
|
|
546
|
+
layer?.refreshTraffic?.();
|
|
439
547
|
```
|
|
440
548
|
|
|
549
|
+
Либо сразу при создании карты: `maps3d: { traffic: { raster: true, opacity: 0.85 } }`.
|
|
550
|
+
|
|
441
551
|
### Жизненный цикл слоя
|
|
442
552
|
|
|
443
553
|
```ts
|
|
444
554
|
const layer = map.getMaps3DLayer();
|
|
445
555
|
|
|
446
|
-
layer?.setMinZoom(15);
|
|
447
|
-
layer?.setObjectsLight({ sun: 1.8, ambient: 0.45, sky: 1.1, exposure: 1.15 });
|
|
448
|
-
await layer?.refresh(); // перечитать
|
|
449
|
-
await layer?.clearCache(); // сбросить IndexedDB-кеш
|
|
556
|
+
layer?.setMinZoom?.(15);
|
|
557
|
+
layer?.setObjectsLight?.({ sun: 1.8, ambient: 0.45, sky: 1.1, exposure: 1.15 });
|
|
558
|
+
await layer?.refresh?.(); // перечитать объекты в кадре
|
|
559
|
+
await layer?.clearCache?.(); // сбросить IndexedDB-кеш моделей
|
|
560
|
+
layer?.diagnostics?.(); // рельеф, потеря контекста WebGL, счётчики зданий
|
|
450
561
|
```
|
|
451
562
|
|
|
452
|
-
Для полной остановки карты используйте только `map.destroy()` / `MahalMap.destroy(map)` — они сами вызывают `destroy()`/`remove()` у Maps3D слоя. **Не вызывайте `layer.destroy()`/`layer.remove()` напрямую**: `MahalMap` не узнает об этом и продолжит считать слой активным (внутренний `maps3dLayer
|
|
563
|
+
Для полной остановки карты используйте только `map.destroy()` / `MahalMap.destroy(map)` — они сами вызывают `destroy()`/`remove()` у Maps3D слоя. **Не вызывайте `layer.destroy()`/`layer.remove()` напрямую**: `MahalMap` не узнает об этом и продолжит считать слой активным (внутренний `maps3dLayer` и `buildingsEnabled` разойдутся с реальностью). Нужно временно выключить только 3D-здания — используйте `map.toggle3DBuildings(false)` (см. выше).
|
|
453
564
|
|
|
454
565
|
## MahalMap
|
|
455
566
|
|
|
@@ -474,6 +585,114 @@ const map = MahalMap.create(
|
|
|
474
585
|
|
|
475
586
|
В NPM-версии второй аргумент `maplibreObject` рекомендуется передавать явно. В browser SDK он берется из `window.maplibregl`.
|
|
476
587
|
|
|
588
|
+
### `MahalMap.createAsync(options, maplibreObject?, maps3dCtor?)`
|
|
589
|
+
|
|
590
|
+
Асинхронный вариант `create()`. Перед созданием карты проверяет подписку JSApi по map token и, если подписки нет, карту не создаёт вообще: MapLibre-инстанс не строится, промис отклоняется с ошибкой.
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
try {
|
|
594
|
+
const map = await MahalMap.createAsync(
|
|
595
|
+
{
|
|
596
|
+
container: "map",
|
|
597
|
+
center: [69.624024, 40.279687],
|
|
598
|
+
zoom: 12,
|
|
599
|
+
theme: "light",
|
|
600
|
+
},
|
|
601
|
+
maplibregl,
|
|
602
|
+
);
|
|
603
|
+
} catch (error) {
|
|
604
|
+
// подписки нет — показать своё сообщение вместо карты
|
|
605
|
+
console.error(error);
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
Правила проверки:
|
|
610
|
+
|
|
611
|
+
| Условие | Поведение |
|
|
612
|
+
| ------- | --------- |
|
|
613
|
+
| `Maps3D` не передан, сервис ответил `success: true` | Карта создаётся на запасном стиле. |
|
|
614
|
+
| `Maps3D` не передан, сервис ответил `success: false` | Карта **не** создаётся, промис отклоняется: `[MahalMap SDK] JSApi subscription is not active for this key: <message>`. |
|
|
615
|
+
| `Maps3D` не передан, проверка не дошла (сеть, CORS, таймаут) | Fail-open: `console.warn` и карта создаётся. Падение сервиса проверки не гасит карты. |
|
|
616
|
+
| `Maps3D` передан | Проверка **пропускается**, запрос не отправляется. |
|
|
617
|
+
| Map token не сохранён | Проверка пропускается, дальше срабатывает обычная ошибка про `apikey`. |
|
|
618
|
+
|
|
619
|
+
С переданным `Maps3D` вызов `createAsync()` ведёт себя ровно как `create()` — доступ к платформе контролируется параметром `?key=` на её стороне, отдельная подписка JSApi к ней отношения не имеет.
|
|
620
|
+
|
|
621
|
+
Синхронный `MahalMap.create()` проверку не выполняет и работает как раньше.
|
|
622
|
+
|
|
623
|
+
### Vue / Nuxt (ClientOnly, container как ref элемента)
|
|
624
|
+
|
|
625
|
+
`container` принимает и `id` строкой, и сам DOM-элемент. Ниже рабочий вариант с проверкой подписки: карта строится только после `createAsync()`, поэтому при отсутствии подписки в контейнере не останется пустой карты.
|
|
626
|
+
|
|
627
|
+
```vue
|
|
628
|
+
<template>
|
|
629
|
+
<ClientOnly>
|
|
630
|
+
<div class="overflow-hidden rounded-2xl border">
|
|
631
|
+
<div ref="mapElement" class="h-[360px] w-full" />
|
|
632
|
+
</div>
|
|
633
|
+
<template #fallback>
|
|
634
|
+
<div class="flex h-[360px] items-center justify-center">{{ loadingLabel }}</div>
|
|
635
|
+
</template>
|
|
636
|
+
</ClientOnly>
|
|
637
|
+
</template>
|
|
638
|
+
|
|
639
|
+
<script setup lang="ts">
|
|
640
|
+
import maplibregl from "maplibre-gl";
|
|
641
|
+
import "maplibre-gl/dist/maplibre-gl.css";
|
|
642
|
+
import type { MahalMap as MahalMapInstance } from "mahal_map";
|
|
643
|
+
import { onBeforeUnmount, onMounted, ref } from "vue";
|
|
644
|
+
|
|
645
|
+
const DUSHANBE_CENTER: [number, number] = [68.759965, 38.572419];
|
|
646
|
+
|
|
647
|
+
const mapElement = ref<HTMLElement | null>(null);
|
|
648
|
+
let map: MahalMapInstance | null = null;
|
|
649
|
+
// onMounted асинхронный: компонент может размонтироваться, пока идёт проверка подписки.
|
|
650
|
+
// Без флага карта создастся уже после unmount и останется висеть в памяти.
|
|
651
|
+
let disposed = false;
|
|
652
|
+
|
|
653
|
+
onMounted(async () => {
|
|
654
|
+
const { MahalMap, keyUtils } = await import("mahal_map");
|
|
655
|
+
|
|
656
|
+
keyUtils.saveKey(import.meta.env.VITE_MAHAL_API_KEY_TILE);
|
|
657
|
+
|
|
658
|
+
try {
|
|
659
|
+
const instance = await MahalMap.createAsync(
|
|
660
|
+
{
|
|
661
|
+
container: mapElement.value,
|
|
662
|
+
center: DUSHANBE_CENTER,
|
|
663
|
+
zoom: 11,
|
|
664
|
+
},
|
|
665
|
+
maplibregl,
|
|
666
|
+
);
|
|
667
|
+
|
|
668
|
+
if (disposed) {
|
|
669
|
+
instance.destroy();
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
map = instance;
|
|
674
|
+
} catch (error) {
|
|
675
|
+
// подписки JSApi нет — показать своё сообщение вместо карты
|
|
676
|
+
console.error(error);
|
|
677
|
+
}
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
onBeforeUnmount(() => {
|
|
681
|
+
disposed = true;
|
|
682
|
+
map?.destroy();
|
|
683
|
+
map = null;
|
|
684
|
+
});
|
|
685
|
+
</script>
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
Замечания по этому паттерну:
|
|
689
|
+
|
|
690
|
+
- Импорт `mahal_map` внутри `onMounted` обязателен в SSR-окружении: пакет работает с `window`/`document`.
|
|
691
|
+
- `ClientOnly` (Nuxt) или эквивалент нужен по той же причине.
|
|
692
|
+
- Для карты с `container` в виде элемента инстанс регистрируется под ключом по умолчанию `"map"`. Для нескольких карт на странице передавайте `container` строкой с разными `id`, иначе `getInstance()` вернёт не тот инстанс.
|
|
693
|
+
- `map.destroy()` снимает карту, логотип и запись из реестра инстансов.
|
|
694
|
+
- Синхронный `MahalMap.create()` в этом же коде работает без изменений — если проверка подписки не нужна, замените `await MahalMap.createAsync(...)` на `MahalMap.create(...)`.
|
|
695
|
+
|
|
477
696
|
### `MahalMap.onReady(container, callback)`
|
|
478
697
|
|
|
479
698
|
Вызывает `callback`, когда карта создана и MapLibre завершил загрузку.
|
|
@@ -557,27 +776,27 @@ camera.flyTo({
|
|
|
557
776
|
|
|
558
777
|
### `map.setStyle(theme)`
|
|
559
778
|
|
|
560
|
-
Переключает
|
|
779
|
+
Переключает светлую/тёмную тему внутри выбранного `family`.
|
|
561
780
|
|
|
562
781
|
```ts
|
|
563
|
-
map.setStyle("dark");
|
|
564
|
-
map.setStyle("light");
|
|
782
|
+
map.setStyle("dark"); // family: "navigator" → navigator-dark
|
|
783
|
+
map.setStyle("light"); // → navigator-light
|
|
565
784
|
```
|
|
566
785
|
|
|
567
|
-
|
|
786
|
+
Адрес стиля строит `Maps3D.styleUrl()`. После загрузки нового стиля библиотека сама зовёт `refreshLayers()` — состояние слоёв переживает смену темы.
|
|
568
787
|
|
|
569
|
-
Метод не
|
|
788
|
+
Метод ничего не делает, если карта создана с явным `style` или `preset` (стиль зафиксирован), либо если `Maps3D` не передан — у запасного стиля вариантов по теме нет.
|
|
570
789
|
|
|
571
790
|
### `map.setLanguage(lang)`
|
|
572
791
|
|
|
573
|
-
|
|
792
|
+
Запоминает язык для поиска и роутинга.
|
|
574
793
|
|
|
575
794
|
```ts
|
|
576
795
|
map.setLanguage("ru");
|
|
577
796
|
map.setLanguage("tj");
|
|
578
797
|
```
|
|
579
798
|
|
|
580
|
-
|
|
799
|
+
Стиль метод не трогает: подписи приходят из самого стиля платформы, отдельных URL по языкам больше нет.
|
|
581
800
|
|
|
582
801
|
### `map.setCenter(center)`
|
|
583
802
|
|
|
@@ -657,6 +876,23 @@ MahalMap.addMarker(map, marker);
|
|
|
657
876
|
MahalMap.getMaps3DLayer(map);
|
|
658
877
|
MahalMap.whenMaps3DReady(map);
|
|
659
878
|
MahalMap.toggle3DBuildings(map, false);
|
|
879
|
+
|
|
880
|
+
// Реестр слоёв
|
|
881
|
+
MahalMap.setLayer(map, "terrain", true, { mode: "on" });
|
|
882
|
+
MahalMap.getLayerState(map, "terrain");
|
|
883
|
+
MahalMap.getLayers(map);
|
|
884
|
+
MahalMap.onLayers(map, (state) => console.log(state.id, state.active));
|
|
885
|
+
MahalMap.refreshLayers(map);
|
|
886
|
+
|
|
887
|
+
// Выделение зданий и клики
|
|
888
|
+
MahalMap.onBuildingClick(map, (building) => console.log(building?.id));
|
|
889
|
+
MahalMap.selectBuilding(map, 123456789);
|
|
890
|
+
MahalMap.selectedBuilding(map);
|
|
891
|
+
MahalMap.setSelectionStyle(map, { color: "#e23b2f" });
|
|
892
|
+
MahalMap.clearSelection(map);
|
|
893
|
+
MahalMap.onRoadClick(map, (road) => console.log(road?.name));
|
|
894
|
+
MahalMap.roadAt(map, { x: 320, y: 240 });
|
|
895
|
+
|
|
660
896
|
MahalMap.destroy(map);
|
|
661
897
|
```
|
|
662
898
|
|
|
@@ -683,6 +919,7 @@ MahalMap.setZoom(map, 14);
|
|
|
683
919
|
| Функция | Описание |
|
|
684
920
|
| -------------------------------------- | ------------------------------------------------------------- |
|
|
685
921
|
| `create(options)` | Создает карту. Требует `apikey` в URL SDK скрипта. |
|
|
922
|
+
| `createAsync(options)` | Создает карту после проверки подписки JSApi (только без Maps3D). |
|
|
686
923
|
| `onReady(container, callback)` | Выполняет callback после загрузки карты. |
|
|
687
924
|
| `getInstance(container)` | Возвращает инстанс карты. |
|
|
688
925
|
| `hasInstance(container)` | Проверяет наличие инстанса. |
|
|
@@ -694,9 +931,21 @@ MahalMap.setZoom(map, 14);
|
|
|
694
931
|
| `setCenter(instance, center)` | Меняет центр карты. |
|
|
695
932
|
| `setZoom(instance, zoom)` | Меняет zoom карты. |
|
|
696
933
|
| `addMarker(instance, marker)` | Добавляет маркер. |
|
|
697
|
-
| `getMaps3DLayer(instance)` | Возвращает инстанс слоя Maps3D (
|
|
934
|
+
| `getMaps3DLayer(instance)` | Возвращает инстанс слоя Maps3D (`undefined`, если Maps3D не передан). |
|
|
698
935
|
| `whenMaps3DReady(instance)` | Промис слоя Maps3D после `attach()` (готов `layer.buildings`). |
|
|
699
|
-
| `toggle3DBuildings(instance, enabled)` | Вкл/выкл
|
|
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
|
+
| `onBuildingClick(instance, callback)` | Клик по зданию. |
|
|
943
|
+
| `selectBuilding(instance, id, style?)` | Выделить здание по `osm_id`. |
|
|
944
|
+
| `clearSelection(instance)` | Снять выделение. |
|
|
945
|
+
| `selectedBuilding(instance)` | Идентификатор выделенного здания или `null`. |
|
|
946
|
+
| `setSelectionStyle(instance, style)` | Облик выделения. |
|
|
947
|
+
| `onRoadClick(instance, callback)` | Клик по дороге. |
|
|
948
|
+
| `roadAt(instance, point, tolPx?)` | Дорога под точкой холста. |
|
|
700
949
|
| `destroy(instance)` | Полностью удаляет карту. |
|
|
701
950
|
| `loadKeyFromScriptUrl()` | Читает `apikey` из URL SDK скрипта. |
|
|
702
951
|
| `loadLanguageFromScriptUrl()` | Читает `lang` из URL SDK скрипта. |
|
|
@@ -838,7 +1087,9 @@ const map = MahalMap.create(
|
|
|
838
1087
|
);
|
|
839
1088
|
```
|
|
840
1089
|
|
|
841
|
-
|
|
1090
|
+
Стиль при этом считается зафиксированным: `setStyle()` и `setLanguage()` его не подменяют.
|
|
1091
|
+
|
|
1092
|
+
С переданным `Maps3D` URL всё равно проходит через `Maps3D.mapOptions()`, поэтому `transformRequest` с ключом на месте — тайлы и шрифты платформы внутри своего стиля продолжают работать.
|
|
842
1093
|
|
|
843
1094
|
## Жизненный цикл
|
|
844
1095
|
|
|
@@ -988,6 +1239,104 @@ interface MeasureShape {
|
|
|
988
1239
|
}
|
|
989
1240
|
```
|
|
990
1241
|
|
|
1242
|
+
## Сервисы поиска и маршрутов
|
|
1243
|
+
|
|
1244
|
+
Сервисы работают независимо от карты: их можно вызывать без `MahalMap.create()`. Токен передаётся аргументом в каждый вызов — сохранённый через `keyUtils.saveKey()` map token для них не используется.
|
|
1245
|
+
|
|
1246
|
+
```ts
|
|
1247
|
+
import { Search, SearchPoi, SearchByLocation, CheckJSApi, Router } from "mahal_map";
|
|
1248
|
+
```
|
|
1249
|
+
|
|
1250
|
+
### `Search(text, token, additionalParam?)`
|
|
1251
|
+
|
|
1252
|
+
Поиск адресов (геокодер). Вызовы дебаунсятся на 500 мс: при вводе по символу уходит один запрос.
|
|
1253
|
+
|
|
1254
|
+
```ts
|
|
1255
|
+
const results = await Search("Рудаки 33", token, {
|
|
1256
|
+
lat: "38.5598",
|
|
1257
|
+
lng: "68.7870",
|
|
1258
|
+
limit: 10,
|
|
1259
|
+
});
|
|
1260
|
+
```
|
|
1261
|
+
|
|
1262
|
+
| Параметр | Тип | Описание |
|
|
1263
|
+
| -------- | --- | -------- |
|
|
1264
|
+
| `text` | `string` | Строка поиска. |
|
|
1265
|
+
| `token` | `string` | Токен сервиса. Обязателен, иначе `[MahalMap SDK] Search token is required`. |
|
|
1266
|
+
| `additionalParam.lat` / `.lng` | `string` | Точка для сортировки результатов по удалённости. |
|
|
1267
|
+
| `additionalParam.limit` | `number` | Максимум результатов. |
|
|
1268
|
+
| `additionalParam.type` | `string` | Фильтр по типу объекта. |
|
|
1269
|
+
|
|
1270
|
+
Возвращает `ISearchResponse[]`.
|
|
1271
|
+
|
|
1272
|
+
### `SearchPoi(text, token, additionalParam?)`
|
|
1273
|
+
|
|
1274
|
+
Поиск POI (организации, объекты). Сигнатура и дебаунс те же, что у `Search`, таймер отдельный — параллельный ввод в двух полях не перебивает запросы друг друга.
|
|
1275
|
+
|
|
1276
|
+
```ts
|
|
1277
|
+
const places = await SearchPoi("кафе", token, { lat: "38.5598", lng: "68.7870", limit: 20 });
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
Возвращает `ISearchResponse[]`.
|
|
1281
|
+
|
|
1282
|
+
### `SearchByLocation(params)`
|
|
1283
|
+
|
|
1284
|
+
Обратный геокодинг: адреса и POI по координатам. Без дебаунса.
|
|
1285
|
+
|
|
1286
|
+
```ts
|
|
1287
|
+
const res = await SearchByLocation({
|
|
1288
|
+
lat: 38.5598,
|
|
1289
|
+
lng: 68.787,
|
|
1290
|
+
token,
|
|
1291
|
+
});
|
|
1292
|
+
```
|
|
1293
|
+
|
|
1294
|
+
| Поле | Тип | Обязательное |
|
|
1295
|
+
| ---- | --- | ------------ |
|
|
1296
|
+
| `lat` | `string \| number` | да |
|
|
1297
|
+
| `lng` | `string \| number` | да |
|
|
1298
|
+
| `token` | `string` | да |
|
|
1299
|
+
| `type` | `string` | нет |
|
|
1300
|
+
|
|
1301
|
+
### `CheckJSApi(token)`
|
|
1302
|
+
|
|
1303
|
+
Проверяет, активна ли подписка JSApi у токена.
|
|
1304
|
+
|
|
1305
|
+
```ts
|
|
1306
|
+
const { success, message } = await CheckJSApi(token);
|
|
1307
|
+
|
|
1308
|
+
if (!success) {
|
|
1309
|
+
console.warn("Подписка не активна:", message);
|
|
1310
|
+
}
|
|
1311
|
+
```
|
|
1312
|
+
|
|
1313
|
+
Промис резолвится и при отрицательном ответе — `success: false` это результат проверки, а не сбой. Исключение бросается только если вызов не дошёл до сервиса (сеть, CORS, таймаут) или токен пустой.
|
|
1314
|
+
|
|
1315
|
+
Этот же вызов используется внутри [`MahalMap.createAsync()`](#mahalmapcreateasyncoptions-maplibreobject-maps3dctor), когда `Maps3D` не передан и карта поднимается на запасном стиле.
|
|
1316
|
+
|
|
1317
|
+
### `Router(points, typeData, token)`
|
|
1318
|
+
|
|
1319
|
+
Маршрут между точками.
|
|
1320
|
+
|
|
1321
|
+
```ts
|
|
1322
|
+
const routes = await Router(
|
|
1323
|
+
[
|
|
1324
|
+
[68.787, 38.5598],
|
|
1325
|
+
[68.809, 38.561],
|
|
1326
|
+
],
|
|
1327
|
+
"geojson",
|
|
1328
|
+
token,
|
|
1329
|
+
);
|
|
1330
|
+
```
|
|
1331
|
+
|
|
1332
|
+
| Параметр | Тип | Описание |
|
|
1333
|
+
| -------- | --- | -------- |
|
|
1334
|
+
| `points` | `number[][]` | Точки в формате `[lng, lat]`. |
|
|
1335
|
+
| `typeData` | `string` | `"geojson"` — декодирует polyline в массив координат. Другое значение оставляет `geometry` строкой polyline. |
|
|
1336
|
+
| `token` | `string` | Токен сервиса. |
|
|
1337
|
+
|
|
1338
|
+
Возвращает `IRoute[]`.
|
|
1339
|
+
|
|
991
1340
|
## License
|
|
992
1341
|
|
|
993
1342
|
ISC
|