diff --git a/ui/UI.py b/app/ui/UI.py similarity index 63% rename from ui/UI.py rename to app/ui/UI.py index f7ebd75..6274e0d 100644 --- a/ui/UI.py +++ b/app/ui/UI.py @@ -1,18 +1,25 @@ +import os.path + from PySide6 import QtCore, QtWidgets, QtGui from PySide6.QtGui import QPainter, QBrush, QFont, QColor, QPen from PySide6.QtWidgets import QMainWindow, QPushButton, QLineEdit, QLabel, QFrame, QScrollArea, QVBoxLayout, QWidget, QGridLayout -from PySide6.QtCore import Qt, QTime, QSize, QTimer -import os +from PySide6.QtCore import Qt, QTime, QSize, QTimer, QPoint -from ui import AFK +from app.utils.Navigation import Navigation +from app.utils.tools.Log import Log +from app.utils.Data import Data -from utils.tools.Log import Log -from utils.Data import Data +from app.ui.utils.AfkUtil import AfkUtil class UI(QMainWindow): def __init__(self, str_name="None"): super().__init__() + + self.afk_util = AfkUtil() + self.data = Data() + self.navigator = Navigation() + # temp self.origin = None self.task_num = 0 @@ -23,7 +30,7 @@ def __init__(self, str_name="None"): self.offset = QtCore.QPoint(60, 60) # navigation - self.current_floor = Data().get_default_floor() + self.current_floor = self.data.get_default_floor() self.has_result = False self.route_ladders = [] self.route_segments = [] @@ -32,10 +39,11 @@ def __init__(self, str_name="None"): self.setWindowTitle(str_name) self.setStyleSheet("background-color: rgb(240, 240, 240);") self.setGeometry(100, 100, 300, 500) - self.setMinimumSize(800, 370 + Data().get_floors_count() * 50) + self.setMinimumSize(800, 370 + self.data.get_floors_count() * 50) self.img = QtGui.QPixmap("./resources/icons/icon.png") if self.img.isNull(): Log().send(Log.LogType.ERROR, "Failed to load ./resources/icons/icon.png") + self.img = QtGui.QPixmap(os.path.join(os.getcwd(), "UniversityNavigationSystem","resources","icons","icon.png")) self.setWindowIcon(self.img) self.setIconSize(QSize(100, 100)) @@ -49,7 +57,7 @@ def __init__(self, str_name="None"): self.input_field.setGeometry(60, 7, self.width() - 60 * 2, 50) self.input_field.setFont(QFont("Arial", 16, weight=QFont.Bold)) self.input_field.setStyleSheet("background-color: white; border-radius: 10px; border: 2px solid black;") - self.completer = QtWidgets.QCompleter(Data().get_rooms_names()) + self.completer = QtWidgets.QCompleter(self.data.get_rooms_names()) self.completer.popup().setStyleSheet("font-size: 16px;") self.input_field.setCompleter(self.completer) @@ -62,6 +70,7 @@ def __init__(self, str_name="None"): # print(os.path.join(os.getcwd(), "resources", "icons", "close.png")) if self.img.isNull(): Log().send(Log.LogType.ERROR, "Failed to load ./resources/icons/close.png") + self.img = QtGui.QPixmap(os.path.join(os.getcwd(), "UniversityNavigationSystem","resources","icons","close.png")) self.clear_btn.setIcon(self.img) self.clear_btn.setIconSize(QSize(50, 50)) self.clear_btn.clicked.connect(lambda: self.input_field.clear()) @@ -75,6 +84,7 @@ def __init__(self, str_name="None"): self.img = QtGui.QPixmap("./resources/icons/find.png") if self.img.isNull(): Log().send(Log.LogType.ERROR, "Failed to load ./resources/icons/find.png") + self.img = QtGui.QPixmap(os.path.join(os.getcwd(), "UniversityNavigationSystem","resources","icons","find.png")) self.find_btn.setIcon(self.img) self.find_btn.setIconSize(QSize(36, 36)) self.find_btn.clicked.connect(lambda: self.use(False)) @@ -83,10 +93,10 @@ def __init__(self, str_name="None"): # floors frame self.floors_frame = QFrame(self) self.floors_frame.setStyleSheet("background-color: white; border-radius: 10px; border: 2px solid black;") - self.floors_frame.setGeometry(7, self.height() - 30 - 50 * Data().get_floors_count(), 50, 50 * Data().get_floors_count()) + self.floors_frame.setGeometry(7, self.height() - 30 - 50 * self.data.get_floors_count(), 50, 50 * self.data.get_floors_count()) self.floors_layout = QGridLayout(self.floors_frame) row = 0 - for name in Data().get_floors(): + for name in self.data.get_floors(): self.button = QLabel(str(name)) self.button.setFixedSize(30, 30) self.button.setFont(QFont("Arial", 16, weight=QFont.Bold)) @@ -131,7 +141,7 @@ def __init__(self, str_name="None"): # frame scroll self.frame_scroll_area = QScrollArea(self.info_frame) self.frame_scroll_area.setGeometry(0, 0, self.info_frame.width(), self.info_frame.height()) - self.frame_scroll_area.setFont(QFont("Arial", 16)) + self.frame_scroll_area.setFont(QFont("Arial", 32)) self.frame_scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.frame_scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) scrollbar_style = """ @@ -153,21 +163,14 @@ def __init__(self, str_name="None"): self.frame_scroll_area.setStyleSheet(scrollbar_style) # frame scroll_layout self.frame_scroll_widget = QWidget() - self.vbox = QVBoxLayout() - for i in range(1, 100): - # TODO text - object = QLabel("тут будет текст") - self.vbox.addWidget(object) self.frame_scroll_widget.setStyleSheet("border: 0px; border-radius: 0px;") - self.frame_scroll_widget.setLayout(self.vbox) - self.frame_scroll_area.setWidget(self.frame_scroll_widget) # Tasks def task_executor(self): # update time self.time_label.setText(QTime.currentTime().toString(" hh:mm")) if self.task_num == 0: - if AFK.check_time(): + if self.afk_util.check_new_changes(): self.afk_close() self.task_num += 1 if self.task_num > 60: @@ -184,7 +187,6 @@ def set_floor(self, floor): self.update() def use(self, close): - AFK.action() if close: self.time_label.setVisible(True) self.name_label.setVisible(True) @@ -196,20 +198,109 @@ def use(self, close): self.route_ladders = [] self.route_segments = [] else: + self.afk_util.action() self.name_label.setVisible(False) self.input_field.setEnabled(False) - self.has_result = Data().is_valid_name(self.input_field.text()) + + dl = self.frame_scroll_widget.layout() + #self.clearLayout(dl) + + self.has_result = self.data.is_valid_name(self.input_field.text()) self.find_btn.setEnabled(False) self.clear_btn.setEnabled(True) self.info_frame.setVisible(True) self.resize_frame() if self.has_result: + # TODO + + trobject = self.data.get_rooms_by_name(self.input_field.text()) + + tm = list(self.navigator.run(self.input_field.text(), trobject.getflor())) + Log().send(Log.LogType.INFO, "Routed segments " + str(tm)) + self.route_ladders = [] + self.route_segments = [] + for zi in tm: + if zi == "f1" or zi == "f2": + continue + try: + lol = int(zi) + except: + self.route_segments.append(self.data.get_lines_by_name(zi)) + Log().send(Log.LogType.INFO, "Routed segments2 " + str(self.route_segments)) + + if trobject.getflor() == "2": + self.route_ladders.append("1") + + vbox = QVBoxLayout() self.frame_error_label.setVisible(False) self.frame_scroll_area.setVisible(True) + + object = QLabel("МАРШРУТ (Терминал -> " + self.input_field.text() + ")") + object.setFont(QFont("Arial", 16, weight=QFont.Bold)) + vbox.addWidget(object) + object = QLabel("Длительность " + str(1 + int(((len(tm) - 2))/ 2)) + " мин.") + object.setFont(QFont("Arial", 15)) + vbox.addWidget(object) + vbox.addWidget(QLabel(" ")) + + if len(self.route_ladders) == 1: + object = QLabel("- Пройдите влево и начните подниматься по лестнице") + object.setFont(QFont("Arial", 16)) + vbox.addWidget(object) + + self.img = QtGui.QPixmap(self.data.get_patch_to_image("ladder1.png")) + if self.img.isNull(): + Log().send(Log.LogType.ERROR, "Failed to load navigation image!") + else: + object = QLabel() + object.setPixmap(self.img) + vbox.addWidget(object) + vbox.addWidget(QLabel(" ")) + + object = QLabel("- Поднимиться по лестнице на второй этаж") + object.setFont(QFont("Arial", 16)) + vbox.addWidget(object) + + self.img = QtGui.QPixmap(self.data.get_patch_to_image("ladder2.png")) + if self.img.isNull(): + Log().send(Log.LogType.ERROR, "Failed to load navigation image!") + else: + object = QLabel() + object.setPixmap(self.img) + vbox.addWidget(object) + vbox.addWidget(QLabel(" ")) + + for ri in self.route_segments: + object = QLabel("- " + ri.getText()) + object.setFont(QFont("Arial", 16)) + vbox.addWidget(object) + + self.img = QtGui.QPixmap(ri.getImg()) + if self.img.isNull(): + Log().send(Log.LogType.ERROR, "Failed to load navigation image!") + else: + object = QLabel() + object.setPixmap(self.img) + vbox.addWidget(object) + vbox.addWidget(QLabel(" ")) + + object = QLabel("- " + trobject.getText()) + object.setFont(QFont("Arial", 16)) + vbox.addWidget(object) + + vbox.addWidget(trobject.getImgL()) + vbox.addWidget(QLabel(" ")) + + object = QLabel("ВЫ ПРИБЫЛИ В ПУНКТ НАЗНАЧЕНИЯ") + object.setFont(QFont("Arial", 16, weight=QFont.Bold)) + vbox.addWidget(object) + + self.frame_scroll_widget.setLayout(vbox) + self.frame_scroll_area.setWidget(self.frame_scroll_widget) + del vbox else: self.frame_error_label.setVisible(True) self.frame_scroll_area.setVisible(False) - # TODO result add self.resize_frame() self.update() @@ -248,9 +339,10 @@ def paintEvent(self, event): # draw map painter = QPainter(self) painter.setPen(QPen(QColor(0, 0, 0), 2)) + painter.setFont(QFont("Arial", int(1 * self.zoom_factor))) - for wall in Data().get_walls(self.current_floor): - x1, y1, x2, y2 = wall + for wall in self.data.get_walls(self.current_floor): + x1, y1, x2, y2 = wall.getLocation() scaled_x1 = x1 * self.zoom_factor + self.offset.x() scaled_y1 = y1 * self.zoom_factor + self.offset.y() scaled_x2 = x2 * self.zoom_factor + self.offset.x() @@ -258,8 +350,8 @@ def paintEvent(self, event): painter.drawLine(scaled_x1, scaled_y1, scaled_x2, scaled_y2) painter.setPen(QPen(QColor(0, 0, 0), 1)) - for empty_rooms in Data().get_empty_rooms(self.current_floor): - x, y, width, height = empty_rooms + for empty_rooms in self.data.get_empty_rooms(self.current_floor): + x, y, width, height = empty_rooms.getLocation() scaled_x = x * self.zoom_factor + self.offset.x() scaled_y = y * self.zoom_factor + self.offset.y() scaled_width = width * self.zoom_factor @@ -267,14 +359,14 @@ def paintEvent(self, event): painter.setBrush(QBrush(QColor(41, 41, 41))) painter.drawRect(scaled_x, scaled_y, scaled_width, scaled_height) - for ladder in Data().get_ladders(self.current_floor): + for ladder in self.data.get_ladders(self.current_floor): x, y, width, height = ladder.getLocation() scaled_x = x * self.zoom_factor + self.offset.x() scaled_y = y * self.zoom_factor + self.offset.y() scaled_width = width * self.zoom_factor scaled_height = height * self.zoom_factor if self.has_result: - if self.route_ladders.count(str("123")) == 1: + if str(ladder.getName()) == "1" and len(self.route_ladders) == 1: painter.setBrush(QBrush(QColor(238, 255, 46))) else: painter.setBrush(QBrush(QColor(183, 194, 64))) @@ -282,42 +374,60 @@ def paintEvent(self, event): painter.setBrush(QBrush(QColor(194, 207, 58))) painter.drawRect(scaled_x, scaled_y, scaled_width, scaled_height) - for room in Data().get_rooms(self.current_floor): + for room in self.data.get_rooms(self.current_floor): x, y, width, height = room.getLocation() scaled_x = x * self.zoom_factor + self.offset.x() scaled_y = y * self.zoom_factor + self.offset.y() scaled_width = width * self.zoom_factor scaled_height = height * self.zoom_factor if self.has_result: - if self.input_field.text() == "1": + if self.input_field.text() == room.getName(): painter.setBrush(QBrush(QColor(59, 196, 57))) else: - painter.setBrush(QBrush(QColor(37, 73, 115))) + painter.setBrush(QBrush(QColor(0, 127, 70))) else: painter.setBrush(QBrush(QColor(62, 127, 201))) painter.drawRect(scaled_x, scaled_y, scaled_width, scaled_height) - if str(self.current_floor) == str(Data().get_default_floor()): - point_id, r, x, y = Data().get_you_pos() + painter.setPen(QPen(QColor(255, 255, 255), 3)) + rn = room.getName() + painter.drawText(QPoint(scaled_x + (scaled_width / 2) - 10, scaled_y + (scaled_height / 2) + 10), rn) + painter.setPen(QPen(QColor(0, 0, 0), 2)) + + + if str(self.current_floor) == str(self.data.get_default_floor()): + point_id, r, x, y = self.data.get_you_pos() scaled_x = x * self.zoom_factor + self.offset.x() scaled_y = y * self.zoom_factor + self.offset.y() scaled_r = r * self.zoom_factor painter.setBrush(QBrush(QColor(242, 137, 39))) painter.drawEllipse(scaled_x, scaled_y, scaled_r, scaled_r) + painter.setPen(QPen(QColor(0, 0, 0), 2)) - painter.setPen(QPen(QColor(242, 39, 63), 3)) - for line in self.route_segments: - x1, y1, x2, y2 = line - scaled_x1 = x1 * self.zoom_factor + self.offset.x() - scaled_y1 = y1 * self.zoom_factor + self.offset.y() - scaled_x2 = x2 * self.zoom_factor + self.offset.x() - scaled_y2 = y2 * self.zoom_factor + self.offset.y() - painter.drawLine(scaled_x1, scaled_y1, scaled_x2, scaled_y2) + if self.has_result: + painter.setPen(QPen(QColor(0, 148, 255), 5)) + + if len(self.route_ladders) == 1 and self.current_floor == "1": + x1, y1, x2, y2 = 22, 40, 19, 38 + scaled_x1 = x1 * self.zoom_factor + self.offset.x() + scaled_y1 = y1 * self.zoom_factor + self.offset.y() + scaled_x2 = x2 * self.zoom_factor + self.offset.x() + scaled_y2 = y2 * self.zoom_factor + self.offset.y() + painter.drawLine(scaled_x1, scaled_y1, scaled_x2, scaled_y2) + + for line in self.route_segments: + if self.current_floor == self.data.get_rooms_by_name(self.input_field.text()).getflor(): + x1, y1, x2, y2 = line.getLocation() + scaled_x1 = x1 * self.zoom_factor + self.offset.x() + scaled_y1 = y1 * self.zoom_factor + self.offset.y() + scaled_x2 = x2 * self.zoom_factor + self.offset.x() + scaled_y2 = y2 * self.zoom_factor + self.offset.y() + painter.drawLine(scaled_x1, scaled_y1, scaled_x2, scaled_y2) painter.end() def resizeEvent(self, event): - AFK.action() + self.afk_util.action() # input self.input_field.setGeometry(60, 7, self.width() - 60 * 2, 50) # find @@ -330,11 +440,11 @@ def resizeEvent(self, event): if self.info_frame.isVisible(): self.resize_frame() else: - self.floors_frame.setGeometry(7, self.height() - 30 - 50 * Data().get_floors_count(), 50, - 50 * Data().get_floors_count()) + self.floors_frame.setGeometry(7, self.height() - 30 - 50 * self.data.get_floors_count(), 50, + 50 * self.data.get_floors_count()) def wheelEvent(self, event): - AFK.action() + self.afk_util.action() # frame if self.floors_frame.underMouse(): return @@ -344,6 +454,13 @@ def wheelEvent(self, event): delta = event.angleDelta().y() / 120 zoom_step = 0.9 + if self.zoom_factor < 5.0: + if delta == -1.0: + return + if self.zoom_factor > 50.0: + if delta == 1.0: + return + if delta > 0: self.zoom_factor += zoom_step else: @@ -355,7 +472,7 @@ def wheelEvent(self, event): self.update() def mousePressEvent(self, event): - AFK.action() + self.afk_util.action() if event.button() == Qt.LeftButton: # floor buttons action if self.floors_frame.underMouse(): @@ -368,7 +485,7 @@ def mousePressEvent(self, event): self.origin = event.globalPosition().toPoint() def mouseMoveEvent(self, event): - AFK.action() + self.afk_util.action() if event.buttons() & Qt.LeftButton: delta = event.globalPosition().toPoint() - self.origin # frame @@ -383,3 +500,13 @@ def mouseMoveEvent(self, event): self.origin = event.globalPosition().toPoint() # update self.update() + + def clearLayout(self, qqq): + if qqq is not None: + while qqq.count(): + item = qqq.takeAt(0) + widget = item.widget() + if widget is not None: + widget.deleteLater() + else: + self.clearLayout(item.layout()) \ No newline at end of file diff --git a/app/ui/utils/AfkUtil.py b/app/ui/utils/AfkUtil.py new file mode 100644 index 0000000..973d52d --- /dev/null +++ b/app/ui/utils/AfkUtil.py @@ -0,0 +1,25 @@ +import time + +from app.utils.tools.Log import Log + + +class AfkUtil: + def __init__(self): + self.last_time = time.time() + self.changes = False + + def check_new_changes(self): + current_time = time.time() + + if not self.changes: + return False + + if current_time - self.last_time > 300: # 5 min = 300 sec + self.changes = False + Log().send(Log.LogType.INFO, "Absence of actions in the last 5 minutes. Return to the initial window.") + return True + return False + + def action(self): + self.changes = True + self.last_time = time.time() diff --git a/app/utils/Data.py b/app/utils/Data.py new file mode 100644 index 0000000..c4040ad --- /dev/null +++ b/app/utils/Data.py @@ -0,0 +1,656 @@ +import json + +from functools import * +import os +import sys + +from app.utils.obj.advanced.CorridorlineObj import CorridorlineObj +from app.utils.obj.simple.EmptyRoomObj import EmptyRoomObj +from app.utils.obj.advanced.LadderObj import LadderObj +from app.utils.obj.advanced.RoomObj import RoomObj +from app.utils.obj.simple.WallObj import WallObj +from app.utils.tools.Log import Log + +default_data = """ + { + "name": "MIREA", + "default": { + "id": "MAIN", + "floor": "1", + "x": "22", + "y": "40", + "size": "2" + }, + "floors": { + "1": { + "walls": { + "1": { + "x1": "0", + "y1": "0", + "x2": "45", + "y2": "0" + }, + "2": { + "x1": "45", + "y1": "0", + "x2": "45", + "y2": "45" + }, + "3": { + "x1": "45", + "y1": "45", + "x2": "0", + "y2": "45" + }, + "4": { + "x1": "0", + "y1": "45", + "x2": "0", + "y2": "0" + } + }, + "empty_rooms": { + "103": { + "x": "0", + "y": "35", + "width": "7", + "height": "10" + }, + "105-2": { + "x": "0", + "y": "13", + "width": "10", + "height": "5" + }, + "106-2": { + "x": "0", + "y": "0", + "width": "8", + "height": "10" + }, + "106-3": { + "x": "18", + "y": "0", + "width": "16", + "height": "10" + }, + "o": { + "x": "35", + "y": "38", + "width": "10", + "height": "7" + } + }, + "ladders": { + "1": { + "x": "16", + "y": "30", + "width": "5", + "height": "7" + }, + "2": { + "x": "28", + "y": "30", + "width": "5", + "height": "7" + } + }, + "rooms": { + "101": { + "x": "14", + "y": "10", + "width": "20", + "height": "20" + }, + "102": { + "x": "7", + "y": "35", + "width": "7", + "height": "10" + }, + "104": { + "x": "0", + "y": "23", + "width": "10", + "height": "7" + }, + "105": { + "x": "0", + "y": "18", + "width": "10", + "height": "5" + }, + "106": { + "x": "8", + "y": "0", + "width": "10", + "height": "10" + }, + "108": { + "x": "38", + "y": "19", + "width": "7", + "height": "15" + }, + "109": { + "x": "38", + "y": "6", + "width": "7", + "height": "10" + }, + "110": { + "x": "34", + "y": "0", + "width": "11", + "height": "6" + } + }, + "corridor": { + "1.1-1.23": { + "x1": "10", + "y1": "3", + "x2": "10", + "y2": "5", + "a" : ["1.1", "somestring2"] + }, + "1.1-1.23": { + "x1": "10", + "y1": "3", + "x2": "10", + "y2": "5", + "a" : ["1.1", "somestring2"] + } + } + }, + "2": { + "walls": { + "1": { + "x1": "0", + "y1": "0", + "x2": "45", + "y2": "0" + }, + "2": { + "x1": "45", + "y1": "0", + "x2": "45", + "y2": "45" + }, + "3": { + "x1": "45", + "y1": "45", + "x2": "0", + "y2": "45" + }, + "4": { + "x1": "0", + "y1": "45", + "x2": "0", + "y2": "0" + } + }, + "ladders": { + "1": { + "x": "16", + "y": "30", + "width": "5", + "height": "7" + }, + "2": { + "x": "28", + "y": "30", + "width": "5", + "height": "7" + } + }, + "empty_rooms": { + "200-2": { + "x": "14", + "y": "10", + "width": "19", + "height": "2" + }, + "204-2": { + "x": "38", + "y": "10", + "width": "7", + "height": "8" + }, + "204-3": { + "x": "0", + "y": "10", + "width": "14", + "height": "16" + } + }, + "rooms": { + "200": { + "x": "14", + "y": "12", + "width": "20", + "height": "18" + }, + "201": { + "x": "0", + "y": "0", + "width": "10", + "height": "7" + }, + "202": { + "x": "10", + "y": "0", + "width": "15", + "height": "7" + }, + "203": { + "x": "25", + "y": "0", + "width": "15", + "height": "7" + }, + "204": { + "x": "40", + "y": "0", + "width": "5", + "height": "10" + }, + "206": { + "x": "38", + "y": "18", + "width": "7", + "height": "12" + }, + "208": { + "x": "0", + "y": "26", + "width": "14", + "height": "10" + }, + "207": { + "x": "0", + "y": "36", + "width": "14", + "height": "9" + } + }, + "corridor": { + "208-207-f2": { + "x1": "10", + "y1": "3", + "x2": "10", + "y2": "5", + "a1": ["208", "207"], + "a2": "5" + }, + "1.1-1.3": { + "x1": "10", + "y1": "3", + "x2": "10", + "y2": "5", + "a" : ["1.1", "somestring2"] + } + } + } + } + } + """ + + +class Data: + _instance = None + _init_already = False + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super().__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not Data._init_already: + self.current_directory = os.getcwd() + self.data_directory = os.path.join(self.current_directory, "UniversityNavigationSystem") + self.img_directory = os.path.join(self.data_directory, "images") + if not os.path.exists(self.img_directory): + os.makedirs(self.img_directory) + self.data_file = os.path.join(self.data_directory, "map.json") + self._generate_file() + # Temp + self.all_names = None + self.all_rooms = {} + Data._init_already = True + self.all_lines = {} + + self.get_lines("1") + self.get_lines("2") + + def _generate_file(self): + """ + Load map.json file (PROTECTED) + """ + # Creating or uploading a file + if os.path.exists(self.data_file): + with open(self.data_file, 'r') as file: + try: + self.data = json.load(file) + except json.decoder.JSONDecodeError: + Log().send(Log.LogType.WARNING, "File map.json is corrupted or contains a JSON validation error.") + sys.exit() + else: + Log().send(Log.LogType.WARNING, "File map.json was not found! Creating a new file.") + self.data = json.loads(default_data) + with open(self.data_file, 'w') as file: + self.data = json.loads(default_data) + json.dump(self.data, file, ensure_ascii=False, indent=4, sort_keys=True) + # Some constant data that is frequently accessed. Created for optimization and acceleration. + try: + self.you_pos = ( + str(self.data["default"]["id"]), int(self.data["default"]["size"]), int(self.data["default"]["x"]), int(self.data["default"]["y"])) + self.floors_count = len(list(self.data["floors"].keys())) + except: + Log().send(Log.LogType.ERROR, "The section \"default\" could not be loaded!") + self.you_pos = ("you_pos", 10, 0, 0) + self.floors_count = 1 + + @lru_cache + def is_valid_name(self, name: str): + """ + Checking the existence of a room by its name + :param str name: room name + :return: result + :rtype: bool + """ + result = name in self.all_names + Log().send(Log.LogType.INFO, "Find use: text = \"" + str(name).lower() + "\", result = " + str(result)) + return result + + def get_rooms_by_name(self, name: str): + """ + Get room by name + :param str name: room name + :return: room object + :rtype: RoomObj + """ + if self.is_valid_name(name): + return self.all_rooms.get(name) + else: + Log().send(Log.LogType.ERROR, "The room \"" + str(name) + "\" does not exist!") + return None + + def get_name(self): + """ + Get the name of the plan + :return: name + :rtype: str + """ + try: + return str(self.data["name"]) + except: + Log().send(Log.LogType.ERROR, "The section \"name\" could not be loaded!") + return "NAME" + + def get_you_pos(self): + """ + Get the information stand position + :return: (id: str, size: int, x: int, y: int) + :rtype: tuple + """ + return self.you_pos + + @lru_cache + def get_floors(self): + """ + Get a list of names of all floors + :return: (name1: str, name2: str ...) + :rtype: tuple + """ + try: + return tuple(sorted(self.data["floors"].keys(), reverse=True)) + except: + Log().send(Log.LogType.ERROR, "The section \"floors\" could not be loaded!") + return tuple("1") + + def get_floors_count(self): + """ + Get the number of all floors + :return: number of all floors + :rtype: int + """ + return self.floors_count + + @lru_cache + def get_default_floor(self): + """ + Get the default floor name. + :return: floor name + :rtype: str + """ + try: + return str(self.data["default"]["floor"]) + except: + Log().send(Log.LogType.ERROR, "The section \"default.floor\" could not be loaded!") + return 1 + + + @lru_cache + def get_rooms_names(self): + """ + Get a list of names of all rooms + :return: (name1: str, name2: str ...) + :rtype: tuple + """ + try: + names = [] + for f in list(self.data["floors"].keys()): + names += [n for n in self.data["floors"][f]["rooms"]] + self.get_rooms(f) + self.all_names = names + return tuple(names) + except: + Log().send(Log.LogType.ERROR, "The section \"floors.rooms\" could not be loaded!") + return tuple() + + @lru_cache + def get_walls(self, floor_name: str): + """ + Get a list of walls + :param str floor_name: floor name + :return: (WallObj, WallObj, ...) + :rtype: list + """ + floor_name = str(floor_name) + try: + walls = [] + for f in list(self.data["floors"][floor_name]["walls"].keys()): + walls.append(WallObj( + int(self.data["floors"][floor_name]["walls"][f]["x1"]), + int(self.data["floors"][floor_name]["walls"][f]["y1"]), + int(self.data["floors"][floor_name]["walls"][f]["x2"]), + int(self.data["floors"][floor_name]["walls"][f]["y2"]) + )) + return walls + except: + Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".walls\" could not be loaded!") + return [] + + @lru_cache + def get_empty_rooms(self, floor_name: str): + """ + Get a list of empty rooms + :param str floor_name: floor name + :return: (EmptyRoomObj, EmptyRoomObj, ...) + :rtype: list + """ + floor_name = str(floor_name) + try: + rooms = [] + for f in list(self.data["floors"][floor_name]["empty_rooms"].keys()): + rooms.append(EmptyRoomObj( + int(self.data["floors"][floor_name]["empty_rooms"][f]["x"]), + int(self.data["floors"][floor_name]["empty_rooms"][f]["y"]), + int(self.data["floors"][floor_name]["empty_rooms"][f]["width"]), + int(self.data["floors"][floor_name]["empty_rooms"][f]["height"]) + )) + return rooms + except: + Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".empty_rooms\" could not be loaded!") + return [] + + @lru_cache + def get_ladders(self, floor_name: str): + """ + Get a list of ladders + :param str floor_name: floor name + :return: (LadderObj, LadderObj, ...) + :rtype: list + """ + floor_name = str(floor_name) + try: + rooms = [] + for f in list(self.data["floors"][floor_name]["ladders"].keys()): + rooms.append( + LadderObj(str(f), + int(self.data["floors"][floor_name]["ladders"][f]["x"]), + int(self.data["floors"][floor_name]["ladders"][f]["y"]), + int(self.data["floors"][floor_name]["ladders"][f]["width"]), + int(self.data["floors"][floor_name]["ladders"][f]["height"]), "")) + return rooms + except: + Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".empty_rooms\" could not be loaded!") + return [] + + @lru_cache + def get_rooms(self, floor_name: str): + """ + Get a list of rooms + :param str floor_name: floor name + :return: (RoomObj, RoomObj, ...) + :rtype: list + """ + try: + rooms = [] + for f in list(self.data["floors"][floor_name]["rooms"].keys()): + tro = RoomObj(str(f), + int(self.data["floors"][floor_name]["rooms"][f]["x"]), + int(self.data["floors"][floor_name]["rooms"][f]["y"]), + int(self.data["floors"][floor_name]["rooms"][f]["width"]), + int(self.data["floors"][floor_name]["rooms"][f]["height"]), os.path.join(self.img_directory, floor_name + "." + f + ".png"), floor_name) + rooms.append(tro) + self.all_rooms[tro.getName()] = tro + return rooms + except: + Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".rooms\" could not be loaded!") + return [] + + @lru_cache + def get_lines(self, floor_name: str): + """ + Get a list of lines + :param str floor_name: floor name + :return: (Obj, Obj, ...) + :rtype: list + """ + # try: + lines = [] + if floor_name == "2": + tro2 = CorridorlineObj(str("208-207-f2"), + int(19), + int(38), + int(14), + int(38), + os.path.join(self.img_directory, "corridor.f2-t-108.png"), + str("Поверните направо и пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + tro2 = CorridorlineObj(str("200-f2"), + int(19), + int(38), + int(25), + int(38), + os.path.join(self.img_directory, "corridor.200-f2.png"), + str("Поверните налево и пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + tro2 = CorridorlineObj(str("f2-t"), + int(25), + int(38), + int(36), + int(38), + os.path.join(self.img_directory, "corridor.f2-t.png"), + str("Пройдите перёд и поверните налево")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + tro2 = CorridorlineObj(str("f2-t-206"), + int(36), + int(38), + int(36), + int(27), + os.path.join(self.img_directory, "corridor.f2-t-206.png"), + str("Пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + tro2 = CorridorlineObj(str("f2-t-203-204"), + int(36), + int(27), + int(36), + int(8), + os.path.join(self.img_directory, "corridor.f2-t-203-204.png"), + str("Пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + tro2 = CorridorlineObj(str("f2-t-201-202"), + int(36), + int(8), + int(10), + int(8), + os.path.join(self.img_directory, "corridor.f2-t-201-202.png"), + str("Пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + # for f in list(self.data["floors"][floor_name]["corridor"].keys()): + # tro2 = CorridorlineObj(str(f), + # int(self.data["floors"][floor_name]["corridor"][f]["x1"]), + # int(self.data["floors"][floor_name]["corridor"][f]["y1"]), + # int(self.data["floors"][floor_name]["corridor"][f]["x2"]), + # int(self.data["floors"][floor_name]["corridor"][f]["y2"]), + # os.path.join(self.img_directory, "corridor" + floor_name + "." + f + ".png"), + # int(self.data["floors"][floor_name]["corridor"][f]["text"]), + # list(self.data["floors"][floor_name]["corridor"][f]["a"])) + # lines.append(tro2) + # self.all_lines[tro2.getName()] = tro2 + else: + tro2 = CorridorlineObj(str("f1-t-108"), + int(22), + int(38), + int(37), + int(37), + os.path.join(self.img_directory, "corridor.f1-t-108.png"), + str("Поверните направо и пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + tro2 = CorridorlineObj(str("f1-t-110-109"), + int(37), + int(37), + int(37), + int(15), + os.path.join(self.img_directory, "corridor.f1-t-110-109.png"), + str("Пройдите перёд")) + self.all_lines[str(tro2.getName())] = tro2 + lines.append(tro2) + + return lines + # except: + # Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".corridor\" could not be loaded!") + # return [] + + def get_patch_to_image(self, name: str): + return os.path.join(self.img_directory, name) + + @lru_cache + def get_lines_by_name(self, name: str): + return self.all_lines.get(name) \ No newline at end of file diff --git a/app/utils/Navigation.py b/app/utils/Navigation.py new file mode 100644 index 0000000..975b440 --- /dev/null +++ b/app/utils/Navigation.py @@ -0,0 +1,101 @@ +import matplotlib.pyplot as plt +import networkx as nx + +from app.utils.Data import Data + + +# G = nx.Graph() # создаём объект графа +# +# # определяем список узлов (ID узлов) +# nodes = ["1,1,1", 1, 2, 3, 4, 5] +# +# # определяем список рёбер +# # список кортежей, каждый из которых представляет ребро +# # кортеж (id_1, id_2) означает, что узлы id_1 и id_2 соединены ребром +# edges = [("1,1,1", 2), (1, 3), (2, 3), (2, 4), (3, 5), (5, 5)] +# +# # добавляем информацию в объект графа +# G.add_nodes_from(nodes) +# G.add_edges_from(edges) +# +# # рисуем граф и отображаем его +# nx.draw(G, with_labels=True, font_weight='bold') +# plt.show() + + +class Navigation: + _instance = None + _init_already = False + + def __new__(cls, *args, **kwargs): + if not cls._instance: + cls._instance = super().__new__(cls, *args, **kwargs) + return cls._instance + + def __init__(self): + if not Navigation._init_already: + self.d = Data() + + self.graph1 = nx.Graph() + self.nodes1 = [] + self.edges1 = [] + + self.graph2 = nx.Graph() + self.nodes2 = [] + self.edges2 = [] + + # Load floors + self.graph1.add_node("f1") + self.graph2.add_node("f2") + + for room in self.d.get_rooms("1"): + self.graph1.add_node(room.getName()) + + self.graph2.add_edge("f1", room.getName(), weight=1) + + for room in self.d.get_rooms("2"): + self.graph2.add_node(room.getName()) + + self.graph1.add_edge("f1", "101", weight=1) + + self.graph1.add_edge("f1", "f1-t-108", weight=1) + self.graph1.add_edge("f1-t-108", "108", weight=1) + + self.graph1.add_edge("f1-t-108", "f1-t-110-109", weight=1) + self.graph1.add_edge("f1-t-110-109", "109", weight=1) + self.graph1.add_edge("f1-t-110-109", "110", weight=1) + + + + self.graph2.add_edge("f2", "208-207-f2", weight=1) + + self.graph2.add_edge("f2", "200-f2", weight=1) + self.graph2.add_edge("200-f2", "200", weight=1) + + self.graph2.add_edge("208-207-f2", "207", weight=1) + self.graph2.add_edge("208-207-f2", "208", weight=1) + + self.graph2.add_edge("200-f2", "f2-t", weight=1) + + self.graph2.add_edge("f2-t", "f2-t-206", weight=1) + self.graph2.add_edge("f2-t-206", "206", weight=1) + + self.graph2.add_edge("f2-t-206", "f2-t-203-204", weight=1) + self.graph2.add_edge("f2-t-203-204", "203", weight=1) + self.graph2.add_edge("f2-t-203-204", "204", weight=1) + + self.graph2.add_edge("f2-t-203-204", "f2-t-201-202", weight=1) + self.graph2.add_edge("f2-t-201-202", "201", weight=1) + self.graph2.add_edge("f2-t-201-202", "202", weight=1) + + + #self.graph2.add_edge(n, room.getCorridor(), weight=1) + + + Navigation._init_already = True + + def run(self, end_point_name: str, z): + if z == "2": + return nx.shortest_path(self.graph2, "f2", str(end_point_name)) + else: + return nx.shortest_path(self.graph1, "f1", str(end_point_name)) diff --git a/app/utils/obj/advanced/CorridorlineObj.py b/app/utils/obj/advanced/CorridorlineObj.py new file mode 100644 index 0000000..d089978 --- /dev/null +++ b/app/utils/obj/advanced/CorridorlineObj.py @@ -0,0 +1,36 @@ +import uuid +from functools import lru_cache + + +class CorridorlineObj: + def __init__(self, name: str, x1: int, y1: int, x2: int, y2: int, img_name: str, img_text): + self.uuid = uuid.uuid4() + self.name = name + + self.x1 = x1 + self.y1 = y1 + self.x2 = x2 + self.y2 = y2 + + self.img_name = img_name + self.img_text = img_text + self.points = 0 + + + def getId(self): + return self.uuid + + def getName(self): + return self.name + + @lru_cache + def getLocation(self): + return tuple([self.x1, self.y1, self.x2, self.y2]) + + def getImg(self): + return self.img_name + + def getText(self): + return self.img_text + def getPoints1(self): + return self.points \ No newline at end of file diff --git a/utils/obj/LadderObj.py b/app/utils/obj/advanced/LadderObj.py similarity index 50% rename from utils/obj/LadderObj.py rename to app/utils/obj/advanced/LadderObj.py index dc4ea09..8079e9b 100644 --- a/utils/obj/LadderObj.py +++ b/app/utils/obj/advanced/LadderObj.py @@ -1,16 +1,31 @@ +import uuid +from functools import lru_cache + + class LadderObj: - def __init__(self, name: str, x: int, y: int, width: int, height: int): + def __init__(self, name: str, x: int, y: int, width: int, height: int, img_name: str): + self.uuid = uuid.uuid4() self.name = name + self.x = x self.y = y self.width = width self.height = height - def getLocation(self): - return tuple([self.x, self.y, self.width, self.height]) + self.img_name = img_name + + def getId(self): + return self.uuid def getName(self): return self.name - def getCorridor(self): - return "self.name" \ No newline at end of file + @lru_cache + def getLocation(self): + return tuple([self.x, self.y, self.width, self.height]) + + def getImg(self): + return self.img_name + + def getText(self): + return "Зайдите на лестницу" diff --git a/app/utils/obj/advanced/RoomObj.py b/app/utils/obj/advanced/RoomObj.py new file mode 100644 index 0000000..2c2038a --- /dev/null +++ b/app/utils/obj/advanced/RoomObj.py @@ -0,0 +1,51 @@ +import uuid +from functools import lru_cache +import os + +from PySide6 import QtGui +from PySide6.QtWidgets import QLabel + +from app.utils.tools.Log import Log + + +class RoomObj: + def __init__(self, name: str, x: int, y: int, width: int, height: int, img_name: str, flor: str): + self.uuid = uuid.uuid4() + self.name = name + + self.x = x + self.y = y + self.width = width + self.height = height + + self.img_name = img_name + + self.flor = flor + + def getId(self): + return self.uuid + + def getName(self): + return self.name + + @lru_cache + def getLocation(self): + return tuple([self.x, self.y, self.width, self.height]) + + def getImg(self): + return self.img_name + + def getText(self): + return "Откройте дверь" + + def getflor(self): + return self.flor + + def getImgL(self): + img = QtGui.QPixmap(self.img_name) + if img.isNull(): + Log().send(Log.LogType.ERROR, "Failed to load navigation image!") + else: + object = QLabel() + object.setPixmap(img) + return object diff --git a/app/utils/obj/simple/EmptyRoomObj.py b/app/utils/obj/simple/EmptyRoomObj.py new file mode 100644 index 0000000..a418f08 --- /dev/null +++ b/app/utils/obj/simple/EmptyRoomObj.py @@ -0,0 +1,13 @@ +from functools import lru_cache + + +class EmptyRoomObj: + def __init__(self, x: int, y: int, width: int, height: int): + self.x = x + self.y = y + self.width = width + self.height = height + + @lru_cache + def getLocation(self): + return tuple([self.x, self.y, self.width, self.height]) diff --git a/app/utils/obj/simple/WallObj.py b/app/utils/obj/simple/WallObj.py new file mode 100644 index 0000000..815a9cf --- /dev/null +++ b/app/utils/obj/simple/WallObj.py @@ -0,0 +1,13 @@ +from functools import lru_cache + + +class WallObj: + def __init__(self, x1: int, y1: int, x2: int, y2: int): + self.x1 = x1 + self.y1 = y1 + self.x2 = x2 + self.y2 = y2 + + @lru_cache + def getLocation(self): + return tuple([self.x1, self.y1, self.x2, self.y2]) diff --git a/utils/tools/Log.py b/app/utils/tools/Log.py similarity index 100% rename from utils/tools/Log.py rename to app/utils/tools/Log.py diff --git a/utils/tools/UpdateChecker.py b/app/utils/tools/UpdateChecker.py similarity index 96% rename from utils/tools/UpdateChecker.py rename to app/utils/tools/UpdateChecker.py index 57d8e13..258e593 100644 --- a/utils/tools/UpdateChecker.py +++ b/app/utils/tools/UpdateChecker.py @@ -1,6 +1,6 @@ import requests -from utils.tools.Log import Log +from app.utils.tools.Log import Log def check(ver: str): diff --git a/main.py b/main.py index 9430927..374ab80 100644 --- a/main.py +++ b/main.py @@ -3,12 +3,12 @@ from PySide6.QtWidgets import QApplication import os -from ui.UI import UI -from utils.Data import Data -from utils.tools import UpdateChecker -from utils.tools.Log import Log +from app.ui.UI import UI +from app.utils.Data import Data +from app.utils.tools import UpdateChecker +from app.utils.tools.Log import Log -APP_VERSION = "0.0.4" +APP_VERSION = "0.0.7" # BUILD @@ -19,19 +19,17 @@ app_directory = os.path.join(os.getcwd(), "UniversityNavigationSystem") if not os.path.exists(app_directory): os.makedirs(app_directory) - # Init logs system log = Log() log.send(Log.LogType.INFO, "Launching the program...") # Checking for updates log.send(Log.LogType.INFO, "Checking for updates...") - UpdateChecker.check(APP_VERSION) + # UpdateChecker.check(APP_VERSION) # Init data system log.send(Log.LogType.INFO, "Uploading data...") data = Data() - #TODO # Loading the window Log().send(Log.LogType.INFO, "Loading the window...") @@ -39,7 +37,7 @@ u_name = "Name" try: app = QApplication(sys.argv) - window = UI(Data().get_name()) + window = UI(str(Data().get_name() + " | UniversityNavigationSystem")) window.show() except: Log().send(Log.LogType.ERROR, "The window could not be created!") diff --git a/ui/AFK.py b/ui/AFK.py deleted file mode 100644 index 199ee22..0000000 --- a/ui/AFK.py +++ /dev/null @@ -1,18 +0,0 @@ -import time - -from utils.tools.Log import Log - -last_time = time.time() - - -def check_time(): - current_time = time.time() - if current_time - last_time > 300: # 5 min = 300 sec - Log().send(Log.LogType.INFO, "Absence of actions in the last 5 minutes. Return to the initial window.") - return True - return False - - -def action(): - global last_time - last_time = time.time() diff --git a/utils/Data.py b/utils/Data.py deleted file mode 100644 index c053d9a..0000000 --- a/utils/Data.py +++ /dev/null @@ -1,357 +0,0 @@ -import json - -from functools import * -import os -import sys - -from utils.obj.LadderObj import LadderObj -from utils.obj.RoomObj import RoomObj -from utils.tools.Log import Log - -default_data = """ - { - "name": "Example", - "default": { - "id": "MAIN", - "floor": "1", - "x": "0", - "y": "0", - "size": "5" - }, - "floors": { - "1": { - "walls": { - "1": { - "x1": "-5", - "y1": "-5", - "x2": "5", - "y2": "5" - }, - "2": { - "x1": "1", - "y1": "3", - "x2": "4", - "y2": "5" - } - }, - "empty_rooms": { - "1": { - "x": "15", - "y": "15", - "width": "5", - "height": "5" - }, - "2": { - "x": "20", - "y": "15", - "width": "5", - "height": "5" - } - }, - "ladders": { - "1": { - "x": "20", - "y": "30", - "width": "5", - "height": "5" - }, - "2": { - "x": "20", - "y": "35", - "width": "5", - "height": "5" - } - }, - "rooms": { - "1.1": { - "x": "10", - "y": "0", - "width": "5", - "height": "4" - }, - "2.1": { - "x": "10", - "y": "5", - "width": "4", - "height": "4" - } - } - }, - "2": { - "walls": { - "1": { - "x1": "0", - "y1": "0", - "x2": "10", - "y2": "0" - }, - "2": { - "x1": "0", - "y1": "0", - "x2": "0", - "y2": "10" - } - }, - "empty_rooms": { - "1": { - "x": "2", - "y": "2", - "width": "5", - "height": "10" - }, - "2": { - "x": "9", - "y": "9", - "width": "5", - "height": "10" - } - }, - "ladders": { - "1": { - "x": "-10", - "y": "0", - "width": "10", - "height": "10" - }, - "2": { - "x": "-20", - "y": "0", - "width": "10", - "height": "10" - } - }, - "rooms": { - "3.1": { - "x": "20", - "y": "20", - "width": "10", - "height": "10" - }, - "3.2": { - "x": "20", - "y": "30", - "width": "10", - "height": "10" - } - } - } - } - } - """ - - -class Data: - _instance = None - _init_already = False - - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super().__new__(cls, *args, **kwargs) - return cls._instance - - def __init__(self): - if not Data._init_already: - self.current_directory = os.getcwd() - self.data_directory = os.path.join(self.current_directory, "UniversityNavigationSystem") - self.data_file = os.path.join(self.data_directory, "map.json") - self._generate_file() - # Temp - self.all_names = None - Data._init_already = True - - def _generate_file(self): - """ - Load map.json file (PROTECTED) - """ - # Creating or uploading a file - if os.path.exists(self.data_file): - with open(self.data_file, 'r') as file: - try: - self.data = json.load(file) - except json.decoder.JSONDecodeError: - Log().send(Log.LogType.WARNING, "File map.json is corrupted or contains a JSON validation error.") - sys.exit() - else: - Log().send(Log.LogType.WARNING, "File map.json was not found! Creating a new file.") - with open(self.data_file, 'w') as file: - self.data = json.loads(default_data) - json.dump(self.data, file, ensure_ascii=False, indent=4, sort_keys=True) - # Some constant data that is frequently accessed. Created for optimization and acceleration. - try: - self.you_pos = ( - str(self.data["default"]["id"]), int(self.data["default"]["size"]), int(self.data["default"]["x"]), int(self.data["default"]["y"])) - self.floors_count = len(list(self.data["floors"].keys())) - except: - Log().send(Log.LogType.ERROR, "The section \"default\" could not be loaded!") - self.you_pos = ("you_pos", 10, 0, 0) - self.floors_count = 1 - - @lru_cache - def is_valid_name(self, name: str): - """ - Checking the existence of a room by its name - :param str name: room name - :return: result - :rtype: bool - """ - result = name in self.all_names - Log().send(Log.LogType.INFO, "Find use: text = \"" + str(name).lower() + "\", result = " + str(result)) - return result - - def get_name(self): - """ - Get the name of the plan - :return: name - :rtype: str - """ - try: - return str(self.data["name"]) - except: - Log().send(Log.LogType.ERROR, "The section \"name\" could not be loaded!") - return "NAME" - - def get_you_pos(self): - """ - Get the information stand position - :return: (id: str, size: int, x: int, y: int) - :rtype: tuple - """ - return self.you_pos - - @lru_cache - def get_floors(self): - """ - Get a list of names of all floors - :return: (name1: str, name2: str ...) - :rtype: tuple - """ - try: - return tuple(sorted(self.data["floors"].keys(), reverse=True)) - except: - Log().send(Log.LogType.ERROR, "The section \"floors\" could not be loaded!") - return tuple("1") - - def get_floors_count(self): - """ - Get the number of all floors - :return: number of all floors - :rtype: int - """ - return self.floors_count - - @lru_cache - def get_default_floor(self): - """ - Get the default floor name. - :return: floor name - :rtype: str - """ - try: - return str(self.data["default"]["floor"]) - except: - Log().send(Log.LogType.ERROR, "The section \"default.floor\" could not be loaded!") - return 1 - - @lru_cache - def get_rooms_names(self): - """ - Get a list of names of all rooms - :return: (name1: str, name2: str ...) - :rtype: tuple - """ - try: - names = [] - for f in list(self.data["floors"].keys()): - names += [n for n in self.data["floors"][f]["rooms"]] - self.all_names = names - return tuple(names) - except: - Log().send(Log.LogType.ERROR, "The section \"floors.rooms\" could not be loaded!") - return tuple() - - @lru_cache - def get_walls(self, floor_name: str): - """ - Get a list of walls - :param str floor_name: floor name - :return: (x1: int, y1: int, x2: int, y2: int) - :rtype: list - """ - floor_name = str(floor_name) - try: - walls = [] - for f in list(self.data["floors"][floor_name]["walls"].keys()): - walls.append(tuple([int(self.data["floors"][floor_name]["walls"][f]["x1"]), - int(self.data["floors"][floor_name]["walls"][f]["y1"]), - int(self.data["floors"][floor_name]["walls"][f]["x2"]), - int(self.data["floors"][floor_name]["walls"][f]["y2"])])) - return walls - except: - Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".walls\" could not be loaded!") - return [] - - @lru_cache - def get_empty_rooms(self, floor_name: str): - """ - Get a list of empty rooms - :param str floor_name: floor name - :return: (x: int, y: int, width: int, height: int) - :rtype: list - """ - floor_name = str(floor_name) - try: - rooms = [] - for f in list(self.data["floors"][floor_name]["empty_rooms"].keys()): - rooms.append(tuple([int(self.data["floors"][floor_name]["empty_rooms"][f]["x"]), - int(self.data["floors"][floor_name]["empty_rooms"][f]["y"]), - int(self.data["floors"][floor_name]["empty_rooms"][f]["width"]), - int(self.data["floors"][floor_name]["empty_rooms"][f]["height"])])) - return rooms - except: - Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".empty_rooms\" could not be loaded!") - return [] - - @lru_cache - def get_ladders(self, floor_name: str): - """ - Get a list of ladders - :param str floor_name: floor name - :return: (LadderObj, LadderObj, ...) - :rtype: list - """ - floor_name = str(floor_name) - try: - rooms = [] - for f in list(self.data["floors"][floor_name]["empty_rooms"].keys()): - rooms.append( - LadderObj(str(f), - int(self.data["floors"][floor_name]["empty_rooms"][f]["x"]), - int(self.data["floors"][floor_name]["empty_rooms"][f]["y"]), - int(self.data["floors"][floor_name]["empty_rooms"][f]["width"]), - int(self.data["floors"][floor_name]["empty_rooms"][f]["height"]))) - return rooms - except: - Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".empty_rooms\" could not be loaded!") - return [] - - @lru_cache - def get_rooms(self, floor_name: str): - """ - Get a list of rooms - :param str floor_name: floor name - :return: (RoomObj, RoomObj, ...) - :rtype: list - """ - try: - rooms = [] - for f in list(self.data["floors"][floor_name]["rooms"].keys()): - rooms.append( - RoomObj(str(f), - int(self.data["floors"][floor_name]["rooms"][f]["x"]), - int(self.data["floors"][floor_name]["rooms"][f]["y"]), - int(self.data["floors"][floor_name]["rooms"][f]["width"]), - int(self.data["floors"][floor_name]["rooms"][f]["height"]))) - return rooms - except: - Log().send(Log.LogType.ERROR, "The section \"floors." + floor_name + ".rooms\" could not be loaded!") - return [] diff --git a/utils/Navigation.py b/utils/Navigation.py deleted file mode 100644 index 9b76498..0000000 --- a/utils/Navigation.py +++ /dev/null @@ -1,74 +0,0 @@ -import matplotlib.pyplot as plt -import networkx as nx - -from utils.Data import Data - -G = nx.Graph() # создаём объект графа - -# определяем список узлов (ID узлов) -nodes = ["1,1,1", 1, 2, 3, 4, 5] - -# определяем список рёбер -# список кортежей, каждый из которых представляет ребро -# кортеж (id_1, id_2) означает, что узлы id_1 и id_2 соединены ребром -edges = [("1,1,1", 2), (1, 3), (2, 3), (2, 4), (3, 5), (5, 5)] - -# добавляем информацию в объект графа -G.add_nodes_from(nodes) -G.add_edges_from(edges) - -# рисуем граф и отображаем его -nx.draw(G, with_labels=True, font_weight='bold') -plt.show() - - -class Navigation: - _instance = None - _init_already = False - - G = nx.Graph() - - def __new__(cls, *args, **kwargs): - if not cls._instance: - cls._instance = super().__new__(cls, *args, **kwargs) - return cls._instance - - def __init__(self): - if not Navigation._init_already: - self.d = Data() - - self.graph = nx.Graph() - self.nodes = [] - self.edges = [] - - # Load floors - self.nodes.append(self.d.get_you_pos()[0]) - for floor in self.d.get_floors(): - # load rooms - for room in self.d.get_rooms(floor): - n = str(floor + ".room." + room.getName()) - - self.nodes.append(n) - self.graph.add_edge(n, room.getCorridor(), weight=1) - - # load ladders - for ladder in self.d.get_ladders(floor): - n = str(floor + ".ladder." + ladder.getName()) - self.nodes.append(n) - self.graph.add_edge(n, ladder.getCorridor(), weight=1) - - # load corridors - for corridor in self.d.get_corridors(floor): - n = str(floor + ".corridor." + corridor.getName()) - self.nodes.append(n) - #self.edges.append(tuple(n, ladder.)) - - self.graph.add_nodes_from(self.nodes) - self.graph.add_edges_from(self.edges) - - - - Navigation._init_already = True - - def get_edges(self, end_point): - return nx.shortest_path(self.graph, self.d.get_you_pos()[0], str(end_point)) diff --git a/utils/obj/RoomObj.py b/utils/obj/RoomObj.py deleted file mode 100644 index 6f241e6..0000000 --- a/utils/obj/RoomObj.py +++ /dev/null @@ -1,16 +0,0 @@ -class RoomObj: - def __init__(self, name: str,x: int, y: int, width: int, height: int): - self.name = name - self.x = x - self.y = y - self.width = width - self.height = height - - def getLocation(self): - return tuple([self.x, self.y, self.width, self.height]) - - def getName(self): - return self.name - - def getCorridor(self): - return "" \ No newline at end of file