Найти первую свободную область через запрос MySQL

Узнай цену своей работы

Формулировка задачи:

Приложил картинку: в базе хранятся закрашенные области (серый цвет), как координаты левого верхнего угла и правого нижнего, т.е. ЧЕТЫРЕ числа (х1,у1,х2,у2). Как запросом в базу MySql получить координаты свободной области, если условия такие: п.1 начиная сверху слева найти свободную область размером 1х1 п.2 начиная сверху слева найти свободную область размером 2х2 То есть для п.1 ответ должен быть 0,0,1,1 (голубой квадратик) для п.2 = 6,0,8,2 (оранжевый квадратик) Сэмпл базы:
Листинг программы
  1. CREATE TABLE `items` (
  2. `id` INT(11) NOT NULL,
  3. `x1` SMALLINT(4) NOT NULL,
  4. `y1` SMALLINT(4) NOT NULL,
  5. `x2` SMALLINT(4) NOT NULL,
  6. `y2` SMALLINT(4) NOT NULL
  7. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  8. INSERT INTO `items` (`id`, `x1`, `y1`, `x2`, `y2`) VALUES
  9. (1, 3, 0, 6, 4),
  10. (2, 8, 0, 9, 2),
  11. (3, 0, 1, 2, 2),
  12. (4, 0, 3, 2, 5),
  13. (5, 7, 3, 9, 7),
  14. (6, 1, 6, 6, 7),
  15. (7, 1, 8, 2, 10);

Решение задачи: «Найти первую свободную область через запрос MySQL»

textual
Листинг программы
  1. CREATE TABLE items (
  2.   id INT UNSIGNED NOT NULL AUTO_INCREMENT,
  3.   t SMALLINT NOT NULL,
  4.   l SMALLINT NOT NULL,
  5.   b SMALLINT NOT NULL,
  6.   r SMALLINT NOT NULL,
  7.   ls linestring NOT NULL,
  8.   CONSTRAINT pk_items_id PRIMARY KEY(id),
  9.   spatial INDEX (ls)
  10. ) engine = myisam DEFAULT CHARACTER SET = cp1251;
  11.  
  12. delimiter ~
  13. CREATE definer = CURRENT_USER TRIGGER bi_items BEFORE INSERT ON items
  14. FOR each ROW
  15. BEGIN
  16.   SET NEW.ls = linestring(point(NEW.t, NEW.l), point(NEW.b, NEW.r));
  17. END~
  18.  
  19. CREATE definer = CURRENT_USER FUNCTION getCell (
  20.   asize INT,     -- размер квадратика
  21.   maxsize INT)   -- размер проверяемой квадратной (обязательно!) матрицы [0, 1, ..., maxsize]
  22. RETURNS linestring
  23. BEGIN
  24.   DECLARE nR INT DEFAULT 0; -- row
  25.   DECLARE nC INT DEFAULT 0; -- col
  26.   DECLARE find tinyint DEFAULT 1;
  27.  
  28. X:  repeat
  29.     SELECT
  30.       SUM(intersects(linestring(point(nR + 0.1, nC + 0.1), point(nR + asize - 0.1, nC + asize - 0.1)), ls))
  31.        INTO find
  32.     FROM items;
  33.    
  34.     IF find > 0 THEN
  35.       IF (nC + asize + 1) > maxsize THEN
  36.         SET nC = 0;
  37.         IF (nR + asize + 1) > maxsize THEN
  38.           leave X;
  39.         ELSE
  40.           SET nR = nR + 1;
  41.         END IF;
  42.       ELSE
  43.         SET nC = nC + 1;
  44.       END IF;
  45.     END IF;
  46.   until find = 0
  47.   END repeat;
  48.   IF find = 0 THEN
  49.     RETURN linestring(point(nR, nC), point(nR + asize, nC + asize));
  50.   ELSE
  51.     RETURN NULL;
  52.   END IF;
  53. END~
  54. delimiter ;
  55.  
  56. INSERT INTO items(t, l, b, r) VALUES
  57.   (0, 3, 4, 6),
  58.   (0, 8, 2, 9),
  59.   (1, 0, 2, 2),
  60.   (3, 0, 5, 2),
  61.   (3, 7, 7, 9),
  62.   (6, 1, 7, 6),
  63.   (8, 1, 10,2);
  64.  
  65. SELECT astext(getCell(1, 10)) FROM dual; -- поиск ячейки размером 1x1
  66. SELECT astext(getCell(2, 10)) FROM dual; -- поиск ячейки размером 2x2

Объяснение кода листинга программы

  1. Создание таблицы items с полями id, t, l, b, r, ls типа INT, SMALLINT, SMALLINT, SMALLINT, SMALLINT, linestring соответственно. Тип linestring используется для хранения геометрических данных.
  2. Создание триггера bi_items перед таблицей items, который будет автоматически присваивать геометрическое значение в поле ls при вставке новой записи.
  3. Создание функции getCell, которая принимает два параметра: asize и maxsize. Функция проверяет пересечение вставленной в таблицу items линии с каждой ячейкой размером asize x maxsize и возвращает координаты первой свободной ячейки.
  4. Вставка данных в таблицу items.
  5. Вызов функции getCell с размерами 1x1 и 2x2 для поиска свободных ячеек.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут