2 votos

Calcular el ángulo de visión de los puntos a un polígono

Esta pregunta Calcular el campo de visión/ángulo de un punto a un shapefile intentaba conseguir un resultado similar a mi necesidad (calcular el ángulo de visión entre las ubicaciones de los observadores y un polígono). La imagen de la pregunta se muestra a continuación para facilitar, con el ángulo de interés es alfa:

Angle between observer point and a polygon

Mi solución es utilizar una capa virtual para calcular el rumbo entre cada punto de vista y cada uno de los nodos de la capa de polígonos y luego utilizar expresiones agregadas para darme la información que necesito.

Actualmente tengo el siguiente código pero al probarlo arroja un error de sintaxis (1 - cerca de ".": error de sintaxis) que no puedo solucionar (puede haber otros errores y no estoy convencido de que sea el código más óptimo pero me gustaría utilizar una capa virtual).

SELECT 
  vp_union.*,
  minimum(vp_union.bearing) AS bearing_min,
  median(vp_union.bearing) AS bearing_med,
  maximum(vp_union.bearing) AS bearing_max,
  range(vp_union.bearing) AS bearing_range,
  distance(
    vp_union.geometry,
    closest_point(
      st_union(redline_outer.geometry),
      vp_union.geometry
    ),
    vp_union.geometry
  ) AS distance
FROM
  (SELECT
    vp.*,
    degrees(
      azimuth(
        vp.geometry,
        redline_nodes.geometry
      )
    ) AS vp.bearing
  FROM
    "Viewpoint Layer 2D" AS vp
  UNION
    (SELECT
      nodes_to_points(
        st_union(redline.geometry)
      ) AS geometry
    FROM
      "Redline" AS redline
    ) AS redline_nodes
  ) AS vp_union,
  "Redline" AS redline_outer
GROUP BY
  vp_union.name

1voto

Josh Nankin Puntos 375

Así que estaba bien fuera de mi idea original. Al final me di cuenta de que hay un posible caso en el que un punto de vista podría estar dentro del casco convexo de los polígonos, así que volví a probar los vértices individuales. Es largo, enrevesado y un poco lento (seguro que alguien podría optimizarlo).

Soy consciente de que esto no te da del todo el alfa (pero hizo lo que yo necesitaba también) y es relativamente trivial calcular ese ángulo usando los puntos de inicio y final de la cadena de líneas para cada punto de vista.

WITH RECURSIVE
  -- generate table with all the points from the polygons layer
  polygons_points AS(
  SELECT
    1 AS fid,
    1 AS n,
    point_n(polygons.geometry,1) AS geometry
  FROM
    "Redline" AS polygons
  UNION ALL
  SELECT
    ogc_fid AS fid,
    n + 1 AS n,
    point_n(polygons.geometry,n+1)
  FROM
    "Redline" AS polygons
  INNER JOIN
    polygons_points ON polygons.ogc_fid = polygons_points.fid
  WHERE
    n < ST_NPoints(polygons.geometry)
  ),

  -- generate table with spokes from polygons_points to the points layer
  spokes AS(
  SELECT
    points.VP AS pid,
    polygons_points.fid,
    polygons_points.n,
    MakeLine(points.geometry,polygons_points.geometry) AS geometry
  FROM
    "Viewpoint Locations 2D" AS points
  CROSS JOIN
    polygons_points
  ),
  -- select sightlines from spokes that do not cross the original polygons
  sightlines AS(
  SELECT spokes.*
  FROM
    spokes
  INNER JOIN
    "Redline" AS polygons
  ON
    polygons.ogc_fid = spokes.fid
  AND
    ST_Crosses(spokes.geometry,polygons.geometry) <> 1
  ),
  -- select and join the polygon segments that intersect with the sightlines
  polygons_segments AS(
  SELECT
    sightlines.pid,
    sightlines.fid,
    sightlines.n,
    ST_AsText(sightlines.geometry) AS point_txt,
    ST_Union(ST_GeometryN(ST_DissolveSegments(ST_ExteriorRing(polygons.geometry)),n)) AS geometry
  FROM
    sightlines
  INNER JOIN
    "Redline" AS polygons
  ON
    polygons.ogc_fid = sightlines.fid
  AND
    ST_Intersects(sightlines.geometry, polygons.geometry)
  GROUP BY
    sightlines.pid
  )

SELECT * FROM polygons_segments

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X