#sql #postgresql #gis #postgis
Вопрос:
Я совсем новичок в postgis, и мне приходится запрашивать время, когда пользовательские дорожки пересекаются с линиями контрольных точек.
Мой дизайн БД :
CREATE TABLE users (
uuid UUID PRIMARY KEY,
name VARCHAR(127) NOT NULL
);
CREATE TABLE locations (
uuid UUID PRIMARY KEY,
user_uuid UUID NOT NULL,
location GEOMETRY(POINT) NOT NULL,
located_at TIMESTAMP NOT NULL
);
CREATE TABLE checkpoints (
uuid UUID PRIMARY KEY,
line GEOMETRY(LINESTRING) NOT NULL
);
Я хотел бы построить запрос, который приведет к строкам такого типа :
| checkpoint_uuid | user_uuid | located_at |
| --------------- | --------------- | --------------- |
| checkpoint_1 | user_1 | 2021-11-05 15:50:30 |
| checkpoint_1 | user_2 | 2021-11-05 15:51:10 |
| checkpoint_1 | user_3 | 2021-11-05 15:51:13 |
| checkpoint_2 | user_1 | 2021-11-05 16:12:30 |
| checkpoint_2 | user_3 | 2021-11-05 16:13:41 |
| checkpoint_2 | user_2 | 2021-11-05 16:13:48 |
У меня есть несколько пользователей, которые отправляют данные о местоположениях с указанием времени в расположениях таблиц.
В таблице контрольных точек у меня есть строка для каждой контрольной точки. Пользователи когда-нибудь перейдут эти границы.
На данный момент я могу найти точку пересечения между пользовательским запуском и контрольными точками :
SELECT checkpoints.uuid, user_uuid, ST_Intersection(ST_MakeLine("location")::geography, line)
FROM locations, checkpoints
GROUP BY checkpoints.uuid, user_uuid, line
Но я не могу восстановить время этого пересечения. Если я добавлю расположенное в к выбору, это приведет к сбою ГРУППЫ ПО
Ответ №1:
Если я правильно понял ваш вопрос, вам просто нужно пространственное соединение. С помощью этой функции ST_Intersects
вы можете фильтровать только те записи, которые пересекаются, например
SELECT
chk.uuid,
loc.user_uuid,
loc.located_at
FROM locations loc
JOIN checkpoints chk ON ST_Intersects(loc.location,chk.line);
Комментарии:
1. Я только что попробовал это, но это не дает никаких результатов. На самом деле местоположения пользователей находятся не совсем на линии контрольной точки. Одна точка пользователя находится на один метр раньше, а следующая-на один метр позже. Пересечение должно быть между линией, проведенной всеми местоположениями пользователей, и линией контрольной точки.
2. @ybert будет ли буфер вокруг точки для вас вариантом?
3. @ybert не могли бы вы взглянуть на запрос в этой скрипке? Это может вас заинтересовать dbfiddle.uk/…
4. @ybert это действительно сложно. Альтернативой могло бы быть прямое обновление строки (добавление новых точек) вместо сохранения каждой новой точки отдельно в виде отдельной записи. Но поскольку я не знаком с вашим вариантом использования, он также может не применяться. Кроме того, вы должны использовать
point m
в этом отношении 😉 Ура и удачи5. Я постараюсь сохранить прямую строку с указателем внутри. Спасибо, вы мне очень помогли ! 🙂