Skip to content

Commit 206fc8a

Browse files
committed
feat: Allow to create a layer from a PMTiles URL in the connect layer component (closes #1409)
1 parent c4579f1 commit 206fc8a

File tree

2 files changed

+43
-48
lines changed

2 files changed

+43
-48
lines changed

map/client/mixins/map/mixin.pmtiles-layers.js

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,7 @@ import { mapbox_style, kdk_style } from '@kalisio/leaflet-pmtiles'
88
import { api, Time, Units, Events, TemplateContext } from '../../../../core/client/index.js'
99
import * as time from '../../../../core/client/utils/utils.time.js'
1010
import * as layers from '../../utils/utils.layers.js'
11-
12-
function detectStyleType (style) {
13-
// `style` field on pmtile layer definition can be one of:
14-
// - string => in this case we assume this is a mapbox json style
15-
// - kdk style object
16-
// - protomaps style object
17-
18-
if (typeof style === 'string') return 'mapbox'
19-
// Look for 'symbolizer' keys in the object, if we find one, this is a protomaps style
20-
if (_.some(style, (rule) => rule.symbolizer !== undefined)) return 'protomaps'
21-
// Otherwise we assume this is a kdk style object
22-
return style ? 'kdk' : 'empty'
23-
}
11+
import { detectStyleType, applyLayerFilters } from '../../../common/pmtiles-utils.js'
2412

2513
export const pmtilesLayers = {
2614
methods: {
@@ -110,28 +98,12 @@ export const pmtilesLayers = {
11098
} else if (styleType === 'kdk') {
11199
// Translate kdk style to protomap rules, take care to merge with default engine style
112100
const engineStyle = _.pick(_.get(this.activityOptions, 'engine.style', {}), ['point', 'line', 'polygon'])
113-
rules = kdk_style(_.merge(engineStyle, style), leafletOptions.dataLayer)
101+
rules = kdk_style(_.merge(_.cloneDeep(engineStyle), style), leafletOptions.dataLayer)
114102
}
115103
if (options.filters) {
116104
// Translate layer filters to filter function
117105
const filterFn = layers.getFilterFunctionFromLayerFilters(options)
118-
rules.paintRules.forEach(rule => {
119-
// kdkFilter member may not be present, this is added by kdk_style when translating kdk style
120-
// to leaflet-protomaps rules
121-
if (rule.kdkFilter) {
122-
rule.filter = (zoom, feature) => {
123-
const kdkFilter = rule.kdkFilter(zoom, feature)
124-
const filter = filterFn({ zoom, feature, properties: feature.props })
125-
// Final filter = kdk style filter + updated filter
126-
return kdkFilter && filter
127-
}
128-
} else {
129-
rule.filter = (zoom, feature) => {
130-
const filter = filterFn({ zoom, feature, properties: feature.props })
131-
return filter
132-
}
133-
}
134-
})
106+
applyLayerFilters(filterFn, rules.paintRules)
135107
}
136108
}
137109

@@ -179,24 +151,13 @@ export const pmtilesLayers = {
179151
}
180152
},
181153
onLayerFilterToggledPMTilesLayers (layer, filter) {
154+
// Retrieve the engine layer and update the filter function directly
155+
const leafletLayer = this.getLeafletLayerByName(layer. name)
156+
if (!leafletLayer) return
182157
// Filtering is managed by mongodb query syntax, we need to update the filter function
183158
const filterFn = layers.getFilterFunctionFromLayerFilters(layer)
184-
// Retrieve the engine layer and update the filter function directly
185-
layer = this.getLeafletLayerByName(layer. name)
186-
if (!layer) return
187-
layer.paintRules.forEach(rule => {
188-
// kdkFilter member may not be present, this is added by kdk_style when translating kdk style
189-
// to leaflet-protomaps rules
190-
if (rule.kdkFilter) {
191-
rule.filter = (zoom, feature) => {
192-
// Final filter = kdk style filter + updated filter
193-
return rule.kdkFilter(zoom, feature) && filterFn({ zoom, feature, properties: feature.props })
194-
}
195-
} else {
196-
rule.filter = (zoom, feature) => filterFn({ zoom, feature, properties: feature.props })
197-
}
198-
})
199-
layer.redraw()
159+
applyLayerFilters(filterFn, leafletLayer.paintRules)
160+
leafletLayer.redraw()
200161
}
201162
},
202163
created () {

map/common/pmtiles-utils.js

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export function getPMTilesLayers(header, metadata) {
1818
id: layer.id,
1919
display: layer.id,
2020
description: layer.description,
21-
bounds: metadata.bounds || [header.minLon, header.maxLon, header.minLat, header.maxLat],
21+
bounds: metadata.bounds || [header.minLon, header.minLat, header.maxLon, header.maxLat],
2222
fields: layer.fields,
2323
minZoom: layer.minzoom || header.minZoom,
2424
maxZoom: layer.maxzoom || header.maxZoom
@@ -48,4 +48,38 @@ export function generatePropertiesSchema (layer) {
4848
})
4949

5050
return schema
51+
}
52+
53+
export function detectStyleType (style) {
54+
// `style` field on pmtiles layer definition can be one of:
55+
// - string => in this case we assume this is the URL to a mapbox json style
56+
// - kdk style object
57+
// - protomaps style object
58+
59+
if (typeof style === 'string') return 'mapbox'
60+
// Look for 'symbolizer' keys in the object, if we find one, this is a protomaps style
61+
if (_.some(style, (rule) => rule.symbolizer !== undefined)) return 'protomaps'
62+
// Otherwise we assume this is a kdk style object
63+
return style ? 'kdk' : 'empty'
64+
}
65+
66+
// Apply layer filters function to paint rules
67+
export function applyLayerFilters(filterFn, paintRules) {
68+
paintRules.forEach(rule => {
69+
// kdkFilter member may not be present, this is added by kdk_style when translating kdk style
70+
// to leaflet-protomaps rules
71+
if (rule.kdkFilter) {
72+
rule.filter = (zoom, feature) => {
73+
const kdkFilter = rule.kdkFilter(zoom, feature)
74+
const filter = filterFn({ zoom, feature, properties: feature.props })
75+
// Final filter = kdk style filter + updated filter
76+
return kdkFilter && filter
77+
}
78+
} else {
79+
rule.filter = (zoom, feature) => {
80+
const filter = filterFn({ zoom, feature, properties: feature.props })
81+
return filter
82+
}
83+
}
84+
})
5185
}

0 commit comments

Comments
 (0)