Skip to content

Commit

Permalink
feat: implement rainfall and vegetation maps (#41)
Browse files Browse the repository at this point in the history
* feat: implement rainfall and vegetation maps

* feat: add separate countries-inactive layer

* feat: uncomment CORS-affected layers
  • Loading branch information
jschoedl authored Nov 19, 2024
1 parent 4d41f97 commit d5d2aad
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 31 deletions.
7 changes: 4 additions & 3 deletions src/components/Map/VectorTileLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@ export default function VectorTileLayer({ countries, disputedAreas }: MapProps)
);
MapOperations.setMapInteractionFunctionality(baseMap);
MapOperations.synchronizeLeafletMapbox(baseMap, mapContainer, context);
/* To add when CORS issue is solved
MapOperations.addFCSFunctionality(baseMap, selectedMapType);
*/
// The following layers currently don't work due to CORS issues.
MapOperations.addRainfallLayer(baseMap, selectedMapType);
MapOperations.addVegetationLayer(baseMap, selectedMapType);
MapOperations.addFCSLayer(baseMap, selectedMapType);

return () => {
baseMap.remove();
Expand Down
28 changes: 28 additions & 0 deletions src/domain/constant/legend/mapLegendData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,34 @@ export function mapLegendData(
'Updated: Daily (low and lower-middle income countries), Annually (upper-middle and high income countries).',
});
break;
case GlobalInsight.RAINFALL:
legendData.push({
title: 'Rainfall',
startColor: 'rainfallLow',
middleColor: 'rainfallNormal',
endColor: 'rainfallHigh',
startLabel: '<40%',
endLabel: '>180%',
tooltipInfo:
'This layer shows the cumulative rainfall in the previous month compared to the 20-year average. ' +
'Variations between 90% and 110% are considered as having an inconsequential impact for crops or pasture and these are represented in white. ' +
'Otherwise, brown shades indicate below-average rainfall and blue shades indicate above-average seasonal rainfall.',
});
break;
case GlobalInsight.VEGETATION:
legendData.push({
title: 'Vegetation',
startColor: 'vegetationLow',
middleColor: 'vegetationNormal',
endColor: 'vegetationHigh',
startLabel: '<50%',
endLabel: '>150%',
tooltipInfo:
'The Normalized Difference Vegetation Index (NDVI) shows the recent vegetation development compared to the average. ' +
'Green shades show areas where vegetation cover is above average, whilst orange and brown shades identify areas where vegetation cover is below normal. ' +
'Values between 90% and 110% are considered as being within the range of normal variability.',
});
break;
default:
}

