Annonce
Pour sa 21ème année, l’association GeoRezo a toujours besoin de vous !
10€ = 1 mois de frais bancaires ; 15€ = 12 mois de nom de domaine ; 30€ = 1 semaine de location des serveurs …
Retrouver nos membres bienfaiteurs
#1 Thu 16 May 2024 10:06
- Pastore
- Participant occasionnel
- Date d'inscription: 4 Nov 2019
- Messages: 44
Rectangle inscrit à l'intérieur d'une forme polygonale
Bonjour à vous,
Dans le cadre d'une analyse du potentiel de densification pour un PLUI, je suis à la recherche d'une fonction Postgresql permettant de définir un rectangle ou carré de taille maximum à l'intérieur d'un polygone.
Pour l'instant, j'ai seulement utilisé la fonction suivante ST_MaximumInscribedCircle (voir le résultat en capture d'écran)
create table ateliers.uf_division_test as
SELECT
ST_Buffer((ST_MaximumInscribedCircle(geom)).center,
(ST_MaximumInscribedCircle(geom)).radius) as MaximumInscribedCircle
FROM
ateliers.uf_division_parcellaire_residentielles
AS t1(geom3)
Est ce que à votre une connaissance une fonction similaire pour un résultat avec des carrés et/ou rectangles existerait ?
Merci à vous
Hors ligne
#2 Thu 16 May 2024 12:17
- Papiroux77
- Participant occasionnel
- Date d'inscription: 26 Mar 2024
- Messages: 10
Re: Rectangle inscrit à l'intérieur d'une forme polygonale
Bonjour,
Malheureusement, postgreSQL ne dispose pas d'une fonction intégrée spécifique pour trouver le carré ou le rectangle inscrit maximal dans un polygone.
Après quelques recherches, vous pouvez quand même y parvenir en bidouillant un peu... Voici ce que j'ai trouvé et que vous pouvez tester de votre côté, sans garanti que ca marche de ma part.
Une proposition à tester est donc l'utilisation d'une combinaison de fonctions existantes et un peu de manipulation de la géométrie.
D'abord, trouver le rectangle minimum tournant qui englobe le polygone. Ce rectangle représente l'ajustement le plus serré autour du polygone, compte tenu de son orientation. Vous pouvez utiliser la fonction ST_MinimumBoundingCircle:
SELECT
ST_MinimumBoundingCircle(geom) AS MinimumBoundingCircle
FROM
ateliers.uf_division_parcellaire_residentielles AS t1(geom3);
Cela vous donnera un cercle qui représente le MBR. Vous pouvez extraire le centre et le rayon du cercle pour définir le MBR.. sauf que ce dernier ne pas être aligné avec les axes du polygone, ce qui entraîne un carré ou un rectangle non optimal. Pour résoudre ce problème, vous devez aligner le rectangle avec les axes principaux du polygone. Vous pouvez utiliser la fonction ST_PrincipalAxis.
SELECT
ST_PrincipalAxis(geom) AS PrincipalAxes
FROM
ateliers.uf_division_parcellaire_residentielles AS t1(geom3);
Cela vous donnera un segment de ligne représentant l'orientation principale du polygone. Avec le MBR et les axes principaux, vous pouvez calculer le carré ou le rectangle maximal qui s'inscrit dans le polygone, aligné avec ses axes. Pour cela, il faut:
a) Trouver la largeur et la hauteur :
- Utilisez la fonction ST_LineLength pour trouver la longueur du segment de ligne représentant l'axe principal. Ce sera la largeur ou la hauteur maximale du rectangle.
- Divisez le rayon du MBR par la racine carrée de 2 (puisque le MBR est un cercle inscrit dans un carré). Cela vous donnera la hauteur ou la largeur approximative.
- Prenez le minimum des deux valeurs calculées ci-dessus pour vous assurer que le carré ou le rectangle s'inscrit entièrement dans le polygone.
b) Créer le carré/rectangle :
- Utilisez le centroïde du polygone (qui peut être extrait du MBR) comme centre du carré ou du rectangle.
- Utilisez la largeur et la hauteur calculées pour créer un point représentant l'autre coin du rectangle.
- Construisez le carré ou le rectangle en utilisant les deux points (centre et coin).
Maintenant, vous pouvez combiner ces étapes en une seule requête pour trouver le carré ou le rectangle inscrit maximal pour chaque polygone et visualiser les résultats:
WITH inscribed_square AS (
SELECT
t1.geom3,
ST_MinimumBoundingCircle(t1.geom3) AS MinimumBoundingCircle,
ST_PrincipalAxis(t1.geom3) AS PrincipalAxes,
CASE
WHEN ST_Length(ST_LineLength(pa.line)) >= 2 * ST_Radius(mbc.circle) THEN
ST_MakePolygon(
ST_MakePoint(mbc.centerx - (ST_Length(pa.line) / SQRT(2)), mbc.centery - (ST_Length(pa.line) / SQRT(2))),
ST_MakePoint(mbc.centerx + (ST_Length(pa.line) / SQRT(2)), mbc.centery - (ST_Length(pa.line) / SQRT(2))),
ST_MakePoint(mbc.centerx + (ST_Length(pa.line) / SQRT(2)), mbc.centery + (ST_Length(pa.line) / SQRT(2))),
ST_MakePoint(mbc.centerx - (ST_Length(pa.line) / SQRT(2)), mbc.centery + (ST_Length(pa.line) / SQRT(2)))
)
ELSE
ST_MakePolygon(
ST_MakePoint(mbc.centerx - (ST_Radius(mbc.circle) / SQRT(2)), mbc.centery - (ST_Radius(mbc.circle) / SQRT(2))),
ST_
Bonne chance.
Hors ligne
#3 Thu 16 May 2024 12:47
- Nicolas Ribot
- Membre
- Lieu: Toulouse
- Date d'inscription: 9 Sep 2005
- Messages: 1554
Re: Rectangle inscrit à l'intérieur d'une forme polygonale
Nice,
(pour créer un rectangle a partir d'un point, vous pouvez utiliser st_expand, par ex:
Code:
select st_astext(st_expand('POINT(0 0)'::geometry, 5, 10)); -- POLYGON((-5 -10,-5 10,5 10,5 -10,-5 -10))
)
Nico
Dernière modification par Nicolas Ribot (Thu 16 May 2024 12:48)
Hors ligne
#4 Thu 16 May 2024 13:54
- Pastore
- Participant occasionnel
- Date d'inscription: 4 Nov 2019
- Messages: 44
Re: Rectangle inscrit à l'intérieur d'une forme polygonale
Merci pour vos retours ; je suis en train de tester votre requête @Papiroux77 mais cela m'indique que la fonction st_PrincipalAxis n'existe pas
Est ce que vous savez ou je peux la trouver pour la rajouter dans le schéma public ?
Merci,
Hors ligne