diff --git a/package-lock.json b/package-lock.json
index 6dfd0fd89691449cc123b3ed5a1c8d33957f2561..5226c2f4253dc71a1351e5b2b7a8d6735914dd5a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
         "@next/font": "^13.5.2",
         "@reduxjs/toolkit": "^1.9.6",
         "@types/node": "20.6.2",
+        "@types/openlayers": "^4.6.20",
         "@types/react": "18.2.21",
         "@types/react-dom": "18.2.7",
         "autoprefixer": "10.4.15",
@@ -19,6 +20,7 @@
         "axios-hooks": "^5.0.0",
         "eslint-config-next": "13.4.19",
         "next": "13.4.19",
+        "ol": "^8.1.0",
         "postcss": "8.4.29",
         "react": "18.2.0",
         "react-accessible-accordion": "^5.0.0",
@@ -60,7 +62,7 @@
         "lint-staged": "^14.0.1",
         "prettier": "^3.0.3",
         "prettier-2": "npm:prettier@^2",
-        "prettier-plugin-tailwindcss": "^0.5.4",
+        "prettier-plugin-tailwindcss": "^0.5.6",
         "typescript": "^5.2.2",
         "zod-fixture": "^2.5.0"
       }
@@ -1876,6 +1878,11 @@
         "node": ">= 8"
       }
     },
+    "node_modules/@petamoriken/float16": {
+      "version": "3.8.4",
+      "resolved": "https://registry.npmjs.org/@petamoriken/float16/-/float16-3.8.4.tgz",
+      "integrity": "sha512-kB+NJ5Br56ZhElKsf0pM7/PQfrDdDVMRz8f0JM6eVOGE+L89z9hwcst9QvWBBnazzuqGTGtPsJNZoQ1JdNiGSQ=="
+    },
     "node_modules/@reduxjs/toolkit": {
       "version": "1.9.6",
       "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-1.9.6.tgz",
@@ -2239,6 +2246,11 @@
       "integrity": "sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A==",
       "dev": true
     },
+    "node_modules/@types/openlayers": {
+      "version": "4.6.20",
+      "resolved": "https://registry.npmjs.org/@types/openlayers/-/openlayers-4.6.20.tgz",
+      "integrity": "sha512-TYgdyK1WyLFcwlFkz2A7lK0stj3MFdVZeUc6+AWCmqsAHk+0o9V8TOgMqdPpb0cVIxknHwxty/g8VawWTt/FRw=="
+    },
     "node_modules/@types/prop-types": {
       "version": "15.7.8",
       "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz",
@@ -4530,6 +4542,11 @@
         "node": ">=4"
       }
     },
+    "node_modules/earcut": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz",
+      "integrity": "sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ=="
+    },
     "node_modules/eastasianwidth": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -6007,6 +6024,34 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/geotiff": {
+      "version": "2.0.7",
+      "resolved": "https://registry.npmjs.org/geotiff/-/geotiff-2.0.7.tgz",
+      "integrity": "sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==",
+      "dependencies": {
+        "@petamoriken/float16": "^3.4.7",
+        "lerc": "^3.0.0",
+        "pako": "^2.0.4",
+        "parse-headers": "^2.0.2",
+        "quick-lru": "^6.1.1",
+        "web-worker": "^1.2.0",
+        "xml-utils": "^1.0.2"
+      },
+      "engines": {
+        "node": ">=10.19"
+      }
+    },
+    "node_modules/geotiff/node_modules/quick-lru": {
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-6.1.2.tgz",
+      "integrity": "sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
@@ -6509,7 +6554,6 @@
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
       "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "dev": true,
       "funding": [
         {
           "type": "github",
@@ -8508,6 +8552,11 @@
         "node": "> 0.8"
       }
     },
+    "node_modules/lerc": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/lerc/-/lerc-3.0.0.tgz",
+      "integrity": "sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww=="
+    },
     "node_modules/leven": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
