Skip to content

Commit

Permalink
Merge pull request #1605 from IFRCGo/fix/map-filtering-base-map
Browse files Browse the repository at this point in the history
Use GlobalMap in-place of BaseMap
  • Loading branch information
frozenhelium authored Dec 26, 2024
2 parents 9f63f03 + cbb58f5 commit bb9a501
Show file tree
Hide file tree
Showing 17 changed files with 174 additions and 409 deletions.
2 changes: 1 addition & 1 deletion app/src/components/domain/ActiveOperationMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ function ActiveOperationMap(props: Props) {
)}
>
<GlobalMap
onClick={handleCountryClick}
onAdminZeroFillClick={handleCountryClick}
>
<MapContainerWithDisclaimer
className={styles.mapContainer}
Expand Down
114 changes: 39 additions & 75 deletions app/src/components/domain/BaseMap/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { useMemo } from 'react';
import { ErrorBoundary } from '@sentry/react';
import {
isDefined,
isFalsyString,
isNotDefined,
} from '@togglecorp/fujs';
useContext,
useMemo,
} from 'react';
import { LanguageContext } from '@ifrc-go/ui/contexts';
import { ErrorBoundary } from '@sentry/react';
import Map, {
MapLayer,
MapSource,
} from '@togglecorp/re-map';
import { type SymbolLayer } from 'mapbox-gl';

