← Back to portfolioShowaib Bin Nasir
Smart City / Renewable Energy / GIS / Digital Twin / Geospatial AnalyticsCase study

City-Scale 3D Solar Digital Twin for Rooftop Solar Potential Analysis

A 3D city-scale solar analysis platform that combines building footprints, LiDAR elevation data, roof geometry, automated solar-panel placement, and interactive 3D visualization to estimate rooftop solar potential and future electricity generation across an entire city. The prototype is currently being developed using London as the initial test environment.

Next.jsReactTypeScriptCesiumJSPostgreSQLPostGISPythonOpenStreetMapGeofabriEnvironment AgencyLiDARDSMDTMRasterioNumPyShapelySciPypsycopgosm2pgsql3D TilesGISLiDARpvlibPVGISSolar EnergyGeospatial Analysis
City-Scale 3D Solar Digital Twin for Rooftop Solar Potential Analysis

Building a City-Scale Solar Digital Twin

The idea behind this project started with a simple question:

How much electricity could an entire city generate if its usable rooftops were covered with solar panels?

Answering that accurately is much harder than simply measuring the size of a roof.

A real solar-potential system needs to understand the height of every building, the actual geometry of each roof, which direction the roof faces, how steep it is, how much of it is usable, how many solar panels can physically fit, and eventually how much sunlight reaches those panels throughout the day.

That is what this project is designed to solve.

The goal is to create a 3D solar digital twin of a city, where every building can be selected and analysed individually while also contributing to larger neighbourhood, district, and city-wide energy calculations.

The first prototype is being developed using London.

Starting with the 3D City

The frontend of the application is built with Next.js, React, TypeScript, and CesiumJS.

Cesium provides the interactive 3D environment where users can move around the city, zoom between neighbourhoods, rotate the camera, and select individual buildings.

At the beginning of development, Cesium's OpenStreetMap 3D Buildings layer was used to create the visual city environment.

However, an important architectural decision was made very early:

The visual 3D building should not be treated as the analytical building.

Cesium is responsible for visualization, while the scientific calculations are based on dedicated geographic datasets stored in our own database.

This separation allows the system to maintain accurate analytical information without depending on the visual representation of the building.

Building a Local Geographic Database

The first analytical dataset comes from OpenStreetMap.

Instead of sending an external API request every time a user selects a building, the Greater London OpenStreetMap dataset is downloaded through Geofabrik and imported into a local PostgreSQL database using osm2pgsql.

The database uses the PostGIS extension, giving PostgreSQL the ability to perform geographic and spatial calculations.

Each building can therefore contain information such as:

  • OpenStreetMap ID

  • building footprint

  • building name

  • building type

  • number of floors

  • address information

  • geographic coordinates

  • footprint area

When a user clicks a building in Cesium, the application obtains the clicked longitude and latitude and sends them to a Next.js API route.

PostGIS then performs a spatial lookup to determine which real building footprint corresponds to the selected 3D building.

The matched footprint is displayed on the map and its information appears in the application dashboard.

This means the system is no longer dependent on public services such as the Overpass API for everyday building queries.

Moving Beyond Estimated Building Heights

OpenStreetMap sometimes contains a building height, but for many buildings that information is missing.

Some buildings contain only the number of floors.

A basic approximation could be made using something such as:

number of floors × 3 metres

but that is not accurate enough for a serious solar and shadow simulation platform.

To solve this, the project uses LiDAR elevation data.

Two different raster datasets are used.

The Digital Terrain Model, or DTM, represents the ground surface.

The Digital Surface Model, or DSM, represents the top surface of the environment and therefore includes buildings, vegetation, and other objects.

By comparing the elevation values from these two datasets, the system can calculate the measured height of a building.

For example:

Roof elevation − Ground elevation = Building height

This makes it possible to replace rough floor-based estimates with measurements derived from real geospatial survey data.

The project currently uses Environment Agency LiDAR data stored in British National Grid coordinates.

Python scripts built with Rasterio, NumPy, Shapely, and psycopg process each building footprint and store the resulting measurements back into PostGIS.

