Use floor-aware maps

The term floor-aware refers to maps and scenes with indoor features that can be queried for their level inside a facility. Apps and APIs that support floor-awareness provide tools to visualize and interact with floor-aware indoor data. Once created and saved using ArcGIS Pro, a floor-aware map or scene can be consumed inside your app. You can filter data displayed by feature layers, point scene layers, and 3D object scene layers based on floor levels.

Refer to the Floor-aware maps topic in the ArcGIS Pro documentation for details about creating floor-aware maps and scenes.

Filter display by floor

Some common use cases for working with floor-aware data include:

  • Filter the display to only show features on a specified level (floor) of a facility.
  • Evaluate the availability and distribution of critical assets for a facility, such as fire extinguishers or defibrillators.
  • Apply a floor filter based on an indoor positioning system (IPS) location.
  • Track assets, such as mobile devices, that may move between facilities and levels.

For more information see:

Floor-aware data model

The floor-aware data model is organized into a hierarchy of layers that describe relevant indoor features and their relationships. Features are associated with a specific level (floor, in other words). Levels are contained within a facility (such as a building), and facilities can belong to a site (for example, a shopping center, industrial complex, or college campus).

A floor-aware map must include, at a minimum, a layer representing facilities and a layer representing levels. These layers must include specific fields that identify the features and define their hierarchical relationships, such as which levels are contained by a given facility. Indoor features can then be assigned the appropriate level within a facility.

Read floor-aware metadata

Floor filtering requires floor-awareness settings defined for the map. When a floor-aware map is loaded the floor-aware metadata populates the following classes.

These classes describe which layers and fields are used to support floor-aware mapping. While you could use this information to build queries to explore floor-aware relationships (facilities within a site, levels within a facility, and so on), the API abstracts this detail allowing you to read floor-aware metadata and implement floor filtering.

  • GeoModelFloorDefinition: exposes classes that define the sites, facilities, and levels configured in the map's floor-aware settings. This is null for maps that are not floor-aware.

  • SiteLayerDefinition: defines the layer and field properties for the (optional) site layer. A site layer defines the boundaries of managed sites (such as college campuses) that each contain one or more facilities.

  • FacilityLayerDefinition: defines the layer and field properties for the facility layer, which describes the footprints of managed facilities containing one or more levels.

  • LevelLayerDefinition: defines the layer and field properties for the level layer, which describes the footprint of each occupiable floor within a facility.

Floor-aware layers

Layers that contain features associated with a specific level within a facility expose floor-aware settings through a FloorAware interface. Layers that support floor-awareness, such as FeatureLayer, implement this interface.

FloorAware defines a read-write floorDefinition property of type LayerFloorDefinition that contains the properties that allow a layer to be floor-aware (such as the level at which a feature exists). Changing this property on-the-fly updates the floor filtering behavior. Setting or clearing this property toggles the floor filter rendering for the layer.

Iterate the floor-aware data model

You can iterate the floor-aware data model for a ArcGISMap to find all available sites, facilities, and levels. You can also find all the facilities for a given site or all levels for a specific facility.

The FloorManager class exposes the sites, facilities, and levels of the floor-aware data model. You can get the FloorManager using the read-only floorManager property of a map. This property returns null for maps that are not floor-aware. FloorManager inherits from Loadable and must be loaded before sites, facilities, and levels are available.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Get all sites, facilities, and levels
val allSites = floorManager.sites
val allFacilities = floorManager.facilities
val allLevels = floorManager.levels

// Get all facilities for a particular site.
val mainCampus = floorManager.sites.first {
    it.id == "ESRI.RED.MAIN"
}
val mainCampusBuildings = mainCampus.facilities

// Get all levels for a particular facility.
val buildingL = floorManager.facilities.first {
    it.id == "ESRI.RED.MAIN.L"
}
val buildingLLevels = buildingL.levels

