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 Mon 08 April 2024 15:06

ppluvinet
Participant assidu
Lieu: VALENCE
Date d'inscription: 6 Aug 2007
Messages: 617

Construire une requete WFS sur le GPU et récupérer un shapefile

Bonjour,
Je cherche à télécharger au format shapefile des données du GeoPortail de l'urbanisme via un service WFS avec comme paramètres un bbox et une limite de nombre d'objets fixé à 5000.


J'ai tenté de construire cette URL mais en vain :

Code:

https://data.geopf.fr/wfs/ows?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetCapabilities&typenames=wfs_du:doc_urba&outputFormat=SHAPE-ZIP&BBOX=44.764,4.498,45.27,5.228&_start=0&_limit=5000

Je ne suis pas du tout à l'aise avec ces appels .

Quelqu'un serait m'aider à construire une requête correcte ?

Merci d'avance


Pascal PLUVINET

Hors ligne

 

#2 Mon 08 April 2024 22:29

ThomasG
Membre
Lieu: Nantes
Date d'inscription: 9 Sep 2005
Messages: 947
Site web

Re: Construire une requete WFS sur le GPU et récupérer un shapefile

Salut,

De base, tu mixes le GetCapabilities qui ne sert qu'à obtenir la liste des couches et ce que permet le serveur en terme d'interrogation dont par exemple le format de sortie SHP ou autre

Sur le papier, wfs_du:doc_urba a une géométrie si je me fie au DescribeFeatureType

Code:

curl 'https://data.geopf.fr/wfs/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&VERSION=2.0.0&TYPENAMES=wfs_du:doc_urba'

J'ai testé

Code:

curl 'https://data.geopf.fr/wfs/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:doc_urba&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=44.764,4.498,45.27,5.228,urn:ogc:def:crs:EPSG::4326&sortBy=gid&STARTINDEX=0&COUNT=10'

Sauf que cela me renvoie vide

Je fais la même requête en changeant de couche

Code:

curl 'https://data.geopf.fr/wfs/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:zone_urba&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=44.764,4.498,45.27,5.228,urn:ogc:def:crs:EPSG::4326&sortBy=gid&STARTINDEX=0&COUNT=10'

qui elle ne me renvoie pas vide...

Je teste wfs_du:doc_urba sans passer de bbox

Code:

curl 'https://data.geopf.fr/wfs/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:doc_urba&SRSNAME=urn:ogc:def:crs:EPSG::4326&sortBy=gid&STARTINDEX=0&COUNT=10'

Miracle, cela me retourne les éléments. Sauf que je vois qu'ils sont sans géométries donc cela va être difficile de filtrer par bbox comme tu l'envisageais...

Si tu veux les zones urba qui ont des géométries, pas dur, ton URL, c'est https://data.geopf.fr/wfs/wfs?SERVICE=W … =SHAPE-ZIP

Si tu veux les doc_urba vu qu'ils n'ont pas de géométrie, alors, là, les grands maux, les grands remèdes...

Prendre le fichier https://cnig.gouv.fr/IMG/pdf/231220_sta … df#page=18 et regarder "Les différentes classes et leurs relations représentées en UML" pour comprendre que tu vas devoir faire des filtres attributaires vu qu'il n'y a rien de spatial sur la couche doc_urba et comprendre que via l'idurba, on devrait pouvoir filtrer en passant les infos entre les zone_urba et les doc_urba

Code:

curl 'https://data.geopf.fr/wfs/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:zone_urba&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=44.764,4.498,45.27,5.228,urn:ogc:def:crs:EPSG::4326&sortBy=gid&STARTINDEX=0&COUNT=10&propertyName=wfs_du:idurba' | xq -r '."wfs:FeatureCollection"."wfs:member"[]."wfs_du:zone_urba"."wfs_du:idurba"'

PS: xq, utilitaire fournit par yq https://kislyuk.github.io/yq/#xml-support

Mais GDAL c'est mieux car tu peux paginer

Bilan: je suis passé par gpu_doc_id qui est toujours rempli contrairement à idurba

Code:

ogr2ogr -f CSV -dialect SQLite -sql 'SELECT DISTINCT gpu_doc_id FROM "wfs_du:zone_urba"' /vsistdout/ 'WFS:https://data.geopf.fr/wfs/wfs?sortBy=gid&SRSNAME=urn:ogc:def:crs:EPSG::4326&BBOX=44.764,4.498,45.27,5.228,urn:ogc:def:crs:EPSG::4326' --config OGR_WFS_PAGING_ALLOWED ON --config OGR_WFS_PAGE_SIZE 5000 >| liste_gpu_doc_id.txt

J'ai pris une approche "brute force" (galèrer à retrouver autrement) mais éviter de lancer sur la moitié de la France en plus ce serait BEAUCOUP trop lent... Ici, il n'y a que 139 appels de 1 ou 2 features...

Code:

