@chrtco/sdk 0.7.2 → 0.7.4
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/atlas/browser.cjs.map +1 -1
- package/dist/atlas/browser.js.map +1 -1
- package/dist/index.cjs +954 -155
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +954 -155
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1307,6 +1307,32 @@ var S52_LOOKUP = {
|
|
|
1307
1307
|
viewingGroup: 13050,
|
|
1308
1308
|
scamin: 45e3
|
|
1309
1309
|
},
|
|
1310
|
+
// Unsurveyed area — a polygon where no reliable hydrographic survey
|
|
1311
|
+
// exists. The IHO S-52 PresLib portrayal is the hatched pattern
|
|
1312
|
+
// UNSURV03 (diagonal lines over a faint grey wash); we don't carry
|
|
1313
|
+
// that sprite, so we lean on the existing OPAQUE_FILLS treatment in
|
|
1314
|
+
// `layer-builder.ts` to force a fully-opaque grey fill that visibly
|
|
1315
|
+
// suppresses anything underneath. The "no data here — don't assume
|
|
1316
|
+
// safe water" signal is the entire point; UNSARE rendering is a BASE
|
|
1317
|
+
// display-category obligation, not an optional cue.
|
|
1318
|
+
//
|
|
1319
|
+
// Note: `UNSARE` is already a member of `OPAQUE_FILLS` and
|
|
1320
|
+
// `OPAQUE_FILL_LAYERS` in `layer-builder.ts` and `style-resolver.ts`
|
|
1321
|
+
// — half-wired before this entry landed. Adding the lookup entry +
|
|
1322
|
+
// draw-order slot completes the wire-up. Surfaced by the
|
|
1323
|
+
// `Audit S-57 Layer Coverage (Weekly)` workflow (issue #575); 5
|
|
1324
|
+
// features in the NOAA corpus, all in remote-Alaska coverage gaps
|
|
1325
|
+
// where survey is genuinely absent.
|
|
1326
|
+
UNSARE: {
|
|
1327
|
+
objectClass: "UNSARE",
|
|
1328
|
+
name: "Unsurveyed Area",
|
|
1329
|
+
category: "Depths",
|
|
1330
|
+
displayCategory: "BASE",
|
|
1331
|
+
int1Ref: "I27",
|
|
1332
|
+
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 1 } },
|
|
1333
|
+
viewingGroup: 13050,
|
|
1334
|
+
scamin: 0
|
|
1335
|
+
},
|
|
1310
1336
|
// ── Land & Shoreline (INT1 Section C) ───────────────────
|
|
1311
1337
|
LNDARE: {
|
|
1312
1338
|
objectClass: "LNDARE",
|
|
@@ -1459,6 +1485,51 @@ var S52_LOOKUP = {
|
|
|
1459
1485
|
viewingGroup: 12050,
|
|
1460
1486
|
scamin: 45e3
|
|
1461
1487
|
},
|
|
1488
|
+
// Rapids — direct navigation hazard in narrows / river constrictions. S-52
|
|
1489
|
+
// INT1 C24 portrayal: a stylised wavy line representing turbulent water.
|
|
1490
|
+
// We use a blue dashed line (DEPVS) so the feature reads as a water
|
|
1491
|
+
// disturbance — same colour family as the depth tints, distinct from the
|
|
1492
|
+
// black coastal-construction line family. Surfaced by the weekly layer-
|
|
1493
|
+
// coverage audit (issue #575); 4 features in the NOAA corpus, all in
|
|
1494
|
+
// freshwater approaches where a small craft could be swept onto rocks.
|
|
1495
|
+
RAPIDS: {
|
|
1496
|
+
objectClass: "RAPIDS",
|
|
1497
|
+
name: "Rapids",
|
|
1498
|
+
category: "Hazards",
|
|
1499
|
+
displayCategory: "STANDARD",
|
|
1500
|
+
int1Ref: "C24",
|
|
1501
|
+
style: { type: "line", paint: { "line-color": "DEPVS", "line-width": 1, "line-dasharray": [3, 2] } },
|
|
1502
|
+
viewingGroup: 24020,
|
|
1503
|
+
scamin: 45e3
|
|
1504
|
+
},
|
|
1505
|
+
// Dyke — physical earth/stone embankment that confines water. Same
|
|
1506
|
+
// black-line family as SLCONS / FNCLNE / CAUSWY: solid CHBLK so the
|
|
1507
|
+
// structure reads as a hard man-made shoreline modification. INT1 F8.
|
|
1508
|
+
// Surfaced by the weekly layer-coverage audit (issue #575); 13 features
|
|
1509
|
+
// in the NOAA corpus.
|
|
1510
|
+
DYKCON: {
|
|
1511
|
+
objectClass: "DYKCON",
|
|
1512
|
+
name: "Dyke",
|
|
1513
|
+
category: "Land",
|
|
1514
|
+
displayCategory: "STANDARD",
|
|
1515
|
+
int1Ref: "F8",
|
|
1516
|
+
style: { type: "line", paint: { "line-color": "CHBLK", "line-width": 1 } },
|
|
1517
|
+
viewingGroup: 12410,
|
|
1518
|
+
scamin: 22e3
|
|
1519
|
+
},
|
|
1520
|
+
// Causeway — raised road or rail bed across tidal flats or shallow water
|
|
1521
|
+
// (Cape Cod, the Florida Keys, etc.). Black-line family alongside DYKCON.
|
|
1522
|
+
// INT1 F3. Surfaced by the weekly layer-coverage audit (issue #575).
|
|
1523
|
+
CAUSWY: {
|
|
1524
|
+
objectClass: "CAUSWY",
|
|
1525
|
+
name: "Causeway",
|
|
1526
|
+
category: "Infrastructure",
|
|
1527
|
+
displayCategory: "STANDARD",
|
|
1528
|
+
int1Ref: "F3",
|
|
1529
|
+
style: { type: "line", paint: { "line-color": "CHBLK", "line-width": 1 } },
|
|
1530
|
+
viewingGroup: 12410,
|
|
1531
|
+
scamin: 22e3
|
|
1532
|
+
},
|
|
1462
1533
|
TUNNEL: {
|
|
1463
1534
|
objectClass: "TUNNEL",
|
|
1464
1535
|
name: "Tunnel",
|
|
@@ -1656,6 +1727,13 @@ var S52_LOOKUP = {
|
|
|
1656
1727
|
scamin: 9e4
|
|
1657
1728
|
},
|
|
1658
1729
|
LNDELV: {
|
|
1730
|
+
// LineString variant (land contours) renders normally with the line
|
|
1731
|
+
// style below. Point variant ≈ spot elevation ("12m") on land — per
|
|
1732
|
+
// S-52 PresLib convention, marine displays suppress land spot heights
|
|
1733
|
+
// so they don't compete with safety-critical hydrography. The
|
|
1734
|
+
// `auditIgnore` flag silences the weekly layer-coverage audit for the
|
|
1735
|
+
// Point geom-type only; it does not disable the line rendering. See
|
|
1736
|
+
// #575 triage matrix for the full rationale.
|
|
1659
1737
|
objectClass: "LNDELV",
|
|
1660
1738
|
name: "Land Elevation",
|
|
1661
1739
|
category: "Land",
|
|
@@ -1663,7 +1741,8 @@ var S52_LOOKUP = {
|
|
|
1663
1741
|
int1Ref: "C10",
|
|
1664
1742
|
style: { type: "line", paint: { "line-color": "CHBRN", "line-width": 0.5 } },
|
|
1665
1743
|
viewingGroup: 12070,
|
|
1666
|
-
scamin: 22e3
|
|
1744
|
+
scamin: 22e3,
|
|
1745
|
+
auditIgnore: true
|
|
1667
1746
|
},
|
|
1668
1747
|
// ── Hazards (INT1 Section K) ────────────────────────────
|
|
1669
1748
|
OBSTRN: {
|
|
@@ -1749,7 +1828,15 @@ var S52_LOOKUP = {
|
|
|
1749
1828
|
int1Ref: "J1",
|
|
1750
1829
|
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 0.15 } },
|
|
1751
1830
|
viewingGroup: 14010,
|
|
1752
|
-
scamin: 22e3
|
|
1831
|
+
scamin: 22e3,
|
|
1832
|
+
// Point variant (NOAA encodes 2,709 SBDARE Points) is rendered as a
|
|
1833
|
+
// seabed-quality text label ("S"/"M"/"R" per S-52 INT1 J) via the
|
|
1834
|
+
// labels.ts path — see layer-builder.ts SBDARE special-case routing.
|
|
1835
|
+
// The layer-coverage audit script only inspects MapLibre layer filters
|
|
1836
|
+
// from buildLayersForClass(), so it can't see that the Point variant
|
|
1837
|
+
// is in fact rendered. Matches the SOUNDG precedent (auditIgnore +
|
|
1838
|
+
// text-via-labels.ts rendering — see s52-lookup.ts SOUNDG entry).
|
|
1839
|
+
auditIgnore: true
|
|
1753
1840
|
},
|
|
1754
1841
|
WEDKLP: {
|
|
1755
1842
|
// Translucent green fill suggests kelp/vegetation; Point variant (the
|
|
@@ -1766,6 +1853,23 @@ var S52_LOOKUP = {
|
|
|
1766
1853
|
viewingGroup: 14010,
|
|
1767
1854
|
scamin: 22e3
|
|
1768
1855
|
},
|
|
1856
|
+
// Oil barrier — a deployed containment boom corralling spilled oil or
|
|
1857
|
+
// marking the perimeter of a spill-response operation. Operational
|
|
1858
|
+
// hazard: small craft must avoid crossing the line (and the polluted
|
|
1859
|
+
// water it contains). S-52 has no formal INT1 entry, but PresLib
|
|
1860
|
+
// convention for spill-response gear is magenta — matches the rest of
|
|
1861
|
+
// the regulated/operational-area portrayal family. Dashed line so it
|
|
1862
|
+
// reads as a temporary/operational marker rather than a permanent
|
|
1863
|
+
// structure. Surfaced by the weekly layer-coverage audit (issue #575).
|
|
1864
|
+
OILBAR: {
|
|
1865
|
+
objectClass: "OILBAR",
|
|
1866
|
+
name: "Oil Barrier",
|
|
1867
|
+
category: "Hazards",
|
|
1868
|
+
displayCategory: "STANDARD",
|
|
1869
|
+
style: { type: "line", paint: { "line-color": "CHMGD", "line-width": 1, "line-dasharray": [4, 2] } },
|
|
1870
|
+
viewingGroup: 24020,
|
|
1871
|
+
scamin: 45e3
|
|
1872
|
+
},
|
|
1769
1873
|
// ── Regulated Areas (INT1 Section N) ────────────────────
|
|
1770
1874
|
ACHARE: {
|
|
1771
1875
|
// Anchorages are conventionally rendered as a subtle filled region in
|
|
@@ -1939,6 +2043,196 @@ var S52_LOOKUP = {
|
|
|
1939
2043
|
viewingGroup: 26050,
|
|
1940
2044
|
scamin: 9e4
|
|
1941
2045
|
},
|
|
2046
|
+
// ── Jurisdictional zones (INT1 Section N) ───────────────
|
|
2047
|
+
// ADMARE / COSARE / CONZNE / EXEZNE / TESARE share an S-52 portrayal
|
|
2048
|
+
// family: magenta dashed boundary, no fill. These are vast offshore
|
|
2049
|
+
// polygons (EEZ extends 200nm, contiguous zone 24nm) where a flood fill
|
|
2050
|
+
// — even at 0.05 opacity — would visibly tint half the chart and stack
|
|
2051
|
+
// with overlapping jurisdictions into a purple wash. Same boundary-only
|
|
2052
|
+
// pattern as TESARE / RESARE / CTNARE via LINE_FROM_POLYGON_LAYERS.
|
|
2053
|
+
// Surfaced by the weekly layer-coverage audit (issue #575 rows 8–15).
|
|
2054
|
+
ADMARE: {
|
|
2055
|
+
// Administration area — state/national waters, the broadest
|
|
2056
|
+
// jurisdictional polygon class. INT1 N40 maps it into the same
|
|
2057
|
+
// magenta-dashed family as territorial-sea / EEZ / contiguous-zone.
|
|
2058
|
+
objectClass: "ADMARE",
|
|
2059
|
+
name: "Administration Area",
|
|
2060
|
+
category: "Regulated Areas",
|
|
2061
|
+
displayCategory: "STANDARD",
|
|
2062
|
+
int1Ref: "N40",
|
|
2063
|
+
style: {
|
|
2064
|
+
type: "line",
|
|
2065
|
+
paint: {
|
|
2066
|
+
"line-color": "CHMGD",
|
|
2067
|
+
"line-width": 1,
|
|
2068
|
+
"line-dasharray": [6, 4],
|
|
2069
|
+
"line-opacity": 0.6
|
|
2070
|
+
}
|
|
2071
|
+
},
|
|
2072
|
+
viewingGroup: 26010,
|
|
2073
|
+
scamin: 9e4
|
|
2074
|
+
},
|
|
2075
|
+
COSARE: {
|
|
2076
|
+
// Coastal area — jurisdictional polygon delineating a coastal-state
|
|
2077
|
+
// administrative region. Previously suppressed via META_LAYERS in
|
|
2078
|
+
// style-generator.ts; promoted here to render as a magenta dashed
|
|
2079
|
+
// boundary alongside the rest of the N-section jurisdiction family.
|
|
2080
|
+
objectClass: "COSARE",
|
|
2081
|
+
name: "Coastal Area",
|
|
2082
|
+
category: "Regulated Areas",
|
|
2083
|
+
displayCategory: "STANDARD",
|
|
2084
|
+
int1Ref: "N40",
|
|
2085
|
+
style: {
|
|
2086
|
+
type: "line",
|
|
2087
|
+
paint: {
|
|
2088
|
+
"line-color": "CHMGD",
|
|
2089
|
+
"line-width": 1,
|
|
2090
|
+
"line-dasharray": [6, 4],
|
|
2091
|
+
"line-opacity": 0.6
|
|
2092
|
+
}
|
|
2093
|
+
},
|
|
2094
|
+
viewingGroup: 26010,
|
|
2095
|
+
scamin: 9e4
|
|
2096
|
+
},
|
|
2097
|
+
CONZNE: {
|
|
2098
|
+
// Contiguous Zone — 24nm offshore boundary. Same magenta dashed
|
|
2099
|
+
// portrayal as territorial sea; boundary-only because the polygon is
|
|
2100
|
+
// vast and a flood fill would obscure huge swathes of chart data.
|
|
2101
|
+
objectClass: "CONZNE",
|
|
2102
|
+
name: "Contiguous Zone",
|
|
2103
|
+
category: "Regulated Areas",
|
|
2104
|
+
displayCategory: "STANDARD",
|
|
2105
|
+
int1Ref: "N44",
|
|
2106
|
+
style: {
|
|
2107
|
+
type: "line",
|
|
2108
|
+
paint: {
|
|
2109
|
+
"line-color": "CHMGD",
|
|
2110
|
+
"line-width": 1,
|
|
2111
|
+
"line-dasharray": [6, 4],
|
|
2112
|
+
"line-opacity": 0.6
|
|
2113
|
+
}
|
|
2114
|
+
},
|
|
2115
|
+
viewingGroup: 26010,
|
|
2116
|
+
scamin: 9e4
|
|
2117
|
+
},
|
|
2118
|
+
EXEZNE: {
|
|
2119
|
+
// Exclusive Economic Zone — 200nm offshore boundary. Largest of the
|
|
2120
|
+
// jurisdictional polygons; flood-filling even at 0.05 opacity would
|
|
2121
|
+
// tint half the chart at coastal zooms. Boundary-only is the only
|
|
2122
|
+
// sensible portrayal at scale.
|
|
2123
|
+
objectClass: "EXEZNE",
|
|
2124
|
+
name: "Exclusive Economic Zone",
|
|
2125
|
+
category: "Regulated Areas",
|
|
2126
|
+
displayCategory: "STANDARD",
|
|
2127
|
+
int1Ref: "N47",
|
|
2128
|
+
style: {
|
|
2129
|
+
type: "line",
|
|
2130
|
+
paint: {
|
|
2131
|
+
"line-color": "CHMGD",
|
|
2132
|
+
"line-width": 1,
|
|
2133
|
+
"line-dasharray": [6, 4],
|
|
2134
|
+
"line-opacity": 0.6
|
|
2135
|
+
}
|
|
2136
|
+
},
|
|
2137
|
+
viewingGroup: 26010,
|
|
2138
|
+
scamin: 9e4
|
|
2139
|
+
},
|
|
2140
|
+
// ── IMO routing measures (INT1 Section M) ───────────────
|
|
2141
|
+
// TSEZNE / DWRTPT / DWRTCL / TWRTPT are IMO-adopted routing measures
|
|
2142
|
+
// (Traffic Separation Scheme zones, deepwater routes, two-way routes).
|
|
2143
|
+
// S-52 portrayal: magenta dashed boundary for polygons, dashed centerline
|
|
2144
|
+
// for the LineString. The INT1 M-section spec calls for additional
|
|
2145
|
+
// diagonal hatching (TSSCRS01 sprite) on TSEZNE and "DW" centroid text
|
|
2146
|
+
// on DWRTPT — both are deferred follow-ups (TSSCRS01 not in the atlas
|
|
2147
|
+
// sprite set; centroid text belongs in labels.ts). Boundary visibility
|
|
2148
|
+
// is the priority cue here; routing-text augmentation comes later.
|
|
2149
|
+
TSEZNE: {
|
|
2150
|
+
// Traffic Separation Zone — the buffer band between opposing lanes of
|
|
2151
|
+
// a TSS. S-52 INT1 M14 calls for T-pattern diagonal hatching
|
|
2152
|
+
// (TSSCRS01) but that sprite isn't in our generated atlas; fall back
|
|
2153
|
+
// to a magenta dashed boundary so the zone is at least visible.
|
|
2154
|
+
objectClass: "TSEZNE",
|
|
2155
|
+
name: "Traffic Separation Zone",
|
|
2156
|
+
category: "Regulated Areas",
|
|
2157
|
+
displayCategory: "STANDARD",
|
|
2158
|
+
int1Ref: "M14",
|
|
2159
|
+
style: {
|
|
2160
|
+
type: "line",
|
|
2161
|
+
paint: {
|
|
2162
|
+
"line-color": "CHMGD",
|
|
2163
|
+
"line-width": 1.2,
|
|
2164
|
+
"line-dasharray": [4, 3],
|
|
2165
|
+
"line-opacity": 0.7
|
|
2166
|
+
}
|
|
2167
|
+
},
|
|
2168
|
+
viewingGroup: 26010,
|
|
2169
|
+
scamin: 9e4
|
|
2170
|
+
},
|
|
2171
|
+
DWRTPT: {
|
|
2172
|
+
// Deepwater Route Part — polygon segment of an IMO-adopted deepwater
|
|
2173
|
+
// route. S-52 INT1 M27 portrayal includes "DW" centroid text; that's
|
|
2174
|
+
// a labels.ts addition deferred to a follow-up. Boundary-only here.
|
|
2175
|
+
objectClass: "DWRTPT",
|
|
2176
|
+
name: "Deepwater Route Part",
|
|
2177
|
+
category: "Regulated Areas",
|
|
2178
|
+
displayCategory: "STANDARD",
|
|
2179
|
+
int1Ref: "M27",
|
|
2180
|
+
style: {
|
|
2181
|
+
type: "line",
|
|
2182
|
+
paint: {
|
|
2183
|
+
"line-color": "CHMGD",
|
|
2184
|
+
"line-width": 1.2,
|
|
2185
|
+
"line-dasharray": [4, 3],
|
|
2186
|
+
"line-opacity": 0.7
|
|
2187
|
+
}
|
|
2188
|
+
},
|
|
2189
|
+
viewingGroup: 26010,
|
|
2190
|
+
scamin: 9e4
|
|
2191
|
+
},
|
|
2192
|
+
DWRTCL: {
|
|
2193
|
+
// Deepwater Route Centerline — LineString feature (not a polygon
|
|
2194
|
+
// boundary) running down the middle of a DWRTPT. Same magenta dashed
|
|
2195
|
+
// style as MAGVAR isogonic lines but slightly heavier so the
|
|
2196
|
+
// route-axis cue reads against busy water.
|
|
2197
|
+
objectClass: "DWRTCL",
|
|
2198
|
+
name: "Deepwater Route Centerline",
|
|
2199
|
+
category: "Regulated Areas",
|
|
2200
|
+
displayCategory: "STANDARD",
|
|
2201
|
+
int1Ref: "M27",
|
|
2202
|
+
style: {
|
|
2203
|
+
type: "line",
|
|
2204
|
+
paint: {
|
|
2205
|
+
"line-color": "CHMGD",
|
|
2206
|
+
"line-width": 0.8,
|
|
2207
|
+
"line-dasharray": [6, 3],
|
|
2208
|
+
"line-opacity": 0.7
|
|
2209
|
+
}
|
|
2210
|
+
},
|
|
2211
|
+
viewingGroup: 26010,
|
|
2212
|
+
scamin: 9e4
|
|
2213
|
+
},
|
|
2214
|
+
TWRTPT: {
|
|
2215
|
+
// Two-Way Route Part — polygon segment of an IMO-adopted two-way
|
|
2216
|
+
// route. S-52 INT1 M28 portrayal includes paired arrow centroid
|
|
2217
|
+
// symbols (TWRTPT52 / TWRTPT53 sprites exist in the atlas but are a
|
|
2218
|
+
// labels.ts follow-up). Boundary-only here.
|
|
2219
|
+
objectClass: "TWRTPT",
|
|
2220
|
+
name: "Two-Way Route Part",
|
|
2221
|
+
category: "Regulated Areas",
|
|
2222
|
+
displayCategory: "STANDARD",
|
|
2223
|
+
int1Ref: "M28",
|
|
2224
|
+
style: {
|
|
2225
|
+
type: "line",
|
|
2226
|
+
paint: {
|
|
2227
|
+
"line-color": "CHMGD",
|
|
2228
|
+
"line-width": 1.2,
|
|
2229
|
+
"line-dasharray": [4, 3],
|
|
2230
|
+
"line-opacity": 0.7
|
|
2231
|
+
}
|
|
2232
|
+
},
|
|
2233
|
+
viewingGroup: 26010,
|
|
2234
|
+
scamin: 9e4
|
|
2235
|
+
},
|
|
1942
2236
|
// ── Infrastructure (INT1 Sections D, F, L) ──────────────
|
|
1943
2237
|
BRIDGE: {
|
|
1944
2238
|
objectClass: "BRIDGE",
|
|
@@ -2247,6 +2541,56 @@ var S52_LOOKUP = {
|
|
|
2247
2541
|
viewingGroup: 12410,
|
|
2248
2542
|
scamin: 22e3
|
|
2249
2543
|
},
|
|
2544
|
+
// Coast Guard station — emergency-response context. Mariners look for
|
|
2545
|
+
// these when navigating unfamiliar coastline or planning a distress-call
|
|
2546
|
+
// contingency. INT1 F62. Symbolised with the same generic tower glyph
|
|
2547
|
+
// (BCNTOW01) used by BUISGL and the CATLMK=17 LNDMRK variant — a
|
|
2548
|
+
// dedicated CGUSTA SVG is a reasonable follow-up but not required for
|
|
2549
|
+
// the structural-presence cue. Surfaced by the weekly layer-coverage
|
|
2550
|
+
// audit (issue #575); 17 Point features in the NOAA corpus.
|
|
2551
|
+
CGUSTA: {
|
|
2552
|
+
objectClass: "CGUSTA",
|
|
2553
|
+
name: "Coast Guard Station",
|
|
2554
|
+
category: "Infrastructure",
|
|
2555
|
+
displayCategory: "OTHER",
|
|
2556
|
+
int1Ref: "F62",
|
|
2557
|
+
style: { type: "symbol", paint: {}, layout: { "icon-size": 0.6, "icon-allow-overlap": true }, iconImage: "BCNTOW01" },
|
|
2558
|
+
viewingGroup: 12410,
|
|
2559
|
+
scamin: 22e3
|
|
2560
|
+
},
|
|
2561
|
+
// "New Object" — S-57 placeholder class for features the issuing HO has
|
|
2562
|
+
// identified but not yet classified into a more specific class. S-52
|
|
2563
|
+
// PresLib does NOT formally define a portrayal because the class is by
|
|
2564
|
+
// construction not-yet-portrayable, so any distinctive symbol is
|
|
2565
|
+
// permissible — we use a vivid magenta-filled circle with a bold black
|
|
2566
|
+
// stroke so a mariner sees clearly that "there is something unclassified
|
|
2567
|
+
// here." Hiding this class would amount to hiding the HO's own
|
|
2568
|
+
// uncertainty marker, which is the exact opposite of what a chart user
|
|
2569
|
+
// needs. displayCategory: STANDARD (not OTHER) so a default-display
|
|
2570
|
+
// mariner cannot accidentally suppress it; scamin: 0 so the marker
|
|
2571
|
+
// stays visible at every scale band. Surfaced by the weekly layer-
|
|
2572
|
+
// coverage audit (issue #575); 8 Point features in the NOAA corpus.
|
|
2573
|
+
// SAFETY CONTRACT: any future "clean up unused magenta point classes"
|
|
2574
|
+
// pass MUST NOT delete or hide this entry — read the comment block on
|
|
2575
|
+
// issue #575 row 22 before touching.
|
|
2576
|
+
NEWOBJ: {
|
|
2577
|
+
objectClass: "NEWOBJ",
|
|
2578
|
+
name: "New Object (Unclassified)",
|
|
2579
|
+
category: "Hazards",
|
|
2580
|
+
displayCategory: "STANDARD",
|
|
2581
|
+
style: {
|
|
2582
|
+
type: "circle",
|
|
2583
|
+
paint: {
|
|
2584
|
+
"circle-color": "CHMGD",
|
|
2585
|
+
"circle-radius": 5,
|
|
2586
|
+
"circle-stroke-color": "CHBLK",
|
|
2587
|
+
"circle-stroke-width": 1.2,
|
|
2588
|
+
"circle-opacity": 0.85
|
|
2589
|
+
}
|
|
2590
|
+
},
|
|
2591
|
+
viewingGroup: 24020,
|
|
2592
|
+
scamin: 0
|
|
2593
|
+
},
|
|
2250
2594
|
// ── Overhead & Underground (INT1 Section L) ─────────────
|
|
2251
2595
|
// Overhead cable — S-52 INT1 L31 portrayal: solid thin magenta line
|
|
2252
2596
|
// (not dashed) because overhead cables are an in-air navigation hazard
|
|
@@ -2298,6 +2642,11 @@ var S52_LOOKUP = {
|
|
|
2298
2642
|
// when the sprite image is missing; `fill-pattern` here is the default
|
|
2299
2643
|
// used if the conditional expression isn't applied for some reason
|
|
2300
2644
|
// (e.g. a consumer that bypasses `resolvePaint`).
|
|
2645
|
+
//
|
|
2646
|
+
// Polygon (vegetation fill) is the primary variant. The Point variant
|
|
2647
|
+
// ≈ a single marker tree; sub-marine-relevance, so `auditIgnore`
|
|
2648
|
+
// silences the audit for the Point geom-type without touching the
|
|
2649
|
+
// Polygon rendering. See #575 triage matrix.
|
|
2301
2650
|
style: {
|
|
2302
2651
|
type: "fill",
|
|
2303
2652
|
paint: { "fill-color": "LANDF", "fill-opacity": 0.6, "fill-pattern": "VEGATN03" }
|
|
@@ -2305,7 +2654,8 @@ var S52_LOOKUP = {
|
|
|
2305
2654
|
hasConditional: true,
|
|
2306
2655
|
conditionalAttributes: ["CATVEG"],
|
|
2307
2656
|
viewingGroup: 12050,
|
|
2308
|
-
scamin: 22e3
|
|
2657
|
+
scamin: 22e3,
|
|
2658
|
+
auditIgnore: true
|
|
2309
2659
|
},
|
|
2310
2660
|
SEAARE: {
|
|
2311
2661
|
// Cross-band water base. SEAARE polygons tile the sea below the
|
|
@@ -2484,6 +2834,42 @@ var S52_LOOKUP = {
|
|
|
2484
2834
|
viewingGroup: 23010,
|
|
2485
2835
|
scamin: 0
|
|
2486
2836
|
},
|
|
2837
|
+
// ── Audit-ignored stubs (non-metadata) ──────────────────
|
|
2838
|
+
// Classes whose non-rendering is a deliberate S-52 portrayal choice
|
|
2839
|
+
// rather than a real gap, but which aren't S-57 metadata. Each is
|
|
2840
|
+
// present here only so the weekly layer-coverage audit (#575) stops
|
|
2841
|
+
// flagging it as missing. Paint is a transparent fill — no visible
|
|
2842
|
+
// output. Swapping `auditIgnore: true` for a real style is a one-line
|
|
2843
|
+
// change if the call ever needs to be reversed.
|
|
2844
|
+
SLOTOP: {
|
|
2845
|
+
// Top of slope — land terrain feature, low marine relevance.
|
|
2846
|
+
objectClass: "SLOTOP",
|
|
2847
|
+
name: "Top of Slope",
|
|
2848
|
+
category: "Land",
|
|
2849
|
+
displayCategory: "OTHER",
|
|
2850
|
+
int1Ref: "C12",
|
|
2851
|
+
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 0 } },
|
|
2852
|
+
auditIgnore: true
|
|
2853
|
+
},
|
|
2854
|
+
SNDWAV: {
|
|
2855
|
+
// Sand waves — niche bathymetric texture feature, not a hazard.
|
|
2856
|
+
objectClass: "SNDWAV",
|
|
2857
|
+
name: "Sand Waves",
|
|
2858
|
+
category: "Depths",
|
|
2859
|
+
displayCategory: "OTHER",
|
|
2860
|
+
int1Ref: "J14",
|
|
2861
|
+
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 0 } },
|
|
2862
|
+
auditIgnore: true
|
|
2863
|
+
},
|
|
2864
|
+
CTRPNT: {
|
|
2865
|
+
// Centerline point — geometric helper, not a feature on the chart.
|
|
2866
|
+
objectClass: "CTRPNT",
|
|
2867
|
+
name: "Centerline Point",
|
|
2868
|
+
category: "Meta",
|
|
2869
|
+
displayCategory: "OTHER",
|
|
2870
|
+
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 0 } },
|
|
2871
|
+
auditIgnore: true
|
|
2872
|
+
},
|
|
2487
2873
|
// ── Meta (hidden by default) ────────────────────────────
|
|
2488
2874
|
// M_* and DSID are S-57 metadata classes — they describe the dataset
|
|
2489
2875
|
// (coverage extent, survey reliability, source publication, etc.) and
|
|
@@ -2522,6 +2908,17 @@ var S52_LOOKUP = {
|
|
|
2522
2908
|
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 0 } },
|
|
2523
2909
|
auditIgnore: true
|
|
2524
2910
|
},
|
|
2911
|
+
M_SDAT: {
|
|
2912
|
+
// Sounding Datum — S-57 metadata describing the vertical datum used
|
|
2913
|
+
// for soundings (typically LAT). Click-query attribute carrier; no
|
|
2914
|
+
// visible shape on its own.
|
|
2915
|
+
objectClass: "M_SDAT",
|
|
2916
|
+
name: "Sounding Datum",
|
|
2917
|
+
category: "Meta",
|
|
2918
|
+
displayCategory: "META",
|
|
2919
|
+
style: { type: "fill", paint: { "fill-color": "CHGRF", "fill-opacity": 0 } },
|
|
2920
|
+
auditIgnore: true
|
|
2921
|
+
},
|
|
2525
2922
|
M_SREL: {
|
|
2526
2923
|
objectClass: "M_SREL",
|
|
2527
2924
|
name: "Survey Reliability",
|
|
@@ -2561,6 +2958,16 @@ var S52_DRAW_ORDER = [
|
|
|
2561
2958
|
// paired paint-spec change (fill-opacity 0 → 1, color → DEPDW).
|
|
2562
2959
|
"SEAARE",
|
|
2563
2960
|
"DEPARE",
|
|
2961
|
+
// 2a. Unsurveyed area — opaque grey wash painted ON TOP of any DEPARE
|
|
2962
|
+
// tile within its extent so depth-tier colours can never imply the area
|
|
2963
|
+
// is surveyed-and-safe. If both DEPARE and UNSARE cover the same pixel,
|
|
2964
|
+
// UNSARE wins on purpose: the hydrographic office classified the polygon
|
|
2965
|
+
// as unsurveyed, so any depth data within it is suspect at best. Sits
|
|
2966
|
+
// below dredged / swept (which represent active survey work) so those
|
|
2967
|
+
// appear if they overlap UNSARE — but in practice they don't, and the
|
|
2968
|
+
// ordering is the safer fallback. Surfaced by the weekly layer-coverage
|
|
2969
|
+
// audit (issue #575); see s52-lookup.ts UNSARE entry for context.
|
|
2970
|
+
"UNSARE",
|
|
2564
2971
|
// 3. Dredged / swept areas (fill)
|
|
2565
2972
|
"DRGARE",
|
|
2566
2973
|
"SWPARE",
|
|
@@ -2598,6 +3005,17 @@ var S52_DRAW_ORDER = [
|
|
|
2598
3005
|
"LOGPON",
|
|
2599
3006
|
"CBLARE",
|
|
2600
3007
|
"PIPARE",
|
|
3008
|
+
// 6a. Jurisdictional zones + IMO routing measures (boundary-only via
|
|
3009
|
+
// LINE_FROM_POLYGON_LAYERS). Slotted at the end of the regulated-area
|
|
3010
|
+
// band so the dashed magenta boundaries paint above the fill family
|
|
3011
|
+
// but below shoreline / depth-contour lines. Closes #575 rows 8–15.
|
|
3012
|
+
"ADMARE",
|
|
3013
|
+
"COSARE",
|
|
3014
|
+
"CONZNE",
|
|
3015
|
+
"EXEZNE",
|
|
3016
|
+
"TSEZNE",
|
|
3017
|
+
"DWRTPT",
|
|
3018
|
+
"TWRTPT",
|
|
2601
3019
|
// 7. Infrastructure areas (fill)
|
|
2602
3020
|
"PONTON",
|
|
2603
3021
|
"HULKES",
|
|
@@ -2607,8 +3025,13 @@ var S52_DRAW_ORDER = [
|
|
|
2607
3025
|
"PYLONS",
|
|
2608
3026
|
"FORSTC",
|
|
2609
3027
|
// 8. Coastline / shore (line)
|
|
3028
|
+
// DYKCON (dyke) and CAUSWY (causeway) join the SLCONS family — solid
|
|
3029
|
+
// black lines representing man-made shoreline modifications. Drawn in
|
|
3030
|
+
// the same band so they layer consistently with adjacent SLCONS edges.
|
|
2610
3031
|
"COALNE",
|
|
2611
3032
|
"SLCONS",
|
|
3033
|
+
"DYKCON",
|
|
3034
|
+
"CAUSWY",
|
|
2612
3035
|
"FNCLNE",
|
|
2613
3036
|
// 9. Depth contours (line)
|
|
2614
3037
|
"DEPCNT",
|
|
@@ -2619,13 +3042,20 @@ var S52_DRAW_ORDER = [
|
|
|
2619
3042
|
// routing and aids-to-nav win the visual hierarchy).
|
|
2620
3043
|
"MAGVAR",
|
|
2621
3044
|
// 10. Navigation lines (line)
|
|
3045
|
+
// RAPIDS and OILBAR are direct/operational water hazards. RAPIDS uses
|
|
3046
|
+
// the depth-blue palette (DEPVS dashed) so the feature reads as a
|
|
3047
|
+
// water-surface disturbance; OILBAR uses CHMGD to fit the operational-
|
|
3048
|
+
// hazard family alongside cables / pipelines.
|
|
2622
3049
|
"NAVLNE",
|
|
2623
3050
|
"TSSBND",
|
|
3051
|
+
"DWRTCL",
|
|
2624
3052
|
"ROADWY",
|
|
2625
3053
|
"RAILWY",
|
|
2626
3054
|
"TUNNEL",
|
|
2627
3055
|
"FERYRT",
|
|
2628
3056
|
"RECTRC",
|
|
3057
|
+
"RAPIDS",
|
|
3058
|
+
"OILBAR",
|
|
2629
3059
|
"PIPSOL",
|
|
2630
3060
|
"PIPOHD",
|
|
2631
3061
|
"CBLSUB",
|
|
@@ -2634,6 +3064,11 @@ var S52_DRAW_ORDER = [
|
|
|
2634
3064
|
"DAMCON",
|
|
2635
3065
|
"BERTHS",
|
|
2636
3066
|
// 11. Point features
|
|
3067
|
+
// CGUSTA (coast guard station, emergency-context) sits with the building
|
|
3068
|
+
// / landmark family — a structural-presence cue rather than a routing
|
|
3069
|
+
// signal. NEWOBJ ("something here we haven't classified yet") goes at
|
|
3070
|
+
// the END of the point list so the distinctive magenta marker stays on
|
|
3071
|
+
// top of neighbouring point features and cannot be visually swallowed.
|
|
2637
3072
|
"SOUNDG",
|
|
2638
3073
|
"MORFAC",
|
|
2639
3074
|
"PILPNT",
|
|
@@ -2647,6 +3082,8 @@ var S52_DRAW_ORDER = [
|
|
|
2647
3082
|
"CRANES",
|
|
2648
3083
|
"DISMAR",
|
|
2649
3084
|
"ACHBRT",
|
|
3085
|
+
"CGUSTA",
|
|
3086
|
+
"NEWOBJ",
|
|
2650
3087
|
// 12. Nav aids (on top)
|
|
2651
3088
|
"FOGSIG",
|
|
2652
3089
|
"RTPBCN",
|
|
@@ -5264,6 +5701,7 @@ var SYMBOL_MAP = {
|
|
|
5264
5701
|
PILBOP: "PILBOP02",
|
|
5265
5702
|
SISTAT: "SISTAT02",
|
|
5266
5703
|
SMCFAC: "ACHARE02",
|
|
5704
|
+
CGUSTA: "BCNTOW01",
|
|
5267
5705
|
// Land infrastructure
|
|
5268
5706
|
SILTNK: "TNKCON02",
|
|
5269
5707
|
BUISGL: "BCNTOW01",
|
|
@@ -5862,6 +6300,15 @@ var NATQUA_ABBR = [
|
|
|
5862
6300
|
// hard
|
|
5863
6301
|
];
|
|
5864
6302
|
var DARK_BG = "#1a1d23";
|
|
6303
|
+
var NAV_HALO = {
|
|
6304
|
+
WHITE: { bright: "#ffffff", night: "#b8b0a0" },
|
|
6305
|
+
CREAM: { bright: "#fdf0b0", night: "#a89868" },
|
|
6306
|
+
YELLOW: { bright: "#eab308", night: "#806020" },
|
|
6307
|
+
BLUE: { bright: "#b0c8e8", night: "#7088a0" }
|
|
6308
|
+
};
|
|
6309
|
+
function navHalo(palette, ct) {
|
|
6310
|
+
return ct === "NIGHT" ? NAV_HALO[palette].night : NAV_HALO[palette].bright;
|
|
6311
|
+
}
|
|
5865
6312
|
var NAV_AID_LABEL_TEXT_SIZE = [
|
|
5866
6313
|
"interpolate",
|
|
5867
6314
|
["linear"],
|
|
@@ -5911,6 +6358,124 @@ function buildSeabedLabelExpression() {
|
|
|
5911
6358
|
const natsurJoined = ["slice", natsurParts, 1];
|
|
5912
6359
|
return ["concat", natquaPrefix, natsurJoined];
|
|
5913
6360
|
}
|
|
6361
|
+
function buildSeaAreaTierExpression() {
|
|
6362
|
+
const catsea = ["coalesce", ["get", "CATSEA"], ["get", "catsea"], 0];
|
|
6363
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6364
|
+
return [
|
|
6365
|
+
"case",
|
|
6366
|
+
// Tier 1 — Ocean (CATSEA=31 OR OBJNAM contains "Ocean", excluding
|
|
6367
|
+
// anchorage-area-style compound names which we filter on later).
|
|
6368
|
+
["==", ["to-number", catsea], 31],
|
|
6369
|
+
1,
|
|
6370
|
+
["any", ["==", ["to-number", catsea], 29], ["==", ["to-number", catsea], 30]],
|
|
6371
|
+
2,
|
|
6372
|
+
[
|
|
6373
|
+
"any",
|
|
6374
|
+
["==", ["to-number", catsea], 4],
|
|
6375
|
+
["==", ["to-number", catsea], 11],
|
|
6376
|
+
["==", ["to-number", catsea], 27],
|
|
6377
|
+
["==", ["to-number", catsea], 28]
|
|
6378
|
+
],
|
|
6379
|
+
3,
|
|
6380
|
+
// Tier 4 — Anchorage detail (must be checked before OBJNAM-substring
|
|
6381
|
+
// promotion so "Boston Harbor, MA …" anchorages don't bubble up).
|
|
6382
|
+
[">=", ["index-of", "Anchorage Area", objnam], 0],
|
|
6383
|
+
4,
|
|
6384
|
+
// OBJNAM-substring promotion shims (run AFTER tier 4 demotion):
|
|
6385
|
+
[">=", ["index-of", "Atlantic Ocean", objnam], 0],
|
|
6386
|
+
1,
|
|
6387
|
+
[">=", ["index-of", "Pacific Ocean", objnam], 0],
|
|
6388
|
+
1,
|
|
6389
|
+
[">=", ["index-of", "Arctic Ocean", objnam], 0],
|
|
6390
|
+
1,
|
|
6391
|
+
[">=", ["index-of", "Gulf of", objnam], 0],
|
|
6392
|
+
2,
|
|
6393
|
+
// Bay/Sound/Sea/Strait/Channel as a tier-3 shim (matches "Massachusetts
|
|
6394
|
+
// Bay", "Buzzards Bay", "Long Island Sound", "Block Island Sound",
|
|
6395
|
+
// "Vineyard Sound", "Cape Cod Bay", etc. without needing CATSEA).
|
|
6396
|
+
[">=", ["index-of", " Bay", objnam], 0],
|
|
6397
|
+
3,
|
|
6398
|
+
[">=", ["index-of", " Sound", objnam], 0],
|
|
6399
|
+
3,
|
|
6400
|
+
[">=", ["index-of", " Strait", objnam], 0],
|
|
6401
|
+
3,
|
|
6402
|
+
[">=", ["index-of", " Sea", objnam], 0],
|
|
6403
|
+
2,
|
|
6404
|
+
5
|
|
6405
|
+
];
|
|
6406
|
+
}
|
|
6407
|
+
function buildBuiltUpAreaTierExpression() {
|
|
6408
|
+
const catbua = ["coalesce", ["get", "CATBUA"], ["get", "catbua"], 0];
|
|
6409
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6410
|
+
const nameLen = ["length", objnam];
|
|
6411
|
+
return [
|
|
6412
|
+
"case",
|
|
6413
|
+
["==", ["to-number", catbua], 1],
|
|
6414
|
+
1,
|
|
6415
|
+
["==", ["to-number", catbua], 5],
|
|
6416
|
+
2,
|
|
6417
|
+
["<=", nameLen, 8],
|
|
6418
|
+
1,
|
|
6419
|
+
["<=", nameLen, 14],
|
|
6420
|
+
2,
|
|
6421
|
+
3
|
|
6422
|
+
];
|
|
6423
|
+
}
|
|
6424
|
+
function buildLandRegionTierExpression() {
|
|
6425
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6426
|
+
const nameLen = ["length", objnam];
|
|
6427
|
+
return [
|
|
6428
|
+
"case",
|
|
6429
|
+
["all", ["<=", nameLen, 12], ["==", ["index-of", ",", objnam], -1]],
|
|
6430
|
+
1,
|
|
6431
|
+
2
|
|
6432
|
+
];
|
|
6433
|
+
}
|
|
6434
|
+
function buildLandAreaTierExpression() {
|
|
6435
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6436
|
+
return [
|
|
6437
|
+
"case",
|
|
6438
|
+
["<=", ["length", objnam], 12],
|
|
6439
|
+
1,
|
|
6440
|
+
2
|
|
6441
|
+
];
|
|
6442
|
+
}
|
|
6443
|
+
function buildLakeTierExpression() {
|
|
6444
|
+
const catlak = ["coalesce", ["get", "CATLAK"], ["get", "catlak"], 0];
|
|
6445
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6446
|
+
return [
|
|
6447
|
+
"case",
|
|
6448
|
+
["==", ["to-number", catlak], 1],
|
|
6449
|
+
1,
|
|
6450
|
+
["any", ["==", ["to-number", catlak], 2], ["==", ["to-number", catlak], 3]],
|
|
6451
|
+
2,
|
|
6452
|
+
["<=", ["length", objnam], 12],
|
|
6453
|
+
1,
|
|
6454
|
+
2
|
|
6455
|
+
];
|
|
6456
|
+
}
|
|
6457
|
+
function buildRiverTierExpression() {
|
|
6458
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6459
|
+
return [
|
|
6460
|
+
"case",
|
|
6461
|
+
[
|
|
6462
|
+
"all",
|
|
6463
|
+
["<=", ["length", objnam], 15],
|
|
6464
|
+
["==", ["index-of", ",", objnam], -1]
|
|
6465
|
+
],
|
|
6466
|
+
1,
|
|
6467
|
+
2
|
|
6468
|
+
];
|
|
6469
|
+
}
|
|
6470
|
+
function buildAirportTierExpression() {
|
|
6471
|
+
const objnam = ["coalesce", ["get", "OBJNAM"], ""];
|
|
6472
|
+
return [
|
|
6473
|
+
"case",
|
|
6474
|
+
["<=", ["length", objnam], 25],
|
|
6475
|
+
1,
|
|
6476
|
+
2
|
|
6477
|
+
];
|
|
6478
|
+
}
|
|
5914
6479
|
var COLOR = {
|
|
5915
6480
|
WATER: "#9ec1d8",
|
|
5916
6481
|
WATER_DEEP: "#8fb8d0",
|
|
@@ -5931,6 +6496,30 @@ var ORIENTATION_BAND_SORT_KEY = [
|
|
|
5931
6496
|
["slice", ["coalesce", ["get", "_cell_id"], "??9???"], 2, 3],
|
|
5932
6497
|
9
|
|
5933
6498
|
];
|
|
6499
|
+
function orientationLabelLayout(extras = {}) {
|
|
6500
|
+
return {
|
|
6501
|
+
"text-anchor": "center",
|
|
6502
|
+
"text-allow-overlap": false,
|
|
6503
|
+
"text-ignore-placement": false,
|
|
6504
|
+
"text-optional": true,
|
|
6505
|
+
"text-padding": 15,
|
|
6506
|
+
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY,
|
|
6507
|
+
...extras
|
|
6508
|
+
};
|
|
6509
|
+
}
|
|
6510
|
+
var ORIENTATION_HALO_WIDTH = [
|
|
6511
|
+
"interpolate",
|
|
6512
|
+
["linear"],
|
|
6513
|
+
["zoom"],
|
|
6514
|
+
8,
|
|
6515
|
+
1.6,
|
|
6516
|
+
11,
|
|
6517
|
+
1.5,
|
|
6518
|
+
14,
|
|
6519
|
+
1,
|
|
6520
|
+
16,
|
|
6521
|
+
0.7
|
|
6522
|
+
];
|
|
5934
6523
|
var LABEL_BEHAVIOR = {
|
|
5935
6524
|
// Orientation labels — render once across all bands.
|
|
5936
6525
|
SEAARE: "orientation-cross-band",
|
|
@@ -5968,9 +6557,9 @@ function getLabelBehavior(layerName) {
|
|
|
5968
6557
|
return LABEL_BEHAVIOR[layerName] ?? "feature-band-gated";
|
|
5969
6558
|
}
|
|
5970
6559
|
function getLabelConfig(layerName, opts = {}) {
|
|
6560
|
+
const ct = opts.colorTable ?? "DAY";
|
|
5971
6561
|
switch (layerName) {
|
|
5972
6562
|
case "SOUNDG": {
|
|
5973
|
-
const ct = opts.colorTable ?? "DAY";
|
|
5974
6563
|
const safetyContour = opts.safetyContour ?? 10;
|
|
5975
6564
|
const twoShade = opts.twoShadeSoundings ?? true;
|
|
5976
6565
|
const weight = opts.soundingFontWeight ?? "semibold";
|
|
@@ -6045,7 +6634,17 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6045
6634
|
}
|
|
6046
6635
|
};
|
|
6047
6636
|
}
|
|
6048
|
-
case "LNDRGN":
|
|
6637
|
+
case "LNDRGN": {
|
|
6638
|
+
const tierExpr = buildLandRegionTierExpression();
|
|
6639
|
+
const sizeAt = (t1, t2) => [
|
|
6640
|
+
"match",
|
|
6641
|
+
tierExpr,
|
|
6642
|
+
1,
|
|
6643
|
+
t1,
|
|
6644
|
+
2,
|
|
6645
|
+
t2,
|
|
6646
|
+
t2
|
|
6647
|
+
];
|
|
6049
6648
|
return {
|
|
6050
6649
|
type: "symbol",
|
|
6051
6650
|
textField: ["get", "OBJNAM"],
|
|
@@ -6053,27 +6652,28 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6053
6652
|
"interpolate",
|
|
6054
6653
|
["linear"],
|
|
6055
6654
|
["zoom"],
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6655
|
+
5,
|
|
6656
|
+
sizeAt(9, 0),
|
|
6657
|
+
7,
|
|
6658
|
+
sizeAt(11, 0),
|
|
6659
|
+
9,
|
|
6660
|
+
sizeAt(12, 0),
|
|
6661
|
+
11,
|
|
6662
|
+
sizeAt(12, 9),
|
|
6663
|
+
13,
|
|
6664
|
+
sizeAt(11, 11),
|
|
6665
|
+
16,
|
|
6666
|
+
sizeAt(10, 10)
|
|
6062
6667
|
],
|
|
6063
6668
|
textColor: DARK_BG,
|
|
6064
6669
|
textHaloColor: COLOR.LAND_REGION,
|
|
6065
|
-
textHaloWidth:
|
|
6670
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6066
6671
|
textOffset: [0, 0],
|
|
6067
6672
|
textFont: ["Open Sans Regular"],
|
|
6068
|
-
minzoom:
|
|
6069
|
-
layout:
|
|
6070
|
-
"text-anchor": "center",
|
|
6071
|
-
"text-allow-overlap": false,
|
|
6072
|
-
"text-padding": 6,
|
|
6073
|
-
"text-optional": true,
|
|
6074
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6075
|
-
}
|
|
6673
|
+
minzoom: 5,
|
|
6674
|
+
layout: orientationLabelLayout()
|
|
6076
6675
|
};
|
|
6676
|
+
}
|
|
6077
6677
|
case "LNDMRK":
|
|
6078
6678
|
return {
|
|
6079
6679
|
type: "symbol",
|
|
@@ -6092,7 +6692,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6092
6692
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6093
6693
|
textFont: NAV_AID_LABEL_FONT,
|
|
6094
6694
|
textColor: DARK_BG,
|
|
6095
|
-
textHaloColor: "
|
|
6695
|
+
textHaloColor: navHalo("WHITE", ct),
|
|
6096
6696
|
textHaloWidth: 1.5,
|
|
6097
6697
|
textOffset: [0, 1.5],
|
|
6098
6698
|
minzoom: 10
|
|
@@ -6104,7 +6704,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6104
6704
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6105
6705
|
textFont: NAV_AID_LABEL_FONT,
|
|
6106
6706
|
textColor: DARK_BG,
|
|
6107
|
-
textHaloColor: "
|
|
6707
|
+
textHaloColor: navHalo("WHITE", ct),
|
|
6108
6708
|
textHaloWidth: 1.5,
|
|
6109
6709
|
textOffset: [0, 1.5],
|
|
6110
6710
|
minzoom: 10
|
|
@@ -6117,7 +6717,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6117
6717
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6118
6718
|
textFont: NAV_AID_LABEL_FONT,
|
|
6119
6719
|
textColor: DARK_BG,
|
|
6120
|
-
textHaloColor: "
|
|
6720
|
+
textHaloColor: navHalo("CREAM", ct),
|
|
6121
6721
|
textHaloWidth: 1.5,
|
|
6122
6722
|
textOffset: [0, 1.5],
|
|
6123
6723
|
minzoom: 10
|
|
@@ -6130,7 +6730,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6130
6730
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6131
6731
|
textFont: NAV_AID_LABEL_FONT,
|
|
6132
6732
|
textColor: DARK_BG,
|
|
6133
|
-
textHaloColor: "
|
|
6733
|
+
textHaloColor: navHalo("YELLOW", ct),
|
|
6134
6734
|
textHaloWidth: 1.5,
|
|
6135
6735
|
textOffset: [0, 1.5],
|
|
6136
6736
|
minzoom: 10
|
|
@@ -6143,7 +6743,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6143
6743
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6144
6744
|
textFont: NAV_AID_LABEL_FONT,
|
|
6145
6745
|
textColor: DARK_BG,
|
|
6146
|
-
textHaloColor: "
|
|
6746
|
+
textHaloColor: navHalo("WHITE", ct),
|
|
6147
6747
|
textHaloWidth: 1.5,
|
|
6148
6748
|
textOffset: [0, 1.5],
|
|
6149
6749
|
minzoom: 10
|
|
@@ -6155,7 +6755,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6155
6755
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6156
6756
|
textFont: NAV_AID_LABEL_FONT,
|
|
6157
6757
|
textColor: DARK_BG,
|
|
6158
|
-
textHaloColor: "
|
|
6758
|
+
textHaloColor: navHalo("CREAM", ct),
|
|
6159
6759
|
textHaloWidth: 1.5,
|
|
6160
6760
|
textOffset: [2, 0],
|
|
6161
6761
|
minzoom: 9,
|
|
@@ -6191,7 +6791,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6191
6791
|
textSize: NAV_AID_LABEL_TEXT_SIZE,
|
|
6192
6792
|
textFont: NAV_AID_LABEL_FONT,
|
|
6193
6793
|
textColor: DARK_BG,
|
|
6194
|
-
textHaloColor: "
|
|
6794
|
+
textHaloColor: navHalo("BLUE", ct),
|
|
6195
6795
|
textHaloWidth: 1.5,
|
|
6196
6796
|
textOffset: [2, 1.2],
|
|
6197
6797
|
minzoom: 11,
|
|
@@ -6202,40 +6802,72 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6202
6802
|
}
|
|
6203
6803
|
};
|
|
6204
6804
|
}
|
|
6205
|
-
case "SEAARE":
|
|
6805
|
+
case "SEAARE": {
|
|
6806
|
+
const tierExpr = buildSeaAreaTierExpression();
|
|
6807
|
+
const sizeAt = (t1, t2, t3, t4, def) => [
|
|
6808
|
+
"match",
|
|
6809
|
+
tierExpr,
|
|
6810
|
+
1,
|
|
6811
|
+
t1,
|
|
6812
|
+
2,
|
|
6813
|
+
t2,
|
|
6814
|
+
3,
|
|
6815
|
+
t3,
|
|
6816
|
+
4,
|
|
6817
|
+
t4,
|
|
6818
|
+
def
|
|
6819
|
+
];
|
|
6206
6820
|
return {
|
|
6207
6821
|
type: "symbol",
|
|
6208
6822
|
textField: ["get", "OBJNAM"],
|
|
6823
|
+
// Default tier (CATSEA=0, uncategorised: canyons, seamounts, fishing
|
|
6824
|
+
// banks etc.) is suppressed at overview/general/coastal scales because
|
|
6825
|
+
// it floods the overview with hundreds of small italic labels that
|
|
6826
|
+
// crowd out the headline Ocean/Sea/Gulf names. It becomes visible only
|
|
6827
|
+
// at approach scale (z9) when the user has zoomed in enough that
|
|
6828
|
+
// individual banks are useful context.
|
|
6209
6829
|
textSize: [
|
|
6210
6830
|
"interpolate",
|
|
6211
6831
|
["linear"],
|
|
6212
6832
|
["zoom"],
|
|
6833
|
+
3,
|
|
6834
|
+
sizeAt(14, 8, 0, 0, 0),
|
|
6213
6835
|
5,
|
|
6836
|
+
sizeAt(16, 13, 9, 0, 0),
|
|
6837
|
+
7,
|
|
6838
|
+
sizeAt(14, 14, 12, 0, 0),
|
|
6839
|
+
9,
|
|
6840
|
+
sizeAt(12, 13, 14, 0, 9),
|
|
6214
6841
|
11,
|
|
6215
|
-
|
|
6842
|
+
sizeAt(10, 12, 13, 0, 11),
|
|
6216
6843
|
13,
|
|
6217
|
-
11,
|
|
6218
|
-
|
|
6219
|
-
|
|
6220
|
-
17
|
|
6844
|
+
sizeAt(9, 11, 12, 10, 11),
|
|
6845
|
+
16,
|
|
6846
|
+
sizeAt(9, 10, 11, 11, 10)
|
|
6221
6847
|
],
|
|
6222
6848
|
textColor: DARK_BG,
|
|
6223
6849
|
textHaloColor: COLOR.WATER_DEEP,
|
|
6224
|
-
textHaloWidth:
|
|
6850
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6225
6851
|
textOffset: [0, 0],
|
|
6226
6852
|
textFont: ["Open Sans Italic"],
|
|
6227
6853
|
minzoom: 5,
|
|
6228
|
-
layout: {
|
|
6229
|
-
"text-anchor": "center",
|
|
6230
|
-
"text-allow-overlap": false,
|
|
6231
|
-
"text-padding": 10,
|
|
6232
|
-
"text-optional": true,
|
|
6854
|
+
layout: orientationLabelLayout({
|
|
6233
6855
|
"text-letter-spacing": 0.15,
|
|
6234
|
-
"text-max-width": 9
|
|
6235
|
-
|
|
6236
|
-
}
|
|
6856
|
+
"text-max-width": 9
|
|
6857
|
+
})
|
|
6237
6858
|
};
|
|
6238
|
-
|
|
6859
|
+
}
|
|
6860
|
+
case "LAKARE": {
|
|
6861
|
+
const tierExpr = buildLakeTierExpression();
|
|
6862
|
+
const sizeAt = (t1, t2) => [
|
|
6863
|
+
"match",
|
|
6864
|
+
tierExpr,
|
|
6865
|
+
1,
|
|
6866
|
+
t1,
|
|
6867
|
+
2,
|
|
6868
|
+
t2,
|
|
6869
|
+
t2
|
|
6870
|
+
];
|
|
6239
6871
|
return {
|
|
6240
6872
|
type: "symbol",
|
|
6241
6873
|
textField: ["get", "OBJNAM"],
|
|
@@ -6243,28 +6875,37 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6243
6875
|
"interpolate",
|
|
6244
6876
|
["linear"],
|
|
6245
6877
|
["zoom"],
|
|
6246
|
-
|
|
6247
|
-
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
|
|
6251
|
-
|
|
6878
|
+
7,
|
|
6879
|
+
sizeAt(9, 0),
|
|
6880
|
+
9,
|
|
6881
|
+
sizeAt(11, 0),
|
|
6882
|
+
11,
|
|
6883
|
+
sizeAt(11, 9),
|
|
6884
|
+
13,
|
|
6885
|
+
sizeAt(10, 11),
|
|
6886
|
+
16,
|
|
6887
|
+
sizeAt(9, 10)
|
|
6252
6888
|
],
|
|
6253
6889
|
textColor: DARK_BG,
|
|
6254
6890
|
textHaloColor: COLOR.WATER,
|
|
6255
|
-
textHaloWidth:
|
|
6891
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6256
6892
|
textOffset: [0, 0],
|
|
6257
6893
|
textFont: ["Open Sans Italic"],
|
|
6258
|
-
minzoom:
|
|
6259
|
-
layout:
|
|
6260
|
-
"text-anchor": "center",
|
|
6261
|
-
"text-allow-overlap": false,
|
|
6262
|
-
"text-padding": 6,
|
|
6263
|
-
"text-optional": true,
|
|
6264
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6265
|
-
}
|
|
6894
|
+
minzoom: 7,
|
|
6895
|
+
layout: orientationLabelLayout()
|
|
6266
6896
|
};
|
|
6267
|
-
|
|
6897
|
+
}
|
|
6898
|
+
case "RIVERS": {
|
|
6899
|
+
const tierExpr = buildRiverTierExpression();
|
|
6900
|
+
const sizeAt = (t1, t2) => [
|
|
6901
|
+
"match",
|
|
6902
|
+
tierExpr,
|
|
6903
|
+
1,
|
|
6904
|
+
t1,
|
|
6905
|
+
2,
|
|
6906
|
+
t2,
|
|
6907
|
+
t2
|
|
6908
|
+
];
|
|
6268
6909
|
return {
|
|
6269
6910
|
type: "symbol",
|
|
6270
6911
|
textField: ["get", "OBJNAM"],
|
|
@@ -6272,27 +6913,26 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6272
6913
|
"interpolate",
|
|
6273
6914
|
["linear"],
|
|
6274
6915
|
["zoom"],
|
|
6916
|
+
7,
|
|
6917
|
+
sizeAt(9, 0),
|
|
6275
6918
|
9,
|
|
6276
|
-
|
|
6277
|
-
12,
|
|
6919
|
+
sizeAt(11, 0),
|
|
6278
6920
|
11,
|
|
6279
|
-
|
|
6280
|
-
13
|
|
6921
|
+
sizeAt(11, 9),
|
|
6922
|
+
13,
|
|
6923
|
+
sizeAt(10, 10),
|
|
6924
|
+
16,
|
|
6925
|
+
sizeAt(9, 10)
|
|
6281
6926
|
],
|
|
6282
6927
|
textColor: DARK_BG,
|
|
6283
6928
|
textHaloColor: COLOR.WATER,
|
|
6284
|
-
textHaloWidth:
|
|
6929
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6285
6930
|
textOffset: [0, 0],
|
|
6286
6931
|
textFont: ["Open Sans Italic"],
|
|
6287
|
-
minzoom:
|
|
6288
|
-
layout:
|
|
6289
|
-
"text-anchor": "center",
|
|
6290
|
-
"text-allow-overlap": false,
|
|
6291
|
-
"text-padding": 4,
|
|
6292
|
-
"text-optional": true,
|
|
6293
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6294
|
-
}
|
|
6932
|
+
minzoom: 7,
|
|
6933
|
+
layout: orientationLabelLayout()
|
|
6295
6934
|
};
|
|
6935
|
+
}
|
|
6296
6936
|
case "CANALS":
|
|
6297
6937
|
return {
|
|
6298
6938
|
type: "symbol",
|
|
@@ -6302,25 +6942,31 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6302
6942
|
["linear"],
|
|
6303
6943
|
["zoom"],
|
|
6304
6944
|
11,
|
|
6945
|
+
10,
|
|
6946
|
+
13,
|
|
6305
6947
|
9,
|
|
6306
|
-
|
|
6307
|
-
|
|
6948
|
+
16,
|
|
6949
|
+
9
|
|
6308
6950
|
],
|
|
6309
6951
|
textColor: DARK_BG,
|
|
6310
6952
|
textHaloColor: COLOR.WATER,
|
|
6311
|
-
textHaloWidth:
|
|
6953
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6312
6954
|
textOffset: [0, 0],
|
|
6313
6955
|
textFont: ["Open Sans Italic"],
|
|
6314
6956
|
minzoom: 11,
|
|
6315
|
-
layout:
|
|
6316
|
-
"text-anchor": "center",
|
|
6317
|
-
"text-allow-overlap": false,
|
|
6318
|
-
"text-padding": 4,
|
|
6319
|
-
"text-optional": true,
|
|
6320
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6321
|
-
}
|
|
6957
|
+
layout: orientationLabelLayout()
|
|
6322
6958
|
};
|
|
6323
|
-
case "LNDARE":
|
|
6959
|
+
case "LNDARE": {
|
|
6960
|
+
const tierExpr = buildLandAreaTierExpression();
|
|
6961
|
+
const sizeAt = (t1, t2) => [
|
|
6962
|
+
"match",
|
|
6963
|
+
tierExpr,
|
|
6964
|
+
1,
|
|
6965
|
+
t1,
|
|
6966
|
+
2,
|
|
6967
|
+
t2,
|
|
6968
|
+
t2
|
|
6969
|
+
];
|
|
6324
6970
|
return {
|
|
6325
6971
|
type: "symbol",
|
|
6326
6972
|
textField: ["get", "OBJNAM"],
|
|
@@ -6328,28 +6974,41 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6328
6974
|
"interpolate",
|
|
6329
6975
|
["linear"],
|
|
6330
6976
|
["zoom"],
|
|
6331
|
-
|
|
6977
|
+
5,
|
|
6978
|
+
sizeAt(8, 0),
|
|
6979
|
+
7,
|
|
6980
|
+
sizeAt(10, 0),
|
|
6332
6981
|
9,
|
|
6333
|
-
|
|
6982
|
+
sizeAt(11, 0),
|
|
6334
6983
|
11,
|
|
6335
|
-
|
|
6336
|
-
13
|
|
6984
|
+
sizeAt(11, 9),
|
|
6985
|
+
13,
|
|
6986
|
+
sizeAt(10, 10),
|
|
6987
|
+
16,
|
|
6988
|
+
sizeAt(9, 10)
|
|
6337
6989
|
],
|
|
6338
6990
|
textColor: DARK_BG,
|
|
6339
6991
|
textHaloColor: COLOR.LAND_NATURAL,
|
|
6340
|
-
textHaloWidth:
|
|
6992
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6341
6993
|
textOffset: [0, 0],
|
|
6342
6994
|
textFont: ["Open Sans Regular"],
|
|
6343
|
-
minzoom:
|
|
6344
|
-
layout:
|
|
6345
|
-
"text-anchor": "center",
|
|
6346
|
-
"text-allow-overlap": false,
|
|
6347
|
-
"text-padding": 6,
|
|
6348
|
-
"text-optional": true,
|
|
6349
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6350
|
-
}
|
|
6995
|
+
minzoom: 5,
|
|
6996
|
+
layout: orientationLabelLayout()
|
|
6351
6997
|
};
|
|
6352
|
-
|
|
6998
|
+
}
|
|
6999
|
+
case "BUAARE": {
|
|
7000
|
+
const tierExpr = buildBuiltUpAreaTierExpression();
|
|
7001
|
+
const sizeAt = (t1, t2, t3) => [
|
|
7002
|
+
"match",
|
|
7003
|
+
tierExpr,
|
|
7004
|
+
1,
|
|
7005
|
+
t1,
|
|
7006
|
+
2,
|
|
7007
|
+
t2,
|
|
7008
|
+
3,
|
|
7009
|
+
t3,
|
|
7010
|
+
t3
|
|
7011
|
+
];
|
|
6353
7012
|
return {
|
|
6354
7013
|
type: "symbol",
|
|
6355
7014
|
textField: ["get", "OBJNAM"],
|
|
@@ -6357,28 +7016,32 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6357
7016
|
"interpolate",
|
|
6358
7017
|
["linear"],
|
|
6359
7018
|
["zoom"],
|
|
7019
|
+
3,
|
|
7020
|
+
sizeAt(11, 0, 0),
|
|
7021
|
+
5,
|
|
7022
|
+
sizeAt(13, 0, 0),
|
|
6360
7023
|
7,
|
|
7024
|
+
sizeAt(13, 9, 0),
|
|
7025
|
+
9,
|
|
7026
|
+
sizeAt(12, 12, 0),
|
|
6361
7027
|
11,
|
|
6362
|
-
10,
|
|
6363
|
-
13,
|
|
7028
|
+
sizeAt(11, 12, 10),
|
|
6364
7029
|
13,
|
|
6365
|
-
|
|
7030
|
+
sizeAt(10, 11, 12),
|
|
7031
|
+
16,
|
|
7032
|
+
sizeAt(10, 10, 11)
|
|
6366
7033
|
],
|
|
6367
7034
|
textColor: DARK_BG,
|
|
6368
7035
|
textHaloColor: COLOR.CITY,
|
|
6369
|
-
textHaloWidth:
|
|
7036
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6370
7037
|
textOffset: [0, 0],
|
|
6371
7038
|
textFont: ["Open Sans Regular"],
|
|
6372
|
-
minzoom:
|
|
6373
|
-
layout: {
|
|
6374
|
-
"text-
|
|
6375
|
-
|
|
6376
|
-
"text-padding": 8,
|
|
6377
|
-
"text-optional": true,
|
|
6378
|
-
"text-letter-spacing": 0.05,
|
|
6379
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6380
|
-
}
|
|
7039
|
+
minzoom: 3,
|
|
7040
|
+
layout: orientationLabelLayout({
|
|
7041
|
+
"text-letter-spacing": 0.05
|
|
7042
|
+
})
|
|
6381
7043
|
};
|
|
7044
|
+
}
|
|
6382
7045
|
case "BRIDGE":
|
|
6383
7046
|
return {
|
|
6384
7047
|
type: "symbol",
|
|
@@ -6446,7 +7109,17 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6446
7109
|
"text-optional": true
|
|
6447
7110
|
}
|
|
6448
7111
|
};
|
|
6449
|
-
case "AIRARE":
|
|
7112
|
+
case "AIRARE": {
|
|
7113
|
+
const tierExpr = buildAirportTierExpression();
|
|
7114
|
+
const sizeAt = (t1, t2) => [
|
|
7115
|
+
"match",
|
|
7116
|
+
tierExpr,
|
|
7117
|
+
1,
|
|
7118
|
+
t1,
|
|
7119
|
+
2,
|
|
7120
|
+
t2,
|
|
7121
|
+
t2
|
|
7122
|
+
];
|
|
6450
7123
|
return {
|
|
6451
7124
|
type: "symbol",
|
|
6452
7125
|
textField: ["get", "OBJNAM"],
|
|
@@ -6454,25 +7127,26 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6454
7127
|
"interpolate",
|
|
6455
7128
|
["linear"],
|
|
6456
7129
|
["zoom"],
|
|
7130
|
+
7,
|
|
7131
|
+
sizeAt(9, 0),
|
|
6457
7132
|
9,
|
|
6458
|
-
|
|
7133
|
+
sizeAt(11, 0),
|
|
7134
|
+
11,
|
|
7135
|
+
sizeAt(11, 9),
|
|
6459
7136
|
13,
|
|
6460
|
-
|
|
7137
|
+
sizeAt(10, 10),
|
|
7138
|
+
16,
|
|
7139
|
+
sizeAt(9, 9)
|
|
6461
7140
|
],
|
|
6462
7141
|
textColor: DARK_BG,
|
|
6463
7142
|
textHaloColor: COLOR.AIRPORT,
|
|
6464
|
-
textHaloWidth:
|
|
7143
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6465
7144
|
textOffset: [0, 0],
|
|
6466
7145
|
textFont: ["Open Sans Regular"],
|
|
6467
|
-
minzoom:
|
|
6468
|
-
layout:
|
|
6469
|
-
"text-anchor": "center",
|
|
6470
|
-
"text-allow-overlap": false,
|
|
6471
|
-
"text-padding": 5,
|
|
6472
|
-
"text-optional": true,
|
|
6473
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6474
|
-
}
|
|
7146
|
+
minzoom: 7,
|
|
7147
|
+
layout: orientationLabelLayout()
|
|
6475
7148
|
};
|
|
7149
|
+
}
|
|
6476
7150
|
case "SBDARE":
|
|
6477
7151
|
return {
|
|
6478
7152
|
type: "symbol",
|
|
@@ -6545,26 +7219,20 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6545
7219
|
"interpolate",
|
|
6546
7220
|
["linear"],
|
|
6547
7221
|
["zoom"],
|
|
7222
|
+
11,
|
|
7223
|
+
9,
|
|
7224
|
+
13,
|
|
6548
7225
|
8,
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
12,
|
|
6552
|
-
15,
|
|
6553
|
-
14
|
|
7226
|
+
16,
|
|
7227
|
+
8
|
|
6554
7228
|
],
|
|
6555
7229
|
textColor: "#c545c3",
|
|
6556
7230
|
textHaloColor: DARK_BG,
|
|
6557
|
-
textHaloWidth:
|
|
7231
|
+
textHaloWidth: ORIENTATION_HALO_WIDTH,
|
|
6558
7232
|
textOffset: [0, 0],
|
|
6559
7233
|
textFont: ["Open Sans Italic"],
|
|
6560
7234
|
minzoom: 8,
|
|
6561
|
-
layout:
|
|
6562
|
-
"text-anchor": "center",
|
|
6563
|
-
"text-allow-overlap": false,
|
|
6564
|
-
"text-padding": 6,
|
|
6565
|
-
"text-optional": true,
|
|
6566
|
-
"symbol-sort-key": ORIENTATION_BAND_SORT_KEY
|
|
6567
|
-
}
|
|
7235
|
+
layout: orientationLabelLayout()
|
|
6568
7236
|
};
|
|
6569
7237
|
case "WEDKLP":
|
|
6570
7238
|
return {
|
|
@@ -6597,7 +7265,7 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6597
7265
|
case "UWTROC":
|
|
6598
7266
|
case "OBSTRN":
|
|
6599
7267
|
case "WRECKS": {
|
|
6600
|
-
const
|
|
7268
|
+
const ct2 = opts.colorTable ?? "DAY";
|
|
6601
7269
|
const valsou = [
|
|
6602
7270
|
"to-number",
|
|
6603
7271
|
["coalesce", ["get", "VALSOU"], ["get", "valsou"], 0],
|
|
@@ -6624,8 +7292,8 @@ function getLabelConfig(layerName, opts = {}) {
|
|
|
6624
7292
|
16,
|
|
6625
7293
|
11
|
|
6626
7294
|
],
|
|
6627
|
-
textColor: resolveColor("CHBLK",
|
|
6628
|
-
textHaloColor: resolveColor("CHWHT",
|
|
7295
|
+
textColor: resolveColor("CHBLK", ct2),
|
|
7296
|
+
textHaloColor: resolveColor("CHWHT", ct2),
|
|
6629
7297
|
textHaloWidth: 1.2,
|
|
6630
7298
|
// Place to the upper-right of the symbol so it doesn't sit on top
|
|
6631
7299
|
// of the asterisk / cross. Anchor top-left so the offset grows
|
|
@@ -8671,7 +9339,21 @@ var LINE_FROM_POLYGON_LAYERS = /* @__PURE__ */ new Set([
|
|
|
8671
9339
|
"MIPARE",
|
|
8672
9340
|
"TESARE",
|
|
8673
9341
|
"MAGVAR",
|
|
8674
|
-
"PRDARE"
|
|
9342
|
+
"PRDARE",
|
|
9343
|
+
"TUNNEL",
|
|
9344
|
+
// Jurisdictional zones (INT1 N40–N47) and IMO routing measures
|
|
9345
|
+
// (INT1 M14, M27, M28) — magenta dashed boundary, no fill. Vast
|
|
9346
|
+
// offshore polygons would tint half the chart if flood-filled, so
|
|
9347
|
+
// every member here renders as boundary-only. DWRTCL is not listed
|
|
9348
|
+
// because it's a native LineString class, not a polygon-as-line.
|
|
9349
|
+
// Closes issue #575 rows 8–15.
|
|
9350
|
+
"ADMARE",
|
|
9351
|
+
"COSARE",
|
|
9352
|
+
"CONZNE",
|
|
9353
|
+
"EXEZNE",
|
|
9354
|
+
"TSEZNE",
|
|
9355
|
+
"DWRTPT",
|
|
9356
|
+
"TWRTPT"
|
|
8675
9357
|
]);
|
|
8676
9358
|
var ZOOM_SCALED_LINES2 = {
|
|
8677
9359
|
DEPCNT: [8, 0.3, 14, 0.8],
|
|
@@ -9659,6 +10341,87 @@ function buildLayersForClass(objectClass, ct, sourceId = DEFAULT_REGION) {
|
|
|
9659
10341
|
metadata: { "s52:objectClass": "RECTRC", "s52:role": "polygon" }
|
|
9660
10342
|
});
|
|
9661
10343
|
}
|
|
10344
|
+
if (objectClass === "PONTON" && resolved.type === "fill") {
|
|
10345
|
+
layers.push({
|
|
10346
|
+
id: `s52-PONTON-line`,
|
|
10347
|
+
type: "line",
|
|
10348
|
+
source: sourceId,
|
|
10349
|
+
"source-layer": "PONTON",
|
|
10350
|
+
filter: GEOM_FILTERS.line,
|
|
10351
|
+
paint: {
|
|
10352
|
+
"line-color": resolveColor("CHGRF", ct),
|
|
10353
|
+
"line-width": 1.5
|
|
10354
|
+
},
|
|
10355
|
+
metadata: { "s52:objectClass": "PONTON", "s52:role": "line" }
|
|
10356
|
+
});
|
|
10357
|
+
}
|
|
10358
|
+
if (objectClass === "SILTNK" && resolved.type === "symbol") {
|
|
10359
|
+
layers.push({
|
|
10360
|
+
id: `s52-SILTNK-symbol-polygon`,
|
|
10361
|
+
type: "symbol",
|
|
10362
|
+
source: sourceId,
|
|
10363
|
+
"source-layer": "SILTNK",
|
|
10364
|
+
filter: GEOM_FILTERS.fill,
|
|
10365
|
+
layout: {
|
|
10366
|
+
"icon-image": "TNKCON02",
|
|
10367
|
+
"icon-size": 0.6,
|
|
10368
|
+
"icon-allow-overlap": true,
|
|
10369
|
+
"icon-ignore-placement": false,
|
|
10370
|
+
"symbol-placement": "point"
|
|
10371
|
+
},
|
|
10372
|
+
paint: {},
|
|
10373
|
+
metadata: { "s52:objectClass": "SILTNK", "s52:role": "symbol-polygon" }
|
|
10374
|
+
});
|
|
10375
|
+
}
|
|
10376
|
+
if (objectClass === "ACHBRT" && resolved.type === "symbol") {
|
|
10377
|
+
layers.push({
|
|
10378
|
+
id: `s52-ACHBRT-symbol-polygon`,
|
|
10379
|
+
type: "symbol",
|
|
10380
|
+
source: sourceId,
|
|
10381
|
+
"source-layer": "ACHBRT",
|
|
10382
|
+
filter: GEOM_FILTERS.fill,
|
|
10383
|
+
layout: {
|
|
10384
|
+
"icon-image": "ACHARE02",
|
|
10385
|
+
"icon-size": 0.5,
|
|
10386
|
+
"icon-allow-overlap": true,
|
|
10387
|
+
"icon-ignore-placement": false,
|
|
10388
|
+
"symbol-placement": "point"
|
|
10389
|
+
},
|
|
10390
|
+
paint: {},
|
|
10391
|
+
metadata: { "s52:objectClass": "ACHBRT", "s52:role": "symbol-polygon" }
|
|
10392
|
+
});
|
|
10393
|
+
}
|
|
10394
|
+
if (objectClass === "BERTHS" && resolved.type === "line") {
|
|
10395
|
+
layers.push({
|
|
10396
|
+
id: `s52-BERTHS-circle`,
|
|
10397
|
+
type: "circle",
|
|
10398
|
+
source: sourceId,
|
|
10399
|
+
"source-layer": "BERTHS",
|
|
10400
|
+
filter: GEOM_FILTERS.circle,
|
|
10401
|
+
paint: {
|
|
10402
|
+
"circle-color": resolveColor("CHBLK", ct),
|
|
10403
|
+
"circle-radius": ["interpolate", ["linear"], ["zoom"], 12, 1.5, 14, 2.2, 17, 3],
|
|
10404
|
+
"circle-stroke-color": resolveColor("CHBLK", ct),
|
|
10405
|
+
"circle-stroke-width": 0.5
|
|
10406
|
+
},
|
|
10407
|
+
metadata: { "s52:objectClass": "BERTHS", "s52:role": "point" }
|
|
10408
|
+
});
|
|
10409
|
+
}
|
|
10410
|
+
if (objectClass === "TUNNEL" && resolved.type === "line") {
|
|
10411
|
+
layers.push({
|
|
10412
|
+
id: `s52-TUNNEL-line`,
|
|
10413
|
+
type: "line",
|
|
10414
|
+
source: sourceId,
|
|
10415
|
+
"source-layer": "TUNNEL",
|
|
10416
|
+
filter: GEOM_FILTERS.line,
|
|
10417
|
+
paint: {
|
|
10418
|
+
"line-color": resolveColor("CHGRD", ct),
|
|
10419
|
+
"line-width": 1,
|
|
10420
|
+
"line-dasharray": [2, 2]
|
|
10421
|
+
},
|
|
10422
|
+
metadata: { "s52:objectClass": "TUNNEL", "s52:role": "line" }
|
|
10423
|
+
});
|
|
10424
|
+
}
|
|
9662
10425
|
}
|
|
9663
10426
|
return layers;
|
|
9664
10427
|
}
|
|
@@ -9894,9 +10657,21 @@ var META_LAYERS = /* @__PURE__ */ new Set([
|
|
|
9894
10657
|
"M_CSCL",
|
|
9895
10658
|
"TS_FEB",
|
|
9896
10659
|
"TS_TIS",
|
|
9897
|
-
"COSARE",
|
|
9898
|
-
"NEWOBJ",
|
|
9899
10660
|
"LOCMAG"
|
|
10661
|
+
// COSARE was previously suppressed here as meta. The weekly layer-
|
|
10662
|
+
// coverage audit (issue #575) classified it as a jurisdictional polygon
|
|
10663
|
+
// (S-52 INT1 N40, same family as ADMARE / TESARE). It now has an
|
|
10664
|
+
// S52_LOOKUP entry and renders as a magenta dashed boundary; suppressing
|
|
10665
|
+
// it as meta would defeat that wire-up.
|
|
10666
|
+
//
|
|
10667
|
+
// NEWOBJ was likewise previously suppressed here. That was the source
|
|
10668
|
+
// of audit gap row 22: NEWOBJ is the S-57 placeholder for features the
|
|
10669
|
+
// HO has identified but not yet classified. Skipping it silently hid
|
|
10670
|
+
// the HO's own "we don't know what this is, but it is here" signal —
|
|
10671
|
+
// the opposite of what mariners need. The class now renders via its
|
|
10672
|
+
// S52_LOOKUP entry as a vivid magenta circle, displayCategory STANDARD,
|
|
10673
|
+
// scamin 0. Do not put it back here — see the lookup entry for the
|
|
10674
|
+
// safety contract.
|
|
9900
10675
|
]);
|
|
9901
10676
|
var PALETTE_NAMES = {
|
|
9902
10677
|
DAY: "DAY_BRIGHT",
|
|
@@ -9987,21 +10762,45 @@ function makeBandVariants(layer, B) {
|
|
|
9987
10762
|
}
|
|
9988
10763
|
return variants;
|
|
9989
10764
|
}
|
|
9990
|
-
|
|
10765
|
+
var CELL_BAND_OPACITY_CURVE = {
|
|
10766
|
+
"1": [[3, 0.5], [5, 0.3], [16, 0.15]],
|
|
10767
|
+
"2": [[5, 0.5], [7, 0.3], [16, 0.15]],
|
|
10768
|
+
"3": [[7, 0.55], [9, 0.35], [16, 0.18]],
|
|
10769
|
+
"4": [[9, 0.55], [11, 0.35], [16, 0.2]],
|
|
10770
|
+
"5": [[11, 0.6], [13, 0.35], [18, 0.25]],
|
|
10771
|
+
"6": [[13, 0.75], [16, 0.55], [22, 0.45]]
|
|
10772
|
+
};
|
|
10773
|
+
function fanOrientationLabelByCellBand(label) {
|
|
10774
|
+
const cellBandExpr = [
|
|
10775
|
+
"slice",
|
|
10776
|
+
["coalesce", ["get", "_cell_id"], "??9???"],
|
|
10777
|
+
2,
|
|
10778
|
+
3
|
|
10779
|
+
];
|
|
9991
10780
|
const variants = [];
|
|
9992
|
-
|
|
9993
|
-
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
if (D === "1") continue;
|
|
9999
|
-
variants.push({
|
|
10781
|
+
for (const code of BAND_DRAW_ORDER) {
|
|
10782
|
+
const range = BAND_PRIORITY_RANGES[code];
|
|
10783
|
+
const curve = CELL_BAND_OPACITY_CURVE[code];
|
|
10784
|
+
const opacityExpr = ["interpolate", ["linear"], ["zoom"]];
|
|
10785
|
+
for (const [z, o] of curve) opacityExpr.push(z, o);
|
|
10786
|
+
const variant = {
|
|
10000
10787
|
...label,
|
|
10001
|
-
id: `${label.id}-
|
|
10002
|
-
filter: combineWithBandFilter(
|
|
10003
|
-
|
|
10004
|
-
|
|
10788
|
+
id: `${label.id}-cell${code}`,
|
|
10789
|
+
filter: combineWithBandFilter(
|
|
10790
|
+
label.filter,
|
|
10791
|
+
["==", cellBandExpr, code]
|
|
10792
|
+
),
|
|
10793
|
+
minzoom: Math.max(
|
|
10794
|
+
label.minzoom ?? range.minzoom,
|
|
10795
|
+
range.minzoom
|
|
10796
|
+
),
|
|
10797
|
+
paint: {
|
|
10798
|
+
...label.paint ?? {},
|
|
10799
|
+
"text-opacity": opacityExpr
|
|
10800
|
+
}
|
|
10801
|
+
};
|
|
10802
|
+
delete variant.maxzoom;
|
|
10803
|
+
variants.push(variant);
|
|
10005
10804
|
}
|
|
10006
10805
|
return variants;
|
|
10007
10806
|
}
|
|
@@ -10125,7 +10924,7 @@ function generateStyle(palette = "DAY", opts = {}) {
|
|
|
10125
10924
|
for (const { objectClass, label } of bundles) {
|
|
10126
10925
|
if (!label) continue;
|
|
10127
10926
|
if (getLabelBehavior(objectClass) === "orientation-cross-band") {
|
|
10128
|
-
labelLayers.push(...
|
|
10927
|
+
labelLayers.push(...fanOrientationLabelByCellBand(label));
|
|
10129
10928
|
}
|
|
10130
10929
|
}
|
|
10131
10930
|
for (const code of BAND_DRAW_ORDER) {
|