osmgl 0.2.0 → 0.3.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
@@ -688,6 +688,24 @@ declare class Shader {
688
688
  * Стиль хранится в `styles/*.json` и целиком вшивается в бандл — карта должна
689
689
  * рисоваться без единого сетевого запроса за конфигом.
690
690
  */
691
+ /**
692
+ * Цвет, ВЫВЕДЕННЫЙ ИЗ ЦВЕТА ДРУГОГО СЛОЯ: «как у него, только темнее».
693
+ *
694
+ * Нужен обводке моста. Собственный цвет ей задать нельзя: тем два десятка, каждая красит дороги
695
+ * по-своему, и любой фиксированный хекс на половине из них смотрелся бы чужим. Полупрозрачная
696
+ * затемняющая краска эту задачу решала, но полупрозрачной линии нельзя: капсулы соседних отрезков
697
+ * перекрываются на изломах, и краска ложится дважды — по вершинам идёт цепочка тёмных бусин.
698
+ * (Трафарет «красить пиксель один раз» бусины убирает, но взамен оставляет светлый шов по
699
+ * сглаженному краю первой капсулы — проверено.)
700
+ *
701
+ * Ссылка снимает вопрос: тема красит обводку дороги, а обводка моста едет следом сама.
702
+ */
703
+ interface ColorFrom {
704
+ /** Идентификатор слоя, у которого берём цвет. */
705
+ from: string;
706
+ /** Насколько затемнить, 0..1 (0.25 — четверть). */
707
+ darken?: number;
708
+ }
691
709
  /** Значение, зависящее от зума: число/цвет либо остановки для интерполяции. */
692
710
  type Interpolated<T> = T | {
693
711
  stops: [number, T][];
@@ -827,13 +845,41 @@ interface FillLayerSpec extends LayerBase {
827
845
  }
828
846
  interface LineLayerSpec extends LayerBase {
829
847
  type: 'line';
848
+ /**
849
+ * СЕТЬ, внутри которой порядок отрисовки решают не слои, а уровни пересечения.
850
+ *
851
+ * Все дорожные слои стиля — обводки, полотна, тень моста — помечаются одним именем (`roads`), и
852
+ * рисуются они не подряд, а по уровням: сначала вся сеть уровня −1 (тоннели), потом вся сеть
853
+ * земли, потом вся сеть эстакад. Поэтому мост со своей тенью и обводкой ложится ЦЕЛИКОМ поверх
854
+ * улицы под ним, какого бы класса та ни была, — а не «полотно моста поверх, обводка под».
855
+ *
856
+ * Так же устроено у Яндекса: у каждого дорожного слоя `line-network: "roads"` и
857
+ * `line-z-level: ["get","z_level"]`. Уровень фичи считается по `generators/level`.
858
+ *
859
+ * Сеть рисуется целиком НА МЕСТЕ ПЕРВОГО своего слоя в стиле; порядок внутри уровня — обычный,
860
+ * по порядку слоёв.
861
+ */
862
+ network?: string;
830
863
  paint: MaterialPaint & {
831
- color: Interpolated<string>;
864
+ /** Цвет линии; `{ from, darken }` — «как у такого-то слоя, только темнее» (см. `ColorFrom`). */
865
+ color: Interpolated<string> | ColorFrom;
832
866
  /** Ширина в ЭКРАННЫХ пикселях: линия не толстеет с приближением к камере. */
833
867
  width: Interpolated<number>;
834
868
  opacity?: Interpolated<number>;
835
869
  /** Сдвиг поперёк линии в пикселях — для обочин и параллельных путей. */
836
870
  offset?: Interpolated<number>;
871
+ /**
872
+ * РАЗМЫТИЕ КРАЯ в пикселях: край растягивается на столько вместо обычного полупикселя.
873
+ *
874
+ * Нужно тени моста. У Яндекса тени нет вовсе как отдельной сущности — там на каждый мост
875
+ * рисуется ВОСЕМЬ вложенных контуров (`road-sd-shadow-1…8__bridge`), каждый с прозрачностью
876
+ * 0.03–0.08, и их сумма изображает размытие. Это обход отсутствующего в их движке размытия:
877
+ * восемь слоёв в стиле и восемь вызовов отрисовки на тайл ради градиента.
878
+ *
879
+ * У нас край линии и так вырезает фрагментный шейдер по расстоянию до оси — растянуть переход
880
+ * стоит одного юниформа. Поэтому тень моста здесь ОДИН слой с честным мягким краем.
881
+ */
882
+ blur?: Interpolated<number>;
837
883
  /**
838
884
  * Уровень полотна в МЕТРАХ — для рельефных вариантов карты: дорожка внутри
839
885
  * приподнятого парка должна лежать на нём, а не тонуть под ним. Меняется
@@ -1349,6 +1395,13 @@ interface LayerPlan {
1349
1395
  maxzoom: number;
1350
1396
  /** Разбить слой на меши по значению свойства (этажи — см. `LayerBase.splitBy`). */
1351
1397
  splitBy?: string;
1398
+ /**
1399
+ * Слой входит в СЕТЬ (`LineLayerSpec.network`): меш бьётся по уровням пересечения.
1400
+ *
1401
+ * Воркеру важно не имя сети, а сам факт: по уровню он раскладывает геометрию, а порядок
1402
+ * расставляет уже рендер.
1403
+ */
1404
+ network?: string;
1352
1405
  /** Скругление углов в метрах — геометрия, поэтому едет в воркер. */
1353
1406
  cornerRadius?: number;
1354
1407
  cornerSegments?: number;
@@ -1616,6 +1669,14 @@ interface LoadedResponse {
1616
1669
  * этажи вообще есть в этом здании.
1617
1670
  */
1618
1671
  splits?: Record<string, (string | number)[]>;
1672
+ /**
1673
+ * Уровни пересечения, встретившиеся в этом тайле (см. `generators/level`), по возрастанию.
1674
+ *
1675
+ * Дорожная сеть рисуется НЕ по слоям, а по уровням: сначала всё, что под землёй, потом земля,
1676
+ * потом эстакады. Какие уровни в тайле есть, знает только тот, кто его разобрал, — рендеру
1677
+ * перебирать все возможные значения было бы дороже, чем передать список.
1678
+ */
1679
+ levels?: number[];
1619
1680
  timing: {
1620
1681
  fetchMs: number;
1621
1682
  parseMs: number;
@@ -3715,6 +3776,18 @@ declare class LayerRenderer {
3715
3776
  private applyMaterial;
3716
3777
  private drawFill;
3717
3778
  private drawLine;
3779
+ /**
3780
+ * СЕТЬ ЦЕЛИКОМ, по уровням пересечения (см. `LineLayerSpec.network`).
3781
+ *
3782
+ * Обычный слой рисуется на своём месте в стиле. Сеть так рисовать нельзя: обводка эстакады
3783
+ * должна лежать поверх ПОЛОТНА улицы под ней, а полотно улицы в стиле идёт позже обводок.
3784
+ * Поэтому вся сеть рисуется одним куском на месте своего первого слоя, и снаружи внутрь порядок
3785
+ * такой: уровень (тоннели → земля → эстакады), а внутри уровня — обычный порядок слоёв.
3786
+ *
3787
+ * Какие уровни в кадре есть, считаем по видимым тайлам: в обычном городе это один нулевой, и
3788
+ * тогда всё сводится к прежней отрисовке слой за слоем.
3789
+ */
3790
+ private drawNetwork;
3718
3791
  /**
3719
3792
  * Подсветка выбранного здания.
3720
3793
  *
@@ -4722,11 +4795,47 @@ interface LineMesh {
4722
4795
  vertexCount: number;
4723
4796
  indexCount: number;
4724
4797
  }
4798
+ interface LineOptions {
4799
+ /**
4800
+ * Уровень пересечения (см. `generators/level`): берём только фичи этого уровня.
4801
+ *
4802
+ * `undefined` — уровни не разделяем, слой строится целиком (так живут все слои, кроме дорожной
4803
+ * сети: у реки или границы пересечений без связи не бывает).
4804
+ */
4805
+ level?: number;
4806
+ }
4725
4807
  declare function generateLine(layer: VectorTileLayer, filter: Filter | undefined, maxSegment?: number,
4726
4808
  /** Уровни поверхностей тайла: по ним дорога ложится на то, по чему идёт. Нет — лежит на нуле. */
4727
4809
  ground?: GroundField,
4728
4810
  /** Метров в единице тайла. Ноль — плавный переход ширины на стыках не строится. */
4729
- metersPerUnit?: number): LineMesh | null;
4811
+ metersPerUnit?: number, opts?: LineOptions): LineMesh | null;
4812
+
4813
+ /**
4814
+ * УРОВЕНЬ ПЕРЕСЕЧЕНИЯ — какой из двух дорог быть сверху там, где они пересекаются без связи.
4815
+ *
4816
+ * ЗАЧЕМ. Плоская карта рисуется краской: слои идут в порядке стиля, и внутри слоя порядок фич
4817
+ * произволен. Поэтому эстакада над улицей ничем не отличалась от перекрёстка — обводки сливались,
4818
+ * полотна пересекались, и место читалось как съезд, которого в жизни нет. Ровно этим у Яндекса
4819
+ * занят `line-z-level` (`["get","z_level"]` у КАЖДОГО дорожного слоя, все они в одной сети
4820
+ * `line-network: "roads"`): сеть рисуется не по слоям, а по уровням, и мост со своей тенью и
4821
+ * обводкой целиком ложится поверх того, что под ним.
4822
+ *
4823
+ * ОТКУДА ЧИСЛО. Готового `z_level` в наших тайлах нет, зато есть то, из чего его считают:
4824
+ * `layer` — тег OSM, честный уровень (−1 подземный, 1 над землёй, изредка 2…5);
4825
+ * `brunnel` — «мост / тоннель / брод», он приходит и там, где `layer` не проставлен.
4826
+ * Поэтому берём `layer`, а если его нет — выводим уровень из `brunnel`. Мост без `layer`
4827
+ * (в Душанбе таких большинство) получает 1, тоннель — −1, обычная улица — 0.
4828
+ *
4829
+ * Считается в ВОРКЕРЕ, при тесселяции: по уровню бьётся меш, и рендеру остаётся только порядок.
4830
+ */
4831
+ /**
4832
+ * Дальше этого уровни не разводим. В OSM попадается и `layer=5`, и опечатки в сотни: каждое
4833
+ * значение — это отдельный бакет и отдельный вызов отрисовки, поэтому хвост подрезаем. Пять этажей
4834
+ * развязки — больше, чем бывает на настоящих.
4835
+ */
4836
+ declare const LEVEL_LIMIT = 5;
4837
+ /** Уровень фичи: `layer` из тегов, иначе вывод из `brunnel`. */
4838
+ declare function featureLevel(props: Record<string, unknown>): number;
4730
4839
 
4731
4840
  /**
4732
4841
  * Положение камеры в адресе страницы.
@@ -5682,4 +5791,4 @@ declare class Map$1 extends Evented<MapEvents> {
5682
5791
  destroy(): void;
5683
5792
  }
5684
5793
 
5685
- export { type AnimationOptions, AssetLoader, type AssetLoaderOptions, BASE_SOURCE, BUILDING_HEIGHT_SCALE, BUILDING_VERTEX_STRIDE, type BuildingHit, type BuildingsMesh, CITY_STYLE, type CameraOptions, Circle, type CircleOptions, type CoverOptions, DEFAULT_ICONS, DEFAULT_LIGHT, DEFAULT_SHADOWS, DEFAULT_SKY, DEFAULT_STYLE, DepthTarget, type DeviceHints, EARTH_CIRCUMFERENCE, FILL_VERTEX_STRIDE, type Filter, type FitBoundsOptions, type FitViewport, type FogPlanes, GLOBE_MAX_PITCH, GLOBE_ZOOM_MAX, GLOBE_ZOOM_MIN, GLYPH_BORDER, GLYPH_SIZE, GROUND_SCALE, GeomType, type GestureOptions, type Glyph, type GlyphMetric, GlyphSource, GroundArrows, IconSource, IndoorMask, type Interpolated, LINE_VERTEX_STRIDE, type LayerPlan, LayerRenderer, type LightSpec, type LinePlacement, type LngLat, LngLatBounds, type LngLatLike, MAX_LATITUDE, MODEL_VERTEX_STRIDE, Map$1 as Map, type MapEvents, MapObject, type MapObjectOptions, type MapOptions, Marker, type MarkerOptions, Model, ModelLayer, type ModelMesh, type ModelOptions, type ModelPrimitive, ObjectManager, type ObjectPaint, type ObjectPart, type Padding, type PlacedGlyph, type PlacedSymbol, Polygon, type PolygonOptions, Polyline, type PolylineOptions, type PolylineSegment, Popup, type PopupOptions, type Projection, type QualityName, type QualityProfile, RELIEF_STYLE, RUNTIME_FILL_STRIDE, RUNTIME_LINE_STRIDE, RasterSource, type RasterSourceOptions, RasterTile, type RoundOptions, type RuntimeMesh, SDF_EDGE, SDF_PX, SOFT_STYLE, SPLIT_SEP, SURFACE_CUT_BLEED, SURFACE_LEVEL_SCALE, SURFACE_VERTEX_STRIDE, type ScreenPoint$1 as ScreenPoint, SdfAtlas, type ShadowSettings, type SkySpec, Style, type StyleLayerSpec, type StyleSpec, type SymbolHit, SymbolRenderer, THEMES, TILE_SIZE, type ThemeSpec, TileID, Transform, VectorTile, VectorTileFeature, VectorTileLayer, abbreviateStreet, addGround, altitudeFromMercatorZ, applyTheme, arrowLabelOffset, arrowVertices, buildRuntimeFill, buildRuntimeLine, cameraForBounds, circumferenceAtLatitude, clampLat, clampPixelRatio, clipLineToRect, coordinateDigits, coveringTiles, createGround, Map$1 as default, deviceHints, distToSegment, evaluateColor, evaluateNumber, extractFeature, fillFootprint, fogPlanes, footprintOf, formatHash, generateBuildings, generateFill, generateLine, generateSurface, generateSymbols, globeBasis, globeFlatMix, globeRadius, globeToLocal, groundAt, iconRotation, insideFootprint, latFromMercatorY, lngFromMercatorX, lngLatToUnit, matchesFilter, mercatorMetersPerTile, mercatorX, mercatorY, mercatorZFromAltitude, metersPerPixel, metersPerTile, nextQualityDown, parseGlb, parseGlbAsync, parseGlyphs, parseHash, patchUV, pickBuilding, pickFill, pitchIntent, pixelsPerMeter, placeAlongLine, pointInRing, qualityFor, qualityProfile, raySphere, resolveTemplate, roundRing, sdfFromAlpha, shapeText, splitBucketKey, splitByGround, splitPolygons, styleWithTheme, tileOriginMeters, tileUrl, toLngLat, unitToLngLat, worldSize };
5794
+ export { type AnimationOptions, AssetLoader, type AssetLoaderOptions, BASE_SOURCE, BUILDING_HEIGHT_SCALE, BUILDING_VERTEX_STRIDE, type BuildingHit, type BuildingsMesh, CITY_STYLE, type CameraOptions, Circle, type CircleOptions, type CoverOptions, DEFAULT_ICONS, DEFAULT_LIGHT, DEFAULT_SHADOWS, DEFAULT_SKY, DEFAULT_STYLE, DepthTarget, type DeviceHints, EARTH_CIRCUMFERENCE, FILL_VERTEX_STRIDE, type Filter, type FitBoundsOptions, type FitViewport, type FogPlanes, GLOBE_MAX_PITCH, GLOBE_ZOOM_MAX, GLOBE_ZOOM_MIN, GLYPH_BORDER, GLYPH_SIZE, GROUND_SCALE, GeomType, type GestureOptions, type Glyph, type GlyphMetric, GlyphSource, GroundArrows, IconSource, IndoorMask, type Interpolated, LEVEL_LIMIT, LINE_VERTEX_STRIDE, type LayerPlan, LayerRenderer, type LightSpec, type LinePlacement, type LngLat, LngLatBounds, type LngLatLike, MAX_LATITUDE, MODEL_VERTEX_STRIDE, Map$1 as Map, type MapEvents, MapObject, type MapObjectOptions, type MapOptions, Marker, type MarkerOptions, Model, ModelLayer, type ModelMesh, type ModelOptions, type ModelPrimitive, ObjectManager, type ObjectPaint, type ObjectPart, type Padding, type PlacedGlyph, type PlacedSymbol, Polygon, type PolygonOptions, Polyline, type PolylineOptions, type PolylineSegment, Popup, type PopupOptions, type Projection, type QualityName, type QualityProfile, RELIEF_STYLE, RUNTIME_FILL_STRIDE, RUNTIME_LINE_STRIDE, RasterSource, type RasterSourceOptions, RasterTile, type RoundOptions, type RuntimeMesh, SDF_EDGE, SDF_PX, SOFT_STYLE, SPLIT_SEP, SURFACE_CUT_BLEED, SURFACE_LEVEL_SCALE, SURFACE_VERTEX_STRIDE, type ScreenPoint$1 as ScreenPoint, SdfAtlas, type ShadowSettings, type SkySpec, Style, type StyleLayerSpec, type StyleSpec, type SymbolHit, SymbolRenderer, THEMES, TILE_SIZE, type ThemeSpec, TileID, Transform, VectorTile, VectorTileFeature, VectorTileLayer, abbreviateStreet, addGround, altitudeFromMercatorZ, applyTheme, arrowLabelOffset, arrowVertices, buildRuntimeFill, buildRuntimeLine, cameraForBounds, circumferenceAtLatitude, clampLat, clampPixelRatio, clipLineToRect, coordinateDigits, coveringTiles, createGround, Map$1 as default, deviceHints, distToSegment, evaluateColor, evaluateNumber, extractFeature, featureLevel, fillFootprint, fogPlanes, footprintOf, formatHash, generateBuildings, generateFill, generateLine, generateSurface, generateSymbols, globeBasis, globeFlatMix, globeRadius, globeToLocal, groundAt, iconRotation, insideFootprint, latFromMercatorY, lngFromMercatorX, lngLatToUnit, matchesFilter, mercatorMetersPerTile, mercatorX, mercatorY, mercatorZFromAltitude, metersPerPixel, metersPerTile, nextQualityDown, parseGlb, parseGlbAsync, parseGlyphs, parseHash, patchUV, pickBuilding, pickFill, pitchIntent, pixelsPerMeter, placeAlongLine, pointInRing, qualityFor, qualityProfile, raySphere, resolveTemplate, roundRing, sdfFromAlpha, shapeText, splitBucketKey, splitByGround, splitPolygons, styleWithTheme, tileOriginMeters, tileUrl, toLngLat, unitToLngLat, worldSize };
package/dist/osmgl.d.ts CHANGED
@@ -688,6 +688,24 @@ declare class Shader {
688
688
  * Стиль хранится в `styles/*.json` и целиком вшивается в бандл — карта должна
689
689
  * рисоваться без единого сетевого запроса за конфигом.
690
690
  */
691
+ /**
692
+ * Цвет, ВЫВЕДЕННЫЙ ИЗ ЦВЕТА ДРУГОГО СЛОЯ: «как у него, только темнее».
693
+ *
694
+ * Нужен обводке моста. Собственный цвет ей задать нельзя: тем два десятка, каждая красит дороги
695
+ * по-своему, и любой фиксированный хекс на половине из них смотрелся бы чужим. Полупрозрачная
696
+ * затемняющая краска эту задачу решала, но полупрозрачной линии нельзя: капсулы соседних отрезков
697
+ * перекрываются на изломах, и краска ложится дважды — по вершинам идёт цепочка тёмных бусин.
698
+ * (Трафарет «красить пиксель один раз» бусины убирает, но взамен оставляет светлый шов по
699
+ * сглаженному краю первой капсулы — проверено.)
700
+ *
701
+ * Ссылка снимает вопрос: тема красит обводку дороги, а обводка моста едет следом сама.
702
+ */
703
+ interface ColorFrom {
704
+ /** Идентификатор слоя, у которого берём цвет. */
705
+ from: string;
706
+ /** Насколько затемнить, 0..1 (0.25 — четверть). */
707
+ darken?: number;
708
+ }
691
709
  /** Значение, зависящее от зума: число/цвет либо остановки для интерполяции. */
692
710
  type Interpolated<T> = T | {
693
711
  stops: [number, T][];
@@ -827,13 +845,41 @@ interface FillLayerSpec extends LayerBase {
827
845
  }
828
846
  interface LineLayerSpec extends LayerBase {
829
847
  type: 'line';
848
+ /**
849
+ * СЕТЬ, внутри которой порядок отрисовки решают не слои, а уровни пересечения.
850
+ *
851
+ * Все дорожные слои стиля — обводки, полотна, тень моста — помечаются одним именем (`roads`), и
852
+ * рисуются они не подряд, а по уровням: сначала вся сеть уровня −1 (тоннели), потом вся сеть
853
+ * земли, потом вся сеть эстакад. Поэтому мост со своей тенью и обводкой ложится ЦЕЛИКОМ поверх
854
+ * улицы под ним, какого бы класса та ни была, — а не «полотно моста поверх, обводка под».
855
+ *
856
+ * Так же устроено у Яндекса: у каждого дорожного слоя `line-network: "roads"` и
857
+ * `line-z-level: ["get","z_level"]`. Уровень фичи считается по `generators/level`.
858
+ *
859
+ * Сеть рисуется целиком НА МЕСТЕ ПЕРВОГО своего слоя в стиле; порядок внутри уровня — обычный,
860
+ * по порядку слоёв.
861
+ */
862
+ network?: string;
830
863
  paint: MaterialPaint & {
831
- color: Interpolated<string>;
864
+ /** Цвет линии; `{ from, darken }` — «как у такого-то слоя, только темнее» (см. `ColorFrom`). */
865
+ color: Interpolated<string> | ColorFrom;
832
866
  /** Ширина в ЭКРАННЫХ пикселях: линия не толстеет с приближением к камере. */
833
867
  width: Interpolated<number>;
834
868
  opacity?: Interpolated<number>;
835
869
  /** Сдвиг поперёк линии в пикселях — для обочин и параллельных путей. */
836
870
  offset?: Interpolated<number>;
871
+ /**
872
+ * РАЗМЫТИЕ КРАЯ в пикселях: край растягивается на столько вместо обычного полупикселя.
873
+ *
874
+ * Нужно тени моста. У Яндекса тени нет вовсе как отдельной сущности — там на каждый мост
875
+ * рисуется ВОСЕМЬ вложенных контуров (`road-sd-shadow-1…8__bridge`), каждый с прозрачностью
876
+ * 0.03–0.08, и их сумма изображает размытие. Это обход отсутствующего в их движке размытия:
877
+ * восемь слоёв в стиле и восемь вызовов отрисовки на тайл ради градиента.
878
+ *
879
+ * У нас край линии и так вырезает фрагментный шейдер по расстоянию до оси — растянуть переход
880
+ * стоит одного юниформа. Поэтому тень моста здесь ОДИН слой с честным мягким краем.
881
+ */
882
+ blur?: Interpolated<number>;
837
883
  /**
838
884
  * Уровень полотна в МЕТРАХ — для рельефных вариантов карты: дорожка внутри
839
885
  * приподнятого парка должна лежать на нём, а не тонуть под ним. Меняется
@@ -1349,6 +1395,13 @@ interface LayerPlan {
1349
1395
  maxzoom: number;
1350
1396
  /** Разбить слой на меши по значению свойства (этажи — см. `LayerBase.splitBy`). */
1351
1397
  splitBy?: string;
1398
+ /**
1399
+ * Слой входит в СЕТЬ (`LineLayerSpec.network`): меш бьётся по уровням пересечения.
1400
+ *
1401
+ * Воркеру важно не имя сети, а сам факт: по уровню он раскладывает геометрию, а порядок
1402
+ * расставляет уже рендер.
1403
+ */
1404
+ network?: string;
1352
1405
  /** Скругление углов в метрах — геометрия, поэтому едет в воркер. */
1353
1406
  cornerRadius?: number;
1354
1407
  cornerSegments?: number;
@@ -1616,6 +1669,14 @@ interface LoadedResponse {
1616
1669
  * этажи вообще есть в этом здании.
1617
1670
  */
1618
1671
  splits?: Record<string, (string | number)[]>;
1672
+ /**
1673
+ * Уровни пересечения, встретившиеся в этом тайле (см. `generators/level`), по возрастанию.
1674
+ *
1675
+ * Дорожная сеть рисуется НЕ по слоям, а по уровням: сначала всё, что под землёй, потом земля,
1676
+ * потом эстакады. Какие уровни в тайле есть, знает только тот, кто его разобрал, — рендеру
1677
+ * перебирать все возможные значения было бы дороже, чем передать список.
1678
+ */
1679
+ levels?: number[];
1619
1680
  timing: {
1620
1681
  fetchMs: number;
1621
1682
  parseMs: number;
@@ -3715,6 +3776,18 @@ declare class LayerRenderer {
3715
3776
  private applyMaterial;
3716
3777
  private drawFill;
3717
3778
  private drawLine;
3779
+ /**
3780
+ * СЕТЬ ЦЕЛИКОМ, по уровням пересечения (см. `LineLayerSpec.network`).
3781
+ *
3782
+ * Обычный слой рисуется на своём месте в стиле. Сеть так рисовать нельзя: обводка эстакады
3783
+ * должна лежать поверх ПОЛОТНА улицы под ней, а полотно улицы в стиле идёт позже обводок.
3784
+ * Поэтому вся сеть рисуется одним куском на месте своего первого слоя, и снаружи внутрь порядок
3785
+ * такой: уровень (тоннели → земля → эстакады), а внутри уровня — обычный порядок слоёв.
3786
+ *
3787
+ * Какие уровни в кадре есть, считаем по видимым тайлам: в обычном городе это один нулевой, и
3788
+ * тогда всё сводится к прежней отрисовке слой за слоем.
3789
+ */
3790
+ private drawNetwork;
3718
3791
  /**
3719
3792
  * Подсветка выбранного здания.
3720
3793
  *
@@ -4722,11 +4795,47 @@ interface LineMesh {
4722
4795
  vertexCount: number;
4723
4796
  indexCount: number;
4724
4797
  }
4798
+ interface LineOptions {
4799
+ /**
4800
+ * Уровень пересечения (см. `generators/level`): берём только фичи этого уровня.
4801
+ *
4802
+ * `undefined` — уровни не разделяем, слой строится целиком (так живут все слои, кроме дорожной
4803
+ * сети: у реки или границы пересечений без связи не бывает).
4804
+ */
4805
+ level?: number;
4806
+ }
4725
4807
  declare function generateLine(layer: VectorTileLayer, filter: Filter | undefined, maxSegment?: number,
4726
4808
  /** Уровни поверхностей тайла: по ним дорога ложится на то, по чему идёт. Нет — лежит на нуле. */
4727
4809
  ground?: GroundField,
4728
4810
  /** Метров в единице тайла. Ноль — плавный переход ширины на стыках не строится. */
4729
- metersPerUnit?: number): LineMesh | null;
4811
+ metersPerUnit?: number, opts?: LineOptions): LineMesh | null;
4812
+
4813
+ /**
4814
+ * УРОВЕНЬ ПЕРЕСЕЧЕНИЯ — какой из двух дорог быть сверху там, где они пересекаются без связи.
4815
+ *
4816
+ * ЗАЧЕМ. Плоская карта рисуется краской: слои идут в порядке стиля, и внутри слоя порядок фич
4817
+ * произволен. Поэтому эстакада над улицей ничем не отличалась от перекрёстка — обводки сливались,
4818
+ * полотна пересекались, и место читалось как съезд, которого в жизни нет. Ровно этим у Яндекса
4819
+ * занят `line-z-level` (`["get","z_level"]` у КАЖДОГО дорожного слоя, все они в одной сети
4820
+ * `line-network: "roads"`): сеть рисуется не по слоям, а по уровням, и мост со своей тенью и
4821
+ * обводкой целиком ложится поверх того, что под ним.
4822
+ *
4823
+ * ОТКУДА ЧИСЛО. Готового `z_level` в наших тайлах нет, зато есть то, из чего его считают:
4824
+ * `layer` — тег OSM, честный уровень (−1 подземный, 1 над землёй, изредка 2…5);
4825
+ * `brunnel` — «мост / тоннель / брод», он приходит и там, где `layer` не проставлен.
4826
+ * Поэтому берём `layer`, а если его нет — выводим уровень из `brunnel`. Мост без `layer`
4827
+ * (в Душанбе таких большинство) получает 1, тоннель — −1, обычная улица — 0.
4828
+ *
4829
+ * Считается в ВОРКЕРЕ, при тесселяции: по уровню бьётся меш, и рендеру остаётся только порядок.
4830
+ */
4831
+ /**
4832
+ * Дальше этого уровни не разводим. В OSM попадается и `layer=5`, и опечатки в сотни: каждое
4833
+ * значение — это отдельный бакет и отдельный вызов отрисовки, поэтому хвост подрезаем. Пять этажей
4834
+ * развязки — больше, чем бывает на настоящих.
4835
+ */
4836
+ declare const LEVEL_LIMIT = 5;
4837
+ /** Уровень фичи: `layer` из тегов, иначе вывод из `brunnel`. */
4838
+ declare function featureLevel(props: Record<string, unknown>): number;
4730
4839
 
4731
4840
  /**
4732
4841
  * Положение камеры в адресе страницы.
@@ -5682,4 +5791,4 @@ declare class Map$1 extends Evented<MapEvents> {
5682
5791
  destroy(): void;
5683
5792
  }
5684
5793
 
5685
- export { type AnimationOptions, AssetLoader, type AssetLoaderOptions, BASE_SOURCE, BUILDING_HEIGHT_SCALE, BUILDING_VERTEX_STRIDE, type BuildingHit, type BuildingsMesh, CITY_STYLE, type CameraOptions, Circle, type CircleOptions, type CoverOptions, DEFAULT_ICONS, DEFAULT_LIGHT, DEFAULT_SHADOWS, DEFAULT_SKY, DEFAULT_STYLE, DepthTarget, type DeviceHints, EARTH_CIRCUMFERENCE, FILL_VERTEX_STRIDE, type Filter, type FitBoundsOptions, type FitViewport, type FogPlanes, GLOBE_MAX_PITCH, GLOBE_ZOOM_MAX, GLOBE_ZOOM_MIN, GLYPH_BORDER, GLYPH_SIZE, GROUND_SCALE, GeomType, type GestureOptions, type Glyph, type GlyphMetric, GlyphSource, GroundArrows, IconSource, IndoorMask, type Interpolated, LINE_VERTEX_STRIDE, type LayerPlan, LayerRenderer, type LightSpec, type LinePlacement, type LngLat, LngLatBounds, type LngLatLike, MAX_LATITUDE, MODEL_VERTEX_STRIDE, Map$1 as Map, type MapEvents, MapObject, type MapObjectOptions, type MapOptions, Marker, type MarkerOptions, Model, ModelLayer, type ModelMesh, type ModelOptions, type ModelPrimitive, ObjectManager, type ObjectPaint, type ObjectPart, type Padding, type PlacedGlyph, type PlacedSymbol, Polygon, type PolygonOptions, Polyline, type PolylineOptions, type PolylineSegment, Popup, type PopupOptions, type Projection, type QualityName, type QualityProfile, RELIEF_STYLE, RUNTIME_FILL_STRIDE, RUNTIME_LINE_STRIDE, RasterSource, type RasterSourceOptions, RasterTile, type RoundOptions, type RuntimeMesh, SDF_EDGE, SDF_PX, SOFT_STYLE, SPLIT_SEP, SURFACE_CUT_BLEED, SURFACE_LEVEL_SCALE, SURFACE_VERTEX_STRIDE, type ScreenPoint$1 as ScreenPoint, SdfAtlas, type ShadowSettings, type SkySpec, Style, type StyleLayerSpec, type StyleSpec, type SymbolHit, SymbolRenderer, THEMES, TILE_SIZE, type ThemeSpec, TileID, Transform, VectorTile, VectorTileFeature, VectorTileLayer, abbreviateStreet, addGround, altitudeFromMercatorZ, applyTheme, arrowLabelOffset, arrowVertices, buildRuntimeFill, buildRuntimeLine, cameraForBounds, circumferenceAtLatitude, clampLat, clampPixelRatio, clipLineToRect, coordinateDigits, coveringTiles, createGround, Map$1 as default, deviceHints, distToSegment, evaluateColor, evaluateNumber, extractFeature, fillFootprint, fogPlanes, footprintOf, formatHash, generateBuildings, generateFill, generateLine, generateSurface, generateSymbols, globeBasis, globeFlatMix, globeRadius, globeToLocal, groundAt, iconRotation, insideFootprint, latFromMercatorY, lngFromMercatorX, lngLatToUnit, matchesFilter, mercatorMetersPerTile, mercatorX, mercatorY, mercatorZFromAltitude, metersPerPixel, metersPerTile, nextQualityDown, parseGlb, parseGlbAsync, parseGlyphs, parseHash, patchUV, pickBuilding, pickFill, pitchIntent, pixelsPerMeter, placeAlongLine, pointInRing, qualityFor, qualityProfile, raySphere, resolveTemplate, roundRing, sdfFromAlpha, shapeText, splitBucketKey, splitByGround, splitPolygons, styleWithTheme, tileOriginMeters, tileUrl, toLngLat, unitToLngLat, worldSize };
5794
+ export { type AnimationOptions, AssetLoader, type AssetLoaderOptions, BASE_SOURCE, BUILDING_HEIGHT_SCALE, BUILDING_VERTEX_STRIDE, type BuildingHit, type BuildingsMesh, CITY_STYLE, type CameraOptions, Circle, type CircleOptions, type CoverOptions, DEFAULT_ICONS, DEFAULT_LIGHT, DEFAULT_SHADOWS, DEFAULT_SKY, DEFAULT_STYLE, DepthTarget, type DeviceHints, EARTH_CIRCUMFERENCE, FILL_VERTEX_STRIDE, type Filter, type FitBoundsOptions, type FitViewport, type FogPlanes, GLOBE_MAX_PITCH, GLOBE_ZOOM_MAX, GLOBE_ZOOM_MIN, GLYPH_BORDER, GLYPH_SIZE, GROUND_SCALE, GeomType, type GestureOptions, type Glyph, type GlyphMetric, GlyphSource, GroundArrows, IconSource, IndoorMask, type Interpolated, LEVEL_LIMIT, LINE_VERTEX_STRIDE, type LayerPlan, LayerRenderer, type LightSpec, type LinePlacement, type LngLat, LngLatBounds, type LngLatLike, MAX_LATITUDE, MODEL_VERTEX_STRIDE, Map$1 as Map, type MapEvents, MapObject, type MapObjectOptions, type MapOptions, Marker, type MarkerOptions, Model, ModelLayer, type ModelMesh, type ModelOptions, type ModelPrimitive, ObjectManager, type ObjectPaint, type ObjectPart, type Padding, type PlacedGlyph, type PlacedSymbol, Polygon, type PolygonOptions, Polyline, type PolylineOptions, type PolylineSegment, Popup, type PopupOptions, type Projection, type QualityName, type QualityProfile, RELIEF_STYLE, RUNTIME_FILL_STRIDE, RUNTIME_LINE_STRIDE, RasterSource, type RasterSourceOptions, RasterTile, type RoundOptions, type RuntimeMesh, SDF_EDGE, SDF_PX, SOFT_STYLE, SPLIT_SEP, SURFACE_CUT_BLEED, SURFACE_LEVEL_SCALE, SURFACE_VERTEX_STRIDE, type ScreenPoint$1 as ScreenPoint, SdfAtlas, type ShadowSettings, type SkySpec, Style, type StyleLayerSpec, type StyleSpec, type SymbolHit, SymbolRenderer, THEMES, TILE_SIZE, type ThemeSpec, TileID, Transform, VectorTile, VectorTileFeature, VectorTileLayer, abbreviateStreet, addGround, altitudeFromMercatorZ, applyTheme, arrowLabelOffset, arrowVertices, buildRuntimeFill, buildRuntimeLine, cameraForBounds, circumferenceAtLatitude, clampLat, clampPixelRatio, clipLineToRect, coordinateDigits, coveringTiles, createGround, Map$1 as default, deviceHints, distToSegment, evaluateColor, evaluateNumber, extractFeature, featureLevel, fillFootprint, fogPlanes, footprintOf, formatHash, generateBuildings, generateFill, generateLine, generateSurface, generateSymbols, globeBasis, globeFlatMix, globeRadius, globeToLocal, groundAt, iconRotation, insideFootprint, latFromMercatorY, lngFromMercatorX, lngLatToUnit, matchesFilter, mercatorMetersPerTile, mercatorX, mercatorY, mercatorZFromAltitude, metersPerPixel, metersPerTile, nextQualityDown, parseGlb, parseGlbAsync, parseGlyphs, parseHash, patchUV, pickBuilding, pickFill, pitchIntent, pixelsPerMeter, placeAlongLine, pointInRing, qualityFor, qualityProfile, raySphere, resolveTemplate, roundRing, sdfFromAlpha, shapeText, splitBucketKey, splitByGround, splitPolygons, styleWithTheme, tileOriginMeters, tileUrl, toLngLat, unitToLngLat, worldSize };