PostgreSQLLa base de données la plus sophistiquée au monde.
Documentation PostgreSQL 13.18 » Langage SQL » Fonctions et opérateurs » Fonctions et opérateurs de géométrie

9.11. Fonctions et opérateurs de géométrie

Les types géométriques point, box, lseg, line, path, polygon et circle ont un large ensemble des fonctions et opérateurs de support natifs, affichés dans Tableau 9.35, Tableau 9.36 et Tableau 9.37.

Tableau 9.35. Opérateurs géométriques

Opérateur

Description

Exemple(s)

geometric_type + pointgeometric_type

Ajoute les coordonnées du deuxième point à celles du premier argument, réalisant ainsi la translation. Disponible pour les types point, box, path, circle.

box '(1,1),(0,0)' + point '(2,0)'(3,1),(2,0)

path + pathpath

Concatène deux chemins ouverts (renvoie NULL si un des chemins est fermé).

path '[(0,0),(1,1)]' + path '[(2,2),(3,3),(4,4)]'[(0,0),(1,1),(2,2),(3,3),(4,4)]

geometric_type - pointgeometric_type

Soustrait les coordonnées du deuxième point de celle de chaque point du premier argument, réalisant ainsi la translation. Disponible pour les types point, box, path, circle.

box '(1,1),(0,0)' - point '(2,0)'(-1,1),(-2,0)

geometric_type * pointgeometric_type

Multiplie chaque point du premier argument avec le second point (traitant un point comme étant un nombre complexe représenté par une partie réelle et une partie imaginaire, et réalisant ainsi une multiplication standard complexe). Si on interprète le deuxième point comme un vecteur, ceci est équivalent à mettre à l'échelle la taille et la distance de l'objet de l'origine par la longueur de la vecteur, et en faisant une rotation en sens inverse de l'horloge autour de l'origine par l'angle du vecteur sur l'axe x. Disponible pour les types point, box,[a] path, circle.

path '((0,0),(1,0),(1,1))' * point '(3.0,0)'((0,0),(3,0),(3,3))

path '((0,0),(1,0),(1,1))' * point(cosd(45), sind(45))((0,0),​(0.7071067811865475,0.7071067811865475),​(0,1.414213562373095))

geometric_type / pointgeometric_type

Divise chaque point du premier argument par le deuxième point (traitant un point comme étant un nombre complexe représenté par les parties réelle et imaginaire, et réalisant la division complexe standard). Si on interprète le deuxième point comme un vecteur, ceci est équivalent à mettre à l'échelle la taille et la distance de l'objet à partir de l'origine sur la longueur du vecteur et en faisant une rotation en sens inverse de l'horloge autour de l'origine par l'angle du vecteur sur l'axe x. Disponible pour les types point, box,[a] path, circle.

path '((0,0),(1,0),(1,1))' / point '(2.0,0)'((0,0),(0.5,0),(0.5,0.5))

path '((0,0),(1,0),(1,1))' / point(cosd(45), sind(45))((0,0),​(0.7071067811865476,-0.7071067811865476),​(1.4142135623730951,0))

@-@ geometric_typedouble precision

Calcule la longueur totale. Disponible pour les types lseg, path.

@-@ path '[(0,0),(1,0),(1,1)]'2

@@ geometric_typepoint

Calcule le point central. Disponible pour les types box, lseg, path, polygon, circle.

@@ box '(2,2),(0,0)'(1,1)

# geometric_typeinteger

Renvoie le nombre de points. Disponible pour les types path, polygon.

# path '((1,0),(0,1),(-1,0))'3

geometric_type # geometric_typepoint

Calcule le point d'intersection, ou NULL s'il n'y en a pas. Disponible pour les types lseg, line.

lseg '[(0,0),(1,1)]' # lseg '[(1,0),(0,1)]'(0.5,0.5)

box # boxbox

Calcule l'intersection de deux boîtes, ou NULL s'il n'y en a pas.

box '(2,2),(-1,-1)' # box '(1,1),(-2,-2)'(1,1),(-1,-1)

geometric_type ## geometric_typepoint

Calcule le point le plus proche du premier objet à partir du deuxième objet. Disponible pour ces paires de types : (point, box), (point, lseg), (point, line), (lseg, box), (lseg, lseg), (line, lseg).

point '(0,0)' ## lseg '[(2,0),(0,2)]'(1,1)