>| doc_urba.csv
for i in $(sed '1d' liste_gpu_doc_id.txt);
  do ogr2ogr -f CSV -dialect SQLite -sql "SELECT * FROM \"wfs_du:doc_urba\" WHERE gpu_doc_id = '${i}'" /vsistdout/ 'WFS:https://data.geopf.fr/wfs/wfs?sortBy=gid&SRSNAME=urn:ogc:def:crs:EPSG::4326' --config OGR_WFS_PAGING_ALLOWED ON --config OGR_WFS_PAGE_SIZE 5000 >> doc_urba.csv;
done;

Tip final le plus important: tu veux comprendre le WFS en ne comprenant rien au WFS. Soit passe par QGIS via le Network logger (raccourci F12 sur des QGIS récents), soit tu passes par ogrinfo/ogr2ogr. Le truc important, c'est --debug on --config CPL_CURL_VERBOSE YES qui te sert à voir les appels http vers le serveur que fait GDAL genre comme ci-dessous

Code:

ogr2ogr -f GeoJSON --debug on --config CPL_CURL_VERBOSE YES -dialect SQLite -sql 'SELECT * FROM "wfs_du:zone_urba" LIMIT 10' /vsistdout/ 'WFS:https://data.geopf.fr/wfs/wfs?sortBy=gid' --config OGR_WFS_PAGING_ALLOWED ON --config OGR_WFS_PAGE_SIZE 50

Thomas

Hors ligne

 

#3 Tue 09 April 2024 14:23

ppluvinet
Participant assidu
Lieu: VALENCE
Date d'inscription: 6 Aug 2007
Messages: 617

Re: Construire une requete WFS sur le GPU et récupérer un shapefile

Merci Thomas,


Cela m'a fait bien avancé.

En fait, je souhaitais mettre à jour un script R inspiré de
https://rdrr.io/github/PascalIrz/tod/ma … a_tod.html

Voici le script mis à jour. Ce n'ai pas toujours très élégant mais ca fonctionne !


Code:

library(dplyr)
library(stringr)
library(curl)
library(zip)





#############################
######PARAMETRES ############
#############################

###EMPRISE en WGS 84
XMIN<-4.498
YMIN<-44.764
XMAX<-5.228
YMAX<-45.27


#####Répertoire où on dépose les données
REP_OUTPUT<-"C:/MONSCHEMIN/"


#Chemin QGIS - pour deuxième partie où on fusionne les shapefile avec ogr2ogr
 BINQGIS<-'C:/OSGeo4W/bin/'
 Sys.setenv(PROJ_LIB="C:/OSGeo4W//share/proj")

#####Couches de données à récupérer

COUCHES_A_RECUP<-c("zone_urba","secteur_cc","prescription_lin","prescription_pct","prescription_surf","info_lin","info_pct","habillage_surf")

##########################################################
###FONCTION RECUPERANT LES SHAPEFILES EN FONCTION DE L'EMPRISE
##########################################################


ign_urba_tod <- function(couche,
                         ymin, xmin, ymax, xmax,
                         index_debut = 0, nb_elements_par_telech = 4999,
                         n_tot_elements_a_telech = 1e6, repertoire = NA)

{

  url_base_1 <- "https://data.geopf.fr/wfs/wfs?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:"
  url_base_2 <- "&SRSNAME=urn:ogc:def:crs:EPSG::2154"
  url_base_3 <- "&BBOX="
  url_base_4 <- "urn:ogc:def:crs:EPSG::4326&sortBy=gid&STARTINDEX="
  url_base_5 <- "&COUNT="
  url_base_6 <- "&outputformat=SHAPE-ZIP"



  # Répertoire de stockage des données. S'il n'est pas spécifié, il est nommé d'après la couche et éventuellement créé
  if(is.na(repertoire))
  {
    repertoire <- paste0("raw_data/", couche)
  }

  if(dir.exists(repertoire) == FALSE) dir.create(repertoire)

  # Création de vecteurs contenant autant d'éléments qu'il y aura de paquets à télécharger
  startindexes <- seq(from = index_debut,
                      to = n_tot_elements_a_telech,
                      by = nb_elements_par_telech) %>%
    format(scientific = FALSE) %>% 
    str_trim(side = "both") # nettoyage des espaces qui traînent

  requetes <- paste0(url_base_1, couche,
                     url_base_2,
                     url_base_3, ymin, ",", xmin, ",", ymax, ",", xmax, ",",
                     url_base_4, startindexes,
                     url_base_5, nb_elements_par_telech,
                     url_base_6)

  indices <- 1:length(requetes)
  chemins <- paste0(repertoire, "/",couche,"_", indices, ".zip")

  # Boucle sur les batch
  for(i in indices[1:length(indices)]) {
    print(requetes[i])
    curl_download(url = requetes[i], destfile = chemins[i]) 
    if(file.size(chemins[i]) < 1e5) break # interruption si l'on commence à télécharger des fichiers vides

  }

flush.console()
}

##################
###TRAITEMENT
#####################



#######################
### BLOUCLE SUR LES COUCHES A RECUPERER

for ( i in COUCHES_A_RECUP){
    print(i)
    ign_urba_tod(couche = i,
    xmin = XMIN,
    ymin = YMIN,
    xmax = XMAX,
    ymax = YMAX,
    repertoire = REP_OUTPUT)

}


