diff --git a/apps/nowcasting-app/components/map/sitesMap.tsx b/apps/nowcasting-app/components/map/sitesMap.tsx index 9ab90249..0056101f 100644 --- a/apps/nowcasting-app/components/map/sitesMap.tsx +++ b/apps/nowcasting-app/components/map/sitesMap.tsx @@ -25,6 +25,7 @@ import { theme } from "../../tailwind.config"; import { Feature, FeatureCollection } from "geojson"; import Slider from "./sitesMapFeatures/sitesZoomSlider"; import SitesLegend from "./sitesMapFeatures/sitesLegend"; +import { getRingMultiplier } from "./sitesMapFeatures/utils"; import { safelyUpdateMapData } from "../helpers/mapUtils"; const yellow = theme.extend.colors["ocf-yellow"].DEFAULT; @@ -100,20 +101,6 @@ const SitesMap: React.FC = ({ 1 ]; - const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS) => { - // TODO: this will need to be dynamic depending on user's site capacities - switch (aggregationLevel) { - case AGGREGATION_LEVELS.SITE: - return 10; - case AGGREGATION_LEVELS.GSP: - return 5; - case AGGREGATION_LEVELS.REGION: - return 1.5; - case AGGREGATION_LEVELS.NATIONAL: - return 0.3; - } - }; - const generateGeoJsonForecastData: ( forecastData?: FcAllResData, targetTime?: string @@ -282,6 +269,11 @@ const SitesMap: React.FC = ({ addGroupSource(map, groupName, groupFeatureArray); } + // get the maximum capacity in all the FeatureArrays, but feature.properties might be null, if so us 1 + const maxCapacity = Math.max( + ...groupFeatureArray.map((feature) => feature.properties?.capacity || 1) + ); + if (groupName === "regions") { let dnoBoundariesSource = map.getSource("dnoBoundaries") as unknown as | mapboxgl.GeoJSONSource @@ -346,7 +338,7 @@ const SitesMap: React.FC = ({ map.setPaintProperty(`Capacity-${groupName}`, "circle-radius", [ "*", ["to-number", ["get", "capacity"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ]); // const visibility = currentAggregationLevel === groupAggregationLevel ? "visible" : "none"; const visibility = "visible"; @@ -366,7 +358,7 @@ const SitesMap: React.FC = ({ "circle-radius": [ "*", ["to-number", ["get", "capacity"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ], "circle-stroke-color": [ "case", @@ -412,7 +404,7 @@ const SitesMap: React.FC = ({ map.setPaintProperty(`Generation-${groupName}`, "circle-radius", [ "*", ["to-number", ["get", "expectedPVRadius"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ]); // const visibility = currentAggregationLevel === groupAggregationLevel ? "visible" : "none"; const visibility = "visible"; @@ -432,7 +424,7 @@ const SitesMap: React.FC = ({ "circle-radius": [ "*", ["to-number", ["get", "expectedPVRadius"]], - getRingMultiplier(groupAggregationLevel) + getRingMultiplier(groupAggregationLevel, maxCapacity) ], "circle-color": [ "case", diff --git a/apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx new file mode 100644 index 00000000..e0a82fd5 --- /dev/null +++ b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.test.tsx @@ -0,0 +1,16 @@ +import { describe, expect, test } from "@jest/globals"; +import { getRingMultiplier } from "./utils"; +import { AGGREGATION_LEVELS } from "../../../constant"; + +describe("Check getRingMultiplier", () => { + test("check getRingMultiplier works for different values", () => { + expect(getRingMultiplier(AGGREGATION_LEVELS.SITE, 10)).toBe(3); + expect(getRingMultiplier(AGGREGATION_LEVELS.GSP, 10)).toBe(4.5); + expect(getRingMultiplier(AGGREGATION_LEVELS.REGION, 10)).toBe(6); + expect(getRingMultiplier(AGGREGATION_LEVELS.NATIONAL, 10)).toBe(10); + expect(getRingMultiplier(AGGREGATION_LEVELS.SITE, 20)).toBe(1.5); + expect(getRingMultiplier(AGGREGATION_LEVELS.GSP, 20)).toBe(2.25); + expect(getRingMultiplier(AGGREGATION_LEVELS.REGION, 20)).toBe(3); + expect(getRingMultiplier(AGGREGATION_LEVELS.NATIONAL, 20)).toBe(5); + }); +}); diff --git a/apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx new file mode 100644 index 00000000..b0f430df --- /dev/null +++ b/apps/nowcasting-app/components/map/sitesMapFeatures/utils.tsx @@ -0,0 +1,19 @@ +import { AGGREGATION_LEVELS } from "../../../constant"; + +export const getRingMultiplier = (aggregationLevel: AGGREGATION_LEVELS, maxCapacity: number) => { + // Get the circle multiplier based, which will times the Expected PV value to get the radius + // We used to use 0.3 for National, 1.5 for DNO, 5 for GSP and 10 for Sites. + // Now we use a multiplier based on the max capacity of the the different sites/regions. + // If a client has 100 3 KW sites. Then the National multipler will be about 0.3. + + switch (aggregationLevel) { + case AGGREGATION_LEVELS.SITE: + return 30 / maxCapacity; + case AGGREGATION_LEVELS.GSP: + return 45 / maxCapacity; + case AGGREGATION_LEVELS.REGION: + return 60 / maxCapacity; + case AGGREGATION_LEVELS.NATIONAL: + return 100 / maxCapacity; + } +};