Skip to main content

Geodata Sync

Enterprise customers with existing indoor map data may wish to import this into Mappedin, either as a one-time import forming the basis of a customer facing map, or as part of a recurring sync. This can be done by converting the data into the Mappedin Venue Format version 3 (MVFv3).

Please use the Mappedin Demo Airport MVFv3 as a reference.

Overview

An MVFv3 is a zip file that contains implementations of one or more MVF Extensions. Each extension defines a set of JSON and GeoJSON files that can or must be included, as well as the shape of the data and how it links to other extensions. Unlike many other geospatial formats, MVF is optimized to represent entire venues in a single package, indoors and outdoors. This includes building geometry, points of interest, outdoor features, and the pathing throughout. This means where possible data is grouped into separate files per floor. Further details on MVFv3, including how to use it, can be found in the MVF v3 Specification. The rest of this document will outline what is needed for an import into the Mappedin CMS.

Special Notes

Identifiers

Many extensions will include arrays of objects with an id property, which is a string that looks like <prefix>_<value>, like f_67a24d8a241d315f309f2436. These identifiers are used to link objects together, both within and between extensions. All identifiers MUST:

  • Be unique within the current MVF it is a part of. So a given MVF can only contain one floor with the id f_1, but MVFs representing different venues could each have their own f_1.
  • Be durable between imports. So if a venue is synced once with an f_1, the next time the sync is run, there should still be an f_1 as long as that floor still exists. Non-durable identifiers will cause any manually managed references in non-imported extensions to break. For example, if floor identifiers changed every sync, and pathing was being done manually in CMS, every sync would delete the entire pathing network. If an object has different properties but fundamentally represents the same object, it should have the same identifier. Eg, a "First floor" gets an expansion and is now called "Main Floor" but still covers the old area, that is still f_1.

In addition, any identifier referenced by an object in the MVF (for example, a location attaching to a locationCategory) MUST be present in the MVF itself. If not, the import will fail. In cases where the class of data is wholly managed in CMS, before submission the latest version of that extension should be downloaded from Mappedin and bundled into the MVF to be re-imported.

Details

Many extensions will include objects with definitions for an optional details property. This is a standard MVF concept, and details can always contain the same properties. On some extensions, details is actually required, usually along with the name property (see Locations).

Example details

    "details": {
// The name of the object
"name": "Joe's Coffee",

// A description of the object
"description": "Hot drinks at Joe's.",

// An identifier that links the object to another system.
// For example, a customer may have their own CMS containing location metadata,
// and this would be the id of the location in that system.
// In Mappedin products, the externalId is typically used as part of the URL
// when generating deep links into that object, so it should be a stable and unique identifier.
"externalId": "JOES-COFFEE-1",

// Not always used, but if an object has an "icon"-like representation
// (which is different from a logo or photograph) it can be included here.
"icon": "https://cdn.mappedin.com/images/mappedin-demo-airport/icon.png",

// An alternative name for an object, typically used in a space constrained environment.
// For example, "Lobby" is often "L".
"shortName": "JC",
},

GeoJSON

All geojson files must be valid RFC-7946 compliant GeoJSON. In particular, this means the coordinate system must be WGS84 (EPSG:4326). This is also true of any other coordinates provided in non-geojson files. Any distances will be in meters.

Extensions will provide additional constraints on particular geojson files, such as mandatory entries in the properties object. They may also limit collections to certain types of geometry, such as Polygon or MultiPolygon.

Note that geometry in the MVFv3 exported by Mappedin after an import is done will NOT be identical to the original geometry. In particular, some rounding may occur, and any "Multi" geometries will be converted to their singular instances. Line strings will also be inflated into Polygons according to the style of the venue.

Validation

All MVFv3s must meet the spec, meaning the data must be in the correct format, and all references must be valid within the MVF. The @mappedin/mvf TypeScript package provides convenient functions to test, validate, and even create MVFv3 zip files. It is recommended to use this package as part of any MVFv3 build processes. Below are options for common scenarios.

Online validator

A manual check can be performed using the MVFv3 validator online tool. This operates locally in your browser, and is just a convenience front end for the @mappedin/mvf package.

Post build step as part of a non-Node pipeline

If the MVFv3 is being built in an environment other than Node, the @mappedin/mvf package can still be used as part of a post build step.

#!/usr/bin/env node
import fs from 'node:fs/promises';
import path from 'node:path';
import process from 'node:process';
import { createCMSMVFv3Parser } from '@mappedin/mvf/preset-cms';