geometric_type <-> geometric_typedouble precision

Calcule la distance entre les objets. Disponible pour tous les types géométriques sauf polygon, pour toutes les combinaisons du point avec un autre type géométrique, et pour ces paires supplémentaires de types : (box, lseg), (lseg, line), (polygon, circle) (et les cas de commutation).

circle '<(0,0),1>' <-> circle '<(5,0),1>'3

geometric_type @> geometric_typeboolean

Est-ce que le premier objet contient le second ? Disponible pour ces paires de types : (box, point), (box, box), (path, point), (polygon, point), (polygon, polygon), (circle, point), (circle, circle).

circle '<(0,0),2>' @> point '(1,1)'t

geometric_type <@ geometric_typeboolean

Est-ce que le premier objet est contenu dans le second ? Disponibles pour ces paires de types : (point, box), (point, lseg), (point, line), (point, path), (point, polygon), (point, circle), (box, box), (lseg, box), (lseg, line), (polygon, polygon), (circle, circle).

point '(1,1)' <@ circle '<(0,0),2>'t

geometric_type && geometric_typeboolean

Est-ce que ces objets se surchargent ? (Un point en commun rend ceci vrai.) Disponible pour box, polygon, circle.

box '(1,1),(0,0)' && box '(2,2),(0,0)'t

geometric_type << geometric_typeboolean

Est-ce que le premier objet est strictement à gauche du second ? Disponible pour point, box, polygon, circle.

circle '<(0,0),1>' << circle '<(5,0),1>'t

geometric_type >> geometric_typeboolean

Est-ce que le premier objet est strictement à droite du second ? Disponible pour point, box, polygon, circle.

circle '<(5,0),1>' >> circle '<(0,0),1>'t

geometric_type &< geometric_typeboolean

Est-ce que le premier objet ne s'étend pas à droite du second ? Disponible pour box, polygon, circle.

box '(1,1),(0,0)' &< box '(2,2),(0,0)'t

geometric_type &> geometric_typeboolean

Est-ce que le premier objet ne s'étend pas à gauche du second ? Disponible pour box, polygon, circle.

box '(3,3),(0,0)' &> box '(2,2),(0,0)'t

geometric_type <<| geometric_typeboolean

Est-ce que le premier objet se trouve strictement en dessous du second ? Disponible pour box, polygon, circle.

box '(3,3),(0,0)' <<| box '(5,5),(3,4)'t

geometric_type |>> geometric_typeboolean

Est-ce que le premier objet se trouve strictement au-dessus du second ? Disponible pour box, polygon, circle.

box '(5,5),(3,4)' |>> box '(3,3),(0,0)'t

geometric_type &<| geometric_typeboolean

Est-ce que le premier objet ne s'étend pas au dessus du second ? Disponible pour box, polygon, circle.

box '(1,1),(0,0)' &<| box '(2,2),(0,0)'t

geometric_type |&> geometric_typeboolean

Est-ce que le premier objet ne s'étend pas en dessous du second ? Disponible pour box, polygon, circle.

box '(3,3),(0,0)' |&> box '(2,2),(0,0)'t

box <^ boxboolean

Est-ce que le premier objet est en-dessous du second (les coins peuvent se toucher) ?

box '((1,1),(0,0))' <^ box '((2,2),(1,1))'t

point <^ pointboolean

Est-ce que le premier objet se trouve strictement en dessous du second ? (Cet opérateur est mal nommé ; cela devrait être <<|.)

point '(1,0)' <^ point '(1,1)'t

box >^ boxboolean

Est-ce que le premier objet se trouve au dessus du second (les coins peuvent se toucher) ?

box '((2,2),(1,1))' >^ box '((1,1),(0,0))'t

point >^ pointboolean

Est-ce que le première objet est strictement au dessus du second ? (Cet opérateur est mal nommé ; cela devrait être |>>.)

point '(1,1)' >^ point '(1,0)'t

geometric_type ?# geometric_typeboolean

Est-ce que ces objets s'intersectent ? Disponible pour ces paires de types : (box, box), (lseg, box), (lseg, lseg), (lseg, line), (line, box), (line, line), (path, path).

lseg '[(-1,0),(1,0)]' ?# box '(2,2),(-2,-2)'t

?- lineboolean

?- lsegboolean

La lign est-elle horizontale ?

?- lseg '[(-1,0),(1,0)]'t

point ?- pointboolean

