我想从PostGIS获得带有属性的geojson功能。我找到了一个具有功能部件集合的示例,但我不能使其仅适用于某个功能部件。这个例子。但输出无效。

评论

我不得不为另一个应用程序做一个概念验证,因此将这个仓库整合在一起,部分使用这里的答案。希望可以帮助您入门-在这里找到它:pg-us-census-poc

#1 楼

使用PostgreSQL 9.4+中的json_build_object可以更简单地完成此操作,它使您可以通过提供交替的键/值参数来构建JSON。例如:

SELECT json_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::json,
    'properties', json_build_object(
        'feat_type', feat_type,
        'feat_area', ST_Area(geom)::geography
     )
 )
 FROM input_table;


在PostgreSQL 9.5+中情况变得更好,在PostgreSQL 9.5+中,为jsonb数据类型(docs)添加了一些新的运算符。这样可以轻松地设置一个“属性”对象,其中包含除ID和几何图形之外的所有内容。

只需用jsonb_agg将其包装起来即可:

SELECT jsonb_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::jsonb,
    'properties', to_jsonb(row) - 'gid' - 'geom'
) FROM (SELECT * FROM input_table) row;


评论


仅凭此功能,我今天早上就忙于从9.3.5升级到9.5.3。如果它像regexp_replace(current_setting('server_version'),'(\ d)\。(\ d)\。(\ d)','\ 1. \ 3. \ 2')一样简单...

– GT。
16年7月12日在22:18



确定-现在已全部升级(尽管无法获得9.5.3作为Windoze服务运行)。无论如何...关于给定示例的一件事-第二个json_build_object具有冒号而不是逗号。

– GT。
16年7月13日在10:19

在pg v9.6上对我不起作用

–白
17年5月19日在13:22

为了完整起见,对于严格的geojson(右手规则),几何顶点可能没有正确的顺序,为纠正这一点,我们可以使用ST_ForcePolygonCCW在geom中重新排列顶点-postgis.net/docs/manual-dev/ ST_ForcePolygonCCW.html

–chrismarx
17年11月2日,13:30



@chrismarx这是一个好点,并引发了是否应修改PostGIS的ST_AsGeoJSON函数以自行纠正方向的问题。

–dbaston
17年11月6日在16:51



#2 楼

此答案可用于9.4之前的PostgreSQL版本。使用dbaston的PostgreSQL 9.4+答案

查询如下:(其中'GEOM'是geometry字段,id是要包含在json属性中的字段,shapefile_feature是表名,489445是想要的功能)

SELECT row_to_json(f) As feature \
     FROM (SELECT 'Feature' As type \
     , ST_AsGeoJSON('GEOM')::json As geometry \
     , row_to_json((SELECT l FROM (SELECT id AS feat_id) As l)) As properties \
     FROM shapefile_feature As l WHERE l.id = 489445) As f;


输出:

{
   "geometry":{
      "type":"MultiPolygon",
      "coordinates":[
         [
            [
               [
                  -309443.24253826,
                  388111.579584133
               ],
               [
                  -134666.391073443,
                  239616.414560895
               ],
               [
                  -308616.222736376,
                  238788.813082666
               ],
               [
                  -309443.24253826,
                  388111.579584133
               ]
            ]
         ]
      ]
   },
   "type":"Feature",
   "properties":{
      "feat_id":489445
   }
}


评论


由于您已将此问题从问题的正文移到了答案,这是否意味着此查询和结果现在可以正常工作?通过GeoJSONLint运行它,它似乎仍然没有提供有效的输出。

– RyanKDalton
2014年8月28日在20:05



太好了,这很有意义。我想我看起来不够仔细。一旦GIS.SE允许它结束问题,就可以将其标记为“已接受”。谢谢!

– RyanKDalton
2014年8月29日14:38

不只接受单引号的不只是GeoJSONLint。 JSON也不正式识别单引号。如果有任何解析器识别出它们,则这是非标准扩展,最好避免。

– jpmc26
16年8月30日,0:34

@BelowtheRadar这是一个字典,而不是JSON。他们是完全不同的东西。 JSON是一个字符串。总是。它是一种文本格式,就像XML只是一种文本格式一样。字典是内存中的对象。

– jpmc26
16年8月30日在15:12



#3 楼

@dbaston的答案最近已由@John Powell akaBarça修改,它在我端产生无效的geojson。修改后,功能集合将返回嵌套在json对象内的每个功能,该功能无效。

我没有信誉直接对答案发表评论,但是最终的jsonb_agg应该在“功能”列而不是“功能”子查询上。聚集列名(如果发现更整洁,则聚集在“ features.feature”上)将每个元素直接放在聚集之后的“ features”数组中,这是正确的方法。

以下几项与@dbaston的答案非常相似,直到几周前(加上@Jonh Powell对子查询命名的更正)确实起作用:
SELECT jsonb_build_object(
  'type',     'FeatureCollection',
  'features', jsonb_agg(feature)
)
FROM (
  SELECT jsonb_build_object(
    'type',       'Feature',
    'id',         gid,
    'geometry',   ST_AsGeoJSON(geom)::jsonb,
    'properties', to_jsonb(inputs) - 'gid' - 'geom'
  ) AS feature
  FROM (
    SELECT * FROM input_table
  ) inputs
) features;


#4 楼

只是对dbaston的答案做了些微修正(我会发表评论,但我没有要点)
您需要将ST_AsGeoJSON的输出转换为json(::json东西):

SELECT json_build_object(
  'type',       'Feature',
  'id',         gid,
  'geometry',   ST_AsGeoJSON(geom)::json,
  'properties', json_build_object(
    'feat_type', feat_type,
    'feat_area', ST_Area(geom)::geography
  )
)
FROM input_table;


否则,几何成员将是字符串。那不是有效的GeoJSON