MVF Navigation Flags
1. Introduction
Navigation flags provide a mechanism to describe the properties of navigation paths within an MVF. They enable consumers of MVF data to make intelligent routing decisions based on the qualities of different paths. For example, an application might use flags to:
- Find routes that are wheelchair accessible
- Avoid outdoor areas when it's raining
- Only show paths that are open to the public
- Include VIP-only areas for authorized users
These flags can be applied to any wayfinding component in other extensions, including but not limited to Connections and Nodes
2. Types
2.1 Navigation Flags Declarations
At the root of the MVF will be a navigationFlagsDelcarations
property.
The NavigationFlagsDeclarations file contains a map of all navigation flag declarations for an MVF. For an MVF to be considered valid, all navigation flags used in any extensions MUST be declared in this file.
The key of the map is a unique, durable string identifier for the flag that developers use when interacting with the flag through an SDK. This will typically be something meaningful like accessible
or indoors
. The value will be a NavigationFlagDeclaration object that describes the flag (in particular, the index
and bit
values used to check for the flag in a flags
array).
2.2 Navigation Flag Declaration
A navigation flag declaration defines a single navigation property. Each declaration MUST include:
index
: The non-durable index of the flag the 32-bit integer in theflags
array, provided by theFlags
type.index
MUST be sequential, starting at 0, and increasing by 1 for every 32 flag definitions.bit
: The non-durable bit position (0-31) that will be set in theflags
integer at the index specified byindex
used by other extensions to indicate the presence of this flag.bit
MUST be sequential, starting at 0, and increasing by 1 for each new flag in the sameindex
.
The combination of index
and bit
MUST be unique across all navigation flag declarations in the same MVF.
A declaration MAY also include:
details
: A Details object that can provide additional information. This is usually a name, but may include other information such as description, images, and links. Like all details, it is targeted towards users, not developers.
2.3 Flags Type
This extension defines a reusable Flags type that can be incorporated into any other type to make it navigation flag aware:
type Flags = {
/**
* An array of 32-bit integers representing the navigation flags. Each bit on an integer corresponds to a flag
* in the NavigationFlagDeclarations, as determined by its index and bit position.
*/
flags: number[];
};
For convenience, this extension also defines a FlaggedGeometryAnchor type that combines the core GeometryAnchor
type with the Flags
type:
type FlaggedGeometryAnchor = GeometryAnchor & Flags;
There are also the WithFlags, WithFlaggedGeometryAnchor, and WithFlaggedGeometryAnchors types that can be added to objects by other extensions to make them navigation flag aware.
2.4 Using Navigation Flags
Extensions that support navigation flags SHOULD either include the Flags
type in their own types, or use the FlaggedGeometryAnchor
type for their anchors, which include the flags
property. flags
is an array of 32-bit integers, where each bit of each integer corresponds to a specific navigation flag. The presence of a flag is indicated by setting the corresponding bit to 1.
For example, if the NavigationFlagsDeclarations file contains:
{
"accessible": {
"index": 0,
"bit": 0
},
"public": {
"index": 0,
"bit": 1
},
"indoors": {
"index": 0,
"bit": 2
}
}
Then a flags
value of [6]
can be broken down as follows:
accessible
flag (index 0, bit 0): 2^0 = 1 (not set)public
flag (index 0, bit 1): 2^1 = 2indoors
flag (index 0, bit 2): 2^2 = 4
The total value is 0 + 2 + 4 = 6, indicating that both indoors
and public
flags are enabled, while accessible
is disabled.
When a consumer of MVF data wants to find a path with specific flags, they can check that each component along the path has the required flags set or not, and use it to change the weight or block that part of the path entirely.
3. Well Known Flags
Certain flags have well known meanings and should be used where possible in preference of custom flags. Applications SHOULD provide first class wayfinding support for Well Known Flags. They MAY provide support for custom flags.
A given MVF DOES NOT need to include all well known flags, only the ones it is using.
For well known flags, only the key
(and meaning) is durable. The index
and bit
values are not guaranteed to be the same across different MVFs. Consumers of MVFs MUST NOT crash if a Well Known Flag is not present in the NavigationFlagsDeclarations.
/**
* All well known navigation flags.
*/
export const WELL_KNOWN_FLAGS = {
accessible: 'accessible',
outdoors: 'outdoors'
} as const;
3.1 Accessible
The accessible
flag indicates that a navigation component is designed to be accessible to people using mobility aids such as wheelchairs. This includes appropriate width for doorways, paths taking ramps instead of stairs, and elevators instead of escalators.
3.2 Outdoors
The outdoors
flag indicates that a navigation component is or goes outside.
4. File Structure
The navigation flags extension adds a single file to the MVF bundle:
map-bundle/
└── navigationFlags.json
The navigationFlags.json file contains an array of NavigationFlagDeclaration objects.
5. Implementation Guidelines
5.1 Checking for Flags
To check if a specific flag is set on a WithFlags object, use the hasFlag function.
It performs the appropriate bitwise AND and looks something like this:
// Assuming flagKey is the key of the flag to check,
// flagBit is its bit position from NavigationFlagsDeclarations,
// and entityFlags is the flags value from an entity
function hasFlag(entityFlags: number[], flagIndex: number, flagBit: number): boolean {
return (entityFlags[flagIndex] & (1 << flagBit)) !== 0;
}
5.2 Setting Flags
When constructing an MVF, a developer can set flags on a flaggable object using a bitwise OR operation:
// To set a flag with bit position flagBit on an entity with existing flags
function setFlag(entityFlagBitfield: number, flagBit: number): number {
return entityFlagBitfield | (1 << flagBit);
}
5.3 Making Types Navigation Flag Aware
Extensions that have made their objects navigation flag aware will have either added the WithFlags type:
import { Flags } from "./navigationFlags";
// An example type in another extension
export type Node = {
id: string;
position: [number, number];
// Other properties...
} & WithFlags; // This adds the flags property
Or used the FlaggedGeometryAnchor
type for their geometryAnchor(s).
import { FlaggedGeometryAnchor } from "./navigationFlags";
// An example type in another extension
export type Connection = {
id: string;
entrances: FlaggedGeometryAnchor[];
exits: FlaggedGeometryAnchor[];
// Other properties...
}
This pattern allows any extension to incorporate navigation flags in a consistent way.