const arg = process.argv[2];
if (!arg) {
console.error('No file provided');
process.exit(1);
}

const filePath = path.resolve(process.cwd(), arg);
let data;
try {
const buf = await fs.readFile(filePath);
data = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
} catch (err) {
console.error(err);
process.exit(1);
}

const parser = createCMSMVFv3Parser().build().unwrap();

const mvfResult = await parser.decompress(data);
if (mvfResult.isErr()) {
console.error(mvfResult.error.message);
process.exit(2);
}

const verifyResult = await parser.verify(mvfResult.value);
if (verifyResult.isErr()) {
console.error(JSON.stringify(verifyResult.error, null, 2));
process.exit(3);
}

process.exit(0);

Integration tests when building an MVF in a Node application

When building an MVFv3 in a Node application, the @mappedin/mvf package can be used to write unit and integration tests.

In the CMS MVFv3 parser, most extensions are OPTIONAL, meaning that it is possible to start with tests that build a manifest, then add floors, then geometry, etc.

import { createCMSMVFv3Parser } from '@mappedin/mvf/preset-cms';
const mvfParser = createCMSMVFv3Parser().build().unwrap();

describe('MVFv3 bundling', () => {
it('should build a valid MVFv3', () => {
const mvf = buildMVFv3(venueData);
expect(mvfParser.parse(mvf).error?.First()).toBeUndefined();
expect(mvfParser.verify(mvf).error).toBeNull();
});
});

Note: In this environment, the parser also provides a compress method that will take an MVFv3 JavaScript object in memory and return a Uint8Array of the zip file.

Mandatory Extensions

While an MVFv3 may have many extensions, only a subset are used for importing into the Mappedin CMS. These are the mandatory extensions.

Core

The Core extension is required and must be present. It contains the manifest, the floors, and the geometry for each floor.

Manifest

The manifest is a GeoJSON file that contains the metadata for the venue. It must be present and must be named manifest.geojson. It must contain a FeatureCollection with a single feature.

Example:

// manifest.geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [-114.0056954137981, 51.13358028945705]
},
"properties": {
// Required, but not currently validated by the import.
"contents": [
{ "type": "file", "name": "manifest.geojson" },
{ "type": "file", "name": "floors.geojson" },
{
"type": "folder",
"name": "geometry",
"children": [
{ "type": "file", "name": "f_67a24d8a241d315f309f2436.geojson" }
]
},
{ "type": "file", "name": "nodes.json" }
],
// Required
"name": "Mappedin Demo - Airport",

// Required by the spec, but not currently used by the import
"time": "2025-09-05T23:45:17.446Z",

// Required. Must always be `3.0.0`
"version": "3.0.0",

// Optional. Used if the venue is usually displayed such that North is not "up".
// 90 degrees would mean East is "up".
"naturalBearing": 0.1543915198848822,

// Optional for single language venues, required for multi-language venues.
"language": "en",

// Optional if sycing only one venue, required if syncing multiple venues.
// Provided my Mappedin. AKA the venue slug.
"mapId": "mappedin-demo-airport",

// Optional. The FloorId of the default floor to display when the venue is loaded.
// For multi-building venues, this SHOULD be the outdoor floor.
"defaultFloor": "f_67a24d8a241d315f309f2436",

// Optional, will be ignored by the import and derived by the geometry
"tzid": "America/Edmonton"
}
}
]
}

Floors

Floors are stored in the floors.geojson file. It must be present and must be named floors.geojson. It must contain a FeatureCollection with a single feature for each floor. The feature must have a Polygon or MultiPolygon geometry which describes the outline of the floor. This will be used to render the outline of the floor when viewed in stacked map mode. The most important property of the feature is the id property, which must be a string beginning with f_ and be unique within the MVF. MOST other extensions will reference a floor by its ID in some way, often in a file named after the floor ID (see Geometry section below for an example).

Example:

// floors.geojson
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
// Required. Must be a string beginning with `f_` and be unique within the MVF.
// Many other extensions will reference this ID, often in a file named by the ID.
"id": "f_67a24d8a241d315f309f2436",

// Required. This is an ordinal value with 0 being the ground floor.
// In a single-building MVF, elevation must be unique within the MVF.
// In a multi-building MVF that implements the floorStack extension,
// elevation must be unique within the floorStack instead.
"elevation": 0,

// Optional. See the section on Details for more information.
// A name, short name, and externalId will be automatically generated if not provided.
// For shortName, consider what the button on the elevator would say.
"details": {
"externalId": "MAP-RIZD7TRZ",
"name": "First Floor",
"shortName": "F1"
},