You can use the FloorManager to build a UI that allows your user to explore available sites, facilities, and levels in the map. For example, you can provide a tree view or set of list controls so the user can filter facilities by site, and then see all levels within a chosen facility.

Alternatively, the open source ArcGIS Maps SDK for Kotlin Toolkit provides a FloorFilter component. If you pass the FloorManager to this component, it presents a UI control that allows your user to filter the floor plan data displayed in your map or scene view.

Floor control in the ArcGIS Online Map Viewer

Filter features by floor

FloorManager exposes a collection of FloorLevel, which includes properties that describe the following aspects of a level.

  • Associated facility: the facility that contains this level.
  • Visibility: whether or not the level is currently visible in the map.
  • Level ID: a string that uniquely identifies the level (across all levels in all facilities).
  • Level number: the number assigned to this level. This can differ from the actual order of the level. Some facilities, for example, don't designate a 13th floor. Instead, this level may be given a level number of 14.
  • Long name: a descriptive name of the level. A good convention for creating a clear description of the level is to use the facility name and level number for the long name.
  • Short name: a more succinct version of the long name. This is useful for showing a compact name in a UI element, such as a drop down list.
  • Vertical order: the actual position of the level in the collection of levels, sorted from low to high. The level order is zero-based. The ground floor is level 0, levels below it are negative, floors above positive.
  • Shape: a polygon geometry that describes the level.

Levels can be shown or hidden to filter the display for a specified level or levels in the map, either for a specific facility, multiple facilities, or across all facilities. The display of all floor-aware features is filtered according to the visibility of their associated level.

To display a single level for all facilities:

  1. Make sure the map is loaded.
  2. Get the map's FloorManager.
    • If the map is not floor-aware, the FloorManager will be null.
  3. Load the FloorManager to read the floor-aware data.
  4. Get the FloorLevel collection from the map's FloorManager.
    • This returns all levels for all facilities in the map.
  5. Iterate all FloorLevel objects in the collection.
    • Set the chosen level as visible.
    • Set all other levels as not visible.
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Get all levels from FloorManager.
val allLevels = floorManager.levels

// Choose the vertical order you're interested in
// Vertical order 0 is the ground floor, < 0 is floors below the ground, > 0 is above ground
val selectedVerticalPosition = 1

// Iterate all levels in the collection.
allLevels.forEach { level ->
    // Set to visible any level with the selected vertical order.
    level.isVisible = (level.verticalOrder == selectedVerticalPosition)
}

To display a single level in a chosen facility:

  1. Make sure the map is loaded.
  2. Get the map's FloorManager.
    • If the map is not floor-aware, the FloorManager will be null.
  3. Load the FloorManager to read the floor-aware data.
  4. Get the chosen site, represented by a FloorSite object.
  5. Get the chosen facility from the collection of facilities for the site, represented by a FloorFacility object.
  6. Set the map view's viewpoint using the facility's geometry.
  7. Get the FloorLevel collection for the facility (exposed as a property on FloorFacility).
  8. Iterate all FloorLevel objects in the collection.
    • Set the chosen level as visible.
    • Set all other levels as not visible.
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// Get the chosen site from the FloorManager (using its unique site ID).
val selectedSiteId = "ESRI.RED.MAIN"
val selectedFacilityId = "ESRI.RED.MAIN.L"

val selectedSite = floorManager.sites.first { it.id == selectedSiteId }

// Get the chosen facility within the selected site (using its unique facility ID).
val building = selectedSite.facilities.first { it.id == selectedFacilityId }

// Set the viewpoint to center on this facility (to better see the levels).
val extent = building.geometry?.extent
extent?.let { theExtent ->
    mapViewProxy.setViewpoint(Viewpoint(theExtent))
}

// Get all levels for this facility.
val facilityLevels = building.levels

// Specify the level number you are interested in.
val selectedLevelNumber = 3

// Iterate all levels in the collection.
facilityLevels.forEach { level ->
    // Set to visible any level that has the specified level number
    level.isVisible = (level.levelNumber == selectedLevelNumber)
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.