diff --git a/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants.ts b/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants.ts
index d038cdf39f083a21b48dad564fcd513094c0adc2..31cae9f134bb5f8d1f4a3d9df4570604782aaa4f 100644
--- a/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants.ts
@@ -1,4 +1,10 @@
-import { ColorObject } from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+import {
+  ColorObject,
+  EllipseCenter,
+  EllipseRadius,
+  ShapeCurvePoint,
+  ShapePoint,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
 
 export const WHITE_COLOR: ColorObject = {
   alpha: 255,
@@ -9,3 +15,153 @@ export const BLACK_COLOR: ColorObject = {
   alpha: 255,
   rgb: -16777216,
 };
+
+export const COMPARTMENT_SQUARE_POINTS: Array<ShapePoint | ShapeCurvePoint> = [
+  {
+    type: 'REL_ABS_POINT',
+    absoluteX: 10.0,
+    absoluteY: 0.0,
+    relativeX: 0.0,
+    relativeY: 0.0,
+    relativeHeightForX: null,
+    relativeWidthForY: null,
+  },
+  {
+    type: 'REL_ABS_POINT',
+    absoluteX: -10.0,
+    absoluteY: 0.0,
+    relativeX: 100.0,
+    relativeY: 0.0,
+    relativeHeightForX: null,
+    relativeWidthForY: null,
+  },
+  {
+    type: 'REL_ABS_BEZIER_POINT',
+    absoluteX1: 0.0,
+    absoluteY1: 10.0,
+    relativeX1: 100.0,
+    relativeY1: 0.0,
+    relativeHeightForX1: null,
+    relativeWidthForY1: null,
+    absoluteX2: -5.0,
+    absoluteY2: 0.0,
+    relativeX2: 100.0,
+    relativeY2: 0.0,
+    relativeHeightForX2: null,
+    relativeWidthForY2: null,
+    absoluteX3: 0.0,
+    absoluteY3: 5.0,
+    relativeX3: 100.0,
+    relativeY3: 0.0,
+    relativeHeightForX3: null,
+    relativeWidthForY3: null,
+  },
+  {
+    type: 'REL_ABS_POINT',
+    absoluteX: 0.0,
+    absoluteY: -10.0,
+    relativeX: 100.0,
+    relativeY: 100.0,
+    relativeHeightForX: null,
+    relativeWidthForY: null,
+  },
+  {
+    type: 'REL_ABS_BEZIER_POINT',
+    absoluteX1: -10.0,
+    absoluteY1: 0.0,
+    relativeX1: 100.0,
+    relativeY1: 100.0,
+    relativeHeightForX1: null,
+    relativeWidthForY1: null,
+    absoluteX2: 0.0,
+    absoluteY2: -5.0,
+    relativeX2: 100.0,
+    relativeY2: 100.0,
+    relativeHeightForX2: null,
+    relativeWidthForY2: null,
+    absoluteX3: -5.0,
+    absoluteY3: 0.0,
+    relativeX3: 100.0,
+    relativeY3: 100.0,
+    relativeHeightForX3: null,
+    relativeWidthForY3: null,
+  },
+  {
+    type: 'REL_ABS_POINT',
+    absoluteX: 10.0,
+    absoluteY: 0.0,
+    relativeX: 0.0,
+    relativeY: 100.0,
+    relativeHeightForX: null,
+    relativeWidthForY: null,
+  },
+  {
+    type: 'REL_ABS_BEZIER_POINT',
+    absoluteX1: 0.0,
+    absoluteY1: -10.0,
+    relativeX1: 0.0,
+    relativeY1: 100.0,
+    relativeHeightForX1: null,
+    relativeWidthForY1: null,
+    absoluteX2: 5.0,
+    absoluteY2: 0.0,
+    relativeX2: 0.0,
+    relativeY2: 100.0,
+    relativeHeightForX2: null,
+    relativeWidthForY2: null,
+    absoluteX3: 0.0,
+    absoluteY3: -5.0,
+    relativeX3: 0.0,
+    relativeY3: 100.0,
+    relativeHeightForX3: null,
+    relativeWidthForY3: null,
+  },
+  {
+    type: 'REL_ABS_POINT',
+    absoluteX: 0.0,
+    absoluteY: 10.0,
+    relativeX: 0.0,
+    relativeY: 0.0,
+    relativeHeightForX: null,
+    relativeWidthForY: null,
+  },
+  {
+    type: 'REL_ABS_BEZIER_POINT',
+    absoluteX1: 10.0,
+    absoluteY1: 0.0,
+    relativeX1: 0.0,
+    relativeY1: 0.0,
+    relativeHeightForX1: null,
+    relativeWidthForY1: null,
+    absoluteX2: 0.0,
+    absoluteY2: 5.0,
+    relativeX2: 0.0,
+    relativeY2: 0.0,
+    relativeHeightForX2: null,
+    relativeWidthForY2: null,
+    absoluteX3: 5.0,
+    absoluteY3: 0.0,
+    relativeX3: 0.0,
+    relativeY3: 0.0,
+    relativeHeightForX3: null,
+    relativeWidthForY3: null,
+  },
+];
+
+export const COMPARTMENT_CIRCLE_CENTER: EllipseCenter = {
+  type: 'REL_ABS_POINT',
+  absoluteX: 0.0,
+  absoluteY: 0.0,
+  relativeX: 50.0,
+  relativeY: 50.0,
+  relativeHeightForX: null,
+  relativeWidthForY: null,
+};
+
+export const COMPARTMENT_CIRCLE_RADIUS: EllipseRadius = {
+  type: 'REL_ABS_RADIUS',
+  absoluteX: 0.0,
+  absoluteY: 0.0,
+  relativeX: 50.0,
+  relativeY: 50.0,
+};
diff --git a/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts b/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts
index 78e365e3a1fc14eccc28c28ec737740f1f77519b..4c5ee626be061e6f81432f40e596f75e4a1d0c4c 100644
--- a/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/MapViewerVector.types.ts
@@ -45,3 +45,21 @@ export type ShapeCurvePoint = {
   relativeHeightForX3: number | null;
   relativeWidthForY3: number | null;
 };
+
+export type EllipseCenter = {
+  type: string;
+  absoluteX: number;
+  absoluteY: number;
+  relativeX: number;
+  relativeY: number;
+  relativeHeightForX: number | null;
+  relativeWidthForY: number | null;
+};
+
+export type EllipseRadius = {
+  type: string;
+  absoluteX: number;
+  absoluteY: number;
+  relativeX: number;
+  relativeY: number;
+};
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 60d5330aab6cdb1c12abe8685333ad7a20cc1bdb..6e52b495d0a18d95ad94e2cbe5a104b3e7d48178 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/config/reactionsLayer/useOlMapReactionsLayer.ts
@@ -16,6 +16,8 @@ import { modelElementsSelector } from '@/redux/modelElements/modelElements.selec
 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/CompartmentSquare';
+import CompartmentCircle from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle';
 
 export const useOlMapReactionsLayer = ({
   mapInstance,
@@ -33,10 +35,10 @@ export const useOlMapReactionsLayer = ({
   const shapes = useSelector(bioShapesSelector);
   const lineTypes = useSelector(lineTypesSelector);
 
-  const elements: Array<MapElement> = useMemo(() => {
+  const elements: Array<MapElement | CompartmentCircle | CompartmentSquare> = useMemo(() => {
     if (!modelElements || !shapes) return [];
 
-    const validElements: Array<MapElement> = [];
+    const validElements: Array<MapElement | CompartmentCircle | CompartmentSquare> = [];
     modelElements.content.forEach(element => {
       const shape = shapes.find(bioShape => bioShape.sboTerm === element.sboTerm);
       if (shape) {
@@ -60,6 +62,7 @@ export const useOlMapReactionsLayer = ({
             nameVerticalAlign: element.nameVerticalAlign as VerticalAlign,
             nameHorizontalAlign: element.nameHorizontalAlign as HorizontalAlign,
             text: element.name,
+            fontSize: element.fontSize,
             pointToProjection,
             mapInstance,
             modifications: element.modificationResidues,
@@ -67,6 +70,35 @@ export const useOlMapReactionsLayer = ({
             bioShapes: shapes,
           }),
         );
+      } else if (element.sboTerm === 'SBO:0000290') {
+        const compartmentProps = {
+          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));
+        }
       }
     });
     return validElements;
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/BaseMultiPolygon.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/BaseMultiPolygon.ts
new file mode 100644
index 0000000000000000000000000000000000000000..62ed6ea9181ddf2187a3c32e8ac1fd5e91324c2e
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/BaseMultiPolygon.ts
@@ -0,0 +1,178 @@
+/* eslint-disable no-magic-numbers */
+import Polygon from 'ol/geom/Polygon';
+import { Style } from 'ol/style';
+import Feature, { FeatureLike } from 'ol/Feature';
+import { MultiPolygon } from 'ol/geom';
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import {
+  ColorObject,
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+import { MapInstance } from '@/types/map';
+import getText from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getText';
+import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/rgbToHex';
+
+export interface BaseMapElementProps {
+  x: number;
+  y: number;
+  width: number;
+  height: number;
+  zIndex: number;
+  text: string;
+  fontSize: number;
+  nameX: number;
+  nameY: number;
+  nameWidth: number;
+  nameHeight: number;
+  fontColor: ColorObject;
+  nameVerticalAlign: VerticalAlign;
+  nameHorizontalAlign: HorizontalAlign;
+  fillColor: ColorObject;
+  borderColor: ColorObject;
+  pointToProjection: UsePointToProjectionResult;
+}
+
+export default abstract class BaseMultiPolygon {
+  x: number;
+
+  y: number;
+
+  width: number;
+
+  height: number;
+
+  zIndex: number;
+
+  text: string;
+
+  fontSize: number;
+
+  nameX: number;
+
+  nameY: number;
+
+  nameWidth: number;
+
+  nameHeight: number;
+
+  fontColor: ColorObject;
+
+  nameVerticalAlign: VerticalAlign;
+
+  nameHorizontalAlign: HorizontalAlign;
+
+  fillColor: ColorObject;
+
+  borderColor: ColorObject;
+
+  polygons: Array<Polygon> = [];
+
+  styles: Array<Style> = [];
+
+  polygonsTexts: Array<string> = [];
+
+  multiPolygonFeature: Feature = new Feature();
+
+  pointToProjection: UsePointToProjectionResult;
+
+  constructor({
+    x,
+    y,
+    width,
+    height,
+    zIndex,
+    text,
+    fontSize,
+    nameX,
+    nameY,
+    nameWidth,
+    nameHeight,
+    fontColor,
+    nameVerticalAlign,
+    nameHorizontalAlign,
+    fillColor,
+    borderColor,
+    pointToProjection,
+  }: BaseMapElementProps) {
+    this.x = x;
+    this.y = y;
+    this.width = width;
+    this.height = height;
+    this.zIndex = zIndex;
+    this.text = text;
+    this.fontSize = fontSize;
+    this.nameX = nameX;
+    this.nameY = nameY;
+    this.nameWidth = nameWidth;
+    this.nameHeight = nameHeight;
+    this.fontColor = fontColor;
+    this.nameVerticalAlign = nameVerticalAlign;
+    this.nameHorizontalAlign = nameHorizontalAlign;
+    this.fillColor = fillColor;
+    this.borderColor = borderColor;
+    this.pointToProjection = pointToProjection;
+  }
+
+  protected abstract createPolygons(): void;
+
+  protected drawText(): void {
+    if (this.text) {
+      const { textCoords, textStyle } = getText({
+        text: this.text,
+        fontSize: this.fontSize,
+        x: this.nameX,
+        y: this.nameY,
+        width: this.nameWidth,
+        height: this.nameHeight,
+        color: rgbToHex(this.fontColor),
+        zIndex: this.zIndex,
+        verticalAlign: this.nameVerticalAlign,
+        horizontalAlign: this.nameHorizontalAlign,
+        pointToProjection: this.pointToProjection,
+      });
+      this.styles.push(textStyle);
+      this.polygonsTexts.push(this.text);
+      this.polygons.push(new Polygon([[textCoords, textCoords]]));
+    }
+  }
+
+  protected drawMultiPolygonFeature(mapInstance: MapInstance): void {
+    this.multiPolygonFeature = new Feature({
+      geometry: new MultiPolygon(this.polygons),
+      getTextScale: (resolution: number): number => {
+        const maxZoom = mapInstance?.getView().getMaxZoom();
+        if (maxZoom) {
+          const minResolution = mapInstance?.getView().getResolutionForZoom(maxZoom);
+          if (minResolution) {
+            return Math.round((minResolution / resolution) * 100) / 100;
+          }
+        }
+        return 1;
+      },
+    });
+
+    this.multiPolygonFeature.setStyle(this.styleFunction.bind(this));
+  }
+
+  protected styleFunction(feature: FeatureLike, resolution: number): Style | Array<Style> | void {
+    const getTextScale = feature.get('getTextScale');
+    let textScale = 1;
+    if (getTextScale instanceof Function) {
+      textScale = getTextScale(resolution);
+    }
+    let index = 0;
+    this.styles.forEach(style => {
+      if (style.getText()) {
+        if (this.fontSize * textScale > 4) {
+          style.getText()?.setScale(textScale);
+          style.getText()?.setText(this.polygonsTexts[index]);
+          index += 1;
+        } else {
+          style.getText()?.setText(undefined);
+        }
+      }
+    });
+    return this.styles;
+  }
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/Compartment.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/Compartment.ts
new file mode 100644
index 0000000000000000000000000000000000000000..deb5a5c560f97199afa9600bc6628fcfea347d83
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/Compartment.ts
@@ -0,0 +1,137 @@
+/* eslint-disable no-magic-numbers */
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import {
+  ColorObject,
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+import BaseMultiPolygon from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/BaseMultiPolygon';
+import { Coordinate } from 'ol/coordinate';
+import Polygon from 'ol/geom/Polygon';
+import { Style } from 'ol/style';
+import getFill from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getFill';
+import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/rgbToHex';
+import getStroke from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getStroke';
+import { MapInstance } from '@/types/map';
+
+export interface CompartmentProps {
+  x: number;
+  y: number;
+  width: number;
+  height: number;
+  thickness: number;
+  outerWidth: number;
+  innerWidth: number;
+  zIndex: number;
+  text: string;
+  fontSize: number;
+  nameX: number;
+  nameY: number;
+  nameWidth: number;
+  nameHeight: number;
+  fontColor: ColorObject;
+  nameVerticalAlign: VerticalAlign;
+  nameHorizontalAlign: HorizontalAlign;
+  fillColor: ColorObject;
+  borderColor: ColorObject;
+  pointToProjection: UsePointToProjectionResult;
+  mapInstance: MapInstance;
+}
+
+export default abstract class Compartment extends BaseMultiPolygon {
+  outerCoords: Array<Coordinate> = [];
+
+  innerCoords: Array<Coordinate> = [];
+
+  outerWidth: number;
+
+  innerWidth: number;
+
+  thickness: number;
+
+  constructor({
+    x,
+    y,
+    width,
+    height,
+    thickness,
+    outerWidth,
+    innerWidth,
+    zIndex,
+    text,
+    fontSize,
+    nameX,
+    nameY,
+    nameWidth,
+    nameHeight,
+    fontColor,
+    nameVerticalAlign,
+    nameHorizontalAlign,
+    fillColor,
+    borderColor,
+    pointToProjection,
+    mapInstance,
+  }: CompartmentProps) {
+    super({
+      x,
+      y,
+      width,
+      height,
+      zIndex,
+      text,
+      fontSize,
+      nameX,
+      nameY,
+      nameWidth,
+      nameHeight,
+      fontColor,
+      nameVerticalAlign,
+      nameHorizontalAlign,
+      fillColor,
+      borderColor,
+      pointToProjection,
+    });
+    this.outerWidth = outerWidth;
+    this.innerWidth = innerWidth;
+    this.thickness = thickness;
+    this.getCompartmentCoords();
+    this.createPolygons();
+    this.drawText();
+    this.drawMultiPolygonFeature(mapInstance);
+  }
+
+  protected abstract getCompartmentCoords(): void;
+
+  protected createPolygons(): void {
+    const framePolygon = new Polygon([this.outerCoords, this.innerCoords]);
+    this.styles.push(
+      new Style({
+        geometry: framePolygon,
+        fill: getFill({ color: rgbToHex({ ...this.fillColor, alpha: 128 }) }),
+        zIndex: this.zIndex,
+      }),
+    );
+    this.polygons.push(framePolygon);
+
+    const outerPolygon = new Polygon([this.outerCoords]);
+    this.styles.push(
+      new Style({
+        geometry: outerPolygon,
+        stroke: getStroke({ color: rgbToHex(this.borderColor), width: this.outerWidth }),
+        zIndex: this.zIndex,
+      }),
+    );
+    this.polygons.push(outerPolygon);
+
+    const innerPolygon = new Polygon([this.innerCoords]);
+    this.styles.push(
+      new Style({
+        geometry: innerPolygon,
+        stroke: getStroke({ color: rgbToHex(this.borderColor), width: this.innerWidth }),
+        fill: getFill({ color: rgbToHex({ ...this.fillColor, alpha: 9 }) }),
+        zIndex: this.zIndex,
+      }),
+    );
+    this.polygons.push(innerPolygon);
+  }
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cfc57c56fcbc043f6fcdb0d4ebfcf1f1e9a2185c
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle.test.ts
@@ -0,0 +1,118 @@
+/* eslint-disable no-magic-numbers */
+import { Feature, Map } from 'ol';
+import { Fill, Style, Text } from 'ol/style';
+import { Polygon, MultiPolygon } from 'ol/geom';
+import getText from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getText';
+import getMultiPolygon from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getMultiPolygon';
+import getStroke from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getStroke';
+import getFill from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getFill';
+import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/rgbToHex';
+import View from 'ol/View';
+import {
+  WHITE_COLOR,
+  BLACK_COLOR,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants';
+import CompartmentCircle, {
+  CompartmentCircleProps,
+} from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle';
+import getEllipseCoords from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getEllipseCoords';
+
+jest.mock('./getText');
+jest.mock('./getMultiPolygon');
+jest.mock('./getStroke');
+jest.mock('./getEllipseCoords');
+jest.mock('./getFill');
+jest.mock('./rgbToHex');
+
+describe('MapElement', () => {
+  let props: CompartmentCircleProps;
+
+  beforeEach(() => {
+    const dummyElement = document.createElement('div');
+    const mapInstance = new Map({
+      target: dummyElement,
+      view: new View({
+        zoom: 5,
+        minZoom: 3,
+        maxZoom: 7,
+      }),
+    });
+    props = {
+      x: 0,
+      y: 0,
+      width: 100,
+      height: 100,
+      zIndex: 1,
+      fillColor: WHITE_COLOR,
+      borderColor: BLACK_COLOR,
+      fontColor: BLACK_COLOR,
+      innerWidth: 1,
+      outerWidth: 2,
+      thickness: 12,
+      text: 'Test Text',
+      fontSize: 12,
+      nameX: 10,
+      nameY: 20,
+      nameHeight: 30,
+      nameWidth: 40,
+      nameVerticalAlign: 'MIDDLE',
+      nameHorizontalAlign: 'CENTER',
+      pointToProjection: jest.fn(),
+      mapInstance,
+    };
+
+    (getText as jest.Mock).mockReturnValue({
+      textCoords: [0, 0],
+      textStyle: new Style({
+        text: new Text({
+          text: props.text,
+          font: `bold ${props.fontSize}px Arial`,
+          fill: new Fill({
+            color: '#000',
+          }),
+          placement: 'point',
+          textAlign: 'center',
+          textBaseline: 'middle',
+        }),
+      }),
+    });
+    (getMultiPolygon as jest.Mock).mockReturnValue([
+      new Polygon([
+        [
+          [0, 0],
+          [1, 1],
+          [2, 2],
+        ],
+      ]),
+    ]);
+    (getStroke as jest.Mock).mockReturnValue(new Style());
+    (getFill as jest.Mock).mockReturnValue(new Style());
+    (rgbToHex as jest.Mock).mockReturnValue('#FFFFFF');
+    (getEllipseCoords as jest.Mock).mockReturnValue([
+      [10, 10],
+      [20, 20],
+      [30, 30],
+    ]);
+  });
+
+  it('should initialize with correct default properties', () => {
+    const multiPolygon = new CompartmentCircle(props);
+
+    expect(multiPolygon.polygons.length).toBe(4);
+    expect(multiPolygon.multiPolygonFeature).toBeInstanceOf(Feature);
+    expect(multiPolygon.multiPolygonFeature.getGeometry()).toBeInstanceOf(MultiPolygon);
+  });
+
+  it('should apply correct styles to the feature', () => {
+    const multiPolygon = new CompartmentCircle(props);
+    const feature = multiPolygon.multiPolygonFeature;
+
+    const style = feature.getStyleFunction()?.call(multiPolygon, feature, 1);
+
+    if (Array.isArray(style)) {
+      expect(style.length).toBeGreaterThan(0);
+    } else {
+      expect(style).toBeInstanceOf(Style);
+    }
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f5f3c51a0cf0eac641fa8666f5d48170b12962d3
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentCircle.ts
@@ -0,0 +1,113 @@
+/* eslint-disable no-magic-numbers */
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import { MapInstance } from '@/types/map';
+import {
+  ColorObject,
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+import {
+  BLACK_COLOR,
+  COMPARTMENT_CIRCLE_CENTER,
+  COMPARTMENT_CIRCLE_RADIUS,
+  WHITE_COLOR,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants';
+import getEllipseCoords from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getEllipseCoords';
+import Compartment from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/Compartment';
+
+export type CompartmentCircleProps = {
+  x: number;
+  y: number;
+  width: number;
+  height: number;
+  zIndex: number;
+  fillColor?: ColorObject;
+  borderColor?: ColorObject;
+  fontColor?: ColorObject;
+  innerWidth?: number;
+  outerWidth?: number;
+  thickness?: number;
+  text?: string;
+  fontSize?: number;
+  nameX: number;
+  nameY: number;
+  nameHeight: number;
+  nameWidth: number;
+  nameVerticalAlign?: VerticalAlign;
+  nameHorizontalAlign?: HorizontalAlign;
+  pointToProjection: UsePointToProjectionResult;
+  mapInstance: MapInstance;
+};
+
+export default class CompartmentCircle extends Compartment {
+  constructor({
+    x,
+    y,
+    width,
+    height,
+    zIndex,
+    fillColor = WHITE_COLOR,
+    borderColor = BLACK_COLOR,
+    fontColor = BLACK_COLOR,
+    innerWidth = 1,
+    outerWidth = 2,
+    thickness = 12,
+    text = '',
+    fontSize = 12,
+    nameX,
+    nameY,
+    nameHeight,
+    nameWidth,
+    nameVerticalAlign = 'MIDDLE',
+    nameHorizontalAlign = 'CENTER',
+    pointToProjection,
+    mapInstance,
+  }: CompartmentCircleProps) {
+    super({
+      x,
+      y,
+      width,
+      height,
+      thickness,
+      outerWidth,
+      innerWidth,
+      zIndex,
+      text,
+      fontSize,
+      nameX,
+      nameY,
+      nameWidth,
+      nameHeight,
+      fontColor,
+      nameVerticalAlign,
+      nameHorizontalAlign,
+      fillColor,
+      borderColor,
+      pointToProjection,
+      mapInstance,
+    });
+  }
+
+  protected getCompartmentCoords(): void {
+    this.outerCoords = getEllipseCoords({
+      x: this.x,
+      y: this.y,
+      center: COMPARTMENT_CIRCLE_CENTER,
+      radius: COMPARTMENT_CIRCLE_RADIUS,
+      height: this.height,
+      width: this.width,
+      points: 40,
+      pointToProjection: this.pointToProjection,
+    });
+    this.innerCoords = getEllipseCoords({
+      x: this.x + this.thickness,
+      y: this.y + this.thickness,
+      center: COMPARTMENT_CIRCLE_CENTER,
+      radius: COMPARTMENT_CIRCLE_RADIUS,
+      height: this.height - 2 * this.thickness,
+      width: this.width - 2 * this.thickness,
+      points: 40,
+      pointToProjection: this.pointToProjection,
+    });
+  }
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d9913b382f90c275bcaeb71ccf3b10262fe3582c
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare.test.ts
@@ -0,0 +1,118 @@
+/* eslint-disable no-magic-numbers */
+import { Feature, Map } from 'ol';
+import { Fill, Style, Text } from 'ol/style';
+import { Polygon, MultiPolygon } from 'ol/geom';
+import getText from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getText';
+import getMultiPolygon from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getMultiPolygon';
+import getStroke from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getStroke';
+import getFill from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getFill';
+import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/rgbToHex';
+import View from 'ol/View';
+import {
+  WHITE_COLOR,
+  BLACK_COLOR,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants';
+import CompartmentSquare, {
+  CompartmentSquareProps,
+} from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare';
+import getPolygonCoords from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getPolygonCoords';
+
+jest.mock('./getText');
+jest.mock('./getMultiPolygon');
+jest.mock('./getStroke');
+jest.mock('./getPolygonCoords');
+jest.mock('./getFill');
+jest.mock('./rgbToHex');
+
+describe('MapElement', () => {
+  let props: CompartmentSquareProps;
+
+  beforeEach(() => {
+    const dummyElement = document.createElement('div');
+    const mapInstance = new Map({
+      target: dummyElement,
+      view: new View({
+        zoom: 5,
+        minZoom: 3,
+        maxZoom: 7,
+      }),
+    });
+    props = {
+      x: 0,
+      y: 0,
+      width: 100,
+      height: 100,
+      zIndex: 1,
+      fillColor: WHITE_COLOR,
+      borderColor: BLACK_COLOR,
+      fontColor: BLACK_COLOR,
+      innerWidth: 1,
+      outerWidth: 2,
+      thickness: 12,
+      text: 'Test Text',
+      fontSize: 12,
+      nameX: 10,
+      nameY: 20,
+      nameHeight: 30,
+      nameWidth: 40,
+      nameVerticalAlign: 'MIDDLE',
+      nameHorizontalAlign: 'CENTER',
+      pointToProjection: jest.fn(),
+      mapInstance,
+    };
+
+    (getText as jest.Mock).mockReturnValue({
+      textCoords: [0, 0],
+      textStyle: new Style({
+        text: new Text({
+          text: props.text,
+          font: `bold ${props.fontSize}px Arial`,
+          fill: new Fill({
+            color: '#000',
+          }),
+          placement: 'point',
+          textAlign: 'center',
+          textBaseline: 'middle',
+        }),
+      }),
+    });
+    (getMultiPolygon as jest.Mock).mockReturnValue([
+      new Polygon([
+        [
+          [0, 0],
+          [1, 1],
+          [2, 2],
+        ],
+      ]),
+    ]);
+    (getStroke as jest.Mock).mockReturnValue(new Style());
+    (getFill as jest.Mock).mockReturnValue(new Style());
+    (rgbToHex as jest.Mock).mockReturnValue('#FFFFFF');
+    (getPolygonCoords as jest.Mock).mockReturnValue([
+      [10, 10],
+      [20, 20],
+      [30, 30],
+    ]);
+  });
+
+  it('should initialize with correct default properties', () => {
+    const multiPolygon = new CompartmentSquare(props);
+
+    expect(multiPolygon.polygons.length).toBe(4);
+    expect(multiPolygon.multiPolygonFeature).toBeInstanceOf(Feature);
+    expect(multiPolygon.multiPolygonFeature.getGeometry()).toBeInstanceOf(MultiPolygon);
+  });
+
+  it('should apply correct styles to the feature', () => {
+    const multiPolygon = new CompartmentSquare(props);
+    const feature = multiPolygon.multiPolygonFeature;
+
+    const style = feature.getStyleFunction()?.call(multiPolygon, feature, 1);
+
+    if (Array.isArray(style)) {
+      expect(style.length).toBeGreaterThan(0);
+    } else {
+      expect(style).toBeInstanceOf(Style);
+    }
+  });
+});
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare.ts
new file mode 100644
index 0000000000000000000000000000000000000000..79962ee718462b919b32947caf2f4ece25eecd01
--- /dev/null
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/CompartmentSquare.ts
@@ -0,0 +1,108 @@
+/* eslint-disable no-magic-numbers */
+import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
+import { MapInstance } from '@/types/map';
+import {
+  ColorObject,
+  HorizontalAlign,
+  VerticalAlign,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
+import {
+  BLACK_COLOR,
+  COMPARTMENT_SQUARE_POINTS,
+  WHITE_COLOR,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants';
+import getPolygonCoords from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getPolygonCoords';
+import Compartment from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/Compartment';
+
+export type CompartmentSquareProps = {
+  x: number;
+  y: number;
+  width: number;
+  height: number;
+  zIndex: number;
+  fillColor?: ColorObject;
+  borderColor?: ColorObject;
+  fontColor?: ColorObject;
+  innerWidth?: number;
+  outerWidth?: number;
+  thickness?: number;
+  text?: string;
+  fontSize?: number;
+  nameX: number;
+  nameY: number;
+  nameHeight: number;
+  nameWidth: number;
+  nameVerticalAlign?: VerticalAlign;
+  nameHorizontalAlign?: HorizontalAlign;
+  pointToProjection: UsePointToProjectionResult;
+  mapInstance: MapInstance;
+};
+
+export default class CompartmentSquare extends Compartment {
+  constructor({
+    x,
+    y,
+    width,
+    height,
+    zIndex,
+    fillColor = WHITE_COLOR,
+    borderColor = BLACK_COLOR,
+    fontColor = BLACK_COLOR,
+    innerWidth = 1,
+    outerWidth = 2,
+    thickness = 12,
+    text = '',
+    fontSize = 12,
+    nameX,
+    nameY,
+    nameHeight,
+    nameWidth,
+    nameVerticalAlign = 'MIDDLE',
+    nameHorizontalAlign = 'CENTER',
+    pointToProjection,
+    mapInstance,
+  }: CompartmentSquareProps) {
+    super({
+      x,
+      y,
+      width,
+      height,
+      thickness,
+      outerWidth,
+      innerWidth,
+      zIndex,
+      text,
+      fontSize,
+      nameX,
+      nameY,
+      nameWidth,
+      nameHeight,
+      fontColor,
+      nameVerticalAlign,
+      nameHorizontalAlign,
+      fillColor,
+      borderColor,
+      pointToProjection,
+      mapInstance,
+    });
+  }
+
+  protected getCompartmentCoords(): void {
+    this.outerCoords = getPolygonCoords({
+      points: COMPARTMENT_SQUARE_POINTS,
+      x: this.x,
+      y: this.y,
+      height: this.height,
+      width: this.width,
+      pointToProjection: this.pointToProjection,
+    });
+    this.innerCoords = getPolygonCoords({
+      points: COMPARTMENT_SQUARE_POINTS,
+      x: this.x + this.thickness,
+      y: this.y + this.thickness,
+      height: this.height - 2 * this.thickness,
+      width: this.width - 2 * this.thickness,
+      pointToProjection: this.pointToProjection,
+    });
+  }
+}
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.test.ts
index 0ed5313bcf38fc80ace22bec8a0982cb420f5760..004f90cd3cfc3350b66ac47f7b2f78de97a35ae4 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.test.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.test.ts
@@ -107,14 +107,4 @@ describe('MapElement', () => {
       expect(style).toBeInstanceOf(Style);
     }
   });
-
-  it('should update text style based on resolution', () => {
-    const multiPolygon = new MapElement(props);
-    const feature = multiPolygon.multiPolygonFeature;
-
-    multiPolygon.styleFunction(feature, 1000);
-    if (multiPolygon.textStyle) {
-      expect(multiPolygon.textStyle.getText()?.getScale()).toBe(1.22);
-    }
-  });
 });
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.ts
index e0943fb44bf4a3cb655f262e80cef366ef24b1a4..f1ba348fd4ef6b2602eb4a26fbe13e16f52bba41 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/MapElement.ts
@@ -1,13 +1,10 @@
 /* eslint-disable no-magic-numbers */
 import { Style, Text } from 'ol/style';
-import Feature, { FeatureLike } from 'ol/Feature';
-import { MultiPolygon } from 'ol/geom';
 import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
 import getStroke from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getStroke';
 import getFill from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getFill';
 import Polygon from 'ol/geom/Polygon';
 import getMultiPolygon from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getMultiPolygon';
-import getText from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getText';
 import { rgbToHex } from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/rgbToHex';
 import { BioShape, LineType, Modification, Shape } from '@/types/models';
 import { MapInstance } from '@/types/map';
@@ -20,6 +17,7 @@ import {
   BLACK_COLOR,
   WHITE_COLOR,
 } from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.constants';
+import BaseMultiPolygon from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/BaseMultiPolygon';
 
 export type MapElementProps = {
   shapes: Array<Shape>;
@@ -34,7 +32,7 @@ export type MapElementProps = {
   lineWidth?: number;
   lineType?: string;
   text?: string;
-  fontSize?: string | number;
+  fontSize?: number;
   nameX: number;
   nameY: number;
   nameHeight: number;
@@ -48,16 +46,18 @@ export type MapElementProps = {
   modifications?: Array<Modification>;
 };
 
-export default class MapElement {
-  textStyle: Style | undefined;
+export default class MapElement extends BaseMultiPolygon {
+  shapes: Array<Shape>;
+
+  lineWidth: number;
 
-  polygons: Array<Polygon> = [];
+  lineType: string | undefined;
 
-  styles: Array<Style> = [];
+  bioShapes: Array<BioShape>;
 
-  polygonsTexts: Array<string> = [];
+  lineTypes: Array<LineType>;
 
-  multiPolygonFeature: Feature;
+  modifications: Array<Modification>;
 
   constructor({
     shapes,
@@ -85,32 +85,44 @@ export default class MapElement {
     lineTypes = [],
     modifications = [],
   }: MapElementProps) {
-    if (text) {
-      const { textCoords, textStyle } = getText({
-        text,
-        fontSize,
-        x: nameX,
-        y: nameY,
-        width: nameWidth,
-        height: nameHeight,
-        color: rgbToHex(fontColor),
-        zIndex,
-        verticalAlign: nameVerticalAlign,
-        horizontalAlign: nameHorizontalAlign,
-        pointToProjection,
-      });
-      this.styles.push(textStyle);
-      this.polygonsTexts.push(text);
-      this.polygons.push(new Polygon([[textCoords, textCoords]]));
-    }
+    super({
+      x,
+      y,
+      width,
+      height,
+      zIndex,
+      text,
+      fontSize,
+      nameX,
+      nameY,
+      nameWidth,
+      nameHeight,
+      fontColor,
+      nameVerticalAlign,
+      nameHorizontalAlign,
+      fillColor,
+      borderColor,
+      pointToProjection,
+    });
+    this.shapes = shapes;
+    this.lineWidth = lineWidth;
+    this.lineType = lineType;
+    this.bioShapes = bioShapes;
+    this.lineTypes = lineTypes;
+    this.modifications = modifications;
+    this.createPolygons();
+    this.drawText();
+    this.drawMultiPolygonFeature(mapInstance);
+  }
 
+  protected createPolygons(): void {
     const multiPolygon: Array<Polygon> = [];
-    modifications.forEach(modification => {
+    this.modifications.forEach(modification => {
       if (modification.state === null) {
         return;
       }
 
-      const shape = bioShapes.find(bioShape => bioShape.sboTerm === modification.sboTerm);
+      const shape = this.bioShapes.find(bioShape => bioShape.sboTerm === modification.sboTerm);
       if (!shape) {
         return;
       }
@@ -120,7 +132,7 @@ export default class MapElement {
         width: modification.width,
         height: modification.height,
         shapes: shape.shapes,
-        pointToProjection,
+        pointToProjection: this.pointToProjection,
         mirror: modification.direction && modification.direction === 'RIGHT',
       });
       multiPolygon.push(...multiPolygonModification.flat());
@@ -151,12 +163,19 @@ export default class MapElement {
       });
     });
 
-    const elementMultiPolygon = getMultiPolygon({ x, y, width, height, shapes, pointToProjection });
+    const elementMultiPolygon = getMultiPolygon({
+      x: this.x,
+      y: this.y,
+      width: this.width,
+      height: this.height,
+      shapes: this.shapes,
+      pointToProjection: this.pointToProjection,
+    });
     this.polygons = [...this.polygons, ...multiPolygon, ...elementMultiPolygon.flat()];
 
     let lineDash: Array<number> = [];
-    if (lineType) {
-      const lineTypeFound = lineTypes.find(type => type.name === lineType);
+    if (this.lineType) {
+      const lineTypeFound = this.lineTypes.find(type => type.name === this.lineType);
       if (lineTypeFound) {
         lineDash = lineTypeFound.pattern;
       }
@@ -165,48 +184,11 @@ export default class MapElement {
       this.styles.push(
         new Style({
           geometry: polygon,
-          stroke: getStroke({ color: rgbToHex(borderColor), width: lineWidth, lineDash }),
-          fill: getFill({ color: rgbToHex(fillColor) }),
-          zIndex,
+          stroke: getStroke({ color: rgbToHex(this.borderColor), width: this.lineWidth, lineDash }),
+          fill: getFill({ color: rgbToHex(this.fillColor) }),
+          zIndex: this.zIndex,
         }),
       );
     });
-
-    this.multiPolygonFeature = new Feature({
-      geometry: new MultiPolygon([...this.polygons]),
-      getTextScale: (resolution: number): number => {
-        const maxZoom = mapInstance?.getView().getMaxZoom();
-        if (maxZoom) {
-          const minResolution = mapInstance?.getView().getResolutionForZoom(maxZoom);
-          if (minResolution) {
-            return Math.round((minResolution / resolution) * 100) / 100;
-          }
-        }
-        return 1;
-      },
-    });
-
-    this.multiPolygonFeature.setStyle(this.styleFunction.bind(this));
-  }
-
-  styleFunction(feature: FeatureLike, resolution: number): Style | Array<Style> | void {
-    const getTextScale = feature.get('getTextScale');
-    let textScale = 1;
-    if (getTextScale instanceof Function) {
-      textScale = getTextScale(resolution);
-    }
-    let index = 0;
-    this.styles.forEach(style => {
-      if (style.getText()) {
-        if (textScale > 0.3) {
-          style.getText()?.setScale(textScale);
-          style.getText()?.setText(this.polygonsTexts[index]);
-          index += 1;
-        } else {
-          style.getText()?.setText(undefined);
-        }
-      }
-    });
-    return this.styles;
   }
 }
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getEllipseCoords.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getEllipseCoords.ts
index 5d1e7f668ebabd78939c0af7d9a424c7e10517ac..b3a307a0c160a492c2e270588679dba5ded727af 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getEllipseCoords.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getEllipseCoords.ts
@@ -3,24 +3,10 @@ import getCoordsX from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/
 import getCoordsY from '@/components/Map/MapViewer/MapViewerVector/utils/shapes/getCoordsY';
 import { Coordinate } from 'ol/coordinate';
 import { UsePointToProjectionResult } from '@/utils/map/usePointToProjection';
-
-type EllipseCenter = {
-  type: string;
-  absoluteX: number;
-  absoluteY: number;
-  relativeX: number;
-  relativeY: number;
-  relativeHeightForX: number | null;
-  relativeWidthForY: number | null;
-};
-
-type EllipseRadius = {
-  type: string;
-  absoluteX: number;
-  absoluteY: number;
-  relativeX: number;
-  relativeY: number;
-};
+import {
+  EllipseCenter,
+  EllipseRadius,
+} from '@/components/Map/MapViewer/MapViewerVector/MapViewerVector.types';
 
 export default function getEllipseCoords({
   x,
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.test.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.test.ts
index a9f0490707370aca9a3e9fe595aab4e83174bcff..e25b4df766b169378fa2e31f029ad0ca54e0c7eb 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.test.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.test.ts
@@ -18,7 +18,7 @@ describe('getText', () => {
     });
 
     expect(textCoords).toEqual([50, 50]);
-    expect(textStyle.getText()?.getFont()).toEqual('bold 12px Arial');
+    expect(textStyle.getText()?.getFont()).toEqual('12pt Arial');
   });
 
   it('should return correct text coordinates and style when text is aligned to bottom', () => {
@@ -36,6 +36,6 @@ describe('getText', () => {
 
     expect(textCoords).toEqual([70, 121]);
 
-    expect(textStyle.getText()?.getFont()).toEqual('bold 18px Arial');
+    expect(textStyle.getText()?.getFont()).toEqual('18pt Arial');
   });
 });
diff --git a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.ts b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.ts
index 10e021881d8e448edd9559a142d819d3b97de00c..09dffbe2806cd54da01562c5dba15818bba63c05 100644
--- a/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.ts
+++ b/src/components/Map/MapViewer/MapViewerVector/utils/shapes/getText.ts
@@ -61,19 +61,22 @@ export default function getText({
     geometry: (feature: FeatureLike): Geometry | RenderFeature | undefined => {
       const geometry = feature.getGeometry();
       if (geometry && geometry.getType() === 'MultiPolygon') {
-        return (geometry as MultiPolygon).getPolygon(0).getInteriorPoint();
+        return (geometry as MultiPolygon)
+          .getPolygon((geometry as MultiPolygon).getPolygons().length - 1)
+          .getInteriorPoint();
       }
       return undefined;
     },
     text: new Text({
       text,
-      font: `bold ${fontSize}px Arial`,
+      font: `${fontSize}pt Arial`,
       fill: new Fill({
         color,
       }),
       placement: 'point',
-      textAlign: 'center',
+      textAlign: horizontalAlign.toLowerCase() as CanvasTextAlign,
       textBaseline: 'middle',
+      overflow: true,
     }),
     zIndex,
   });
diff --git a/src/models/modelElementSchema.ts b/src/models/modelElementSchema.ts
index 326f6d9f9c0610f553ff83872daee4d0c5972058..3f650899441c4ef31cbba8dba6f640eedc51a5b7 100644
--- a/src/models/modelElementSchema.ts
+++ b/src/models/modelElementSchema.ts
@@ -37,6 +37,10 @@ export const modelElementSchema = z.object({
   formerSymbols: z.array(z.string()),
   activity: z.boolean().optional(),
   lineWidth: z.number().optional(),
+  innerWidth: z.number().optional(),
+  outerWidth: z.number().optional(),
+  thickness: z.number().optional(),
+  shape: z.enum(['SQUARE_COMPARTMENT', 'OVAL_COMPARTMENT', 'PATHWAY']).optional(),
   complex: z.number().nullable().optional(),
   initialAmount: z.number().nullable().optional(),
   charge: z.number().nullable().optional(),