, and under Authorized redirect URIs add (for “Sign in without pop-up”).Every analysis below has four parts:
Validation re-runs the app's code, taken unchanged from this page, on seeded test data, and compares it with established reference implementations: PySAL, pylandstats/FRAGSTATS, scikit-learn, jenkspy, scipy, networkx, pvlib and pythermalcomfort. The tables show the latest run. To reproduce it, run tests/validation/validate.py in the source repository.
Validation shows that the app computes each method correctly. It does not show that open data such as OpenStreetMap is complete, or that a screening index predicts outcomes on the ground.
Method. The map view is cut into 1 ha cells (100 m) in the local UTM zone. Buildings come from Google–Microsoft Open Buildings (VIDA PMTiles), counted by centroid, with exact clipped coverage. Streets, land use, green space and points of interest come from OpenStreetMap (OpenFreeMap tiles). The other inputs are:
Calibration. The intensity measures follow the Spacematrix definitions (Berghauser Pont & Haupt 2010):
Floors = height ÷ 3 m, with a minimum of 1.
Limits. How complete OpenStreetMap is varies by city: the summary reports the share of cells with no land-use tag. Footprints from imagery miss some buildings and merge others. Without the optional height layer, FSI and every height-based measure are estimates.
Method. Each cell, and an 800 m window around it, gets:
Calibration of the summary benchmarks:
| Indicator | Threshold | Source |
|---|---|---|
| Street density | ≥ 18 km/km² (streets on ≥ 30% of land) | UN-Habitat (2014), A new strategy of sustainable neighbourhood planning: five principles |
| Intersection density | ≥ 35/km² surrounding area; ≥ 54/km² internal (90 and 140 per sq mi) | LEED v4 for Neighborhood Development, Connected and Open Community |
| Block size | blocks ≤ 150 m (≈ 2.25 ha) | ITDP TOD Standard, "small blocks" |
| Orientation order φ | 1 = perfect grid, 0 = uniform | Boeing (2019), Applied Network Science 4:67. Computed exactly from the app's 18 bins over 180°. |
| Slope classes | 0–8 / 8–15 / 15–25 / 25–40 / > 40%; housing ≤ 15% | Permen PU 20/PRT/M/2007; SNI 03-1733-2004 §4.3 |
The app previously used a "≥ 100 intersections/km²" walkability target. I found no source for it, so it was replaced by the LEED-ND thresholds above.
Validation: slope against numpy.gradient, and the distance transform against scipy.
Limits. Slope from about 30 m terrain tiles, resampled to 100 m cells, smooths out local relief. Street measures count vehicular and service streets; footpaths are reported separately.
Method. Continuous layers use Jenks natural breaks (Fisher's exact optimal partition) or quantiles, with 5 classes. For more than 6,000 cells, the breaks are computed on a random sample of 6,000.
Validation: against jenkspy.
Method. The distance from each cell centre to the nearest destination is measured along the walking network: one multi-source Dijkstra search from all destinations, attached to the nearest street within 100 m, up to 5 km. Before the network is built, straight-line distance is used instead (an exact Euclidean distance transform).
Calibration of the walkshed radii in the summary:
| Destination | Radii | Source |
|---|---|---|
| Transit stop | 400 m · 800 m | SNI 03-1733-2004 §5.2 (ideal walking distance 400 m at 4 km/h); Permen ATR/BPN 16/2017 (TOD 400–800 m) |
| School | 1,000 m · 3,000 m | SNI 03-1733-2004 education table: SD and SLTP 1,000 m, SMU 3,000 m |
| Health | 1,500 m · 3,000 m | SNI 03-1733-2004 health table: puskesmas pembantu, doctor and pharmacy 1,500 m; puskesmas 3,000 m |
| Shops and food | 300 m · 2,000 m | SNI 03-1733-2004 commerce table: toko/warung 300 m, pertokoan 2,000 m |
| Green space | 300 m to ≥ 0.5 ha | WHO Europe (2016), Urban green spaces and health. A 1 ha cell that is ≥ 50% green holds ≥ 0.5 ha. |
Validation: network distances against networkx multi-source Dijkstra, with entrances split onto the street segments.
Limits. Points of interest are OpenStreetMap features. Unmapped facilities read as far away. The SNI radii are planning norms, not observed behaviour.
Method. A port of SNAPy 0.2.14 (Sutjijadi; MIT licence), after the Urban Network Analysis toolbox (Sevtsuk & Mekonnen 2012, Revue Internationale de Géomatique 22(2)).
Calibration. The defaults are SNAPy's own: SearchDist 1,200 m (1,500 m for Straightness), EntDist 100 m, and the distance-decay settings. Networks under 1 km of street are ignored by default: they are isolated OpenStreetMap fragments.
Validation: Reach N and network distance to the nearest destination, against networkx.
Found and fixed by this check: the destination search dropped any destination whose straight-line distance was over 91% of SearchDist, even when the walking distance was within it. On the test network, 26% of origins got a lower Reach count. The bound is now exact (network distance ≥ straight-line distance).
Limits. SNAPy's DetourR multi-path option isn't ported, so movement follows shortest paths only. Betweenness patronage is checked through its building blocks (paths and distances), not against SNAPy's own output.
Method.
Validation: against PySAL esda, and the textbook Gi* formula.
Limits. The permutation p-values are random: cells near p = 0.05 can change class between runs. Gi* in the ratio form PySAL uses is only defined for positive variables; the app's z-score form doesn't change when a constant is added, so the check compares the two on a shifted variable.
Method. Class-level FRAGSTATS metrics on the 1 ha grid, with 8-neighbour patches and edges inside the study area only:
Calibration. "Built" means GSI ≥ 10% (an app convention). "Green" means ≥ 50% green cover, the same 0.5 ha-per-cell rule as the WHO access indicator.
Validation: against pylandstats (FRAGSTATS definitions), and the FRAGSTATS formula for AI.
Found and fixed by this check: SHAPE_MN used the vector formula 0.25 P/√A, which was 1–5% off. It now uses FRAGSTATS' raster form, P ÷ minimum perimeter (McGarigal 2015).
Method.
This follows the multivariate morphometric approach of Fleischmann et al. (2022), and the review by Zhang, Ghosh & Park (2023).
Validation: against scikit-learn PCA and KMeans (20 starts).
Limits. k is your choice. Types are relative to the view being analysed, so the same fabric can be named differently in another city.
Method.
Validation. No external reference exists for this index: it ranks places by closeness to your reference. Read it relatively, not as a probability. The ingredients (standardisation and distance) are simple and deterministic.
Method.
Validation. These are published data products: their accuracy is assessed in those papers. The app only samples and counts them.
Method. A weighted linear combination of fuzzy-standardised criteria with Boolean constraints (Eastman 1999; Malczewski 2006):
Calibration. Each criterion shows its source in the panel.
Validation. No ground truth exists for "best location", so this is a transparent screening tool: change a weight or a constraint and see how robust the candidate sites are. The membership functions and the clustering are deterministic.
Not modelled (from Permenperin 35/2010): distance to the city centre (≥ 10 km), an arterial road, a seaport outlet, a river within 5 km, soil bearing capacity and land price.
Method.
Validation: UTCI and SolarCal against pythermalcomfort, sun position against NREL SPA (pvlib), plus the sanity scenarios.
Wind uses a sheltering and channelling heuristic for 16 directions (wake factor 0.4 up to 3 obstacle heights, recovering by 12; up to +40% in aligned streets). The comfort fraction evaluates every daytime hour with its own weather and wind, and shade from the 21st of the month.
Building heights come from Open Buildings 2.5D when it is loaded, otherwise from an OpenStreetMap height or storey tag (via OpenFreeMap; its 5 m placeholder counts as unknown), otherwise, if you tick it, from GlobalBuildingAtlas (Zhu et al. 2025; CC BY-NC 4.0, non-commercial; estimates that come out low for towers), otherwise 2 storeys. The panel counts each source.
Trees are semi-transparent crowns. Sun through a crown is attenuated by Beer–Lambert (k = 0.25 /m, about 13% passes through 8 m of crown; measured single urban trees are often denser, Konarska et al. 2014). A crown hides 70% of the sky behind it and shelters wind half as much as a building. Ground albedo comes from the default ground, OpenStreetMap roads (asphalt 0.10) and drawn zones (concrete 0.30 to cool paving 0.60). It enters SolarCal's reflected term and scales the sunlit ground's long-wave excess, so bright paving can raise a pedestrian's MRT in full sun while the ground itself stays cooler.
Design options add or remove buildings, plant trees and draw ground zones. Difference maps show option − Existing for UTCI or comfortable hours, matched point by point on the shared grid. CFD or ML wind factors (local ÷ reference speed at 1.5 m, per direction or for all) replace the heuristic at the points they cover.
Validation (Phase 3): checks under a single tree for beam transmittance, SVF and midday UTCI; the albedo map; the two opposite effects of albedo on MRT; and a crown sheltering less than a building (all in tests/microclimate/run.mjs).
Limits. The wind heuristic is not CFD. Wall and ground surface temperatures are approximated. Trees don't cool the air, and leaf density is fixed. Results are indicative: see docs/microclimate.md.
Method. Landmarks are named features with a Wikipedia or Wikidata link, or a heritage tag.
Validation. These are descriptive rules of thumb (app conventions) that depend on how well OpenStreetMap covers the area.