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
PolygonorMultiPolygon -
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
bboxfield 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
PolygonorMultiPolygonobject. -
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
bboxfield 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
_indexis specified: - It must match
lvlin the payload
→"The requested level index and payload lvl information do not match." -
If no
_indexis provided and a level with samelvlalready exists:
→"Building already has a level with the given level index." -
If
_indexis 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
siddoes not resolve to a valid site:
→"Site with siteIdentifier '{sid}' could not be found." -
If
biddoes 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.