This repo is built directly on top of the Sketchmapia Microservices framework developed by the Spatial Intelligence Lab (SIL) at the Institute for Geoinformatics (IFGI) in University of Münster.
This feature was developed based on the foundational research presented in:
The GMDA feature is added as an independent Django microservice that lives alongside the
existing SketchMapia services, all orchestrated through docker-compose.
- Geospatial Compatibility: Directly ingests GeoJSON feature collections representing landmarks.
- Advanced Mode Support: Implements the paper's "Advanced Mode" by using 8 peripheral points along the MBR of each landmark instead of the "Basic Mode", which uses a Single Centroid. This accurately captures both the position and the spatial extent/orientation of the drawn landmarks or objects.
-
Robust Angular Math:
It uses the trigonometric summation (np.arctan2) to accurately calculate circular means, gracefully handling the
$0^\circ \equiv 360^\circ$ wrap-around. - Strict 1-to-1 Alignment: Utilizes a Union-Find structure via a "SketchAlign" attribute to group features, filtering for strict 1-to-1 matches to prevent severe distortion of metrics.
Since this method represents each landmark using 8 peripheral points, it generates a massive number of pairwise comparisons. To prevent the peripheral points belonging to the same landmark from being compared to one another, the total number of valid comparisons is strictly calculated.
Let
For Total Target Landmarks (
For Drawn Landmarks (
This service outputs a dictionary containing the following core spatial metrics:
-
Canonical Organization (CanOrg):
Measures the overall spatial organization and topological accuracy (N/S/E/W relationships). It uses the total possible landmark pairs (
$N_{TL}$ ) as the denominator, intentionally penalizing the score for any omitted/forgotten landmarks.
-
Canonical Accuracy (CanAcc):
Isolates the accuracy of the spatial layout from recall completeness. It switches the denominator to the drawn landmark pairs (
$N_{DL}$ ), meaning it does not penalize the user for missing landmarks, only for the placement of the landmarks they did draw.
-
Distance Accuracy (DistAcc):
Calculates the magnitude of distance error between landmark pairs, scale-equalized and normalized to a score between 0 and 1. Let
$dr_{SM}$ and$dr_{TE}$ be the distance ratios (distance divided by max distance) for the sketch map and target environment, respectively.
- Scaling Bias (ScaBias): Tracks the directional expansion or compression of the map by evaluating scale-equalized distance ratios. Positive values indicate expansion, while negative values indicate compression.
-
Angular Accuracy (AngAcc):
Averages the absolute angular deviations (
$ang_{Diff}$ ) between target and drawn landmark pairs. It scales the errors against the maximum possible error ($180^\circ$ ) to produce a normalized score between 0 and 1.
- Rotational Bias (RotBias): Computes the circular mean of angular differences to identify systematic rotational skewing of the entire drawn map compared to the reference. Positive values indicate clockwise rotation, and negative indicate counterclockwise.
The end-to-end flow from loading a project to viewing the GMDA metrics:
- GMDA Calculator (Landmark Based):
Calculates the six GMDA metrics using polygon features (landmarks such as buildings) from the generalized basemap and sketchmap.
How it works?
- In the Analyse modal, checking "Buildings GMDA" (alongside Completeness, and optionally Accuracy) triggers
runAnalysis(), which runs the base analysis first, then automatically sends both maps as GeoJSON to the gmda microservice via a POST request to /gmda/calculateGMDA - The backend extracts all polygon features from both maps, builds 8-point MBRs for each, resolves alignment using the SketchAlign property, and classifies pairs into 1:1, Many:1, and Many:Many groups using Union-Find.
- The six metrics are computed over all valid landmark pairs and returned as JSON.
- Results are then written directly into the Buildings GMDA columns of the main results table.
- Junction based GMDA Calculator:
Calculates the six GMDA metrics using street junction points -- the intersections of road segments -- from both maps.
How it works?
- In the Analyse modal, checking "Junctions GMDA" causes
runAnalysis()to send both maps as GeoJSON to /gmda/calculateJunctionGMDA after the base analysis completes. - The backend detects junctions by finding road endpoints that share the same coordinate (rounded to 3 decimal places) across two or more line segments.
- For the basemap, all junctions are considered for nTL (total landmarks). For the sketchmap, only junctions formed by road IDs shared with the base maps are used.
- Junctions are matched between maps using a topological subset check: a sketch junction matches a base junction if all road IDs at the sketch junction are a subset of the road IDs at the base junction.
- Matched pairs are classified using the same Union-Find grouping as landmarks, and the six metrics are computed and returned, then written into the Junctions GMDA columns of the main results table.
A new Django microservice was added following the same architecture as the existing services (completeness, accuracy, generalizations).
gmda/
├── Dockerfile # runs on port 8005
├── requirements.txt # Django, numpy, shapely
├── manage.py
├── gmda/
│ ├── settings.py
│ ├── urls.py # routes /gmda/ to microservice/urls.py
│ ├── wsgi.py
│ └── asgi.py
└── microservice/
├── urls.py # maps endpoints to views
└── views.py # all GMDA logic lives here
| Endpoint | Method | Description |
|---|---|---|
/gmda/calculateGMDA/ |
POST | Landmark-based GMDA |
/gmda/calculateJunctionGMDA/ |
POST | Junction-based GMDA |
POST /gmda/calculateGMDA/
Content-Type: application/x-www-form-urlencoded
basemapdata=[GeoJSON string]&sketchmapdata=[GeoJSON string]
{
"CanOrg": 0.0962,
"CanAcc": 0.8917,
"ScaBias": -0.0001,
"DistAcc": 0.9358,
"RotBias": -30.2334,
"AngAcc": 0.7942,
"nTL": 14,
"nDL": 5
}| File | Change |
|---|---|
docker-compose.yml |
Added gmda service on port 8005. |
sketchmap_analyser/static/js/project.js |
Added gmda: 8005 to port map; added computeGMDAFromAllGenBaseMap() and computeJunctionGMDAFromAllGenBaseMap(); results are written into genResultArray (including nTL/nDL, and Junc_-prefixed fields for junctions) and rendered via populateGMDAResults() into the main results table; ResultSummary.csv export extended with 12 GMDA columns; added a new GMDADetailedOutput.csv export containing nTL/nDL and all six metrics for both Buildings and Junctions. |
sketchmap_analyser/templates/generalizingmaps.html |
Replaced the standalone GMDA Calculator dropdown with an Analyse modal (#analyseModal) containing checkboxes: Completeness (locked on), Accuracy, Buildings GMDA, Junctions GMDA. |
sketchmap_analyser/templates/results.html |
Merged GMDA metrics into the main results table (#OrderingofMaps) as two grouped column sets ("Buildings GMDA", "Junctions GMDA") with a 2-row <thead>, replacing the separate GMDA Summary panel. Result window enlarged and given a sticky header. |
sketchmap_analyser/static/js/sketchmapeditor.js |
Added openAnalyseModal(), closeAnalyseModal(), and runAnalysis(), which sequences Completeness → Accuracy → Buildings GMDA → Junctions GMDA based on the modal's checkboxes, and toggles hide-accuracy/hide-buildings/hide-junctions classes on the results table to show only the selected columns. |
sketchmap_analyser/static/css/main.css |
Added modal styling (matching the existing menu button theme) and column show/hide rules (.hide-accuracy, .hide-buildings, .hide-junctions) plus sticky header rules for the results table. |
generalizations/generalizations/settings.py |
Fixed CORS configuration. |
- Start all services:
docker-compose up --build
- Open
http://localhost:8000/generalizingmaps/in your browser. - Load a project and click Analyse.
- In the modal, Completeness is always included. Check Accuracy, Buildings GMDA, and/or Junctions GMDA for whichever metrics you also want, then click Run Analysis.
- Results appear as columns in the results table: Completeness/Generalization/Qualitative Accuracy on the left, with Buildings GMDA and Junctions GMDA grouped in their own column sets on the right. Only the columns for metrics you selected are shown; the rest stay hidden.
- Click Download Results to get a zip containing
CompletenessDetailedOutput.csv,ResultSummary.csv(now including all 12 GMDA columns),GeneralizationDetailedOutput.csv,QADetailedOutput.csv, and a newGMDADetailedOutput.csvwithnTL/nDLplus all six metrics for both Buildings and Junctions.
A massive thank you to everyone who helped build the GMDA Calculator!
- Clement Amirault CL-77
- Ajay ajay-sheokand