// Optional. If a floor has another name it can be put here.
// This name is typically shown near, but with less emphasis than, the actual name.
"subtitle": "Arrivals",

},
"geometry": {
"type": "MultiPolygon",
"coordinates": [
// Snipped for brevity, must be valid WGS84 GeoJSON coordinates
]
}
},
]
}

Geometry

Geometry are the fundamental building blocks of the MVF. They are stored in the geometry folder. Each file must be named after the floor ID it is associated with, and must be a GeoJSON file. It must contain a FeatureCollection with every feature of the floor. This includes any walls, polygons for rooms, points that locations or elevators represent, etc. These objects will be heavily referenced by other extensions.

Example:

// geometry/f_67a24d8a241d315f309f2436.geojson
{
"features": [
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[-114.00868338785048, 51.13111184629685],
[-114.00869812368491, 51.13108800537968],
[-114.00873495449434, 51.13109592381163],
[-114.008720270649, 51.13111972993556],
[-114.00868338785048, 51.13111184629685]
]
]
},
"properties": {
"id": "g_67a24e03241d315f309f37a6",
// Typically, externalId is the only property provided, if any.
// This is often the space identifier in a customer's location management system.
"details": { "externalId": "ROOM-123" }
}
}
]
}

Floor Stacks

In a multi-building MVF, the Floor Stacks extension is required. In a single building MVF, it is optional, unless the Facade extension is also present, or if there are outdoor features like parking lots, when it is then required. It groups floors together into buildings, and provides basic metadata about those buildings. It must be present and must be named floor-stacks.json. It must contain an array of objects with a id property and a floors property. The id property must be a string beginning with fs_ and be unique within the MVF. The floors property must be an array of floor IDs. A floor can only be in one floor stack, and the elevation of the floors inside a stack must be unique. They do not need to be contiguous. Also see the Outdoors extension below.

Example:

// floor-stacks.json
[
{
// Required, must be a string beginning with `fs_` and be unique within the MVF.
"id": "fs_67a24d8a241d315f309f2431",

// Optional, a standard details object.
"details": {
"externalId": "MG-N6HS75U6",
"name": "Domestic Parking",
"shortName": "P1"
},

// Required, an array of floor IDs belonging to this stack.
"floors": [
"f_67a24d8a241d315f309f2437",
"f_67a24d8a241d315f309f2438",
],

// Optional, the floor ID of the default floor to display when the stack is loaded.
"defaultFloor": "f_67a24d8a241d315f309f2437"
},
]

In a single building MVF with no Outdoors extension, a Floor Stack will be created automatically if not supplied.

Outdoors

In a multi-building MVF, or a single building MVF with the Facade extension,the Outdoors extension is required. It must be present and must be named outdoors.json, which contains a single object with a floors array containing the floor IDs of the outdoor floors. It describes the floors that represent the outdoor area of a venue. It can have multiple levels, such as when Arrivals and Departures are accessible from "outside" but are stacked on top of each other. When implementing the Facade extension, the geometry that describes the outer shell (or facade) of the building should be included on an outdoor floor.

Other outdoor features, such as parking lots or outdoor amenities should be included on an outdoor floor rather than outside on the first floor.

Example:

// outdoors.json
{
// Required, an array of floor IDs belonging to the outdoors.
// Elevation must be unique within the outdoor floors
"floors": [
"f_67a24d8a241d315f309f2436"
]
}

CMS

The CMS extension represents several sub extensions that contain data required by the Mappedin CMS. All CMS sub extensions will be present inside of the cms folder. The layers extension is required for geometry imports, but others are optional.

Layers

The layers extension is required for geometry imports. There must be a cms/layers folder with a f_<floorId>.json file for each floor. Each file contains an object with a mapping of geometryId to layer name. The standard layer names are:

  • Floor
  • Walls
  • Non Public
  • Entrance
  • Connections
  • Parking Garage
  • Retails
  • Security Area
  • Zones
  • Check In Counters
  • Washrooms
  • Gates
  • Obstructions
  • Services
  • Inner Wall
  • Baggage Carousels

A geometry of any type other than Point or MultiPoint MUST be mapped to a layer, or the import will fail.

Example:

