[GRASS-dev] [GRASS GIS] #3926: allow limit viewshed computation by angle

#3926: allow limit viewshed computation by angle
----------------------------------+-------------------------
Reporter: annakrat | Owner: grass-dev@…
     Type: enhancement | Status: new
Priority: normal | Milestone: 8.0.0
Component: Raster | Version: unspecified
Keywords: r.viewshed, viewshed | CPU: All
Platform: All |
----------------------------------+-------------------------
r.viewshed should allow to restrict the computation to range of angles,
e.g. to simulate human field of view.

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/3926&gt;
GRASS GIS <https://grass.osgeo.org>

#3926: allow limit viewshed computation by angle
--------------------------+----------------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: enhancement | Status: new
  Priority: normal | Milestone: 8.0.0
Component: Raster | Version: unspecified
Resolution: | Keywords: r.viewshed, viewshed
       CPU: All | Platform: All
--------------------------+----------------------------------

Comment (by annakrat):

For the record, this is my attempt with hardcoded values, which fails with
angle 1 to 270 (the viewshed is written but incorrect). Interestingly, it
works with angle 0 to 270.

{{{
index 95ecd47..94d0741 100644
--- a/raster/r.viewshed/eventlist.cpp
+++ b/raster/r.viewshed/eventlist.cpp
@@ -605,7 +605,20 @@ int is_point_outside_max_dist(Viewpoint vp,
GridHeader hd,
      return 0;
  }

+int is_point_inside_angle(Viewpoint vp,
+ dimensionType row, dimensionType col,
+ float minAngle, float maxAngle)
+{
+ double ang;
+
+ ang = atan2(vp.row -row, col - vp.col) * 180 / M_PI;
+ if (ang < 0)
+ ang += 360;
+ if (ang < minAngle || ang > maxAngle)
+ return 0;

+ return 1;
+}

  /* ------------------------------------------------------------
     //note: this is expensive because distance is not stored in the event
diff --git a/raster/r.viewshed/eventlist.h b/raster/r.viewshed/eventlist.h
index e071687..234e700 100644
--- a/raster/r.viewshed/eventlist.h
+++ b/raster/r.viewshed/eventlist.h
@@ -74,7 +74,9 @@ is_point_outside_max_dist(Viewpoint vp, GridHeader hd,
                           dimensionType row, dimensionType col,
                           float maxDist);

-
+int is_point_inside_angle(Viewpoint vp,
+ dimensionType row, dimensionType col,
+ float minAngle, float maxAngle);

  /*sort the event list by the angle around the viewpoint) */
  void sort_event_list(AMI_STREAM < AEvent > **eventList);
diff --git a/raster/r.viewshed/grass.cpp b/raster/r.viewshed/grass.cpp
index b9dac21..d5fa240 100644
--- a/raster/r.viewshed/grass.cpp
+++ b/raster/r.viewshed/grass.cpp
@@ -316,6 +316,11 @@ init_event_list_in_memory(AEvent * eventList, char
*rastName,
                 (*vp, *hd, i, j, viewOptions.maxDist))
                 continue;

+ if (!is_point_inside_angle(*vp, i, j, 1, 270)) {
+ add_result_to_inmem_visibilitygrid(visgrid, i, j,
+ hd->nodata_value);
+ continue;
+ }
             /* if it got here it is not the viewpoint, not NODATA, and
                within max distance from viewpoint; generate its 3 events
                and insert them */
}}}

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/3926#comment:1&gt;
GRASS GIS <https://grass.osgeo.org>

#3926: allow limit viewshed computation by angle
--------------------------+----------------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: enhancement | Status: new
  Priority: normal | Milestone: 8.0.0
Component: Raster | Version: unspecified
Resolution: | Keywords: r.viewshed, viewshed
       CPU: All | Platform: All
--------------------------+----------------------------------

Comment (by mmetz):

Replying to [comment:1 annakrat]:
> For the record, this is my attempt with hardcoded values, which fails
with angle 1 to 270 (the viewshed is written but incorrect).
Interestingly, it works with angle 0 to 270.

Your PR [https://github.com/OSGeo/grass/pull/180 #180] works for me. I
tested in the NC dataset with

{{{
g.region -p rast=elev_state_500m
r.viewshed in=elev_state_500m out=viewshed
coord=637942.9512846764,188095.68718268772 obs=100 direction_range=0,270
r.viewshed in=elev_state_500m out=viewshed
coord=637942.9512846764,188095.68718268772 obs=100 direction_range=1,270
r.viewshed in=elev_state_500m out=viewshed
coord=637942.9512846764,188095.68718268772 obs=100 direction_range=270,0
r.viewshed in=elev_state_500m out=viewshed
coord=637942.9512846764,188095.68718268772 obs=100 direction_range=270,1
}}}

and the results seem to be correct.

Can you provide an example where your PR does not work?

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/3926#comment:2&gt;
GRASS GIS <https://grass.osgeo.org>

#3926: allow limit viewshed computation by angle
--------------------------+----------------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: enhancement | Status: new
  Priority: normal | Milestone: 8.0.0
Component: Raster | Version: unspecified
Resolution: | Keywords: r.viewshed, viewshed
       CPU: All | Platform: All
--------------------------+----------------------------------

Comment (by annakrat):

Pushed to master (https://github.com/OSGeo/grass/pull/180).

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/3926#comment:3&gt;
GRASS GIS <https://grass.osgeo.org>

#3926: allow limit viewshed computation by angle
--------------------------+----------------------------------
  Reporter: annakrat | Owner: grass-dev@…
      Type: enhancement | Status: closed
  Priority: normal | Milestone: 8.0.0
Component: Raster | Version: unspecified
Resolution: fixed | Keywords: r.viewshed, viewshed
       CPU: All | Platform: All
--------------------------+----------------------------------
Changes (by annakrat):

* status: new => closed
* resolution: => fixed

--
Ticket URL: <https://trac.osgeo.org/grass/ticket/3926#comment:4&gt;
GRASS GIS <https://grass.osgeo.org>