diff --git a/docs/data/bioentities.md b/docs/plugins/data/bioentities.md
similarity index 100%
rename from docs/data/bioentities.md
rename to docs/plugins/data/bioentities.md
diff --git a/docs/plugins/map/position.md b/docs/plugins/map/position.md
new file mode 100644
index 0000000000000000000000000000000000000000..a08872c6e6c00f67b041ef4b97641ef3ff84580e
--- /dev/null
+++ b/docs/plugins/map/position.md
@@ -0,0 +1,63 @@
+### Map positon
+
+With use of the methods below plugins can access and modify user position data.
+
+#### Get zoom
+
+To get current zoom value, plugins can use the `window.minerva.map.getZoom()` method, which returns current zoom value as a number.
+
+**Example:**
+
+```ts
+const currentZoom = window.minerva.map.getZoom();
+console.log(currentZoom); // 5
+```
+
+#### Set zoom
+
+To modify current zoom value, plugins can use the `window.minerva.map.setZoom(zoom)` method. This function accepts non-negative number as an argument and returns nothing. If argument is invalid, `setZoom` method throws an error.
+
+**Valid example:**
+
+```ts
+window.minerva.map.setZoom(7.54);
+console.log(window.minerva.map.getZoom()); // 7.54
+```
+
+**Invalid example:**
+
+```ts
+window.minerva.map.setZoom(-14);
+// Uncaught ZodError: [...]
+```
+
+#### Get center
+
+User position is defined as center coordinate. It's value is defined as x/y/z points of current viewport center translated to map position. Plugins can access center value and modify it.
+
+To get current position value, plugins can use the `window.minerva.map.getCenter()` method which returns current position value as an object containing `x`, `y` and `z` fields. All of them are non-negative numbers but `z` is an optional field and it defines current zoom value. If argument is invalid, `getCenter` method throws an error.
+
+**Valid example:**
+
+```ts
+const currentCenter = window.minerva.map.getCenter();
+console.log(currentCenter); // {x: 13256, y: 8118, z: 5}
+```
+
+#### Set center
+
+To modify position center value plugins can use `window.minerva.map.setCenter(positionObject)` which accepts single object as an argument and returns nothing. This object should contain `x`, `y` fields and `z` optionally. All of them are non-negative numbers. If argument is invalid, `setCenter` method throws an error.
+
+**Valid example:**
+
+```ts
+window.minerva.map.setCenter({ x: 13256, y: 8118, z: 5 });
+console.log(window.minerva.map.getCenter()); // {x: 13256, y: 8118, z: 5}
+```
+
+**Invalid example:**
+
+```ts
+window.minerva.map.setCenter({ x: 13256, y: 8118, z: -5 });
+// Uncaught ZodError: [...]
+```
diff --git a/docs/plugins/overview-images.md b/docs/plugins/overview-images.md
new file mode 100644
index 0000000000000000000000000000000000000000..b425d071b1aa1cdbf327a383e28b986e51a1eb91
--- /dev/null
+++ b/docs/plugins/overview-images.md
@@ -0,0 +1,46 @@
+### Overview images
+
+The methods contained within 'Overview images' are used to access data on Overview images and modify behavior of Overview images modal.
+
+Below is a description of the methods, as well as the types they return. description of the object types can be found in folder `/docs/types/`.
+
+**Available data access methods include:**
+
+- `getCurrentOverviewImage`
+  - gets currently selected overview image
+  - returns `OverviewImageView` or `undefined`
+- `getOverviewImage`
+  - gets all loaded overview images
+  - returns array of `OverviewImageView`
+
+**Available data modify methods include:**
+
+##### `hideOverviewImageModal`
+
+- accepts no arguments
+- hides overview image modal if opened
+- returns nothing
+- example:
+  ```ts
+  window.minerva.overviewImage.hideOverviewImageModal();
+  ```
+
+##### `selectOverviewImage`
+
+- accepts single argument of number representing id of one of loaded overview images
+- selects overview image of provided id as current, if image does not exists throws an error
+- returns nothing
+- example:
+  ```ts
+  window.minerva.overviewImage.selectOverviewImage(42);
+  ```
+
+##### `showOverviewImageModal`
+
+- accepts single argument of number representing id of one of loaded overview images
+- selects overview image of provided id as current and opens overview image modal, if image does not exists throws an error
+- returns nothing
+- example:
+  ```ts
+  window.minerva.overviewImage.showOverviewImageModal(24);
+  ```
diff --git a/docs/types/OverviewImageView.md b/docs/types/OverviewImageView.md
new file mode 100644
index 0000000000000000000000000000000000000000..33cf4cce60d81e907af4d6cd37132b2e1aff6347
--- /dev/null
+++ b/docs/types/OverviewImageView.md
@@ -0,0 +1,88 @@
+```json
+{
+  "type": "object",
+  "properties": {
+    "idObject": {
+      "type": "number"
+    },
+    "filename": {
+      "type": "string"
+    },
+    "width": {
+      "type": "number"
+    },
+    "height": {
+      "type": "number"
+    },
+    "links": {
+      "type": "array",
+      "items": {
+        "anyOf": [
+          {
+            "type": "object",
+            "properties": {
+              "idObject": {
+                "type": "number"
+              },
+              "polygon": {
+                "type": "array",
+                "items": {
+                  "type": "object",
+                  "properties": {
+                    "x": {
+                      "type": "number"
+                    },
+                    "y": {
+                      "type": "number"
+                    }
+                  },
+                  "required": ["x", "y"],
+                  "additionalProperties": false
+                }
+              },
+              "imageLinkId": {
+                "type": "number"
+              },
+              "type": {
+                "type": "string"
+              }
+            },
+            "required": ["idObject", "polygon", "imageLinkId", "type"],
+            "additionalProperties": false
+          },
+          {
+            "type": "object",
+            "properties": {
+              "idObject": {
+                "type": "number"
+              },
+              "polygon": {
+                "type": "array",
+                "items": {
+                  "$ref": "#/definitions/overviewImageView/properties/links/items/anyOf/0/properties/polygon/items"
+                }
+              },
+              "zoomLevel": {
+                "type": "number"
+              },
+              "modelPoint": {
+                "$ref": "#/definitions/overviewImageView/properties/links/items/anyOf/0/properties/polygon/items"
+              },
+              "modelLinkId": {
+                "type": "number"
+              },
+              "type": {
+                "type": "string"
+              }
+            },
+            "required": ["idObject", "polygon", "zoomLevel", "modelPoint", "modelLinkId", "type"],
+            "additionalProperties": false
+          }
+        ]
+      }
+    }
+  },
+  "required": ["idObject", "filename", "width", "height", "links"],
+  "additionalProperties": false
+}
+```
diff --git a/index.d.ts b/index.d.ts
index db769bd296186e97e8d09c6adc0460de5f166242..bbde76a542bd803d1396d3a25d40df60ef9aa927 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -1,8 +1,11 @@
 import { getModels } from '@/services/pluginsManager/map/models/getModels';
