Level Payload Validation
This document describes the validation rules applied to the Level GeoJSON payloads in the system. The validation is performed in two layers:
- JSON Schema Validation: Structural and field-level constraints.
- Runtime Validation: Business rules and contextual consistency enforced by application logic.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://geojson.org/schema/Level.json",
"title": "GeoJSON Level",
"type": "object",
"required": [
"type",
"features"
],
"properties": {
"type": {
"type": "string",
"enum": [
"FeatureCollection"
]
},
"features": {
"type": "array",
"items": {
"title": "GeoJSON Level",
"type": "object",
"required": [
"type",
"properties",
"geometry"
],
"properties": {
"type": {
"type": "string",
"enum": [
"Feature"
]
},
"id": {
"type": "number"
},
"properties": {
"type": "object",
"required": [
"fid",
"lvl",
"typeCode",
"name",
"sid",
"bid",
"shortName"
],
"properties": {
"fid": {
"type": "string",
"maxLength": 36,
"minLength": 1
},
"name": {
"type": "string",
"maxLength": 255,
"minLength": 0
},
"typeCode": {
"type": "string",
"enum": [
"level-outline"
]
},
"lvl": {
"type": "number"
},
"sid": {
"type": "string"
},
"bid": {
"type": "string"
},
"shortName": {
"type": "string"
}
}
},
"geometry": {
"oneOf": [
{
"title": "GeoJSON Polygon",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": {
"type": "string",
"enum": ["Polygon"]
},
"coordinates": {
"type": "array",
"minItems": 1,
"items": {
"type": "array",
"minItems": 4,
"items": {
"type": "array",
"minItems": 2,
"items": [
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -180,
"exclusiveMaximum": 180
},
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -90,
"exclusiveMaximum": 90
}
]
}
}
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
},
{
"title": "GeoJSON MultiPolygon",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": {
"type": "string",
"enum": ["MultiPolygon"]
},
"coordinates": {
"type": "array",
"minItems": 1,
"items": {
"type": "array",
"items": {
"type": "array",
"minItems": 4,
"items": {
"type": "array",
"minItems": 2,
"items": [
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -180,
"exclusiveMaximum": 180
},
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -90,
"exclusiveMaximum": 90
}
]
}
}
}
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
}
]
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
}
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
}
1. JSON Schema Validation
The JSON payload must conform to the GeoJSON FeatureCollection
structure, where each item in the features
array represents a single level of a building.
🔸 Root Object
- type:
"FeatureCollection"
(required) - features: array of Feature objects (required)
- bbox: optional array of numbers (minItems: 4)
🔸 features[].type
- Must be
"Feature"
(required)
🔸 features[].id
- Optional numeric identifier
🔸 features[].properties
- Must include the following fields (required):
- fid: string (1–36 chars)
- lvl: number
- typeCode: must be
"level-outline"
- name: string (max 255 chars)
- sid: string
- bid: string
- shortName: string
🔸 features[].geometry
- Must be either a valid GeoJSON
Polygon
orMultiPolygon
-
Coordinates must:
- Conform to valid GeoJSON structure.
- Include at least 4 coordinate points for each ring.
- Have latitude (
lat
) in range(-90, 90)
and longitude (lon
) in range(-180, 180)
, with high precision.
-
Optional
bbox
field must be an array of at least 4 numbers.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "https://geojson.org/schema/Level.json",
"title": "GeoJSON Level",
"type": "object",
"required": [
"type",
"properties",
"geometry"
],
"properties": {
"type": {
"type": "string",
"enum": [
"Feature"
]
},
"id": {
"type": "number"
},
"properties": {
"type": "object",
"required": [
"fid",
"lvl",
"typeCode",
"name",
"sid",
"bid",
"shortName"
],
"properties": {
"fid": {
"type": "string",
"maxLength": 36,
"minLength": 1
},
"name": {
"type": "string",
"maxLength": 255,
"minLength": 0
},
"typeCode": {
"type": "string",
"enum": [
"level-outline"
]
},
"lvl": {
"type": "number"
},
"sid": {
"type": "string"
},
"bid": {
"type": "string"
},
"shortName": {
"type": "string"
}
}
},
"geometry": {
"oneOf": [
{
"title": "GeoJSON Polygon",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": {
"type": "string",
"enum": ["Polygon"]
},
"coordinates": {
"type": "array",
"minItems": 1,
"items": {
"type": "array",
"minItems": 4,
"items": {
"type": "array",
"minItems": 2,
"items": [
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -180,
"exclusiveMaximum": 180
},
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -90,
"exclusiveMaximum": 90
}
]
}
}
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
},
{
"title": "GeoJSON MultiPolygon",
"type": "object",
"required": ["type", "coordinates"],
"properties": {
"type": {
"type": "string",
"enum": ["MultiPolygon"]
},
"coordinates": {
"type": "array",
"minItems": 1,
"items": {
"type": "array",
"items": {
"type": "array",
"minItems": 4,
"items": {
"type": "array",
"minItems": 2,
"items": [
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -180,
"exclusiveMaximum": 180
},
{
"type": "number",
"multipleOf": 0.00000001,
"exclusiveMinimum": -90,
"exclusiveMaximum": 90
}
]
}
}
}
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
}
]
},
"bbox": {
"type": "array",
"minItems": 4,
"items": {
"type": "number"
}
}
}
}
1. JSON Schema Validation
The incoming payload must conform to the following rules defined in the JSON Schema:
🔸 Root Object
- type: must be
"Feature"
(required). - id: optional numeric identifier.
- bbox: optional array with at least 4 numerical values.
🔸 properties
Object
-
fid (Feature Identifier):
- Required
- String
- Minimum length: 1
- Maximum length: 36
-
lvl:
- Required
- Integer
-
typeCode:
- Required
- Must be
"level-outline"
-
name:
- Required
- String
- Maximum length: 255
-
sid (Feature Identifier):
- Required
- String
- Minimum length: 1
- Maximum length: 36
-
bid (Feature Identifier):
- Required
- String
- Minimum length: 1
- Maximum length: 36
-
shortName:
- Required
- String
- Maximum length: 255
-
Other fields are allowed unless explicitly forbidden (see Runtime Validation section).
🔸 geometry
Object
- Must be a valid GeoJSON
Polygon
orMultiPolygon
object. -
Coordinates must:
- Conform to valid GeoJSON structure.
- Include at least 4 coordinate points for each ring.
- Have latitude (
lat
) in range(-90, 90)
and longitude (lon
) in range(-180, 180)
, with high precision.
-
Optional
bbox
field must be an array of at least 4 numbers.
2. Runtime Validations (Application Logic)
These checks are performed in application code and cannot be enforced by JSON Schema alone:
🔹 1. fid
(Feature Identifier)
- If missing:
→"fid is required."
- If invalid:
→"The fid field contains an invalid value."
🔹 2. sid
(Site Identifier)
- If missing:
→"sid is required. fid: '{fid}'"
- If invalid:
→"The sid field contains an invalid value."
- If not matching the requested site:
→"The requested siteIdentifier and payload sid do not match. fid : '{fid}'"
🔹 3. bid
(Building Identifier)
- If missing:
→"bid is required. fid: '{fid}'"
- If invalid:
→"The bid field contains an invalid value."
- If not matching the requested building:
→"The requested buildingIdentifier and payload bid do not match. fid : '{fid}'"
🔹 4. name
- Cannot be null or empty
→"The name field cannot be empty."
- Cannot exceed max length (255 chars)
→"Level name cannot exceed '255' characters."
🔹 5. shortName
- Cannot be null or empty
→"The shortName field cannot be empty."
- Cannot exceed max length
→"Level shortName cannot exceed '{MaxLength}' characters."
🔹 6. levelType
- Must be provided and non-empty
→"The levelType field cannot be empty."
- Must be in the allowed types list (case-insensitive match)
→"The levelType is invalid."
🔹 7. lvl
(Level Index)
- Must be present and a valid integer
→"lvl must be a valid unique integer."
- If a request-level
_index
is specified: - It must match
lvl
in the payload
→"The requested level index and payload lvl information do not match."
-
If no
_index
is provided and a level with samelvl
already exists:
→"Building already has a level with the given level index."
-
If
_index
is provided but the level is not found:
→"Level was not found with given lvl: {lvl}."
🔹 8. eid
(External Identifier)
- If present:
- Must not be empty
→"The eid field cannot be empty."
- Must not be used by another level with different
fid
→"Another level exists with the same levelExternalIdentifier for this client."
🔹 9. Site and Building Existence
-
If
sid
does not resolve to a valid site:
→"Site with siteIdentifier '{sid}' could not be found."
-
If
bid
does not resolve to a valid building:
→"Building with buildingIdentifier '{bid}' could not be found."
This validation process ensures that level data submitted to the platform is accurate, complete, and adheres to both structural and contextual integrity constraints.