Inspiration

SolarShift started with a simple question: what if an aerial photograph could help us understand where solar panels would work best?

Rooftops are everywhere, but their energy potential is difficult to see. A large roof may lose valuable sunlight to nearby buildings, while a smaller roof may receive better exposure throughout the day. I wanted to make those differences visible through an interactive tool that connects computer vision with solar physics.

What it does

SolarShift turns aerial photographs into an interactive solar-planning workspace. Users can upload an image or explore the included sample locations. An AI model identifies building boundaries, which become editable rooftop regions.

Moving the timeline shows how sunlight, shadows, and estimated power change throughout the day. Users can compare rooftops, correct detected boundaries, add shading obstacles, calibrate image scale, and adjust location, heights, and panel settings.

Each roof includes a daily generation curve and a clear-sky energy estimate. The complete analysis can be exported as JSON.

How I built it

I built the backend with Python and FastAPI. A pretrained RF-DETR building segmentation model runs through PyTorch and Hugging Face Transformers to produce building masks. OpenCV converts those masks into polygons, while Shapely handles geometry and shadow intersections.

For the solar calculations, pvlib computes the sun’s position and clear-sky irradiance using the selected location, date, and timezone. Buildings and manually reviewed vegetation regions are represented as extruded polygons.

The shadow length on a receiving roof depends on the height difference and solar elevation:

$$ L = \frac{\Delta h}{\tan(\alpha)} $$

Here, $\Delta h$ is the height difference between the shading object and the receiving roof, and $\alpha$ is the sun’s elevation.

Sample points across each rooftop estimate the shaded fraction. This reduces direct irradiance, which feeds the power calculation:

$$ P_{\mathrm{kW}} = C_{\mathrm{kWp}} \frac{G_{\mathrm{effective}}}{1000} \, PR $$

Daily energy is calculated by integrating power over time.

The frontend uses JavaScript, HTML, CSS, Canvas, and SVG. OpenAI Codex assisted with implementation, debugging, documentation, and verification.

Challenges I faced

The biggest challenge was connecting image pixels to meaningful physical estimates. Image scale affects roof area, building heights affect shadows, and timezone handling affects the sun’s position. I made these assumptions visible and editable so users can understand what drives the results.

Large images also required overlapping inference tiles, which can produce duplicate or incomplete detections. I added deduplication, coordinate mapping, and manual boundary correction.

Shadow geometry presented another challenge: concave buildings needed a polygon sweep that preserved their shape. Simpler geometry could incorrectly shade empty space between building sections.

Accomplishments

SolarShift combines real building segmentation, editable geometry, solar calculations, and interactive visualization in one working application.

Testing on two supplied aerial images produced 13 rooftop candidates in Davis and 38 in Sacramento. The project also passed 25 automated tests covering geometry, shading, nighttime behavior, daylight-saving changes, and input validation.

What I learned

I learned that useful estimates need visible assumptions. Showing users how scale, height, orientation, and shading influence a result makes the tool easier to understand and improve.

I also learned that interface design can explain physics: watching shadows move while generation changes makes the relationship between sunlight and energy tangible.

What’s next

I want to add better vegetation detection, georeferenced imagery, roof-slope estimation, feasible panel layouts, and weather-based production modeling.

The current version provides preliminary clear-sky scenarios. Future improvements would help it account for more of the conditions that affect real solar installations.

Share this project:

Updates

Submission history