@mailwoman/cartographer 1.0.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.
Files changed (100) hide show
  1. package/README.md +3 -0
  2. package/base/buildings.ts +124 -0
  3. package/base/composition.ts +119 -0
  4. package/base/index.ts +10 -0
  5. package/base/layers.ts +52 -0
  6. package/base/terrain.ts +33 -0
  7. package/base/theme.ts +118 -0
  8. package/bdc/index.ts +395 -0
  9. package/coverage/index.ts +89 -0
  10. package/hspa/index.ts +20 -0
  11. package/index.ts +12 -0
  12. package/out/base/buildings.d.ts +11 -0
  13. package/out/base/buildings.d.ts.map +1 -0
  14. package/out/base/buildings.js +109 -0
  15. package/out/base/buildings.js.map +1 -0
  16. package/out/base/composition.d.ts +33 -0
  17. package/out/base/composition.d.ts.map +1 -0
  18. package/out/base/composition.js +86 -0
  19. package/out/base/composition.js.map +1 -0
  20. package/out/base/index.d.ts +10 -0
  21. package/out/base/index.d.ts.map +1 -0
  22. package/out/base/index.js +10 -0
  23. package/out/base/index.js.map +1 -0
  24. package/out/base/layers.d.ts +9 -0
  25. package/out/base/layers.d.ts.map +1 -0
  26. package/out/base/layers.js +49 -0
  27. package/out/base/layers.js.map +1 -0
  28. package/out/base/terrain.d.ts +20 -0
  29. package/out/base/terrain.d.ts.map +1 -0
  30. package/out/base/terrain.js +29 -0
  31. package/out/base/terrain.js.map +1 -0
  32. package/out/base/theme.d.ts +20 -0
  33. package/out/base/theme.d.ts.map +1 -0
  34. package/out/base/theme.js +103 -0
  35. package/out/base/theme.js.map +1 -0
  36. package/out/bdc/index.d.ts +27 -0
  37. package/out/bdc/index.d.ts.map +1 -0
  38. package/out/bdc/index.js +344 -0
  39. package/out/bdc/index.js.map +1 -0
  40. package/out/coverage/index.d.ts +58 -0
  41. package/out/coverage/index.d.ts.map +1 -0
  42. package/out/coverage/index.js +77 -0
  43. package/out/coverage/index.js.map +1 -0
  44. package/out/hspa/index.d.ts +12 -0
  45. package/out/hspa/index.d.ts.map +1 -0
  46. package/out/hspa/index.js +18 -0
  47. package/out/hspa/index.js.map +1 -0
  48. package/out/index.d.ts +12 -0
  49. package/out/index.d.ts.map +1 -0
  50. package/out/index.js +12 -0
  51. package/out/index.js.map +1 -0
  52. package/out/race-dots/index.d.ts +61 -0
  53. package/out/race-dots/index.d.ts.map +1 -0
  54. package/out/race-dots/index.js +59 -0
  55. package/out/race-dots/index.js.map +1 -0
  56. package/out/styles/index.d.ts +8 -0
  57. package/out/styles/index.d.ts.map +1 -0
  58. package/out/styles/index.js +8 -0
  59. package/out/styles/index.js.map +1 -0
  60. package/out/styles/layers.d.ts +33 -0
  61. package/out/styles/layers.d.ts.map +1 -0
  62. package/out/styles/layers.js +108 -0
  63. package/out/styles/layers.js.map +1 -0
  64. package/out/styles/sources.d.ts +22 -0
  65. package/out/styles/sources.d.ts.map +1 -0
  66. package/out/styles/sources.js +12 -0
  67. package/out/styles/sources.js.map +1 -0
  68. package/out/tiger/index.d.ts +11 -0
  69. package/out/tiger/index.d.ts.map +1 -0
  70. package/out/tiger/index.js +64 -0
  71. package/out/tiger/index.js.map +1 -0
  72. package/out/tiles/api.d.ts +20 -0
  73. package/out/tiles/api.d.ts.map +1 -0
  74. package/out/tiles/api.js +41 -0
  75. package/out/tiles/api.js.map +1 -0
  76. package/out/tiles/coords.d.ts +16 -0
  77. package/out/tiles/coords.d.ts.map +1 -0
  78. package/out/tiles/coords.js +34 -0
  79. package/out/tiles/coords.js.map +1 -0
  80. package/out/tiles/index.d.ts +9 -0
  81. package/out/tiles/index.d.ts.map +1 -0
  82. package/out/tiles/index.js +9 -0
  83. package/out/tiles/index.js.map +1 -0
  84. package/out/tiles/schema.d.ts +41 -0
  85. package/out/tiles/schema.d.ts.map +1 -0
  86. package/out/tiles/schema.js +7 -0
  87. package/out/tiles/schema.js.map +1 -0
  88. package/out/tsconfig.tsbuildinfo +1 -0
  89. package/package.json +46 -0
  90. package/race-dots/index.ts +68 -0
  91. package/styles/index.ts +8 -0
  92. package/styles/layers.ts +148 -0
  93. package/styles/sources.ts +26 -0
  94. package/tiger/index.ts +71 -0
  95. package/tiles/api.ts +53 -0
  96. package/tiles/coords.ts +46 -0
  97. package/tiles/index.ts +9 -0
  98. package/tiles/schema.ts +42 -0
  99. package/tsconfig.json +22 -0
  100. package/typedoc.json +4 -0
