¿La consulta SQL tiene una función geojson completa de PostGIS?

25

Me gustaría obtener una función geojson con propiedades de PostGIS. He encontrado un ejemplo para tener una colección de características, pero no puedo hacer que funcione solo para una característica.

SELECT row_to_json(fc)
 FROM ( SELECT 'FeatureCollection' As type, array_to_json(array_agg(f)) As features
 FROM (SELECT 'Feature' As type
    , ST_AsGeoJSON(lg.geog)::json As geometry
    , row_to_json(lp) As properties
   FROM locations As lg 
         INNER JOIN (SELECT loc_id, loc_name FROM locations) As lp 
       ON lg.loc_id = lp.loc_id  ) As f )  As fc;

hasta ahora he intentado modificar la consulta de colección de características del ejemplo. pero la salida no es válida.

    
pregunta Below the Radar 28.08.2014 - 16:35

4 respuestas

20

Esta respuesta podría usarse con la versión de PostgreSQL anterior a 9.4. Utilice la respuesta de dbaston para PostgreSQL 9.4+

La consulta es la siguiente: (donde 'GEOM' es el campo de geometría, id el campo para incluir en las propiedades json, shapefile_feature el nombre de la tabla y 489445 es el id de la característica deseada)

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;

salida:

{
   "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
   }
}
    
respondido por el Below the Radar 28.08.2014 - 21:14
46

Esto se puede hacer un poco más simplemente con json_build_object en PostgreSQL 9.4+, que le permite crear un JSON al proporcionar argumentos clave / valor alternativos. Por ejemplo:

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;

Las cosas se ponen aún mejor en PostgreSQL 9.5+, donde se agregan algunos operadores nuevos para el tipo de datos jsonb ( documentos ). Esto facilita la configuración de un objeto de "propiedades" que contiene todo menos el ID y la geometría .

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;

¿Quieres hacer una FeatureCollection? Solo envuélvalo todo con jsonb_agg :

SELECT jsonb_build_object(
    'type',     'FeatureCollection',
    'features', jsonb_agg(features.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;
    
respondido por el dbaston 27.04.2016 - 20:56
3

Solo una pequeña corrección a la respuesta de dbaston's (comentaré pero no tengo puntos) Debe convertir la salida de ST_AsGeoJSON como json (el ::json thingie):

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;

De lo contrario, el miembro de geometría será una cadena. Eso no es válido GeoJSON

    
respondido por el JavPL 18.10.2016 - 19:41
3
La respuesta de @ dbaston ha sido modificada últimamente por @John Powell, también conocido como Barça, y en mi opinión produce errores no válidos. Según se modificó, la agregación en características devuelve cada característica anidada dentro de un objeto json, que no es válido.

No tengo la reputación de comentar directamente sobre la respuesta, pero el jsonb_agg final debe estar en la columna "característica" y no en la subconsulta "características". La agregación en el nombre de la columna (o "features.feature" si lo encuentra más ordenado) coloca cada elemento directamente en la matriz de "características" después de la agregación, que es la forma correcta de hacerlo.

Entonces, lo siguiente, que es bastante similar a la respuesta de @dbaston como lo fue hasta hace unas semanas (más la corrección de @Jonh Powell a la asignación de nombres a las subconsultas) funciona:

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;
    
respondido por el jufaua 27.06.2018 - 15:50

Lea otras preguntas en las etiquetas