// cms/layers/f_67a24d8a241d315f309f2442.json
{
"g_67a24e03241d315f309f348d": "Zones",
"g_67a24e03241d315f309f348e": "Connections",
"g_67a24e03241d315f309f348f": "Connections",
"g_67a24e03241d315f309f3490": "Connections",
"g_67a24e03241d315f309f3491": "Connections",
"g_67a24e03241d315f309f3492": "Connections",
"g_67a24e03241d315f309f3493": "Connections",
"g_67a24e03241d315f309f3494": "Connections",
"g_67a24e03241d315f309f3495": "Connections",
"g_67a24e03241d315f309f3496": "Connections",
"g_67a24e03241d315f309f3497": "Connections",
"g_67a24e03241d315f309f3498": "Non Public",
"g_67a24e03241d315f309f3499": "Non Public",
"g_67a24e03241d315f309f349a": "Floor",
"g_67a24e03241d315f309f34e4": "Wall",
"g_67a24e03241d315f309f34e5": "Wall",
"g_67a24e03241d315f309f34e8": "Inner Wall",
"g_67a24e03241d315f309f34e9": "Inner Wall",
"g_67a24e03241d315f309f34ea": "Inner Wall",
"g_67a24e03241d315f309f34ee": "Connections",
"g_67a24e03241d315f309f34ef": "Connections",
"g_67a24e03241d315f309f34f0": "Connections",
"g_67a24e03241d315f309f34f1": "Connections",
"g_67a24e03241d315f309f34f7": "Connections",
"g_67a24e03241d315f309f34f8": "Connections",
"g_67a24e03241d315f309f34f9": "Connections",
"g_67a24e03241d315f309f3503": "Non Public",
"g_67a24e03241d315f309f3504": "Non Public",
"g_67a24e03241d315f309f3506": "Void",
"g_67a24e03241d315f309f3507": "Non Public",
"g_67a24e03241d315f309f3508": "Non Public",
"g_67a24e03241d315f309f3509": "Floor",
"g_67a24e03241d315f309f3729": "Retails"
},

Optional Extensions

The following extensions are optional, but highly recommended if the data is available. More details on each extension can be found in the MVF v3 Specification page.

  • Connections - Defines elevators, stairs, and other connections between floors
  • Facade - Defines the outer shell of the building. Used heavily in multi-building mode in the Mappedin SDK
  • Locations - Defines POI data for the venue

Facade

The facade extension maps polygons on the outdoor map to the building (floor stack) they represent. This is used heavily in features such as Dynamic Focus to peel back the outer shell of the building to reveal the interior. A simple facade might just be a single polygon that represents all the geometry of the default floor of the building merged together, but more complex facades with multiple polygons can also be supported.

The facade extension requires a facade folder, which contains f_<floorId>.json files for each floor. Each file contains an array of objects with a floorStackId property that references the floor stack they represent, and a geometryIds property that is an array of geometry IDs that represent the facade on that floor.

If there are multiple outdoor floors, there should be a facade file for each one.

Example:

// facade/f_67a24d8a241d315f309f244c.json
[
{
"floorStackId": "fs_67a24d8a241d315f309f2435",
"geometryIds": [ "g_67a24e03241d315f309f3768" ]
}
]

Reminder: The file name is the floor the facade geometry is on, and the geometry Ids must be geometry on that floor. The floorStackId is the building the geometry represents, and will be other floors.

Connections & Navigation Flags

The connections extension defines elevators, stairs, and other connections between floors. For it to be used as part of a continuous import, it is essential that that a connection's entrances and exits map to the right geometries on the right floors.

If Connections is provided, Navigation Flags is required (see below).

Example:

