Repository for CODECHECK certificate 2025-026.
Report: https://zenodo.org/records/{placeholder_identifier}
Publication: Automated validation of route instructions in indoor environments
Code Repository: https://doi.org/10.6084/m9.figshare.24208518
If you find the paper or this repository helpful in your publications, please consider citing it.
@article{Arabsheibani2025,
author = {Arabsheibani, Reza and Winter, Stephan and Tomko, Martin},
journal = {Journal of Spatial Information Science (JOSIS)},
title = {Automated validation of route instructions in indoor environments},
year = {2025},
number = {30},
pages = {25–60},
doi = {https://doi.org/10.5311/JOSIS.2025.30.385}
}If you want to use the checked code in your publications, please consider citing it.
@article{Arabsheibani2023,
author = "Reza Arabsheibani",
title = "{Unlocking Navigation Success: Using Instruction-following Agents to Explore the Role of Floorplan Complexity in Route Instructions Validity.}",
year = "2023",
month = "9",
url = "https://figshare.com/articles/software/Unlocking_Navigation_Success_Using_Instruction-following_Agents_to_Explore_the_Role_of_Floorplan_Complexity_in_Route_Instructions_Validity_/24208518",
doi = "10.6084/m9.figshare.24208518.v1"
}If you want to reproduce the code yourself again, then first run the following command to build the Docker image:
docker build -f CodecheckDockerfile -t codecheck-2025-026 .Next run the following command to start the docker container, from where all scripts can be executed.
docker run --rm -it -v "$PWD:/codecheck" -w /codecheck codecheck-2025-026This repository contains a comprehensive pipeline for generating synthetic indoor environments from font glyphs, converting them to TextWorld game formats, calculating complexity metrics, generating route instructions, and validating navigation through automated agents.
The pipeline consists of five main stages:
- Generating Synthetic Environments - Creating geometric environments from font glyphs
- Converting to TextWorld Format - Transforming GeoJSON environments into playable TextWorld games
- Calculating Complexity Criteria - Computing spatial complexity metrics
- Finding Longest Shortest Paths - Identifying optimal routes for navigation
- Navigation Validation - Testing route instructions with automated agents
RouteInstructionGeneration/
├── Fonts/ # Font files used for environment generation
├── geojson/ # Generated GeoJSON environments
│ └── Curated7/ # Curated dataset (shapefiles)
├── games/ # Generated TextWorld game files (.z8, .ni)
├── data/ # Intermediate data files
│ ├── RI/ # Route instruction XML files
│ └── [letter]_*.geojson # Per-letter environment components
├── dicts.py # Configuration dictionaries (letters, landmarks)
├── direction.py # Direction mapping utilities
├── concepts.py # TextWorld concept definitions
├── templates.py # Inform7 code templates
├── generator.py # Core game generator (TextWorld_WP1 compatible)
├── creating_ni_2.py # Game production from GeoJSON
├── RouteFromPath.py # Route instruction generation utilities
├── Complexity_Criteria_Finder_parallel.py # Complexity metric calculation
├── Generate_Route_Instructions_LongestShortestV4.py # LSP route generation
├── Navigate_Parallel.py # Parallel navigation validation
├── Run_Experiment.py # Experiment runner
└── [other utility scripts]
- geopandas - Geospatial data manipulation
- shapely - Geometric operations
- networkx - Graph algorithms
- momepy - Urban morphology analysis
- textworld - Text-based game framework
- freetype-py - Font glyph extraction
- osmnx - Spatial network analysis
- pandas - Data manipulation
- openpyxl - Excel file handling
- xml.etree.ElementTree - XML parsing
pip install geopandas shapely networkx momepy textworld freetype-py osmnx pandas openpyxlNote: TextWorld requires Inform7 compiler to be installed on your system. Install Inform7 from https://ganelson.github.io/inform/ and ensure it's accessible in your system PATH.
To run the complete pipeline:
-
Generate environments (if not already done):
from Run_Experiment import create_Polygons_from_Letters create_Polygons_from_Letters(folder_name='Curated7', version='V7')
-
Create room/door/landmark files (if not already done):
python create_rooms_parallel.py
-
Generate games (for each letter/route combination):
from creating_ni_2 import produce_game produce_game(letterz='A_perspire_Approach1', x_origin='...', y_origin='...', primary_orientation=6)
-
Calculate complexity metrics:
# Edit Complexity_Criteria_Finder_parallel.py to set condition=True python Complexity_Criteria_Finder_parallel.py
-
Generate route instructions:
python Generate_Route_Instructions_LongestShortestV3.py
-
Validate navigation:
# Edit Navigate_Parallel.py to set correct XML file path python Navigate_Parallel.py
Purpose: Create geometric environments from font glyphs with landmarks and spatial structure.
Key Files:
dicts.py- Defines letters to process and landmark typesdirection.py- Direction mappings (cardinal, relative)concepts.py- TextWorld concept classes (Player, IndoorArea, IndoorRoom, Door, Landmark)templates.py- Inform7 code templates for game generationRun_Experiment.py- Main script for environment generation
Process:
- Load font files from
Fonts/directory - Extract glyph outlines for letters defined in
dicts.letters - Convert glyphs to polygons (GeoJSON format)
- Generate random landmarks within each letter polygon
- Create skeletonized network structure
- Save environments as shapefiles in
geojson/Curated7/
Output: Shapefiles containing:
ICD_CalculatedV7.shp- Letter polygons with distinct identifiersOneLetterV7.shp- Individual letter geometriesSkelV7.shp- Skeletonized network structurelandmarksV7.shp- Landmark points
Usage:
from Run_Experiment import create_Polygons_from_Letters
create_Polygons_from_Letters(folder_name='Curated7', version='V7')Purpose: Transform GeoJSON environments into playable TextWorld games (.z8 format).
Key Files:
creating_ni_2.py- Main conversion script (produce_game()function)RouteFromPath.py- Path finding utilitiescreate_rooms_parallel.py- Room decomposition (parallel processing)
Process:
- Load shapefiles for a specific letter
- Decompose letter polygon into rooms (using cross-line splitting)
- Extract skeleton network and convert to graph
- Identify decision points (nodes with degree ≥ 3)
- Create indoor areas from graph nodes
- Identify doors at room intersections
- Assign landmarks to areas
- Generate Inform7 code using templates
- Compile to TextWorld game format (.z8)
Output:
games/random/[letter]_[x_origin]_[y_origin].z8- Playable game filesdata/[letter]_room.geojson- Room geometriesdata/[letter]_door.geojson- Door locationsdata/[letter]_landmark.geojson- Landmark locationsdata/[letter]_skeleton.geojson- Skeleton networkdata/[letter]_graphNodes.geojson- Graph node locationsdata/[letter]_graphEdges.geojson- Graph edge connections
Usage:
from creating_ni_2 import produce_game
produce_game(letterz='A_perspire_Approach1',
x_origin='500748.67',
y_origin='1028060.38',
primary_orientation=6)Purpose: Compute spatial complexity metrics for each environment.
Key File: Complexity_Criteria_Finder_parallel.py
Metrics Calculated:
- ICD (Intersection Count Density) -
2 * edges / nodes - Bearing Entropy - Shannon entropy of edge bearings
- Categorized Bearing Entropy - Entropy of bearings in 10 categories (36° each)
- Graph Asymmetry - Rotation angles required for node symmetry
Process:
- Load letter polygons and skeleton networks
- Convert skeleton to NetworkX graph
- Calculate bearings for all edges
- Compute entropy metrics
- Calculate graph asymmetry (for nodes with degree 3-4)
- Normalize all metrics to [0,1] range
- Categorize normalized values into deciles
Output: Excel file (Complexity_Criteria_for_v*.xlsx) with columns:
- Letter, ICD, Bearing Entropy, Categorized Bearing Entropy, Graph Asymmetry
- Normalized versions of all metrics
- Skeletonization_Method, Path
Usage:
# Edit the main block in Complexity_Criteria_Finder_parallel.py
# Set the condition to True and run:
python Complexity_Criteria_Finder_parallel.pyPurpose: Identify the longest shortest path in each environment and generate route instructions in multiple styles and grammars.
Key Files:
Generate_Route_Instructions_LongestShortestV4.py- Finds LSP paths onlyGenerate_Route_Instructions_LongestShortestV3.py- Finds LSP paths AND generates route instructions
Process:
- Load letter polygons and skeleton networks
- Convert skeleton to NetworkX graph
- Calculate all-pairs shortest path lengths using Dijkstra's algorithm
- Find the pair with maximum shortest path length
- Extract the actual path between origin and destination
- Generate route instructions using
RouteFromPath.py:- Styles: Turn-based, Landmark-based, Hybrid
- Grammars: 4sector, 6sector, 8sector, Klippel
- Instructions use relative directions (turn left, go straight, etc.)
- Landmark references when landmarks are near path edges
- Save instructions to XML format
Route Instruction Generation (RouteFromPath.py):
- Converts path edges to relative turn instructions
- Incorporates landmarks when within proximity threshold
- Supports multiple grammar systems (4/6/8 sector, Klippel)
- Generates step-by-step navigation instructions
Output:
- XML file (
data/RI/Route_Instructions_LongestShortestV*.xml) with structure:<letter name="..."> <route x_origin="..." y_origin="..." x_destination="..." y_destination="..."> <style name="Turn-based|Landmark|Hybrid"> <grammar name="4sector|6sector|8sector|Klippel"> <route_instruction>Go straight. Turn left. ... Arrive at destination.</route_instruction> </grammar> </style> </route> </letter>
- CSV file (
data/RI/Route_Instructions_LongestShortest_length.csv) with path lengths
Usage:
# For path finding only:
python Generate_Route_Instructions_LongestShortestV4.py
# For path finding + instruction generation:
python Generate_Route_Instructions_LongestShortestV3.pyPurpose: Validate route instructions by navigating agents through TextWorld games.
Key Files:
Navigate_Parallel.py- Parallel navigation testingRead_Route_Instructions.py- XML route instruction reader
Process:
- Load route instructions from XML file
- For each letter, route, style, and grammar combination:
- Load or generate the corresponding game file
- Initialize TextWorld environment
- Execute route instructions step-by-step
- Extract final coordinates from game state
- Compare with intended destination
- Mark as Valid/Invalid
- Save results to Excel file
Output: Excel file with columns:
- Letter, Origin_X, Origin_Y, Destination_X, Destination_Y
- Grammar, Valid/Invalid
Usage:
# Edit the XML file path in Navigate_Parallel.py
python Navigate_Parallel.pyEdit dicts.py to modify:
letters- List of letter combinations to processlandmarks_dict- Available landmark typesproblematic- Letters to exclude
Place font files (.ttf) in Fonts/ directory. The system supports multiple fonts:
- perspire.ttf (default)
- Average-Regular.ttf
- Arial variants
- And others
All spatial data uses EPSG:32639 (WGS 84 / UTM zone 39N). Conversion to lat/long (EPSG:4326) is handled automatically for bearing calculations.
Font Files → GeoJSON Environments → TextWorld Games
↓
Complexity Metrics
↓
Route Instructions (XML)
↓
Navigation Validation (Excel)
The data/ directory contains intermediate files organized by letter:
data/
├── RI/ # Route Instructions
│ ├── Route_Instructions_LongestShortestV*.xml
│ └── Route_Instructions_LongestShortest_length.csv
└── [letter]_*.geojson # Per-letter files
├── [letter]_room.geojson # Room polygons
├── [letter]_door.geojson # Door points
├── [letter]_landmark.geojson # Landmark points
├── [letter]_skeleton.geojson # Skeleton network
├── [letter]_graphNodes.geojson # Graph nodes
└── [letter]_graphEdges.geojson # Graph edges
- Turn-based: Uses only directional instructions (turn left, go straight)
- Landmark: Uses landmark references (pass the desk, go toward chair)
- Hybrid: Combines both turn-based and landmark instructions
- 4sector: 4-directional (straight, left, right, around)
- 6sector: 6-directional (adds slight left/right)
- 8sector: 8-directional (adds sharp left/right)
- Klippel: Based on Klippel et al. spatial relations model
-
Parallel Processing: Several scripts use multiprocessing for efficiency:
Complexity_Criteria_Finder_parallel.pyNavigate_Parallel.pycreate_rooms_parallel.py
-
File Naming Convention:
- Letters are identified as
[letter]_[font]_[approach] - Games are named
[letter]_[x_origin]_[y_origin].z8
- Letters are identified as
-
TextWorld Integration: The codebase extends TextWorld with:
- 8-directional navigation (N, S, E, W, NE, NW, SE, SW)
- Relative directions (front, back, left, right, sharp left/right, slight left/right)
- Ego-centric frame of reference
- Indoor space concepts (rooms, areas, doors, landmarks)
-
Excluded Folder: The
TextWorld_WP1/folder contains earlier work and is excluded from this pipeline.
Additional scripts for specific tasks:
dissolv.py- Alternative environment generation scriptmain.py- Simple font glyph extraction examplemain_merge.py- Font glyph extraction with character setcountRooms.py- Room counting utilitiesLettersConnected.py- Letter connectivity analysisComplexity_Criteria_Finder_parallel.py- Also includes functions for:- Joining Excel files (
join_excel()) - Adding agent validation results (
add_agent_grammar_to_excel())
- Joining Excel files (
- Missing Font Files: Ensure all required fonts are in
Fonts/directory - Shapefile Errors: Verify GeoJSON/Shapefile CRS is EPSG:32639
- TextWorld Compilation Errors: Check Inform7 installation and game file paths
- Memory Issues: Reduce parallel processing cores or process letters in batches
If you encounter issues with momepy or osmnx, ensure compatible versions:
pip install momepy==0.6.0 osmnx==1.6.0If you use this codebase, please cite the associated research paper. Arabsheibani, Reza, Stephan Winter, and Martin Tomko. "Automated validation of route instructions in indoor environments." Journal of Spatial Information Science 30 (2025): 25-60.