Skip to content

Commit 15f08d8

Browse files
committed
Group lookups by their objc and tnam per section 10.3.3.1
1 parent aec5019 commit 15f08d8

1 file changed

Lines changed: 94 additions & 23 deletions

File tree

packages/styles/src/symbolology/index.ts

Lines changed: 94 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
BackgroundLayerSpecification,
44
ExpressionFilterSpecification,
55
ExpressionSpecification,
6+
FilterSpecification,
67
LayerSpecification,
78
} from "maplibre-gl";
89
import { LookupEntry } from "@enc-tiles/dai";
@@ -37,33 +38,103 @@ const filterGeometryType: Record<LookupEntry["ftyp"], ExpressionSpecification> =
3738
};
3839

3940
export function build(config: LayerConfig): LayerSpecification[] {
41+
// Group by object class and table name
42+
const lookupGroups = getLookups(config).reduce((acc, lookup) => {
43+
const key = [lookup.obcl, lookup.tnam].join("|");
44+
acc[key] ??= [];
45+
acc[key].push(lookup);
46+
return acc;
47+
}, {});
48+
49+
const layers: LayerSpecification[] = Object.values(lookupGroups).flatMap(
50+
(lookups) => {
51+
if (!lookups)
52+
throw new Error(
53+
"This should never happen but TypeScript insists it can.",
54+
);
55+
56+
if (lookups.length <= 1) {
57+
return lookups.flatMap(lookupToLayers);
58+
} else {
59+
return lookupGroupToLayers(lookups);
60+
}
61+
},
62+
);
63+
64+
return [background(config), ...layers];
65+
}
66+
67+
/**
68+
* 10.3.3.1 Look-Up Table Entry Matching
69+
*
70+
* > To find the symbology instruction for a specific object, enter the look-up table with the object's
71+
* > class code and gather all lines that contain [`objc`]. If only a single line is found,
72+
* > [`attc`] must be empty and the object is always shown with the same symbology
73+
* > regardless of its description.
74+
*
75+
* > If there is more than one line in the look-up table, search for the first line each of whose attribute
76+
* > values in [`attc`] can also be found in the attribute values of the object. If more than one attribute
77+
* > value is given in the look-up table, the match to the object must be exact, in order as well as
78+
* > content.
79+
*/
80+
export function lookupGroupToLayers(
81+
lookups: LookupEntry[],
82+
): LayerSpecification[] {
83+
const [fallbackLookup, ...otherLookups] = lookups;
84+
85+
const fallbackFilter: FilterSpecification = [
86+
"!",
87+
[
88+
"any",
89+
...otherLookups.map((lookup) => {
90+
return filters.all(...filters.attributeFilters(lookup.attc));
91+
}),
92+
],
93+
];
4094
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-
}),
95+
...lookupToLayers(fallbackLookup!).map((layer) => ({
96+
...layer,
97+
...("filter" in layer
98+
? {
99+
filter: filters.all(
100+
fallbackFilter,
101+
layer.filter as ExpressionFilterSpecification,
102+
),
103+
}
104+
: {}),
105+
})),
106+
...otherLookups.flatMap(lookupToLayers),
64107
];
65108
}
66109

110+
let i = 0;
111+
112+
export function lookupToLayers(lookup: LookupEntry): LayerSpecification[] {
113+
return instructionsToStyles(lookup.inst).map((layer) => {
114+
return {
115+
...layer,
116+
metadata: {
117+
s52: lookup,
118+
},
119+
filter: filters.all(
120+
filters.scaleFilter(),
121+
filterGeometryType[lookup.ftyp],
122+
...filters.attributeFilters(lookup.attc),
123+
...("filter" in layer
124+
? [layer.filter as ExpressionFilterSpecification]
125+
: []),
126+
),
127+
layout: {
128+
...layer.layout,
129+
[`${layer.type}-sort-key`]: sortKey(lookup.dpri, layer),
130+
},
131+
source: "enc",
132+
"source-layer": lookup.obcl,
133+
id: [i++, lookup.obcl, lookup.ftyp].join("-"),
134+
};
135+
});
136+
}
137+
67138
function background({ mode }: LayerConfig): BackgroundLayerSpecification {
68139
return {
69140
id: "background",

0 commit comments

Comments
 (0)