// connections.json
[
{
// Required, must be a string beginning with `c_` and be unique within the MVF.
"id": "c_67a24e01241d315f309f2fb1",

// Required, must be one of "elevator", "stairs", "escalator", "door", "travelator", or "ramp".
// See the Connections specification for more details.
"type": "elevator",

// Required, an array of Flagged Geometry Anchors (see the Navigation Flags extension).
// These are the points a person can ENTER the connection. From there, they can leave at any exit.
// These are objects with a geometryId, the floorId it is on, and a flags array.
// For most use cases, the flags array will be [1] if the entrance is "accessible" for wheelchair
// users, and [0] if it is not.
"entrances": [
{
"geometryId": "g_67a24e01241d315f309f2636",
"floorId": "f_67a24d8a241d315f309f2437",
"flags": [1]
},
{
"geometryId": "g_67a24e01241d315f309f265f",
"floorId": "f_67a24d8a241d315f309f2438",
"flags": [1]
},
{
"geometryId": "g_67a24e01241d315f309f26bf",
"floorId": "f_67a24d8a241d315f309f2439",
"flags": [1]
},
{
"geometryId": "g_67a24e01241d315f309f272e",
"floorId": "f_67a24d8a241d315f309f243a",
"flags": [1]
},
],

// Required, an array of Flagged Geometry Anchors (see the Navigation Flags extension).
// These are the points a person can EXIT the connection. They must enter at an entrance. These
// do not need to be symmetrical, meaning you can have a stairwell that you can enter from the
// second floor without being able to exit there.
"exits": [
{
"geometryId": "g_67a24e01241d315f309f2636",
"floorId": "f_67a24d8a241d315f309f2437",
"flags": [1]
},
{
"geometryId": "g_67a24e01241d315f309f265f",
"floorId": "f_67a24d8a241d315f309f2438",
"flags": [1]
},
{
"geometryId": "g_67a24e01241d315f309f26bf",
"floorId": "f_67a24d8a241d315f309f2439",
"flags": [1]
},
{
"geometryId": "g_67a24e01241d315f309f272e",
"floorId": "f_67a24d8a241d315f309f243a",
"flags": [1]
}
],

// Required, must be positive. The cost (in meters) to enter the connection.
// i.e., the distance it's worth walking to avoid using this connection. Often very high for
// elevators, and very low for escalators, to encourage use of higher throughput escalators.
"entryCost": 5000,

// Required, must be >= 1. The value to multiply the difference in elevation by to add to
// the cost to use the connection. Often low for elevators, high for stairs, medium for escalators.
// A person has to wait a bit for an elevator, but once they are on it's much faster to travel
// through high numbers of floors compared to escalators, and stairs are even worse.
"floorCostMultiplier": 1,

// Optional, a standard details object.
"details": { "name": "DPG-Elevator 1", "externalId": "CON-8E5939QH" },
}
]

If unsure about the cost values, use the values in the example MVF, or ask your Mappedin representative.

NOTE: Connections can reference both Point and Polygon geometries. Polygons are preferred if available, since that renders better, but Points are supported.

For the purposes of geodata import, it is sufficient to provide this static file:

// navigationFlags.json
{
"accessible": {
"index": 0,
"bit": 0,
"details": {
"name": "Accessible",
"description": "Accessible routes indicate that they can be used by people with mobility issues, in particular wheelchair users."
}
},
"outdoors": {
"index": 0,
"bit": 1,
"details": {
"name": "Outdoors",
"description": "Outdoors routes indicate that can be exposed to the elements."
}
}
}

For more information, see the Navigation Flags specification.

Locations

The locations extension defines POI data for the venue. It is how stores, restrooms, etc are defined. It also includes categories, which are used to group locations together. For customers that wish to do an one time geodata import, but want an on-going POI sync, providing an API similar to the one outlined in Common Data Objects is recommended. Providing an MVF will require a fully integral, up to date import MVF every time, which is equivalent to a full geodata sync.

Locations.json

The Locations aspect of the Locations extension comes in the form of a locations.json file, which contains an array of Location objects.

Example:

