overture-schema-theme-buildings 0.1.1.dev0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ Metadata-Version: 2.4
2
+ Name: overture-schema-theme-buildings
3
+ Version: 0.1.1.dev0
4
+ Summary: Overture Maps buildings theme shared structures, building types, and building part types
5
+ License-Expression: MIT
6
+ Requires-Dist: overture-schema-common>=0.1.1
7
+ Requires-Dist: overture-schema-system>=0.1.1
8
+ Requires-Dist: pydantic>=2.13.0
9
+ Maintainer: Overture Maps Schema Working Group
10
+ Requires-Python: >=3.10
11
+ Project-URL: Homepage, https://overturemaps.org
12
+ Project-URL: Source, https://github.com/OvertureMaps/schema
13
+ Project-URL: Issues, https://github.com/OvertureMaps/schema/issues
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Overture Schema Buildings Theme
17
+
18
+ Shared structures and validation logic for Overture Maps buildings theme.
19
+ Contains common building types, classes, and shared validation patterns.
@@ -0,0 +1,4 @@
1
+ # Overture Schema Buildings Theme
2
+
3
+ Shared structures and validation logic for Overture Maps buildings theme.
4
+ Contains common building types, classes, and shared validation patterns.
@@ -0,0 +1,83 @@
1
+ [project]
2
+ dependencies = [
3
+ "overture-schema-common>=0.1.1",
4
+ "overture-schema-system>=0.1.1",
5
+ "pydantic>=2.13.0",
6
+ ]
7
+ description = "Overture Maps buildings theme shared structures, building types, and building part types"
8
+ version = "0.1.1.dev0"
9
+ license = "MIT"
10
+ name = "overture-schema-theme-buildings"
11
+ readme = "README.md"
12
+ requires-python = ">=3.10"
13
+
14
+ [[project.maintainers]]
15
+ name = "Overture Maps Schema Working Group"
16
+
17
+ [project.urls]
18
+ Homepage = "https://overturemaps.org"
19
+ Source = "https://github.com/OvertureMaps/schema"
20
+ Issues = "https://github.com/OvertureMaps/schema/issues"
21
+
22
+ [project.entry-points."overture.models"]
23
+ building = "overture.schema.buildings:Building"
24
+ building_part = "overture.schema.buildings:BuildingPart"
25
+
26
+ [project.entry-points.pytest11]
27
+ overture_baselines = "overture.schema.system.testing.plugin"
28
+
29
+ [tool.uv.sources.overture-schema-common]
30
+ workspace = true
31
+
32
+ [tool.uv.sources.overture-schema-system]
33
+ workspace = true
34
+
35
+ [tool.uv.build-backend]
36
+ module-name = "overture.schema.buildings"
37
+
38
+ [build-system]
39
+ requires = ["uv_build>=0.11.32,<0.13"]
40
+ build-backend = "uv_build"
41
+
42
+ [[examples.Building]]
43
+ id = "148f35b1-7bc1-4180-9280-10d39b13883b"
44
+ geometry = "POLYGON ((-176.6435004 -43.9938042, -176.6435738 -43.9937107, -176.6437726 -43.9937913, -176.6436992 -43.9938849, -176.6435004 -43.9938042))"
45
+ version = 1
46
+ has_parts = false
47
+ is_underground = false
48
+ theme = "buildings"
49
+ type = "building"
50
+
51
+ [examples.Building.bbox]
52
+ xmin = -176.643798828125
53
+ xmax = -176.64349365234375
54
+ ymin = -43.9938850402832
55
+ ymax = -43.993709564208984
56
+
57
+ [[examples.Building.sources]]
58
+ property = ""
59
+ dataset = "OpenStreetMap"
60
+ record_id = "w519166507@1"
61
+ update_time = "2017-08-27T21:39:50.000Z"
62
+
63
+ [[examples.BuildingPart]]
64
+ id = "19412d64-51ac-3d6a-ac2f-8a8c8b91bb60"
65
+ geometry = "POLYGON ((-73.2462509 -39.8108937, -73.2462755 -39.8109047, -73.246291 -39.8109182, -73.2463022 -39.8109382, -73.2463039 -39.810959, -73.2462962 -39.81098, -73.2462796 -39.8109977, -73.2462674 -39.8110052, -73.2462281 -39.8110153, -73.2461998 -39.811013, -73.2461743 -39.8110034, -73.2461566 -39.8109898, -73.246144 -39.8109702, -73.2461418 -39.8109427, -73.2461511 -39.8109221, -73.2461669 -39.8109066, -73.2461908 -39.8108947, -73.2462184 -39.8108898, -73.2462509 -39.8108937))"
66
+ version = 0
67
+ level = 3
68
+ is_underground = false
69
+ building_id = "bd663bd4-1844-4d7d-a400-114de051cf49"
70
+ theme = "buildings"
71
+ type = "building_part"
72
+
73
+ [examples.BuildingPart.bbox]
74
+ xmin = -73.24630737304688
75
+ xmax = -73.24613952636719
76
+ ymin = -39.81101608276367
77
+ ymax = -39.81088638305664
78
+
79
+ [[examples.BuildingPart.sources]]
80
+ property = ""
81
+ dataset = "OpenStreetMap"
82
+ record_id = "w223076787@2"
83
+ update_time = "2014-10-31T22:55:36.000Z"
@@ -0,0 +1,82 @@
1
+ [project]
2
+ maintainers = [
3
+ {name = "Overture Maps Schema Working Group"},
4
+ ]
5
+ dependencies = [
6
+ "overture-schema-common>=0.1.1",
7
+ "overture-schema-system>=0.1.1",
8
+ "pydantic>=2.13.0",
9
+ ]
10
+ description = "Overture Maps buildings theme shared structures, building types, and building part types"
11
+ version = "0.1.1.dev0"
12
+ license = "MIT"
13
+ name = "overture-schema-theme-buildings"
14
+ readme = "README.md"
15
+ requires-python = ">=3.10"
16
+
17
+ [project.urls]
18
+ Homepage = "https://overturemaps.org"
19
+ Source = "https://github.com/OvertureMaps/schema"
20
+ Issues = "https://github.com/OvertureMaps/schema/issues"
21
+
22
+ [tool.uv.sources]
23
+ overture-schema-common = { workspace = true }
24
+ overture-schema-system = { workspace = true }
25
+
26
+
27
+ [build-system]
28
+ requires = ["uv_build>=0.11.32,<0.13"]
29
+ build-backend = "uv_build"
30
+
31
+ [tool.uv.build-backend]
32
+ module-name = "overture.schema.buildings"
33
+
34
+ [project.entry-points."overture.models"]
35
+ building = "overture.schema.buildings:Building"
36
+ building_part = "overture.schema.buildings:BuildingPart"
37
+
38
+ [project.entry-points.pytest11]
39
+ overture_baselines = "overture.schema.system.testing.plugin"
40
+
41
+ [[examples.Building]]
42
+ id = "148f35b1-7bc1-4180-9280-10d39b13883b"
43
+ geometry = "POLYGON ((-176.6435004 -43.9938042, -176.6435738 -43.9937107, -176.6437726 -43.9937913, -176.6436992 -43.9938849, -176.6435004 -43.9938042))"
44
+ version = 1
45
+ has_parts = false
46
+ is_underground = false
47
+ theme = "buildings"
48
+ type = "building"
49
+
50
+ [examples.Building.bbox]
51
+ xmin = -176.643798828125
52
+ xmax = -176.64349365234375
53
+ ymin = -43.9938850402832
54
+ ymax = -43.993709564208984
55
+
56
+ [[examples.Building.sources]]
57
+ property = ""
58
+ dataset = "OpenStreetMap"
59
+ record_id = "w519166507@1"
60
+ update_time = "2017-08-27T21:39:50.000Z"
61
+
62
+ [[examples.BuildingPart]]
63
+ id = "19412d64-51ac-3d6a-ac2f-8a8c8b91bb60"
64
+ geometry = "POLYGON ((-73.2462509 -39.8108937, -73.2462755 -39.8109047, -73.246291 -39.8109182, -73.2463022 -39.8109382, -73.2463039 -39.810959, -73.2462962 -39.81098, -73.2462796 -39.8109977, -73.2462674 -39.8110052, -73.2462281 -39.8110153, -73.2461998 -39.811013, -73.2461743 -39.8110034, -73.2461566 -39.8109898, -73.246144 -39.8109702, -73.2461418 -39.8109427, -73.2461511 -39.8109221, -73.2461669 -39.8109066, -73.2461908 -39.8108947, -73.2462184 -39.8108898, -73.2462509 -39.8108937))"
65
+ version = 0
66
+ level = 3
67
+ is_underground = false
68
+ building_id = "bd663bd4-1844-4d7d-a400-114de051cf49"
69
+ theme = "buildings"
70
+ type = "building_part"
71
+
72
+ [examples.BuildingPart.bbox]
73
+ xmin = -73.24630737304688
74
+ xmax = -73.24613952636719
75
+ ymin = -39.81101608276367
76
+ ymax = -39.81088638305664
77
+
78
+ [[examples.BuildingPart.sources]]
79
+ property = ""
80
+ dataset = "OpenStreetMap"
81
+ record_id = "w223076787@2"
82
+ update_time = "2014-10-31T22:55:36.000Z"
@@ -0,0 +1,29 @@
1
+ """Buildings theme.
2
+
3
+ Human-made building structures, including building footprints and building parts with
4
+ attributes like height, floors, and materials.
5
+ """
6
+
7
+ __path__ = __import__("pkgutil").extend_path(__path__, __name__)
8
+
9
+ from ._common import (
10
+ Appearance,
11
+ FacadeMaterial,
12
+ RoofMaterial,
13
+ RoofOrientation,
14
+ RoofShape,
15
+ )
16
+ from .building import Building, BuildingClass, BuildingSubtype
17
+ from .building_part import BuildingPart
18
+
19
+ __all__ = [
20
+ "Appearance",
21
+ "Building",
22
+ "BuildingClass",
23
+ "BuildingPart",
24
+ "BuildingSubtype",
25
+ "FacadeMaterial",
26
+ "RoofMaterial",
27
+ "RoofOrientation",
28
+ "RoofShape",
29
+ ]
@@ -0,0 +1,204 @@
1
+ import textwrap
2
+ from enum import Enum
3
+ from typing import Annotated
4
+
5
+ from pydantic import BaseModel, Field
6
+
7
+ from overture.schema.system.doc import DocumentedEnum
8
+ from overture.schema.system.numeric import float64, int32
9
+ from overture.schema.system.string import HexColor
10
+
11
+
12
+ class FacadeMaterial(str, Enum):
13
+ """The outer surface material of building facade."""
14
+
15
+ BRICK = "brick"
16
+ CEMENT_BLOCK = "cement_block"
17
+ CLAY = "clay"
18
+ CONCRETE = "concrete"
19
+ GLASS = "glass"
20
+ METAL = "metal"
21
+ PLASTER = "plaster"
22
+ PLASTIC = "plastic"
23
+ STONE = "stone"
24
+ TIMBER_FRAMING = "timber_framing"
25
+ WOOD = "wood"
26
+
27
+
28
+ class RoofMaterial(str, Enum):
29
+ """The outermost material of the roof."""
30
+
31
+ CONCRETE = "concrete"
32
+ COPPER = "copper"
33
+ ETERNIT = "eternit"
34
+ GLASS = "glass"
35
+ GRASS = "grass"
36
+ GRAVEL = "gravel"
37
+ METAL = "metal"
38
+ PLASTIC = "plastic"
39
+ ROOF_TILES = "roof_tiles"
40
+ SLATE = "slate"
41
+ SOLAR_PANELS = "solar_panels"
42
+ TAR_PAPER = "tar_paper"
43
+ THATCH = "thatch"
44
+ WOOD = "wood"
45
+
46
+
47
+ class RoofShape(str, Enum):
48
+ """The shape of the roof."""
49
+
50
+ DOME = "dome"
51
+ FLAT = "flat"
52
+ GABLED = "gabled"
53
+ GAMBREL = "gambrel"
54
+ HALF_HIPPED = "half_hipped"
55
+ HIPPED = "hipped"
56
+ MANSARD = "mansard"
57
+ ONION = "onion"
58
+ PYRAMIDAL = "pyramidal"
59
+ ROUND = "round"
60
+ SALTBOX = "saltbox"
61
+ SAWTOOTH = "sawtooth"
62
+ SKILLION = "skillion"
63
+ SPHERICAL = "spherical"
64
+
65
+
66
+ class RoofOrientation(str, DocumentedEnum):
67
+ """
68
+ Orientation of the roof shape relative to the footprint shape.
69
+
70
+ The members of this enumeration, `"across"` and `"along"`, are borrowed from the OpenStreetMap
71
+ `roof:orientation=*` tag and have the same meanings as they do in OSM.
72
+ """
73
+
74
+ ACROSS = (
75
+ "across",
76
+ "The roof ridge runs perpendicular to the longer of the two building edges, parallel to the shorter",
77
+ )
78
+ ALONG = (
79
+ "along",
80
+ "The roof ridge runs parallel to the longer of the two building edges",
81
+ )
82
+
83
+
84
+ class Appearance(BaseModel):
85
+ """Physical and visual properties of a building, including dimensions, materials, and colors."""
86
+
87
+ # Optional
88
+
89
+ height: Annotated[
90
+ float64 | None,
91
+ Field(
92
+ gt=0,
93
+ description=textwrap.dedent("""
94
+ Height of the building or part in meters.
95
+
96
+ This is the distance from the lowest point to the highest point.
97
+ """).strip(),
98
+ ),
99
+ ] = None
100
+ is_underground: Annotated[
101
+ bool | None,
102
+ Field(
103
+ description=textwrap.dedent("""
104
+ Whether the entire building or part is completely below ground.
105
+
106
+ The underground flag is useful for display purposes. Buildings and building parts
107
+ that are entirely below ground can be styled differently or omitted from the
108
+ rendered image.
109
+
110
+ This flag is conceptually different from the `level` field, which indicates
111
+ relative z-ordering and, notably, can be negative even if the building is entirely
112
+ above-ground.
113
+ """).strip(),
114
+ strict=True,
115
+ ),
116
+ ] = None
117
+ num_floors: Annotated[
118
+ int32 | None,
119
+ Field(
120
+ gt=0,
121
+ description="Number of above-ground floors of the building or part.",
122
+ ),
123
+ ] = None
124
+ num_floors_underground: Annotated[
125
+ int32 | None,
126
+ Field(
127
+ gt=0,
128
+ description="Number of below-ground floors of the building or part.",
129
+ ),
130
+ ] = None
131
+ min_height: Annotated[
132
+ float64 | None,
133
+ Field(
134
+ description=textwrap.dedent("""
135
+ Altitude above ground where the bottom of the building or building part starts.
136
+
137
+ If present, this value indicates that the lowest part of the building or building
138
+ part starts is above ground level.
139
+ """).strip(),
140
+ ),
141
+ ] = None
142
+ min_floor: Annotated[
143
+ int32 | None,
144
+ Field(
145
+ gt=0,
146
+ description=textwrap.dedent("""
147
+ Start floor of this building or part.
148
+
149
+ If present, this value indicates that the building or part is "floating" and its
150
+ bottom-most floor is above ground level, usually because it is part of a larger
151
+ building in which some parts do reach down to ground level. An example is a building
152
+ that has an entry road or driveway at ground level into an interior courtyard, where
153
+ part of the building bridges above the entry road. This property may sometimes be
154
+ populated when `min_height` is missing and in these cases can be used as a proxy for
155
+ `min_height`.
156
+ """).strip(),
157
+ ),
158
+ ] = None
159
+ facade_color: Annotated[
160
+ HexColor | None,
161
+ Field(
162
+ description="Facade color in `#rgb` or `#rrggbb` hex notation",
163
+ ),
164
+ ] = None
165
+ facade_material: Annotated[
166
+ FacadeMaterial | None,
167
+ Field(description="Outer surface material of the facade"),
168
+ ] = None
169
+ roof_material: Annotated[
170
+ RoofMaterial | None, Field(description="Outer surface material of the roof")
171
+ ] = None
172
+ roof_shape: Annotated[RoofShape | None, Field(description="Shape of the roof")] = (
173
+ None
174
+ )
175
+ roof_direction: Annotated[
176
+ float64 | None,
177
+ Field(
178
+ ge=0,
179
+ lt=360,
180
+ description="Bearing of the roof ridge line in degrees",
181
+ ),
182
+ ] = None
183
+ roof_orientation: Annotated[
184
+ RoofOrientation | None,
185
+ Field(
186
+ description="""Orientation of the roof shape relative to the footprint shape""",
187
+ ),
188
+ ] = None
189
+ roof_color: Annotated[
190
+ HexColor | None,
191
+ Field(
192
+ description="The roof color in `#rgb` or `#rrggbb` hex notation",
193
+ ),
194
+ ] = None
195
+ roof_height: Annotated[
196
+ float64 | None,
197
+ Field(
198
+ description=textwrap.dedent("""
199
+ Height of the roof in meters.
200
+
201
+ This is the distance from the base of the roof to its highest point.
202
+ """).strip(),
203
+ ),
204
+ ] = None
@@ -0,0 +1,202 @@
1
+ """
2
+ The `Building` feature type model and supporting types.
3
+ """
4
+
5
+ import textwrap
6
+ from enum import Enum
7
+ from typing import Annotated, Literal
8
+
9
+ from pydantic import ConfigDict, Field
10
+
11
+ from overture.schema.buildings._common import Appearance
12
+ from overture.schema.common import OvertureFeature
13
+ from overture.schema.common.level import Stacked
14
+ from overture.schema.common.names import Named
15
+ from overture.schema.system.geometric import (
16
+ Geometry,
17
+ GeometryType,
18
+ GeometryTypeConstraint,
19
+ )
20
+
21
+
22
+ class BuildingSubtype(str, Enum):
23
+ """
24
+ Broadest classification of the type and purpose of a building.
25
+
26
+ This broad classification can be refined by `BuildingClass`.
27
+ """
28
+
29
+ AGRICULTURAL = "agricultural"
30
+ CIVIC = "civic"
31
+ COMMERCIAL = "commercial"
32
+ EDUCATION = "education"
33
+ ENTERTAINMENT = "entertainment"
34
+ INDUSTRIAL = "industrial"
35
+ MEDICAL = "medical"
36
+ MILITARY = "military"
37
+ OUTBUILDING = "outbuilding"
38
+ RELIGIOUS = "religious"
39
+ RESIDENTIAL = "residential"
40
+ SERVICE = "service"
41
+ TRANSPORTATION = "transportation"
42
+
43
+
44
+ class BuildingClass(str, Enum):
45
+ """
46
+ Further classification of the type and purpose of a building.
47
+
48
+ The building class adds detail to the broad classification of `BuildingSubtype`.
49
+ """
50
+
51
+ AGRICULTURAL = "agricultural"
52
+ ALLOTMENT_HOUSE = "allotment_house"
53
+ APARTMENTS = "apartments"
54
+ BARN = "barn"
55
+ BEACH_HUT = "beach_hut"
56
+ BOATHOUSE = "boathouse"
57
+ BRIDGE_STRUCTURE = "bridge_structure"
58
+ BUNGALOW = "bungalow"
59
+ BUNKER = "bunker"
60
+ CABIN = "cabin"
61
+ CARPORT = "carport"
62
+ CATHEDRAL = "cathedral"
63
+ CHAPEL = "chapel"
64
+ CHURCH = "church"
65
+ CIVIC = "civic"
66
+ COLLEGE = "college"
67
+ COMMERCIAL = "commercial"
68
+ COWSHED = "cowshed"
69
+ DETACHED = "detached"
70
+ DIGESTER = "digester"
71
+ DORMITORY = "dormitory"
72
+ DWELLING_HOUSE = "dwelling_house"
73
+ FACTORY = "factory"
74
+ FARM = "farm"
75
+ FARM_AUXILIARY = "farm_auxiliary"
76
+ FIRE_STATION = "fire_station"
77
+ GARAGE = "garage"
78
+ GARAGES = "garages"
79
+ GER = "ger"
80
+ GLASSHOUSE = "glasshouse"
81
+ GOVERNMENT = "government"
82
+ GRANDSTAND = "grandstand"
83
+ GREENHOUSE = "greenhouse"
84
+ GUARDHOUSE = "guardhouse"
85
+ HANGAR = "hangar"
86
+ HOSPITAL = "hospital"
87
+ HOTEL = "hotel"
88
+ HOUSE = "house"
89
+ HOUSEBOAT = "houseboat"
90
+ HUT = "hut"
91
+ INDUSTRIAL = "industrial"
92
+ KINDERGARTEN = "kindergarten"
93
+ KIOSK = "kiosk"
94
+ LIBRARY = "library"
95
+ MANUFACTURE = "manufacture"
96
+ MILITARY = "military"
97
+ MONASTERY = "monastery"
98
+ MOSQUE = "mosque"
99
+ OFFICE = "office"
100
+ OUTBUILDING = "outbuilding"
101
+ PARKING = "parking"
102
+ PAVILION = "pavilion"
103
+ POST_OFFICE = "post_office"
104
+ PRESBYTERY = "presbytery"
105
+ PUBLIC = "public"
106
+ RELIGIOUS = "religious"
107
+ RESIDENTIAL = "residential"
108
+ RETAIL = "retail"
109
+ ROOF = "roof"
110
+ SCHOOL = "school"
111
+ SEMI = "semi"
112
+ SEMIDETACHED_HOUSE = "semidetached_house"
113
+ SERVICE = "service"
114
+ SHED = "shed"
115
+ SHELTER = "shelter"
116
+ SHRINE = "shrine"
117
+ SILO = "silo"
118
+ SLURRY_TANK = "slurry_tank"
119
+ SPORTS_CENTRE = "sports_centre"
120
+ SPORTS_HALL = "sports_hall"
121
+ STABLE = "stable"
122
+ STADIUM = "stadium"
123
+ STATIC_CARAVAN = "static_caravan"
124
+ STILT_HOUSE = "stilt_house"
125
+ STORAGE_TANK = "storage_tank"
126
+ STY = "sty"
127
+ SUPERMARKET = "supermarket"
128
+ SYNAGOGUE = "synagogue"
129
+ TEMPLE = "temple"
130
+ TERRACE = "terrace"
131
+ TOILETS = "toilets"
132
+ TRAIN_STATION = "train_station"
133
+ TRANSFORMER_TOWER = "transformer_tower"
134
+ TRANSPORTATION = "transportation"
135
+ TRULLO = "trullo"
136
+ UNIVERSITY = "university"
137
+ WAREHOUSE = "warehouse"
138
+ WAYSIDE_SHRINE = "wayside_shrine"
139
+
140
+
141
+ class Building(
142
+ OvertureFeature[Literal["buildings"], Literal["building"]],
143
+ Named,
144
+ Stacked,
145
+ Appearance,
146
+ ):
147
+ """
148
+ Buildings are man-made structures with roofs that exist permanently in one place.
149
+
150
+ A building's geometry represents the two-dimensional footprint of the building as viewed from
151
+ directly above, looking down. Fields such as `height` and `num_floors` allow the
152
+ three-dimensional shape to be approximated. Some buildings, identified by the `has_parts` field,
153
+ have associated `BuildingPart` features which can be used to generate a more representative 3D
154
+ model of the building.
155
+ """
156
+
157
+ model_config = ConfigDict(title="building")
158
+
159
+ # Overture Feature
160
+
161
+ geometry: Annotated[
162
+ Geometry,
163
+ GeometryTypeConstraint(GeometryType.POLYGON, GeometryType.MULTI_POLYGON),
164
+ Field(
165
+ description="""The building's footprint or roofprint (if traced from aerial/satellite imagery).""",
166
+ ),
167
+ ]
168
+
169
+ # Optional
170
+
171
+ subtype: Annotated[
172
+ BuildingSubtype | None,
173
+ Field(
174
+ description=textwrap.dedent("""
175
+ A broad classification of the current use and purpose of the building.
176
+
177
+ If the current use of the building no longer accords with the original built
178
+ purpose, the current use should be specified. For example, a building built as a
179
+ train station but later converted into a shopping mall would have the value
180
+ `"commercial"` rather than `"transportation"`.
181
+ """).strip()
182
+ ),
183
+ ] = None
184
+ class_: Annotated[
185
+ BuildingClass | None,
186
+ Field(
187
+ alias="class",
188
+ description=textwrap.dedent("""
189
+ A more specific classification of the current use and purpose of the building.
190
+
191
+ If the current use of the building no longer accords with the original built
192
+ purpose, the current use should be specified.
193
+ """).strip(),
194
+ ),
195
+ ] = None
196
+ has_parts: Annotated[
197
+ bool | None,
198
+ Field(
199
+ description="Whether the building has associated building part features",
200
+ strict=True,
201
+ ),
202
+ ] = None
@@ -0,0 +1,56 @@
1
+ """
2
+ The `BuildingPart` feature type model and supporting types.
3
+ """
4
+
5
+ from typing import Annotated, Literal
6
+
7
+ from pydantic import Field
8
+
9
+ from overture.schema.buildings._common import Appearance
10
+ from overture.schema.buildings.building import Building
11
+ from overture.schema.common import OvertureFeature
12
+ from overture.schema.common.level import Stacked
13
+ from overture.schema.common.names import Named
14
+ from overture.schema.system.geometric import (
15
+ Geometry,
16
+ GeometryType,
17
+ GeometryTypeConstraint,
18
+ )
19
+ from overture.schema.system.ref import Id, Reference, Relationship
20
+
21
+
22
+ class BuildingPart(
23
+ OvertureFeature[Literal["buildings"], Literal["building_part"]],
24
+ Named,
25
+ Stacked,
26
+ Appearance,
27
+ ):
28
+ """
29
+ Building parts represent parts of larger building features. They allow buildings to be modeled
30
+ in rich detail suitable for creating realistic 3D models.
31
+
32
+ Every building part is associated with a parent `Building` feature via the `building_id` field.
33
+ In addition, a building part has a footprint geometry and may include additional details such as
34
+ its height, the number of floors, and the color and material of its facade and roof.
35
+
36
+ Building parts can float or be stacked on top of each other. The `min_height`, `min_floor`,
37
+ `height`, and `num_floors`, fields can be used to arrange the parts correctly along the
38
+ vertical dimension.
39
+ """
40
+
41
+ # Core
42
+ geometry: Annotated[
43
+ Geometry,
44
+ GeometryTypeConstraint(GeometryType.POLYGON, GeometryType.MULTI_POLYGON),
45
+ Field(
46
+ description="The footprint or roofprint of the building part.",
47
+ ),
48
+ ]
49
+
50
+ # Required
51
+
52
+ building_id: Annotated[
53
+ Id,
54
+ Field(description="The building to which this part belongs"),
55
+ Reference(Relationship.COMPOSITION, Building, role="part_of"),
56
+ ]