首页 > 解决方案 > 如何在 Postgresql 中将地球数据类型转换为 json

问题描述

我想将地球数据类型转换为 Postgresql (9.5) 中的 json 数组。

这就是我所拥有的:

CREATE OR REPLACE FUNCTION earth_to_json (inpt earth)
RETURNS json AS $$
    SELECT json_build_array(latitude(inpt), longitude(inpt))
$$ LANGUAGE SQL;

CREATE CAST (earth AS JSON) WITH FUNCTION earth_to_json(earth) AS IMPLICIT;

执行上面的查询时,我得到以下输出:

WARNING: cast will be ignored because the source data type is a domain 
CREATE CAST 
Query returned successfully in 47 msec.

所以earth数据类型是域,根据上面的消息。我知道 earthdistance 是基于 cube 模块的,但我假设earth数据类型是一个真实的数据类型,所以我应该能够转换。

因此,如果上面的代码应该可以工作,那么下面的代码应该可以正常运行。

SELECT ll_to_earth(10.10, 30.01)::JSON

但我得到了错误

 ERROR: cannot cast type earth to json LINE 1

标签: postgresqlcastingearthdistance

解决方案


我发现了什么:

earth数据类型不是真正的数据类型。这是带有约束的立方体类型(约束在地球域中定义)。所以我真的需要创建一个将多维数据集数据类型转换为 json 的转换。

当您不小心有一个适合地球域的立方体时,它将作为lat, lon数组返回。您可以创建自己的数据类型来解决此问题。对我来说这没问题,因为我不使用多维数据集数据类型。

CREATE OR REPLACE FUNCTION cube_to_json (inpt cube)
RETURNS json AS $$
BEGIN
    BEGIN
        RETURN json_build_array(latitude(inpt), longitude(inpt));
    EXCEPTION WHEN SQLSTATE '23514' THEN
        RETURN CASE WHEN json_array_length(sub) = 1 THEN sub->0 ELSE sub END FROM (SELECT translate('[' || inpt::TEXT || ']', '()', '[]')::JSON AS sub) AS o;
    END;
END;
$$ LANGUAGE plpgsql;


CREATE CAST (cube AS json) WITH FUNCTION cube_to_json(cube) AS IMPLICIT
-- Now test
SELECT (ll_to_earth(10,20))::JSON; -- Outputs [10,20]
SELECT ('(5437508.36471516, 3140612.41127573), (118.44062468, 1)'::CUBE)::JSON; -- Outputs "[[5437508.36471516, 3140612.41127573], [118.44062468, 1]]"

推荐阅读