For each analysed building, the database can now contain values such as:

  • ground elevation

  • typical roof elevation

  • 95th-percentile roof elevation

  • LiDAR-derived building height

  • height source

A fallback system remains available so that buildings without LiDAR information can still use OpenStreetMap height or floor-based estimates.

Understanding the Roof

Knowing the height of the building is only part of the problem.

For solar analysis, the roof itself needs to be understood.

The DSM is therefore processed again to calculate the elevation gradient across each rooftop.

From this information, the system calculates:

  • roof slope

  • roof direction

  • flat-roof percentage

  • roof surface area

  • dominant roof orientation

Roof direction is represented using an azimuth value.

For example:

  • 0° represents North

  • 90° represents East

  • 180° represents South

  • 270° represents West

This is important because two roofs with the same area can have very different solar-generation potential depending on their direction and slope.

Splitting Buildings into Individual Roof Planes

Real buildings rarely have one simple roof surface.

A building might contain a south-facing pitched section, a north-facing section, a flat central roof, and several smaller structures.

Because of this, the system does not simply calculate one average roof direction for the entire building.

Instead, the DSM pixels are grouped according to their slope, orientation, and spatial connectivity.

This creates separate roof planes.

Each roof plane is stored independently in PostGIS and contains information such as:

  • roof-plane geometry

  • slope

  • azimuth

  • horizontal area

  • actual surface area

  • whether the roof section is flat

A single building can therefore contain several roof planes with completely different solar characteristics.

This is a major step toward accurate panel placement.

Calculating Solar-Usable Roof Area

Not every square metre of rooftop can contain a solar panel.

The platform therefore applies several constraints before calculating available solar area.

Roof sections that are too small can be rejected.

Safety and maintenance setbacks are added around roof boundaries.

Different packing assumptions are used for pitched roofs and flat roofs.

Flat roofs require additional spacing because solar panels are normally tilted and rows can cast shadows onto each other.

The system then calculates the usable roof surface area for every suitable roof plane.

At this stage, it can already estimate how many solar panels could fit on the roof and calculate the approximate installed peak capacity.

Moving from Estimated Capacity to Real Panel Placement

Area-based capacity estimates are useful, but they are still estimates.

The project therefore goes one step further by generating actual solar-panel polygons.

A generic modern solar module is currently used during development, with approximate dimensions of:

1.134 m × 1.722 m

and a power rating of:

430 W

The placement algorithm attempts to fit individual panel rectangles inside each usable roof plane while respecting:

  • roof boundaries

  • setbacks

  • panel dimensions

  • panel orientation

  • panel spacing

  • roof tilt

  • roof azimuth

  • flat-roof row spacing

Every successfully placed panel becomes its own geographic object stored in PostGIS.

Each virtual panel contains information such as:

  • panel ID

  • building ID

  • roof-plane ID

  • panel geometry

  • panel dimensions

  • power rating

  • tilt

  • azimuth

This means the system can move beyond saying:

“This building could support approximately 100 panels.”

Instead, it can say:

“These are the exact 87 panel positions that fit within the analysed roof geometry.”

The installed solar capacity can then be calculated directly from the number of successfully placed modules.

Visualizing Solar Panels in the 3D City

The placed panel geometries are exposed through the Next.js backend and loaded into Cesium.

When a user selects a processed building, the application can retrieve the corresponding panel layout from PostGIS and draw those panels over the 3D building.

This provides a direct visual connection between the analytical model and the city map.

The user can therefore select a building and inspect:

  • building information

  • footprint area

  • measured building height

  • ground elevation

  • roof elevation

  • roof planes

  • usable solar area

  • number of placed panels

  • installed solar capacity

The user interface also contains independent loading states so that geographic information and panel information can load without blocking the rest of the map.

The Next Major Stage: The Sun

The next stage of the project introduces the most dynamic part of the digital twin: the Sun.

The application will calculate the real solar position using:

  • geographic location

  • date

  • time

  • timezone

The Sun will have a real azimuth and elevation based on its actual position in the sky.

