Project

General

Profile

Development #38865

opengis: traiter (ou pas) les contenus XML

Added by Nicolas Roche about 1 year ago. Updated 8 months ago.

Status:
Solution proposée
Priority:
Normal
Assignee:
Target version:
-
Start date:
09 Jan 2020
Due date:
% Done:

0%

Estimated time:
Patch proposed:
Yes
Planning:
No

Description

Le serveur OpenData de Toulouse (https://data.toulouse-metropole.fr/) retourne des contenus XML,
or le connecteur opengis s'attend à recevoir du JSON.

cf https://docs.geoserver.org/latest/en/user/services/wfs/outputformats.html

smihai‎: le outputformat=json est bien envoyé?

oui : https://data.toulouse-metropole.fr/api/wfs?version=1.1.0&OUTPUTFORMAT=json&CQL_FILTER=DWITHIN%28the_geom%2CPoint%281.412+43.596%29%2C5%2Cmeters%29&SERVICE=WFS&REQUEST=GetFeature&TYPENAME=ods%3Apoints_apport_volontaire_dmt&VERSION=1.0.0

cf https://help.opendatasoft.com/apis/wfs/#getfeature
(aucune mention du paramètre outputformat)

smihai‎: alors p'tet une couille dans OpenDataSoft


Files


Related issues

Related to Passerelle - Bug #38851: opengis: adapter le paramètre typeNames à la version du serveurSolution déployée08 Jan 2020

Actions
Related to Passerelle - Development #41224: opengis: json n'est pas un format standardSolution déployée01 Apr 2020

Actions

History

#1

Updated by Nicolas Roche about 1 year ago

  • Related to Bug #38851: opengis: adapter le paramètre typeNames à la version du serveur added
#2

Updated by Frédéric Péters about 1 year ago

https://data.toulouse-metropole.fr/api/wfs?version=1.1.0&request=GetCapabilities&service=WFS

On y note <wfs:OutputFormats><wfs:Format>text/xml; subtype=gml/3.1.1</wfs:Format></wfs:OutputFormats> l'absence de sortie possible en json.

À comparer, https://download.data.grandlyon.com/wfs/grandlyon?request=GetCapabilities&service=WFS.

<ows:AllowedValues>
  <ows:Value>application/gml+xml; version=3.2</ows:Value>
  <ows:Value>text/xml; subtype=gml/3.2.1</ows:Value>
  <ows:Value>text/xml; subtype=gml/3.1.1</ows:Value>
  <ows:Value>text/xml; subtype=gml/2.1.2</ows:Value>
  <ows:Value>application/shapefile</ows:Value>
  <ows:Value>application/json; subtype=geojson</ows:Value>
</ows:AllowedValues>

Et je dirais donc qu'ici comme pour TYPENAMES, il faut interroger le serveur en fonction de ce qu'il peut faire. Et que le rôle du connecteur est de fournir un comportement identique peu importe ce qu'on trouve derrière. Et donc transformer ce FeatureCollection XML en FeatureCollection geojson.

Pour un exemple de format : https://download.data.grandlyon.com/wfs/grandlyon?SERVICE=WFS&VERSION=2.0.0&outputformat=GEOJSON&request=GetFeature&typename=ter_territoire.maison_de_la_metropole&SRSNAME=urn:ogc:def:crs:EPSG::4326

#3

Updated by Nicolas Roche about 1 year ago

En copiant la configuration de toulouse, https://passerelle-moncompte.cutm-ea-dev-publik.nfrance.com/opengis/opendata-tm/
ce patch semble fonctionner sur cet appel : /opengis/opendata-tm/reverse?lat=45.79689&lon=4.78414

{"lat": "1.474023", "lon": "43.564278", "err": 0, "address": {"city": "TOULOUSE"}}

(je veux bien plus de billes pour aller plus loin)

A noter : j'ai modifié les tests des connecteurs grenoble_gru et vivaticket à cause des problèmes d'encodage sur la réponse que l'on obtient avec la requête testée ci-dessus.

#4

Updated by Benjamin Dauvergne about 1 year ago

Nicolas Roche a écrit :

En copiant la configuration de toulouse, https://passerelle-moncompte.cutm-ea-dev-publik.nfrance.com/opengis/opendata-tm/
ce patch semble fonctionner sur cet appel : /opengis/opendata-tm/reverse?lat=45.79689&lon=4.78414
[...]
(je veux bien plus de billes pour aller plus loin)

A noter : j'ai modifié les tests des connecteurs grenoble_gru et vivaticket à cause des problèmes d'encodage sur la réponse que l'on obtient avec la requête testée ci-dessus.

Si tu veux émuler FakedResponse au plus près tu dois respecter son API, .content doit être un str/bytes (force_bytes) et .text un unicode/str (force_text). Je pense que l'API devrait ressembler à ça :

def __init__(self, text=None, content=None):
    if content is not None:
        self.content = content
    elif text is not None:
        self.content = force_bytes(text)

@property
def text(self):
    return force_text(self.content)

Ça devrait éviter d'avoir à changer grenoble gru et vivaticket.

#5

Updated by Nicolas Roche about 1 year ago

Si tu veux émuler FakedResponse au plus près ...

Nickel ! Mais je pense que ça attendra #38781, et que d'ici là ce premier patch ne sera plus nécessaire.

Concernant directement ce ticket, le second patch ne fait que marcher les endpoints reverse et features.
#8

Updated by Nicolas Roche 12 months ago

Le endpoint features semble en fait ne fonctionner que si l'on ne passe pas de valeur à propertyName.
J'ai l'impression que le serveur visé ne gère pas ce paramètre décrit dans
https://docs.geoserver.org/latest/en/user/services/wfs/reference.html#getfeature

Par exemple, cette requête au connecteur :
https://passerelle.dev.publik.love/opengis/aaa/features?property_name=index&type_names=gymnases
déclenche celle-ci sur le serveur openData :
https://data.toulouse-metropole.fr/api/wfs?OUTPUTFORMAT=xml&SERVICE=WFS&PROPERTYNAME=index&REQUEST=GetFeature&TYPENAME=gymnases&VERSION=1.0.0
qui répond une 400 :

<Exception exceptionCode="InvalidParameterValue" locator="PropertyName"/>

#10

Updated by Benjamin Dauvergne 12 months ago

Nicolas Roche a écrit :

Le endpoint features semble en fait ne fonctionner que si l'on ne passe pas de valeur à propertyName.
J'ai l'impression que le serveur visé ne gère pas ce paramètre décrit dans
https://docs.geoserver.org/latest/en/user/services/wfs/reference.html#getfeature

Par exemple, cette requête au connecteur :
https://passerelle.dev.publik.love/opengis/aaa/features?property_name=index&type_names=gymnases
déclenche celle-ci sur le serveur openData :
https://data.toulouse-metropole.fr/api/wfs?OUTPUTFORMAT=xml&SERVICE=WFS&PROPERTYNAME=index&REQUEST=GetFeature&TYPENAME=gymnases&VERSION=1.0.0
qui répond une 400 :
[...]

Deux choses qui me choquent :
  • dans la doc les noms des attributs semble sensible à la casse (en tout cas ils capitalisent bizarrement) mais c'est peut-être pas le cas
  • ils utilisent version=2.0.0 (ceci explique cela certainement)

Dans la norme 1.0.0 ça semble existe, chercher PROPERTYNAME= dans http://portal.opengeospatial.org/files/?artifact_id=7176 sur https://www.opengeospatial.org/standards/wfs .

#11

Updated by Benjamin Dauvergne 12 months ago

Je remarque que c'est la valeur de PROPERTYNAME qui l'embête aussi, pas la clé. Donc c'est juste pas index qu'il faut demander.

#12

Updated by Nicolas Roche 12 months ago

les noms des attributs semble sensible à la casse

dans l'ensemble ça à l'air de fonctionner avec les majuscules, comme le montre le test du endpoint reverse si dessus.

ils utilisent version=2.0.0 (ceci explique cela certainement)

non, c'est tout l'objet du ticket (plutôt #38848 en fait) : faire fonctionner le connecteur opengis sur leur opendata (https://data.toulouse-metropole.fr) qui tourne WFS en 1.1.0 alors que le connecteur a été développé sur leur geoserver (https://geows.extranet.toulouse-metropole.fr/geoserver/gisements/ows?service=WFS&request=GetCapabilities&service=WFS) qui tourne WFS en 2.0.0

(merci pour la doc, qui dit :)

The <PropertyName> element is used to enumerate the feature properties that should be
selected during a query and whose values should be included in the response to a
GetFeature request. A client application can determine the properties of a feature by
making a DescribeFeatureType request before composing a GetFeature request. The
DescribeFeatureType operation [sec. 8] will generate a GML application schema
defining the schema of the feature type.

cf https://data.toulouse-metropole.fr/api/wfs?SERVICE=WFS&REQUEST=DescribeFeatureType&TYPENAME=points_apport_volontaire_dmt

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema ...>
  <xsd:import .../>
  <xsd:element substitutionGroup="gml:_Feature" type="ods:points_apport_volontaire_dmt_Type" name="points_apport_volontaire_dmt"/>
  <xsd:complexType name="points_apport_volontaire_dmt_Type">
    <xsd:complexContent>
      <xsd:extension base="gml:AbstractFeatureType">
        <xsd:sequence>
          <xsd:element maxOccurs="1" nillable="true" type="xsd:string" name="adresse" minOccurs="0"/>
          <xsd:element maxOccurs="1" nillable="true" type="xsd:string" name="commune" minOccurs="0"/>
...
          <xsd:element maxOccurs="1" nillable="true" type="xsd:string" name="zone" minOccurs="0"/>
          <xsd:element maxOccurs="1" nillable="true" type="xsd:string" name="num_prest" minOccurs="0"/>
          <xsd:element maxOccurs="1" nillable="true" type="gml:GeometryPropertyType" name="geo_shape" minOccurs="0"/>
        </xsd:sequence>
      </xsd:extension>
    </xsd:complexContent>
  </xsd:complexType>
</xsd:schema>

The client can then select the properties to be
fetched.
...

cf https://data.toulouse-metropole.fr/api/wfs?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=points_apport_volontaire_dmt&PROPERTYNAME=commune

<Exception exceptionCode="InvalidParameterValue" locator="PropertyName"/>

If no <PropertyName> elements are specified, then all feature properties should be
fetched.

cf https://data.toulouse-metropole.fr/api/wfs?SERVICE=WFS&REQUEST=GetFeature&TYPENAME=points_apport_volontaire_dmt
...

  <gml:featureMember>
    <ods:points_apport_volontaire_dmt gml:id="points_apport_volontaire_dmt.3757c88a87f28488c314717a52331451b96fe021">
      <ods:geo_shape>
        <gml:Point srsName="urn:x-ogc:def:crs:EPSG:4326">
          <gml:pos>43.6247999998 1.47496000344</gml:pos>
        </gml:Point>
      </ods:geo_shape>
      <ods:commune>TOULOUSE</ods:commune>
      <ods:centre_ville>N</ods:centre_ville>
      <ods:zone>B</ods:zone>
      <ods:flux>TX</ods:flux>
      <ods:prestataire>LE RELAIS</ods:prestataire>
      <ods:adresse>64 ROUTE D'AGDE</ods:adresse>
      <ods:code_com>31555</ods:code_com>
      <ods:longitude>1.47496</ods:longitude>
      <ods:geo_point_2d>
        <gml:Point srsName="urn:x-ogc:def:crs:EPSG:4326">
          <gml:pos>43.6247999998 1.47496000344</gml:pos>
        </gml:Point>
      </ods:geo_point_2d>
      <ods:volume>0.0</ods:volume>
      <ods:marque>CONTENEUR</ods:marque>
      <ods:a_e>A</ods:a_e>
      <ods:code_tm>TLSTX5056</ods:code_tm>
      <ods:mes>20041101</ods:mes>
      <ods:latitude>43.6248</ods:latitude>
      <ods:num_prest>05.63.98.96.28</ods:num_prest>
      <ods:modele>PUBLIC</ods:modele>
    </ods:points_apport_volontaire_dmt>
  </gml:featureMember>
  ...

Il me manque un cas d'usage pour avancer.
Peut-être que l'on pourrait pousser en l'état et dans un premier temps laisser Cyril continuer à tester (#38848) ?

#13

Updated by Benjamin Dauvergne 12 months ago

J'ai compris la syntaxe :

https://data.toulouse-metropole.fr/api/wfs?SERVICE=WFS&REQUEST=GetFeature&PROPERTYNAME=points_apport_volontaire_dmt/commune&TYPENAME=points_apport_volontaire_dmt

(en lisant la page 67 du doc pointé plus haut, il faut donc mettre le nom du type séparé par un slash du nom de l'attribut, ensuite séparé la liste d'attributs par des virgules).

#14

Updated by Nicolas Roche 12 months ago

Donc cette requête fonctionne bien : https://passerelle.dev.publik.love/opengis/aaa/features?property_name=gymnases/index&type_names=gymnases
Merci Benjamin !!

Maintenant si je veux aller au bout (intégrer tous les paramètres du endpoint dans la requête), j'ai un dernier problème avec le paramètre q :
https://passerelle.dev.publik.love/opengis/aaa/features?cql_filter=commune=%27TOULOUSE%27&filter_property_name=index&case-insensitive=true&property_name=gymnases/index&type_names=gymnases
=>
https://data.toulouse-metropole.fr/api/wfs?version=1.1.0&OUTPUTFORMAT=xml&CQL_FILTER=commune%3D%27TOULOUSE%27&SERVICE=WFS&PROPERTYNAME=gymnases%2Findex&REQUEST=GetFeature&TYPENAME=gymnases&VERSION=1.0.0
(ok)

https://passerelle.dev.publik.love/opengis/aaa/features?cql_filter=commune=%27TOULOUSE%27&filter_property_name=index&case-insensitive=true&property_name=gymnases/index&type_names=gymnases&q=eau
=>
https://data.toulouse-metropole.fr/api/wfs?version=1.1.0&OUTPUTFORMAT=xml&CQL_FILTER=commune%3D%27TOULOUSE%27+AND+index+ILIKE+%27%25eau%25%27&SERVICE=WFS&PROPERTYNAME=gymnases%2Findex&REQUEST=GetFeature&TYPENAME=gymnases&VERSION=1.0.0
403 Forbidden (à priori de la part de nginx)

Rq : s/AND/AAND/ + s/index/inddex/ et ça passe
https://data.toulouse-metropole.fr/api/wfs?version=1.1.0&OUTPUTFORMAT=xml&CQL_FILTER=commune%3D%27TOULOUSE%27+AAND+inddex+ILIKE+%27%25eau%25%27&SERVICE=WFS&PROPERTYNAME=gymnases%2Findex&REQUEST=GetFeature&TYPENAME=gymnases&VERSION=1.0.0

Un problème de filtrage côté nginx ?

#15

Updated by Benjamin Dauvergne 12 months ago

Là je pense qu'il faut prendre contact avec Toulouse Strasbourg pour comprendre, expose ton problème sur le ticket #38848.

#16

Updated by Benjamin Dauvergne 12 months ago

À finir si on dispose d'un service WFS en version 1.0 qui accepte le paramètre CQL_FILTER (on aurait ça à Strabourg?), ou alors on pousse comme cela en sachant que le support du CQL_FILTER n'est pas testé et on verra le jour où on en aura besoin.

#17

Updated by Nicolas Roche 11 months ago

Non, je n'ai pas l'impression qu'il y ait un service WFS à Strasbourg : http://adict.strasbourg.eu/mapproxy/demo/

#18

Updated by Valentin Deniaud 10 months ago

#20

Updated by Thomas Noël 8 months ago

  • Assignee set to Nicolas Roche

Also available in: Atom PDF