osmgl 0.12.1 → 0.13.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/dist/osmgl.d.cts CHANGED
@@ -1683,7 +1683,8 @@ interface SurfaceLayerSpec extends LayerBase {
1683
1683
  groundField?: boolean;
1684
1684
  bevelDrop?: number;
1685
1685
  paint: MaterialPaint & {
1686
- color: Interpolated<string>;
1686
+ /** Цвет поверхности; `{ from, darken }` — «как у такого-то слоя» (см. `ColorFrom`). */
1687
+ color: Interpolated<string> | ColorFrom;
1687
1688
  opacity?: Interpolated<number>;
1688
1689
  /** Насколько темнее борт и юбка, 0..1. */
1689
1690
  sideShade?: Interpolated<number>;
@@ -1691,8 +1692,11 @@ interface SurfaceLayerSpec extends LayerBase {
1691
1692
  * Цвет борта и юбки. По умолчанию у УТОПЛЕННОЙ поверхности это фон стиля —
1692
1693
  * то есть земля вокруг: стенка утопленной воды и есть берег, и красить её
1693
1694
  * водой значит обводить реку тёмной каймой.
1695
+ *
1696
+ * `{ from, darken }` — «как у такого-то слоя» (см. `ColorFrom`): так бордюр полотна берёт цвет
1697
+ * обводки дорог из темы и меняется вместе с ней, а не остаётся одним хексом на все палитры.
1694
1698
  */
1695
- sideColor?: Interpolated<string>;
1699
+ sideColor?: Interpolated<string> | ColorFrom;
1696
1700
  /**
1697
1701
  * Насколько борт освещается КАК ЗЕМЛЯ (0 — по своей нормали, 1 — по
1698
1702
  * вертикальной). У берега нормаль горизонтальная, света он почти не
@@ -1700,6 +1704,20 @@ interface SurfaceLayerSpec extends LayerBase {
1700
1704
  * умолчанию 1, и край берёт свет окружающей земли.
1701
1705
  */
1702
1706
  sideLight?: Interpolated<number>;
1707
+ /**
1708
+ * ТОН ПО ВЫСОТЕ: чем выше лежит верх поверхности, тем он светлее (> 0) или темнее (< 0).
1709
+ *
1710
+ * Уровни развязки читаются сверху, без наклона камеры: у Baidu нижняя дорога под эстакадой
1711
+ * заметно темнее верхней, а по длине съезда тон меняется плавно (замер их кадров,
1712
+ * `sdk/baydumap/RESEARCH.md` §6.4 в монорепозитории). Считается по высоте КАЖДОЙ вершины —
1713
+ * профиль подъёма (`liftPath`) даёт градиент по съезду сам, без нарезки на куски.
1714
+ *
1715
+ * Доля смешивания с белым (или чёрным) на полной высоте [`liftToneHeight`], 0..1. Земля
1716
+ * (верх ниже уровня слоя + четверти метра) не меняется — тема остаётся темой.
1717
+ */
1718
+ liftTone?: Interpolated<number>;
1719
+ /** Высота, на которой тон набирает всю силу, метры. По умолчанию — `levelHeight` стиля или 8. */
1720
+ liftToneHeight?: number;
1703
1721
  };
1704
1722
  }
1705
1723
  /**
@@ -2790,6 +2808,15 @@ declare class Tile {
2790
2808
  requestId: number;
2791
2809
  /** Ресурсы GPU по имени слоя — слой создаёт лениво, источник гарантированно чистит. */
2792
2810
  readonly buckets: Map<string, TileBucket>;
2811
+ /**
2812
+ * Сколько памяти держит разобранный тайл, байт.
2813
+ *
2814
+ * Считается ОДИН раз при приёме: складывать буферы каждой проверки бюджета значило бы обходить
2815
+ * все слои всех тайлов на каждом кадре. Нужно это затем, что тайлы разного веса: тайл застройки
2816
+ * центра города — это мегабайты, а тайл точек на том же зуме — десятки килобайт, и держать
2817
+ * одинаковое ЧИСЛО тех и других (как делал кеш) — значит не знать, сколько памяти занято.
2818
+ */
2819
+ bytesHeld: number;
2793
2820
  constructor(id: TileID);
2794
2821
  /** Сырой тайл, каким он приехал: из него запросы берут свойства фич. */
2795
2822
  get raw(): ArrayBuffer | undefined;
@@ -2876,6 +2903,25 @@ declare class TileSource extends Evented<TileSourceEvents> {
2876
2903
  /** Отмена загрузок по своему протоколу: у них своя сигнализация, пул о них не знает. */
2877
2904
  private protocolAborts;
2878
2905
  /** Тайлы, которые слой должен нарисовать в этом кадре. */
2906
+ /**
2907
+ * Сколько памяти держат разобранные тайлы этого источника.
2908
+ *
2909
+ * Считается обходом кеша, а не счётчиком: счётчик пришлось бы править в полудюжине мест
2910
+ * (приём, вытеснение, сброс данных, смена стиля), и разойдись он хоть раз — бюджет памяти
2911
+ * молча перестал бы работать. Обход идёт раз на кадр по паре сотен записей.
2912
+ */
2913
+ get retainedBytes(): number;
2914
+ /**
2915
+ * Выбросить самый давний тайл, который сейчас не рисуют. Возвращает, сколько байт освободилось.
2916
+ *
2917
+ * Видимые не трогаем ни при каких обстоятельствах: выбросить то, что в кадре, — это дыра на
2918
+ * экране вместо экономии.
2919
+ *
2920
+ * В ответе `-1` означает «выбрасывать нечего», а не ноль: пустой тайл (приехал без единого слоя)
2921
+ * весит ноль байт, и путать «выбросил, но освободилось ноль» с «нечего выбрасывать» нельзя —
2922
+ * на этом обрезка однажды останавливалась, не дойдя до толстых тайлов.
2923
+ */
2924
+ dropOldest(): number;
2879
2925
  get visibleTiles(): TileID[];
2880
2926
  /** Версия содержимого: меняется, когда приехал очередной тайл или сменился видимый набор. */
2881
2927
  get dataVersion(): number;
@@ -2983,6 +3029,95 @@ declare class TileSource extends Evented<TileSourceEvents> {
2983
3029
  destroy(): void;
2984
3030
  }
2985
3031
 
3032
+ /**
3033
+ * СБОРКА ДОМОВ, РАЗРЕЗАННЫХ ГРАНИЦЕЙ ТАЙЛА.
3034
+ *
3035
+ * Тайл видит только свой кусок дома, и правильной геометрии из него не построить: скругление,
3036
+ * фаска, стены и скатная крыша считаются по контуру, а у куска контур обрублен ложным ребром. Как
3037
+ * ни выравнивай правила, на шве остаётся угловатость — разрез не край дома, и любая обработка,
3038
+ * смотрящая на соседние вершины, на нём врёт.
3039
+ *
3040
+ * Собрать дом целиком можно только там, где видно ВСЕ его куски, — то есть здесь, на главном
3041
+ * потоке, где известен весь загруженный набор тайлов. Сшивание делает `stitch.ts`, геометрию —
3042
+ * тот же код, что и для обычных домов (`generateStitchedBuildings`), иначе сшитый дом отличался бы
3043
+ * от соседних и мы поменяли бы шов на разнобой.
3044
+ *
3045
+ * ЧТО С КУСКАМИ. Воркер строит их как и раньше — это страховка: сшить удаётся не всегда, дом бывает
3046
+ * длиннее загруженных тайлов. Куски успешно сшитых домов прячутся тем же механизмом, что и дома,
3047
+ * заменённые 3D-моделью (`hiddenBuildings`), поэтому двойной отрисовки не возникает, а несшитые
3048
+ * продолжают рисоваться по-старому.
3049
+ *
3050
+ * ЦЕНА. На паре тайлов Душанбе из 1364 домов границу задевают 45 — около 3 %. Пересборка идёт не
3051
+ * каждый кадр, а только когда меняется состав загруженных тайлов.
3052
+ */
3053
+ declare class SeamAssembler {
3054
+ /** Сшитая геометрия по ключу тайла-хозяина: в его координатах она и построена. */
3055
+ readonly meshes: Map<string, {
3056
+ tile: TileID;
3057
+ mesh: BuildingsMesh;
3058
+ }>;
3059
+ /** Дома, которые собраны: их куски надо спрятать — но только там, где они пошли в дело. */
3060
+ readonly stitched: Set<number>;
3061
+ /**
3062
+ * Какие дома прятать В КАКОМ тайле: ключ тайла → номера домов.
3063
+ *
3064
+ * Прятать по одному лишь номеру дома нельзя. Замена собирается из тех кусков, что сейчас
3065
+ * загружены, и стоит соседнему тайлу уйти из вида, как его кусок в сборку не попадает — а
3066
+ * спрятан он всё равно был бы. На карте это выглядело так: ведёшь мышью, часть здания уезжает
3067
+ * за край экрана и ПРОПАДАЕТ. Потайловый список это закрывает: кусок, не вошедший в сборку,
3068
+ * продолжает рисоваться сам.
3069
+ */
3070
+ readonly hiddenByTile: Map<string, Set<number>>;
3071
+ /**
3072
+ * Тайлы-хозяева, чья геометрия сменилась в последнем `update`. Их буферы на видеокарте устарели.
3073
+ *
3074
+ * Пересобирать всё подряд нельзя: за панораму тайлы приезжают десятками, а меши сшитых домов
3075
+ * меняются от силы у двух-трёх хозяев. Полная перезаливка стоила 40–70 мс на кадр — ровно те
3076
+ * рывки, что видно при движении.
3077
+ */
3078
+ readonly changed: Set<string>;
3079
+ /**
3080
+ * Сколько домов собирать и сколько мешей строить ЗА ОДИН ЗАХОД. Ноль — без ограничения.
3081
+ *
3082
+ * Ставит карта по профилю устройства (`QualityProfile.seamBudget`). Разом весь набор — это
3083
+ * стоп-кадр: замер на эмуляторе дал 125 мс на таком кадре, а состав загруженных тайлов при зуме
3084
+ * и панораме меняется постоянно.
3085
+ */
3086
+ budget: number;
3087
+ /**
3088
+ * Осталась ли работа с прошлого захода.
3089
+ *
3090
+ * По нему рендер просит следующий кадр: без этого недоделанная сборка ждала бы, пока камеру
3091
+ * тронут снова, — то есть шов остался бы неготовым на неподвижной карте.
3092
+ */
3093
+ pending: boolean;
3094
+ /** Состав набора, на котором собирали. Не изменился — не пересобираем. */
3095
+ private signature;
3096
+ /** Из чего построен меш каждого хозяина: не изменилось — меш не трогаем. */
3097
+ private meshSig;
3098
+ /**
3099
+ * Собранные дома, по номеру. Живут, пока дом виден хоть одному загруженному тайлу.
3100
+ *
3101
+ * Кеш нужен не только ради скорости. Без него объединение считалось бы заново на каждое движение
3102
+ * камеры от того набора кусков, что есть прямо сейчас, — и здание «дышало» бы: то целое, то
3103
+ * половина. Пока хоть один кусок на месте, дом остаётся тем же самым.
3104
+ */
3105
+ private cache;
3106
+ /**
3107
+ * Пересобрать то, что изменилось.
3108
+ *
3109
+ * Возвращает `true`, если геометрия поменялась и кешам пора обновиться.
3110
+ */
3111
+ update(source: TileSource, layerId: string, opts: {
3112
+ zoom: number;
3113
+ metersPerTile: number;
3114
+ cornerRadius?: number;
3115
+ cornerSegments?: number;
3116
+ }): boolean;
3117
+ /** Забыть собранное: после смены стиля или пересборки тайлов оно уже не про эту геометрию. */
3118
+ reset(): void;
3119
+ }
3120
+
2986
3121
  /**
2987
3122
  * Атлас SDF: глифы и иконки лежат в ОДНОЙ текстуре.
2988
3123
  *
@@ -5302,7 +5437,7 @@ declare class LayerRenderer {
5302
5437
  */
5303
5438
  hiddenBuildings: ReadonlySet<number>;
5304
5439
  /** Сборщик домов, разрезанных границей тайла. См. `layers/seams.ts`. */
5305
- private readonly seams;
5440
+ readonly seams: SeamAssembler;
5306
5441
  /** GPU-буферы сшитых домов по ключу тайла-хозяина. */
5307
5442
  private seamGpu;
5308
5443
  /**
@@ -5740,8 +5875,12 @@ declare class LayerRenderer {
5740
5875
  * поток при панораме (46 МБ за 70 кадров, то есть 0.67 МБ на кадр). Остаток переносится на
5741
5876
  * следующий кадр, который тут же и заказывается: на глаз тайл достраивается за пару кадров, а
5742
5877
  * вместо провала в 75 мс остаётся ровный ход.
5878
+ *
5879
+ * ЧИСЛО БЕРЁТСЯ У ПРОФИЛЯ (`uploadBudget`), а не стоит константой: те же полтора мегабайта на
5880
+ * телефоне стоят втрое дороже, и на нём это снова рывок — тот самый, что видно при загрузке
5881
+ * дорог и домов на ходу.
5743
5882
  */
5744
- private static readonly UPLOAD_BUDGET;
5883
+ uploadBudget: number;
5745
5884
  private uploadLeft;
5746
5885
  private uploadDeferred;
5747
5886
  private bucketFor;
@@ -6138,6 +6277,42 @@ interface QualityProfile {
6138
6277
  * с дискретной картой (до этой правки так и было: бюджет был константой на всех).
6139
6278
  */
6140
6279
  modelBudget: number;
6280
+ /**
6281
+ * Сколько байт геометрии за кадр уезжает в видеопамять.
6282
+ *
6283
+ * Тайлы приезжают пачками: при панораме в кадр разом въезжает несколько новых, и у каждого
6284
+ * десяток слоёв. Заливка всей пачки разом — это и есть рывок: карта едет ровно, а раз в полсекунды
6285
+ * замирает. Остаток переносится на следующий кадр, и тайл достраивается за пару кадров вместо
6286
+ * одного провала.
6287
+ *
6288
+ * ПОЧЕМУ ЭТО ПРОФИЛЬ, А НЕ КОНСТАНТА. Байты одинаковы, а время на них — нет: полтора мегабайта
6289
+ * стоят дюжину миллисекунд на ноутбуке с дискретной картой и втрое больше на телефоне, где та же
6290
+ * заливка идёт через общую с процессором память. Постоянный бюджет на всех означает, что на
6291
+ * телефоне при каждой загрузке дорог и домов кадр выпадает из шестидесяти герц — ровно на то и
6292
+ * жалуются.
6293
+ */
6294
+ uploadBudget: number;
6295
+ /**
6296
+ * Сколько памяти отводится РАЗОБРАННЫМ ТАЙЛАМ ВСЕХ наборов, байт.
6297
+ *
6298
+ * Держать в кеше фиксированное ЧИСЛО тайлов на набор — значит не знать, сколько занято: тайл
6299
+ * застройки центра это мегабайты, а тайл точек на том же зуме — десятки килобайт. Наборов у
6300
+ * карты семь, и на полном профиле их кеши вместе съедали кучу приложения целиком: замер на
6301
+ * эмуляторе 28.09.2026 — 330 сборок мусора за полминуты и падение с OutOfMemory посреди зума.
6302
+ *
6303
+ * Бюджет ОБЩИЙ, а не по набору: наборы соревнуются за одну и ту же память, и делить её поровну
6304
+ * между основой и точками неправильно.
6305
+ */
6306
+ tileMemoryBudget: number;
6307
+ /**
6308
+ * Сколько домов, разрезанных границей тайла, собирается за кадр.
6309
+ *
6310
+ * Сборка идёт на потоке кадра, а состав загруженных тайлов при зуме и панораме меняется
6311
+ * постоянно — то есть собирать приходится часто. Разом весь набор это стоп-кадр: замер на
6312
+ * эмуляторе дал 125 мс на такой кадр. Остаток переносится на следующий кадр, и на глаз шов
6313
+ * доводится за несколько кадров вместо одного провала.
6314
+ */
6315
+ seamBudget: number;
6141
6316
  /**
6142
6317
  * Упрощать геометрию тайла: без скругления углов и без объёма у плоских зон.
6143
6318
  *
@@ -6614,6 +6789,15 @@ declare function sdfFromAlpha(alpha: Uint8Array | Uint8ClampedArray, width: numb
6614
6789
  height: number;
6615
6790
  };
6616
6791
 
6792
+ /**
6793
+ * Откуда раскладка берёт глифы.
6794
+ *
6795
+ * Интерфейс, а не сам `GlyphSource`: раскладке нужна от него ровно одна операция, а сверке порта
6796
+ * нужен источник, набитый заранее, — без сети и без обещаний.
6797
+ */
6798
+ interface GlyphLookup {
6799
+ get(code: number): Glyph | undefined;
6800
+ }
6617
6801
  /** Один разложенный символ: где стоит и какой глиф рисовать. */
6618
6802
  interface ShapedGlyph {
6619
6803
  glyph: Glyph;
@@ -6638,7 +6822,7 @@ interface Shaped {
6638
6822
  /**
6639
6823
  * @param letterSpacing разрядка между буквами в единицах кегля 24 — см. `letterSpacingFor`
6640
6824
  */
6641
- declare function shapeText(text: string, source: GlyphSource, maxLineChars?: number, letterSpacing?: number): Shaped | null;
6825
+ declare function shapeText(text: string, source: GlyphLookup, maxLineChars?: number, letterSpacing?: number): Shaped | null;
6642
6826
 
6643
6827
  /**
6644
6828
  * Сокращение родового слова в названии улицы: «улица Истаравшан» → «ул. Истаравшан».
@@ -7330,6 +7514,28 @@ interface RoadGraphOptions {
7330
7514
  ringMax?: number;
7331
7515
  }
7332
7516
  declare function buildRoadGraph(axes: RoadAxis[], options?: RoadGraphOptions): RoadGraph;
7517
+ declare function snapRoadEnds(axes: RoadAxis[], reach: number,
7518
+ /**
7519
+ * Последнее слово за вызывающим: конец оси `from` (голова или хвост) в точку (x, y) оси `to`.
7520
+ * Нужен тому, кто знает высоты: у съезда и улицы под ним уровень в данных один и тот же.
7521
+ */
7522
+ accept?: (from: number, atHead: boolean, to: number, x: number, y: number) => boolean): RoadAxis[];
7523
+ /**
7524
+ * КОЛЬЦО — ОКРУЖНОСТЬЮ.
7525
+ *
7526
+ * Кольцевая развязка в данных — многоугольник из двух десятков точек, и лента по нему выходит
7527
+ * гранёной: островок в середине — восьмиугольник (Шанхай, 121.4833, 31.2341). Замкнутая ось,
7528
+ * которая и в самом деле почти круг, заменяется окружностью, подобранной по её точкам (Каса:
7529
+ * наименьшие квадраты по x² + y² + Dx + Ey + F), с шагом `step` по дуге.
7530
+ *
7531
+ * «Почти круг» — это и форма (4πS/P² не меньше `CIRCULAR`), и разброс радиуса точек (не больше
7532
+ * `RADIUS_SPREAD`): петля вокруг парковки тоже замкнута, но кругом её делать нельзя.
7533
+ *
7534
+ * Концы чужих осей, сидевшие в вершинах кольца, переезжают на окружность вместе с ними (на луч
7535
+ * из центра), а их точки входят в окружность отсчётами — связь по графу не рвётся. Направление
7536
+ * обхода сохраняется: у одностороннего кольца оно и есть направление движения.
7537
+ */
7538
+ declare function roundRings(axes: RoadAxis[], maxLength: number, step?: number): RoadAxis[];
7333
7539
 
7334
7540
  /**
7335
7541
  * РАЗМЕТКА ПО ГРАФУ ДОРОГ.
@@ -7462,6 +7668,13 @@ interface MarkingOptions {
7462
7668
  * Стоп-линия отмеряется ОТ ПЕРЕХОДА, поэтому едет вместе с ним и остаётся к нему прижатой.
7463
7669
  */
7464
7670
  crossingAt?: (chain: RoadChain, index: number, node: number) => number | null;
7671
+ /**
7672
+ * СТОП-ЛИНИЯ НА ГЛАВНОЙ У Т-ПРИМЫКАНИЯ. `true` (как было) — на каждом подходе к перекрёстку;
7673
+ * `false` — у узла на три луча улица, проходящая его насквозь (у её луча есть продолжение под
7674
+ * 180° ± 30°), главная, и стоп-линии на ней нет: стоит только тот, кто выезжает сбоку. Иначе
7675
+ * каждое примыкание двора перечёркивало проспект поперёк (Шанхай, 27.09.2026).
7676
+ */
7677
+ throughStop?: boolean;
7465
7678
  }
7466
7679
  declare function roadMarkings(graph: RoadGraph, options?: MarkingOptions): Marking[];
7467
7680
 
@@ -7880,6 +8093,9 @@ declare function roadSurfaces(graph: RoadGraph, options?: RoadSurfaceOptions): R
7880
8093
  * Платит за это середина: у такой кривой она в полтора раза круче. Значит уклон в решателе
7881
8094
  * берётся в полтора раза меньше — чтобы в самом крутом месте выйти ровно на заданный.
7882
8095
  *
8096
+ * 4. (по опции `clearance`) Уточнение с ограничениями: зазор на пересечениях без общего узла,
8097
+ * уклон, общий узел, выравнивание соседних проезжих частей. См. `refine` в конце файла.
8098
+ *
7883
8099
  * Считает в метрах, как и весь граф.
7884
8100
  */
7885
8101
 
@@ -7893,6 +8109,25 @@ interface RoadHeightOptions {
7893
8109
  * восьмидесяти. Это уклон в САМОМ КРУТОМ месте кривой, а не средний.
7894
8110
  */
7895
8111
  maxGrade?: number;
8112
+ /**
8113
+ * ЗАЗОР ПОД ЭСТАКАДОЙ, метры. Ноль — уточнение выключено, работают только шаги 1–3.
8114
+ *
8115
+ * Шаги 1–3 знают только граф: поднятое — наверх, от него по уклону вниз. О ПЕРЕСЕЧЕНИЯХ без общего
8116
+ * узла они не знают ничего. Поэтому съезд, который идёт к дальней проезжей части моста и по пути
8117
+ * проходит под ближней, набирал высоту от точки примыкания и протыкал ближний настил (развязка
8118
+ * «Нового моста» в Худжанде, 27.09.2026). С зазором поверх шагов 1–3 работает шаг 4 — уточнение
8119
+ * с ограничениями, см. `refine`.
8120
+ */
8121
+ clearance?: number;
8122
+ /** Шаг отсчётов высоты вдоль цепочки при уточнении, в единицах графа. */
8123
+ step?: number;
8124
+ /**
8125
+ * Насколько соседние параллельные проезжие части могут отстоять кромка от кромки, чтобы их
8126
+ * выравнивало по высоте, в единицах графа.
8127
+ */
8128
+ alignGap?: number;
8129
+ /** Число итераций уточнения. */
8130
+ iterations?: number;
7896
8131
  }
7897
8132
  interface RoadHeights {
7898
8133
  /** Высота узла, метры. */
@@ -7913,6 +8148,128 @@ interface RoadHeights {
7913
8148
  }
7914
8149
  declare function roadHeights(graph: RoadGraph, options?: RoadHeightOptions): RoadHeights;
7915
8150
 
8151
+ /**
8152
+ * ПОЛОТНО ДОРОГ СЕТКОЙ: ЛЕНТЫ ПО ГРАФУ И ПЯТНА УЗЛОВ, СРАЗУ В 3D.
8153
+ *
8154
+ * Прежний путь (`road-surface` → полигоны → слияние → поле высот `liftPath`) терял главное: ЧЬЯ ЭТО
8155
+ * ТОЧКА. Лента, ставшая полигоном, уже не знает, какой вершине какое место оси соответствует, и
8156
+ * высоту приходилось угадывать заново по «ближайшей оси». Все дефекты развязок жили на этом шаге:
8157
+ * провал настила над хвостом соседа, смешивание осей разных уровней, стенки на торцах, зубцы
8158
+ * слияния (27.09.2026).
8159
+ *
8160
+ * Здесь параметризация не теряется ни на одном шаге:
8161
+ *
8162
+ * 1. ПЕРЕГОН — лента по тройке «кромка — ось — кромка» (`roadEdges`). Высота каждой вершины —
8163
+ * `heights.at` СВОЕЙ оси в этом месте; полей и смешивания нет.
8164
+ *
8165
+ * 2. ЛЕНТА ОБРЕЗАЕТСЯ У УЗЛА ровно там, где бордюрная дуга радиуса `kerbRadius` касается её
8166
+ * кромки. Так и зазор до чужого полотна получается сам: у прямого перекрёстка это полуширина
8167
+ * поперечной улицы плюс радиус.
8168
+ *
8169
+ * 3. ПЯТНО УЗЛА — контур из торцов лент и дуг между соседними кромками (кубическая Безье,
8170
+ * касательная к обеим кромкам: то же, что дуга окружности, но точно в торцевые вершины).
8171
+ * Вершины на стыке с лентой ОБЩИЕ — ни щели, ни перекрытия по построению.
8172
+ *
8173
+ * 4. ГРУППЫ БЛИЗКИХ УЗЛОВ. Перекрёсток двух улиц с разделительной — это четыре узла в двадцати
8174
+ * метрах друг от друга, и короткие перемычки между ними после обрезки по дугам не помещаются
8175
+ * вовсе. Такие узлы сводятся в ОДНО пятно: перемычки уходят внутрь него, контур обходит все
8176
+ * лучи, выходящие из группы.
8177
+ *
8178
+ * 5. УЗКИЙ ПРОМЕЖУТОК между лентами одного уровня (проезжие части эстакады, идущие вплотную)
8179
+ * заливается: каждая лента доращивает свою кромку до середины щели. Иначе в щель видно землю
8180
+ * и стенки вниз, а у Baidu там сплошной настил.
8181
+ *
8182
+ * 6. ОБЪЁМ: верх, борт, бордюрный камень и низ. Борт и камень строятся ТОЛЬКО по внешнему
8183
+ * контуру — у торца, примыкающего к пятну, стенки нет, потому что там нет края; где снаружи
8184
+ * от кромки чужой асфальт той же высоты — тоже. Камень лежит внутри границы асфальта (как у
8185
+ * Baidu), его внутренняя линия у ленты и у пятна в общих вершинах одна и та же.
8186
+ *
8187
+ * 7. СЛИЯНИЯ НЕТ: эстакада и дорога под ней — разные ленты, кто сверху, решает буфер глубины.
8188
+ *
8189
+ * Считает в единицах графа (метрах). Отдаёт треугольники; во что их превратить — дело рендера.
8190
+ */
8191
+
8192
+ interface RoadMeshOptions {
8193
+ /** Сколько добавить к полуширине проезжей части — свес бордюра, метры. */
8194
+ widthExtra?: number;
8195
+ /** Радиус бордюра на углу перекрёстка, метры. */
8196
+ kerbRadius?: number;
8197
+ /** Верх полотна над своей высотой — бордюр на земле, метры. */
8198
+ elevation?: number;
8199
+ /** Толщина настила: низ поднятого полотна на столько ниже верха, метры. */
8200
+ deck?: number;
8201
+ /** Шаг отсчётов вдоль ленты, метры: по нему идёт высота. */
8202
+ step?: number;
8203
+ /** Наименьший отступ торца от узла, метры. */
8204
+ minCut?: number;
8205
+ /**
8206
+ * БОРДЮРНЫЙ КАМЕНЬ, метры: ширина поперёк и высота над асфальтом. Ноль — без камня, голый борт.
8207
+ *
8208
+ * Как у Baidu (кадр 四元桥 z20, наклон): камень лежит ВНУТРИ границы асфальта тонким белым
8209
+ * ободом (≈ 2 px на z20 — 0.27 м при 7.42 px/м), его грань к дороге светло-серая, а наружная
8210
+ * грань переходит в борт полотна. Внутри контура асфальта — поэтому и «только в границах
8211
+ * асфальта»: наружу камень не выходит ни на сантиметр.
8212
+ */
8213
+ kerbWidth?: number;
8214
+ kerbHeight?: number;
8215
+ /**
8216
+ * Перемычка между узлами короче этого уходит внутрь общего пятна, если после обрезки по дугам
8217
+ * она не помещается, метры. Ноль — группы не собираются.
8218
+ */
8219
+ clusterLink?: number;
8220
+ /** Промежуток между лентами одного уровня уже этого заливается, метры. Ноль — не заливается. */
8221
+ fillGap?: number;
8222
+ /** Собирать островки безопасности из дырок в асфальте. */
8223
+ islands?: boolean;
8224
+ /**
8225
+ * ОТДАТЬ ПЛОСКИЙ КОНТУР АСФАЛЬТА (`outline`): объединение лент, пятен и полукруглых тупиков, где
8226
+ * дырки-островки заменены их сглаженной формой. Для генератора тайлов: сетка там не нужна — в
8227
+ * тайл идут плоские фигуры, а рисует их обычный слой поверхности.
8228
+ */
8229
+ outline?: boolean;
8230
+ /** Пропустить цепочку (тоннели, пешеходное). */
8231
+ skip?: (chain: number) => boolean;
8232
+ }
8233
+ /** Часть сетки: по ней рендер выбирает цвет. */
8234
+ declare const MESH_TOP = 0;
8235
+ declare const MESH_SIDE = 1;
8236
+ declare const MESH_BOTTOM = 2;
8237
+ /** Верх бордюрного камня. */
8238
+ declare const MESH_KERB_TOP = 3;
8239
+ /** Грань камня, обращённая к дороге. */
8240
+ declare const MESH_KERB_SIDE = 4;
8241
+ /** Верх островка безопасности. */
8242
+ declare const MESH_ISLAND = 5;
8243
+ interface RoadMesh {
8244
+ /** x, y, z на вершину; x и y — единицы графа, z — метры. */
8245
+ positions: Float64Array;
8246
+ normals: Float32Array;
8247
+ /** `MESH_TOP` / `MESH_SIDE` / `MESH_BOTTOM` / `MESH_KERB_*` на вершину. */
8248
+ part: Uint8Array;
8249
+ /** Высота полотна (без `elevation`) на вершину — для тона по высоте. */
8250
+ height: Float32Array;
8251
+ indices: Uint32Array;
8252
+ ribbons: number;
8253
+ patches: number;
8254
+ /** Пятен, собранных из нескольких узлов, и перемычек, ушедших внутрь них. */
8255
+ clusters: number;
8256
+ links: number;
8257
+ /** Отсчётов кромки, дорощенных до соседа. */
8258
+ filled: number;
8259
+ /** Островков безопасности, собранных из дырок в асфальте. */
8260
+ islands: number;
8261
+ /** Плоский контур асфальта (только с `outline`): внешний контур против часовой, дырки — по. */
8262
+ outline?: {
8263
+ outer: number[];
8264
+ holes: number[][];
8265
+ }[];
8266
+ /** Отрезков бордюра, снятых потому, что снаружи чужой асфальт той же высоты. */
8267
+ kerbSkipped: number;
8268
+ /** Для отладки: по ленте [цепочка, длина, обрезка у головы, у хвоста, нужная у головы, у хвоста]. */
8269
+ cuts: Float32Array;
8270
+ }
8271
+ declare function roadMesh(graph: RoadGraph, heights: RoadHeights, options?: RoadMeshOptions): RoadMesh;
8272
+
7916
8273
  /**
7917
8274
  * МОСТ КАК СООРУЖЕНИЕ: продольный профиль и опоры.
7918
8275
  *
@@ -8558,6 +8915,31 @@ interface SurfaceMesh {
8558
8915
  declare const SURFACE_CUT_BLEED = 1;
8559
8916
  declare function generateSurface(layer: VectorTileLayer, extent: number, filter: Filter | undefined, opts: SurfaceOptions): SurfaceMesh | null;
8560
8917
 
8918
+ /**
8919
+ * Здание, пересекающее границу тайла, приезжает В ОБОИХ — и каждый раз с
8920
+ * буфером (у наших тайлов 64 единицы из 4096). В полосе перекрытия получаются
8921
+ * ДВЕ копии одной крыши и одних стен на одной высоте, и они дерутся за глубину:
8922
+ * на экране это мерцающая полоса ровно по стыку тайлов, тем шире, чем крупнее
8923
+ * зум. Проверено на Душанбе: из 2700 зданий тайла 165 лежат ещё и в соседнем.
8924
+ *
8925
+ * Лечится обрезкой по квадрату тайла (Сазерленд — Ходжман). Тот же приём у
8926
+ * Mapbox: в `fill_extrusion_bucket` кольца, целиком лежащие за границей,
8927
+ * выбрасываются с прямой пометкой «они определены в тайле по ту сторону».
8928
+ *
8929
+ * Стены на линии разреза при этом НЕ строятся — см. `isCutEdge`: разрез не
8930
+ * стена, у соседнего тайла там продолжение дома.
8931
+ */
8932
+ /**
8933
+ * Запас за границей тайла, в единицах тайла.
8934
+ *
8935
+ * Источник отдаёт геометрию с буфером в 4 пикселя из 256 на тайл — здесь это та же величина, но в
8936
+ * единицах тайла. Резать по квадрату С ЗАПАСОМ, а не по самому квадрату, нужно затем, чтобы линия
8937
+ * разреза не попадала в кадр: любая обработка, смотрящая на соседние рёбра (фаска, борта,
8938
+ * скругление), у соседних тайлов на разрезе расходится, а признака «это ребро ненастоящее» в
8939
+ * векторных тайлах нет — так записано и в их спецификации.
8940
+ */
8941
+ declare const cutMargin: (extent: number) => number;
8942
+
8561
8943
  /**
8562
8944
  * Объединение полигонов слоя в один контур — до построения меша.
8563
8945
  *
@@ -9339,6 +9721,18 @@ declare class Map$1 extends Evented<MapEvents> {
9339
9721
  calculateCameraOptionsFromTo(from: LngLatLike, altitudeFrom: number, to: LngLatLike, altitudeTo?: number): CameraOptions & {
9340
9722
  elevation: number;
9341
9723
  };
9724
+ /**
9725
+ * ДЕРЖАТЬ РАЗОБРАННЫЕ ТАЙЛЫ В ПРЕДЕЛАХ БЮДЖЕТА ПАМЯТИ.
9726
+ *
9727
+ * Кеш каждого набора считает ТАЙЛЫ, а тратится ПАМЯТЬ, и вес тайла отличается на два порядка:
9728
+ * застройка центра — мегабайты, точки — десятки килобайт. Наборов у карты семь, и вместе они
9729
+ * съедали всю кучу приложения (см. `tileMemoryBudget`).
9730
+ *
9731
+ * Выбрасываем у САМОГО ТОЛСТОГО набора и по одному: так первым худеет тот, кто занял больше
9732
+ * всех, а не тот, кому не повезло оказаться в списке первым. Видимые тайлы не трогаются вовсе —
9733
+ * если выбрасывать нечего, выходим и живём с перерасходом до следующего кадра.
9734
+ */
9735
+ private trimTileMemory;
9342
9736
  /** Зум, прилипший к шагу `zoomSnap`. */
9343
9737
  private snapZoom;
9344
9738
  private stepAnimation;
@@ -9798,6 +10192,15 @@ declare class Map$1 extends Evented<MapEvents> {
9798
10192
  profile: QualityProfile;
9799
10193
  pixelRatio: number;
9800
10194
  };
10195
+ /**
10196
+ * Настройки профиля, которые живут в рендере.
10197
+ *
10198
+ * Отдельным методом, потому что зовётся ДВАЖДЫ: при заведении карты и при каждой смене профиля.
10199
+ * Без первого раза карта, заведённая на слабом устройстве, рисовала бы первым делом по
10200
+ * настройкам самого сильного — детализация, тени и бюджеты остались бы от значений по
10201
+ * умолчанию, пока профиль не сменится.
10202
+ */
10203
+ private applyRendererQuality;
9801
10204
  /**
9802
10205
  * @param keepLook не трогать то, что видно НАВСЕГДА, — плотность буфера и упрощение геометрии.
9803
10206
  * Так приходит автоснижение: см. `checkFrameBudget`.
@@ -9964,4 +10367,4 @@ declare class Map$1 extends Evented<MapEvents> {
9964
10367
  destroy(): void;
9965
10368
  }
9966
10369
 
9967
- export { type AnimationOptions, type ArrowSize, AssetLoader, type AssetLoaderOptions, AttributionControl, type AxisChain, BASE_SOURCE, BUILDING_HEIGHT_SCALE, BUILDING_POS_SCALE, BUILDING_VERTEX_STRIDE, BoxZoomHandler, type BridgeProfile, type BuildingHit, type BuildingsMesh, CITY_STYLE, type CameraOptions, type CameraUpdate, Circle, type CircleOptions, type ControlPosition, CooperativeGesturesHandler, type CoverOptions, type CustomLayer, DATA_PAINT_STRIDE, DEFAULT_ICONS, DEFAULT_LIGHT, DEFAULT_SHADOWS, DEFAULT_SKY, DEFAULT_STYLE, type DataPaintSpec, type DemEncoding, DemSource, type DemSourceOptions, DemTile, DemTileEntry, DepthTarget, type DeviceHints, EARTH_CIRCUMFERENCE, type ExprContext, type ExprValue, FILL_VERTEX_STRIDE, FeaturePaint, type Filter, type FitBoundsOptions, type FitViewport, type FogPlanes, FullscreenControl, GLOBE_MAX_PITCH, GLOBE_ZOOM_MAX, GLOBE_ZOOM_MIN, GLYPH_BORDER, GLYPH_SIZE, GROUND_SCALE, type GeoJSONData, type GeoJSONFeature, type GeoJSONFeatureCollection, type GeoJSONGeometry, GeoJSONSource, GeolocateControl, GeomType, GestureHandler, type GestureOptions, GlobeControl, type Glyph, type GlyphMetric, GlyphSource, type GpuClass, GroundArrows, type IControl, IconSource, ImageManager, IndoorMask, type Interpolated, type Junctions, LEVEL_LIMIT, LINE_VERTEX_STRIDE, type LaneArrow, type LaneGuide, type LaneGuideOptions, type LayerPlan, LayerRenderer, type LiftField, type LightSpec, type LinePlacement, type LngLat, LngLatBounds, type LngLatLike, LogoControl, MAX_GRADE, MAX_LATITUDE, MIN_PIER_HEIGHT_METERS, MODEL_VERTEX_STRIDE, Map$1 as Map, type MapEvents, MapObject, type MapObjectOptions, type MapOptions, Marker, type MarkerOptions, type Marking, type MarkingKind, type MarkingOptions, type MarkingRing, type MediaCoordinates, type MediaKind, MediaSource, Model, ModelLayer, type ModelMesh, type ModelOptions, type ModelPrimitive, NavigationControl, ObjectManager, type ObjectPaint, type ObjectPart, PIER_SPACING_METERS, type Padding, type Pier, type PierOptions, type PlacedGlyph, type PlacedSymbol, Polygon, type PolygonOptions, type PolygonPiece, Polyline, type PolylineOptions, type PolylineSegment, Popup, type PopupOptions, type Projection, type ProtocolHandler, type QualityChange, QualityGovernor, type QualityName, type QualityProfile, type QueriedFeature, type QueryGeometry, RELIEF_STYLE, ROAD_SIGNS, RUNTIME_FILL_STRIDE, RUNTIME_LINE_STRIDE, type RampOptions, RasterSource, type RasterSourceOptions, RasterTile, type RenderedQueryOptions, type RoadAxis, type RoadChain, type RoadEdges, type RoadGraph, type RoadGraphOptions, type RoadHeightOptions, type RoadHeights, type RoadNode, type RoadRay, type RoadSourceEdges, type RoadSurface, type RoadSurfaceOptions, type RoundOptions, type RuntimeMesh, SDF_EDGE, SDF_PX, SIGN_SIZE, SOFT_STYLE, SPLIT_SEP, SURFACE_CUT_BLEED, SURFACE_LEVEL_SCALE, SURFACE_VERTEX_STRIDE, ScaleControl, type ScreenPoint$1 as ScreenPoint, SdfAtlas, type ShadowSettings, type SkySpec, Style, type StyleImage, type StyleImageData, type StyleImageOptions, type StyleLayerSpec, type StyleSpec, type SymbolHit, SymbolRenderer, TAPER_METERS, TERRAIN_STYLE, THEMES, TILE_SIZE, type TaperedWidth, TerrainControl, type ThemeSpec, type TileAddress, TileID, Transform, type TransformConstrain, type TransformRequest, VectorTile, VectorTileFeature, VectorTileLayer, abbreviateStreet, addGround, altitudeFromMercatorZ, applyTheme, arrowLabelOffset, arrowVertices, bridgePiers, bridgeProfile, buildRoadGraph, buildRuntimeFill, buildRuntimeLine, cameraForBounds, chainAxes, circumferenceAtLatitude, clampLat, clampPixelRatio, classifyRenderer, clipLineToRect, coordinateDigits, coveringTiles, createGround, Map$1 as default, densifyLine, deviceHints, distToSegment, evaluateColor, evaluateExpression, evaluateNumber, expressionColor, expressionNumber, extractFeature, featureDrivenPaint, featureLevel, fillFootprint, fogPlanes, footprintOf, formatHash, generateBuildings, generateFill, generateLine, generateSurface, generateSymbols, globeBasis, globeFlatMix, globeRadius, globeToLocal, groundAt, iconRotation, insideFootprint, isExpression, junctionIndex, laneArrow, laneGuides, latFromMercatorY, liftFields, lngFromMercatorX, lngLatToUnit, makeFeaturePaint, matchesFilter, mercatorMetersPerTile, mercatorX, mercatorY, mercatorZFromAltitude, metersPerPixel, metersPerTile, needsDataPaint, nextQualityDown, parseGlb, parseGlbAsync, parseGlyphs, parseHash, parseLift, patchUV, pickBuilding, pickFill, pitchIntent, pixelsPerMeter, placeAlongLine, placeMarking, pointInRing, qualityFor, qualityProfile, queryRendered, querySource, raySphere, refineLine, relaxAngle, relaxCurvature, resolveTemplate, ribbonFromEdges, ribbonRing, ribbonShape, ringEdges, roadEdges, roadHeights, roadMarkings, roadSurfaces, roundLine, roundRing, sdfFromAlpha, shapeText, speedSign, splitBucketKey, splitByGround, splitPolygons, stitchPieces, stopLine, styleWithTheme, taperedWidth, tileOriginMeters, tileUrl, toLngLat, unitToLngLat, unpackVector, waffle, worldSize, zebra };
10370
+ export { type AnimationOptions, type ArrowSize, AssetLoader, type AssetLoaderOptions, AttributionControl, type AxisChain, BASE_SOURCE, BUILDING_HEIGHT_SCALE, BUILDING_POS_SCALE, BUILDING_VERTEX_STRIDE, BoxZoomHandler, type BridgeProfile, type BuildingHit, type BuildingsMesh, CITY_STYLE, type CameraOptions, type CameraUpdate, Circle, type CircleOptions, type ControlPosition, CooperativeGesturesHandler, type CoverOptions, type CustomLayer, DATA_PAINT_STRIDE, DEFAULT_ICONS, DEFAULT_LIGHT, DEFAULT_SHADOWS, DEFAULT_SKY, DEFAULT_STYLE, type DataPaintSpec, type DemEncoding, DemSource, type DemSourceOptions, DemTile, DemTileEntry, DepthTarget, type DeviceHints, EARTH_CIRCUMFERENCE, type ExprContext, type ExprValue, FILL_VERTEX_STRIDE, FeaturePaint, type Filter, type FitBoundsOptions, type FitViewport, type FogPlanes, FullscreenControl, GLOBE_MAX_PITCH, GLOBE_ZOOM_MAX, GLOBE_ZOOM_MIN, GLYPH_BORDER, GLYPH_SIZE, GROUND_SCALE, type GeoJSONData, type GeoJSONFeature, type GeoJSONFeatureCollection, type GeoJSONGeometry, GeoJSONSource, GeolocateControl, GeomType, GestureHandler, type GestureOptions, GlobeControl, type Glyph, type GlyphMetric, GlyphSource, type GpuClass, GroundArrows, type IControl, IconSource, ImageManager, IndoorMask, type Interpolated, type Junctions, LEVEL_LIMIT, LINE_VERTEX_STRIDE, type LaneArrow, type LaneGuide, type LaneGuideOptions, type LayerPlan, LayerRenderer, type LiftField, type LightSpec, type LinePlacement, type LngLat, LngLatBounds, type LngLatLike, LogoControl, MAX_GRADE, MAX_LATITUDE, MESH_BOTTOM, MESH_ISLAND, MESH_KERB_SIDE, MESH_KERB_TOP, MESH_SIDE, MESH_TOP, MIN_PIER_HEIGHT_METERS, MODEL_VERTEX_STRIDE, Map$1 as Map, type MapEvents, MapObject, type MapObjectOptions, type MapOptions, Marker, type MarkerOptions, type Marking, type MarkingKind, type MarkingOptions, type MarkingRing, type MediaCoordinates, type MediaKind, MediaSource, Model, ModelLayer, type ModelMesh, type ModelOptions, type ModelPrimitive, NavigationControl, ObjectManager, type ObjectPaint, type ObjectPart, PIER_SPACING_METERS, type Padding, type Pier, type PierOptions, type PlacedGlyph, type PlacedSymbol, Polygon, type PolygonOptions, type PolygonPiece, Polyline, type PolylineOptions, type PolylineSegment, Popup, type PopupOptions, type Projection, type ProtocolHandler, type QualityChange, QualityGovernor, type QualityName, type QualityProfile, type QueriedFeature, type QueryGeometry, RELIEF_STYLE, ROAD_SIGNS, RUNTIME_FILL_STRIDE, RUNTIME_LINE_STRIDE, type RampOptions, RasterSource, type RasterSourceOptions, RasterTile, type RenderedQueryOptions, type RoadAxis, type RoadChain, type RoadEdges, type RoadGraph, type RoadGraphOptions, type RoadHeightOptions, type RoadHeights, type RoadMesh, type RoadMeshOptions, type RoadNode, type RoadRay, type RoadSourceEdges, type RoadSurface, type RoadSurfaceOptions, type RoundOptions, type RuntimeMesh, SDF_EDGE, SDF_PX, SIGN_SIZE, SOFT_STYLE, SPLIT_SEP, SURFACE_CUT_BLEED, SURFACE_LEVEL_SCALE, SURFACE_VERTEX_STRIDE, ScaleControl, type ScreenPoint$1 as ScreenPoint, SdfAtlas, type ShadowSettings, type SkySpec, Style, type StyleImage, type StyleImageData, type StyleImageOptions, type StyleLayerSpec, type StyleSpec, type SymbolHit, SymbolRenderer, TAPER_METERS, TERRAIN_STYLE, THEMES, TILE_SIZE, type TaperedWidth, TerrainControl, type ThemeSpec, type TileAddress, TileID, Transform, type TransformConstrain, type TransformRequest, VectorTile, VectorTileFeature, VectorTileLayer, abbreviateStreet, addGround, altitudeFromMercatorZ, applyTheme, arrowLabelOffset, arrowVertices, bridgePiers, bridgeProfile, buildRoadGraph, buildRuntimeFill, buildRuntimeLine, cameraForBounds, chainAxes, circumferenceAtLatitude, clampLat, clampPixelRatio, classifyRenderer, clipLineToRect, coordinateDigits, coveringTiles, createGround, cutMargin, Map$1 as default, densifyLine, deviceHints, distToSegment, evaluateColor, evaluateExpression, evaluateNumber, expressionColor, expressionNumber, extractFeature, featureDrivenPaint, featureLevel, fillFootprint, fogPlanes, footprintOf, formatHash, generateBuildings, generateFill, generateLine, generateSurface, generateSymbols, globeBasis, globeFlatMix, globeRadius, globeToLocal, groundAt, iconRotation, insideFootprint, isExpression, junctionIndex, laneArrow, laneGuides, latFromMercatorY, liftFields, lngFromMercatorX, lngLatToUnit, makeFeaturePaint, matchesFilter, mercatorMetersPerTile, mercatorX, mercatorY, mercatorZFromAltitude, metersPerPixel, metersPerTile, needsDataPaint, nextQualityDown, parseGlb, parseGlbAsync, parseGlyphs, parseHash, parseLift, patchUV, pickBuilding, pickFill, pitchIntent, pixelsPerMeter, placeAlongLine, placeMarking, pointInRing, qualityFor, qualityProfile, queryRendered, querySource, raySphere, refineLine, relaxAngle, relaxCurvature, resolveTemplate, ribbonFromEdges, ribbonRing, ribbonShape, ringEdges, roadEdges, roadHeights, roadMarkings, roadMesh, roadSurfaces, roundLine, roundRing, roundRings, sdfFromAlpha, shapeText, snapRoadEnds, speedSign, splitBucketKey, splitByGround, splitPolygons, stitchPieces, stopLine, styleWithTheme, taperedWidth, tileOriginMeters, tileUrl, toLngLat, unitToLngLat, unpackVector, waffle, worldSize, zebra };