diff --git a/demo/js/farming.js b/demo/js/farming.js
index 424cc2b8..946e323c 100755
--- a/demo/js/farming.js
+++ b/demo/js/farming.js
@@ -37,6 +37,7 @@ var datasetsPlugin = createDatasetsPlugin({
id: 'field-parcels',
label: 'Field parcels',
geojson: `${process.env.FARMING_API_URL}/api/collections/parcels/items?sbi=106325052`, // 106200212
+ idProperty: 'id',
transformRequest: transformDataRequest,
maxFeatures: 50000,
// filter: [
diff --git a/demo/js/index.js b/demo/js/index.js
index cfdab65f..4830f71b 100755
--- a/demo/js/index.js
+++ b/demo/js/index.js
@@ -125,6 +125,7 @@ const datasetsPlugin = createDatasetsPlugin({
showInKey: true,
showInMenu: true,
style: {
+ symbolDescription: 'Land cover',
fillPattern: 'horizontal-hatch',
fillPatternForegroundColor: { outdoor: '#00897B', dark: '#ffffff' },
fillPatternBackgroundColor: 'transparent'
@@ -190,7 +191,7 @@ const datasetsPlugin = createDatasetsPlugin({
{
id: 'existing-fields',
label: 'Existing fields',
- // groupLabel: 'Test group',
+ groupLabel: 'Test group',
filter: ['all',['==', ['get', 'sbi'], '106223377'],['==', ['get', 'is_dominant_land_cover'], true]],
tiles: ['https://farming-tiles-702a60f45633.herokuapp.com/field_parcels_with_hedges/{z}/{x}/{y}'],
sourceLayer: 'field_parcels_filtered',
@@ -204,7 +205,8 @@ const datasetsPlugin = createDatasetsPlugin({
fill: 'rgba(21,101,192,0.1)',
symbolDescription: { outdoor: 'blue outline', dark: 'white outline' }
}
- },{
+ },
+ {
id: 'historic-monuments',
label: 'Historic monuments',
geojson: pointData,
@@ -215,6 +217,7 @@ const datasetsPlugin = createDatasetsPlugin({
style: {
symbol: 'square',
symbolGraphic: 'M3 15H1V1h2v2h2V1h2v5h2V4h2v2h2V4h2v11H6V9H3v6z', // Historic monument
+ symbolAnchor: [0.1, 0.1],
// symbolBackgroundColor: { outdoor: '#ca3535', dark: '#ffffff' },
// symbolForegroundColor: { outdoor: '#ffffff', dark: '#0b0c0c' }
},
@@ -224,6 +227,7 @@ const datasetsPlugin = createDatasetsPlugin({
filter: ['in', ['get', 'category'], 'prehistoric'],
showInMenu: true,
style: {
+ symbolAnchor: [0.5, 0.5],
symbolBackgroundColor: '#00897B',
}
},{
@@ -232,6 +236,7 @@ const datasetsPlugin = createDatasetsPlugin({
filter: ['in', ['get', 'category'], 'roman'],
showInMenu: true,
style: {
+ // symbolAnchor: [0.1, 0.1],
symbolBackgroundColor: '#ca3535',
}
},{
@@ -240,13 +245,15 @@ const datasetsPlugin = createDatasetsPlugin({
filter: ['in', ['get', 'category'], 'medieval'],
showInMenu: true,
style: {
+ // symbolAnchor: [0.9, 0.9],
symbolBackgroundColor: '#1565C0',
}
}]
- },{
+ },
+ {
id: 'hedge-control',
label: 'Hedge control',
- // groupLabel: 'Test group',
+ groupLabel: 'Test group',
tiles: ['https://farming-tiles-702a60f45633.herokuapp.com/field_parcels_with_hedges/{z}/{x}/{y}'],
sourceLayer: 'hedge_control',
minZoom: 10,
@@ -261,7 +268,8 @@ const datasetsPlugin = createDatasetsPlugin({
symbolDescription: { outdoor: 'blue outline' },
keySymbolShape: 'line',
}
- }]
+ }
+]
})
const interactiveMap = new InteractiveMap('map', {
@@ -346,18 +354,26 @@ interactiveMap.on('datasets:ready', function () {
// setTimeout(() => datasetsPlugin.setFeatureVisibility(false, [55], { datasetId: 'land-covers', idProperty: null }), 2000)
// setTimeout(() => datasetsPlugin.setFeatureVisibility(true, [55], { datasetId: 'land-covers', idProperty: null }), 4000)
- // setTimeout(() => datasetsPlugin.setStyle(
- // {
- // stroke: { outdoor: '#ff0000', dark: '#ffffff' },
- // fillPattern: 'horizontal-hatch',
- // fillPatternForegroundColor: { outdoor: '#ff0000', dark: '#ffffff' },
- // fillPatternBackgroundColor: 'transparent'
- // },
- // { datasetId: 'land-covers', sublayerId: '130-131' }), 2000)
+ setTimeout(() => datasetsPlugin.setStyle({
+ stroke: { outdoor: '#ff0000', dark: '#ffffff' },
+ fillPattern: 'horizontal-hatch',
+ fillPatternForegroundColor: { outdoor: '#ff0000', dark: '#ffffff' },
+ fillPatternBackgroundColor: 'transparent'
+ }, { datasetId: 'land-covers', sublayerId: '130-131' }), 1000)
+
+ // Hide all landcovers
+ setTimeout(() => datasetsPlugin.setDatasetVisibility(false, { datasetId: 'land-covers' }), 2000)
+ // Specifically hide landcovers-130-131
+ setTimeout(() => datasetsPlugin.setDatasetVisibility(false, { datasetId: 'land-covers', sublayerId: '130-131' }), 3000)
+ // Show landcovers - expect landcovers-130-131 to remain hidden
+ setTimeout(() => datasetsPlugin.setDatasetVisibility(true, { datasetId: 'land-covers' }), 4000)
+ // now reshow show landcovers-130-131
+ setTimeout(() => datasetsPlugin.setDatasetVisibility(true, { datasetId: 'land-covers', sublayerId: '130-131' }), 5000)
+
// setTimeout(() => datasetsPlugin.setDatasetVisibility(false), 1000)
// setTimeout(() => datasetsPlugin.setDatasetVisibility(true), 5000)
// setTimeout(() => datasetsPlugin.setDatasetVisibility(true, { datasetId: 'hedge-control' }), 500)
- // setTimeout(() => datasetsPlugin.setStyle({ stroke: { outdoor: '#ffff00' }, }, { datasetId: 'hedge-control' }), 1000)
+ // setTimeout(() => datasetsPlugin.setStyle({ stroke: { outdoor: '#ffff00' }, }, { datasetId: 'hedge-control' }), 2000)
})
// Ref to the selected features
diff --git a/plugins/beta/datasets/src/DatasetsInit.jsx b/plugins/beta/datasets/src/DatasetsInit.jsx
index 19fcd3e9..4f87329f 100755
--- a/plugins/beta/datasets/src/DatasetsInit.jsx
+++ b/plugins/beta/datasets/src/DatasetsInit.jsx
@@ -73,13 +73,13 @@ export function DatasetsInit ({ pluginConfig, pluginState, appState, mapState, m
initDatasets()
}, [isMapStyleReady, appState.mode])
- useEffect(() => {
- dispatch({ type: 'BUILD_KEY_GROUPS', payload: null })
- }, [pluginState.datasets])
-
const datasetsRef = useRef(pluginState.mappedDatasets)
+ const orderedDatasetsRef = useRef(pluginState.orderedDatasets)
datasetsRef.current = pluginState.mappedDatasets
- useEffect(() => datasetRegistry.attach(datasetsRef.current), [pluginState.mappedDatasets])
+ orderedDatasetsRef.current = pluginState.orderedDatasets
+ useEffect(() => {
+ datasetRegistry.attach(datasetsRef.current, pluginState.orderedDatasets)
+ }, [pluginState.mappedDatasets, pluginState.orderedDatasets])
useLayerAdapterActions('setStyle', dispatch, pluginState, [pluginState.layerAdapterActions.setStyle])
useLayerAdapterActions('setDatasetVisibility', dispatch, pluginState, [pluginState.layerAdapterActions.setDatasetVisibility])
diff --git a/plugins/beta/datasets/src/adapters/maplibre/datasets/mapLibreDataset.js b/plugins/beta/datasets/src/adapters/maplibre/datasets/mapLibreDataset.js
index 30e8532b..5a4ff2c1 100644
--- a/plugins/beta/datasets/src/adapters/maplibre/datasets/mapLibreDataset.js
+++ b/plugins/beta/datasets/src/adapters/maplibre/datasets/mapLibreDataset.js
@@ -89,7 +89,7 @@ export class MapLibreDataset extends Dataset {
minzoom: this.minZoom,
maxzoom: this.maxZoom,
layout: {
- visibility: this.visibility === 'hidden' ? 'none' : 'visible',
+ visibility: this.visibility,
'icon-image': imageId,
'icon-anchor': anchorToMaplibre(anchor || symbolDef?.anchor || [0.5, 0.5]),
'icon-allow-overlap': true
@@ -106,7 +106,7 @@ export class MapLibreDataset extends Dataset {
'source-layer': this.sourceLayer,
minzoom: this.minZoom,
maxzoom: this.maxZoom,
- layout: { visibility: this.visibility === 'hidden' ? 'none' : 'visible' },
+ layout: { visibility: this.visibility },
paint,
...(this.filter ? { filter: this.filter } : {})
}
@@ -120,7 +120,7 @@ export class MapLibreDataset extends Dataset {
'source-layer': this.sourceLayer,
minzoom: this.minZoom,
maxzoom: this.maxZoom,
- layout: { visibility: this.visibility === 'hidden' ? 'none' : 'visible' },
+ layout: { visibility: this.visibility },
paint,
...(this.filter ? { filter: this.filter } : {})
}
diff --git a/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js b/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js
index 275bb1b5..e59d88c0 100644
--- a/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js
+++ b/plugins/beta/datasets/src/adapters/maplibre/maplibreLayerAdapter.js
@@ -356,12 +356,11 @@ export default class MaplibreLayerAdapter {
const { sublayerIds } = registryDataset
sublayerIds.forEach(sublayerId => { this.setDatasetVisibility(sublayerId) })
} else {
- const { visible } = registryDataset
+ const { visibility } = registryDataset
const datasetId = registryDataset.id
style.layers.filter(layer =>
layer.id === datasetId || layer.id.startsWith(`${datasetId}-`)
).forEach(layer => {
- const visibility = visible ? 'visible' : 'none'
this._map.setLayoutProperty(layer.id, 'visibility', visibility)
})
}
diff --git a/plugins/beta/datasets/src/components/KeySvg.jsx b/plugins/beta/datasets/src/components/KeySvg.jsx
deleted file mode 100644
index 3a46fe7f..00000000
--- a/plugins/beta/datasets/src/components/KeySvg.jsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import { hasSymbol } from '../../../../../src/utils/symbolUtils.js'
-import { hasPattern } from '../../../../../src/utils/patternUtils.js'
-import { KeySvgPattern } from './KeySvgPattern.jsx'
-import { KeySvgSymbol } from './KeySvgSymbol.jsx'
-import { KeySvgLine } from './KeySvgLine.jsx'
-import { KeySvgRect } from './KeySvgRect.jsx'
-
-export const KeySvg = (props) => {
- const { symbolRegistry } = props
- const symbolDef = hasSymbol(props) && symbolRegistry.getSymbolDef(props)
- if (symbolDef) {
- return
- }
-
- if (hasPattern(props)) {
- return
- }
-
- if (props.keySymbolShape === 'line') {
- return
- }
-
- return
-}
diff --git a/plugins/beta/datasets/src/components/KeySvgLine.jsx b/plugins/beta/datasets/src/components/KeySvgLine.jsx
deleted file mode 100644
index d1015383..00000000
--- a/plugins/beta/datasets/src/components/KeySvgLine.jsx
+++ /dev/null
@@ -1,19 +0,0 @@
-import { svgProps, SVG_SIZE, SVG_CENTER } from './svgProperties.js'
-import { getValueForStyle } from '../../../../../src/utils/getValueForStyle'
-
-export const KeySvgLine = (props) => {
- const { mapStyle } = props
- return (
-
- )
-}
diff --git a/plugins/beta/datasets/src/components/KeySvgRect.jsx b/plugins/beta/datasets/src/components/KeySvgRect.jsx
deleted file mode 100644
index 0207d561..00000000
--- a/plugins/beta/datasets/src/components/KeySvgRect.jsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import { getValueForStyle } from '../../../../../src/utils/getValueForStyle'
-import { svgProps, SVG_SIZE } from './svgProperties.js'
-
-export const KeySvgRect = (props) => {
- const { mapStyle } = props
- return (
-
- )
-}
diff --git a/plugins/beta/datasets/src/components/EmptyKey.jsx b/plugins/beta/datasets/src/components/key/EmptyKey.jsx
similarity index 100%
rename from plugins/beta/datasets/src/components/EmptyKey.jsx
rename to plugins/beta/datasets/src/components/key/EmptyKey.jsx
diff --git a/plugins/beta/datasets/src/components/EmptyKey.test.jsx b/plugins/beta/datasets/src/components/key/EmptyKey.test.jsx
similarity index 100%
rename from plugins/beta/datasets/src/components/EmptyKey.test.jsx
rename to plugins/beta/datasets/src/components/key/EmptyKey.test.jsx
diff --git a/plugins/beta/datasets/src/components/key/KeyGroupItem.jsx b/plugins/beta/datasets/src/components/key/KeyGroupItem.jsx
new file mode 100644
index 00000000..ac8cc0b0
--- /dev/null
+++ b/plugins/beta/datasets/src/components/key/KeyGroupItem.jsx
@@ -0,0 +1,18 @@
+import { KeyItem } from './KeyItem.jsx'
+
+export const KeyGroupItem = ({ headingId, label, datasets, symbolRegistry, patternRegistry, mapStyle }) => {
+ return (
+
+ {label}
+ {datasets.map(dataset =>
+
+ )}
+
+ )
+}
diff --git a/plugins/beta/datasets/src/components/key/KeyItem.jsx b/plugins/beta/datasets/src/components/key/KeyItem.jsx
new file mode 100644
index 00000000..f931a7dc
--- /dev/null
+++ b/plugins/beta/datasets/src/components/key/KeyItem.jsx
@@ -0,0 +1,20 @@
+import { getValueForStyle } from '../../../../../../src/utils/getValueForStyle.js'
+import { KeySvg } from './KeySvg.jsx'
+
+export const KeyItem = ({ registryDataset, symbolRegistry, patternRegistry, mapStyle }) => {
+ return (
+
+ -
+
+
+ -
+ {registryDataset.label}
+ {registryDataset.symbolDescription && (
+
+ ({getValueForStyle(registryDataset.symbolDescription, mapStyle.id)})
+
+ )}
+
+
+ )
+}
diff --git a/plugins/beta/datasets/src/components/key/KeySvg.jsx b/plugins/beta/datasets/src/components/key/KeySvg.jsx
new file mode 100644
index 00000000..264369ac
--- /dev/null
+++ b/plugins/beta/datasets/src/components/key/KeySvg.jsx
@@ -0,0 +1,22 @@
+import { KeySvgPattern } from './KeySvgPattern.jsx'
+import { KeySvgSymbol } from './KeySvgSymbol.jsx'
+import { KeySvgLine } from './KeySvgLine.jsx'
+import { KeySvgRect } from './KeySvgRect.jsx'
+
+export const KeySvg = ({ symbolRegistry, registryDataset, mapStyle, patternRegistry }) => {
+ const { hasSymbol, hasPattern, style } = registryDataset
+ const symbolDef = hasSymbol && symbolRegistry.getSymbolDef(style)
+ if (symbolDef) {
+ return
+ }
+
+ if (hasPattern) {
+ return
+ }
+
+ if (style.keySymbolShape === 'line') {
+ return
+ }
+
+ return
+}
diff --git a/plugins/beta/datasets/src/components/KeySvg.test.jsx b/plugins/beta/datasets/src/components/key/KeySvg.test.jsx
similarity index 63%
rename from plugins/beta/datasets/src/components/KeySvg.test.jsx
rename to plugins/beta/datasets/src/components/key/KeySvg.test.jsx
index 84b02b7a..494e9c4f 100644
--- a/plugins/beta/datasets/src/components/KeySvg.test.jsx
+++ b/plugins/beta/datasets/src/components/key/KeySvg.test.jsx
@@ -1,21 +1,11 @@
import { render } from '@testing-library/react'
import { KeySvg } from './KeySvg'
-import { hasSymbol } from '../../../../../src/utils/symbolUtils.js'
-import { hasPattern } from '../../../../../src/utils/patternUtils.js'
-import { symbolRegistry } from '../../../../../src/services/symbolRegistry.js'
-// import { patternRegistry } from '../../../../../src/services/patternRegistry.js'
+import { symbolRegistry } from '../../../../../../src/services/symbolRegistry.js'
+import { patternRegistry } from '../../../../../../src/services/patternRegistry.js'
const getSymbolDef = jest.spyOn(symbolRegistry, 'getSymbolDef')
-jest.mock('../../../../../src/utils/symbolUtils.js', () => ({
- hasSymbol: jest.fn(() => false)
-}))
-
-jest.mock('../../../../../src/utils/patternUtils.js', () => ({
- hasPattern: jest.fn(() => false)
-}))
-
jest.mock('./KeySvgPattern.jsx', () => ({
KeySvgPattern: () =>
}))
@@ -32,33 +22,37 @@ jest.mock('./KeySvgRect.jsx', () => ({
KeySvgRect: () =>
}))
+const baseRegistryDataset = {
+ hasSymbol: false,
+ hasPattern: false,
+ style: {}
+}
+
const baseProps = {
symbolRegistry,
- mapStyle: { id: 'default' }
+ patternRegistry,
+ mapStyle: { id: 'default' },
+ registryDataset: baseRegistryDataset
}
beforeEach(() => {
- hasSymbol.mockReturnValue(false)
getSymbolDef.mockReturnValue(null)
- hasPattern.mockReturnValue(false)
})
describe('KeySvg', () => {
it('renders KeySvgSymbol when a symbolDef is resolved', () => {
- hasSymbol.mockReturnValue(true)
getSymbolDef.mockReturnValue({ id: 'marker' })
- const { getByTestId } = render()
+ const { getByTestId } = render()
expect(getByTestId('key-svg-symbol')).toBeTruthy()
})
it('renders KeySvgPattern when hasPattern is true and no symbol', () => {
- hasPattern.mockReturnValue(true)
- const { getByTestId } = render()
+ const { getByTestId } = render()
expect(getByTestId('key-svg-pattern')).toBeTruthy()
})
it('renders KeySvgLine when keySymbolShape is line and no symbol or pattern', () => {
- const { getByTestId } = render()
+ const { getByTestId } = render()
expect(getByTestId('key-svg-line')).toBeTruthy()
})
@@ -68,30 +62,26 @@ describe('KeySvg', () => {
})
it('prefers symbol over pattern when both are present', () => {
- hasSymbol.mockReturnValue(true)
getSymbolDef.mockReturnValue({ id: 'marker' })
- hasPattern.mockReturnValue(true)
- const { getByTestId, queryByTestId } = render()
+ const { getByTestId, queryByTestId } = render()
expect(getByTestId('key-svg-symbol')).toBeTruthy()
expect(queryByTestId('key-svg-pattern')).toBeNull()
})
it('prefers pattern over line when both conditions are met', () => {
- hasPattern.mockReturnValue(true)
- const { getByTestId, queryByTestId } = render()
+ const { getByTestId, queryByTestId } = render()
expect(getByTestId('key-svg-pattern')).toBeTruthy()
expect(queryByTestId('key-svg-line')).toBeNull()
})
it('renders KeySvgRect when keySymbolShape is not line and no symbol or pattern', () => {
- const { getByTestId } = render()
+ const { getByTestId } = render()
expect(getByTestId('key-svg-rect')).toBeTruthy()
})
it('does not render KeySvgSymbol when hasSymbol is true but getSymbolDef returns null', () => {
- hasSymbol.mockReturnValue(true)
getSymbolDef.mockReturnValue(null)
- const { getByTestId } = render()
+ const { getByTestId } = render()
expect(getByTestId('key-svg-rect')).toBeTruthy()
})
})
diff --git a/plugins/beta/datasets/src/components/key/KeySvgLine.jsx b/plugins/beta/datasets/src/components/key/KeySvgLine.jsx
new file mode 100644
index 00000000..5d156550
--- /dev/null
+++ b/plugins/beta/datasets/src/components/key/KeySvgLine.jsx
@@ -0,0 +1,19 @@
+import { svgProps, SVG_SIZE, SVG_CENTER } from '../svgProperties.js'
+import { getValueForStyle } from '../../../../../../src/utils/getValueForStyle.js'
+
+export const KeySvgLine = ({ mapStyle, registryDataset }) => {
+ const { style } = registryDataset
+ return (
+
+ )
+}
diff --git a/plugins/beta/datasets/src/components/KeySvgLine.test.jsx b/plugins/beta/datasets/src/components/key/KeySvgLine.test.jsx
similarity index 89%
rename from plugins/beta/datasets/src/components/KeySvgLine.test.jsx
rename to plugins/beta/datasets/src/components/key/KeySvgLine.test.jsx
index 26711623..866aa330 100644
--- a/plugins/beta/datasets/src/components/KeySvgLine.test.jsx
+++ b/plugins/beta/datasets/src/components/key/KeySvgLine.test.jsx
@@ -1,15 +1,19 @@
import { render } from '@testing-library/react'
import { KeySvgLine } from './KeySvgLine'
-import { getValueForStyle } from '../../../../../src/utils/getValueForStyle'
+import { getValueForStyle } from '../../../../../../src/utils/getValueForStyle'
-jest.mock('../../../../../src/utils/getValueForStyle', () => ({
+jest.mock('../../../../../../src/utils/getValueForStyle', () => ({
getValueForStyle: jest.fn((value) => value)
}))
const defaultProps = {
- stroke: '#ff0000',
- strokeWidth: 2,
+ registryDataset: {
+ style: {
+ stroke: '#ff0000',
+ strokeWidth: 2
+ }
+ },
mapStyle: { id: 'default' }
}
diff --git a/plugins/beta/datasets/src/components/KeySvgPattern.jsx b/plugins/beta/datasets/src/components/key/KeySvgPattern.jsx
similarity index 54%
rename from plugins/beta/datasets/src/components/KeySvgPattern.jsx
rename to plugins/beta/datasets/src/components/key/KeySvgPattern.jsx
index 9fdb4d93..cd5c2286 100644
--- a/plugins/beta/datasets/src/components/KeySvgPattern.jsx
+++ b/plugins/beta/datasets/src/components/key/KeySvgPattern.jsx
@@ -1,10 +1,9 @@
-import { svgProps } from './svgProperties.js'
+import { svgProps } from '../svgProperties.js'
const PATTERN_INSET = 2
-export const KeySvgPattern = (props) => {
- const { patternRegistry, mapStyle } = props
-
- const paths = patternRegistry.getKeyPatternPaths(props, mapStyle.id)
+export const KeySvgPattern = ({ patternRegistry, registryDataset, mapStyle }) => {
+ const { style } = registryDataset
+ const paths = patternRegistry.getKeyPatternPaths(style, mapStyle.id)
return (