Les points sont-ils alignés horizontalement (autrement dit, même coordonnée y) ?

point '(1,0)' ?- point '(0,0)'t

?| lineboolean

?| lsegboolean

La ligne est-elle verticale ?

?| lseg '[(-1,0),(1,0)]'f

point ?| pointboolean

Les points sont-ils alignés verticalement (autrement dit, même coordonnée x) ?

point '(0,1)' ?| point '(0,0)'t

line ?-| lineboolean

lseg ?-| lsegboolean

Les lignes sont-elles perpendiculaires ?

lseg '[(0,0),(0,1)]' ?-| lseg '[(0,0),(1,0)]'t

line ?|| lineboolean

lseg ?|| lsegboolean

Les lignes sont-elles parallèles ?

lseg '[(-1,0),(1,0)]' ?|| lseg '[(-1,2),(1,2)]'t

geometric_type ~= geometric_typeboolean

Ces objets sont-ils les mêmes ? Disponible pour point, box, polygon, circle.

polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'t

[a] Faire une « Rotation » d'une boîte avec ces opérateurs déplace seulement ses coins : la boîte est toujours considérée avoir des côtés parallèles sur les axes. De ce fait, la taille de la boîte n'est pas préservée, bien qu'une vraie rotation le ferait.


Attention

Notez que l'opérateur « same as », ~=, représente la notion habituelle d'égalité pour les types point, box, polygon et circle. Certains types géométriques ont aussi un opérateur = mais = compare seulement des aires égales. Les autres opérateurs de comparaison scalaires (<= et ainsi de suite), si disponibles pour ces types, comparent aussi des aires.

Note

Avant PostgreSQL 8.2, les opérateurs de confinement @> et <@ étaient respectivement appelés ~ et @. Ces noms sont toujours disponibles mais sont obsolètes et finiront par être supprimés.

Tableau 9.36. Fonctions géométriques

Fonction

Description

Exemple(s)

area ( geometric_type ) → double precision

Calcule l'aire. Disponible pour box, path, circle. Une entrée path doit être terminée, sinon NULL est renvoyé. De plus, si path s'intersecte lui-même, le résultat pourrait ne pas avoir de signification.

area(box '(2,2),(0,0)')4

center ( geometric_type ) → point

Calcule le point central. Disponible pour box, lseg, polygon, circle.

center(box '(1,2),(0,0)')(0.5,1)

diagonal ( box ) → lseg

Extrait la diagonale de la boîte sous la forme d'un segment de ligne (identique à lseg(box)).

diagonal(box '(1,2),(0,0)')[(1,2),(0,0)]

diameter ( circle ) → double precision

Calcule le diamètre d'un cercle.

diameter(circle '<(0,0),2>')4

height ( box ) → double precision

Calcule la taille verticale d'une boîte.

height(box '(1,2),(0,0)')2

isclosed ( path ) → boolean

Le chemin est-il fermé ?

isclosed(path '((0,0),(1,1),(2,0))')t

isopen ( path ) → boolean

Le chemin est-il ouvert ?

isopen(path '[(0,0),(1,1),(2,0)]')t

length ( geometric_type ) → double precision

Calcule la longueur totale. Disponible pour lseg, path.

length(path '((-1,0),(1,0))')4

npoints ( geometric_type ) → integer

Renvoie le nombre de points. Disponible pour path, polygon.

npoints(path '[(0,0),(1,1),(2,0)]')3

pclose ( path ) → path

Convertit le chemin en un chemin fermé.

pclose(path '[(0,0),(1,1),(2,0)]')((0,0),(1,1),(2,0))

popen ( path ) → path

Convertit le chemin en un chemin ouvert.

popen(path '((0,0),(1,1),(2,0))')[(0,0),(1,1),(2,0)]

radius ( circle ) → double precision

Calcule le rayon du cercle.

radius(circle '<(0,0),2>')2

slope ( point, point ) → double precision

Calcule la pente d'une ligne tracée entre les deux points.

slope(point '(0,0)', point '(2,1)')0.5

width ( box ) → double precision

Calcule la taille horizontale d'une boîte.

width(box '(1,2),(0,0)')1


Tableau 9.37. Fonctions de conversion de type géométrique

Fonction

Description

Exemple(s)

box ( circle ) → box

Calcule la boîte inscrite dans un cercle.

