From b10f7c6667a07ff58276ee473bcfca7aae0e4c8a Mon Sep 17 00:00:00 2001 From: Anton Ahatov Date: Mon, 6 Nov 2023 19:28:59 +0000 Subject: [PATCH] add dtp heatmap (#121) --- components/Map/Map.tsx | 5 ++-- components/Map/layers/DtpSource.tsx | 43 ++++++++++++++++++++++++++--- constants/map.ts | 2 ++ 3 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 constants/map.ts diff --git a/components/Map/Map.tsx b/components/Map/Map.tsx index 58debece..a83f831a 100644 --- a/components/Map/Map.tsx +++ b/components/Map/Map.tsx @@ -5,6 +5,7 @@ import React, { useContext } from 'react'; import MapGl from 'react-map-gl'; import maplibregl from 'maplibre-gl'; import { COORDS_EKATERINBURG } from 'constants/coords'; +import { MAX_ZOOM, MIN_ZOOM } from 'constants/map'; import { BuildingSource } from './layers/BuildingSource'; import { OknSource } from './layers/OknSource'; @@ -39,8 +40,8 @@ export function Map() { zoom: 15, pitch: 30, }} - minZoom={11} - maxZoom={20} + minZoom={MIN_ZOOM} + maxZoom={MAX_ZOOM} // hash style={{ width: '100vw', height: '100vh', color: 'black' }} mapStyle="https://map-backend.netlify.app/style.json" diff --git a/components/Map/layers/DtpSource.tsx b/components/Map/layers/DtpSource.tsx index a88a10df..faa0947d 100644 --- a/components/Map/layers/DtpSource.tsx +++ b/components/Map/layers/DtpSource.tsx @@ -1,17 +1,18 @@ import React, { useEffect } from 'react'; import { Source, Layer, useMap } from 'react-map-gl'; -import type { CircleLayer } from 'react-map-gl'; +import type { CircleLayer, HeatmapLayer } from 'react-map-gl'; import { useSelector } from 'react-redux'; import { activeFilterSelector, activeFilterParamsSelector } from 'state/features/selectors'; import { FilterType } from 'types/Filters.types'; import { SEVERITY_CONFIG } from 'components/Layers/DTP/DTP.constants'; import { MapItemType } from 'types/map-item'; -import { getLayerStyle } from 'components/Map/helpers/getFeatureState'; +import { MAX_ZOOM, MIN_ZOOM } from 'constants/map'; import dtp from '../../../public/ekb-dtp.json'; import { usePopup } from '../providers/usePopup'; import useMapObjectState from '../providers/useMapObjectState'; const DTP_LAYER_ID = 'dtp-point'; +const DTP_LAYER_HEATMAP_ID = 'dtp-point-heatmap'; export function DtpSource() { const ekbMap = useMap(); @@ -66,13 +67,46 @@ export function DtpSource() { type: 'circle', source: 'ekb-dtp-source', paint: { - 'circle-radius': getLayerStyle({ initial: 8, hover: 10, active: 12 }), // @ts-ignore 'circle-color': ['case'].concat(...colors).concat(['rgba(0, 0, 0, 0)']), - // @ts-ignore 'circle-stroke-width': 1, // @ts-ignore 'circle-stroke-color': ['case'].concat(...strokeColors).concat(['rgba(0, 0, 0, 0)']), + 'circle-radius': ['interpolate', ['linear'], ['zoom'], MIN_ZOOM, 1, MAX_ZOOM, 12], + }, + }; + + const heatmapStyle: HeatmapLayer = { + id: DTP_LAYER_HEATMAP_ID, + source: 'ekb-dtp-source', + type: 'heatmap', + paint: { + 'heatmap-weight': { + type: 'exponential', + property: 'weight', + stops: [ + [0, 0], + [1, 1], + ], + }, + 'heatmap-intensity': 1, + 'heatmap-color': [ + 'interpolate', + ['linear'], + ['heatmap-density'], + 0, + 'rgba(0, 0, 255, 0)', + 0.2, + 'rgb(0, 255, 0)', + 0.4, + 'rgb(255, 255, 0)', + 0.6, + 'rgb(255, 0, 0)', + 1, + 'rgb(255, 0, 0)', + ], + 'heatmap-radius': ['interpolate', ['linear'], ['zoom'], MIN_ZOOM, 2, MAX_ZOOM, 50], + 'heatmap-opacity': ['interpolate', ['linear'], ['zoom'], MIN_ZOOM, 1, MAX_ZOOM, 0], }, }; @@ -80,6 +114,7 @@ export function DtpSource() { <> + ); diff --git a/constants/map.ts b/constants/map.ts new file mode 100644 index 00000000..41c6957f --- /dev/null +++ b/constants/map.ts @@ -0,0 +1,2 @@ +export const MIN_ZOOM = 11; +export const MAX_ZOOM = 20;