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.
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:
- Read floor-aware settings for a map.
- Iterate features in the floor-aware data model.
- Filter features by floor.
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 isnull
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 IFloorAware
interface. Layers that support floor-awareness, such as FeatureLayer
, implement this interface.
IFloorAware
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 Map
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 ILoadable
and must be loaded before sites, facilities, and levels are available.
// Get all sites, facilities, and levels
IReadOnlyList<FloorSite> allSites = floorManager.Sites;
IReadOnlyList<FloorFacility> allFacilities = floorManager.Facilities;
IReadOnlyList<FloorLevel> allLevels = floorManager.Levels;
// Get all facilities for a particular site.
FloorSite mainCampus = floorManager.Sites.FirstOrDefault(s => s.SiteId == "ESRI.RED.MAIN");
IReadOnlyList<FloorFacility> mainCampusBuildings = mainCampus.Facilities;
// Get all levels for a particular facility.
FloorFacility buildingQ = floorManager.Facilities.FirstOrDefault(f => f.FacilityId == "ESRI.RED.MAIN.Q");
IReadOnlyList<FloorLevel> buildingQLevels = buildingQ.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 .NET 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.
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.
Example: Display a single level for all facilities:
- Make sure the map is loaded.
FloorManager
is alwaysnull
until the map loads.
- Get the map's
FloorManager
.- If the map is not floor-aware, the
FloorManager
will benull
.
- If the map is not floor-aware, the
- Load the
FloorManager
to read the floor-aware data. - Get the
FloorLevel
collection from the map'sFloorManager
.- This returns all levels for all facilities in the map.
- Iterate all
FloorLevel
objects in the collection.- Set the chosen level as visible.
- Set all other levels as not visible.
// Get all levels from FloorManager.
IReadOnlyList<FloorLevel> allLevels = floorManager.Levels;
// Iterate all levels in the collection.
foreach (FloorLevel lvl in allLevels)
{
// Set levels with the selected vertical order visible.
lvl.IsVisible = lvl.VerticalOrder == selectedVerticalPosition;
}
Example: Display a single level in a chosen facility:
- Make sure the map is loaded.
FloorManager
is alwaysnull
until the map loads.
- Get the map's
FloorManager
.- If the map is not floor-aware, the
FloorManager
will benull
.
- If the map is not floor-aware, the
- Load the
FloorManager
to read the floor-aware data. - Get the chosen site, represented by a
FloorSite
object. - Get the chosen facility from the collection of facilities for the site, represented by a
FloorFacility
object. - Set the map view's viewpoint using the facility's geometry.
- Get the
FloorLevel
collection for the facility (exposed as a property onFloorFacility
). - Iterate all
FloorLevel
objects in the collection.- Set the chosen level as visible.
- Set all other levels as not visible.
// Get the chosen site from the FloorManager (using its unique site ID).
FloorSite selectedSite = floorManager.Sites.FirstOrDefault(s => s.SiteId == selectedSiteId);
// Get the chosen facility within the selected site (using its unique facility ID).
FloorFacility building = selectedSite.Facilities.FirstOrDefault(f => f.FacilityId == selectedFacilityId);
if (building == null) { return; }
// Set the viewpoint to center on this facility (to better see the levels).
var facilityViewpoint = new Viewpoint(building.Geometry);
MainMapView.SetViewpoint(facilityViewpoint);
// Get all levels for this facility.
IReadOnlyList<FloorLevel> facilityLevels = building.Levels;
// Iterate all levels in the collection.
foreach (FloorLevel lvl in facilityLevels)
{
// Set levels with the selected level number visible.
lvl.IsVisible = lvl.LevelNumber == selectedLevelNum;
}