-import { OpenMapArgs, openMap } from '@/services/pluginsManager/map/openMap';
+import { openMap } from '@/services/pluginsManager/map/openMap';
+import { getCenter } from '@/services/pluginsManager/map/position/getCenter';
+import { setCenter } from '@/services/pluginsManager/map/position/setCenter';
 import { triggerSearch } from '@/services/pluginsManager/map/triggerSearch';
+import { getZoom } from '@/services/pluginsManager/map/zoom/getZoom';
+import { setZoom } from '@/services/pluginsManager/map/zoom/setZoom';
 import { MinervaConfiguration } from '@/services/pluginsManager/pluginsManager';
-import { MapModel } from '@/types/models';
 import { getDisease } from '@/services/pluginsManager/project/data/getDisease';
 import { getName } from '@/services/pluginsManager/project/data/getName';
 import { getOrganism } from '@/services/pluginsManager/project/data/getOrganism';
@@ -40,6 +43,17 @@ declare global {
         };
         openMap: typeof openMap;
         triggerSearch: typeof triggerSearch;
+        getZoom: typeof getZoom;
+        setZoom: typeof setZoom;
+        getCenter: typeof getCenter;
+        setCenter: typeof setCenter;
+      };
+      overviewImage: {
+        getCurrentOverviewImage: typeof getCurrentOverviewImage;
+        getOverviewImages: typeof getOverviewImages;
+        hideOverviewImageModal: typeof hideOverviewImageModal;
+        selectOverviewImage: typeof selectOverviewImage;
+        showOverviewImageModal: typeof showOverviewImageModal;
       };
       project: {
         data: {
diff --git a/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx b/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx
index d944235a29d04b7a1c376869c37cdc29e502ed2d..cefbc59f7cd06e4449d33f704ad4e42bf960eaea 100644
--- a/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx
+++ b/src/components/FunctionalArea/MapNavigation/MapNavigation.component.test.tsx
@@ -1,14 +1,14 @@
 /* eslint-disable no-magic-numbers */
+import { MODELS_MOCK } from '@/redux/compartmentPathways/compartmentPathways.mock';
+import { initialMapDataFixture, openedMapsThreeSubmapsFixture } from '@/redux/map/map.fixtures';
+import { MODELS_DATA_MOCK_WITH_MAIN_MAP } from '@/redux/models/models.mock';
+import { StoreType } from '@/redux/store';
+import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
 import {
   InitialStoreState,
   getReduxWrapperWithStore,
 } from '@/utils/testing/getReduxWrapperWithStore';
-import { StoreType } from '@/redux/store';
-import { initialMapDataFixture, openedMapsThreeSubmapsFixture } from '@/redux/map/map.fixtures';
 import { act, render, screen, within } from '@testing-library/react';
-import { MODELS_MOCK } from '@/redux/compartmentPathways/compartmentPathways.mock';
-import { MODELS_DATA_MOCK_WITH_MAIN_MAP } from '@/redux/models/models.mock';
-import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
 import { MapNavigation } from './MapNavigation.component';
 
 const MAIN_MAP_ID = 5053;
@@ -170,7 +170,7 @@ describe('MapNavigation - component', () => {
         histamineMapCloseButton.click();
       });
 
-      expect(dispatchEventMock).toHaveBeenCalledTimes(2);
+      expect(dispatchEventMock).toHaveBeenCalledTimes(4);
       expect(dispatchEventMock).toHaveBeenCalledWith('onSubmapClose', 5052);
       expect(dispatchEventMock).toHaveBeenCalledWith('onSubmapOpen', 52);
     });
