Skip to content

[FEATURE] Sibling-aware add_attributes in tile_post_process of Custommap (for Simple 3D Buildings / hide_3d) #1578

Description

@CommanderStorm

Is your feature request related to a problem? Please describe.

A custommap schema that emits both building and building:part polygons can't render Simple 3D Buildings correctly, because it can't express the core S3DB rule:

an outline covered by parts must not be extruded (OpenMapTiles' hide_3d flag).

Everything else (geom, height/min_height, a part marker) is trivial in YAML.
Only this one cross-feature spatial test forces a drop to the Java API.

tile_post_process currently contains merge_polygons/merge_line_strings, both of which transform features in isolation. There's no declarative way to relate a feature to the other features in its layer.

Describe the solution you'd like

A tile_post_process step that sets attributes on a feature based on spatial relationship to its siblings:

tile_post_process:
  merge_polygons:
    min_area: 2
  add_attributes:  # NEW
  - key: hide_3d
    value: true
    include_when: '${ siblings.exists(s, s.tags["is_part"] && area_overlap(feature, s) > 0.1) }'
    else: false

So, one PostProcess entry, that allows sibling-aware data-movement via the CEL-convences via both siblings and a area_overlap function.

Happy to work on this and open a PR if the surface looks right.

Describe alternatives you've considered

  • Per-feature ${…} function doesn't work, because processFeature is a streaming, single-feature pass with no view of other features.
    They're only grouped at tile assembly, so this has to be post-processing.
  • Java profile (subclass ConfiguredProfile, overriding postProcessLayerFeatures) works, but pushes a standard, reusable pattern out of config.

Additional context

Here is what I am envisioning:

- id: buildings
  features:
  - source: osm
    geometry: polygon
    include_when:
      building: __any__
      building:part: __any__
    attributes:
    - key: is_part
      value: true
      include_when: { building:part: __any__ }
      else: false
    - key: height      # derived from height / building:levels ...
    - key: min_height  # derived from min_height / building:min_level ...
  tile_post_process:
    merge_polygons:
      min_area: 2
    add_attributes: # NEW
    - key: hide_3d
      value: true
      include_when: '${ siblings.exists(s, s.tags["is_part"] && area_overlap(feature, s) > 0.1) }'
      else: false

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions