Podría lograr esto de diferentes maneras dependiendo del tipo de salida que desee, pero el concepto es el mismo. En general, es más fácil hacer una rotación simple seguida de una traducción en lugar de tratar de calcular las coordenadas en un solo paso.
En este caso, los pasos básicos son:
- Cree una línea de la longitud deseada en el origen (0,0). Esta línea debe correr a lo largo del eje desde el que desea medir su ángulo y tener su centro en el origen.
- Gire la línea alrededor del origen.
- Traslade la línea por las coordenadas del punto en el que desea que se centre.
La siguiente vista de PostGIS crea las líneas de su escenario de ejemplo. Se suponen algunas cosas:
- La columna de geometría se llama
shape
- El ángulo se mide desde el eje x. Su dibujo de ejemplo fue un poco confuso ya que mencionó por primera vez 40 grados, dibujó una línea vertical punteada, pero luego dijo que debería estar alrededor de 160 grados. He interpretado que significa que realmente quieres medir desde el eje x.
Los datos se proyectan en las mismas unidades con las que desea medir (es decir, metros).
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
Para desglosar lo que realmente está sucediendo con esa última línea, comenzando desde el interior:
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)
y ST_MakePoint(-1.0,0.0)
: Cree los puntos finales para una línea horizontal que sea nuestra longitud deseada y centrada en el origen.
ST_MakeLine(...)
: Use nuestros puntos finales recién creados para crear una línea.
ST_Rotate(..., radians(40))
: Gire esa nueva línea alrededor del origen.
ST_Translate(..., ST_X(vertex), ST_Y(vertex))
: Centre la línea girada en nuestro punto de referencia (entrada).
ST_SetSRID(..., ST_SRID(vertex))
: Asigne a la nueva línea el mismo SRID que la geometría de entrada.
Si está utilizando PostGIS 2.0, puede simplificar esto ya que puede especificar un origen diferente para ST_Rotate
. Si desea rotar a un ángulo basado en la pendiente de la línea, primero deberá calcularlo y agregarlo al ángulo de rotación.
Si los datos no se proyectan en las mismas unidades que desea medir, aún puede hacer algo similar, pero necesitará un paso adicional:
- Cree una línea (proyectada en algo que use lo que desea medir)
- Girar
- Reproyectar a su proyección objetivo
- Traducir al punto objetivo
Editar
Ahora entiendo lo que quieres decir con el ángulo. Esencialmente, desea una rotación en el sentido de las agujas del reloj desde el eje Y (0 es hacia arriba, 90 es hacia la derecha, 180 es hacia abajo, etc.).
Todavía necesita usar la radians
función ya que ST_Rotate
espera el ángulo en radianes. Debería poder obtener el ángulo correcto con dos pequeños cambios:
- Comience con una línea vertical (use
ST_MakePoint(0.0,1.0)
y ST_MakePoint(0.0,-1.0)
)
- Multiplica tu ángulo por -1. Esto lo hará negativo, causando
ST_rotate
que gire en sentido horario.radians(<angle> * -1)