使用函数计算 gps 位置和 postgis 地理值之间的距离?

Calculating distance between a gps location and postgis geography value using a function?

我有用户的经纬度值。我在数据库中保存了各个位置的地址。我想根据半径值找到最近的报价。我正在使用 postgis。

目前我的位置栏是地理类型。

  1. 当我只有纬度和经度时,我应该以什么格式将数据输入到“位置”列地理类型中?我无法使用 postgis 函数,因为我正在使用 graphql 进行数据插入。

  2. 我一直在努力编写一个用于此目的的函数。这就是我想到的 with.Is 有更好的方法吗?

CREATE OR REPLACE FUNCTION public."getNearByOffers"(
    lat double precision,
    lon double precision,
    radius integer)
    RETURNS "Offers"
    LANGUAGE 'sql'
    COST 100
    VOLATILE 
AS $BODY$ SELECT O.*
FROM "public"."Offers" O
  JOIN "public"."Address" A ON A.id = O."addressId"
WHERE 
 ST_DWithin(ST_MakePoint(lat, lon)::geography,
    A.location::Geography, radius);$BODY$;
  1. 当我运行这个函数时,所有在查询结果的列都合并在一起了。如何将其拆分为查询结果中的不同列?

在此问题上,我将不胜感激!

对于 GIS 操作,您需要点数据类型。您可以使用 VIEW 创建伪 table,其中包含原始列加上半径 and/or 点。您不能在视图上创建索引(如果这很重要),但您可以在表达式上创建索引。我目前没有能力尝试这个,但如果这不能回答你的问题,我可以稍后修改它。

类似

CREATE VIEW offer_address AS (
  SELECT o.*, ST_DWithin(ST_MakePoint(a.lat, a.lon), a.location) radius
  FROM offers o JOIN address a ON a.id = o."addressId"
);

然后像往常一样插入 offersaddress 并查询,但不插入 offer_address.

P.S。 GraphQL 本身不应该阻止您执行任意 SQL,但我不确定您的设置到底是什么。

Hasura 在其 GraphQL 架构中内置了对 PostGIS 的支持。由于您的字段已经是 geography 类型,因此您不需要该函数。

在 Hasura 中,您需要创建 offersaddress 表之间的关系,GraphQL 查询应该类似于:

query nearby_offers($point: geography!) {
  offers(where: {address: {location: {_st_d_within: {distance: 200000, from: $point}}}}) {
    id
    offer_fields
    address {
      location
    }
  }
}

Hasura 中的地理类型要求值采用 GEOJSON 格式。您的变量 $point 应该如下所示:

{
  "point": {
    "type" : "Point", 
    "coordinates": [longitude, latitude]
  }
}

插入值(变异)时需要相同类型的变量 (GEOJSON)。