diff --git a/src/constants/errors.ts b/src/constants/errors.ts
index 887f64f35d00d60ce428da9f5b4239c0d8c6cbaa..b8639a2f43545749b6be91055fa69ec9c8ab852e 100644
--- a/src/constants/errors.ts
+++ b/src/constants/errors.ts
@@ -1 +1,5 @@
 export const DEFAULT_ERROR: Error = { message: '', name: '' };
+
+export const OVERVIEW_IMAGE_ERRORS = {
+  IMAGE_ID_IS_INVALID: "Image id is invalid. There's no such image in overview images list",
+};
diff --git a/src/models/pointSchema.ts b/src/models/pointSchema.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2b097ef8235bf4e2a0a27698337828153a62c553
--- /dev/null
+++ b/src/models/pointSchema.ts
@@ -0,0 +1,9 @@
+import { z } from 'zod';
+
+export const zPointSchema = z.number().nonnegative('z should be non negative').optional();
+
+export const pointSchema = z.object({
+  x: z.number().nonnegative('x should be non negative'),
+  y: z.number().nonnegative('y should be non negative'),
+  z: zPointSchema,
+});
diff --git a/src/redux/map/map.reducers.ts b/src/redux/map/map.reducers.ts
index 362745fc00327c7fff640f6d74c388b85400bb07..e21b6566379527c7da5bf2ed8d6cf43ae54c10a0 100644
--- a/src/redux/map/map.reducers.ts
+++ b/src/redux/map/map.reducers.ts
@@ -1,6 +1,6 @@
 import { DEFAULT_ZOOM } from '@/constants/map';
-import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
 import { PluginsEventBus } from '@/services/pluginsManager/pluginsEventBus';
