Я полагаю, что простого l oop с jsonb_build_obejct
над набором результатов из ST_DumpPoints
будет достаточно. Если вы также хотите применить эту функцию в составных геометриях, вам нужно создать еще одну l oop для предварительного извлечения всех геометрий, используя ST_Dump
:
CREATE OR REPLACE FUNCTION generate_custom_geojson(g GEOMETRY)
RETURNS json AS $$
DECLARE
j geometry;
i geometry;
coords jsonb[] := '{}';
coords_multi jsonb[] := '{}';
BEGIN
FOR j IN SELECT (ST_Dump(g)).geom LOOP
FOR i IN SELECT (ST_DumpPoints(j)).geom LOOP
coords := coords || jsonb_build_object('x',ST_X(i),'y',ST_Y(i));
END LOOP;
IF ST_NumGeometries(g)=1 THEN
coords_multi := coords;
ELSE
coords_multi := coords_multi || jsonb_agg(coords);
END IF;
END LOOP;
RETURN json_build_object('type',replace(ST_GeometryType(g),'ST_',''),
'coordinates',coords_multi);
END;
$$ LANGUAGE plpgsql;
Эта функция просто извлекает все точки данной геометрии и помещает их в массив - добавляется с помощью ||
. Этот массив позже используется для создания coordinates
набора пар x,y
. Тип геометрии извлекается с использованием ST_GeometryType
.
Тест:
WITH j (g) AS (
VALUES ('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)'),
('POLYGON ((30 10, 40 40, 20 40, 10 20, 30 10))'),
('MULTILINESTRING ((10 10, 20 20, 10 40),(40 40, 30 30, 40 20, 30 10))'),
('MULTIPOLYGON (((30 20, 45 40, 10 40, 30 20)),((15 5, 40 10, 10 20, 5 10, 15 5)))'),
('MULTIPOINT (10 40, 40 30, 20 20, 30 10)')
)
SELECT generate_custom_geojson(g) FROM j;
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
{"type" : "LineString", "coordinates" : [{"x": 77.29, "y": 29.07},{"x": 77.42, "y": 29.26},{"x": 77.27, "y": 29.31},{"x": 77.29, "y": 29.07}]}
{"type" : "Polygon", "coordinates" : [{"x": 30, "y": 10},{"x": 40, "y": 40},{"x": 20, "y": 40},{"x": 10, "y": 20},{"x": 30, "y": 10}]}
{"type" : "MultiLineString", "coordinates" : [[[{"x": 10, "y": 10}, {"x": 20, "y": 20}, {"x": 10, "y": 40}]],[[{"x": 10, "y": 10}, {"x": 20, "y": 20}, {"x": 10, "y": 40}, {"x": 40, "y": 40}, {"x": 30, "y": 30}, {"x": 40, "y": 20}, {"x": 30, "y": 10}]]]}
{"type" : "MultiPolygon", "coordinates" : [[[{"x": 30, "y": 20}, {"x": 45, "y": 40}, {"x": 10, "y": 40}, {"x": 30, "y": 20}]],[[{"x": 30, "y": 20}, {"x": 45, "y": 40}, {"x": 10, "y": 40}, {"x": 30, "y": 20}, {"x": 15, "y": 5}, {"x": 40, "y": 10}, {"x": 10, "y": 20}, {"x": 5, "y": 10}, {"x": 15, "y": 5}]]]}
{"type" : "MultiPoint", "coordinates" : [[[{"x": 10, "y": 40}]],[[{"x": 10, "y": 40}, {"x": 40, "y": 30}]],[[{"x": 10, "y": 40}, {"x": 40, "y": 30}, {"x": 20, "y": 20}]],[[{"x": 10, "y": 40}, {"x": 40, "y": 30}, {"x": 20, "y": 20}, {"x": 30, "y": 10}]]]}
(5 Zeilen)