@@ -3,11 +3,13 @@ import type {
33 BackgroundLayerSpecification ,
44 ExpressionFilterSpecification ,
55 ExpressionSpecification ,
6+ FilterSpecification ,
67 LayerSpecification ,
78} from "maplibre-gl" ;
89import { LookupEntry } from "@enc-tiles/dai" ;
910import { instructionsToStyles } from "../instructions/index.js" ;
1011import * as filters from "../filters.js" ;
12+ import { groupBy } from "../utils.js" ;
1113
1214export interface LayerConfig {
1315 mode : Mode ;
@@ -37,33 +39,99 @@ const filterGeometryType: Record<LookupEntry["ftyp"], ExpressionSpecification> =
3739 } ;
3840
3941export function build ( config : LayerConfig ) : LayerSpecification [ ] {
42+ const lookupGroups = groupBy ( getLookups ( config ) , ( lookup ) => {
43+ return [ lookup . obcl , lookup . tnam ] . join ( "|" ) ;
44+ } ) ;
45+
46+ const layers : LayerSpecification [ ] = Object . values ( lookupGroups ) . flatMap (
47+ ( lookups ) => {
48+ if ( ! lookups )
49+ throw new Error (
50+ "This should never happen but TypeScript insists it can." ,
51+ ) ;
52+
53+ if ( lookups . length <= 1 ) {
54+ return lookups . flatMap ( lookupToLayers ) ;
55+ } else {
56+ return lookupGroupToLayers ( lookups ) ;
57+ }
58+ } ,
59+ ) ;
60+
61+ return [ background ( config ) , ...layers ] ;
62+ }
63+
64+ /**
65+ * 10.3.3.1 Look-Up Table Entry Matching
66+ *
67+ * > To find the symbology instruction for a specific object, enter the look-up table with the object's
68+ * > class code and gather all lines that contain [`objc`]. If only a single line is found,
69+ * > [`attc`] must be empty and the object is always shown with the same symbology
70+ * > regardless of its description.
71+ *
72+ * > If there is more than one line in the look-up table, search for the first line each of whose attribute
73+ * > values in [`attc`] can also be found in the attribute values of the object. If more than one attribute
74+ * > value is given in the look-up table, the match to the object must be exact, in order as well as
75+ * > content.
76+ */
77+ export function lookupGroupToLayers (
78+ lookups : LookupEntry [ ] ,
79+ ) : LayerSpecification [ ] {
80+ const [ fallbackLookup , ...otherLookups ] = lookups ;
81+
82+ const fallbackFilter : FilterSpecification = [
83+ "!" ,
84+ [
85+ "any" ,
86+ ...otherLookups . map ( ( lookup ) => {
87+ return filters . all ( ...filters . attributeFilters ( lookup . attc ) ) ;
88+ } ) ,
89+ ] ,
90+ ] ;
4091 return [
41- background ( config ) ,
42- ...getLookups ( config ) . flatMap ( ( lookup , i ) => {
43- return instructionsToStyles ( lookup . inst ) . map ( ( layer , j ) => {
44- return {
45- ...layer ,
46- filter : filters . all (
47- filters . scaleFilter ( ) ,
48- filterGeometryType [ lookup . ftyp ] ,
49- ...filters . attributeFilters ( lookup . attc ) ,
50- ...( "filter" in layer
51- ? [ layer . filter as ExpressionFilterSpecification ]
52- : [ ] ) ,
53- ) ,
54- layout : {
55- ...layer . layout ,
56- [ `${ layer . type } -sort-key` ] : sortKey ( lookup . dpri , layer ) ,
57- } ,
58- source : "enc" ,
59- "source-layer" : lookup . obcl ,
60- id : [ lookup . obcl , layer . type , lookup . rcid , i , j ] . join ( "-" ) ,
61- } ;
62- } ) ;
63- } ) ,
92+ ...lookupToLayers ( fallbackLookup ! ) . map ( ( layer ) => ( {
93+ ...layer ,
94+ ...( "filter" in layer
95+ ? {
96+ filter : filters . all (
97+ fallbackFilter ,
98+ layer . filter as ExpressionFilterSpecification ,
99+ ) ,
100+ }
101+ : { } ) ,
102+ } ) ) ,
103+ ...otherLookups . flatMap ( lookupToLayers ) ,
64104 ] ;
65105}
66106
107+ let i = 0 ;
108+
109+ export function lookupToLayers ( lookup : LookupEntry ) : LayerSpecification [ ] {
110+ return instructionsToStyles ( lookup . inst ) . map ( ( layer ) => {
111+ return {
112+ ...layer ,
113+ metadata : {
114+ s52 : lookup ,
115+ } ,
116+ filter : filters . all (
117+ filters . scaleFilter ( ) ,
118+ filterGeometryType [ lookup . ftyp ] ,
119+ ...filters . attributeFilters ( lookup . attc ) ,
120+ ...( "filter" in layer
121+ ? [ layer . filter as ExpressionFilterSpecification ]
122+ : [ ] ) ,
123+ ) ,
124+ layout : {
125+ ...layer . layout ,
126+ [ `${ layer . type } -sort-key` ] : sortKey ( lookup . dpri , layer ) ,
127+ } ,
128+ source : "enc" ,
129+ "source-layer" : lookup . obcl ,
130+ id : [ i ++ , lookup . obcl , lookup . ftyp ] . join ( "-" ) ,
131+ } ;
132+ } ) ;
133+ }
134+
67135function background ( { mode } : LayerConfig ) : BackgroundLayerSpecification {
68136 return {
69137 id : "background" ,
0 commit comments