package/bdc/index.ts ADDED
@@ -0,0 +1,395 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ import { TIGERLevel } from "@mailwoman/tiger"
8
+ import {
9
+ type CircleLayerSpecification,
10
+ type FillExtrusionLayerSpecification,
11
+ type FillLayerSpecification,
12
+ type HeatmapLayerSpecification,
13
+ type LineLayerSpecification,
14
+ type SymbolLayerSpecification,
15
+ } from "@maplibre/maplibre-gl-style-spec"
16
+ import { interpolateTurbo } from "d3-scale-chromatic"
17
+ import { type LayerSpecificationListInput } from "../styles/layers.js"
18
+ import { TileSetSourceID } from "../styles/sources.js"
19
+
20
+ /**
21
+ * Identifier for the Broadband Data Collection tile set.
22
+ */
23
+ export const BDCTileSetID = TileSetSourceID("bdc")
24
+
25
+ /**
26
+ * Broadband Data Collection layer specifications.
27
+ *
28
+ * @internal
29
+ */
30
+ export type BDCLayerSpecificationInput = LayerSpecificationListInput<
31
+ | FillLayerSpecification
32
+ | LineLayerSpecification
33
+ | CircleLayerSpecification
34
+ | HeatmapLayerSpecification
35
+ | SymbolLayerSpecification
36
+ | FillExtrusionLayerSpecification
37
+ >
38
+
39
+ /**
40
+ * Base specification for a Broadband Data Collection layer.
41
+ *
42
+ * @internal
43
+ */
44
+ export type BaseBDCLayerSpecification<T> = T extends BDCLayerSpecificationInput
45
+ ? Omit<T, "source-layer" | "source">
46
+ : never
47
+
48
+ function createBDCBlockLayer<T extends BDCLayerSpecificationInput>(spec: BaseBDCLayerSpecification<T>): T {
49
+ return {
50
+ ...spec,
51
+ id: `bdc_${TIGERLevel.Block}_${spec.id}`,
52
+ source: BDCTileSetID,
53
+ "source-layer": `bdc_${TIGERLevel.Block}`,
54
+ minzoom: 12,
55
+ } as unknown as T
56
+ }
57
+
58
+ function createBDCTractLayer<T extends BDCLayerSpecificationInput>(spec: BaseBDCLayerSpecification<T>): T {
59
+ return {
60
+ ...spec,
61
+ id: `bdc_${TIGERLevel.Tract}_${spec.id}`,
62
+ source: BDCTileSetID,
63
+ "source-layer": `bdc_${TIGERLevel.Tract}`,
64
+ maxzoom: 12,
65
+ minzoom: 9,
66
+ } as unknown as T
67
+ }
68
+
69
+ function createBDCCountyLayer<T extends BDCLayerSpecificationInput>(spec: BaseBDCLayerSpecification<T>): T {
70
+ return {
71
+ ...spec,
72
+ id: `bdc_${TIGERLevel.County}_${spec.id}`,
73
+ source: BDCTileSetID,
74
+ "source-layer": `bdc_${TIGERLevel.County}`,
75
+ maxzoom: 9,
76
+ minzoom: 2,
77
+ } as unknown as T
78
+ }
79
+
80
+ export function createBDCLayer<T extends BDCLayerSpecificationInput>(spec: BaseBDCLayerSpecification<T>): T[] {
81
+ return [createBDCBlockLayer(spec), createBDCTractLayer(spec), createBDCCountyLayer(spec)] as T[]
82
+ }
83
+
84
+ const GIGABIT_BROADBAND_SPEED = 1000
85
+
86
+ export const BroadbandDataCollectionLayers: BDCLayerSpecificationInput[] = [
87
+ {
88
+ afterID: "earth",
89
+ // metadata: {
90
+ // queryable: false,
91
+ // },
92
+ id: "blocks-underserved",
93
+ layout: {
94
+ visibility: "none",
95
+ },
96
+ "source-layer": `bdc_${TIGERLevel.Block}`,
97
+ source: BDCTileSetID,
98
+ type: "fill",
99
+ filter: [
100
+ // ---
101
+ "all",
102
+ ["in", 50, ["get", "technology_codes"]], // Fiber only
103
+ [">", ["get", "land_area_sqm"], 0],
104
+ // ["==", ["get", "UR"], "R"],
105
+ ],
106
+ paint: {
107
+ // "fill-extrusion-height": [
108
+ // // Our extrusion height represents the magnitude of broadband underservice,
109
+ // // e.g. How many people are underserved per square meter of land area.
110
+ // "let",
111
+ // "population_density",
112
+ // ["/", ["to-number", ["get", "population"]], ["to-number", ["get", "land_area_sqm"]]],
113
+ // ["*", ["var", "population_density"], 10000],
114
+ // ],
115
+ "fill-color": "hsl(60deg, 100%, 50%)",
116
+ "fill-opacity": [
117
+ // Underserved areas are emphasized to their level importance,
118
+ // relative to the impact of the underservice.
119
+ "let",
120
+ "internet_speed_impact",
121
+ ["/", ["to-number", ["get", "average_download_speed"]], GIGABIT_BROADBAND_SPEED],
122
+ [
123
+ // ---
124
+ "interpolate",
125
+ ["linear"],
126
+ ["var", "internet_speed_impact"],
127
+ 0,
128
+ 0.1,
129
+ 1,
130
+ 0.5,
131
+ ],
132
+ ],
133
+ },
134
+ // layout: {
135
+ // visibility: "none",
136
+ // },
137
+ },
138
+
139
+ {
140
+ afterID: "blocks-underserved",
141
+ id: "bdc-boundary-blocks",
142
+ layout: {
143
+ visibility: "none",
144
+ },
145
+ metadata: {
146
+ queryable: false,
147
+ },
148
+ "source-layer": `bdc_${TIGERLevel.Block}`,
149
+ source: BDCTileSetID,
150
+ type: "line",
151
+ // filter: [">=", ["get", "ALAND"], 0],
152
+ minzoom: 9,
153
+ paint: {
154
+ "line-color": "#000",
155
+ "line-width": 1,
156
+ "line-dasharray": [2, 2],
157
+ },
158
+ },
159
+ {
160
+ afterID: "blocks-underserved",
161
+ metadata: {
162
+ queryable: false,
163
+ },
164
+ id: "blocks-underserved-ratio-label",
165
+ "source-layer": `bdc_${TIGERLevel.Block}`,
166
+ source: BDCTileSetID,
167
+ type: "symbol",
168
+ filter: [
169
+ // ---
170
+ "all",
171
+ // ["in", 50, ["get", "technology_codes"]], // Fiber only
172
+ [">", ["get", "land_area_sqm"], 0],
173
+ // ["==", ["get", "UR"], "R"],
174
+ ],
175
+ paint: {
176
+ "text-color": "black",
177
+ "text-halo-color": "white",
178
+ "text-halo-width": 1,
179
+ },
180
+ layout: {
181
+ visibility: "none",
182
+ "text-field": [
183
+ "concat",
184
+ ["number-format", ["get", "average_download_speed"], { "min-fraction-digits": 0, "max-fraction-digits": 2 }],
185
+ " Mbps",
186
+ ],
187
+ "text-size": 10,
188
+ "text-offset": [0, 0],
189
+ "text-anchor": "center",
190
+ "text-font": ["Fira Code Regular"],
191
+ },
192
+ },
193
+ ...createBDCLayer({
194
+ id: "coverage-fiber-label",
195
+ beforeID: "places_subplace",
196
+ filter: [
197
+ // ---
198
+
199
+ "all",
200
+ ["==", ["get", "provider_id"], 131425],
201
+ // ["in", 50, ["get", "technology_codes"]],
202
+ ],
203
+ type: "symbol",
204
+ layout: {
205
+ visibility: "none",
206
+ "text-field": [
207
+ "concat",
208
+ ["number-format", ["get", "average_download_speed"], { "min-fraction-digits": 0, "max-fraction-digits": 2 }],
209
+ " Mbps",
210
+ ],
211
+ "text-size": [
212
+ // ---
213
+ "let",
214
+ "multiplier",
215
+ // We scale the text size based on the average download speed.
216
+ // By default, we're no smaller than 14, Any speed above the gigabit threshold
217
+ // acts as a multiplier for the text size.
218
+ // ---
219
+ ["/", ["get", "average_download_speed"], GIGABIT_BROADBAND_SPEED / 4],
220
+ ["+", 14, ["var", "multiplier"]],
221
+ ],
222
+ "text-offset": [0, 0],
223
+ "text-line-height": 1.2,
224
+ "text-pitch-alignment": "viewport",
225
+ "text-variable-anchor": ["center"],
226
+ "text-padding": 10,
227
+ "text-anchor": "center",
228
+ "text-font": ["Fira Code Medium"],
229
+ },
230
+
231
+ paint: {
232
+ "text-halo-width": 2,
233
+ "text-halo-color": [
234
+ // ---
235
+ "interpolate",
236
+ ["exponential", 0.5],
237
+ ["get", "average_download_speed"],
238
+ GIGABIT_BROADBAND_SPEED / 4,
239
+ "#fff",
240
+
241
+ GIGABIT_BROADBAND_SPEED,
242
+ "#000",
243
+ ],
244
+
245
+ "text-color": [
246
+ // ---
247
+ "interpolate",
248
+ ["exponential", 0.25],
249
+ ["get", "average_download_speed"],
250
+ GIGABIT_BROADBAND_SPEED / 4,
251
+ interpolateTurbo(0),
252
+
253
+ GIGABIT_BROADBAND_SPEED / 2,
254
+ interpolateTurbo(0.25),
255
+
256
+ GIGABIT_BROADBAND_SPEED,
257
+ interpolateTurbo(0.5),
258
+
259
+ GIGABIT_BROADBAND_SPEED * 2,
260
+ interpolateTurbo(0.75),
261
+
262
+ GIGABIT_BROADBAND_SPEED * 4,
263
+ interpolateTurbo(1),
264
+ ],
265
+ },
266
+ }),
267
+ {
268
+ afterID: "blocks-underserved",
269
+ type: "line",
270
+ source: "composite",
271
+ id: "lm-routes",
272
+ paint: {
273
+ "line-color": "#ff009c",
274
+
275
+ "line-width": [
276
+ "interpolate",
277
+ ["exponential", 1.6],
278
+ ["zoom"],
279
+ // ---
280
+ 3,
281
+ 0,
282
+ 6,
283
+ 1.1,
284
+ 12,
285
+ 1.6,
286
+ 15,
287
+ 5,
288
+ 18,
289
+ 15,
290
+ ],
291
+ },
292
+ layout: {
293
+ "line-cap": "round",
294
+ },
295
+ "source-layer": "CENTURYLINK_ROUTE",
296
+ },
297
+ ...createBDCLayer({
298
+ afterID: "earth",
299
+ id: "coverage-fiber-heat",
300
+ filter: [
301
+ // ---
302
+
303
+ "all",
304
+ ["==", ["get", "provider_id"], 131425],
305
+ ],
306
+ minzoom: 10,
307
+ type: "heatmap",
308
+ layout: {
309
+ visibility: "none",
310
+ },
311
+ paint: {
312
+ "heatmap-color": [
313
+ // ---
314
+ "interpolate",
315
+ ["linear"],
316
+ ["heatmap-density"],
317
+ ...Array.from({ length: 10 }, (_, i) => {
318
+ return [i / 10, interpolateTurbo(i / 10)] as [number, string]
319
+ }).flat(),
320
+ ],
321
+
322
+ "heatmap-radius": [
323
+ // ---
324
+ "interpolate",
325
+ ["linear"],
326
+ ["zoom"],
327
+ 10,
328
+ 5,
329
+ 15,
330
+ 20,
331
+ ],
332
+ "heatmap-weight": [
333
+ // ---
334
+ "*",
335
+ ["get", "land_area_sqm"],
336
+ 0.00001,
337
+ ],
338
+ },
339
+ }),
340
+
341
+ {
342
+ maxzoom: 13,
343
+ beforeID: "places_locality",
344
+ type: "circle",
345
+ id: "datacenter-marker",
346
+ source: "composite",
347
+ "source-layer": "DataCentersCombined20220921",
348
+ paint: {
349
+ "circle-color": "red",
350
+ "circle-stroke-color": "hsl(0, 0%, 100%)",
351
+ "circle-stroke-width": 2,
352
+ "circle-radius": ["interpolate", ["linear"], ["zoom"], 2, 3, 12, 5],
353
+ "circle-opacity": ["interpolate", ["linear"], ["zoom"], 2, 0.84, 3, 1, 22, 1],
354
+ },
355
+ layout: {
356
+ visibility: "none",
357
+ },
358
+ },
359
+
360
+ {
361
+ maxzoom: 13,
362
+ minzoom: 8,
363
+ afterID: "datacenter-marker",
364
+ id: "datacenter-label",
365
+ type: "symbol",
366
+ source: "composite",
367
+ "source-layer": "DataCentersCombined20220921",
368
+ layout: {
369
+ // visibility: "none",
370
+ "text-field": ["get", "Category"],
371
+ "text-size": 12,
372
+ "text-anchor": "top",
373
+ "text-offset": [0, 0.5],
374
+ // "text-allow-overlap": true,
375
+ "text-font": ["Fira Code Regular"],
376
+ },
377
+ paint: {
378
+ "text-color": "#fff",
379
+ "text-halo-color": "#fb8429",
380
+ "text-halo-width": 1,
381
+ "text-opacity": [
382
+ // We fade out the outline at higher zoom levels
383
+ "interpolate",
384
+ ["linear"],
385
+ ["zoom"],
386
+ 1,
387
+ 0.01,
388
+ 6,
389
+ 0.5,
390
+ 16,
391
+ 1,
392
+ ],
393
+ },
394
+ },
395
+ ]
@@ -0,0 +1,89 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ *
6
+ * The "fog of war" address-COVERAGE overlay. An H3 hexbin tileset (built by
7
+ * `scripts/build-coverage-tiles.ts`) shades each area by how much address-point data we hold:
8
+ * covered → clear (the basemap shows through), empty → opaque gray fog. Answers "where do we need
9
+ * more data" at a glance, and reveals the "looks covered until you zoom in, then it goes gray" gaps.
10
+ *
11
+ * Each cell carries TWO baked fog values in [0,1] (0 = covered, 1 = empty), so the same tiles drive
12
+ * either reading without a rebuild:
13
+ * • `fog_opt` — optimistic: partial coverage lifted toward clear, so a region "looks covered" when
14
+ * zoomed out and the gaps only surface on zoom-in.
15
+ * • `fog` — honest: true coverage fraction, so the gap is visible even at low zoom.
16
+ * We expose each as its OWN default-off fill layer (`coverage-opt-fog`, `coverage-honest-fog`) so the
17
+ * demo's LayerToggleControl gives each its own checkbox — pick the reading you want, no extra UI.
18
+ *
19
+ * Served as XYZ vector tiles by the tile worker from `nexus-assets/tiles/coverage-us-v4.pmtiles` (same
20
+ * as `basemap-v4`); the consumer passes its TileJSON URL (`tiles.sister.software/coverage-us-v4.json`)
21
+ * to `createCoverageSource`.
22
+ */
23
+
24
+ import type {
25
+ FillLayerSpecification,
26
+ VectorSourceSpecification,
27
+ } from "@maplibre/maplibre-gl-style-spec"
28
+ import { TileSetSourceID } from "../styles/sources.js"
29
+
30
+ export const CoverageTileSetID = TileSetSourceID("coverage-us-v4")
31
+
32
+ /**
33
+ * The single source-layer the coverage PMTiles ships (see `build-coverage-tiles.ts` → tippecanoe `-l`).
34
+ */
35
+ export const COVERAGE_SOURCE_LAYER = "coverage"
36
+
37
+ /**
38
+ * Fog tint — a near-black indigo reading as "unknown / unsurveyed". Pushed dark (vs a mid indigo) so it
39
+ * holds contrast over the demo's terrain+hillshade basemap, which is itself dark-green over forest where
40
+ * a lighter fog would simply vanish.
41
+ */
42
+ export const COVERAGE_FOG_COLOR = "#663399" // Rebecca Purple
43
+
44
+ /**
45
+ * Opacity of a fully-empty (`fog = 1`) cell. Covered cells scale down from here toward transparent.
46
+ */
47
+ export const COVERAGE_MAX_FOG_OPACITY = 0.9
48
+
49
+ /**
50
+ * Layer IDs, exported so the demo (toggle wiring, imperative add) and tests can reference them.
51
+ */
52
+ export const CoverageLayerID = {
53
+ optimistic: "coverage-opt-fog",
54
+ honest: "coverage-honest-fog",
55
+ } as const
56
+
57
+ /**
58
+ * Build the coverage source spec from the tile worker's TileJSON endpoint
59
+ * (`https://tiles.sister.software/coverage-us-v4.json`).
60
+ */
61
+ export function createCoverageSource(url: string): VectorSourceSpecification {
62
+ return { type: "vector", url }
63
+ }
64
+
65
+ function fogFill(id: string, fogProperty: "fog" | "fog_opt"): FillLayerSpecification {
66
+ return {
67
+ id,
68
+ type: "fill",
69
+ source: CoverageTileSetID,
70
+ "source-layer": COVERAGE_SOURCE_LAYER,
71
+ // Default OFF — an overlay, surfaced via the layer toggle, never on by default.
72
+ layout: { visibility: "none" },
73
+ paint: {
74
+ "fill-color": COVERAGE_FOG_COLOR,
75
+ // Opacity tracks the cell's fog value; coalesce guards a missing prop to 0 (fully clear).
76
+ "fill-opacity": ["*", ["coalesce", ["to-number", ["get", fogProperty]], 0], COVERAGE_MAX_FOG_OPACITY],
77
+ },
78
+ }
79
+ }
80
+
81
+ /**
82
+ * The two default-off fog fills (optimistic + honest). Plain MapLibre specs — the demo adds them
83
+ * imperatively on map-load with a `beforeId` of the first symbol layer, so the fog sits beneath place
84
+ * labels but above basemap geometry (roads/water vanish under fog where we have no data).
85
+ */
86
+ export const CoverageLayers: FillLayerSpecification[] = [
87
+ fogFill(CoverageLayerID.optimistic, "fog_opt"),
88
+ fogFill(CoverageLayerID.honest, "fog"),
89
+ ]
package/hspa/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ // import { LayerSpecificationListInput } from "../styles/layers.js"
8
+ import { TileSetSourceID } from "../styles/sources.js"
9
+
10
+ /**
11
+ * Identifier for the Health Service Provider Access tile set.
12
+ */
13
+ export const HSPATileSetID = TileSetSourceID("HPSA_PNTPC_SHP_DET_CUR_VX")
14
+ export const MUATileSetID = TileSetSourceID("MUA_CMPPC_SHP_DET_CUR_VX")
15
+
16
+ // export const MUALayers: LayerSpecificationListInput[] = [
17
+ // {
18
+ // "id": ""
19
+ // },
20
+ // ]
package/index.ts ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+
7
+ export * from "./base/index.js"
8
+ export * from "./bdc/index.js"
9
+ export * from "./hspa/index.js"
10
+ export * from "./styles/index.js"
11
+ export * from "./tiger/index.js"
12
+ export * from "./tiles/index.js"
@@ -0,0 +1,11 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import { type LayerSpecification } from "@maplibre/maplibre-gl-style-spec";
7
+ /**
8
+ * Layer definitions for building data.
9
+ */
10
+ export declare const BuildingLayers: LayerSpecification[];
11
+ //# sourceMappingURL=buildings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildings.d.ts","sourceRoot":"","sources":["../../base/buildings.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAwC,KAAK,kBAAkB,EAAE,MAAM,kCAAkC,CAAA;AAOhH;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,kBAAkB,EA8D9C,CAAA"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import {} from "@maplibre/maplibre-gl-style-spec";
7
+ import { interpolateTurbo } from "d3-scale-chromatic";
8
+ import { LayerID } from "../styles/layers.js";
9
+ import { MailwomanBaseTileSetID } from "./theme.js";
10
+ const BuildingLayerID = LayerID.bind(null, "buildings");
11
+ /**
12
+ * Layer definitions for building data.
13
+ */
14
+ export const BuildingLayers = [
15
+ createBuildingFillStyleLayer({
16
+ id: BuildingLayerID("buildings-extruded"),
17
+ paint: {
18
+ "fill-extrusion-color": [
19
+ // ---
20
+ "interpolate",
21
+ // ["exponential", 0.25],
22
+ ["linear"],
23
+ [
24
+ // --
25
+ "coalesce",
26
+ ["get", "height"],
27
+ ["get", "minheight"],
28
+ 10,
29
+ ],
30
+ ...Array.from({ length: 10 }, (_, i) => {
31
+ const sizeScalingFactor = 250 - 250 / i;
32
+ return [sizeScalingFactor, interpolateTurbo(sizeScalingFactor / 250)];
33
+ }).flat(),
34
+ ],
35
+ "fill-extrusion-translate": [0.1, 0.1],
36
+ },
37
+ }),
38
+ {
39
+ id: "basemap-buildings-outline",
40
+ type: "line",
41
+ source: MailwomanBaseTileSetID,
42
+ "source-layer": "buildings",
43
+ minzoom: 11,
44
+ filter: ["==", ["%", ["to-number", ["id"]], 2], 0],
45
+ paint: {
46
+ "line-width": 1,
47
+ "line-color": "hsl(240deg 100% 80%)",
48
+ "line-opacity": ["interpolate", ["linear"], ["zoom"], 11, 0, 20, 1],
49
+ "line-dasharray": [2, 3],
50
+ },
51
+ },
52
+ {
53
+ id: "basemap-buildings-kind",
54
+ type: "symbol",
55
+ source: MailwomanBaseTileSetID,
56
+ "source-layer": "buildings",
57
+ minzoom: 11,
58
+ layout: {
59
+ visibility: "none",
60
+ "text-field": ["to-string", ["id"]],
61
+ "text-offset": [0, 0],
62
+ "text-anchor": "center",
63
+ "text-font": ["Fira Sans Regular"],
64
+ },
65
+ paint: {
66
+ "text-color": "black",
67
+ "text-halo-color": "red",
68
+ "text-halo-width": 1,
69
+ },
70
+ },
71
+ ];
72
+ function createBuildingFillStyleLayer(fillStyleSpec) {
73
+ const baseStyle = {
74
+ ...fillStyleSpec,
75
+ type: "fill-extrusion",
76
+ source: MailwomanBaseTileSetID,
77
+ "source-layer": "buildings",
78
+ minzoom: 12,
79
+ paint: {
80
+ ...fillStyleSpec.paint,
81
+ "fill-extrusion-vertical-gradient": true,
82
+ "fill-extrusion-height": [
83
+ "+",
84
+ [
85
+ // --
86
+ "coalesce",
87
+ ["get", "height"],
88
+ ["get", "minheight"],
89
+ 10,
90
+ ],
91
+ fillStyleSpec.heightOffset || 0,
92
+ ],
93
+ "fill-extrusion-translate-anchor": "map",
94
+ // "fill-extrusion-opacity": 0.7,
95
+ "fill-extrusion-opacity": [
96
+ // We fade out the outline at higher zoom levels
97
+ "interpolate",
98
+ ["linear"],
99
+ ["zoom"],
100
+ 11,
101
+ 0.6,
102
+ 16,
103
+ 0.95,
104
+ ],
105
+ },
106
+ };
107
+ return baseStyle;
108
+ }
109
+ //# sourceMappingURL=buildings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildings.js","sourceRoot":"","sources":["../../base/buildings.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAiE,MAAM,kCAAkC,CAAA;AAChH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAEnD,MAAM,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;AAEvD;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAyB;IACnD,4BAA4B,CAAC;QAC5B,EAAE,EAAE,eAAe,CAAC,oBAAoB,CAAC;QAEzC,KAAK,EAAE;YACN,sBAAsB,EAAE;gBACvB,MAAM;gBACN,aAAa;gBACb,yBAAyB;gBACzB,CAAC,QAAQ,CAAC;gBACV;oBACC,KAAK;oBACL,UAAU;oBACV,CAAC,KAAK,EAAE,QAAQ,CAAC;oBACjB,CAAC,KAAK,EAAE,WAAW,CAAC;oBACpB,EAAE;iBACF;gBACD,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;oBACtC,MAAM,iBAAiB,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAA;oBAEvC,OAAO,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,iBAAiB,GAAG,GAAG,CAAC,CAAqB,CAAA;gBAC1F,CAAC,CAAC,CAAC,IAAI,EAAE;aACT;YACD,0BAA0B,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC;SACtC;KACD,CAAC;IAEF;QACC,EAAE,EAAE,2BAA2B;QAC/B,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,WAAW;QAC3B,OAAO,EAAE,EAAE;QACX,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QAClD,KAAK,EAAE;YACN,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,sBAAsB;YACpC,cAAc,EAAE,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YACnE,gBAAgB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;SACxB;KACD;IAED;QACC,EAAE,EAAE,wBAAwB;QAC5B,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,WAAW;QAC3B,OAAO,EAAE,EAAE;QACX,MAAM,EAAE;YACP,UAAU,EAAE,MAAM;YAClB,YAAY,EAAE,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC;YACnC,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;YACrB,aAAa,EAAE,QAAQ;YACvB,WAAW,EAAE,CAAC,mBAAmB,CAAC;SAClC;QAED,KAAK,EAAE;YACN,YAAY,EAAE,OAAO;YACrB,iBAAiB,EAAE,KAAK;YACxB,iBAAiB,EAAE,CAAC;SACpB;KACD;CACD,CAAA;AAOD,SAAS,4BAA4B,CAAC,aAAoC;IACzE,MAAM,SAAS,GAAuB;QACrC,GAAG,aAAa;QAChB,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,sBAAsB;QAC9B,cAAc,EAAE,WAAW;QAC3B,OAAO,EAAE,EAAE;QACX,KAAK,EAAE;YACN,GAAG,aAAa,CAAC,KAAK;YACtB,kCAAkC,EAAE,IAAI;YAExC,uBAAuB,EAAE;gBACxB,GAAG;gBACH;oBACC,KAAK;oBACL,UAAU;oBACV,CAAC,KAAK,EAAE,QAAQ,CAAC;oBACjB,CAAC,KAAK,EAAE,WAAW,CAAC;oBACpB,EAAE;iBACF;gBACD,aAAa,CAAC,YAAY,IAAI,CAAC;aAC/B;YACD,iCAAiC,EAAE,KAAK;YACxC,iCAAiC;YACjC,wBAAwB,EAAE;gBACzB,gDAAgD;gBAChD,aAAa;gBACb,CAAC,QAAQ,CAAC;gBACV,CAAC,MAAM,CAAC;gBACR,EAAE;gBACF,GAAG;gBACH,EAAE;gBACF,IAAI;aACJ;SACD;KACD,CAAA;IAED,OAAO,SAAS,CAAA;AACjB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @copyright Sister Software.
3
+ * @license AGPL-3.0
4
+ * @author Teffen Ellis, et al.
5
+ */
6
+ import type { SourceSpecification } from "@maplibre/maplibre-gl-style-spec";
7
+ import type { LightSpecification, SkySpecification, StyleSpecification, TerrainSpecification } from "maplibre-gl";
8
+ import { LayerSpecificationList, type LayerSpecificationListInput, type LayerSpecificationListItem } from "../styles/layers.js";
9
+ import { type TileSetSourceRecord } from "../styles/sources.js";
10
+ export declare function createLightSpec(spec?: Partial<LightSpecification>): LightSpecification;
11
+ export declare function createSkySpec(spec?: Partial<SkySpecification>): SkySpecification;
12
+ export interface StyleSpecificationComposition {
13
+ sources: Record<string, SourceSpecification>;
14
+ layers?: LayerSpecificationListInput[];
15
+ light?: Partial<LightSpecification>;
16
+ sky?: Partial<SkySpecification>;
17
+ terrain?: Partial<TerrainSpecification>;
18
+ }
19
+ /**
20
+ * A stateful class for composing a style specification.
21
+ */
22
+ export declare class StyleSpecificationComposer {
23
+ layersList: LayerSpecificationList;
24
+ light: LightSpecification;
25
+ sky: SkySpecification;
26
+ terrain: TerrainSpecification;
27
+ sources: TileSetSourceRecord;
28
+ constructor(spec: StyleSpecificationComposition);
29
+ get layers(): LayerSpecificationListItem[];
30
+ toJSON(): StyleSpecification;
31
+ toJS(): StyleSpecification;
32
+ }
33
+ //# sourceMappingURL=composition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.d.ts","sourceRoot":"","sources":["../../base/composition.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAA;AAC3E,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACjH,OAAO,EACN,sBAAsB,EACtB,KAAK,2BAA2B,EAChC,KAAK,0BAA0B,EAC/B,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAQ/D,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAYtF;AAED,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAUhF;AAMD,MAAM,WAAW,6BAA6B;IAC7C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,2BAA2B,EAAE,CAAA;IACtC,KAAK,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAA;IACnC,GAAG,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;CACvC;AAED;;GAEG;AACH,qBAAa,0BAA0B;IACtC,UAAU,EAAE,sBAAsB,CAAA;IAClC,KAAK,EAAE,kBAAkB,CAAA;IACzB,GAAG,EAAE,gBAAgB,CAAA;IACrB,OAAO,EAAE,oBAAoB,CAAA;IAC7B,OAAO,EAAE,mBAAmB,CAAA;gBAEhB,IAAI,EAAE,6BAA6B;IAsB/C,IAAW,MAAM,IAAI,0BAA0B,EAAE,CAEhD;IAED,MAAM,IAAI,kBAAkB;IAkB5B,IAAI,IAAI,kBAAkB;CAG1B"}