import useCountry from '#hooks/domain/useCountry';
import {
defaultMapOptions,
defaultMapStyle,
Expand All @@ -28,39 +26,8 @@ type overrides = 'mapStyle' | 'mapOptions' | 'navControlShown' | 'navControlPosi
export type Props = Omit<MapProps, overrides> & {
baseLayers?: React.ReactNode;
withDisclaimer?: boolean;
// NOTE: Labels with be added from the country information instead of the
// mapbox layers
withoutLabel?: boolean;
} & Partial<Pick<MapProps, overrides>>;

const sourceOptions: mapboxgl.GeoJSONSourceRaw = {
type: 'geojson',
};

const adminLabelOverrideOptions: Omit<SymbolLayer, 'id'> = {
type: 'symbol',
layout: {
'text-field': ['get', 'name'],
'text-font': ['Poppins Regular', 'Arial Unicode MS Regular'],
'text-letter-spacing': 0.15,
'text-line-height': 1.2,
'text-max-width': 8,
'text-justify': 'center',
'text-anchor': 'top',
'text-padding': 2,
'text-size': [
'interpolate', ['linear', 1], ['zoom'],
0, 6,
6, 16,
],
},
paint: {
'text-color': '#000000',
'text-halo-color': '#555555',
'text-halo-width': 0.2,
},
};

function BaseMap(props: Props) {
const {
baseLayers,
Expand All @@ -71,36 +38,33 @@ function BaseMap(props: Props) {
navControlOptions,
scaleControlShown,
children,
withoutLabel = false,
...otherProps
} = props;

const countries = useCountry();
const { currentLanguage } = useContext(LanguageContext);

// FIXME: We should check for special cases like ICRC, IFRC, etc.
const countryCentroidGeoJson = useMemo(
(): GeoJSON.FeatureCollection<GeoJSON.Geometry> => ({
type: 'FeatureCollection' as const,
features: countries
?.map((country) => {
if (isFalsyString(country.name) || isNotDefined(country.centroid)) {
return undefined;
}
const adminLabelLayerOptions : Omit<SymbolLayer, 'id'> = useMemo(
() => {
// ar, es, fr
let label: string;
if (currentLanguage === 'es') {
label = 'name_es';
} else if (currentLanguage === 'ar') {
label = 'name_ar';
} else if (currentLanguage === 'fr') {
label = 'name_fr';
} else {
label = 'name';
}

return {
type: 'Feature' as const,
geometry: country.centroid as {
type: 'Point',
coordinates: [number, number],
},
properties: {
id: country.id,
name: country.name,
},
};
}).filter(isDefined) ?? [],
}),
[countries],
return {
type: 'symbol',
layout: {
'text-field': ['get', label],
},
};
},
[currentLanguage],
);

return (
Expand All @@ -118,20 +82,20 @@ function BaseMap(props: Props) {
sourceKey="composite"
managed={false}
>
<MapLayer
layerKey="admin-0-label"
layerOptions={adminLabelLayerOptions}
/>
<MapLayer
layerKey="admin-0-label-non-independent"
layerOptions={adminLabelLayerOptions}
/>
<MapLayer
layerKey="admin-0-label-priority"
layerOptions={adminLabelLayerOptions}
/>
{baseLayers}
</MapSource>
{!withoutLabel && (
<MapSource
sourceKey="override-labels"
sourceOptions={sourceOptions}
geoJson={countryCentroidGeoJson}
>
<MapLayer
layerKey="symbol-label"
layerOptions={adminLabelOverrideOptions}
/>
</MapSource>
)}
{children}
</Map>
);
Expand Down
84 changes: 13 additions & 71 deletions app/src/components/domain/GlobalMap/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import {
useContext,
useMemo,
useState,
} from 'react';
import { LanguageContext } from '@ifrc-go/ui/contexts';
import { MapLayer } from '@togglecorp/re-map';
import {
type Expression,
type FillLayer,
type FillPaint,
type LineLayer,
type LngLatLike,
type MapboxGeoJSONFeature,
type SymbolLayer,
} from 'mapbox-gl';

import BaseMap, { type Props as BaseMapProps } from '#components/domain/BaseMap';
Expand Down Expand Up @@ -62,19 +58,23 @@ const adminZeroHighlightPaint: FillPaint = {
],
};

interface Props extends Omit<BaseMapProps, 'baseLayers'> {
onHover?: (hoveredFeatureProperties: AdminZeroFeatureProperties | undefined) => void;
onClick?: (
interface Props extends BaseMapProps {
adminZeroFillPaint?: mapboxgl.FillPaint,
onAdminZeroFillHover?: (
hoveredFeatureProperties: AdminZeroFeatureProperties | undefined
) => void;
onAdminZeroFillClick?: (
clickedFeatureProperties: AdminZeroFeatureProperties,
lngLat: LngLatLike,
) => void;
activeCountryIso3?: string | undefined | null;
}

function GlobalMap(props: Props) {
const {
onHover,
onClick,
onAdminZeroFillHover: onHover,
onAdminZeroFillClick: onClick,
adminZeroFillPaint,
baseLayers,
...baseMapProps
} = props;

Expand Down Expand Up @@ -146,52 +146,15 @@ function GlobalMap(props: Props) {
visibility: 'visible',
'fill-sort-key': fillSortKey,
},
paint: adminZeroFillPaint,
}),
[fillSortKey],
);

const adminZeroLineLayerOptions = useMemo<Omit<LineLayer, 'id'>>(
() => ({
type: 'line',
layout: {
visibility: 'visible',
},
}),
[],
);

const { currentLanguage } = useContext(LanguageContext);

const adminLabelLayerOptions : Omit<SymbolLayer, 'id'> = useMemo(
() => {
// ar, es, fr
let label: string;
if (currentLanguage === 'es') {
label = 'name_es';
} else if (currentLanguage === 'ar') {
label = 'name_ar';
} else if (currentLanguage === 'fr') {
label = 'name_fr';
} else {
label = 'name';
}

return {
type: 'symbol',
layout: {
'text-field': ['get', label],
visibility: 'visible',
},
};
},
[currentLanguage],
[fillSortKey, adminZeroFillPaint],
);

return (
<BaseMap
// eslint-disable-next-line react/jsx-props-no-spreading
{...baseMapProps}
withoutLabel
baseLayers={(
<>
<MapLayer
Expand All @@ -200,35 +163,14 @@ function GlobalMap(props: Props) {
onMouseEnter={handleFeatureMouseEnter}
onMouseLeave={handleFeatureMouseLeave}
/>
<MapLayer
layerKey="admin-0-label"
layerOptions={adminLabelLayerOptions}
/>
<MapLayer
layerKey="admin-0-label-non-independent"
layerOptions={adminLabelLayerOptions}
/>
<MapLayer
layerKey="admin-0-label-priority"
layerOptions={adminLabelLayerOptions}
/>
{/*
<MapLayer
layerKey="admin-0-boundary"
layerOptions={adminZeroLineLayerOptions}
/>
*/}
<MapLayer
layerKey="admin-0-boundary-disputed"
layerOptions={adminZeroLineLayerOptions}
/>
{(onHover || onClick) && (
<MapLayer
layerKey="admin-0-highlight"
layerOptions={adminZeroHighlightLayerOptions}
onClick={onClick ? handleClick : undefined}
/>
)}
{baseLayers}
</>
)}
/>
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/domain/RiskImminentEventMap/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import type {
SymbolLayer,
} from 'mapbox-gl';

import BaseMap from '#components/domain/BaseMap';
import GlobalMap from '#components/domain/GlobalMap';
import MapContainerWithDisclaimer from '#components/MapContainerWithDisclaimer';
import { type components } from '#generated/riskTypes';
import useDebouncedValue from '#hooks/useDebouncedValue';
Expand Down Expand Up @@ -347,7 +347,7 @@ function RiskImminentEventMap<

return (
<div className={styles.riskImminentEventMap}>
<BaseMap
<GlobalMap
mapOptions={{ bounds }}
>
<MapContainerWithDisclaimer
Expand Down Expand Up @@ -469,7 +469,7 @@ function RiskImminentEventMap<
padding={DEFAULT_MAP_PADDING}
/>
)}
</BaseMap>
</GlobalMap>
<Container
heading={sidePanelHeading}
className={styles.sidePanel}
Expand Down
Loading

0 comments on commit bb9a501

Please sign in to comment.