Проверьте расстояние геометрической точки со следующей точкой - PullRequest
0 голосов
/ 05 сентября 2018

Это моя таблица местоположения:

create table olocations
(
  id                 uuid not null
    constraint oid
    primary key,
  lat                double precision,
  lng                double precision,
  "deviceId"         text,
  topic              text,
  "userId"           uuid,
  "userName"         text,
  "creationDateTime" timestamp with time zone,
  shape              geometry,
  "appName"          text,
  "appVersion"       text
);

Я хочу проверить расстояние геометрической точки до следующей точки, пока расстояние между ними не станет меньше 15 метров:

SELECT olocations.id,
    olocations."userId",
    olocations."deviceId",
    olocations."creationDateTime",
    olocations.shape,
    row_number() OVER ()
FROM olocations
    where st_distance(shape, (select shape from olocations
                                             where // ????  )) <= 15
GROUP BY olocations.id, olocations."creationDateTime"
ORDER BY olocations."creationDateTime"

В методе st_distance() для первого параметра я установил первую точку, но как я могу установить следующую точку в качестве второго параметра?

После этого я хочу сделать мультилинию между этими точками, расстояние между ними было менее 15 метров. Как я могу это сделать?

1 Ответ

0 голосов
/ 06 сентября 2018

Я изменил запрос в соответствии с новой информацией. Во-первых, мы ранжируем наши записи по «creationDateTime» в разделах, созданных userId и deviceId. Мы также группируем записи по пользователю, устройству и дню из creatioDateTime. - CTE ol_dt

Затем мы создаем линии между точками, соединяя их внутри групп и по нашему ранжированию (поэтому мы соединяем нашу точку со следующим моментом времени от того же пользователя и устройства в конкретный день) - линии CTE

Последнее, что мы объединяем все строки от точки к точке, чтобы одна (много) линейная строка все еще в группах.

with ol_dt as (SELECT row_number() over (partition by "userId", "deviceId" 
                                          order by "creationDateTime") rnk,
                       rank() over (order by "userId", "deviceId", 
                                              date("creationDateTime")) rnk2,
                       o."userId",
                       o."deviceId",
                       date(o."creationDateTime") as day,
                       o.shape
                  FROM olocations o),
      lines as (select ol_dt."userId", ol_dt."deviceId", ol_dt.day, 
                       st_makeline(ol_dt.shape, ol_dt2.shape) as geom
                  from ol_dt, ol_dt ol_dt2
                 where ol_dt.rnk2=ol_dt.rnk2
                   and ol_dt.rnk+1=ol_dt2.rnk)
select "userId", "deviceId", day, st_union(geom) geom
   from lines
  group by "userId", "deviceId", day

Для больших наборов данных (гончих тысяч или миллионов или более записей), когда вы хотите сделать это для всего набора данных одновременно.

Create temp table ol_dt as
SELECT row_number() over (partition by "userId", "deviceId" 
                          order by "creationDateTime") rnk,
       rank() over (order by "userId", "deviceId", date("creationDateTime")) rnk2,
        o."userId",
        o."deviceId",
        date(o."creationDateTime") as day,
        o.shape
  FROM olocations o;
create index on ol_dt using btree (rnk, rnk2);
create index on ol_dt using gist(shape);

Затем создайте таблицу со вторым CTE

create temp table lines as
select ol_dt."userId", ol_dt."deviceId", ol_dt.day, 
       st_makeline(ol_dt.shape, ol_dt2.shape) as geom
  from ol_dt, ol_dt ol_dt2
 where ol_dt.rnk2=ol_dt.rnk2
   and ol_dt.rnk+1=ol_dt2.rnk;

И, наконец,

 select "userId", "deviceId", day, st_union(geom) geom
   from lines
  group by "userId", "deviceId", day
...