## 3 Methodological Developments and Application to the Greater Geneva Area
### Methodological Improvement on Shadow Casting Algorithms  
If we are looking only at the local data provided by the DUSM, the shadow casting algorithm works by starting from a given point (\(P_{0}\), i.e., a cell of the DUSM), and incrementally looking in the direction provided for another point \(P_{i}\) that is higher (\(H\)) than the ray \(R\) that is traced from the sun or light source in that direction. The presence of such a point indicates an obstruction, and its absence the lack thereof. This concept illustrated in Figure 4 is presented more in detail in ([PERSON], 2016). Listing 1 gives the pseudocode of this shadow casting algorithm. As for the integration of remote obstruction, the new architecture supports now two main features that were not provided by the previous work detailed in Section 2. Figure 4: Concept of shadow casting algorithm adapted from ([PERSON], 2016). In this example \(P_{0}\) is shaded by \(P_{1}\), where the relative height (\(H_{1}\)) is higher than the ray \(R\), but not by \(P_{2}\). The first one is a methodological change on how the distant terrain features were handled. Originally the calculation of the SVF and DI was done on both resolutions, then enlarging the low-resolution version (as explained in Section 2) and taking the minimum between the two. This does not give the correct result when local obstacles (for example buildings) defined on the DQSM are not situated in the same direction as remote relief features (for example mountains) defined on the DTM. In that case, cumulative shadowing effects from both relief and local obstacles should be considered on the SVF, instead of merely taking the minimum of both SVFs. Therefore, we integrate the multiresolution aspect in our main shadow casting loop by testing obstructions in both the resolutions in a given direction. The final result of that obstruction check will be the disjunction of both results (Listing 2 and Listing 3). The second one is, while testing for obstructions on the low-resolution model, we ignore obstructions that occur within the boundaries of the tile, since we have access to more detailed information within the tile (due to the DQSM). ```
is_obstructed_1(DQSM,point,direction_azimuth,direction_elevation) -> dx=cos(direction_azimuth) dy=-sin(direction_azimuth)//(0,0)istop-leftintheDQSM dz=tan(direction_elevation)*resolution(DQSM) current_point=point+[dx,dy] current_altitude=DQSM[point]+dz whilecurrent_pointisnotoutsideDQSMandcurrent_altitude<=max(DQSM) if(DQSM[round(current_point)]>current_altitude) returnTRUE current_point+=[dx,dy] current_altitude++dz returnFALSE
```  
**Box 2. ** In counterpart to Listing 1, this is the pseudocode of the shadow casting algorithm that determines distant obstructions due to terrain features, that are determined by the lower resolution DTM. ```
is_obstructed_2(DTM,DQSM,point,direction_azimuth,direction_elevation) -> dtm_point=theconversionof\"point\"fromDQSMtoDTMcoordinates dx=cos(direction_azimuth) dy=-sin(direction_azimuth)//(0,0)istop-leftintheDTM dz=tan(direction_elevation)*resolution(DTM) current_point=dtm_point+[dx,dy] current_altitude=DQSM[point]+dz whilecurrent_pointisnotoutsideDTMandcurrent_altitude<=max(DTM) if(DTM[current_point]>current_altitude andcurrent_pointisoutsidetheboundariesoftthetile) returnTRUE current_point+=[dx,dy] current_altitude++dz returnFALSE
```  
**Box 3. ** We take the disjunction between Listing 1 and Listing 2 to get the final determination of obstruction. ```
is_obstructed(DTM,DQSM,point,direction_azimuth,direction_elevation) -> returnis_obstructed_1(DQSM,point,direction_azimuth, direction_elevation)OR is_obstructed_2(DTM,DQSM,point,direction_azimuth, direction_elevation)
```  
In addition, the CUDA kernels have also been written with the notion of \"early termination\" in mind, in that, as an implementation optimization, we actually combine both loops into one, and in the case of an obstruction in either resolution, declare an obstruction immediately.