+import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
 import { getPointMerged } from '../../utils/object/getPointMerged';
 import {
   initMapBackground,
@@ -16,6 +16,7 @@ import {
   SetActiveMapAction,
   SetBackgroundAction,
   SetLastPositionZoomAction,
+  SetLastPositionZoomWithDeltaAction,
   SetMapDataAction,
   SetMapPositionDataAction,
 } from './map.types';
@@ -32,19 +33,34 @@ export const setMapDataReducer = (state: MapState, action: SetMapDataAction): vo
 export const setMapPositionReducer = (state: MapState, action: SetMapPositionDataAction): void => {
   const position = action.payload || {};
   const statePosition = state.data.position;
+  const finalPosition = getPointMerged(position || {}, statePosition.last);
+  const { modelId } = state.data;
+
+  PluginsEventBus.dispatchEvent('onCenterChanged', {
+    modelId,
+    x: finalPosition.x,
+    y: finalPosition.y,
+  });
+
+  if (position?.z) {
+    PluginsEventBus.dispatchEvent('onZoomChanged', {
+      modelId,
+      zoom: position?.z,
+    });
+  }
 
   state.data = {
     ...state.data,
     position: {
-      initial: getPointMerged(position || {}, statePosition.initial),
-      last: getPointMerged(position || {}, statePosition.last),
+      initial: finalPosition,
+      last: finalPosition,
     },
   };
 };
 
 export const varyPositionZoomReducer = (
   state: MapState,
-  action: SetLastPositionZoomAction,
+  action: SetLastPositionZoomWithDeltaAction,
 ): void => {
   const { minZoom, maxZoom } = state.data.size;
   const { delta } = action.payload;
@@ -63,6 +79,23 @@ export const varyPositionZoomReducer = (
   state.data.position.initial.z = newZLimited;
 };
 
+export const setLastPositionZoomReducer = (
+  state: MapState,
+  action: SetLastPositionZoomAction,
+): void => {
+  const { zoom } = action.payload;
+
+  if (state.data.position.last.z !== zoom) {
+    PluginsEventBus.dispatchEvent('onZoomChanged', {
+      modelId: state.data.modelId,
+      zoom,
+    });
+  }
+
+  state.data.position.last.z = zoom;
+  state.data.position.initial.z = zoom;
+};
+
 const updateLastPositionOfCurrentlyActiveMap = (state: MapState): void => {
   const currentMapId = state.data.modelId;
   const currentOpenedMap = state.openedMaps.find(openedMap => openedMap.modelId === currentMapId);
diff --git a/src/redux/map/map.slice.ts b/src/redux/map/map.slice.ts
index 8fc687b9fb29301fc18cc15579ca40b6caef893f..02e8a878292906e9894c26fe8f841dd5219fbbc8 100644
--- a/src/redux/map/map.slice.ts
+++ b/src/redux/map/map.slice.ts
@@ -9,6 +9,7 @@ import {
   initOpenedMapsReducer,
   openMapAndSetActiveReducer,
   setActiveMapReducer,
+  setLastPositionZoomReducer,
   setMapBackgroundReducer,
   setMapDataReducer,
   setMapPositionReducer,
@@ -27,6 +28,7 @@ const mapSlice = createSlice({
     setMapPosition: setMapPositionReducer,
     varyPositionZoom: varyPositionZoomReducer,
     setMapBackground: setMapBackgroundReducer,
+    setLastPositionZoom: setLastPositionZoomReducer,
   },
   extraReducers: builder => {
     initMapPositionReducers(builder);
@@ -45,6 +47,7 @@ export const {
   setMapPosition,
   setMapBackground,
   varyPositionZoom,
+  setLastPositionZoom,
 } = mapSlice.actions;
 
 export default mapSlice.reducer;
diff --git a/src/redux/map/map.types.ts b/src/redux/map/map.types.ts
index b11c5cfefe794fb850de5629934e181c4f94877d..727df76f71b29da80f9690edcc3e9e86c9888d12 100644
--- a/src/redux/map/map.types.ts
+++ b/src/redux/map/map.types.ts
@@ -88,10 +88,17 @@ export type GetUpdatedMapDataResult = Pick<
 
 export type SetMapPositionDataAction = PayloadAction<Point>;
 
-export type SetLastPositionZoomActionPayload = {
+export type SetLastPositionZoomWithDeltaActionPayload = {
   delta: number;
 };
 
+export type SetLastPositionZoomWithDeltaAction =
+  PayloadAction<SetLastPositionZoomWithDeltaActionPayload>;
+
+export type SetLastPositionZoomActionPayload = {
+  zoom: number;
+};
+
 export type SetLastPositionZoomAction = PayloadAction<SetLastPositionZoomActionPayload>;
 
 export type InitMapDataActionPayload = {
diff --git a/src/services/pluginsManager/map/position/getCenter.test.ts b/src/services/pluginsManager/map/position/getCenter.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f9d9dd545bda215f262f039e2d9c5f2ae7349ab5
--- /dev/null
+++ b/src/services/pluginsManager/map/position/getCenter.test.ts
@@ -0,0 +1,39 @@
+import { initialMapDataFixture, openedMapsThreeSubmapsFixture } from '@/redux/map/map.fixtures';
+import { RootState, store } from '@/redux/store';
+import { getCenter } from './getCenter';
+
+jest.mock('../../../../redux/store');
+
+describe('getCenter - plugin method', () => {
+  const getStateSpy = jest.spyOn(store, 'getState');
+
+  getStateSpy.mockImplementation(
+    () =>
+      ({
+        map: {
+          data: {
+            ...initialMapDataFixture,
+            position: {
+              ...initialMapDataFixture.position,
+              last: {
+                x: 2137,
+                y: 420,
+                z: 1.488,
+              },
+            },
+          },
+          loading: 'succeeded',
+          error: { message: '', name: '' },
+          openedMaps: openedMapsThreeSubmapsFixture,
+        },
+      }) as RootState,
+  );
+
+  it('should return last position from Redux', () => {
+    expect(getCenter()).toStrictEqual({
+      x: 2137,
+      y: 420,
+      z: 1.488,
+    });
+  });
+});
diff --git a/src/services/pluginsManager/map/position/getCenter.ts b/src/services/pluginsManager/map/position/getCenter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ccf28579481881132d6677d2a982a465321ddac0
--- /dev/null
+++ b/src/services/pluginsManager/map/position/getCenter.ts
@@ -0,0 +1,10 @@
+import { mapDataLastPositionSelector } from '@/redux/map/map.selectors';
+import { store } from '@/redux/store';
+import { Point } from '@/types/map';
+
+export const getCenter = (): Point => {
+  const { getState } = store;
+  const lastPosition = mapDataLastPositionSelector(getState());
+
+  return lastPosition;
+};
diff --git a/src/services/pluginsManager/map/position/setCenter.test.ts b/src/services/pluginsManager/map/position/setCenter.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ef26567b20576c97982dd6385a71829b534d4249
--- /dev/null
+++ b/src/services/pluginsManager/map/position/setCenter.test.ts
@@ -0,0 +1,55 @@
+import { setMapPosition } from '@/redux/map/map.slice';
+import { store } from '@/redux/store';
+import { Point } from '@/types/map';
+import { ZodError } from 'zod';
+import { setCenter } from './setCenter';
+
+jest.mock('../../../../redux/store');
+
+describe('setCenter - plugin method', () => {
+  const dispatchSpy = jest.spyOn(store, 'dispatch');
+
+  describe('when position is invalid', () => {
+    const invalidPositions = [
+      {
+        x: -1,
+        y: 1,
+        z: 1,
+      },
+      {
+        x: 1,
+        y: -1,
+        z: 1,
+      },
+      {
+        x: 1,
+        y: 1,
+        z: -1,
+      },
+      {
+        y: 1,
+      },
+      {
+        x: 1,
+      },
+    ] as Point[];
+
+    it.each(invalidPositions)('should throw error', position => {
+      expect(() => setCenter(position)).toThrow(ZodError);
+    });
+  });
+
+  describe('when position is valid', () => {
+    const position: Point = {
+      x: 500,
+      y: 200,
+      z: 2,
+    };
+
+    it('should set map position', () => {
+      setCenter(position);
+
+      expect(dispatchSpy).toHaveBeenCalledWith(setMapPosition(position));
+    });
+  });
+});
diff --git a/src/services/pluginsManager/map/position/setCenter.ts b/src/services/pluginsManager/map/position/setCenter.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a32717df9b4897e0136f3d461d26779a9e5480ab
--- /dev/null
+++ b/src/services/pluginsManager/map/position/setCenter.ts
@@ -0,0 +1,11 @@
+import { pointSchema } from '@/models/pointSchema';
+import { setMapPosition } from '@/redux/map/map.slice';
+import { store } from '@/redux/store';
+import { Point } from '@/types/map';
+
+export const setCenter = (position: Point): void => {
+  const { dispatch } = store;
+  pointSchema.parse(position);
+
+  dispatch(setMapPosition(position));
+};
diff --git a/src/services/pluginsManager/map/zoom/getZoom.test.ts b/src/services/pluginsManager/map/zoom/getZoom.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b7808d53163d34fa802f14c8e090119590c3c11f
--- /dev/null
+++ b/src/services/pluginsManager/map/zoom/getZoom.test.ts
@@ -0,0 +1,69 @@
+/* eslint-disable no-magic-numbers */
+import { initialMapDataFixture, openedMapsThreeSubmapsFixture } from '@/redux/map/map.fixtures';
+import { RootState, store } from '@/redux/store';
+import { getZoom } from './getZoom';
+
+jest.mock('../../../../redux/store');
+
+describe('getZoom - plugin method', () => {
+  const getStateSpy = jest.spyOn(store, 'getState');
+
+  describe('when last position zoom is present', () => {
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            map: {
+              data: {
+                ...initialMapDataFixture,
+                position: {
+                  ...initialMapDataFixture.position,
+                  last: {
+                    x: 2137,
+                    y: 420,
+                    z: 1.488,
+                  },
+                },
+              },
+              loading: 'succeeded',
+              error: { message: '', name: '' },
+              openedMaps: openedMapsThreeSubmapsFixture,
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should return last position from Redux', () => {
+      expect(getZoom()).toEqual(1.488);
+    });
+  });
+
+  describe('when last position zoom is NOT present', () => {
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            map: {
+              data: {
+                ...initialMapDataFixture,
+                position: {
+                  ...initialMapDataFixture.position,
+                  last: {
+                    x: 2137,
+                    y: 420,
+                  },
+                },
+              },
+              loading: 'succeeded',
+              error: { message: '', name: '' },
+              openedMaps: openedMapsThreeSubmapsFixture,
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should return undefined', () => {
+      expect(getZoom()).toBeUndefined();
+    });
+  });
+});
diff --git a/src/services/pluginsManager/map/zoom/getZoom.ts b/src/services/pluginsManager/map/zoom/getZoom.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fee865408304b40d1f3ea5d614d39c2315b32123
--- /dev/null
+++ b/src/services/pluginsManager/map/zoom/getZoom.ts
@@ -0,0 +1,9 @@
+import { mapDataLastPositionSelector } from '@/redux/map/map.selectors';
+import { store } from '@/redux/store';
+
+export const getZoom = (): number | undefined => {
+  const { getState } = store;
+  const lastPosition = mapDataLastPositionSelector(getState());
+
+  return lastPosition?.z;
+};
diff --git a/src/services/pluginsManager/map/zoom/setZoom.test.ts b/src/services/pluginsManager/map/zoom/setZoom.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dc92068af316a5a7b667f0e225b40197c0c3944d
--- /dev/null
+++ b/src/services/pluginsManager/map/zoom/setZoom.test.ts
@@ -0,0 +1,29 @@
+/* eslint-disable no-magic-numbers */
+import { setLastPositionZoom } from '@/redux/map/map.slice';
+import { store } from '@/redux/store';
+import { ZodError } from 'zod';
+import { setZoom } from './setZoom';
+
+jest.mock('../../../../redux/store');
+
+describe('setZoom - plugin method', () => {
+  const dispatchSpy = jest.spyOn(store, 'dispatch');
+
+  describe('when zoom is invalid', () => {
+    const invalidZoom = [-1, -123, '-123'] as number[];
+
+    it.each(invalidZoom)('should throw error', zoom => {
+      expect(() => setZoom(zoom)).toThrow(ZodError);
+    });
+  });
+
+  describe('when zoom is valid', () => {
+    const zoom = 2;
+
+    it('should set map zoom', () => {
+      setZoom(zoom);
+
+      expect(dispatchSpy).toHaveBeenCalledWith(setLastPositionZoom({ zoom }));
+    });
+  });
+});
diff --git a/src/services/pluginsManager/map/zoom/setZoom.ts b/src/services/pluginsManager/map/zoom/setZoom.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8d599604907f7900c9799979d2226e91b69f8311
--- /dev/null
+++ b/src/services/pluginsManager/map/zoom/setZoom.ts
@@ -0,0 +1,10 @@
+import { zPointSchema } from '@/models/pointSchema';
+import { setLastPositionZoom } from '@/redux/map/map.slice';
+import { store } from '@/redux/store';
+
+export const setZoom = (zoom: number): void => {
+  const { dispatch } = store;
+  zPointSchema.parse(zoom);
+
+  dispatch(setLastPositionZoom({ zoom }));
+};
diff --git a/src/services/pluginsManager/overviewImage/getCurrentOverviewImage.ts b/src/services/pluginsManager/overviewImage/getCurrentOverviewImage.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b9d54c9aad16354024f9efbf5e9f487e182926eb
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/getCurrentOverviewImage.ts
@@ -0,0 +1,10 @@
+import { currentOverviewImageSelector } from '@/redux/project/project.selectors';
+import { store } from '@/redux/store';
+import { OverviewImageView } from '@/types/models';
+
+export const getCurrentOverviewImage = (): OverviewImageView | undefined => {
+  const { getState } = store;
+  const overviewImage = currentOverviewImageSelector(getState());
+
+  return overviewImage;
+};
diff --git a/src/services/pluginsManager/overviewImage/getOverviewImages.ts b/src/services/pluginsManager/overviewImage/getOverviewImages.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8e2e19c189033e08f86b97d4a0b983d6cca30cb3
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/getOverviewImages.ts
@@ -0,0 +1,10 @@
+import { projectOverviewImagesSelector } from '@/redux/project/project.selectors';
+import { store } from '@/redux/store';
+import { OverviewImageView } from '@/types/models';
+
+export const getOverviewImages = (): OverviewImageView[] => {
+  const { getState } = store;
+  const overviewImages = projectOverviewImagesSelector(getState());
+
+  return overviewImages;
+};
diff --git a/src/services/pluginsManager/overviewImage/hideOverviewImageModal.test.ts b/src/services/pluginsManager/overviewImage/hideOverviewImageModal.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..25eb34afffd19c5809906d2adc013892927dc3e7
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/hideOverviewImageModal.test.ts
@@ -0,0 +1,60 @@
+import { closeModal } from '@/redux/modal/modal.slice';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { RootState, store } from '@/redux/store';
+import { hideOverviewImageModal } from './hideOverviewImageModal';
+
+jest.mock('../../../redux/store');
+
+describe('hideOverviewImageModal - util', () => {
+  const getStateSpy = jest.spyOn(store, 'getState');
+
+  beforeEach(() => {
+    jest.resetAllMocks();
+  });
+
+  describe('when opened modal is overview image', () => {
+    const dispatchSpy = jest.spyOn(store, 'dispatch');
+
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            modal: {
+              ...INITIAL_STORE_STATE_MOCK.modal,
+              modalName: 'overview-images',
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should close modal', () => {
+      hideOverviewImageModal();
+
+      expect(dispatchSpy).toHaveBeenCalledWith(closeModal());
+    });
+  });
+
+  describe('when opened modal is NOT overview image', () => {
+    const dispatchSpy = jest.spyOn(store, 'dispatch');
+
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            modal: {
+              ...INITIAL_STORE_STATE_MOCK.modal,
+              modalName: 'login',
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should not close modal', () => {
+      hideOverviewImageModal();
+
+      expect(dispatchSpy).not.toHaveBeenCalledWith(closeModal());
+    });
+  });
+});
diff --git a/src/services/pluginsManager/overviewImage/hideOverviewImageModal.ts b/src/services/pluginsManager/overviewImage/hideOverviewImageModal.ts
new file mode 100644
index 0000000000000000000000000000000000000000..47652cd524a0fb8a0851ad730d280085d3105559
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/hideOverviewImageModal.ts
@@ -0,0 +1,14 @@
+import { modalSelector } from '@/redux/modal/modal.selector';
+import { closeModal } from '@/redux/modal/modal.slice';
+import { store } from '@/redux/store';
+
+export const hideOverviewImageModal = (): void => {
+  const { getState, dispatch } = store;
+  const { modalName } = modalSelector(getState());
+
+  if (modalName !== 'overview-images') {
+    return;
+  }
+
+  dispatch(closeModal());
+};
diff --git a/src/services/pluginsManager/overviewImage/selectOverviewImage.test.ts b/src/services/pluginsManager/overviewImage/selectOverviewImage.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..500bfae94ebce30954ce2b772a67a4c12b224917
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/selectOverviewImage.test.ts
@@ -0,0 +1,63 @@
+import { OVERVIEW_IMAGE_ERRORS } from '@/constants/errors';
+import { setOverviewImageId } from '@/redux/modal/modal.slice';
+import { PROJECT_OVERVIEW_IMAGE_MOCK } from '@/redux/project/project.mock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { RootState, store } from '@/redux/store';
+import { selectOverviewImage } from './selectOverviewImage';
+
+jest.mock('../../../redux/store');
+
+describe('selectOverviewImage - plugin method', () => {
+  const dispatchSpy = jest.spyOn(store, 'dispatch');
+  const getStateSpy = jest.spyOn(store, 'getState');
+
+  describe('when image id is valid', () => {
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            project: {
+              ...INITIAL_STORE_STATE_MOCK.project,
+              data: {
+                ...INITIAL_STORE_STATE_MOCK.project.data,
+                overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
+              },
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should dispatch action set overview image', () => {
+      selectOverviewImage(PROJECT_OVERVIEW_IMAGE_MOCK.idObject);
+
+      expect(dispatchSpy).toHaveBeenCalledWith(
+        setOverviewImageId(PROJECT_OVERVIEW_IMAGE_MOCK.idObject),
+      );
+    });
+  });
+
+  describe('when image id is NOT valid', () => {
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            project: {
+              ...INITIAL_STORE_STATE_MOCK.project,
+              data: {
+                ...INITIAL_STORE_STATE_MOCK.project.data,
+                overviewImageViews: [],
+              },
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should throw error', () => {
+      expect(() => selectOverviewImage(PROJECT_OVERVIEW_IMAGE_MOCK.idObject)).toThrow(
+        OVERVIEW_IMAGE_ERRORS.IMAGE_ID_IS_INVALID,
+      );
+    });
+  });
+});
diff --git a/src/services/pluginsManager/overviewImage/selectOverviewImage.ts b/src/services/pluginsManager/overviewImage/selectOverviewImage.ts
new file mode 100644
index 0000000000000000000000000000000000000000..71ef40f1ff80adc6892ac6621a62562750cd3be4
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/selectOverviewImage.ts
@@ -0,0 +1,17 @@
+import { OVERVIEW_IMAGE_ERRORS } from '@/constants/errors';
+import { setOverviewImageId } from '@/redux/modal/modal.slice';
+import { projectOverviewImagesSelector } from '@/redux/project/project.selectors';
+import { store } from '@/redux/store';
+
+export const selectOverviewImage = (imageId: number): void => {
+  const { dispatch, getState } = store;
+  const overviewImages = projectOverviewImagesSelector(getState());
+  const foundOverviewImage = overviewImages.find(o => o.idObject === imageId);
+  const isImageIdValid = Boolean(foundOverviewImage);
+
+  if (!isImageIdValid) {
+    throw new Error(OVERVIEW_IMAGE_ERRORS.IMAGE_ID_IS_INVALID);
+  }
+
+  dispatch(setOverviewImageId(imageId));
+};
diff --git a/src/services/pluginsManager/overviewImage/showOverviewImageModal.test.ts b/src/services/pluginsManager/overviewImage/showOverviewImageModal.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f829470b22eb062f67a5e17a6641ffdbde72cbe7
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/showOverviewImageModal.test.ts
@@ -0,0 +1,105 @@
+import { OVERVIEW_IMAGE_ERRORS } from '@/constants/errors';
+import { openOverviewImagesModalById } from '@/redux/modal/modal.slice';
+import { PROJECT_OVERVIEW_IMAGE_MOCK } from '@/redux/project/project.mock';
+import { INITIAL_STORE_STATE_MOCK } from '@/redux/root/root.fixtures';
+import { RootState, store } from '@/redux/store';
+import { showOverviewImageModal } from './showOverviewImageModal';
+
+jest.mock('../../../redux/store');
+
+describe('showOverviewImageModal - plugin method', () => {
+  const dispatchSpy = jest.spyOn(store, 'dispatch');
+  const getStateSpy = jest.spyOn(store, 'getState');
+
+  beforeEach(() => {
+    jest.resetAllMocks();
+  });
+
+  describe('when image id is not provided', () => {
+    const defaultImageId = 23332;
+
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            project: {
+              ...INITIAL_STORE_STATE_MOCK.project,
+              data: {
+                ...INITIAL_STORE_STATE_MOCK.project.data,
+                overviewImageViews: [
+                  PROJECT_OVERVIEW_IMAGE_MOCK,
+                  {
+                    ...PROJECT_OVERVIEW_IMAGE_MOCK,
+                    idObject: defaultImageId,
+                  },
+                ],
+                topOverviewImage: {
+                  ...PROJECT_OVERVIEW_IMAGE_MOCK,
+                  idObject: defaultImageId,
+                },
+              },
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should dispatch action set overview image with defaultImageId', () => {
+      showOverviewImageModal();
+
+      expect(dispatchSpy).toHaveBeenCalledWith(openOverviewImagesModalById(defaultImageId));
+    });
+  });
+
+  describe('when image id is valid', () => {
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            project: {
+              ...INITIAL_STORE_STATE_MOCK.project,
+              data: {
+                ...INITIAL_STORE_STATE_MOCK.project.data,
+                overviewImageViews: [PROJECT_OVERVIEW_IMAGE_MOCK],
+                topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
+              },
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should dispatch action set overview image', () => {
+      showOverviewImageModal(PROJECT_OVERVIEW_IMAGE_MOCK.idObject);
+
+      expect(dispatchSpy).toHaveBeenCalledWith(
+        openOverviewImagesModalById(PROJECT_OVERVIEW_IMAGE_MOCK.idObject),
+      );
+    });
+  });
+
+  describe('when image id is NOT valid', () => {
+    beforeEach(() => {
+      getStateSpy.mockImplementation(
+        () =>
+          ({
+            ...INITIAL_STORE_STATE_MOCK,
+            project: {
+              ...INITIAL_STORE_STATE_MOCK.project,
+              data: {
+                ...INITIAL_STORE_STATE_MOCK.project.data,
+                overviewImageViews: [],
+                topOverviewImage: PROJECT_OVERVIEW_IMAGE_MOCK,
+              },
+            },
+          }) as RootState,
+      );
+    });
+
+    it('should throw error', () => {
+      expect(() => showOverviewImageModal(PROJECT_OVERVIEW_IMAGE_MOCK.idObject)).toThrow(
+        OVERVIEW_IMAGE_ERRORS.IMAGE_ID_IS_INVALID,
+      );
+    });
+  });
+});
diff --git a/src/services/pluginsManager/overviewImage/showOverviewImageModal.ts b/src/services/pluginsManager/overviewImage/showOverviewImageModal.ts
new file mode 100644
index 0000000000000000000000000000000000000000..ac4351069bceb73d3a136dfe8a11d357ee7ba165
--- /dev/null
+++ b/src/services/pluginsManager/overviewImage/showOverviewImageModal.ts
@@ -0,0 +1,23 @@
+import { OVERVIEW_IMAGE_ERRORS } from '@/constants/errors';
+import { openOverviewImagesModalById } from '@/redux/modal/modal.slice';
+import {
+  projectDefaultOverviewImageIdSelector,
+  projectOverviewImagesSelector,
+} from '@/redux/project/project.selectors';
+import { store } from '@/redux/store';
+
+export const showOverviewImageModal = (imageId?: number): void => {
+  const { dispatch, getState } = store;
+  const overviewImages = projectOverviewImagesSelector(getState());
+  const defaultImageId = projectDefaultOverviewImageIdSelector(getState());
+  const selectedImageId = imageId || defaultImageId;
+
+  const foundOverviewImage = overviewImages.find(o => o.idObject === selectedImageId);
+  const isImageIdValid = Boolean(foundOverviewImage);
+
+  if (!isImageIdValid) {
+    throw new Error(OVERVIEW_IMAGE_ERRORS.IMAGE_ID_IS_INVALID);
+  }
+
+  dispatch(openOverviewImagesModalById(selectedImageId));
+};
diff --git a/src/services/pluginsManager/pluginsManager.ts b/src/services/pluginsManager/pluginsManager.ts
index 23a78ff89353268cccf150657ebb644f4c850259..813274a16b43d74fea00d7250e3424adbd2fe1ce 100644
--- a/src/services/pluginsManager/pluginsManager.ts
+++ b/src/services/pluginsManager/pluginsManager.ts
@@ -2,18 +2,27 @@ import { PLUGINS_CONTENT_ELEMENT_ATTR_NAME, PLUGINS_CONTENT_ELEMENT_ID } from '@
 import { registerPlugin } from '@/redux/plugins/plugins.thunks';
 import { store } from '@/redux/store';
 import md5 from 'crypto-js/md5';
