asit-asso / extract

EXTRACT makes it easy to extract and deliver of your geodata
GNU General Public License v3.0
9 stars 4 forks source link

2.1-BETA.1 : QGIS Server print : La clef primaire de sélection des features est hard codée. #304

Closed yblatti closed 4 months ago

yblatti commented 6 months ago

Lors de l'extraction de identifiants à utiliser pour l'impression, le xpath cherche un champ hard codé (id). On trouve le xpath ici : config.properties. Valeur : /FeatureCollection/featureMember/%s/id.

Si le layer qui défini les zones à imprimer de l'atlas (atlasCoverageLayer) utilise une autre clé primaire, ou n'en a pas (par exemple un shapefile aura son FID interne, mais ce n'est pas un champ, il n'est donc pas forcément présenté comme tel dans la réponse du GetFeature).

Erreur dans le log si la couche d'atlasCoverageLayer n'a pas de champ id :

12:44:04.689 511515928 [pool-5-thread-2] DEBUG c.a.e.p.qgisprint.QGISPrintPlugin - HTTP GetFeature completed with status code 200.
12:44:04.689 511515928 [pool-5-thread-2] DEBUG c.a.e.p.qgisprint.QGISPrintPlugin - HTTP GetFeature was successful. Response was HttpResponseProxy{HTTP/1.1 200 OK [Date: Wed, 08 May 2024 12:44:04 GMT, Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8, Transfer-Encoding: chunked, Connection: keep-alive, Server: QGIS FCGI server - QGIS version 3.36.2-Maidenhead] ResponseEntityProxy{[Content-Type: text/xml; subtype=gml/3.1.1; charset=utf-8,Chunked: true]}}.
12:44:04.690 511515929 [pool-5-thread-2] DEBUG c.a.e.p.qgisprint.QGISPrintPlugin - Coverage layer has found []
12:44:04.691 511515930 [pool-5-thread-2] ERROR c.a.e.p.qgisprint.QGISPrintPlugin - The QGIS extraction service has failed
java.lang.Exception: Aucun identifiant de couche n'a été trouvé dans le service QGIS Server
        at ch.asit_asso.extract.plugins.qgisprint.QGISPrintPlugin.execute(QGISPrintPlugin.java:400)
        at ch.asit_asso.extract.orchestrator.runners.RequestTaskRunner.executeTask(RequestTaskRunner.java:275)
        at ch.asit_asso.extract.orchestrator.runners.RequestTaskRunner.run(RequestTaskRunner.java:173)
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
        at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.base/java.lang.Thread.run(Unknown Source)

Je pense qu'il faudrait utiliser le gml:id : /FeatureCollection/featureMember/%s/@id, qui est toujours composé ainsi sur QGIS Server : <featureType>.<id> en faisant attention : un feature type peut contenir des points.

Pseudo code :

        String gmlIdFromXpath = "avec_des._points._test.987";
        String[] gmlIdElements = gmlIdFromXpath.split("\\.", 0);
        String primaryKeyForAtlas_PK = gmlIdElements[gmlIdElements.length - 1];

Pseudo implémentation (non testé):

# /extract-task-qgisprint/src/main/resources/plugins/qgisprint/properties/config.properties
getFeature.xpath.gmlId=/FeatureCollection/featureMember/%s/@id
// /extract-task-qgisprint/src/main/java/ch/asit_asso/extract/plugins/qgisprint/QGISPrintPlugin.java
        final NodeList idsList = this.getXMLNodeListFromXPath(document,
                String.format(this.config.getProperty("getFeature.xpath.gmlId"), coverageLayer));
        ArrayList<String> ids = new ArrayList<String>();

        for (int i = 0; i < idsList.getLength(); i++) {
            String[] gmlIdElements = idsList.item(i).getTextContent().split("\\.", 0);
            ids.add(gmlIdElements[gmlIdElements.length - 1]);
        }
yblatti commented 6 months ago

Remonté pour correction : ticket interne FS#23419

yblatti commented 6 months ago

Projet pour reproduire : https://github.com/asit-asso/qgis-server-extract-demo

yblatti commented 5 months ago

Testé sur beta.3, tout roule ! Merci