在 PL/pgSQL 函数中添加 ST_Transform
Adding ST_Transform in a PL/pgSQL function
我使用 Paul Ramsey´s blog 中的函数从 postGIS 数据库中查询 geoJSON 数据。
我稍微调整了功能,目前有效:
CREATE OR REPLACE FUNCTION rowjsonb_to_geojson(
rowjsonb JSONB,
geom_column TEXT DEFAULT 'geom')
RETURNS json AS
$$
DECLARE
json_props jsonb;
json_geom jsonb;
json_type jsonb;
BEGIN
IF NOT rowjsonb ? geom_column THEN
RAISE EXCEPTION 'geometry column ''%'' is missing', geom_column;
END IF;
json_geom := ST_AsGeoJSON((rowjsonb ->> geom_column)::geometry)::jsonb;
json_geom := jsonb_build_object('geometry', json_geom);
json_props := jsonb_build_object('properties', rowjsonb - geom_column);
json_type := jsonb_build_object('type', 'Feature');
return (json_type || json_geom || json_props)::text;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
现在我正要整合 ST_Transform(geom_column, 4326) 以返回传单申请的 lat/lng 数据:
- 我试过调整线
json_geom := ST_AsGeoJSON(((rowjsonb ->> ST_Transform(geom_column, 4326))::geometry)::jsonb;
这是行不通的,因为 ST_Transform 需要在几何图形而不是文本上执行,或者 json;
- 我的另一个想法,声明一个新变量 geom_c 并在块中首先执行转换
geom_c := ST_Transform(geom_column, 4326)::geometry;
这也不起作用。
我还尝试了以下方法:
json_geom := ST_AsGeoJSON(rowjsonb ->> ST_Transform((geom_column->>'geom')::geometry, 4326))::jsonb;
返回错误:运算符不存在:文本 ->> 未知
json_geom := ST_AsGeoJSON(rowjsonb ->> ST_Transform(ST_GeomFromGeoJSON(geom_column), 4326))::jsonb;
给出错误的意外字符(偏移量为 0)
这是我要查询的标准 table 的两个样本点:
"id": "0", "geom": "0101000020787F0000000000001DDF2541000000800B285441"
"id": "1", "geom": "0101000020787F000000000000EFE42541000000A074275441"
我使用的查询是:
SELECT 'FeatureCollection' AS type,
'standorts' AS name,
json_build_object('type', 'name', 'properties',
json_build_object('name', 'urn:ogc:def:crs:OGC:1.3:CRS84')) AS CRS,
array_to_json(array_agg(rowjsonb_to_geojson(to_jsonb(standort.*)))) AS FEATURES FROM standort";
我什至可以将 ST_Transform 功能集成到块段中吗?还是我需要逻辑重写块?
欢迎来到 SO。参数必须是几何图形,所以你需要在参数本身中转换字符串,而不是函数的结果,例如
json_geom := ST_AsGeoJSON(((rowjsonb ->> ST_Transform(geom_column::geometry, 4326)))::jsonb;
示例:
SELECT
ST_AsGeoJSON(
ST_Transform('SRID=32636;POINT(1 2)'::GEOMETRY,4326));
st_asgeojson
-----------------------------------------------------------
{"type":"Point","coordinates":[28.511265075,0.000018039]}
也就是说,您的函数可以这样修改:
CREATE OR REPLACE FUNCTION rowjsonb_to_geojson(
rowjsonb JSONB,
geom_column TEXT DEFAULT 'geom')
RETURNS json AS
$$
DECLARE
json_props jsonb;
json_geom jsonb;
json_type jsonb;
BEGIN
IF NOT rowjsonb ? geom_column THEN
RAISE EXCEPTION 'geometry column ''%'' is missing', geom_column;
END IF;
json_geom := ST_AsGeoJSON(ST_Transform((rowjsonb ->> geom_column)::geometry,4326))::jsonb;
json_geom := jsonb_build_object('geometry', json_geom);
json_props := jsonb_build_object('properties', rowjsonb - geom_column);
json_type := jsonb_build_object('type', 'Feature');
return (json_type || json_geom || json_props)::text;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
使用您的示例数据进行测试
WITH standort (id,geom) AS (
VALUES
(0,'0101000020787F0000000000001DDF2541000000800B285441'),
(1,'0101000020787F000000000000EFE42541000000A074275441')
)
SELECT row_to_json(q) AS my_collection FROM (
SELECT 'FeatureCollection' AS type,
'standorts' AS name,
json_build_object('type', 'name', 'properties',
json_build_object('name', 'urn:ogc:def:crs:OGC:1.3:CRS84')) AS CRS,
array_to_json(array_agg(rowjsonb_to_geojson(to_jsonb(standort.*)))) AS features
FROM standort) q;
my_collection
-----------------------------------------------
{
"type": "FeatureCollection",
"name": "standorts",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
11.886684554,
47.672030583
]
},
"properties": {
"id": 0
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
11.896296029,
47.666357408
]
},
"properties": {
"id": 1
}
}
]
}
注意 ST_AsGeoJSON 的用法:ST_Transforms
需要一个几何图形,ST_AsGeoJSON
returns 一个包含表示的文本几何,而不是几何本身。因此,您首先需要转换几何图形,然后将其序列化为 GeoJSON。
演示:db<>fiddle
我使用 Paul Ramsey´s blog 中的函数从 postGIS 数据库中查询 geoJSON 数据。 我稍微调整了功能,目前有效:
CREATE OR REPLACE FUNCTION rowjsonb_to_geojson(
rowjsonb JSONB,
geom_column TEXT DEFAULT 'geom')
RETURNS json AS
$$
DECLARE
json_props jsonb;
json_geom jsonb;
json_type jsonb;
BEGIN
IF NOT rowjsonb ? geom_column THEN
RAISE EXCEPTION 'geometry column ''%'' is missing', geom_column;
END IF;
json_geom := ST_AsGeoJSON((rowjsonb ->> geom_column)::geometry)::jsonb;
json_geom := jsonb_build_object('geometry', json_geom);
json_props := jsonb_build_object('properties', rowjsonb - geom_column);
json_type := jsonb_build_object('type', 'Feature');
return (json_type || json_geom || json_props)::text;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
现在我正要整合 ST_Transform(geom_column, 4326) 以返回传单申请的 lat/lng 数据:
- 我试过调整线
json_geom := ST_AsGeoJSON(((rowjsonb ->> ST_Transform(geom_column, 4326))::geometry)::jsonb;
这是行不通的,因为 ST_Transform 需要在几何图形而不是文本上执行,或者 json;
- 我的另一个想法,声明一个新变量 geom_c 并在块中首先执行转换
geom_c := ST_Transform(geom_column, 4326)::geometry;
这也不起作用。
我还尝试了以下方法:
json_geom := ST_AsGeoJSON(rowjsonb ->> ST_Transform((geom_column->>'geom')::geometry, 4326))::jsonb;
返回错误:运算符不存在:文本 ->> 未知
json_geom := ST_AsGeoJSON(rowjsonb ->> ST_Transform(ST_GeomFromGeoJSON(geom_column), 4326))::jsonb;
给出错误的意外字符(偏移量为 0)
这是我要查询的标准 table 的两个样本点:
"id": "0", "geom": "0101000020787F0000000000001DDF2541000000800B285441"
"id": "1", "geom": "0101000020787F000000000000EFE42541000000A074275441"
我使用的查询是:
SELECT 'FeatureCollection' AS type,
'standorts' AS name,
json_build_object('type', 'name', 'properties',
json_build_object('name', 'urn:ogc:def:crs:OGC:1.3:CRS84')) AS CRS,
array_to_json(array_agg(rowjsonb_to_geojson(to_jsonb(standort.*)))) AS FEATURES FROM standort";
我什至可以将 ST_Transform 功能集成到块段中吗?还是我需要逻辑重写块?
欢迎来到 SO。参数必须是几何图形,所以你需要在参数本身中转换字符串,而不是函数的结果,例如
json_geom := ST_AsGeoJSON(((rowjsonb ->> ST_Transform(geom_column::geometry, 4326)))::jsonb;
示例:
SELECT
ST_AsGeoJSON(
ST_Transform('SRID=32636;POINT(1 2)'::GEOMETRY,4326));
st_asgeojson
-----------------------------------------------------------
{"type":"Point","coordinates":[28.511265075,0.000018039]}
也就是说,您的函数可以这样修改:
CREATE OR REPLACE FUNCTION rowjsonb_to_geojson(
rowjsonb JSONB,
geom_column TEXT DEFAULT 'geom')
RETURNS json AS
$$
DECLARE
json_props jsonb;
json_geom jsonb;
json_type jsonb;
BEGIN
IF NOT rowjsonb ? geom_column THEN
RAISE EXCEPTION 'geometry column ''%'' is missing', geom_column;
END IF;
json_geom := ST_AsGeoJSON(ST_Transform((rowjsonb ->> geom_column)::geometry,4326))::jsonb;
json_geom := jsonb_build_object('geometry', json_geom);
json_props := jsonb_build_object('properties', rowjsonb - geom_column);
json_type := jsonb_build_object('type', 'Feature');
return (json_type || json_geom || json_props)::text;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;
使用您的示例数据进行测试
WITH standort (id,geom) AS (
VALUES
(0,'0101000020787F0000000000001DDF2541000000800B285441'),
(1,'0101000020787F000000000000EFE42541000000A074275441')
)
SELECT row_to_json(q) AS my_collection FROM (
SELECT 'FeatureCollection' AS type,
'standorts' AS name,
json_build_object('type', 'name', 'properties',
json_build_object('name', 'urn:ogc:def:crs:OGC:1.3:CRS84')) AS CRS,
array_to_json(array_agg(rowjsonb_to_geojson(to_jsonb(standort.*)))) AS features
FROM standort) q;
my_collection
-----------------------------------------------
{
"type": "FeatureCollection",
"name": "standorts",
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:OGC:1.3:CRS84"
}
},
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
11.886684554,
47.672030583
]
},
"properties": {
"id": 0
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
11.896296029,
47.666357408
]
},
"properties": {
"id": 1
}
}
]
}
注意 ST_AsGeoJSON 的用法:ST_Transforms
需要一个几何图形,ST_AsGeoJSON
returns 一个包含表示的文本几何,而不是几何本身。因此,您首先需要转换几何图形,然后将其序列化为 GeoJSON。
演示:db<>fiddle