I actually worked on that and I used QGIS, GRASS and geotools + opencarto java library to achieve my goal. I can give you the main steps :
- From academic literature, it seems the smallest MBR is the best method to find the building main orientation (important to know to calculate the solar panel yield). First of all you will need to compute the main orientation of each building. The opencarto library has a method for that (that's why I came to java and geotools to do it)
- Rasterize your data to calculate slope and aspect (needed to compute solar radiation). To get shadows with accuracy you should merge MNT with your building raster layer. Choose the buffer radius to work on. This step is usefull if you work in mountain area for example since they are obstacles to solar radiation.
- I found two ways for getting annual solar radiation. The first one use r.sun GRASS module and the process is quite long since you have to calculate solar radiation for the sunny season (see code below - got it from GRASS wiki I guess) This first method get the annual solar radiation value. The second is shorter and less accurate, using gdaldem hillshade at equinoxes and solstices at the right time. This principle is to exclude parts of buildings that are too shaddy and apply a unique radiation value for all buildings (there is scientific website to get this information).
Of course there is some more steps to get a solar potential value, but this is the more complicated spatial part. If I can give you another advice, before starting any project, just read a little bit on solar panel technology. You will see that many hypotheses could be altered.
I can already say that the method has some limits :
- not taking in account vegetation shadow
- do not consider roof slope
- building main orientation is not perfect
But I think, at a territory/regional scale, the method is not bad, especially for rural areas.
The method is probably perfectible, (I'd like to have roof slopes for example to get a better accuracy of solar panel yield, but spatial data I have do not provide that) so if you have any ideas to do so, I will be pleased to read about it.
Hope it helps!
Grass sun script using r.sun module :
#!/bin/sh
echo "Enter elevation map :"
read elev
g.copy rast=$elev,SOLelev
echo "Enter slope map:"
read sl
g.copy rast=$sl,SOLslope
echo "Enter aspect map :"
read asp
g.copy rast=$asp,SOLaspect
i=75
lastday=288
# we fit to the raster input region
g.region rast=SOLelev
#generate an empty map for global radiation:
r.mapcalc "global.rad=0"
while [ $i -le $lastday ]
do
# generate map names convenient for xganim and r.out.mpeg:
DAY=`echo $i | awk '{printf "%03i", $1}'`
echo "Computing radiation for day $DAY..."
r.sun -s elevin=SOLelev aspin=SOLaspect slopein=SOLslope\
day="$i"\
beam_rad=b_rad.$DAY diff_rad=d_rad.$DAY\
refl_rad=r_rad.$DAY
#add to (cell-wise) global energy:
r.mapcalc "global.rad=global.rad + b_rad.$DAY +\
d_rad.$DAY + r_rad.$DAY"
r.timestamp b_rad.$DAY date="$i days"
r.colors b_rad.$DAY col=gyr
r.timestamp d_rad.$DAY date="$i days"
r.colors d_rad.$DAY col=gyr
r.timestamp r_rad.$DAY date="$i days"
r.colors r_rad.$DAY col=gyr
i=`expr $i + 1`
done
#cleanup:
g.remove rast=SOLelev,SOLaspect,SOLslope
g.mremove -f rast="b_rad*"
g.mremove -f rast="d_rad*"
g.mremove -f rast="r_rad*"
echo "Finished."