box(circle '<(0,0),2>')(1.414213562373095,1.414213562373095),​(-1.414213562373095,-1.414213562373095)

box ( point ) → box

Convertit le point en boîte vide.

box(point '(1,0)')(1,0),(1,0)

box ( point, point ) → box

Convertit deux points (utilisés comme coins) en une boîte.

box(point '(0,1)', point '(1,0)')(1,1),(0,0)

box ( polygon ) → box

Calcule la boîte englobante d'un polygone.

box(polygon '((0,0),(1,1),(2,0))')(2,1),(0,0)

bound_box ( box, box ) → box

Calcule la boîte englobante de deux boîtes.

bound_box(box '(1,1),(0,0)', box '(4,4),(3,3)')(4,4),(0,0)

circle ( box ) → circle

Calcule le plus petit cercle englobant une boîte.

circle(box '(1,1),(0,0)')<(0.5,0.5),0.7071067811865476>

circle ( point, double precision ) → circle

Calcule le cercle à partir de son centre et de son rayon.

circle(point '(0,0)', 2.0)<(0,0),2>

circle ( polygon ) → circle

Convertit un poligône en cercle. Le centre du cercle est la moyenne des positions des points du polygone, et le rayon est la distance moyenne des points du polygone à partir de ce centre.

circle(polygon '((0,0),(1,3),(2,0))')<(1,1),1.6094757082487299>

line ( point, point ) → line

Convertit deux points en une ligne qui les traverse.

line(point '(-1,0)', point '(1,0)'){0,-1,0}

lseg ( box ) → lseg

Extrait la diagonale de la boîte en un segment de ligne.

lseg(box '(1,0),(-1,0)')[(1,0),(-1,0)]

lseg ( point, point ) → lseg

Construit le segment de ligne à partir de deux points finaux.

lseg(point '(-1,0)', point '(1,0)')[(-1,0),(1,0)]

path ( polygon ) → path

Convertit un polygone en un chemin fermé avec la même liste de points.

path(polygon '((0,0),(1,1),(2,0))')((0,0),(1,1),(2,0))

point ( double precision, double precision ) → point

Calcule un point à partir de ses coordonnées.

point(23.4, -44.5)(23.4,-44.5)

point ( box ) → point

Calcule le centre d'une boîte.

point(box '(1,0),(-1,0)')(0,0)

point ( circle ) → point

Calcule le centre d'un cercle.

point(circle '<(0,0),2>')(0,0)

point ( lseg ) → point

Calcule le centre d'un segment de ligne.

point(lseg '[(-1,0),(1,0)]')(0,0)

point ( polygon ) → point

Calcule le centre d'un polygone (la moyenne des positions des points du polygone).

point(polygon '((0,0),(1,1),(2,0))')(1,0.3333333333333333)

polygon ( box ) → polygon

Convertit une boîte en un polygone à 4 points.

polygon(box '(1,1),(0,0)')((0,0),(0,1),(1,1),(1,0))

polygon ( circle ) → polygon

Convertit un cercle en un polygone à 12 points.

polygon(circle '<(0,0),2>')((-2,0),​(-1.7320508075688774,0.9999999999999999),​(-1.0000000000000002,1.7320508075688772),​(-1.2246063538223773e-16,2),​(0.9999999999999996,1.7320508075688774),​(1.732050807568877,1.0000000000000007),​(2,2.4492127076447545e-16),​(1.7320508075688776,-0.9999999999999994),​(1.0000000000000009,-1.7320508075688767),​(3.673819061467132e-16,-2),​(-0.9999999999999987,-1.732050807568878),​(-1.7320508075688767,-1.0000000000000009))

polygon ( integer, circle ) → polygon

Convertit un cercle en un polygone à n points.

polygon(4, circle '<(3,0),1>')((2,0),​(3,1),​(4,1.2246063538223773e-16),​(3,-1))

polygon ( path ) → polygon

Convertit un chemin fermé en un polygone avec la même liste de points.

polygon(path '((0,0),(1,1),(2,0))')((0,0),(1,1),(2,0))


Il est possible d'accéder aux deux nombres composants d'un point comme si le point était un tableau avec les index 0 et 1. Par exemple, si t.p est une colonne point, alors SELECT p[0] FROM t récupère la coordonnée X et UPDATE t SET p[1] = ... modifie la coordonnée Y. De la même façon, une valeur de type box ou lseg peut être traitée comme un tableau de deux valeurs point.