Skip to content

Add --theme option to select 3DCityDB v5 textures by appearance theme - #259

Open
christianbraun wants to merge 6 commits into
Geodan:masterfrom
christianbraun:feat/theme-filter
Open

Add --theme option to select 3DCityDB v5 textures by appearance theme#259
christianbraun wants to merge 6 commits into
Geodan:masterfrom
christianbraun:feat/theme-filter

Conversation

@christianbraun

Copy link
Copy Markdown

What

Adds an optional --theme <name> flag to the 3DCityDB v5+ texture pipeline. When set, only textures belonging to that appearance theme are exported.

Why

3DCityDB v5 can hold many appearance themes over one shared geometry (e.g. an aerial photo theme plus per-period analysis themes), each theme being a set of appearance rows that reference surface_data via appear_to_surface_data.

Today the texture-enrichment query joins geometry_data -> surface_data_mapping -> surface_data -> tex_image with no appearance filter and ORDER BY g.id, sdm.surface_data_id, so a geometry with multiple mappings always renders the lowest surface_data_id and silently ignores every other theme. There is no way to ask for a specific theme.

This matters for use cases where one building geometry carries several textured "layers" (analysis results, thematic overlays) and you want to publish one tileset per theme from a single shared geometry, rather than duplicating geometry per theme.

How

  • New --theme option (Options.cs), default empty. Threaded through InputTable -> both tilers -> GetGeometrySubset -> EnrichWithTextures, mirroring the existing plumbing for IdColumn / Query.
  • When a theme is given, EnrichWithTextures adds an EXISTS semi-join on appear_to_surface_data + appearance filtering appearance.theme = @theme. A semi-join (not a plain JOIN) is used so a surface_data referenced by multiple appearances sharing the theme still yields exactly one row, never duplicate embedded textures.
  • The theme value is passed as an Npgsql parameter (@theme) - no string interpolation of user input.

Backwards compatibility

  • Empty theme (the default) reproduces the previous query verbatim - zero behaviour change for existing users.
  • All new method parameters are optional with safe defaults; existing call sites and unit tests compile unchanged.

Testing

Verified on a 3DCityDB v5.0 database (Luxembourg 3D open-data) where geometry_data id=1 carries two mappings: a photo texture (theme Aerial, lower surface_data_id) and a hand-authored analysis texture (theme test).

  • No --theme: exported glb embeds the photo JPEG (39066 B) - unchanged baseline.
  • --theme test: exported glb embeds the analysis PNG (393 B), a single texture, no duplication.

3DCityDB v5+ can hold many appearance themes per shared geometry. The
texture-enrichment query previously joined surface_data_mapping ->
surface_data -> tex_image with no appearance filter, so a geometry with
multiple mappings always rendered the lowest surface_data_id. Add an
optional --theme option that, when set, joins appear_to_surface_data +
appearance and filters on appearance.theme, letting one shared geometry
serve N themes via N runs (no geometry duplication). Empty theme keeps
the original behaviour.
A surface_data can be referenced by multiple appearance rows sharing the
same theme string; the previous fan-out JOIN then emitted N identical rows
per surface, and EnrichWithTextures adds each without dedup, embedding the
same image N times. Replace the appearance JOIN with an EXISTS semi-join so
each matching surface_data contributes exactly one row. Empty theme still
reproduces the original query verbatim.
@bertt

bertt commented Aug 7, 2026

Copy link
Copy Markdown
Member

Related issue: #252

Adds a 3DCityDB v5 appearance fixture (citydb.appearance /
citydb.appear_to_surface_data, column names taken from a real v5 database) and
a fourth geometry whose single surface is textured twice - red under theme
'summer', blue under 'winter'. Selecting 'winter' must return the blue texture,
which the unfiltered query would never pick (lower surface_data_id wins).

'summer' is carried by two appearances that both reference the same
surface_data, so the second test pins the EXISTS semi-join: one texture, not
one per appearance.

The fixture is a separate script and sits outside the bounding boxes the
existing texture tests query, so their expectations are untouched.
@bertt

bertt commented Aug 10, 2026

Copy link
Copy Markdown
Member

Hi, looks good this addition, can you add the new parameter to README.md and a description to dataprocessing/dataprocessing_citygml.md

@christianbraun

Copy link
Copy Markdown
Author

Hi, you're welcome. I made the additions.

--theme "  " fell through the string.Empty check and filtered on a theme no
appearance carries, silently dropping every texture. IsNullOrWhiteSpace makes
blank mean absent, which is what the option's default documents.

Also moves the test helpers to the top of the class and corrects a comment that
said the unfiltered query picks the lowest surface_data_id - it returns both
mappings, and the renderer takes the first per objectId.
A theme nobody wrote is not an error to the tiler: it bakes a complete,
valid tileset in which every tile is untextured, with the same exit code
and tile count, so a typo only surfaces in the viewer.

Probe citydb.appearance once, up front, and warn. Not per tile - with a
theme filter most tiles are legitimately untextured. Gated on the texture
pipeline, since citydb.appearance need not exist otherwise.
@bertt

bertt commented Aug 10, 2026

Copy link
Copy Markdown
Member

Do you have a link to a Luxemburg textured building CityGML dataset (with multiple appearances)?

@bertt

bertt commented Aug 10, 2026

Copy link
Copy Markdown
Member

Do you have a link to a Luxemburg textured building CityGML dataset (with multiple appearances)?

maybe https://data.public.lu/en/datasets/base-de-donnees-nationale-des-batiments-3d-2023/

update:  ACT2023v2_bati3d_Beaufort.gml only has 1 appearance texture

@christianbraun

Copy link
Copy Markdown
Author

maybe https://data.public.lu/en/datasets/base-de-donnees-nationale-des-batiments-3d-2023/

that's the base data I am working with. This has one appearance theme. I am about to calculate others. When I am ready to share I will provide a demo data set.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants