Opened 5 years ago
Closed 5 years ago
#3926 closed enhancement (fixed)
allow limit viewshed computation by angle
| Reported by: | annakrat | Owned by: | |
|---|---|---|---|
| Priority: | normal | Milestone: | 8.0.0 |
| Component: | Raster | Version: | unspecified |
| Keywords: | r.viewshed, viewshed | Cc: | |
| CPU: | All | Platform: | All |
Description
r.viewshed should allow to restrict the computation to range of angles, e.g. to simulate human field of view.
Change History (4)
follow-up: 2 comment:1 by , 5 years ago
comment:2 by , 5 years ago
Replying to 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 #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?
comment:4 by , 5 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Note:
See TracTickets
for help on using tickets.

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 */