diff --git a/src/controls/controlsLocale.js b/src/controls/controlsLocale.js index 39b6c6ac..8555c1e8 100644 --- a/src/controls/controlsLocale.js +++ b/src/controls/controlsLocale.js @@ -1,7 +1,7 @@ const controlsLocale = { 'SearchControl.SearchForPlace': 'Search for place or address', 'FitBoundsControl.ZoomToContent': 'Zoom to content', - 'HoverLabel.NoData': 'No data', + 'Label.NoData': 'No data', 'MeasureControl.MeasureDistancesAndAreas': 'Measure distances and areas', 'MeasureControl.ClickStartMeasurement': 'Click where you want to start the measurement', diff --git a/src/layers/Layer.js b/src/layers/Layer.js index 490097c9..3af6fd43 100644 --- a/src/layers/Layer.js +++ b/src/layers/Layer.js @@ -1,9 +1,9 @@ -import { v4 as uuid } from 'uuid' import bbox from '@turf/bbox' import { Evented } from 'maplibre-gl' -import { addImages } from '../utils/images' -import { featureCollection } from '../utils/geometry' +import { v4 as uuid } from 'uuid' import { bufferSource } from '../utils/buffers' +import { featureCollection } from '../utils/geometry' +import { addImages } from '../utils/images' import { labelSource } from '../utils/labels' import { setLayersOpacity } from '../utils/opacity' @@ -346,8 +346,8 @@ class Layer extends Evented { const content = (hoverLabel || label).replace( /\{ *([\w_-]+) *\}/g, (str, key) => - properties[key] || - (key === 'value' ? this.locale('HoverLabel.NoData') : '') + properties[key] ?? + (key === 'value' ? this.locale('Label.NoData') : '') ) this._map.showLabel(content, evt.lngLat) diff --git a/src/utils/__tests__/labels.spec.js b/src/utils/__tests__/labels.spec.js index 7a6edb5b..26ebcb80 100644 --- a/src/utils/__tests__/labels.spec.js +++ b/src/utils/__tests__/labels.spec.js @@ -1,10 +1,133 @@ -import { labelLayer } from '../labels' +import { labelSource, labelLayer } from '../labels' import defaults from '../style' const id = 'abc' const opacity = 0.5 +const fontSize = 10 +const labelNoData = 'No Data' +const isBoundary = false +const geometryPoint = { + type: 'Point', + coordinates: [0, 0], +} +const features = [ + { + // Test a polygon + geometry: { + type: 'Polygon', + coordinates: [ + [ + [0, 0], + [1, 0], + [1, 1], + [0, 1], + [0, 0], + ], + ], + }, + properties: { + name: 'Feature1', + radius: 1, + value: 1, + }, + }, + { + // Test a point with a valid value which is not 0 + geometry: geometryPoint, + properties: { + name: 'Feature2', + radius: 1, + value: 1, + }, + }, + { + // Test a point with a valid value which is 0 + geometry: geometryPoint, + properties: { + name: 'Feature3', + radius: 1, + value: 0, + }, + }, + { + // Test a point with no value + geometry: geometryPoint, + properties: { + name: 'Feature4', + radius: 1, + }, + }, +] +const generateLabelSourceItem = (coordinates, name, anchor, offset, value) => { + return { + type: 'Feature', + geometry: { + type: 'Point', + coordinates, + }, + properties: { + name, + anchor, + offset, + color: '#333', + value, + }, + } +} describe('labels', () => { + it('Handles different label sources scenario', () => { + const expected = { + type: 'geojson', + data: { + type: 'FeatureCollection', + features: [ + // Label for a polygon + generateLabelSourceItem( + [0.5, 0.5], + 'Feature1', + 'center', + [0, 0], + 1 + ), + // Label for a point with a valid value which is not 0 + generateLabelSourceItem( + [0, 0], + 'Feature2', + 'top', + [0, 0.5], + 1 + ), + // Label for a point with a valid value which is 0 + generateLabelSourceItem( + [0, 0], + 'Feature3', + 'top', + [0, 0.5], + 0 + ), + // Label for a point with no value + generateLabelSourceItem( + [0, 0], + 'Feature4', + 'top', + [0, 0.5], + 'No Data' + ), + ], + }, + } + const received = labelSource( + features, + { fontSize, labelNoData }, + isBoundary + ) + + expect(JSON.stringify(received, null, 2)).toEqual( + JSON.stringify(expected, null, 2) + ) + }) + it('Should set opacity for for label layer', () => { expect(labelLayer({ id, opacity }).paint['text-opacity']).toBe(opacity) }) diff --git a/src/utils/labels.js b/src/utils/labels.js index e2be9750..11f32644 100644 --- a/src/utils/labels.js +++ b/src/utils/labels.js @@ -15,7 +15,11 @@ const fonts = { const getOffsetEms = (type, radius = 5, fontSize = 11) => type === 'Point' ? radius / parseInt(fontSize, 10) + 0.4 : 0 -export const labelSource = (features, { fontSize }, isBoundary) => ({ +export const labelSource = ( + features, + { fontSize, labelNoData = '' }, + isBoundary +) => ({ type: 'geojson', data: featureCollection( features.map(({ geometry, properties }) => ({ @@ -32,7 +36,7 @@ export const labelSource = (features, { fontSize }, isBoundary) => ({ getOffsetEms(geometry.type, properties.radius, fontSize), ], color: isBoundary ? properties.color : '#333', - value: properties.value, + value: properties.value ?? labelNoData, }, })) ),