@@ -9669,6 +9718,21 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/ol": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/ol/-/ol-8.1.0.tgz",
+      "integrity": "sha512-cx3SH2plpFS9fM8pp1nCypgQXGJD7Mcb1E3mEySmy5XEw1DUEo+kkNzgtAZz5qupekqi7aU9iBJEjCoMfqvO2Q==",
+      "dependencies": {
+        "earcut": "^2.2.3",
+        "geotiff": "^2.0.7",
+        "pbf": "3.2.1",
+        "rbush": "^3.0.1"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/openlayers"
+      }
+    },
     "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
@@ -9798,6 +9862,11 @@
         "node": ">=6"
       }
     },
+    "node_modules/pako": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
+      "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
+    },
     "node_modules/parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -9809,6 +9878,11 @@
         "node": ">=6"
       }
     },
+    "node_modules/parse-headers": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.5.tgz",
+      "integrity": "sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA=="
+    },
     "node_modules/parse-json": {
       "version": "5.2.0",
       "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@@ -9885,6 +9959,18 @@
         "node": ">=8"
       }
     },
+    "node_modules/pbf": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz",
+      "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
+      "dependencies": {
+        "ieee754": "^1.1.12",
+        "resolve-protobuf-schema": "^2.1.0"
+      },
+      "bin": {
+        "pbf": "bin/pbf"
+      }
+    },
     "node_modules/pend": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
@@ -10169,9 +10255,9 @@
       }
     },
     "node_modules/prettier-plugin-tailwindcss": {
-      "version": "0.5.5",
-      "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.5.tgz",
-      "integrity": "sha512-voy0CjWv/CM8yeaduv5ZwovovpTGMR5LbzlhGF+LtEvMJt9wBeVTVnW781hL38R/RcDXCJwN2rolsgr94B/n0Q==",
+      "version": "0.5.6",
+      "resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.5.6.tgz",
+      "integrity": "sha512-2Xgb+GQlkPAUCFi3sV+NOYcSI5XgduvDBL2Zt/hwJudeKXkyvRS65c38SB0yb9UB40+1rL83I6m0RtlOQ8eHdg==",
       "dev": true,
       "engines": {
         "node": ">=14.21.3"
@@ -10316,6 +10402,11 @@
         "react-is": "^16.13.1"
       }
     },
+    "node_modules/protocol-buffers-schema": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz",
+      "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw=="
+    },
     "node_modules/proxy-from-env": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -10410,6 +10501,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/quickselect": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
+      "integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
+    },
     "node_modules/randexp": {
       "version": "0.5.3",
       "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.5.3.tgz",
@@ -10423,6 +10519,14 @@
         "node": ">=4"
       }
     },
+    "node_modules/rbush": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz",
+      "integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==",
+      "dependencies": {
+        "quickselect": "^2.0.0"
+      }
+    },
     "node_modules/react": {
       "version": "18.2.0",
       "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
@@ -10860,6 +10964,14 @@
         "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
       }
     },
+    "node_modules/resolve-protobuf-schema": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
+      "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
+      "dependencies": {
+        "protocol-buffers-schema": "^3.3.1"
+      }
+    },
     "node_modules/resolve.exports": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
@@ -12181,6 +12293,11 @@
         "defaults": "^1.0.3"
       }
     },
+    "node_modules/web-worker": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz",
+      "integrity": "sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA=="
+    },
     "node_modules/webidl-conversions": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@@ -12402,6 +12519,11 @@
         "node": ">=12"
       }
     },
+    "node_modules/xml-utils": {
+      "version": "1.7.0",
+      "resolved": "https://registry.npmjs.org/xml-utils/-/xml-utils-1.7.0.tgz",
+      "integrity": "sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw=="
+    },
     "node_modules/xmlchars": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
diff --git a/package.json b/package.json
index a7feaab56721eecfb48ad854e60c0ac989dd447d..2192fbdfc7e619cd1bd53c4d249a720130bcc24a 100644
--- a/package.json
+++ b/package.json
@@ -26,6 +26,7 @@
     "@next/font": "^13.5.2",
     "@reduxjs/toolkit": "^1.9.6",
     "@types/node": "20.6.2",
+    "@types/openlayers": "^4.6.20",
     "@types/react": "18.2.21",
     "@types/react-dom": "18.2.7",
     "autoprefixer": "10.4.15",
