Working with 3DCityDB Series

This blog is part of a step-by-step 3DCityDB tutorial series for beginners working with CityGML, PostgreSQL, PostGIS, and 3D city digital twins.

In this blog, you will learn to create an Empty Spatial Database for CityGML. By the end of this part, you will:

Photo by Growtika on Unsplash

This is Part 3. Some readers will land directly here from Google. To give an overview, in the previous parts of this series, we explored what digital twins are, why they matter for modern cities, and how 3DCityDB fits into the larger ecosystem of CityGML-based urban digital twins. We also walked through the software requirements and preparation steps needed before working with real 3D city data.

Now it’s time to get our hands dirty.

In this part, we move from preparation to execution by setting up the core foundation of 3DCityDB: an empty spatial database built on PostgreSQL and PostGIS. This database is where every building geometry, surface, attribute, texture, and semantic relationship from CityGML will ultimately live.

If you think of a digital twin as a living system, then this database is its backbone. Without it, 3DCityDB cannot store, query, or manage 3D city models efficiently.

This blog will guide you step-by-step through:

No prior database expertise is required. Each action is explained in simple terms, with clear reasoning behind it, so you understand what’s happening under the hood—not just which buttons to click.

By the end of this tutorial, you’ll have a fully initialized 3DCityDB database, ready to accept CityGML datasets and power the next stages of your city-scale digital twin. No data yet, no visualizations yet—just a solid foundation that ensures everything you build next is stable, scalable, and standards-compliant.

Let’s begin by connecting to PostgreSQL and creating your first CityGML-ready spatial database that will hold your first 3D city.

Photo by Conny Schneider on Unsplash

1. Setting Up the Database Server Using pgAdmin 4

Photo by U. Storsberg on Unsplash

Now that PostgreSQL and PostGIS are installed (Working with 3DCityDB blog series, part 2), the next step is to create a database server connection that will later host our CityGML data. For this, we’ll use pgAdmin 4, the official graphical interface for managing PostgreSQL databases.

pgAdmin is a graphical interface that allows you to create databases, run SQL commands, and manage spatial extensions without touching the command line.

Launching pgAdmin 4

On Windows:

After a few seconds, pgAdmin will open in your default browser window.

Launching pgAdmin 4 (Windows)

You’ll notice a clean interface with a tree panel on the left. This panel represents database servers, databases, schemas, and extensions. Think of it as a file explorer, but for databases.

pgAdmin 4 Interface

Register a New Database Server

Since this is your first time using pgAdmin, you need to tell it where your PostgreSQL server lives.

On the home screen, under Quick Links, click on:

“Add New Server”

This opens the Register-Server dialog.

Add New Server, Register—Server settings

Fill in Server Details

General Tab

Here, you only need to provide a friendly name.

Connection Tab

This is where pgAdmin actually connects to PostgreSQL.

Fill in the following details:

⚠️ If you don’t remember the password, don’t worry, this is very common.
You can reset it using this guide:
👉 https://hassanannajjar.medium.com/how-to-fix-error-password-authentication-failed-for-the-user-in-postgresql-896e1fd880dc

Once all fields are filled, click Save.

Register — Server settings

After saving, you’ll see your newly registered server appear in the left panel.

Expand it, and you should see:

If you can expand the server without errors, 🎉 your PostgreSQL connection is working correctly.

Registered Server

You’re now ready to create a new database for 3DCityDB, but first, let’s understand some related terminologies.

Understanding Database Servers, Databases, Schemas, and Extensions

When you first open pgAdmin 4, the left panel shows a tree structure with several technical terms. If you’re new to databases, this can look intimidating—but the concepts are actually quite intuitive once you relate them to real life.

Let’s break them down one by one.

1. Database Server

Think of a database server as the building.

A database server is the running PostgreSQL service on your machine (or on another computer). It’s the engine that listens on a port (usually 5432) and handles all requests to store, retrieve, or update data.

In our setup:

📌 Example:
Your laptop is the building. PostgreSQL is the caretaker managing all rooms inside it.