##### On supprime les ZIP trop petits et on extrait les plus grands
ZIP_FILES_PATH<-list.files(REP_OUTPUT, pattern = ".zip", full.names = TRUE)

for (i in ZIP_FILES_PATH) {
    if(file.size(i) < 1e5){ 
    unlink (i)
    } else {
        unzip(i, overwrite=TRUE , exdir=paste0(REP_OUTPUT,"/",gsub(".zip","",basename(i))))
        unlink (i)
    }
}

#Merge shapefile via ogr2ogr


for ( i in COUCHES_A_RECUP){

DIR_PATH<-list.files(REP_OUTPUT, pattern = i, full.names = TRUE)

    for ( j in 1:length(DIR_PATH) ){
        if (j==1){
        FILESHP<-list.files(DIR_PATH[j], pattern = ".shp", full.names = TRUE)
        if(length(FILESHP)>0){
            SHPMERGED<-paste0(REP_OUTPUT,"/",i,".shp")
            COMMAND<-paste0('"',BINQGIS,'ogr2ogr" -overwrite -t_srs EPSG:2154 ','"',SHPMERGED,'"'," ",'"',FILESHP,'"')
            system(COMMAND)
            print(COMMAND)
            flush.console()
        }
        
        } else {
        FILESHP<-list.files(DIR_PATH[j], pattern = ".shp", full.names = TRUE)
        if(length(FILESHP)>0){
            NAMEnln<-gsub(".shp","",basename(SHPMERGED))
            COMMAND<-paste0('"',BINQGIS,'ogr2ogr" -update -append -t_srs EPSG:2154 ','"',SHPMERGED,'"'," ",'"',FILESHP,'" -nln ',NAMEnln)
            system(COMMAND)
            print(COMMAND)    
            flush.console()
        }
        }

    }
}

Pascal PLUVINET

Hors ligne

 

#4 Mon 15 April 2024 14:51

LEHALLAIS Arnaud
Participant occasionnel
Lieu: Maison du Département - St-Lô
Date d'inscription: 12 Oct 2006
Messages: 20
Site web

Re: Construire une requete WFS sur le GPU et récupérer un shapefile

Bonjour, pour ceux qui utilisent FME pour télécharger en SHAPEFILE les données du GPU (nouvelle plateforme IGN), voici la liste des URL à renseigner dans le HTTPCaller :

zone_urba

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:zone_urba&TYPENAME=wfs_du:zone_urba&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

secteur_cc

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:secteur_cc&TYPENAME=wfs_du:secteur_cc&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

prescription_surf

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:prescription_surf&TYPENAME=wfs_du:prescription_surf&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

prescription_pct

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:prescription_pct&TYPENAME=wfs_du:prescription_pct&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

prescription_lin

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:prescription_lin&TYPENAME=wfs_du:prescription_lin&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

info_surf

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:info_surf&TYPENAME=wfs_du:info_surf&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

info_pct

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:info_pct&TYPENAME=wfs_du:info_pct&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

info_lin

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:info_lin&TYPENAME=wfs_du:info_lin&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

habillage_txt

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:habillage_txt&TYPENAME=wfs_du:habillage_txt&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

habillage_surf

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:habillage_surf&TYPENAME=wfs_du:habillage_surf&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

habillage_pct

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:habillage_pct&TYPENAME=wfs_du:habillage_pct&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

habillage_lin

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:habillage_lin&TYPENAME=wfs_du:habillage_lin&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

document

Code:

https://data.geopf.fr/wfs/?SERVICE=WFS&REQUEST=GetFeature&VERSION=2.0.0&TYPENAMES=wfs_du:document&TYPENAME=wfs_du:document&STARTINDEX=0&SRSNAME=urn:ogc:def:crs:EPSG::4326&bbox=48.456,-1.949,49.728,-0.735,urn:ogc:def:crs:EPSG::4326&SORTBY=gid&COUNT=1

Pensez à modifier les coordonnées du rectangle englobant si vous ne voulez pas récupérer tout le département de la Manche.

Si vous souhaitez récupérer les 13 scripts FME complets, envoyez-moi un message.

En espérant que cela vous sera utile.

Arnaud

Dernière modification par LEHALLAIS Arnaud (Mon 15 April 2024 14:53)

Hors ligne

 

#5 Fri 19 April 2024 12:57

pierre_inci
Juste Inscrit !
Date d'inscription: 19 Apr 2024
Messages: 1

Re: Construire une requete WFS sur le GPU et récupérer un shapefile

Si comme moi vous cherchez à afficher les zones et servitudes du PLU à l"échelle du pays on peut télécharger l'ensemble des données en ftp. Fini pour ma part les requêtes récursives en python avec 5000 entités max pour les reconstituer.

Pour plus de détails on peut construire des requêtes à partir des partitions ou liens contenus dans les table attributaires.

https://www.geoportail-urbanisme.gouv.f … massif.pdf

Nomenclature des servitudes :

https://www.geoinformations.developpeme … 7abf9e.pdf

Hors ligne

 

Pied de page des forums

Powered by FluxBB