@@ -33,6 +34,7 @@
     "axios-hooks": "^5.0.0",
     "eslint-config-next": "13.4.19",
     "next": "13.4.19",
+    "ol": "^8.1.0",
     "postcss": "8.4.29",
     "react": "18.2.0",
     "react-accessible-accordion": "^5.0.0",
@@ -74,7 +76,7 @@
     "lint-staged": "^14.0.1",
     "prettier": "^3.0.3",
     "prettier-2": "npm:prettier@^2",
-    "prettier-plugin-tailwindcss": "^0.5.4",
+    "prettier-plugin-tailwindcss": "^0.5.6",
     "typescript": "^5.2.2",
     "zod-fixture": "^2.5.0"
   },
diff --git a/prettier.config.js b/prettier.config.js
index 7946df2239da49eb1b21142cd0f61e667ceedefe..fd41c7ea28115342ff628216fd2269ac7fb37e53 100644
--- a/prettier.config.js
+++ b/prettier.config.js
@@ -3,7 +3,7 @@ const config = {
   trailingComma: 'all',
   printWidth: 100,
   arrowParens: 'avoid',
-  plugins: ['prettier-plugin-tailwindcss'],
+  plugins: [import('prettier-plugin-tailwindcss')],
   tailwindConfig: './tailwind.config.ts',
   tailwindFunctions: ['twMerge'],
 };
