Esto se puede lograr de diferentes maneras, dependiendo del tipo de resultado que se desee, pero el concepto es el mismo. Por lo general, es más fácil hacer una simple rotación seguida de una traslación que intentar calcular las coordenadas en un solo paso.
En este caso, los pasos básicos son:
- Crea 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.
- Rota la línea alrededor del origen.
- Traslada la línea por las coordenadas del punto en el que quieres que esté centrada.
La siguiente vista de PostGIS crea las líneas de su escenario de ejemplo. Se asumen algunas cosas:
- La columna de geometría se llama
shape
- El ángulo se mide desde el eje x. Tu dibujo de ejemplo era un poco confuso ya que primero mencionaste 40 grados, dibujaste una línea vertical punteada, pero luego dijiste que debería ser alrededor de 160 grados. He interpretado eso como que en realidad quieres medir desde el eje x.
-
Los datos se proyectan en las mismas unidades con las que se quiere 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 sucede con esa última línea, empezando por lo más interno: 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)
: Crea los puntos extremos de una línea horizontal que tenga la longitud deseada y esté centrada en el origen.
ST_MakeLine(...)
: Utiliza nuestros puntos finales recién creados para crear una línea.
ST_Rotate(..., radians(40))
: Rota esa nueva línea alrededor del origen.
ST_Translate(..., ST_X(vertex), ST_Y(vertex))
: Centra la línea rotada en nuestro punto de referencia (de entrada).
ST_SetSRID(..., ST_SRID(vertex))
: Dar 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 quieres rotar a un ángulo basado en la pendiente de la línea, tendrás que calcularlo primero y añadirlo al ángulo de rotación.
Si los datos no se proyectan en las mismas unidades en las que quieres medir, puedes hacer algo similar, pero necesitarás un paso adicional:
- Cree una línea (proyectada en algo que utilice lo que quiere medir)
- Girar
- Reproyectar a su proyección de destino
- Trasladar al punto de destino
Editar
Ahora entiendo lo que quieres decir con lo del ángulo. Esencialmente, quieres una rotación en el sentido de las agujas del reloj desde el eje Y (0 es arriba, 90 es derecha, 180 es abajo, etc.).
Todavía tiene que utilizar el radians
función desde ST_Rotate
espera el ángulo en radianes. Deberías ser capaz de obtener el ángulo correcto con dos pequeños cambios:
- Comience con una línea vertical (utilice
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
para girarlo en el sentido de las agujas del reloj. radians(<angle> * -1)