2. Databases

Databases are individual rooms inside the building.

Inside one database server, you can create multiple databases, each completely separate from the others. Data in one database cannot be accessed from another unless explicitly linked.

For 3DCityDB:

📌 Example:

Each room has its own purpose.

3. Schemas

Schemas are organized cupboards inside a room.

A schema is a logical container that organizes tables, views, and functions inside a database. Instead of throwing everything into one place, schemas help keep things clean and structured.

In PostgreSQL:

📌 Example (very important for 3DCityDB):

This separation is one of the reasons 3DCityDB scales so well for large cities.

4. Extensions

Extensions are feature add-ons for the database.

By default, PostgreSQL understands tables and text, but it does not understand geography or 3D geometry. Extensions add these capabilities.

The most important extension for us is PostGIS.

PostGIS adds:

📌 Without PostGIS:
PostgreSQL sees a building as random numbers.

📌 With PostGIS:
PostgreSQL understands:

This is why PostGIS is mandatory for 3DCityDB.

Once all of these are in place, 3DCityDB can:

Now, since the database server is in place, let's create an empty database inside it.

Photo by Point3D Commercial Imaging Ltd. on Unsplash

2. Creating a Spatial Database for 3DCityDB in pgAdmin 4

With pgAdmin 4 connected to your PostgreSQL server, the next step is to create a dedicated database that will hold your 3D city model. This database will later be transformed into a full 3DCityDB instance.

Creating a New Database

Create new database in database server

A dialog window opens where you define the basic properties of the new database.

Enter the following:

Once done, click Save.

Create new database

You will now see BerlinDigitalTwin listed under the Databases section in the Object Explorer. At this stage, the database exists, but it is still a regular database without any spatial capabilities.

New database created
Photo by Curdin on Unsplash

3. Enabling Spatial Support with PostGIS

3DCityDB relies heavily on spatial data types and geometry operations. To support this, we need to enable PostGIS extensions inside the newly created empty database.

Make sure the BerlinDigitalTwin database is selected in the Object Explorer. Then click on the Query Tool icon in the top toolbar to open a new SQL editor window.

Open Query Tool
Empty Query Tool

Inside the query editor, type the following command:

CREATE EXTENSION IF NOT EXISTS postgis;
CREATE EXTENSION IF NOT EXISTS postgis_raster;
Execute SQL script

Click the Run button (▶) to execute the command.

If everything is configured correctly, PostgreSQL will install the PostGIS extensions inside this database. This may take a few seconds.

Add extensions

To confirm the installation:

You should now see PostGIS extensions listed in the extensions tree.

Postgis extensions added

While 3DCityDB primarily works with vector geometries, certain CityGML workflows and dependencies expect raster support to be available. Enabling postgis_raster upfront prevents downstream issues that are otherwise difficult to debug.

This database is now ready to be transformed into a 3DCityDB schema, which we’ll do next by applying the official 3DCityDB SQL scripts.

At this point, our database understands geometry — but it still doesn’t understand cities. That’s where the 3DCityDB schema comes in.

Photo by Raymond Petrik on Unsplash

4. Creating the 3DCityDB Database Schema

At this point, we have:

Now comes the most important step: transforming this empty database into a 3DCityDB-ready CityGML database.

We can proceed to install the actual 3DCityDB schema.

What Are the 3DCityDB SQL Scripts?

PostgreSQL on its own does not understand CityGML. It doesn’t know what a building is, how surfaces relate to geometry, or how semantic attributes should be stored. This is why 3DCityDB provides a set of official SQL and PL/pgSQL scripts.

PL/pgSQL stands for Procedural Language / PostgreSQL. It is PostgreSQL’s built-in programming language that lets you write logic, rules, and automation directly inside the database.

3DCityDB SQL Scripts:

Instead of manually creating tables, we simply run these scripts once, and the database becomes CityGML-aware.

Configuring Database Connection Details

To apply the 3DCityDB schema, we first need to tell the scripts how to connect to our database.

Navigate to the following folder on your system:

