检查下一个点的几何点距离

时间:2018-09-05 11:53:10

标签: postgresql postgis

这是我的位置表:

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 :(得分:0)

我已根据新信息更改了查询。 首先,我们在“ userId”和“ deviceId”组成的分区中按“ creationDateTime”对记录进行排名。我们还根据creatioDateTime中的用户,设备和日期对记录进行分组。 -CTE ol_dt

然后,我们在点之间创建线,将它们连接到组内并按排名排序(因此,我们将点与特定时间的同一用户和设备的下一个时间点连接起来)– CTE行

最后,我们将所有线从点到点连接到仍然成组的一个(多)线串。

public static DataTable GetAddressStatusOfDevice(string deviceId, string connectionString)
{
    string commandText = "SELECT AddressStatus FROM dbo.DeviceAddresses WHERE DeviceID = @ID;";
    var dt = new DataTable();
    var da = new SqlDataAdapter(commandText, connectionString);
    da.SelectCommand.Parameters.Add("@ID", SqlDbType.Int).Value = deviceId;
    da.Fill(dt);
    return dt;
}

对于较大的数据集(成千上万的记录或数百万个或更多记录),当您想一次为整个数据集创建时。

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

然后使用第二个CTE创建表

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);

最后

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;
相关问题