diff --git a/src/constants/map.ts b/src/constants/map.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d8bde744a06a6337ec5a2dcc83aa720c364c3fd1
--- /dev/null
+++ b/src/constants/map.ts
@@ -0,0 +1,19 @@
+import { Point } from '@/types/map';
+
+export const DEFAULT_TILE_SIZE = 256;
+export const DEFAULT_MIN_ZOOM = 2;
+export const DEFAULT_MAX_ZOOM = 9;
+export const DEFAULT_ZOOM = 5;
+export const DEFAULT_CENTER_X = 0;
+export const DEFAULT_CENTER_Y = 0;
+
+export const DEFAULT_CENTER_POINT: Point = {
+  x: DEFAULT_CENTER_X,
+  y: DEFAULT_CENTER_Y,
+  z: DEFAULT_ZOOM,
+};
+
+export const OPTIONS = {
+  showFullExtent: false,
+  wrapXInTileLayer: false,
+};
diff --git a/src/redux/map/map.constants.ts b/src/redux/map/map.constants.ts
new file mode 100644
index 0000000000000000000000000000000000000000..19bf5fb562d94a93ce85bdfac206caafe498cb96
--- /dev/null
+++ b/src/redux/map/map.constants.ts
@@ -0,0 +1,27 @@
+import { PROJECT_ID } from '@/constants';
+import {
+  DEFAULT_CENTER_POINT,
+  DEFAULT_MAX_ZOOM,
+  DEFAULT_MIN_ZOOM,
+  DEFAULT_TILE_SIZE,
+} from '@/constants/map';
+import { MapData } from './map.types';
+
+export const MAP_DATA_INITIAL_STATE: MapData = {
+  projectId: PROJECT_ID,
+  meshId: '',
+  modelId: 0,
+  overlaysIds: [],
+  position: DEFAULT_CENTER_POINT,
+  show: {
+    legend: false,
+    comments: false,
+  },
+  size: {
+    width: 0,
+    height: 0,
+    tileSize: DEFAULT_TILE_SIZE,
+    minZoom: DEFAULT_MIN_ZOOM,
+    maxZoom: DEFAULT_MAX_ZOOM,
+  },
+};
diff --git a/src/redux/map/map.reducers.ts b/src/redux/map/map.reducers.ts
new file mode 100644
index 0000000000000000000000000000000000000000..95d763254f76bcea970ec8f428e2082e80fba5d2
--- /dev/null
+++ b/src/redux/map/map.reducers.ts
@@ -0,0 +1,9 @@
+import { PayloadAction } from '@reduxjs/toolkit';
+import { MapData, MapState } from './map.types';
+
+export const setMapDataReducer = (
+  state: MapState,
+  action: PayloadAction<Partial<MapData> | undefined>,
+): void => {
+  state.data = { ...state.data, ...action.payload };
+};
diff --git a/src/redux/map/map.selectors.ts b/src/redux/map/map.selectors.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9e559fd44e250809c36021ac18690da90cf1d92e
--- /dev/null
+++ b/src/redux/map/map.selectors.ts
@@ -0,0 +1,4 @@
+import { createSelector } from '@reduxjs/toolkit';
+import { rootSelector } from '@/redux/root/root.selectors';
+
+export const mapDataSelector = createSelector(rootSelector, state => state.map);
diff --git a/src/redux/map/map.slice.ts b/src/redux/map/map.slice.ts
new file mode 100644
index 0000000000000000000000000000000000000000..62b95df2be671ec12d4dec2341978c586ef235c2
--- /dev/null
+++ b/src/redux/map/map.slice.ts
@@ -0,0 +1,22 @@
+import { createSlice } from '@reduxjs/toolkit';
+import { MAP_DATA_INITIAL_STATE } from './map.constants';
+import { setMapDataReducer } from './map.reducers';
+import { MapState } from './map.types';
+
+const initialState: MapState = {
+  data: MAP_DATA_INITIAL_STATE,
+  loading: 'idle',
+  error: { name: '', message: '' },
+};
+
+const mapSlice = createSlice({
+  name: 'map',
+  initialState,
+  reducers: {
+    setMapData: setMapDataReducer,
+  },
+});
+
+export const { setMapData } = mapSlice.actions;
+
+export default mapSlice.reducer;
diff --git a/src/redux/map/map.types.ts b/src/redux/map/map.types.ts
new file mode 100644
index 0000000000000000000000000000000000000000..245bd58a7867dc4b6e3602a0079c3cbc0e63b646
--- /dev/null
+++ b/src/redux/map/map.types.ts
@@ -0,0 +1,29 @@
+import { Loading } from '@/types/loadingState';
+import { Point } from '@/types/map';
+
+export interface MapSize {
+  width: number;
+  height: number;
+  tileSize: number;
+  minZoom: number;
+  maxZoom: number;
+}
+
+export type MapData = {
+  projectId: string;
+  meshId: string;
+  modelId: number;
+  overlaysIds: number[];
+  size: MapSize;
+  position: Point;
+  show: {
+    legend: boolean;
+    comments: boolean;
+  };
+};
+
+export type MapState = {
+  data: MapData;
+  loading: Loading;
+  error: Error;
+};
diff --git a/src/redux/store.ts b/src/redux/store.ts
index 081acb384c7b0247810a8e614de74d979f8bdbc8..0136870f551d8ceb8695c6e54e45087e360f3ca6 100644
--- a/src/redux/store.ts
+++ b/src/redux/store.ts
@@ -1,8 +1,9 @@
-import { configureStore } from '@reduxjs/toolkit';
-import searchReducer from '@/redux/search/search.slice';
-import projectSlice from '@/redux/project/project.slice';
-import drugsReducer from '@/redux/drugs/drugs.slice';
 import drawerReducer from '@/redux/drawer/drawer.slice';
+import drugsReducer from '@/redux/drugs/drugs.slice';
+import mapReducer from '@/redux/map/map.slice';
+import projectSlice from '@/redux/project/project.slice';
+import searchReducer from '@/redux/search/search.slice';
+import { configureStore } from '@reduxjs/toolkit';
 
 export const store = configureStore({
   reducer: {
@@ -10,6 +11,7 @@ export const store = configureStore({
     project: projectSlice,
     drugs: drugsReducer,
     drawer: drawerReducer,
+    map: mapReducer,
   },
   devTools: true,
 });
diff --git a/src/types/map.ts b/src/types/map.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8dedc23f1526474dcc10d639b9e3e76312a86996
--- /dev/null
+++ b/src/types/map.ts
@@ -0,0 +1,7 @@
+export interface Point {
+  x: number;
+  y: number;
+  z?: number;
+}
+
+export type LatLng = [number, number];