使用 PostgreSQL 从众所周知的文本创建 GeoJSON 输出

zer*_*ero 5 postgresql postgis geojson

我有 wkt 数据,我正在尝试在 PostgreSQL 中创建一个 JSON 输出。

我知道有一个函数 ST_AsGeoJSON ( https://postgis.net/docs/ST_AsGeoJSON.html ) 创建例如:

SELECT ST_AsGeoJSON('LINESTRING(77.29 29.07,77.42 29.26,77.27 29.31,77.29 29.07)');

Output:
{"type":"LineString","coordinates":[[77.29,29.07],[77.42,29.26],[77.27,29.31],[77.29,29.07]]}
Run Code Online (Sandbox Code Playgroud)

但是,我希望创建一个输出,如下所示:

{"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}]}

Run Code Online (Sandbox Code Playgroud)

请注意,我正在为所有类型的几何对象寻找通用解决方案。谢谢

Jim*_*nes 0

jsonb_build_obejct我相信一个带有结果集的简单循环ST_DumpPoints就足够了。如果您还想在多部分几何图形中应用此函数,则必须使用以下命令构建另一个循环来预先提取所有几何图形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;
Run Code Online (Sandbox Code Playgroud)

该函数只是提取给定几何图形的所有点并将它们放入一个数组中 - 使用 附加||。该数组稍后用于创建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)
Run Code Online (Sandbox Code Playgroud)