// locations.json
[
{
// Required, must be a string beginning with `loc_` and be unique within the MVF.
"id": "loc_67a24e09241d315f309f3869",

// Required, a standard details object except for name, which is now also required
"details": {
"name": "Who's Who In The Zoo",
"description": "Any child or “child at heart” will be delighted with the selection of stuffed animals, dolls, wind-ups and battery-operated gizmos filling the shelves of Who’s Who in the Zoo. Their boutique is designed specifically for flight lovers and offers a wide selection of airplane and spacecraft models.",
"externalId": "405"
},

// Required, but can be empty. An array of geometry anchors. Each geometry anchor must have a
// `geometryId` property, which is the ID of the geometry on the floor, and a `floorId` property,
// which is the ID of the floor.
//
// These are the physical places this location can be found. If a location is in a room, it should
// be anchored to Polygon geometry. If it's more of a point in space, like an AED, it should be
// anchored to a Point geometry.
//
// NOTE: A location can be attached to many geometries, on many floors, and many locations can be
// attached to the same geometry.
"geometryAnchors": [
{
"geometryId": "g_67a24e03241d315f309f313e",
"floorId": "f_67a24d8a241d315f309f243e"
}
],

// Required, but can be empty. An array of category IDs this location belongs to.
// See location-categories.json below.
"categories": [
"lcat_67a24e08241d315f309f3820",
"lcat_67a24e08241d315f309f383d"
],

// Required, but can be empty. An array of image objects. Each image object must have a `url`
// property, which is the full URL of the image. Pictures are usually photographs of the
// location. See Logo for the brand logo.
"images": [{
"url": "https://cdn.mappedin.com/5a3827a74bd0ef04d9000000/0d0a9e3afb1f4e662387d3502e76c35cb7785c74.png"
}],

// Required, but can be empty. An array of objects with a `url` property, which is the full URL of the link,
// and a `label` property describing the link.
"links": [{
"url": "https://www.whoswhointhezoo.com/collection/offers/",
"label": "Offers"
}],

// Required, but can be empty. An array of social media objects. Each social media object must have a `url`
// property, which is the full URL of the social media profile, and `name` which is the name of the social
// media platform.
// For a geodata import, must be one of "facebook", "twitter", or "instagram".
"social": [],

// Required, but can be empty (which will be interpreted as using the venue's opening hours).
// This is an array of objects meeting a more permissive OpeningHoursSpecification schema.org type.
// See https://docs.mappedin.com/mvf/v3/latest/types/_mappedin_mvf.locations.OpeningHoursSpecification.html
"openingHours": [
{
"@type": "OpeningHoursSpecification",
"opens": "07:30",
"closes": "20:00",
"dayOfWeek": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
]
}
],

// Optional. If present, must be an object with a `url` property, which is the full URL of the
// website, and a `label` property, which should always be "Website" (other values will be ignored).
"website": { "label": "Website", "url": "http://whoswhointhezoo.com/" },

// Optional. If present, must be a string representing the (public) phone number of the location
"phone": "403-291-7037",

// Optional, but highly recommended. If present, must be a string representing the logo image URL.
// This is usually displayed on the card for the location in Mappedin Solutions, and should be
// square if possible.

"logo": "https://cdn.mappedin.com/5a3827a74bd0ef04d9000000/0d0a9e3afb1f4e662387d3502e76c35cb7785c74.png"

// Optional. If an SDK customer needs to pass additional data to the SDK, this is the place
// to do it. Talk to your Mappedin representative if you need to use this.
"extra": { },
}
]

NOTE: For any image URLs, in a recurring sync, the image will ONLY be updated if the URL has changed. Meaning, if the URL is something like https://example.com/store-123.png, and that image is re-uploaded to the same URL, it will not be changed in the Mappedin system after a sync.

Location Categories

The Location Categories aspect of the Locations extension comes in the form of a location-categories.json file, which contains an array of LocationCategory objects.

Example:

// location-categories.json
[
{
// Required, must be a string beginning with `lcat_` and be unique within the MVF.
"id": "lcat_67a24e08241d315f309f3833",

// Required, a standard details object except for name, which is now also required
"details": { "name": "Travel Essentials", "externalId": "CAT-XZGGCK75" },

// Optional, but can be empty. A string representing the ID of the parent category.
// Best practice is not to have deeply nested parent/child relationships.
"parent": "lcat_67a24e08241d315f309f3820",

// Optional. If an SDK customer needs to pass additional data to the SDK, this is the place
// to do it. Talk to your Mappedin representative if you need to use this.
"extra": { },
}
]

Here is the standard recommended location categories for Airport venues:

// location-categories.json
[
{
"id": "lcat_1",
// Or Restrooms/Toilets as appropriate
"details": { "name": "Washrooms" }
},
{
"id": "lcat_2",
"details": { "name": "Checkin" }
},
{
"id": "lcat_3",
"details": { "name": "Security" }
},
{
"id": "lcat_4",
"details": { "name": "Gates" }
},
{
"id": "lcat_5",
"details": { "name": "Food & Drinks" }
},
{
"id": "lcat_6",
"details": { "name": "Shops" }
},
{
"id": "lcat_7",
"details": { "name": "Services" }
},
{
"id": "lcat_8",
"details": { "name": "Lounges" }
},
{
"id": "lcat_9",
"details": { "name": "Baggage Claim" }
},
{
"id": "lcat_10",
"details": { "name": "Parking" }
},
{
"id": "lcat_11",
"details": { "name": "ATM/Exchange" }
},
{
"id": "lcat_12",
// Shuttles, rideshare pickups, taxi stands, etc
"details": { "name": "Transportation*" }
},
{
"id": "lcat_13",
"details": { "name": "Connections" }
},
{
"id": "lcat_14",
// A location for each terminal (if applicable), who's geometry points to the facade for that
// terminal on the outdoor map.
"details": { "name": "Terminals" }
},
{
"id": "lcat_15",
"details": { "name": "Hotel" }
},
{
"id": "lcat_16",
"details": { "name": "Art" }
}
]