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

Printemps des cartes 2024

#1 Wed 02 February 2022 11:17

Hippo
Participant actif
Date d'inscription: 18 Jan 2015
Messages: 57

Intersection spatiale en version DQL

Bonjour,

Je dispose de 2 couches de données, l'une contenant les centroides des communes françaises et l'autre des polygones répartis sur le territoire français.
Je souhaite créer un buffer autour du centroide d'une des communes que j'aurai sélectionnée et intersecter ce buffer avec mes polygones pour renvoyer lesquels sont dans le périmètre.

Lorsque je lance ma requête dans PgAdmin, pas de problème.
Pour autant, lorsque mon dev créé la requête en DQL dans Doctrine (Symfony), la requête retourne les polygones présents dans le buffer contenu dans les limites de la commune sélectionnée. Hors, si je veux créer un buffer de 15km, celui ci doit pouvoir s'étendre au delà des limites communales.


J'ai l'impression que dans le DQL du coup, c'est le "andWhere" qui pose alors problème.

Ma requête en SQL :

Code:

SELECT a.lon,a.lat,a.code_insee, b.geometry
    FROM public.commune a, public.polygones b
      WHERE ST_Intersects(ST_Transform(ST_SetSRID(b.geometry, 4326), 2154),
                       ST_BUFFER(ST_Transform(ST_SetSRID(ST_Point( a.lon, a.lat), 4326), 2154),15000))
      AND a.code_insee = '21231'

La requête en DQL :

Code:

->where('ST_Intersects(ST_Transform(ST_SetSRID(b.geometry, 4326), 2154),

                    ST_Buffer(ST_Transform(ST_SetSRID(ST_Point(a.lon, a.lat), 4326), 2154), :perimetre)) = true')

                    ->andWhere('a.codeInsee = :codeInsee')

Hors ligne

 

#2 Wed 02 February 2022 11:49

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

Re: Intersection spatiale en version DQL

Bonjour,

Ce n'est pas la peine de créer physiquement un buffer pour faire ce que vous voulez faire: c'est une opération très coûteuse.
Il existe la fonction st_dwithin(geom1, geom2, distance) (distance within) qui permet de répondre à votre question.
Avec des index spatiaux sur les colonnes geom, c'est très rapide et ca supporte le type geography que vous semblez stocker dans votre table (http://postgis.net/docs/ST_DWithin.html).

Votre requête deviendrait:

Code:

SELECT a.lon,a.lat,a.code_insee, b.geometry
FROM public.commune a join public.polygones b on ST_dwithin(b.geometry::geography, ST_Point( a.lon, a.lat, 4326)::geography,15000)
where a.code_insee = '21231';

Il faudrait alors ajouter un index spatial sur polygones.geom::geography, ou directement stocker une geography dans cette table (ce qui est mieux si le srid = 4326).
ca serait bien aussi pour la performance de créer une colonne geography sur les communes avec long/lat)

De ce que je vois, la clause andwhere de DQL ne fait qu'injecter une constante (:codeinsee) dans la requete.

Vous pouvez logger les requêtes dans PG et ainsi voir la vraie requête lancée par Symfony.

Nicolas
ps. c'est pour ce genre de comportement que je ne suis pas fan des ORM wink

Hors ligne

 

#3 Thu 03 February 2022 14:31

Hippo
Participant actif
Date d'inscription: 18 Jan 2015
Messages: 57

Re: Intersection spatiale en version DQL

Merci pour votre réponse Nicolas.

Bien vu pour St_dwithin, j'étais passé à côté sur cette requête !

La clause andwhere du DQL nous permet effectivement de passer un code insee en paramètre.
Nous avons toujours le même problème, même en passant la requête en native dans Doctrine.
Il faut sûrement que l'on cherche ailleurs du coup ...

Hors ligne

 

#4 Thu 03 February 2022 17:11

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

Re: Intersection spatiale en version DQL

Bonjour,

Vous voyez passer la requete dans les logs PG ?
Sinon, doctrine est bien branchée sur la meme base que vous pour les tests ? (ca arrive souvent si on a plusieurs bases)
Le user doctrine est le meme que celui des tests, il a peut etre des restrictions sur des colonnes/lignes ?

Nicolas

Hors ligne

 

#5 Fri 04 February 2022 12:28

Hippo
Participant actif
Date d'inscription: 18 Jan 2015
Messages: 57

Re: Intersection spatiale en version DQL

En fait la requête DQL renvoie un résultat, mais elle ne renvoie en version DQL que les polygones à la fois dans le périmètre de la commune spécifiée et du buffer. Du coup si je trace un buffer à 50km autour du centroide de Lyon par exemple, au final seuls les polygones dans le périmètre de la commune de Lyon seront pris en compte et non ceux dans le rayon de 50km mais en dehors de la commune de Lyon.
A l'inverse dans la version SQL, ce sont bien l'ensemble de mes polygones dans le rayon de recherche qui sont retournés, sans se limiter au périmètre de la commune sélectionnée.

Hors ligne

 

Pied de page des forums

Powered by FluxBB