diff --git a/libs/shared/src/lib/models/layer.model.ts b/libs/shared/src/lib/models/layer.model.ts index c9e6aab956..863a33bbb5 100644 --- a/libs/shared/src/lib/models/layer.model.ts +++ b/libs/shared/src/lib/models/layer.model.ts @@ -2,6 +2,7 @@ import { FaIconName } from '@oort-front/ui'; import { Gradient } from '../components/controls/gradient-picker/gradient-picker.component'; import { LayerType } from '../components/ui/map/interfaces/layer-settings.type'; import { HeatMapOptions as HeatMapOptionsWithoutOpacity } from 'leaflet'; +import { AdminIdentifier } from '../services/map/map-polygons.service'; /** * Layer types for backend @@ -135,7 +136,7 @@ export interface LayerDatasource { layout?: string; aggregation?: string; geoField?: string; - adminField?: string; + adminField?: AdminIdentifier; latitudeField?: string; longitudeField?: string; type?: LayerDatasourceType; diff --git a/libs/shared/src/lib/services/map/map-layers.service.ts b/libs/shared/src/lib/services/map/map-layers.service.ts index 0f1b31be52..37670d1c69 100644 --- a/libs/shared/src/lib/services/map/map-layers.service.ts +++ b/libs/shared/src/lib/services/map/map-layers.service.ts @@ -435,9 +435,10 @@ export class MapLayersService { map((value) => { // When using adminField mapping, update the feature so geometry is replaced with according polygons if (layer.datasource?.adminField) { - return this.mapPolygonsService.assignPolygons( + return this.mapPolygonsService.assignGeometry( value, - layer.datasource.adminField as any + layer.datasource.adminField, + layer.datasource.type ); } else { // Else, directly returns the feature layer diff --git a/libs/shared/src/lib/services/map/map-polygons.service.ts b/libs/shared/src/lib/services/map/map-polygons.service.ts index 655915d17b..dfc8429c0e 100644 --- a/libs/shared/src/lib/services/map/map-polygons.service.ts +++ b/libs/shared/src/lib/services/map/map-polygons.service.ts @@ -7,13 +7,28 @@ import { flattenDeep, get, isArray, isNil, isObject, uniq } from 'lodash'; import * as L from 'leaflet'; import REGIONS from './regions'; import booleanPointInPolygon from '@turf/boolean-point-in-polygon'; +import { Feature, MultiPolygon, Polygon } from 'geojson'; +import { LayerDatasourceType } from '../../models/layer.model'; /** Available admin identifiers */ -type AdminIdentifier = 'admin0.iso2code' | 'admin0.iso3code' | 'admin0.id'; +export type AdminIdentifier = + | 'admin0.iso2code' + | 'admin0.iso3code' + | 'admin0.id'; /** Admin 0 available identifiers */ type Admin0Identifier = 'iso2code' | 'iso3code' | 'id'; +type Admin0 = { + id: number; + centerlatitude: string; + centerlongitude: string; + iso2code: string; + iso3code: string; + name: string; + polygons: Polygon | MultiPolygon | Feature; +}; + /** * Shared map polygons service. * Allow to use polygons from common services, and assign them to the layer features. @@ -23,7 +38,7 @@ type Admin0Identifier = 'iso2code' | 'iso3code' | 'id'; }) export class MapPolygonsService { /** Admin0 polygons */ - public admin0s: any[] = []; + public admin0s: Admin0[] = []; /** Are admin0 polygons ready */ private admin0sReady = new BehaviorSubject(false); /** Admin0 polygons status as observable */ @@ -60,15 +75,26 @@ export class MapPolygonsService { * * @param data feature layer * @param identifier admin identifier + * @param layerDatasourceType type of datasource, point or polygon * @returns feature layer with polygons for geometry */ - public assignAdmin0Polygons( + public assignAdmin0Geometry( data: any, - identifier: Admin0Identifier = 'iso3code' + identifier: Admin0Identifier = 'iso3code', + layerDatasourceType: LayerDatasourceType ) { - const polygons = {}; + const geometry = {}; for (const admin0 of this.admin0s) { - set(polygons, admin0[identifier].toLowerCase(), admin0.polygons); + set( + geometry, + admin0[identifier].toString().toLowerCase(), + layerDatasourceType === 'Polygon' + ? admin0.polygons + : { + type: 'Point', + coordinates: [admin0.centerlongitude, admin0.centerlatitude], + } + ); } const features: any[] = []; for (const feature of data.features) { @@ -76,12 +102,12 @@ export class MapPolygonsService { (x) => !isObject(x) && !isNil(x) ); adminIds.forEach((adminId) => { - const adminPolygons = get(polygons, adminId.toString().toLowerCase()); - if (adminPolygons) { + const adminGeometry = get(geometry, adminId.toString().toLowerCase()); + if (adminGeometry) { features.push({ ...feature, type: 'Feature', - geometry: adminPolygons, + geometry: adminGeometry, }); } }); @@ -97,16 +123,19 @@ export class MapPolygonsService { * * @param data feature layer * @param identifier admin identifier + * @param layerDatasourceType type of layer datasource, polygon by default * @returns feature layer with polygons for geometry */ - public assignPolygons( + public assignGeometry( data: any, - identifier: AdminIdentifier = 'admin0.iso3code' + identifier: AdminIdentifier = 'admin0.iso3code', + layerDatasourceType: LayerDatasourceType = 'Polygon' ) { if (identifier.startsWith('admin0.')) { - return this.assignAdmin0Polygons( + return this.assignAdmin0Geometry( data, - identifier.replace('admin0.', '') as Admin0Identifier + identifier.replace('admin0.', '') as Admin0Identifier, + layerDatasourceType ); } else { return EMPTY_FEATURE_COLLECTION;