Nous utilisons des cookies pour vous garantir la meilleure expérience sur notre site. Si vous continuez à utiliser ce dernier, nous considèrerons que vous acceptez l'utilisation des cookies. J'ai compris ! ou En savoir plus !.
banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oublié ?

Annonce

Rencontres QGIS 2025

L'appel à participation est ouvert jusqu'au 19 janvier 2025!

#1 Sat 19 January 2019 19:24

Benji12
Participant occasionnel
Date d'inscription: 5 Apr 2018
Messages: 23

Requête pour geojson

Je souhaiterais générer un geojson avec 2 entrées (une linestring & une multiline string). la différence entre les deux selects se situe au niveau de principal_way = true/false

Je me suis penché sur la doc postgis et j'ai commencé à rédiger ma requête, mais j'obtiens l'erreur suivante :
ERROR:  column "track.id" must appear in the GROUP BY clause or be used in an aggregate function


Code:

select row_to_json(collec)
  from (
    select
      'FeatureCollection' as "type",
        array_to_json(array_agg(variantes)) as "features"
    from (
          select 'Feature' as "type", 
          ST_AsGeoJSON(st_linemerge(st_collect(track.path))) :: json as "geometry",
            row_to_json((track.id, track.track_name)) As properties                                   
            from tracks track
            INNER JOIN track_ways ON track_ways.track_id = track.id                                        
            where track.principal_way= false
            and track_ways.display= true
            and track_ways.way_id = 1
    ) as variantes                                    
) as collec

Autre question que je me pose, c'est à quel niveau je dois intégrer ma deuxième requête (la même avec la valeur where track.principal_way= true).

Merci pour votre aide wink

Hors ligne

 

#2 Sun 20 January 2019 18:23

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Requête pour geojson

Bonsoir,

L'erreur vient du fait que vous utilisez une fonction agrégée (st_collect) sans grouper les autres colonnes de la table track (id, name).

Tester d'abord la construction des linestring avant d'en faire du geojson:

Code:

select track.id, track.track_name,
       ST_AsGeoJSON(st_linemerge(st_collect(track.path))) :: json as "geometry"
from tracks track JOIN track_ways ON track_ways.track_id = track.id
where not track.principal_way 
      and track_ways.display 
      and track_ways.way_id = 1
group by 1, 2;

Track contient des portions de lignes que vous voulez fusionner ?

Je ne comprends pas bien la derniere question: vous voulez les lignes telles que track.principal_way soit vrai ET track.principal_way soit faux ?
Si c'est ca, il suffit de ne filtrer sur cette colonne.

Nicolas

Hors ligne

 

#3 Sun 20 January 2019 19:26

Benji12
Participant occasionnel
Date d'inscription: 5 Apr 2018
Messages: 23

Re: Requête pour geojson

Merci, pour ce retour. je comprends mieux wink

En fait, j'ai des tracks (qui ont pour valeur principal_way = true ou false)

Je voudrais faire un geojson avec ces deux valeurs :

1 - un merge des tracks qui on la valeur principal way = true et comme valeur properties way.id & way.name

Code:

select row_to_json(collec)
  from (
    select
      'FeatureCollection' as "type",
        array_to_json(array_agg(variantes)) as "features"
    from (
          select 'Feature' as "type", 
          ST_AsGeoJSON(st_linemerge(st_collect(track.path))) :: json as "geometry"                                   
            from tracks track
            INNER JOIN track_ways ON track_ways.track_id = track.id                                        
            where track.principal_way= true
            and track_ways.display= true
            and track_ways.way_id = 1
    ) as variantes                                    
) as collec

La requête (partielle) fonctionne bien et j'obtiens bien une seule linestring, mais je n'arrive pas a générer le properties qui devrait avoir pour valeur way.id && way.name

2- une liste de toutes les tracks qui ont la valeur principal_way = false avec pour valeur properties l'id.track && track.name de chaque track (donc plusieurs linestrings)

L'objectif étant d'avoir dans un seul geojson, la voie principale(tracks mergés) et les variantes existantes (principal_way = false).

Mon geojson devrait contenir une linestring correspondant à la voie principale et une liste de linestrings, correspondant à chaque variantes. Au final, le geojson devrait ressembler à ça :

Code:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "way_id": 1,
        "way_name": "Voie principale"
      },
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            30.5,
            56.5
          ],
          [
            37.2,
            57.3
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "track_id": 1,
        "track_name": "Voie secondaire 1"},
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            32.1,
            57.2
          ],
          [
            33.0,
            57.3
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {
        "track_id": 1,
        "track_name": "Voie secondaire 2"},
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [
            33.5,
            57.4
          ],
          [
            34.0,
            57.0
          ]
        ]
      }
    }
  ]
}

Dernière modification par Benji12 (Sun 20 January 2019 19:37)

Hors ligne

 

#4 Sun 20 January 2019 20:02

Nicolas Ribot
Membre
Lieu: Toulouse
Date d'inscription: 9 Sep 2005
Messages: 1554

Re: Requête pour geojson

Pour la partie properties, il faut faire un sous select pour pouvoir exprimer les colonnes sous forme de record et le passer a row_to_json.

Par ex:

Code:

with tmp as (
  select 1 as id, 'way1' as name, 'srid=4326;LINESTRING(0 0, 1 1)'::geometry as geom
), tmp1 as (
  select 'Feature' as "type",
         ST_AsGeoJSON(geom, 6)::json as "geometry",
         (
           select json_strip_nulls(row_to_json(t))
           from (select id, name) t
         ) as "properties"
  from tmp t
), tmp2 as (
         select 'FeatureCollection' as "type",
              array_to_json(array_agg(t)) as "features"
       from tmp1 t
) select row_to_json(t)
from tmp2 t;

Si les tracks principal_way=false ne doivent pas etre mergées, utilisez UNION ALL pour construire la line mergée principal_way=true et toutes les autres tracks principal_way=false, puis faites la conversion json de cet ensemble. (condition where a adapter suivant votre cas)

Code:

select track.id, track.name,  
  st_linemerge(st_collect(track.path)) as geom                                   
from tracks track INNER JOIN track_ways ON track_ways.track_id = track.id                                        
where track.principal_way= true
and track_ways.display= true
and track_ways.way_id = 1
group by 1, 2
UNION ALL
select track.id, track.name, 
  track.path as geom                                   
from tracks track INNER JOIN track_ways ON track_ways.track_id = track.id                                        
where track.principal_way= false
and track_ways.display= true

Nicolas

Hors ligne

 

Pied de page des forums

Powered by FluxBB