C:\RTG_Schulungskurs_2016\Importer-Exporter-Tool\3dcitydb\postgresql\ShellScripts\Windows

Inside this folder, locate the file named:

CONNECTION_DETAILS.bat

Open this file using a text editor such as Notepad++ or Notepad.

Editing CONNECTION_DETAILS.bat

Inside the file, you’ll see a section where database parameters are defined. Update the values so they match your local PostgreSQL setup.

Use the following configuration:

:: Provide your database details here -----------------------------------------
set PGBIN=C:\Program Files\PostgreSQL\18\pgAdmin 4\runtime
set PGHOST=127.0.0.1
set PGPORT=5432
set CITYDB=BerlinDigitalTwin
set PGUSER=postgres
::-----------------------------------------------------------------------------

A quick explanation of what these mean:

Once updated, save and close the file.

Creating the 3DCityDB Schema

Now comes the actual schema creation.

This step is where a regular spatial database officially becomes a CityGML-aware 3D city database.

In the same folder, double-click on:

CREATE_DB.bat
CREATE_DB.bat

A command-line window will open and guide you through a few configuration inputs.

Providing Spatial Reference Information

You will be prompted for several values. Enter them exactly as shown below.

Spatial Reference Identifier (SRID)
Enter:

25833

This corresponds to ETRS89 / UTM Zone 33N, commonly used for German datasets.

Height System EPSG Code
Simply press ENTER to accept the default.

SRSName (OGC-compliant CRS identifier)
Enter:

urn:ogc:def:crs,crs:EPSG:6.12:25833,crs:EPSG:6.12:5783

This defines both horizontal and vertical coordinate reference systems.

Enter valid SRID
Enter SRSName (OGC-compliant CRS identifier)

Entering the Database Password

When prompted for the PostgreSQL password, type the password you set during installation.

⚠️ Important note:
While typing, the cursor will not move, and no characters will appear on the screen. This is normal. Type the password carefully and press ENTER.

Schema Creation Complete

The script will now begin creating the 3DCityDB schema. This process usually takes about one minute.

Once finished, you’ll see a confirmation message in the command window indicating successful completion.

3DCityDB Schema Creation Complete

Press any key to close the window.

Go to pgAdmin 4 and refresh Schemas by right-clicking on it.

Refresh Schemas

Now you would be seeing the citydb schema created under Schemas.

citydb schema created under Schemas

What We’ve Achieved So Far

At this point, you have successfully:

Our database is no longer empty. It is now a fully functional 3D City Database, capable of storing buildings, geometries, textures, and semantic relationships at the city scale.

This hierarchy is important: CityGML does not live directly in PostgreSQL — it lives inside a structured 3DCityDB schema, which itself lives inside a spatial database.

Photo by Olesya Grichina on Unsplash

What’s Next?

You’ve now completed one of the most important milestones in the 3DCityDB workflow — setting up a fully functional 3D city database that’s ready to store real CityGML data.

By registering your database server, creating a spatial database, enabling PostGIS, and applying the official 3DCityDB schema, you’ve transformed an empty PostgreSQL instance into a CityGML-ready backend. This database will act as the semantic core of your digital twin, capable of storing buildings, surfaces, attributes, and relationships at the city scale.

While this setup step may feel technical, it’s a one-time effort that unlocks everything that follows — importing CityGML files, exporting 3D formats, running spatial queries, and visualizing your city in the browser.

At this stage, our system doesn’t yet show a city — but it fully understands how to store, query, and manage one.

In the next part of this series, we’ll finally bring data into the system by importing a real CityGML dataset and exploring how 3DCityDB organizes buildings, geometry, and semantics inside the database.

Follow along, and your digital twin will start taking shape.

If you’re following till here:

I’d love to hear how it went.

💬 Drop a comment below if:

Your questions help shape the next posts in this series.

See you in Part 4!

References

Have a question? Working on a digital twin?

👇 Drop a comment — I’d love to hear what you’re building.

Let’s learn and experiment together. 🚀🌍