Expand Down
4 changes: 2 additions & 2 deletions src/domain/entities/map/MapColorsType.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export interface MapColorsType {
activeCountries: string;
inactiveCountries: string;
countriesBase: string;
inactiveCountriesOverlay: string;
ocean: string;
outline: string;
roads: string;
Expand Down
98 changes: 76 additions & 22 deletions src/operations/map/MapOperations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,36 +32,42 @@ export class MapOperations {
mapboxStreets: {
type: 'vector',
url: 'mapbox://mapbox.mapbox-streets-v8',
bounds: [-180, -60, 180, 90],
},
},
layers: [
{
id: 'ocean',
type: 'background',
paint: {
'background-color': mapColors.ocean,
},
paint: { 'background-color': mapColors.ocean },
},
{
id: 'countries-base',
type: 'fill',
source: 'countries',
paint: { 'fill-color': mapColors.countriesBase },
},
// additional layers (FCS, vegetation etc.) are being placed here
{
id: 'countries-inactive',
type: 'fill',
source: 'countries',
paint: { 'fill-color': mapColors.inactiveCountriesOverlay, 'fill-opacity': 0.5 },
filter: ['==', ['coalesce', ['get', 'interactive'], false], false],
},
{
id: 'country-fills',
id: 'countries-hover',
type: 'fill',
source: 'countries',
layout: {},
paint: {
'fill-color': [
'case',
['boolean', ['coalesce', ['get', 'interactive'], false]],
mapColors.activeCountries,
mapColors.inactiveCountries,
],
'fill-opacity': ['case', ['boolean', ['feature-state', 'hover'], false], 0.7, 1],
'fill-color': mapColors.outline,
'fill-opacity': ['case', ['boolean', ['feature-state', 'hover'], false], 0.3, 0],
},
},
{
id: 'country-borders',
type: 'line',
source: 'countries',
layout: {},
paint: {
'line-color': mapColors.outline,
'line-width': 0.7,
Expand Down Expand Up @@ -89,7 +95,7 @@ export class MapOperations {
static setMapInteractionFunctionality(baseMap: mapboxgl.Map): void {
let hoveredPolygonId: string | number | undefined;

baseMap.on('mousemove', 'country-fills', (e) => {
baseMap.on('mousemove', 'countries-hover', (e) => {
if (e.features && e.features.length > 0 && (e.features[0] as unknown as CountryMapData).properties.interactive) {
if (hoveredPolygonId) {
baseMap.setFeatureState({ source: 'countries', id: hoveredPolygonId }, { hover: false });
Expand All @@ -101,7 +107,7 @@ export class MapOperations {
}
});

baseMap.on('mouseleave', 'country-fills', () => {
baseMap.on('mouseleave', 'countries-hover', () => {
if (hoveredPolygonId) {
baseMap.setFeatureState({ source: 'countries', id: hoveredPolygonId }, { hover: false });
}
Expand All @@ -117,7 +123,7 @@ export class MapOperations {
isDragging = true;
});

baseMap.on('mouseup', 'country-fills', (e) => {
baseMap.on('mouseup', 'countries-hover', (e) => {
if (!isDragging && e.features && (e.features[0] as unknown as CountryMapData).properties.interactive) {
alert(`You clicked on ${(e.features[0] as unknown as CountryMapData).properties.adm0_name}`);

Check warning on line 128 in src/operations/map/MapOperations.ts

View workflow job for this annotation

GitHub Actions / lint-and-format

Unexpected alert
}
Expand Down Expand Up @@ -186,7 +192,7 @@ export class MapOperations {
});
}

static addFCSFunctionality(baseMap: mapboxgl.Map, selectedMapType: GlobalInsight) {
static addFCSLayer(baseMap: mapboxgl.Map, selectedMapType: GlobalInsight) {
baseMap.on('load', () => {
baseMap.addSource('fcsRaster', {
type: 'raster',
Expand All @@ -195,13 +201,61 @@ export class MapOperations {
scheme: 'tms',
});

baseMap.addLayer({
id: 'fcsLayer',
baseMap.addLayer(
{
id: 'fcsLayer',
type: 'raster',
source: 'fcsRaster',
layout: { visibility: selectedMapType === GlobalInsight.FOOD ? 'visible' : 'none' },
},
'countries-inactive'
);
});
}

static addRainfallLayer(baseMap: mapboxgl.Map, selectedMapType: GlobalInsight) {
baseMap.on('load', () => {
baseMap.addSource('rainfallRaster', {
type: 'raster',
source: 'fcsRaster',
layout: { visibility: selectedMapType === GlobalInsight.FOOD ? 'visible' : 'none' },
paint: {},
tiles: [`https://dev.api.earthobservation.vam.wfp.org/tiles/latest/r3q_dekad/{z}/{x}/{y}.png`],
tileSize: 256,
scheme: 'xyz',
maxzoom: 7,
bounds: [-180, -49, 180, 49],
});

baseMap.addLayer(
{
id: 'rainfallLayer',
type: 'raster',
source: 'rainfallRaster',
layout: { visibility: selectedMapType === GlobalInsight.RAINFALL ? 'visible' : 'none' },
},
'countries-inactive'
);
});
}

static addVegetationLayer(baseMap: mapboxgl.Map, selectedMapType: GlobalInsight) {
baseMap.on('load', () => {
baseMap.addSource('vegetationRaster', {
type: 'raster',
tiles: [`https://dev.api.earthobservation.vam.wfp.org/tiles/latest/viq_dekad/{z}/{x}/{y}.png`],
tileSize: 256,
scheme: 'xyz',
maxzoom: 7,
bounds: [-180, -60, 180, 80],
});

baseMap.addLayer(
{
id: 'vegetationLayer',
type: 'raster',
source: 'vegetationRaster',
layout: { visibility: selectedMapType === GlobalInsight.VEGETATION ? 'visible' : 'none' },
},
'countries-inactive'
);
});
}
}
4 changes: 2 additions & 2 deletions src/styles/MapColors.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { MapColorsType } from '@/domain/entities/map/MapColorsType.ts';

export const getColors = (isDark: boolean): MapColorsType => ({
activeCountries: isDark ? '#0e6397' : '#fefeff',
inactiveCountries: isDark ? '#5a819b' : '#e8e8e8',
countriesBase: isDark ? '#0e6397' : '#fefeff',
inactiveCountriesOverlay: isDark ? '#a69f9f' : '#d2d1d1',
ocean: isDark ? '#111111' : '#91cccb',
outline: isDark ? '#0e2a3a' : '#306f96',
roads: isDark ? '#404040' : '#808080',
Expand Down
10 changes: 8 additions & 2 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,12 @@ const config = {
fcsGreen: '#345d34',
fcsOrange: '#ea6a2c',
fcsRed: '#fa190e',
rainfallLow: '#b99260',
rainfallNormal: '#fff',
rainfallHigh: '#4295d3',
vegetationLow: '#b99260',
vegetationNormal: '#fff',
vegetationHigh: '#b1dbb5',
},
},
dark: {
Expand Down Expand Up @@ -175,6 +181,6 @@ const config = {
},
}),
],
}
};

module.exports = config
module.exports = config

0 comments on commit d5d2aad

Please sign in to comment.