Découper les rues suivant un polygone dans PostGIS

Bonjour,

Je poste ma question ici parce que je ne m’y retrouve pas là…

Mon besoin est le suivant : générer des plans de quartiers (mais de quartiers découpés par moi-même) en les découpant afin que les noms des rues ne soient affichés que dans la zone du quartier (je ne veux pas que le nom de la rue soit affiché tout le long de la rue en dehors du quartier).

J’utilise les données OSM et j’ai créé mes découpes de quartiers sous QGis, puis utilisé ogr2ogr pour en faire une table PostGIS.

Le problème est le suivant, comment faire la bonne requête sur ces tables ?

J’ai tenté des choses comme ça :

(select p.* from planet_osm_line as p inner join fiches as f on St_Intersects(ST_Transform(f.wkb_geometry,900913),p.way) where f.quartier='zone1' and not st_isempty(st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)))) as lignes

Les rues sont affichées en dehors de la zone.

(select p.*,f.wkb_geometry,st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)) from planet_osm_line as p, (select * from fiches where quartier='zone1') as f where not st_isempty(st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)))) as lignes

et là, les noms des rues s’affichent bien seulement dans la zone, mais ils ne sont pas dans l’ordre, et le nom de la rue qui s’affiche n’est pas celui de la rue réelle.

J’ai tenté pas mal de modifs sur ces requêtes avec à chaque fois un de ces deux résultats…

Merci de votre aide.

Bonjour

La première requête est manifestement fausse. Le résultat de la requête est décrit juste après le select, donc tu as en résultat p.way qui n’a subit aucune transformation et n’est pas découpé par l’opérateur st_intersection . Le p.way en résultat doit juste respecter la clause where, càd présenter une intersection avec zone1.

Seconde requête

select
  p.*,
  f.wkb_geometry
  st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)) 
from  
  planet_osm_line as p ,
  (select * from fiches where quartier='zone1') as f 
 where 
   not st_isempty(st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)))

Là je ne vois pas ce qui cloche. Déjà on peut la simplifier: en résultat f on s’en fout, et st_isempty + st_intersection peut être avantageusement remplacé.
Je laisse le nom et l’id OSM : ton ano pourrait venir d’osm, non ?

select
  st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)) as way,
  p.name as name,
  p.osm_id
from  
  planet_osm_line as p ,
  (select * from fiches where quartier='zone1') as f 
 where 
   st_intersects(p.way,ST_Transform(f.wkb_geometry,900913))

On peut ajouter une clause pour être sur qu’il va utiliser les index géospatiaux. L’opérateur && renvoit VRAI quand les bbox (polygone envelopant) des 2 objets intersectent. C’est pour la performance uniquement.

and p.way && ST_Transform(f.wkb_geometry,900913))

Tu peux voir avec ça ?
Bruno

Bonsoir et merci pour la réponse rapide.

Malheureusement, si je supprime le f.wkb_geometry, j’obtiens :

ERROR:  column "wkb_geometry" does not exist
LINE 1: SELECT ST_AsBinary("wkb_geometry")

C’est pour ça que je le mets.

(select p.*,f.wkb_geometry,st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)) from planet_osm_line as p, (select * from fiches where quartier='zone1') as f where not st_isempty(st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)))) as lignes

Le problème ne vient-il pas du p.* ?

Ca retourne tout les champs de p, donc la géométrie initiale alors qu’on sort une géométrie découpée juste après avec le ST_Intersection mais sans la nommer… que devient-elle ?
A quoi sert le f.wkb_geometry ?

La subquery me semble peu adaptée elle aussi…

Voici ma version:

(select p.*, st_intersection(p.way,ST_Transform(f.wkb_geometry,900913)) as way2 from planet_osm_line as p join fiches on (ST_Intersects(p.way,ST_Transform(f.wkb_geometry,900913))) where f.quartier='zone1') as lignes

Bien sûr il faut utiliser way2 et pas way… si besoin remplacer le p.* par la liste des champs dont on a vraiment besoin.

Bonsoir,

Merci de votre aide, mais malheureusement, après plusieurs essais, cela ne fonctionne pas…

ERROR:  missing FROM-clause entry for table "f"
LINE 1: ... join fiches on (ST_Intersects(p.way,ST_Transform(f.wkb_geom...

Je poste une image pour illustrer ce qu’il se passe ici

Tout est nickel pour les batiments, mais pas pour les noms des rues parce que la ligne est en partie incluse dans la zone.

Il ne faut pas que les rues en dehors de la zone soient affichées.

Merci beaucoup de votre aide !

C’est visiblement p.way qui est utilisé et pas p.way2… je répète donc ma dernières ligne:

Bien sûr il faut utiliser way2 et pas way… si besoin remplacer le p.* par la liste des champs dont on a vraiment besoin.

Je ne sais pas comment QGis décide se prendre tel ou telle colonne contenant une géométrie lorsqu’il y en a plusieurs retournées. Peut être qu’en mettant le .* après le way2 il prendra way2 en premier…

Bonsoir,

Excuse moi cquest, je ne t’avais pas bien compris.

(select p.name,p.way,p.barrier,p.boundary,p.highway,p.operator, p.railway,p.z_order,st_intersection(p.way,ST_Transform(fiches.wkb_geometry,900913)) as way2 from planet_osm_line as p join fiches on (ST_Intersects(p.way,ST_Transform(fiches.wkb_geometry,900913))) where fiches.quartier='zone1') as lignes

Cette ligne fonctionne, il fallait utiliser way2 en ce sens que dans le champ "Geometry field SQL (field containing feature geometry) soit renseigné à way2.

Désolé, merci beaucoup cquest.

Si quelqu’un peut marquer le sujet comme clos.