The same Sun position can then be represented visually in Cesium.

Users will eventually be able to move a time slider and watch the Sun travel across the city.

As the Sun moves, shadows from surrounding buildings, roof structures, terrain, and eventually vegetation will also change.

From Visual Shadows to Analytical Shadows

The visual shadow shown by the 3D engine is useful for the user experience, but it should not be treated as the scientific result.

The analytical system will independently determine whether sunlight reaches each roof plane or solar panel.

This can be done by tracing the direction between a panel and the Sun and checking whether another object blocks that path.

This creates a shading factor that can change throughout the day.

For example, one panel may receive full direct sunlight at midday while another panel on the same building may be partially shaded by a neighbouring tower.

Tree shading can also be included once vegetation geometry is added to the model.

Calculating Actual Solar Electricity Generation

Sunlight intensity is different from Sun position.

The Sun may be visible, but cloud cover and atmospheric conditions can dramatically change how much energy reaches the solar panel.

The final energy model will therefore combine the geometric Sun model with irradiance data.

Solar-weather datasets such as PVGIS can provide information including:

  • global horizontal irradiance

  • direct normal irradiance

  • diffuse irradiance

  • temperature

  • historical solar conditions

The project will eventually use a solar modelling library such as pvlib to calculate the amount of solar radiation reaching each panel.

Electricity generation can then account for:

  • panel surface area

  • panel efficiency

  • tilt

  • azimuth

  • solar irradiance

  • shading

  • temperature

  • inverter losses

  • cable losses

  • other system losses

From One Building to an Entire City

One of the main objectives of this project is scalability.

The smallest analytical unit is an individual solar panel.

Those values can then be aggregated upward.

For example:

Panel → Roof Plane → Building → Street → Neighbourhood → District → City

The final dashboard could therefore display information such as:

  • number of analysed buildings

  • total available rooftop area

  • solar-usable rooftop area

  • total number of possible panels

  • installed peak capacity

  • current generation

  • today's generated energy

  • monthly generation

  • annual generation

  • generation by neighbourhood

  • generation by individual building

The 3D city can also be colour-coded to create a solar heatmap.

Buildings with excellent solar potential could appear differently from heavily shaded or unsuitable buildings.

Building the Digital Twin Efficiently

An important part of the architecture is deciding which calculations happen in real time and which calculations happen beforehand.

Heavy operations such as:

  • LiDAR processing

  • building-height calculations

  • roof segmentation

  • panel placement

  • annual shadow analysis

should not be repeated every time a user opens the application.

Instead, these operations are performed as offline batch-processing jobs.

The calculated information is saved into PostGIS.

The web application then retrieves those prepared results very quickly.

This makes it possible to eventually analyse hundreds of thousands of buildings while still providing a responsive interactive 3D experience.

Current Progress

The current prototype already supports the core geospatial pipeline.

A 3D London environment is running in Cesium.

Buildings can be selected interactively.

The selected visual building can be matched to its real OpenStreetMap footprint.

Greater London building data is stored locally in PostGIS.

LiDAR DSM and DTM data can be processed to calculate measured building heights.

Roof slope, orientation, area, and flat-roof characteristics can be extracted.

Buildings can be split into individual analytical roof planes.

Suitable solar roof area can be calculated.

Solar panels can be automatically positioned and stored as individual geographic polygons.

The panel geometry can then be returned to the frontend for visualization in the 3D city.

The current workflow is being validated on a smaller set of London buildings before the processing system is expanded across the full city.

Long-Term Goal

The long-term goal is to create a complete city-scale solar digital twin capable of answering questions such as:

How much rooftop solar capacity exists in this city?

Which buildings have the highest solar potential?

How many solar panels could realistically be installed?

How much electricity could those panels generate today?

How does generation change throughout the year?

How much generation is lost because of building or tree shadows?

What is the total current solar output of an entire neighbourhood or city?

By combining GIS, LiDAR, 3D visualization, solar modelling, and spatial databases, the platform is designed to turn an entire city into an interactive renewable-energy simulation.