Vous pouvez accomplir cela de différentes manières selon le type de sortie que vous recherchez, mais le concept est le même. Il est généralement plus facile de faire une simple rotation suivie d'une translation plutôt que d'essayer de calculer les coordonnées en une seule étape.
Dans ce cas, les étapes de base sont les suivantes:
- Créez une ligne de la longueur souhaitée à l'origine (0,0). Cette ligne doit courir le long de l'axe à partir duquel vous souhaitez mesurer votre angle et avoir son centre à l'origine.
- Faites pivoter la ligne autour de l'origine.
- Traduisez la ligne par les coordonnées du point sur lequel vous souhaitez qu'elle soit centrée.
La vue PostGIS suivante crée les lignes à partir de votre exemple de scénario. Quelques hypothèses sont supposées:
- La colonne de géométrie est appelée
shape
- L'angle est mesuré à partir de l'axe x. Votre exemple de dessin était un peu déroutant puisque vous avez mentionné pour la première fois 40 degrés, dessiné une ligne verticale en pointillés, mais que vous aviez ensuite dit qu'il devrait être d'environ 160 degrés. J'ai interprété cela comme signifiant que vous voulez réellement mesurer à partir de l'axe des x.
Les données sont projetées dans les mêmes unités avec lesquelles vous souhaitez mesurer (c.-à-d. Des mètres).
CREATE OR REPLACE VIEW <viewname> AS
WITH vertices AS
(SELECT
objectid,
(ST_DumpPoints(shape)).path[1] AS v_id,
(ST_DumpPoints(shape)).geom AS vertex
FROM <source_data>
)
SELECT
objectid,
v_id,
ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 1.0,0.0),
ST_MakePoint(-1.0,0.0)),
radians(40)), ST_X(vertex), ST_Y(Vertex)),
ST_SRID(vertex)) AS newline
FROM vertices
Pour décomposer ce qui se passe réellement avec cette dernière ligne, en commençant par le plus intérieur:
ST_SetSRID(ST_Translate(ST_Rotate(ST_MakeLine(ST_MakePoint( 0,1.0),
ST_MakePoint(0,-1.0)),
radians(40)), ST_X(vertex), ST_Y(Vertex)),
ST_SRID(vertex)) AS newline
ST_MakePoint(1.0,0.0)
et ST_MakePoint(-1.0,0.0)
: Créez les points d'extrémité pour une ligne horizontale qui est notre longueur souhaitée et centrée sur l'origine.
ST_MakeLine(...)
: Utilisez nos points de terminaison nouvellement créés pour créer une ligne.
ST_Rotate(..., radians(40))
: Faites pivoter cette nouvelle ligne autour de l'origine.
ST_Translate(..., ST_X(vertex), ST_Y(vertex))
: Centrez la ligne pivotée sur notre point de référence (entrée).
ST_SetSRID(..., ST_SRID(vertex))
: Donnez à la nouvelle ligne le même SRID que la géométrie en entrée.
Si vous utilisez PostGIS 2.0, vous pouvez simplifier cela car vous pouvez spécifier une origine différente pour ST_Rotate
. Si vous souhaitez faire pivoter selon un angle basé sur la pente de la ligne, vous devrez d'abord le calculer et l'ajouter à l'angle de rotation.
Si les données ne sont pas projetées dans les mêmes unités que celles que vous souhaitez mesurer, vous pouvez toujours faire quelque chose de similaire, mais vous aurez besoin d'une étape supplémentaire:
- Créez une ligne (projetée dans quelque chose qui utilise ce que vous voulez mesurer)
- Tourner
- Reprojetez à votre projection cible
- Traduire au point cible
Éditer
Je comprends maintenant ce que vous entendez par l'angle. Essentiellement, vous voulez une rotation dans le sens horaire à partir de l'axe Y (0 est haut, 90 est droit, 180 est bas, etc.).
Vous devez toujours utiliser la radians
fonction, car ST_Rotate
attendez l'angle en radians. Vous devriez pouvoir obtenir l'angle correct avec deux petits changements:
- Commencez par une ligne verticale (utilisez
ST_MakePoint(0.0,1.0)
et ST_MakePoint(0.0,-1.0)
)
- Multipliez votre angle par -1. Cela le rendra négatif, provoquant
ST_rotate
sa rotation dans le sens horaire.radians(<angle> * -1)