+import { bioEntitiesMethods } from './bioEntities';
 import { getModels } from './map/models/getModels';
 import { openMap } from './map/openMap';
-import { bioEntitiesMethods } from './bioEntities';
+import { getCenter } from './map/position/getCenter';
+import { setCenter } from './map/position/setCenter';
 import { triggerSearch } from './map/triggerSearch';
+import { getZoom } from './map/zoom/getZoom';
+import { setZoom } from './map/zoom/setZoom';
+import { getCurrentOverviewImage } from './overviewImage/getCurrentOverviewImage';
+import { getOverviewImages } from './overviewImage/getOverviewImages';
+import { hideOverviewImageModal } from './overviewImage/hideOverviewImageModal';
+import { selectOverviewImage } from './overviewImage/selectOverviewImage';
+import { showOverviewImageModal } from './overviewImage/showOverviewImageModal';
 import { PluginsEventBus } from './pluginsEventBus';
-import { getProjectId } from './project/data/getProjectId';
-import { getName } from './project/data/getName';
-import { getVersion } from './project/data/getVersion';
-import { getDisease } from './project/data/getDisease';
-import { getOrganism } from './project/data/getOrganism';
 import type { PluginsManagerType } from './pluginsManager.types';
 import { configurationMapper } from './pluginsManager.utils';
+import { getDisease } from './project/data/getDisease';
+import { getName } from './project/data/getName';
+import { getOrganism } from './project/data/getOrganism';
+import { getProjectId } from './project/data/getProjectId';
+import { getVersion } from './project/data/getVersion';
 
 export const PluginsManager: PluginsManagerType = {
   hashedPlugins: {},
@@ -38,6 +47,17 @@ export const PluginsManager: PluginsManagerType = {
         },
         openMap,
         triggerSearch,
+        getZoom,
+        setZoom,
+        getCenter,
+        setCenter,
+      },
+      overviewImage: {
+        getCurrentOverviewImage,
+        getOverviewImages,
+        hideOverviewImageModal,
+        selectOverviewImage,
+        showOverviewImageModal,
       },
       project: {
         data: {
diff --git a/src/types/error.ts b/src/types/error.ts
new file mode 100644
index 0000000000000000000000000000000000000000..48e6926ad764eeb1355d602ced1e5d149bcea3dc
--- /dev/null
+++ b/src/types/error.ts
@@ -0,0 +1,3 @@
+export interface PluginError {
+  message: string;
+}