diff --git a/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts b/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts
index a896f4be019afda0cdea7b9ff858bae65e0e6045..e7ccb7c9fa70b4bc304697f8d6d64a5beca9556b 100644
--- a/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts
@@ -1,5 +1,6 @@
 import View from 'ol/View';
 import BaseLayer from 'ol/layer/Base';
+import { OverlayBioEntityRender } from '@/types/OLrendering';
 
 export type MapConfig = {
   view: View;
@@ -8,3 +9,7 @@ export type MapConfig = {
 
 export type VerticalAlign = 'TOP' | 'MIDDLE' | 'BOTTOM';
 export type HorizontalAlign = 'LEFT' | 'RIGHT' | 'CENTER' | 'END' | 'START';
+
+export type OverlayBioEntityGroupedElementsType = {
+  [id: string]: Array<OverlayBioEntityRender & { amount: number }>;
+};
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/processModelElements.ts b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/processModelElements.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8aba562e8bc3001d6e6bf2db476e920332eeb0f8
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/processModelElements.ts
@@ -0,0 +1,120 @@
+import { ModelElement, ModelElements } from '@/types/models';
+import MapElement from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement';
+import CompartmentCircle from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentCircle';
+import CompartmentSquare from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentSquare';
+import CompartmentPathway from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentPathway';
+import Glyph from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/Glyph';
+import {
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+import { MapInstance } from '@/types/map';
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import { BioShapesDict, LineTypeDict } from '@/redux/shapes/shapes.types';
+import { OverlayOrder } from '@/redux/overlayBioEntity/overlayBioEntity.utils';
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+
+export default function processModelElements(
+  modelElements: ModelElements,
+  shapes: BioShapesDict,
+  lineTypes: LineTypeDict,
+  groupedElementsOverlays: Record<string, Array<OverlayBioEntityRender>>,
+  overlaysOrder: Array<OverlayOrder>,
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties,
+  mapInstance: MapInstance,
+  pointToProjection: UsePointToProjectionResult,
+): Array<MapElement | CompartmentCircle | CompartmentSquare | CompartmentPathway | Glyph> {
+  const validElements: Array<
+    MapElement | CompartmentCircle | CompartmentSquare | CompartmentPathway | Glyph
+  > = [];
+  modelElements.content.forEach((element: ModelElement) => {
+    if (element.glyph) {
+      const glyph = new Glyph({
+        id: element.glyph.id,
+        x: element.x,
+        y: element.y,
+        width: element.width,
+        height: element.height,
+        zIndex: element.z,
+        pointToProjection,
+        mapInstance,
+      });
+      validElements.push(glyph);
+      return;
+    }
+
+    if (element.sboTerm === 'SBO:0000290') {
+      const compartmentProps = {
+        id: element.id,
+        x: element.x,
+        y: element.y,
+        nameX: element.nameX,
+        nameY: element.nameY,
+        nameHeight: element.nameHeight,
+        nameWidth: element.nameWidth,
+        width: element.width,
+        height: element.height,
+        zIndex: element.z,
+        innerWidth: element.innerWidth,
+        outerWidth: element.outerWidth,
+        thickness: element.thickness,
+        fontColor: element.fontColor,
+        fillColor: element.fillColor,
+        borderColor: element.borderColor,
+        nameVerticalAlign: element.nameVerticalAlign as VerticalAlign,
+        nameHorizontalAlign: element.nameHorizontalAlign as HorizontalAlign,
+        text: element.name,
+        fontSize: element.fontSize,
+        pointToProjection,
+        mapInstance,
+      };
+      if (element.shape === 'OVAL_COMPARTMENT') {
+        validElements.push(new CompartmentCircle(compartmentProps));
+      } else if (element.shape === 'SQUARE_COMPARTMENT') {
+        validElements.push(new CompartmentSquare(compartmentProps));
+      } else if (element.shape === 'PATHWAY') {
+        validElements.push(new CompartmentPathway(compartmentProps));
+      }
+      return;
+    }
+    const elementShapes = shapes[element.sboTerm];
+    if (elementShapes) {
+      validElements.push(
+        new MapElement({
+          id: element.id,
+          shapes: elementShapes,
+          x: element.x,
+          y: element.y,
+          nameX: element.nameX,
+          nameY: element.nameY,
+          nameHeight: element.nameHeight,
+          nameWidth: element.nameWidth,
+          width: element.width,
+          height: element.height,
+          zIndex: element.z,
+          lineWidth: element.lineWidth,
+          lineType: element.borderLineType,
+          fontColor: element.fontColor,
+          fillColor: element.fillColor,
+          borderColor: element.borderColor,
+          nameVerticalAlign: element.nameVerticalAlign as VerticalAlign,
+          nameHorizontalAlign: element.nameHorizontalAlign as HorizontalAlign,
+          homodimer: element.homodimer,
+          activity: element.activity,
+          text: element.name,
+          fontSize: element.fontSize,
+          pointToProjection,
+          mapInstance,
+          modifications: element.modificationResidues,
+          lineTypes,
+          bioShapes: shapes,
+          overlays: groupedElementsOverlays[element.id],
+          overlaysOrder,
+          getOverlayColor,
+        }),
+      );
+    }
+  });
+  return validElements;
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index 00ff8cb89f65c58492a94d0f9388455d49a8123f..87f31fcf34f378176ec4fc91d070135875204e5f 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -12,23 +12,32 @@ import {
   lineTypesSelector,
 } from '@/redux/shapes/shapes.selectors';
 import { MapInstance } from '@/types/map';
-import {
-  HorizontalAlign,
-  VerticalAlign,
-} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
 import { modelElementsSelector } from '@/redux/modelElements/modelElements.selector';
 import { currentModelIdSelector } from '@/redux/models/models.selectors';
 import { getModelElements } from '@/redux/modelElements/modelElements.thunks';
 import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
 import CompartmentSquare from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentSquare';
 import CompartmentCircle from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentCircle';
-import { ModelElement } from '@/types/models';
 import Glyph from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/Glyph';
 import CompartmentPathway from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/CompartmentPathway';
 import Reaction from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/reaction/Reaction';
 import { newReactionsDataSelector } from '@/redux/newReactions/newReactions.selectors';
 import { getNewReactions } from '@/redux/newReactions/newReactions.thunks';
 import { VECTOR_MAP_LAYER_TYPE } from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants';
+import {
+  getOverlayOrderSelector,
+  overlayBioEntitiesForCurrentModelSelector,
+} from '@/redux/overlayBioEntity/overlayBioEntity.selector';
+import { groupBy } from '@/utils/array/groupBy';
+import { useGetOverlayColor } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import { useAppSelector } from '@/redux/hooks/useAppSelector';
+import getOverlays from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays';
+import LineOverlay from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay';
+import { markersSufraceOfCurrentMapDataSelector } from '@/redux/markers/markers.selectors';
+import { parseSurfaceMarkersToBioEntityRender } from '@/components/Map/MapViewer/utils/config/overlaysLayer/parseSurfaceMarkersToBioEntityRender';
+import MarkerOverlay from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay';
+import processModelElements from '@/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/processModelElements';
+import useDebouncedValue from '@/utils/useDebouncedValue';
 
 export const useOlMapReactionsLayer = ({
   mapInstance,
@@ -36,18 +45,70 @@ export const useOlMapReactionsLayer = ({
   mapInstance: MapInstance;
 }): VectorLayer<VectorSource<Feature>> => {
   const dispatch = useAppDispatch();
+
+  const currentModelId = useSelector(currentModelIdSelector);
   const modelElements = useSelector(modelElementsSelector);
   const modelReactions = useSelector(newReactionsDataSelector);
-  const currentModelId = useSelector(currentModelIdSelector);
+  const shapes = useSelector(bioShapesSelector);
+  const lineTypes = useSelector(lineTypesSelector);
+  const arrowTypes = useSelector(arrowTypesSelector);
+  const overlaysOrder = useSelector(getOverlayOrderSelector);
+  const currentMarkers = useAppSelector(markersSufraceOfCurrentMapDataSelector);
+  const markersRender = parseSurfaceMarkersToBioEntityRender(currentMarkers);
+  const bioEntities = useAppSelector(overlayBioEntitiesForCurrentModelSelector);
+  const debouncedBioEntities = useDebouncedValue(bioEntities, 2000);
+  const { getOverlayBioEntityColorByAvailableProperties } = useGetOverlayColor();
+
+  const pointToProjection = usePointToProjection();
+
   useEffect(() => {
     dispatch(getModelElements(currentModelId));
     dispatch(getNewReactions(currentModelId));
   }, [currentModelId, dispatch]);
 
-  const pointToProjection = usePointToProjection();
-  const shapes = useSelector(bioShapesSelector);
-  const lineTypes = useSelector(lineTypesSelector);
-  const arrowTypes = useSelector(arrowTypesSelector);
+  const groupedElementsOverlays = useMemo(() => {
+    const elementsBioEntitesOverlay = debouncedBioEntities.filter(
+      bioEntity => bioEntity.type !== 'line',
+    );
+    const grouped = groupBy(elementsBioEntitesOverlay, bioEntity => bioEntity.id.toString());
+    return getOverlays(grouped, getOverlayBioEntityColorByAvailableProperties);
+  }, [debouncedBioEntities, getOverlayBioEntityColorByAvailableProperties]);
+
+  const linesOverlays = useMemo(() => {
+    return bioEntities.filter(bioEntity => bioEntity.type === 'line');
+  }, [bioEntities]);
+
+  const linesOverlaysFeatures = useMemo(() => {
+    return linesOverlays.map(lineOverlay => {
+      return new LineOverlay({
+        lineOverlay,
+        getOverlayColor: getOverlayBioEntityColorByAvailableProperties,
+        pointToProjection,
+        mapInstance,
+      }).lineFeature;
+    });
+  }, [
+    getOverlayBioEntityColorByAvailableProperties,
+    linesOverlays,
+    mapInstance,
+    pointToProjection,
+  ]);
+
+  const markerOverlaysFeatures = useMemo(() => {
+    return markersRender.map(marker => {
+      return new MarkerOverlay({
+        markerOverlay: marker,
+        getOverlayColor: getOverlayBioEntityColorByAvailableProperties,
+        pointToProjection,
+        mapInstance,
+      }).markerFeature;
+    });
+  }, [
+    getOverlayBioEntityColorByAvailableProperties,
+    mapInstance,
+    markersRender,
+    pointToProjection,
+  ]);
 
   const reactions = useMemo(() => {
     return modelReactions.map(reaction => {
@@ -79,109 +140,44 @@ export const useOlMapReactionsLayer = ({
     if (!modelElements || !shapes) {
       return [];
     }
-
-    const validElements: Array<
-      MapElement | CompartmentCircle | CompartmentSquare | CompartmentPathway | Glyph
-    > = [];
-    modelElements.content.forEach((element: ModelElement) => {
-      if (element.glyph) {
-        const glyph = new Glyph({
-          id: element.glyph.id,
-          x: element.x,
-          y: element.y,
-          width: element.width,
-          height: element.height,
-          zIndex: element.z,
-          pointToProjection,
-          mapInstance,
-        });
-        validElements.push(glyph);
-        return;
-      }
-
-      if (element.sboTerm === 'SBO:0000290') {
-        const compartmentProps = {
-          id: element.id,
-          x: element.x,
-          y: element.y,
-          nameX: element.nameX,
-          nameY: element.nameY,
-          nameHeight: element.nameHeight,
-          nameWidth: element.nameWidth,
-          width: element.width,
-          height: element.height,
-          zIndex: element.z,
-          innerWidth: element.innerWidth,
-          outerWidth: element.outerWidth,
-          thickness: element.thickness,
-          fontColor: element.fontColor,
-          fillColor: element.fillColor,
-          borderColor: element.borderColor,
-          nameVerticalAlign: element.nameVerticalAlign as VerticalAlign,
-          nameHorizontalAlign: element.nameHorizontalAlign as HorizontalAlign,
-          text: element.name,
-          fontSize: element.fontSize,
-          pointToProjection,
-          mapInstance,
-        };
-        if (element.shape === 'OVAL_COMPARTMENT') {
-          validElements.push(new CompartmentCircle(compartmentProps));
-        } else if (element.shape === 'SQUARE_COMPARTMENT') {
-          validElements.push(new CompartmentSquare(compartmentProps));
-        } else if (element.shape === 'PATHWAY') {
-          validElements.push(new CompartmentPathway(compartmentProps));
-        }
-        return;
-      }
-      const elementShapes = shapes[element.sboTerm];
-      if (elementShapes) {
-        validElements.push(
-          new MapElement({
-            id: element.id,
-            shapes: elementShapes,
-            x: element.x,
-            y: element.y,
-            nameX: element.nameX,
-            nameY: element.nameY,
-            nameHeight: element.nameHeight,
-            nameWidth: element.nameWidth,
-            width: element.width,
-            height: element.height,
-            zIndex: element.z,
-            lineWidth: element.lineWidth,
-            lineType: element.borderLineType,
-            fontColor: element.fontColor,
-            fillColor: element.fillColor,
-            borderColor: element.borderColor,
-            nameVerticalAlign: element.nameVerticalAlign as VerticalAlign,
-            nameHorizontalAlign: element.nameHorizontalAlign as HorizontalAlign,
-            homodimer: element.homodimer,
-            activity: element.activity,
-            text: element.name,
-            fontSize: element.fontSize,
-            pointToProjection,
-            mapInstance,
-            modifications: element.modificationResidues,
-            lineTypes,
-            bioShapes: shapes,
-          }),
-        );
-      }
-    });
-    return validElements;
-  }, [modelElements, shapes, pointToProjection, mapInstance, lineTypes]);
+    return processModelElements(
+      modelElements,
+      shapes,
+      lineTypes,
+      groupedElementsOverlays,
+      overlaysOrder,
+      getOverlayBioEntityColorByAvailableProperties,
+      mapInstance,
+      pointToProjection,
+    );
+  }, [
+    modelElements,
+    shapes,
+    pointToProjection,
+    mapInstance,
+    lineTypes,
+    groupedElementsOverlays,
+    overlaysOrder,
+    getOverlayBioEntityColorByAvailableProperties,
+  ]);
 
   const features = useMemo(() => {
     const reactionsFeatures = reactions.flat();
     const elementsFeatures = elements.map(element => element.feature);
-    return [...reactionsFeatures, ...elementsFeatures];
-  }, [elements, reactions]);
+    return [
+      ...reactionsFeatures,
+      ...elementsFeatures,
+      ...linesOverlaysFeatures,
+      ...markerOverlaysFeatures,
+    ];
+  }, [elements, linesOverlaysFeatures, markerOverlaysFeatures, reactions]);
 
-  const vectorSource = useMemo(() => {
-    return new VectorSource({
-      features,
-    });
-  }, [features]);
+  const vectorSource = useMemo(() => new VectorSource(), []);
+
+  useEffect(() => {
+    vectorSource.clear();
+    vectorSource.addFeatures(features);
+  }, [features, vectorSource]);
 
   return useMemo(() => {
     const vectorLayer = new VectorLayer({
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/config/useOlMapVectorLayers.ts b/src/components/Map/MapViewer/MapViewerVector/utils/config/useOlMapVectorLayers.ts
index 7ebb6e709f662cef89e30112e052bad29c871324..cebab4e092508f7d15bbeaf8a649166db7dfbe02 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/config/useOlMapVectorLayers.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/useOlMapVectorLayers.ts
@@ -2,8 +2,9 @@
 import { MapInstance } from '@/types/map';
 import { useOlMapWhiteCardLayer } from '@/components/Map/MapViewer/MapViewerVector/utils/config/useOlMapWhiteCardLayer';
 import { useOlMapAdditionalLayers } from '@/components/Map/MapViewer/MapViewerVector/utils/config/additionalLayers/useOlMapAdditionalLayers';
-import { MapConfig } from '../../MapViewerVector.types';
+import { useMemo } from 'react';
 import { useOlMapReactionsLayer } from './reactionsLayer/useOlMapReactionsLayer';
+import { MapConfig } from '../../MapViewerVector.types';
 
 interface UseOlMapLayersInput {
   mapInstance: MapInstance;
@@ -14,5 +15,7 @@ export const useOlMapVectorLayers = ({ mapInstance }: UseOlMapLayersInput): MapC
   const whiteCardLayer = useOlMapWhiteCardLayer();
   const additionalLayers = useOlMapAdditionalLayers(mapInstance);
 
-  return [whiteCardLayer, reactionsLayer, ...additionalLayers];
+  return useMemo(() => {
+    return [whiteCardLayer, reactionsLayer, ...additionalLayers];
+  }, [whiteCardLayer, reactionsLayer, additionalLayers]);
 };
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.test.ts
index 64c1f92d23ef03b84c8c1a39f226655f4fa2f189..71c5c3c2bb31a688274e51b808af8bea595f9d44 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.test.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.test.ts
@@ -60,6 +60,7 @@ describe('MapElement', () => {
       nameHorizontalAlign: 'CENTER',
       pointToProjection: jest.fn(),
       mapInstance,
+      getOverlayColor: (): string => '#ffffff',
     };
 
     (getTextStyle as jest.Mock).mockReturnValue(
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.ts
index dae35c65e06fb8b226ca18a2946961ad95f1465e..94d5f96f4fe3c23d0529a14cf983b3514ba20b0e 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/MapElement.ts
@@ -22,6 +22,11 @@ import getTextStyle from '@/components/Map/MapViewer/MapViewerVector/utils/shape
 import getShapePolygon from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/elements/getShapePolygon';
 import { BioShapesDict, LineTypeDict } from '@/redux/shapes/shapes.types';
 import { FEATURE_TYPE } from '@/constants/features';
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { getPolygonLatitudeCoordinates } from '@/components/Map/MapViewer/utils/config/overlaysLayer/getPolygonLatitudeCoordinates';
+import { ZERO } from '@/constants/common';
+import { OverlayOrder } from '@/redux/overlayBioEntity/overlayBioEntity.utils';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
 
 export type MapElementProps = {
   id: number;
@@ -51,6 +56,9 @@ export type MapElementProps = {
   bioShapes?: BioShapesDict;
   lineTypes?: LineTypeDict;
   modifications?: Array<Modification>;
+  overlays?: Array<OverlayBioEntityRender>;
+  overlaysOrder?: Array<OverlayOrder>;
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties;
 };
 
 export default class MapElement extends BaseMultiPolygon {
@@ -72,6 +80,12 @@ export default class MapElement extends BaseMultiPolygon {
 
   lineDash: Array<number> = [];
 
+  overlays: Array<OverlayBioEntityRender> = [];
+
+  overlaysOrder: Array<OverlayOrder> = [];
+
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties;
+
   constructor({
     id,
     shapes,
@@ -100,6 +114,9 @@ export default class MapElement extends BaseMultiPolygon {
     bioShapes = {},
     lineTypes = {},
     modifications = [],
+    overlays = [],
+    overlaysOrder = [],
+    getOverlayColor,
   }: MapElementProps) {
     super({
       type: FEATURE_TYPE.ALIAS,
@@ -130,6 +147,9 @@ export default class MapElement extends BaseMultiPolygon {
     this.bioShapes = bioShapes;
     this.lineTypes = lineTypes;
     this.modifications = modifications;
+    this.overlays = overlays;
+    this.overlaysOrder = overlaysOrder;
+    this.getOverlayColor = getOverlayColor;
     this.createPolygons();
     this.drawText();
     this.drawMultiPolygonFeature(mapInstance);
@@ -160,6 +180,7 @@ export default class MapElement extends BaseMultiPolygon {
       }
       this.drawElementPolygon(homodimerShift, homodimerOffset);
     }
+    this.drawOverlays();
   }
 
   drawModification(modification: Modification, shapes: Array<Shape>): void {
@@ -250,7 +271,7 @@ export default class MapElement extends BaseMultiPolygon {
       const elementStyle = getStyle({
         geometry: elementPolygon,
         borderColor: this.borderColor,
-        fillColor: this.fillColor,
+        fillColor: this.overlays.length ? undefined : this.fillColor,
         lineWidth: this.lineWidth,
         lineDash: this.lineDash,
         zIndex: this.zIndex,
@@ -260,4 +281,37 @@ export default class MapElement extends BaseMultiPolygon {
       this.styles.push(elementStyle);
     });
   }
+
+  drawOverlays(): void {
+    this.overlays.forEach(entity => {
+      if (entity.value === Infinity) {
+        return;
+      }
+      const { xMin, xMax } = getPolygonLatitudeCoordinates({
+        width: entity.width,
+        nOverlays: this.overlaysOrder.length,
+        xMin: entity.x1,
+        overlayIndexBasedOnOrder:
+          this.overlaysOrder.find(({ id }) => id === entity.overlayId)?.index || ZERO,
+      });
+      const color = this.getOverlayColor(entity);
+      const polygon = new Polygon([
+        [
+          this.pointToProjection({ x: xMin, y: entity.y1 }),
+          this.pointToProjection({ x: xMax, y: entity.y1 }),
+          this.pointToProjection({ x: xMax, y: entity.y2 }),
+          this.pointToProjection({ x: xMin, y: entity.y2 }),
+        ],
+      ]);
+      const style = getStyle({
+        geometry: polygon,
+        borderColor: color,
+        fillColor: color,
+        zIndex: this.zIndex,
+      });
+      this.polygons.push(polygon);
+      this.lineWidths.push(1);
+      this.styles.push(style);
+    });
+  }
 }
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4efbc9d6e3f4b4c78f4689ca0ecb77ef8e230ba4
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay.test.ts
@@ -0,0 +1,60 @@
+/* eslint-disable no-magic-numbers */
+import { Feature, Map } from 'ol';
+import { Stroke, Style } from 'ol/style';
+import getStroke from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStroke';
+import getFill from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getFill';
+import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/rgbToHex';
+import View from 'ol/View';
+import LineOverlay, {
+  LineOverlayProps,
+} from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay';
+import { Coordinate } from 'ol/coordinate';
+
+jest.mock('../style/getStroke');
+jest.mock('../style/getFill');
+jest.mock('../style/rgbToHex');
+
+describe('LineOverlay', () => {
+  let props: LineOverlayProps;
+
+  beforeEach(() => {
+    const dummyElement = document.createElement('div');
+    const mapInstance = new Map({
+      target: dummyElement,
+      view: new View({
+        zoom: 5,
+        minZoom: 3,
+        maxZoom: 7,
+      }),
+    });
+    props = {
+      lineOverlay: {
+        color: null,
+        height: 2,
+        id: '3',
+        modelId: 1,
+        overlayId: 0,
+        type: 'line',
+        value: 0.43,
+        width: 2,
+        x1: 1,
+        x2: 3,
+        y1: 3,
+        y2: 1,
+      },
+      getOverlayColor: (): string => '#AABB11',
+      pointToProjection: ({ x, y }: { x: number; y: number }): Coordinate => [x, y],
+      mapInstance,
+    };
+
+    (getStroke as jest.Mock).mockReturnValue(new Stroke());
+    (getFill as jest.Mock).mockReturnValue(new Style());
+    (rgbToHex as jest.Mock).mockReturnValue('#FFFFFF');
+  });
+
+  it('should initialize line overlay feature', () => {
+    const lineOverlay = new LineOverlay(props);
+
+    expect(lineOverlay.lineFeature).toBeInstanceOf(Feature);
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b6d8eecb4099b69fe38221288af470ec2d76554c
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/LineOverlay.ts
@@ -0,0 +1,75 @@
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import { LineString } from 'ol/geom';
+import getStyle from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStyle';
+import { Feature } from 'ol';
+import { FeatureLike } from 'ol/Feature';
+import Style from 'ol/style/Style';
+import { MapInstance } from '@/types/map';
+
+export type LineOverlayProps = {
+  lineOverlay: OverlayBioEntityRender;
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties;
+  pointToProjection: UsePointToProjectionResult;
+  mapInstance: MapInstance;
+};
+
+export default class LineOverlay {
+  lineOverlay: OverlayBioEntityRender;
+
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties;
+
+  pointToProjection: UsePointToProjectionResult;
+
+  mapInstance: MapInstance;
+
+  lineFeature: Feature;
+
+  constructor({ lineOverlay, getOverlayColor, pointToProjection, mapInstance }: LineOverlayProps) {
+    this.lineOverlay = lineOverlay;
+    this.getOverlayColor = getOverlayColor;
+    this.pointToProjection = pointToProjection;
+    this.mapInstance = mapInstance;
+    this.lineFeature = this.drawOverlay();
+  }
+
+  drawOverlay(): Feature {
+    const points = [
+      this.pointToProjection({ x: this.lineOverlay.x1, y: this.lineOverlay.y1 }),
+      this.pointToProjection({ x: this.lineOverlay.x2, y: this.lineOverlay.y2 }),
+    ];
+    const color = this.getOverlayColor(this.lineOverlay);
+    const lineString = new LineString(points);
+    const lineStyle = getStyle({
+      geometry: lineString,
+      borderColor: color,
+      lineWidth: 6,
+      zIndex: 99999,
+    });
+    const lineFeature = new Feature<LineString>({
+      geometry: lineString,
+      style: lineStyle,
+      lineWidth: 6,
+    });
+    lineFeature.setStyle(this.getStyle.bind(this));
+    return lineFeature;
+  }
+
+  protected getStyle(feature: FeatureLike, resolution: number): Style | Array<Style> | void {
+    const maxZoom = this.mapInstance?.getView().get('originalMaxZoom');
+    const minResolution = this.mapInstance?.getView().getResolutionForZoom(maxZoom);
+    const style = feature.get('style');
+    if (!minResolution || !style) {
+      return [];
+    }
+
+    const scale = minResolution / resolution;
+    const lineWidth = feature.get('lineWidth') * scale;
+
+    if (style instanceof Style && style.getStroke()) {
+      style.getStroke()?.setWidth(lineWidth);
+    }
+    return style;
+  }
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4fe3c4aad5120a9cd322f84b943b40c039195543
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay.test.ts
@@ -0,0 +1,61 @@
+/* eslint-disable no-magic-numbers */
+import { Feature, Map } from 'ol';
+import { Stroke, Style } from 'ol/style';
+import getStroke from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStroke';
+import getFill from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getFill';
+import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/rgbToHex';
+import View from 'ol/View';
+import { Coordinate } from 'ol/coordinate';
+import MarkerOverlay, {
+  MarkerOverlayProps,
+} from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay';
+
+jest.mock('../style/getStroke');
+jest.mock('../style/getFill');
+jest.mock('../style/rgbToHex');
+
+describe('MarkerOverlay', () => {
+  let props: MarkerOverlayProps;
+
+  beforeEach(() => {
+    const dummyElement = document.createElement('div');
+    const mapInstance = new Map({
+      target: dummyElement,
+      view: new View({
+        zoom: 5,
+        minZoom: 3,
+        maxZoom: 7,
+      }),
+    });
+    props = {
+      markerOverlay: {
+        color: null,
+        height: 2,
+        hexColor: '#A756BA90',
+        id: '3',
+        modelId: 1,
+        overlayId: 0,
+        type: 'rectangle',
+        value: 0.43,
+        width: 2,
+        x1: 1,
+        x2: 3,
+        y1: 3,
+        y2: 1,
+      },
+      getOverlayColor: (): string => '#AABB11',
+      pointToProjection: ({ x, y }: { x: number; y: number }): Coordinate => [x, y],
+      mapInstance,
+    };
+
+    (getStroke as jest.Mock).mockReturnValue(new Stroke());
+    (getFill as jest.Mock).mockReturnValue(new Style());
+    (rgbToHex as jest.Mock).mockReturnValue('#FFFFFF');
+  });
+
+  it('should initialize line overlay feature', () => {
+    const markerOverlay = new MarkerOverlay(props);
+
+    expect(markerOverlay.markerFeature).toBeInstanceOf(Feature);
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a0336335d7a158c1d13c8895a59504673eff8f27
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/MarkerOverlay.ts
@@ -0,0 +1,83 @@
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import getStyle from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStyle';
+import { Feature } from 'ol';
+import { FeatureLike } from 'ol/Feature';
+import Style from 'ol/style/Style';
+import { MapInstance } from '@/types/map';
+import Polygon from 'ol/geom/Polygon';
+
+export type MarkerOverlayProps = {
+  markerOverlay: OverlayBioEntityRender;
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties;
+  pointToProjection: UsePointToProjectionResult;
+  mapInstance: MapInstance;
+};
+
+export default class MarkerOverlay {
+  markerOverlay: OverlayBioEntityRender;
+
+  getOverlayColor: GetOverlayBioEntityColorByAvailableProperties;
+
+  pointToProjection: UsePointToProjectionResult;
+
+  mapInstance: MapInstance;
+
+  markerFeature: Feature;
+
+  constructor({
+    markerOverlay,
+    getOverlayColor,
+    pointToProjection,
+    mapInstance,
+  }: MarkerOverlayProps) {
+    this.markerOverlay = markerOverlay;
+    this.getOverlayColor = getOverlayColor;
+    this.pointToProjection = pointToProjection;
+    this.mapInstance = mapInstance;
+    this.markerFeature = this.drawOverlay();
+  }
+
+  drawOverlay(): Feature {
+    const color = this.getOverlayColor(this.markerOverlay);
+    const polygon = new Polygon([
+      [
+        this.pointToProjection({ x: this.markerOverlay.x1, y: this.markerOverlay.y1 }),
+        this.pointToProjection({ x: this.markerOverlay.x2, y: this.markerOverlay.y1 }),
+        this.pointToProjection({ x: this.markerOverlay.x2, y: this.markerOverlay.y2 }),
+        this.pointToProjection({ x: this.markerOverlay.x1, y: this.markerOverlay.y2 }),
+      ],
+    ]);
+    const style = getStyle({
+      geometry: polygon,
+      fillColor: this.markerOverlay.hexColor || color,
+      lineWidth: 1,
+      zIndex: 99999,
+    });
+    const markerFeature = new Feature<Polygon>({
+      geometry: polygon,
+      style,
+      lineWidth: 1,
+    });
+    markerFeature.setStyle(this.getStyle.bind(this));
+    return markerFeature;
+  }
+
+  protected getStyle(feature: FeatureLike, resolution: number): Style | Array<Style> | void {
+    const maxZoom = this.mapInstance?.getView().get('originalMaxZoom');
+    const minResolution = this.mapInstance?.getView().getResolutionForZoom(maxZoom);
+    const style = feature.get('style');
+    if (!minResolution || !style) {
+      return [];
+    }
+
+    const scale = minResolution / resolution;
+    const lineWidth = feature.get('lineWidth') * scale;
+
+    if (style instanceof Style && style.getStroke()) {
+      style.getStroke()?.setWidth(lineWidth);
+    }
+    return style;
+  }
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e328d4e4e0cef2b34061c915fc1d55cec8e41d03
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions.test.ts
@@ -0,0 +1,47 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import calculateOverlayDimensions from './calculateOverlayDimensions';
+
+describe('calculateOverlayDimensions', () => {
+  it('should calculate overlay dimensions and update y1, y2, and height', () => {
+    const overlay: OverlayBioEntityRender & { amount: number } = {
+      amount: 3,
+      color: null,
+      height: 100,
+      hexColor: '#0000001a',
+      id: '3',
+      modelId: 0,
+      overlayId: 1,
+      type: 'submap-link',
+      value: -0.43,
+      width: 100,
+      x1: 200,
+      x2: 300,
+      y1: 750,
+      y2: 700,
+    };
+    const entityOverlays: Array<OverlayBioEntityRender> = [
+      {
+        color: null,
+        height: 100,
+        hexColor: '#0000001a',
+        id: '3',
+        modelId: 0,
+        overlayId: 1,
+        type: 'submap-link',
+        value: -0.43,
+        width: 100,
+        x1: 200,
+        x2: 300,
+        y1: 750,
+        y2: 700,
+      },
+    ];
+
+    const index = 1;
+    const result = calculateOverlayDimensions(overlay, index, 4, 100, entityOverlays);
+
+    expect(result.height).toEqual(75);
+    expect(result.y1).toEqual(entityOverlays[index - 1].y1 + 75);
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7ac9819ca24c4d360fbc2090de13a1c873d3852c
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions.ts
@@ -0,0 +1,20 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+
+export default function calculateOverlayDimensions(
+  overlay: OverlayBioEntityRender & { amount: number },
+  index: number,
+  totalAmount: number,
+  totalHeight: number,
+  entityOverlays: Array<OverlayBioEntityRender>,
+): OverlayBioEntityRender {
+  const ratio = overlay.amount / totalAmount;
+  const overlayHeight = ratio * totalHeight;
+  const overlayEntity = { ...overlay, height: overlayHeight };
+  if (index !== 0) {
+    overlayEntity.y2 = entityOverlays[index - 1].y1;
+  }
+  overlayEntity.y1 = overlayEntity.y2 + overlayHeight;
+
+  return overlayEntity;
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e19c1bfc632f4a3f4e78a92b21d3aa8c9da615f0
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle.test.ts
@@ -0,0 +1,66 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import findMatchingSubmapLinkRectangle from './findMatchingSubmapLinkRectangle';
+
+describe('findMatchingSubmapLinkRectangle', () => {
+  const elements: Array<OverlayBioEntityRender & { amount: number }> = [
+    {
+      amount: 1,
+      color: null,
+      height: 50,
+      hexColor: '#0000001a',
+      id: '3',
+      modelId: 0,
+      overlayId: 1,
+      type: 'submap-link',
+      value: -0.43,
+      width: 100,
+      x1: 200,
+      x2: 300,
+      y1: 750,
+      y2: 700,
+    },
+  ];
+
+  it('should find a matching submap link rectangle by value or color', () => {
+    const overlayBioEntity: OverlayBioEntityRender = {
+      color: null,
+      height: 50,
+      hexColor: '#0000001a',
+      id: '3',
+      modelId: 0,
+      overlayId: 1,
+      type: 'submap-link',
+      value: -0.43,
+      width: 100,
+      x1: 200,
+      x2: 300,
+      y1: 750,
+      y2: 700,
+    };
+
+    const result = findMatchingSubmapLinkRectangle(elements, overlayBioEntity);
+    expect(result).toEqual(elements[0]);
+  });
+
+  it('should return undefined if no matching element is found', () => {
+    const overlayBioEntity: OverlayBioEntityRender = {
+      color: null,
+      height: 50,
+      hexColor: '#0000001a',
+      id: '3',
+      modelId: 0,
+      overlayId: 1,
+      type: 'submap-link',
+      value: 0.21,
+      width: 100,
+      x1: 200,
+      x2: 300,
+      y1: 750,
+      y2: 700,
+    };
+
+    const result = findMatchingSubmapLinkRectangle(elements, overlayBioEntity);
+    expect(result).toBeUndefined();
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle.ts
new file mode 100644
index 0000000000000000000000000000000000000000..25305cc3f6977796f3f02d0c685effe6f256f6c5
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle.ts
@@ -0,0 +1,19 @@
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+
+export default function findMatchingSubmapLinkRectangle(
+  elements: Array<OverlayBioEntityRender & { amount: number }>,
+  overlayBioEntity: OverlayBioEntityRender,
+): (OverlayBioEntityRender & { amount: number }) | undefined {
+  return elements.find(element => {
+    const hasAllRequiredValueProperties = element.value && overlayBioEntity.value;
+    const isValueEqual = hasAllRequiredValueProperties && element.value === overlayBioEntity.value;
+
+    const hasAllRequiredColorProperties = element.color && overlayBioEntity.color;
+    const isColorEqual =
+      hasAllRequiredColorProperties &&
+      element.color?.alpha === overlayBioEntity?.color?.alpha &&
+      element.color?.rgb === overlayBioEntity?.color?.rgb;
+
+    return Boolean(isValueEqual || isColorEqual);
+  });
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e9fef8cf2f1ab61e5462f4e5a9b2f667492c0b71
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays.test.ts
@@ -0,0 +1,60 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import groupOverlayEntities from './groupOverlayEntities';
+
+describe('groupOverlays', () => {
+  it('should group overlay entities correctly by overlayId, value, and color', () => {
+    const overlayBioEntities: Array<OverlayBioEntityRender> = [
+      {
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '1',
+        modelId: 0,
+        overlayId: 1,
+        type: 'submap-link',
+        value: 0.1,
+        width: 100,
+        x1: 1200,
+        x2: 1300,
+        y1: 550,
+        y2: 500,
+      },
+      {
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '1',
+        modelId: 0,
+        overlayId: 1,
+        type: 'submap-link',
+        value: 0.1,
+        width: 100,
+        x1: 1200,
+        x2: 1300,
+        y1: 550,
+        y2: 500,
+      },
+      {
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '3',
+        modelId: 0,
+        overlayId: 2,
+        type: 'submap-link',
+        value: -0.43,
+        width: 100,
+        x1: 200,
+        x2: 300,
+        y1: 750,
+        y2: 700,
+      },
+    ];
+
+    const result = groupOverlayEntities(overlayBioEntities);
+    expect(result['1'][0].amount).toBe(2);
+    expect(result['2'][0].amount).toBe(1);
+    expect(result['3']).toBeUndefined();
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8cc7c0043eabf5328a350603e63131357a83f452
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/getOverlays.ts
@@ -0,0 +1,26 @@
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import groupOverlayEntities from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities';
+import processOverlayGroupedElements from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements';
+
+export default function getOverlays(
+  groupedOverlays: Record<string, Array<OverlayBioEntityRender>>,
+  getColor: GetOverlayBioEntityColorByAvailableProperties,
+): Record<string, Array<OverlayBioEntityRender>> {
+  const resultEntityOverlays: Record<string, Array<OverlayBioEntityRender>> = {};
+
+  Object.entries(groupedOverlays).forEach(([key, overlayBioEntities]) => {
+    const entityOverlays: Array<OverlayBioEntityRender> = [];
+    if (!resultEntityOverlays[key]) {
+      resultEntityOverlays[key] = [];
+    }
+
+    const groupedElements = groupOverlayEntities(overlayBioEntities);
+
+    processOverlayGroupedElements(groupedElements, entityOverlays, getColor);
+
+    resultEntityOverlays[key].push(...entityOverlays);
+  });
+
+  return resultEntityOverlays;
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1f58872b69f34f21e02621ca5d633ac858712d7c
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities.test.ts
@@ -0,0 +1,60 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import groupOverlayEntities from './groupOverlayEntities';
+
+describe('groupOverlayEntities', () => {
+  it('should group overlay entities correctly by overlayId, value, and color', () => {
+    const overlayBioEntities: Array<OverlayBioEntityRender> = [
+      {
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '1',
+        modelId: 0,
+        overlayId: 0,
+        type: 'submap-link',
+        value: 0.1,
+        width: 100,
+        x1: 1200,
+        x2: 1300,
+        y1: 550,
+        y2: 500,
+      },
+      {
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '2',
+        modelId: 0,
+        overlayId: 0,
+        type: 'submap-link',
+        value: 0.1,
+        width: 100,
+        x1: 1200,
+        x2: 1300,
+        y1: 550,
+        y2: 500,
+      },
+      {
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '3',
+        modelId: 0,
+        overlayId: 1,
+        type: 'submap-link',
+        value: -0.43,
+        width: 100,
+        x1: 200,
+        x2: 300,
+        y1: 750,
+        y2: 700,
+      },
+    ];
+    const result = groupOverlayEntities(overlayBioEntities);
+
+    expect(result['0'][0].amount).toBe(2);
+    expect(result['1'][0].amount).toBe(1);
+    expect(result['2']).toBeUndefined();
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities.ts
new file mode 100644
index 0000000000000000000000000000000000000000..984574cfe4b7379ef61f6ff6c592b2ccb32a0f5d
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/groupOverlayEntities.ts
@@ -0,0 +1,34 @@
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import findMatchingSubmapLinkRectangle from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/findMatchingSubmapLinkRectangle';
+import { OverlayBioEntityGroupedElementsType } from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+
+export default function groupOverlayEntities(
+  overlayBioEntities: Array<OverlayBioEntityRender>,
+): OverlayBioEntityGroupedElementsType {
+  const groupedElements: OverlayBioEntityGroupedElementsType = {};
+
+  overlayBioEntities.forEach(overlayBioEntity => {
+    if (overlayBioEntity.type !== 'submap-link') {
+      return;
+    }
+    if (!groupedElements[overlayBioEntity.overlayId]) {
+      groupedElements[overlayBioEntity.overlayId] = [];
+    }
+
+    const matchedElement = findMatchingSubmapLinkRectangle(
+      groupedElements[overlayBioEntity.overlayId],
+      overlayBioEntity,
+    );
+
+    if (!matchedElement) {
+      groupedElements[overlayBioEntity.overlayId].push({
+        ...overlayBioEntity,
+        amount: 1,
+      });
+    } else {
+      matchedElement.amount += 1;
+    }
+  });
+
+  return groupedElements;
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..680002ea1ba899f15df25fe9af4fe8227aae5c1c
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements.test.ts
@@ -0,0 +1,55 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import processOverlayGroupedElements from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements';
+import { OverlayBioEntityGroupedElementsType } from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+
+describe('processOverlayGroupedElements', () => {
+  it('should correctly process overlay grouped elements and add to entityOverlays', () => {
+    const groupedElements = {
+      '1': [
+        {
+          amount: 1,
+          color: null,
+          height: 50,
+          hexColor: '#0000001a',
+          id: '5',
+          modelId: 0,
+          overlayId: 1,
+          type: 'submap-link',
+          value: 0.1,
+          width: 100,
+          x1: 1200,
+          x2: 1300,
+          y1: 550,
+          y2: 500,
+        },
+        {
+          amount: 1,
+          color: null,
+          height: 50,
+          hexColor: '#0000001a',
+          id: '5',
+          modelId: 0,
+          overlayId: 1,
+          type: 'submap-link',
+          value: -0.43,
+          width: 100,
+          x1: 200,
+          x2: 300,
+          y1: 750,
+          y2: 700,
+        },
+      ],
+    } as OverlayBioEntityGroupedElementsType;
+
+    const entityOverlays: Array<OverlayBioEntityRender> = [];
+    const getColor: GetOverlayBioEntityColorByAvailableProperties = jest.fn(() => 'color');
+
+    processOverlayGroupedElements(groupedElements, entityOverlays, getColor);
+
+    expect(entityOverlays.length).toBe(2);
+    expect(entityOverlays[0].height).toEqual(25);
+    expect(entityOverlays[1].height).toEqual(25);
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7e2a9b434f656123cf48262b0c6ae547f83903b2
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/processOverlayGroupedElements.ts
@@ -0,0 +1,35 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import sortElementOverlayByColor from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor';
+import calculateOverlayDimensions from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/calculateOverlayDimensions';
+import { OverlayBioEntityGroupedElementsType } from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+
+export default function processOverlayGroupedElements(
+  groupedElements: OverlayBioEntityGroupedElementsType,
+  entityOverlays: Array<OverlayBioEntityRender>,
+  getColor: GetOverlayBioEntityColorByAvailableProperties,
+): void {
+  Object.values(groupedElements).forEach(elementOverlay => {
+    const overlaysPerGroup: Array<OverlayBioEntityRender> = [];
+    sortElementOverlayByColor(elementOverlay, getColor);
+
+    const totalHeight = elementOverlay[0].height;
+    const totalAmount = elementOverlay.reduce(
+      (accumulator: number, overlay) => accumulator + overlay.amount,
+      0,
+    );
+
+    elementOverlay.forEach((overlay, index) => {
+      const overlayEntity = calculateOverlayDimensions(
+        overlay,
+        index,
+        totalAmount,
+        totalHeight,
+        overlaysPerGroup,
+      );
+      overlaysPerGroup.push(overlayEntity);
+    });
+    entityOverlays.push(...overlaysPerGroup);
+  });
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1f39cc2aa9d26b8460f694daf3fe95ee6e600af2
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor.test.ts
@@ -0,0 +1,51 @@
+/* eslint-disable no-magic-numbers */
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import sortElementOverlayByColor from './sortElementOverlayByColor';
+
+describe('sortElementOverlayByColor', () => {
+  it('should sort elements by color', () => {
+    const elementOverlay: Array<OverlayBioEntityRender & { amount: number }> = [
+      {
+        amount: 1,
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '5',
+        modelId: 0,
+        overlayId: 0,
+        type: 'submap-link',
+        value: 0.1,
+        width: 100,
+        x1: 1200,
+        x2: 1300,
+        y1: 550,
+        y2: 500,
+      },
+      {
+        amount: 1,
+        color: null,
+        height: 50,
+        hexColor: '#0000001a',
+        id: '2',
+        modelId: 0,
+        overlayId: 1,
+        type: 'submap-link',
+        value: -0.43,
+        width: 100,
+        x1: 200,
+        x2: 300,
+        y1: 750,
+        y2: 700,
+      },
+    ];
+
+    const getColor: GetOverlayBioEntityColorByAvailableProperties = jest.fn(
+      entity => `#A633C${entity.id}`,
+    );
+    sortElementOverlayByColor(elementOverlay, getColor);
+
+    expect(elementOverlay[0].id).toEqual('2');
+    expect(elementOverlay[1].id).toEqual('5');
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b185b6373eecc6a0d06e364f053b8565454031db
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/overlay/sortElementOverlayByColor.ts
@@ -0,0 +1,20 @@
+/* eslint-disable no-magic-numbers */
+import { GetOverlayBioEntityColorByAvailableProperties } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor';
+import { OverlayBioEntityRender } from '@/types/OLrendering';
+
+export default function sortElementOverlayByColor(
+  elementOverlay: Array<OverlayBioEntityRender & { amount: number }>,
+  getColor: GetOverlayBioEntityColorByAvailableProperties,
+): void {
+  elementOverlay.sort((a, b) => {
+    const colorA = getColor(a);
+    const colorB = getColor(b);
+    if (colorA === colorB) {
+      return 0;
+    }
+    if (colorA < colorB) {
+      return -1;
+    }
+    return 1;
+  });
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStyle.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStyle.ts
index 6c98bf802207863a86679b0f3a9e43c95f80d0f3..96083434e3f49d298495931f119bcd3b96f314b7 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStyle.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/style/getStyle.ts
@@ -19,8 +19,8 @@ export default function getStyle({
   zIndex = 1,
 }: {
   geometry?: Geometry;
-  borderColor?: Color;
-  fillColor?: Color;
+  borderColor?: Color | string;
+  fillColor?: Color | string;
   lineWidth?: number;
   lineDash?: Array<number>;
   zIndex?: number;
@@ -28,11 +28,11 @@ export default function getStyle({
   return new Style({
     geometry,
     stroke: getStroke({
-      color: rgbToHex(borderColor),
+      color: typeof borderColor === 'string' ? borderColor : rgbToHex(borderColor),
       width: lineWidth,
       lineDash,
     }),
-    fill: getFill({ color: rgbToHex(fillColor) }),
+    fill: getFill({ color: typeof fillColor === 'string' ? fillColor : rgbToHex(fillColor) }),
     zIndex,
   });
 }
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts
index e11025d81b6401b8b26fc0879d8b51d255a1e034..a6ca120fdf276150bbf8e84435d36d82d63d46c6 100644
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayGeometryFeature.ts
@@ -5,7 +5,10 @@ import { Fill, Stroke, Style } from 'ol/style';
 import { createFeatureFromExtent } from './createFeatureFromExtent';
 
 const getBioEntityOverlayFeatureStyle = (color: string): Style =>
-  new Style({ fill: new Fill({ color }), stroke: new Stroke({ color: 'black', width: 1 }) });
+  new Style({
+    fill: new Fill({ color }),
+    stroke: new Stroke({ color: 'black', width: 1 }),
+  });
 
 export const createOverlayGeometryFeature = (
   [xMin, yMin, xMax, yMax]: number[],
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
index 46d7190721fbb14929d055cdeead41208bde90d3..0ac575a40485c369e3f791e2a6af4e27b2671075 100644
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useGetOverlayColor.ts
@@ -14,7 +14,9 @@ import { getHexStringColorFromRGBIntWithAlpha } from '@/utils/convert/getHexStri
 import { getHexTricolorGradientColorWithAlpha } from '@/utils/convert/getHexTricolorGradientColorWithAlpha';
 import { useCallback, useMemo } from 'react';
 
-type GetOverlayBioEntityColorByAvailableProperties = (entity: OverlayBioEntityRender) => string;
+export type GetOverlayBioEntityColorByAvailableProperties = (
+  entity: OverlayBioEntityRender,
+) => string;
 
 type UseTriColorLerpReturn = {
   getOverlayBioEntityColorByAvailableProperties: GetOverlayBioEntityColorByAvailableProperties;
diff --git a/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts b/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts
index 107add31699aceb508557e10d9b54420c4d5171a..020e6ae987dd7d3c16964637ee8ef92bf4fe0bd4 100644
--- a/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts
+++ b/src/components/Map/MapViewer/utils/config/overlaysLayer/useOverlayFeatures.ts
@@ -22,6 +22,7 @@ export const useOverlayFeatures = (): Feature<Polygon>[] | Feature<SimpleGeometr
   const overlaysOrder = useAppSelector(getOverlayOrderSelector);
   const currentMarkers = useAppSelector(markersSufraceOfCurrentMapDataSelector);
   const markersRender = parseSurfaceMarkersToBioEntityRender(currentMarkers);
+
   const bioEntities = useBioEntitiesWithSubmapsLinks();
 
   const markersFeatures = useMemo(
diff --git a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
index 75d8c838d5ae06005c42beacd068044fe7ff7dbc..641b537da8e0fd922993eadc7c3e2f0291d8dc0c 100644
--- a/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer.ts
@@ -11,7 +11,7 @@ import Feature from 'ol/Feature';
 import { Geometry } from 'ol/geom';
 import VectorLayer from 'ol/layer/Vector';
 import VectorSource from 'ol/source/Vector';
-import { useCallback, useMemo } from 'react';
+import { useCallback, useEffect, useMemo } from 'react';
 import { useSelector } from 'react-redux';
 import { getBioEntitiesFeatures } from './getBioEntitiesFeatures';
 import { getMarkersFeatures } from './getMarkersFeatures';
@@ -67,19 +67,18 @@ export const useOlMapPinsLayer = (): VectorLayer<VectorSource<Feature<Geometry>>
     ],
   );
 
-  const vectorSource = useMemo(() => {
-    return new VectorSource({
-      features: [...elementsFeatures],
-    });
-  }, [elementsFeatures]);
+  const vectorSource = useMemo(() => new VectorSource(), []);
 
-  const pinsLayer = useMemo(
+  useEffect(() => {
+    vectorSource.clear();
+    vectorSource.addFeatures(elementsFeatures);
+  }, [elementsFeatures, vectorSource]);
+
+  return useMemo(
     () =>
       new VectorLayer({
         source: vectorSource,
       }),
     [vectorSource],
   );
-
-  return pinsLayer;
 };
diff --git a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
index c564b6622773e5e8b26812bbbab2ea20cf757dc3..a6350f6357cf3b6d6bcd8acedbcca8099010e5d1 100644
--- a/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -6,15 +6,15 @@ import { MarkerLine, Reaction } from '@/types/models';
 import { LinePoint } from '@/types/reactions';
 import { usePointToProjection } from '@/utils/map/usePointToProjection';
 import { Feature } from 'ol';
-import { SimpleGeometry } from 'ol/geom';
 import VectorLayer from 'ol/layer/Vector';
 import VectorSource from 'ol/source/Vector';
 import Fill from 'ol/style/Fill';
 import Stroke from 'ol/style/Stroke';
 import Style from 'ol/style/Style';
-import { useMemo } from 'react';
+import { useEffect, useMemo } from 'react';
 import { useSelector } from 'react-redux';
 import { createOverlayLineFeature } from '@/components/Map/MapViewer/utils/config/overlaysLayer/createOverlayLineFeature';
+import { Geometry } from 'ol/geom';
 import { getLineFeature } from './getLineFeature';
 
 const getLinePoints = ({ start, end }: Pick<MarkerLine, 'start' | 'end'>): LinePoint => [
@@ -25,7 +25,7 @@ const getLinePoints = ({ start, end }: Pick<MarkerLine, 'start' | 'end'>): LineP
 const getReactionsLines = (reactions: Reaction[]): LinePoint[] =>
   reactions.map(({ lines }) => lines.map(getLinePoints)).flat();
 
-export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<SimpleGeometry>>> => {
+export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<Geometry>>> => {
   const pointToProjection = usePointToProjection();
   const reactions = useSelector(allReactionsSelectorOfCurrentMap);
   const markers = useSelector(markersLinesCurrentMapDataSelector);
@@ -47,13 +47,15 @@ export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<Simpl
     [markers, pointToProjection],
   );
 
-  const vectorSource = useMemo(() => {
-    return new VectorSource({
-      features: [...reactionsLinesFeatures, ...markerLinesFeatures],
-    });
-  }, [reactionsLinesFeatures, markerLinesFeatures]);
+  const vectorSource = useMemo(() => new VectorSource(), []);
 
-  const reactionsLayer = useMemo(
+  useEffect(() => {
+    vectorSource.clear();
+    vectorSource.addFeatures(reactionsLinesFeatures);
+    vectorSource.addFeatures(markerLinesFeatures);
+  }, [reactionsLinesFeatures, markerLinesFeatures, vectorSource]);
+
+  return useMemo(
     () =>
       new VectorLayer({
         source: vectorSource,
@@ -64,6 +66,4 @@ export const useOlMapReactionsLayer = (): VectorLayer<VectorSource<Feature<Simpl
       }),
     [vectorSource],
   );
-
-  return reactionsLayer;
 };
diff --git a/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.test.ts b/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.test.ts
index ded469b28450cc91d57fd1cc0410b380e9de994c..852f8093ee021e4863f614c8ec194cd484a7ff0e 100644
--- a/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.test.ts
+++ b/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.test.ts
@@ -88,11 +88,4 @@ describe('useOlMapCommonLayers - util', () => {
     expect(result[2]).toBeInstanceOf(VectorLayer);
     expect(result[2].getSourceState()).toBe('ready');
   });
-
-  it('should return valid VectorLayer instance [4]', () => {
-    const result = getRenderedHookResults();
-
-    expect(result[3]).toBeInstanceOf(VectorLayer);
-    expect(result[3].getSourceState()).toBe('ready');
-  });
 });
diff --git a/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.ts b/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.ts
index bca964e7fd5f23b3ac90b2be4eb6e5e2640fb2f4..ad70201bb3a2d1eb82a70eff6229a098f885bf78 100644
--- a/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.ts
+++ b/src/components/Map/MapViewer/utils/config/useOlMapCommonLayers.ts
@@ -1,15 +1,16 @@
 /* eslint-disable no-magic-numbers */
-import { useOlMapOverlaysLayer } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useOlMapOverlaysLayer';
 import { useOlMapPinsLayer } from '@/components/Map/MapViewer/utils/config/pinsLayer/useOlMapPinsLayer';
 import { useOlMapReactionsLayer } from '@/components/Map/MapViewer/utils/config/reactionsLayer/useOlMapReactionsLayer';
 import { useOlMapCommentsLayer } from '@/components/Map/MapViewer/utils/config/commentsLayer/useOlMapCommentsLayer';
+import { useMemo } from 'react';
 import { MapConfig } from '../../MapViewer.types';
 
 export const useOlMapCommonLayers = (): MapConfig['layers'] => {
-  const overlaysLayer = useOlMapOverlaysLayer();
   const pinsLayer = useOlMapPinsLayer();
   const reactionsLayer = useOlMapReactionsLayer();
   const commentsLayer = useOlMapCommentsLayer();
 
-  return [overlaysLayer, pinsLayer, reactionsLayer, commentsLayer];
+  return useMemo(() => {
+    return [pinsLayer, reactionsLayer, commentsLayer];
+  }, [pinsLayer, reactionsLayer, commentsLayer]);
 };
diff --git a/src/components/Map/MapViewer/utils/config/useOlMapLayers.test.ts b/src/components/Map/MapViewer/utils/config/useOlMapLayers.test.ts
index c0be0af81ff66c3ec74e7d2ebb0825c3df17e38e..ffcd6326cfbef787a7561c27b6b4a7333a731bde 100644
--- a/src/components/Map/MapViewer/utils/config/useOlMapLayers.test.ts
+++ b/src/components/Map/MapViewer/utils/config/useOlMapLayers.test.ts
@@ -5,6 +5,7 @@ import { renderHook } from '@testing-library/react';
 import BaseLayer from 'ol/layer/Base';
 import TileLayer from 'ol/layer/Tile';
 import React from 'react';
+import VectorLayer from 'ol/layer/Vector';
 import { useOlMapLayers } from './useOlMapLayers';
 
 const useRefValue = {
@@ -74,4 +75,11 @@ describe('useOlMapLayers - util', () => {
     expect(result[0]).toBeInstanceOf(TileLayer);
     expect(result[0].getSourceState()).toBe('ready');
   });
+
+  it('should return valid VectorLayer instance [2]', () => {
+    const result = getRenderedHookResults();
+
+    expect(result[1]).toBeInstanceOf(VectorLayer);
+    expect(result[1].getSourceState()).toBe('ready');
+  });
 });
diff --git a/src/components/Map/MapViewer/utils/config/useOlMapLayers.ts b/src/components/Map/MapViewer/utils/config/useOlMapLayers.ts
index f05f8c9d85e764a7074a9e35d98f5d695a65ae92..10169c987bf91c24241479ea9a1acb666bd7b64a 100644
--- a/src/components/Map/MapViewer/utils/config/useOlMapLayers.ts
+++ b/src/components/Map/MapViewer/utils/config/useOlMapLayers.ts
@@ -1,9 +1,11 @@
 /* eslint-disable no-magic-numbers */
+import { useOlMapOverlaysLayer } from '@/components/Map/MapViewer/utils/config/overlaysLayer/useOlMapOverlaysLayer';
 import { MapConfig } from '../../MapViewer.types';
 import { useOlMapTileLayer } from './useOlMapTileLayer';
 
 export const useOlMapLayers = (): MapConfig['layers'] => {
+  const overlaysLayer = useOlMapOverlaysLayer();
   const tileLayer = useOlMapTileLayer();
 
-  return [tileLayer];
+  return [tileLayer, overlaysLayer];
 };
diff --git a/src/utils/useDebouncedValue.test.ts b/src/utils/useDebouncedValue.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d0691ad24ba8d165c5f9c55ddde375a2df98d982
--- /dev/null
+++ b/src/utils/useDebouncedValue.test.ts
@@ -0,0 +1,50 @@
+/* eslint-disable no-magic-numbers */
+import { act, renderHook } from '@testing-library/react';
+import useDebouncedValue from './useDebouncedValue';
+
+jest.useFakeTimers();
+
+describe('useDebouncedValue', () => {
+  it('should return the initial value immediately', () => {
+    const { result } = renderHook(() => useDebouncedValue('initial', 500));
+    expect(result.current).toBe('initial');
+  });
+
+  it('should update the value after the specified delay', () => {
+    const { result, rerender } = renderHook(({ value, delay }) => useDebouncedValue(value, delay), {
+      initialProps: { value: 'initial', delay: 500 },
+    });
+
+    rerender({ value: 'updated', delay: 500 });
+
+    expect(result.current).toBe('initial');
+
+    act(() => {
+      jest.advanceTimersByTime(500);
+    });
+
+    expect(result.current).toBe('updated');
+  });
+
+  it('should clear the timeout if value changes quickly', () => {
+    const { result, rerender } = renderHook(({ value, delay }) => useDebouncedValue(value, delay), {
+      initialProps: { value: 'initial', delay: 500 },
+    });
+
+    rerender({ value: 'intermediate', delay: 500 });
+
+    act(() => {
+      jest.advanceTimersByTime(300);
+    });
+
+    expect(result.current).toBe('initial');
+
+    rerender({ value: 'final', delay: 500 });
+
+    act(() => {
+      jest.advanceTimersByTime(500);
+    });
+
+    expect(result.current).toBe('final');
+  });
+});
diff --git a/src/utils/useDebouncedValue.ts b/src/utils/useDebouncedValue.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5d52da6b550e3aef6c118a1bb5a1d6e78548448d
--- /dev/null
+++ b/src/utils/useDebouncedValue.ts
@@ -0,0 +1,15 @@
+import { useEffect, useState } from 'react';
+
+export default function useDebouncedValue<T>(value: T, delay: number): T {
+  const [debouncedValue, setDebouncedValue] = useState(value);
+
+  useEffect(() => {
+    const handler = setTimeout(() => setDebouncedValue(value), delay);
+
+    return () => {
+      clearTimeout(handler);
+    };
+  }, [value, delay]);
+
+  return debouncedValue;
+}