[general]
name=PlanX
email=yusuf.eminoglu@deu.edu.tr
author=Geophilo
qgisMinimumVersion=3.28
description=Urban analytics studio inside QGIS: 84 Processing tools for street networks and space syntax, accessibility, GTFS transit, morphology, microclimate, travel demand, seismic risk and plan reports.
about=PlanX is an urban analytics studio for city planners and researchers. It brings the methods that usually need a stack of separate programs, from space syntax and travel demand to microclimate and seismic risk, into 84 Processing tools in 19 groups. Every tool runs on your own layers, writes ordinary QGIS layers and tables, carries its own icon in the Processing Toolbox and the PlanX Studio dock, and chains in the Model Designer and in batch mode.
    NETWORK ANALYSIS (9): Prepare Network readies a street layer once for every network tool. OD Cost Matrix and OD Routes return network distances and real shortest-path geometries, Service Areas draws isochrones, and Nearest Facility Allocation assigns every demand point to its closest facility along a real route. Dead-End Analysis walks each cul-de-sac back to its junction and measures the whole branch, with dead-end ratios by node count and by network length. Link Criticality ranks the street segments whose loss most raises travel cost or cuts off demand, and Network Robustness finds bridges, draws percolation curves under random failure and under a recalculated betweenness attack, and reports global efficiency.
    CENTRALITY AND SPACE SYNTAX (2): Segment angular analysis with integration, choice and the normalised NACH and NAIN at any radius, and the centrality family: degree, closeness, straightness, eigenvector and betweenness.
    URBAN MORPHOLOGY (4): Building form metrics, morphological tessellation, Spacematrix density (GSI, FSI, OSR and L) and street network morphology including orientation entropy.
    ACCESSIBILITY (2): Multi-amenity 15-minute-city scores with population-weighted summaries, and gravity accessibility as cumulative opportunities, Hansen potential and two-step floating catchment area over six distance-decay functions.
    TRANSIT (4): GTFS import with clear validation errors and per-day stop and route service statistics; stop frequency and headway maps for any time window; door-to-door transit travel times that walk to a stop on the street network, ride a RAPTOR-style timetable with transfers and walk to the destination, always compared with walking all the way; and Transport for London PTAL bands.
    WALKABILITY (4): Walkability Audit scores every street segment from 0 to 100 using intersection density, land-use mix entropy, destinations, block length and slope, each with editable breakpoints and weights. Pedestrian Route Quality routes over quality-weighted streets and reports the detour ratio and the share of the walk on low-scoring segments. Walking Slope Comfort profiles gradients with Tobler walking times, and Street Environment Comfort builds kernel densities of street assets and barriers.
    CYCLING (2): Level of Traffic Stress 1 to 4 from speed, lanes, traffic volume and infrastructure with editable thresholds, plus low-stress connectivity islands and the population each island can reach.
    EQUITY (3): Population-weighted Gini, a Theil index split into between-group and within-group inequality, the P90/P10 ratio and the access-poverty share; Lorenz and concentration curves with the Atkinson index at a chosen inequality aversion; and demographic cross-tabs that report each subgroup's share among the worst and best served, with Duncan dissimilarity.
    GREEN INFRASTRUCTURE (4): Park-hierarchy access that tests minimum-size-within-maximum-distance standards on real network distances, patch connectivity with the Probability of Connectivity index and each patch's dPC importance, FRAGSTATS-style landscape metrics, and least-cost corridors over a resistance raster.
    MICROCLIMATE (10): Shadow casting for any date and time with an embedded NOAA solar-position model, whole-day sun hours, clear-sky daily irradiation that combines shadow-aware direct light with diffuse light weighted by sky view, annual solar potential in kWh/m² with an optional monthly raster, sky view factor, frontal area index, a heat-island risk grid from buildings, green and water, RLS-90-style road noise with population exposure bands, road emissions, and air-quality dispersion screening.
    VISIBILITY (3): DSM viewsheds with observer and target heights, isovist fields that sample Benedikt's area, radials, circularity and occlusivity between buildings, and landmark visual exposure for skyline and heritage screening.
    PLAN STANDARDS AND QA (3): Land-use balance against configurable per-capita standards, facility adequacy that combines capacity with network distance, and dasymetric density grids.
    POPULATION AND HOUSING (5): Cohort-component projection as a Leslie matrix with survival, fertility and migration read from table fields; housing needs with vacancy allowance, replacement losses and backlog; residential capacity that turns each parcel's remaining floor area into whole dwellings; allocation of population growth to newly developed land; and area-weighted or dasymetric interpolation between zone systems.
    OPTIMIZATION (5): Maximal coverage and Teitz-Bart p-median facility siting with candidate screening and existing facilities, capacity-respecting allocation that spills to the next facility when one is full, capacitated facility siting, a multi-objective land-use allocation optimiser with compactness, adjacency and contiguity, and a land-use Pareto front that reports the suitability-versus-compactness trade-off and its knee.
    URBAN GROWTH (3): Land-cover transition matrices with gains, losses and persistence in hectares, a deterministic constrained cellular-automaton growth simulation in the SLEUTH tradition (same seed, same map) writing a year-of-conversion raster, and sprawl metrics built around the SDG 11.3.1 land-consumption-to-population-growth ratio.
    TRAVEL DEMAND (7): Trip generation from rate tables, doubly constrained gravity distribution with exponential or power deterrence calibrated to an observed mean trip cost, multinomial logit mode split, jobs-housing balance with commute-shed ratios and dissimilarity, user-equilibrium traffic assignment with BPR volume-delay functions solved by conjugate Frank-Wolfe with the relative gap reported at every iteration, and a parking balance that estimates demand from per-category rates and compares it with a counted inventory, separating a real deficit from a coverage gap.
    HAZARD SCREENING (3): Priority-flood DEM filling and D8 flow accumulation, height-above-nearest-drainage (HAND) inundation mapping, and flood exposure of buildings and population.
    SEISMIC RISK (5): Ground Motion Scenario runs the Akkar-Sandıkkaya-Bommer 2014 model, one of the four in the logic tree of Turkey's 2018 national seismic hazard map, from a point source or a fault trace, giving peak ground acceleration, peak ground velocity and any spectral period at every receiver; rows outside the model's published range are flagged instead of extrapolated. Seismic Collapse and Debris Spread turns the shaking into a Hazus damage distribution for every building, debris volumes, blocked streets, open evacuation corridors and the navigable core for a minimum vehicle width, with optional multi-seed runs. Seismic Human Impact carries that damage into the Hazus casualty and shelter models, with occupancy and time-of-day population shares. Liquefaction Screening (Zhu et al. 2015 or the Hazus susceptibility model) and Coseismic Landslide Screening (Newmark displacement after Jibson 2007) answer the two ground-failure questions, and each refuses inputs its published tables do not cover.
    REPORTING AND DASHBOARD (7): Scenario snapshots, A/B comparison in which every metric knows which direction is better, weighted multi-scenario ranking, a LUTI-lite pipeline that chains growth, population allocation and re-evaluation, a Batch Plan Auditor that runs the core analyses from a plan's main layers in one call, a one-click single-file HTML Plan Dashboard and Performance Report, and a demo city for trying every tool in minutes. The PlanX Studio dock shows live score cards and a Plan Performance Index history.
    Everything is computed by the plugin's own engine on the Python that ships with QGIS; SciPy speeds up some tools when it is present.
    Manual: https://geophilo.com/planx/manual.html
version=4.22.2
tracker=https://gitlab.com/geophilo1/planx/-/issues
repository=https://gitlab.com/geophilo1/planx

category=Vector
tags=planx,areal interpolation,dasymetric,jobs housing balance,landscape metrics,fragstats,least cost path,corridor,traffic assignment,user equilibrium,frank-wolfe,ptal,2sfca,gravity accessibility,percolation,space syntax,centrality,betweenness,urban morphology,spacematrix,tessellation,accessibility,15 minute city,isochrone,service area,od matrix,network analysis,cycling,lts,bicycle,low stress connectivity,equity,gini,theil,environmental justice,shadow,sun hours,solar,sky view factor,heat island,microclimate,air quality,emissions,flood,hand,hazard,hydrology,travel demand,trip generation,gravity model,mode split,parking,parking demand,supply balance,luti,scenario pipeline,population allocation,dashboard,report,location allocation,p-median,capacity,land use allocation,suitability,zoning,compactness,adjacency,multi-objective,urban planning,processing,scenario ranking,od routes,shortest path,slope,walking comfort,kernel density,link criticality,network robustness,vulnerability,resilience,geophilo
homepage=https://geophilo.com/planx/
icon=icons/icon.png
experimental=False
deprecated=False
qgisMaximumVersion=4.99
hasProcessingProvider=yes
plugin_dependencies=
license=GPL-3.0-or-later
changelog=
    4.22.2 - Hub listing text rewritten; author Geophilo; university affiliation removed; documentation links use the standard geophilo.com pages (manual.html, guide/); manual HTML no longer ships in the plugin package.
    4.22.1 - English only: the landslide citation now gives its journal under its English title (Pamukkale University Journal of Engineering Sciences) instead of the Turkish one, and the reference manual no longer quotes the Turkish name of the Spatial Plans Regulation. THIRD_PARTY_NOTICES.md credited the article to M. E. Yigit; the author is Adil Yigit, as the record under its DOI states. The practical guide's link to the reference manual no longer returns a 404.
    4.22.0 - Areal Interpolation moves counts and rates between incompatible zone systems - census tracts to plan zones or a hexagon grid - splitting counts by area with the total preserved, averaging rates rather than splitting them, optionally dasymetric over residential land, with the mass balance printed. Jobs-Housing Balance gives every zone its local and commute-shed ratio of jobs to workers on the street network, a balance index, and the area-wide dissimilarity between jobs and workers.
    4.21.0 - Two landscape-ecology tools in Green Infrastructure. Landscape Metrics reports the FRAGSTATS class and landscape families - area, patches, edge, shape, core area, the aggregation index, contagion and Shannon and Simpson diversity - in ground units on any projected categorical raster. Least-Cost Corridor spreads accumulated cost over a resistance raster between two habitat sets and returns the cost surface, the least-cost path with its effective resistance and the normalised corridor of near-optimal routes.
    4.20.0 - Four new tools and a closed four-step model. Traffic Assignment loads the Gravity Distribution OD table onto the street network and solves Wardrop's user equilibrium with BPR volume-delay functions (conjugate Frank-Wolfe by default, Frank-Wolfe, MSA or all-or-nothing), reporting volume, v/c, LOS, congested time and delay per street and the relative gap of every iteration. Gravity Accessibility counts opportunities with cumulative, Hansen and two-step floating catchment area measures over six decay functions. PTAL rates every place 0 to 6b by the public transport service within walking distance, with Transport for London's method, from any GTFS feed. Network Robustness finds the bridges, traces percolation under random failure and a recalculated betweenness attack, and measures global efficiency. Gravity Distribution can calibrate beta to an observed mean trip cost and no longer sends trips between disconnected zones under power deterrence. The access score and transit access walk in ground metres. Space Syntax reports intelligibility and synergy. The default renderer no longer repeats class limits, and eighteen stray build markers were removed from the manual.
    4.19.0 - New tool: Dead-End Analysis, the first Network Analysis tool that measures a cul-de-sac as a street rather than as a node. A dead end is a chain - the whole roadway from the junction out to the turning head, which is the length a resident has to drive twice before reaching a through route - and counting degree-1 nodes sees the tip and misses the street: on the tool's own fixture a 100 m cul-de-sac drawn as two 50 m segments is one node and two segments. Every segment of the network now comes back tagged with branch_id, depth (how many segments you drive to the junction), branch_length_m, branch_segments and anchor_node, so cul-de-sacs can be styled, ranked and measured as whole streets; a dead-end point layer carries one point per degree-1 node with the branch it belongs to; and a seventeen-row summary answers "how much of this network is dead end" both ways, because the two answers differ - deadend_node_ratio counts junctions that are dead ends, deadend_length_ratio measures the share of the network's length that is dead-end branch, and the length ratio usually exceeds the node ratio because a cul-de-sac street is longer than the junction it ends at. A minimum-branch parameter flags sub-threshold branches as stubs without dropping them from the result, because sub-metre cul-de-sacs are almost always digitising gaps rather than streets, and both ratios are repeated with the stubs excluded rather than letting them silently inflate the headline. Every length is ground metres through the same helper as the rest of the toolset, a disconnected network is warned about, and a degree-1 node the walk fails to place on a branch raises rather than being reported as "not a dead end". Also in this version: correlated damage sampling in the seismic debris tool, so that a simulation run no longer draws every building independently (a real earthquake shakes neighbours together, and independent draws made the city-wide damage band far too narrow; the new default shares the demand part of each fragility's variability, with between-event and fully-correlated modes beside it), and a resolution warning in Liquefaction Screening, which was feeding any DEM's wetness index to a model calibrated at about 1 km without saying so.
    4.18.1 - Fixed file outputs (GeoPackage, Shapefile) arriving without renderer, readable field names or provenance on 61 of 72 algorithms. Updated plugin icon.
    4.18.0 - Ground units across the toolset. A layer's geometry().area() returns the layer's own coordinate units, and two separate errors hide in that: the unit may not be the metre (a US state-plane layer is in survey feet, so a 100-unit square is 929.041 m2 of ground while the layer reports 10000), and a conformal projection carries its own scale factor (EPSG:3857 at 41 N reports 400 for a 20-unit box that is 227.835 m2 of ground). Thirteen algorithms were publishing one of those numbers under a metre's name, in columns called area_m2, km2, m2, per-hectare and metres of length. Every one of them now measures on the ground through one helper, and every one of them is checked by a test that can actually fail: the same city is run a second time translated to 41 N, where a map unit is 0.7547 of a ground metre and nothing else about the run changes, so a ground area must move by cos-squared, a length by cos, a per-ground-area count by the inverse - and a column still in the layer's own units reads identically in both runs. A ratio of two quantities in one layer's units was left alone, because the error cancels in it. Two things deliberately did not change: planx:preparenetwork's length_m and the network family's cost columns stay in the source CRS, because that unit is documented and every break, isochrone and cost downstream reads it; and the parameters whose own labels say map units - a walking radius, a grid cell size, a noise cutoff, an extent - stay in map units, because they are also what gates the counts and the tessellation around them. The physical quantities compared against published planning thresholds moved onto the ground. No algorithm, input or output schema changed.
    4.17.0 - New tool: Coseismic Landslide Screening, the third ground-failure question. Ground motion says how hard the ground shakes, liquefaction asks whether saturated soil loses its strength, and neither asks whether the hillside itself moves. An earthquake triggers landslides on slopes that were stable before it, and in a hilly city they are a large share of the physical damage: severed roads, blocked valleys, and slopes that stay unstable for months after the shaking stops. This tool answers it with the Newmark sliding-block displacement, in the disposable-parameter form of Jibson (2007) Equation 7, and its output is a distance in centimetres - the only quantity in this group that is a length rather than a probability or a volume.
        - The critical acceleration is the whole problem, and a city almost never holds it. Three routes supply it and the tool makes you choose: a field of your own in g, the Hazus 6.1 Section 4.2.2.2 geologic-group chain from the group letter and the groundwater state, or a susceptibility map somebody else already classified I to X. Every row records which route it took in ac_src, because the same 0.25 g is a measurement, a table lookup off a geological map, and a table lookup off somebody else's susceptibility map, and the three say different things about the ground.
        - The route has no default. A run that leaves it unset stops with an explicit message rather than picking one, and the same is true of the groundwater state on the Hazus route: dry and wet are up to four susceptibility categories apart at one slope and group - a factor of eight in the acceleration - and a third of Table 4-14's cells change between them.
        - The DEM is required on every route, including the ones that do not use the slope to pick the acceleration. The slope angle is part of reading the answer whatever route produced it, and a feature whose sample point falls off the DEM or on a nodata cell stops the run instead of being skipped, because a missing terrain input is not a missing hazard.
        - Jibson Equation 7, transcribed rather than recalled. The paper is paywalled and was not read; its coefficients were read from an open-access reproduction that prints them beside its own refit of the same data - coefficients that differ (1.3593 against 2.335), which is what makes the source usable as a transcription and not just a citation. The equation number is not taken from that reproduction, which numbers the paper's equations by its own scheme; it is taken from the paper's numbering as an independent implementation cites it. The ratio exponents, the -2.71 intercept, the 0.424 magnitude term and the 0.454 log10 dispersion are asserted in the engine tests against those printed values.
        - Jibson Equation 10 and the Arias-intensity regression of Jibson, Harp and Michael (1998) are deliberately not implemented, and the manual says why: both are Arias forms, and Arias intensity is the total energy the shaking deposits, which Ground Motion Scenario does not produce and no other tool in the plugin does either. Deriving one would mean a ground-motion model of its own. Equation 7 is the only regression in the paper that takes exactly the critical-acceleration ratio and the magnitude, with nothing to import from outside the chain.
        - The two failure cases are reported as what they are rather than clipped into silence. Where the critical acceleration meets or exceeds the shaking the block does not move, the displacement is a genuine zero, and the row notes say so. Where the ratio falls below 0.05 the number is an extrapolation and the row says that instead - the value is reported as the equation gives it and is not floored or clipped.
        - A zero critical acceleration is refused, not substituted. The (ac/amax) to the -1.478 term diverges as the ratio goes to zero, because a material with no strength to mobilise is not a slope with a displacement, it is a flow - and a flow is the liquefaction question, not this one. That refusal is in the engine and in a test, not just in the documentation.
        - Below Table 4-15's slope bound Hazus establishes no susceptibility deposit at all, and the tool reports an EMPTY critical acceleration rather than a zero. The distinction is load-bearing: zero is the value Equation 7 diverges on, so a zeroed row would be the model's loudest answer arriving disguised as its safest. The run log counts those rows separately, so a map of nowhere-slides cannot be read as a map of stable slopes.
        - Table 4-15's acceleration bound is applied as a floor on the Table 4-16 category value, and across the whole three-group by two-moisture by six-band table it changes exactly one cell: group B, wet, above 40 degrees. Which cell conflicts is asserted in the test suite rather than assumed, and every row the floor touches says so in its notes.
        - Table 4-17's area fraction is reported in its own column and never multiplied into the displacement. The displacement is a property of the sliding block and the fraction is a property of the map unit; folding them together would produce a number that is neither.
        - The susceptibility-category route accepts Roman numerals only. A numeric column would not say whether 1 meant the least susceptible, as Hazus counts it, or the most, and guessing that wrong reverses the map while leaving every count and every schema check green. Digits are refused with the list of values found.
        - Slope is one D8 steepest-descent gradient sampled at one point per feature, with the pixel left in the DEM's own CRS units. A slope is a ratio of a vertical to a horizontal difference, and converting one of the two alone would rescale every slope on a DEM whose elevations are in feet; the run log states the assumption instead of hiding it. The point sample is a real limit and the manual says so: a parcel whose point-on-surface lands on the flat bench above a scarp will read as not susceptible while the scarp itself is the hazard.
        - Output is one feature per input feature with geometry and attributes preserved, carrying the median displacement, its 90th percentile, the log displacement, the critical acceleration, the route, the ratio the equation actually turns on, the category, the area fraction, and the shaking, magnitude and slope the row was evaluated at - so any row can be re-derived from the file it is in.
        - Documented as screening, not design. It is a United States calibration, UNCALIBRATED for Turkish geology, with no pore-pressure ratio, no duration term, no topographic amplification of the shaking, no lateral spread, no runout, and no fragility relationship between a displacement and a damage state. It ranks and it prioritises; it does not predict an address, and a zero is not a certificate that a slope is stable.
        - Gate floors moved to 75 algorithms (smoke_provider_catalog.py, qgis_runtime_algorithm_matrix.py, tests/smoke_plugin.py). The runtime matrix grew a value check that re-derives every output row - slope from the synthetic surface's own closed form, the Hazus chain from the tool's parameters, the displacement from the engine - so the three routes are checked against the wiring they claim, not against a snapshot of themselves; two mutations of that wiring were each caught before this shipped.
    4.16.0 - New tool: Liquefaction Screening, the ground-failure question the seismic chain never asked. Ground motion says how hard the ground shakes, and the debris and casualty tools say what that does to buildings. Neither asks whether the ground itself fails: saturated sand loses its strength during shaking and the soil behaves as a liquid, which is a different hazard from shaking, on a different scale, and not correlated with building age the way collapse is. Two published models answer it from two different sets of inputs behind one interface.
        - Regression mode - Zhu, Daley, Baise, Thompson, Wald and Knudsen (2015), Earthquake Spectra 31(3), 1813-1837, Table 3. A logistic regression on shaking, topographic wetness and shear-wave velocity. It needs a DEM and a shaking level and nothing else: the wetness index and the slope come out of one D8 pass on the DEM, and Vs30 comes from the slope through the piecewise table of USGS Open-File Report 2007-1357 (Allen and Wald 2007).
        - The magnitude term sits INSIDE the logarithm, not beside it: the log of PGA times Mw raised to 2.56, weighted by 2.067. The form that writes 2.56 times the log of magnitude as its own additive term scales magnitude by one instead of 2.067, and it looks perfectly plausible in a result table - a 5.29 against a 2.56 sensitivity. That identity is asserted in the tests rather than trusted.
        - ShakeMap accelerations are published in percent g, and the source expression carries a division by 100 to match. This tool's field is in g already, so the division is not applied - and the log reports the clip ceiling as 2.7 g, the source's own ceiling restated in the unit the parameter actually takes, rather than the 270 the paper prints.
        - Site velocity: a Vs30 field wins, then a Vs30 raster, then a constant, then the slope estimate, and every row says in vs30_src which of the four it took. Where the slope falls outside the published nodes the velocity is held at the table's own endpoint and the run reports how many rows were clamped, rather than extrapolating a curve nobody published.
        - Tectonic setting has NO default. Topographic slope maps to a different velocity on an active margin than on a stable continent: at one slope the two columns of the source table differ by a factor of 1.96 in velocity, which the velocity coefficient turns into 3.2 logit units. The tool refuses to choose, and the log says which column was used and whether it changed any row's answer at all.
        - Wetness index: the DEM's pixel size is read in metres whatever the DEM's own linear unit is. The index is the log of a metric area, so a DEM in feet inflates it by ln(3.281) = 1.19 everywhere - 0.42 logit units of pure unit error with no visible symptom in the result. The same defect class as 4.15.1's raw-geometry areas, and fixed here before it shipped rather than after. A flat or ponded cell has no downslope neighbour at all, so its index is genuinely infinite and the model's own ceiling of 15 is what evaluates it; the run counts and reports those rows separately from a cell that is off the grid or on nodata, which stops the run instead - a missing terrain input is not a missing hazard.
        - Susceptibility mode - Hazus 6.1 Earthquake Model Technical Manual, Section 4.2.2.1, Equations 4-9 to 4-11 and Tables 4-10 to 4-13, transcribed from the manual. It reads a polygon layer of map units somebody has already classified Very High, High, Moderate, Low, Very Low or None, and gives each unit the probability and the expected settlement in inches. Both published correction polynomials are applied exactly as printed, reference-value residual and all: K_M at Mw 7.5 comes out 1.0147 and K_W at the 5 ft reference depth 1.04 rather than 1.0, and renormalising them would move every number in the tool about 5 percent away from the published method to fix a cosmetic inconsistency in the source.
        - Susceptibility mode REFUSES to run without a classified layer, and refuses a category it does not recognise, listing the values it found instead. Hazus itself assumes no ground failure when it has no input, and an empty map of nowhere-liquefies is the most dangerous answer this family of tools can give: an unrecognised category read as zero would report "no liquefaction hazard" for a unit nobody ever classified. Case and separators are ignored, so "very high" is accepted; "VH" and "1" are not.
        - Groundwater depth is a parameter, in metres, because Hazus Equation 4-11 takes feet and a metres value passed through it is a 7 percent error that no result table shows. The default 1.524 m is the manual's own 5 ft reference depth, and the conversion happens once in the engine rather than at each call site.
        - Shaking is a constant PGA in g or a PGA field, and a field wins. A row with an empty or zero PGA stops the run rather than being substituted: the model takes the logarithm of it, and there is no reference shaking level the way there is a reference velocity, so there is nothing honest to fall back to. Ground Motion Scenario writes exactly that field, so the chain runs without leaving QGIS.
        - Output is one feature per input feature with geometry and attributes preserved, carrying the probability, the separate 0.81 proportion-of-area reading, the Hazus conditional probability with both correction factors, the settlement, and the PGA, magnitude, wetness index, slope and Vs30 the row was actually evaluated at - so any row can be re-derived from the file it is in. A notes column carries the clips, the clamping and the below-threshold warning per row, and the run log summarises them with the counts.
        - Both modes share one output schema, with the columns a mode does not compute left empty, rather than a schema that changes shape with a combo box: a saved Processing model that reads a column keeps working when the mode changes, and a model that reads a column that is empty can see that it is empty, which a missing column cannot tell it.
        - Documented as screening, not design. Both models are United States calibrations and no Turkish liquefaction inventory was used to fit or to check them. The Hazus categories describe United States regional geology, so a Turkish map unit inherits whatever class somebody assigned it, which is the weakest link in that mode. The tool ranks places against each other; it does not predict an address, and it is not a substitute for a geotechnical investigation or a code check.
    4.15.1 - Unit fix: three tools reported areas and lengths in the layer's own coordinate units while documenting them as metres. No algorithm added or removed, no parameter changed, no output column renamed - the values that move are the ones that were wrong.
        - Seismic Collapse and Debris Spread: footprint_area, debris_vol_m3, debris_pile_m3 and debris_mass_t are ground metres on the layer's ellipsoid now, not the layer's own square units. TWO SEPARATE THINGS break that assumption. The coordinate unit is not always the metre - on a California state-plane layer in US survey feet a 100-unit square is 929.041 square metres of ground and 10000 in the layer's own units. And a conformal projection carries its own scale factor - EPSG:3857 is a metre CRS, but its units are metres only at the equator, so at 41 degrees north a 20-unit box is 227.835 square metres of ground against 400 square units in the layer. That is the 1.76x recorded as an open defect in 4.15.0, in a metre CRS. Both scale a plausible number by a constant, which is why neither reads as an error in a result table. The debris radius does not move: it is driven by height alone.
        - Street widths inside the same tool are metres now too - the debris envelopes, the reach along the street axis, the region-of-interest hull and the morphological opening behind the Navigable core output, where the minimum clear width is a metre threshold by definition. On a foot layer a 5 metre road was being cleared by a 5 foot envelope.
        - Street Network Morphology: total_length_km, avg_segment_length_m and intersection_density_km2 divided raw network and hull units by 1000 and 1e6. On a foot layer those figures were wrong by 3.28 and 10.8; on EPSG:3857 at 41 degrees north by 1.33 in length and 1.76 in area, on a metre layer that gave no sign of it. This is the defect carried from 4.14.0, fixed in the release that changes reported values and says so.
        - Seismic Human Impact: the footprint read from the geometry - the fallback used when the building layer carries no footprint column - was raw, so the occupant count and everything downstream of it inherited the error.
        - New module planx/algorithms/_units.py holds GroundUnits: one QgsDistanceArea bound to the layer's CRS and ellipsoid, exposing area in square metres, length in metres, layer units per ground metre and the ground scale at an extent centre. Both error classes are the same question - how long is a layer unit on the ground here - so one mechanism answers both.
        - The runtime matrix could not see this class and still cannot: its fixture city is generated at the origin of EPSG:3857, the one place on that grid where the scale factor is exactly 1, so 73 cases ran green over a defect any real city would show. The smoke test now checks the helper itself, against expectations written out from the CRS definitions rather than read back from the code - a 20-unit box at 41 degrees north, a 100-foot square at Los Angeles with its reciprocal, and a 1000 metre square in UTM 35N that must stay near a million square metres rather than be corrected away.
        - The same class is still live in about a dozen other tools that write an area or a km2 column from raw geometry: building metrics, green connectivity, land-use balance, residential capacity, Spacematrix, tessellation, density grid, growth simulation, land-cover change, sprawl metrics and walkability among them. They are deliberately not touched here. It is a wide pass that changes reported values in most of the plugin's analytical tools, and it deserves its own release rather than a footnote to this one.
        - Test infrastructure: the runtime matrix now checks the debris identity feature by feature - debris_vol_m3 must equal footprint_area times height times the solid ratio times the released fraction of the damage state - which is the check that breaks first if the reported area and the area the volume was built from ever stop being the same number. These checks read their output with sqlite3, never with a QgsVectorLayer: on Windows a file held open by a QGIS datasource cannot be replaced, and the matrix's second runs re-create the destinations the first run wrote.
        - Test infrastructure: the smoke test no longer hangs, and the cause was the QGIS profile rather than the teardown the first reading pointed at. Run by hand it printed its verdict and then never returned; the same module under the verify command finished normally. Both give QgsApplication a throwaway profile of their own, but only the verify command also sets QGIS_CUSTOM_CONFIG_PATH, so the block is inside QGIS's own shutdown path in the real user profile and a profile folder passed to the constructor does not avoid it. It now exits through os._exit from the frame that still holds the application, as the runtime matrix already did, which short-circuits shutdown on either environment; the failure path exits 1 with its traceback and no hang. The other half of the hazard, exitQgis blocking once a provider is loaded, stays guarded as the matrix guards it.
    4.15.0 - New tool: Seismic Human Impact (Casualties and Shelter), the end of the seismic chain. The two existing tools stop at physics - how hard the ground shakes, and what the shaking does to buildings and streets. Nothing in the plugin said who gets hurt. This tool reads the damage distribution the debris tool writes and carries it into the two Hazus models that end in people: Section 12 for casualties and Section 13 for displacement and shelter.
        - Casualties from the whole damage distribution, not from collapse alone. Hazus's event tree is implemented as the manual writes it: every damage state contributes its own four injury rates, and the Complete state is the only one that splits, into complete-but-standing and collapsed, by the Table 12-8 collapse probability. That split is where almost all the deaths come from - for a C1L frame the collapsed branch's severity-4 rate is 10 per occupant against 0.01 for the intact branch - so a model without it would report Complete damage as nearly harmless.
        - Four severities, in Hazus's own order: treatable injuries, injuries needing hospitalisation, life-threatening injuries, and instant deaths. People outside and close to the building are counted separately on the manual's outdoor tables, which drop the slight-damage branch and do not split on collapse, because falling parapets and glazing hurt people on the pavement whether or not the floors came down.
        - WHO IS IN THE BUILDING is a parameter, not an afterthought. Hazus Table 12-2 gives the indoor and outdoor share of each occupancy class at 2 a.m., 2 p.m. and 5 p.m., and those shares decide the result: a residential building is 98.9 percent occupied at 2 a.m. and 52.5 percent at 2 p.m.; a school is empty at 2 a.m.; a hotel is a fifth full at 2 p.m. A nighttime earthquake and a daytime one are two runs of this tool, and the recommendation is to do both.
        - Occupants come from a population field, or - when there is none - from footprint area times storeys divided by an area per occupant. That divisor is stated as this tool's own screening assumption rather than a Hazus figure, and the run log says which source was used. A dwelling-unit field drives the shelter equations when the building layer has one; without it a residential building counts as one dwelling.
        - The footprint comes from the building geometry, or from a column when the buildings are points. Point buildings have no area, and the debris tool upstream writes points, so a footprint field is read instead - named on the new Footprint area field parameter, or found automatically. Seismic Collapse and Debris Spread now writes that column, so the chain runs with nothing to configure. With no footprint anywhere the tool stops and says so, rather than report a city of nobody; when only some buildings lack one it warns with the count.
        - Shelter: Hazus Equations 13-1 to 13-5 with Table 13-1's single-family and multi-family weights, giving unhoused households and then the number of people who will seek PUBLICLY PROVIDED shelter. The demographic filter is implemented in full, with the Table 13-2 category weights and four modifiers that default to 1.0. That default is deliberate and is stated everywhere it matters: at neutral the filter changes nothing, alpha is exactly 1.0, and the answer is an UPPER BOUND in which every displaced person seeks public shelter. Hazus's own Table 13-3 factors run from 0.13 to 0.62, so a real estimate sits well below the default - enter a share-weighted mean for any category you have distribution data for, and label the figure an upper bound if you have none.
        - If the four damage probability columns are absent and no damage-state column is named, the tool stops with an explicit message rather than returning zeros, because a zero casualty count is indistinguishable from a good outcome. A single damage-state column is accepted as a fallback, and the run log says that it discards the distribution.
        - Output is one feature per building with the geometry and every input attribute preserved, so the result joins straight back to the damage and debris layers, plus occupancy class, resolved Hazus type, occupant count, the four severity counts, their total, unhoused households and public shelter need. The default renderer colours by the casualty total.
        - Seismic Collapse and Debris Spread gained one output column, footprint_area, so the building footprint survives onto its point output for the casualties tool to read back. It carries no renderer token, so the default renderer still colours by collapse probability.
        - Documented as orders of magnitude, not counts: the rates are fitted to United States earthquakes and the shelter factors to United States Red Cross shelter data, and the damage distribution arrives with the uncalibrated-to-Turkish-stock caveat the debris tool already carries. Bridges and the population in the street away from any building are left out rather than approximated.
    4.14.0 - New tool: Ground Motion Scenario, the first half of the seismic chain. Seismic debris could always be driven from a joined PGA field, but nothing in the plugin produced one - the only way to feed it was a ShakeMap or an AFAD raster from outside QGIS, or the tool's own magnitude guess, which has no distance, site or fault term. This tool closes that gap with Akkar, Sandikkaya and Bommer (2014), one of the four ground-motion models in the logic tree of Turkey's 2018 national seismic hazard map, using the authors' own published coefficients.
        - Scenario geometry: A, a point source with an epicentre and a focal depth, which is the only geometry where a hypocentral distance means anything; or B, an extended rupture as a fault trace, where the model's Joyner-Boore term is measured to the trace. A point source has no rupture surface, so its Joyner-Boore and epicentral distances are the same number, and an extended rupture has no single hypocentre, so only Joyner-Boore is offered - the tool says which distances it can support for the geometry you chose instead of inventing the missing one.
        - Output: peak ground acceleration, peak ground velocity and any spectral periods you name, at every receiver, keeping the receiver's own geometry and attributes so the result drops straight back onto the layer you asked about. A distance metric parameter chooses Joyner-Boore, epicentral or hypocentral distance and the choice is written to every row, so a joined result can never be read as the wrong distance.
        - Distances are measured in kilometres whatever the receiver layer's projection uses: the CRS's own linear unit is read off the layer and converted, so a metres-based grid and a feet-based one give the same answer. A fault trace is reprojected into the receivers' CRS before it is measured, so a trace supplied in a different projection is not silently mixed in.
        - Fault mechanism (strike-slip, normal, reverse) and epsilon, the number of standard deviations above or below the median, which is how a scenario is pinned to a rarer level than the median.
        - Site: Vs30 as a constant or from a field, defaulting to 750 m/s, the model's own reference velocity where its site term is exactly zero - so the default run reports rock-reference motion and any soil amplification in the result is a choice the user made. Receivers whose Vs30 field is empty fall back to the constant and are flagged in the output, and the value actually used is written to a vs30 column. Above the model's 1000 m/s ceiling Vs30 is capped and the row says so.
        - Spectral periods are named in seconds and the model is not interpolated between them: a period the paper does not tabulate is refused with the nearest published ones listed, because an interpolated value would be one no source supports.
        - Every row carries a caveat column naming the applicability limits it breaks - magnitude, distance, depth or site outside the range the coefficients were fitted for - and the run log repeats them as warnings. The number is still computed and still shown; the point is that it is labelled rather than silently extrapolated.
        - The help text and manual repeat throughout that these are median values from a shallow-crustal model for Europe and the Middle East, not design levels, not a code check and not a substitute for the national hazard map, and that the model carries no basin term and no directivity.
    4.13.0 - Seismic debris rebuilt on the Hazus fragility curves. The tool's damage model was a binary collapse flag driven by construction year, and above about Mw 7.2 that flag saturated: every pre-2000 building came out certain to collapse, so the model carried no information for the most vulnerable stock at the magnitudes a Marmara scenario actually occupies. It now gives each building a full damage distribution (none, slight, moderate, extensive, complete) from lognormal fragility curves, using the equivalent-PGA structural medians of the Hazus 6.1 Technical Manual, Tables 5-37 to 5-40, one row per building type and seismic design level, with the manual's uniform dispersion of 0.64. Probabilities now rise smoothly and separately with magnitude.
        - New optional PGA field: point the tool at a peak-ground-acceleration column (a ShakeMap, USGS or AFAD raster joined to the footprints) and fragility is driven by real site shaking, with distance and site effects included. Without it the magnitude path still works, through the same curves, and the run log says plainly that this path has no distance, site or fault term.
        - New Building type parameter (13 Hazus types, height class derived from the floor-count field). C3, S5 and URM are not offered because Hazus publishes no moderate- or high-code curve for them; the help text says so and recommends the closest tabulated type instead of inventing a row.
        - Debris now comes from the whole damage distribution, not collapse alone, so a building left standing but losing its facade and infill puts material in the street - the case the binary model under-counted. Outputs are now three quantities: solid material volume, bulked pile volume (new Void ratio parameter) and mass in tonnes (new Debris density parameter).
        - New Navigable street core output and Minimum clear width parameter: the corridor network is morphologically opened at the clear width, so a half-metre strip of pavement beside debris no longer counts as an evacuation route. The log reports the street area lost to pinching.
        - New Simulation runs parameter (default 0): reruns the scenario under N seeds and writes an empirical per-building collapse frequency plus mean, standard deviation and 5th/50th/95th percentiles of blocked street area, replacing the old advice to repeat the tool by hand.
        - Network source A now refuses a non-polygonal layer with an explicit message instead of silently producing a zero-area network.
        - No input became required and no existing parameter changed meaning, so saved models keep running; the defaults reproduce the previous single-realisation workflow. The manual card is rewritten to the new chain, and the tool is documented as uncalibrated to Turkish building stock: the Hazus design levels are mapped onto Turkish regulation years by analogy, and the curves are conditioned on a western-United States reference spectrum.
    4.12.0 - Parking demand and supply balance: two new Travel Demand tools. Parking Demand Estimator turns each zone's land-use category and size into spaces demanded through an editable per-category rate table whose entries carry their own basis (dwelling units, floor area or seats), reporting categories that match no rate row instead of returning a silent zero. Parking Supply-Demand Balance compares that demand against a counted inventory within an access radius, following the street network when one is supplied and a straight line otherwise, and separates a real deficit from a coverage gap by classifying every zone counted, zero supply found or supply data absent, with a NULL balance for unsurveyed ground so the column cannot be summed into a false shortfall. The manual documents both the same depth as the rest, and its counts, version and search index are current: 71 algorithms, 19 tool groups, 300 numbered display equations and 386 references. No existing algorithm behaviour changed.
    4.11.2 - Quality infrastructure. Fixed the dead Help button: the manual host was hard-coded to the retired GitHub Pages address, so all 69 Help links and both Studio dock documentation actions opened a 404 - they now resolve through a single definition that names the live host. The 528-check pure engine suite was filed in the QGIS tier with tests_pure empty, so nothing ran it; it is now where CI can reach it. Added a pure catalog gate set (registry versus manual anchors in both directions, groups, icons, version literals, help host) and a runtime matrix that instantiates and executes all 69 algorithms on QGIS 3.44 LTR and 4.2. Refreshed the manual's stale Processing IDs and version, and made the README's equation and reference counts countable. No algorithm behaviour changed.
    4.11.1 - Upgraded official plugin icon to high-end tactile 3D brand identity with circular teal pedestal; synchronized documentation, repository and issue tracker endpoints to GeoPhilo and GitLab. Fixed field preservation and fid handling in network preparation and service areas algorithms.
    PlanX 4.10.1 - QGIS 4 / Qt6 readiness and a fully clean security scan.
        - Scoped every Processing/geometry enum (QgsProcessing.SourceType, QgsWkbTypes.Type/GeometryType, QgsFeatureSink.Flag and friends) so the Hub Qt6 compatibility check reports zero issues; runtime behaviour is unchanged on QGIS 3.28+ and 4.x. Minimum QGIS is now 3.28.
        - Replaced the betweenness source-sampling RNG with a self-contained seeded generator and removed the .bandit config, so the security scan now passes as fully Validated (no suppressions). No functional change.
    PlanX 4.10.0 - Link Criticality: rank the street segments whose loss most hurts the network, 69 algorithms total, 19 groups.
        - Link Criticality (Network Robustness) in Network Analysis: removes each segment in turn over your origin-destination demand and reports the extra travel it forces (criticality, extra_cost), the demand it severs (n_disconnected) and how many shortest paths use it (used_by) - the road-network vulnerability view, embedded, no external routing.
        - OD Routes, OD Cost Matrix and Nearest Facility help now spell out the cost-field contract (additive per-segment cost, never a speed; units inherited by net_cost and cutoffs; NULL reads as 0).
    PlanX 4.6.1 - Seismic debris tool: four road/open-space network sources, no manual digitizing required.
        - Network source selector: street polygons as-is, OSM highway centerlines buffered by class-typical widths, any centerlines buffered by a road-width attribute, or region-of-interest minus dissolved blocks/parcels (automatic convex-hull ROI when omitted).
        - Network inputs are reprojected to the buildings CRS; clear errors for wrong mode/layer combinations.
    PlanX 4.6.0 - Seismic Risk: Monte Carlo building-collapse and debris-spread screening with reproducible seeding, 64 algorithms total, 19 groups.
        - Seismic Collapse and Debris Spread (new Seismic Risk group): per-building collapse probability from construction year and event magnitude, seeded Monte Carlo collapse draw, debris spread radius/volume, network blockage and remaining evacuation corridors.
        - Also fixed a demo-city generator bug: green-space blocks no longer receive building footprints.
    PlanX 4.5.0 - LUTI-lite Scenario Pipeline: chained cellular-automaton growth, largest-remainder population growth allocation, and access/walkability evaluation, 63 algorithms total, 18 groups.
        - Population Allocation: distributes a population growth increment over parcels using deterministic largest-remainder apportionment.
        - Scenario Pipeline (new Reporting tool): chains cellular-automaton growth, allocates population growth to new development, and evaluates accessibility and walkability.
    PlanX 4.4.0 - Travel Demand: trip generation, gravity distribution, and mode split modeling, 61 algorithms total, 18 groups.
        - Trip Generation (new Travel Demand group): calculates zone production and attraction totals from population and jobs.
        - Gravity Distribution: runs a doubly constrained Furness/IPF gravity model over zone totals and network travel costs with exponential or power deterrence.
        - Mode Split: splits OD flows into multiple mode shares and flows using a multinomial logit model.
    PlanX 4.3.0 - Hazard Screening: flow accumulation, HAND, and flood exposure mapping, 58 algorithms total, 17 groups.
        - Road Emissions: calculates road segment emissions (g/km/day) from a traffic volume field and a generic NOx-proxy emission factor.
        - Air Quality Screening: generates a dispersion index grid and calculates receiver levels and exposure bands, accounting for wind speed, decay exponent alpha, and street canyon effects.
    PlanX 4.1.0 - Cycling and LTS: cycling stress classification and low-stress connectivity, 53 algorithms total, 16 groups.
        - Cycling Stress (new Cycling group): classifies street segments into LTS 1-4 from speed, lanes, AADT and infrastructure fields, with editable threshold rules and a length-share table.
        - Low-Stress Connectivity: filters the network by an LTS threshold, labels connected cycling islands, reports low-stress network length share and optional destination-reach population.
    PlanX 4.0.0 - Demo City & Speed: synthetic city generator and hot-loop vectorisation, 51 algorithms total, 15 groups.
        - Generate Demo City (Reporting and Dashboard group): generates a deterministic synthetic town with streets, buildings, land use, POIs, facilities, demand points, green polygons and a DSM raster, allowing all tools to be tried in one click.
        - Speed optimization: visibility isovist_field precomputes direction offsets to speed up the loop, and noise screening grid uses row-broadcasting for distance checks.
    PlanX 3.6.0 - the Batch Plan Auditor closes the loop: 50 algorithms total, 15 groups.
        - Batch Plan Auditor (Reporting group): the whole standard battery in one run - give the plan's core layers once (network, demand, amenities, land use, facilities, greens) and it chains the 15-minute access score, the walkability audit, land-use balance, facility adequacy, green-space access and access equity, gathers every score into one scenario snapshot JSON (ready for Scenario Compare A/B) and optionally writes the one-file Plan Performance Report. Each part is optional - supply its inputs and it joins the battery. Model-designer friendly and fully headless.
        - Plan Dashboard: a Plan Performance Index HISTORY sparkline grows with every saved snapshot, and an Audit button opens the Batch Plan Auditor directly.
        - Scenario metric registry gains the auditor's keys (walkability mean, low-walk share, weakest green coverage, access Gini), all direction-aware in A/B comparisons.
        - New docs/METHODS.md: the method, formula and primary source of every tool group, one page.
    PlanX 3.5.0 - Urban Growth: change accounting, growth simulation and the sprawl scorecard, 49 algorithms total.
        - Land-Cover Change Analysis (new Urban Growth group): the transition matrix of two class rasters - one row per from/to pair with cells and hectares, a per-class summary of gains, losses, persistence and net change, optional class labels, and the largest conversion named in the log.
        - Urban Growth Simulation (CA): a constrained cellular automaton in the SLEUTH tradition - per step, non-urban cells score suitability x (base + weight x urban neighbourhood share) and the top scorers convert until the step's land demand is met; constraints raster for never-build land; fully deterministic for a given random seed across processes. Outputs the year-of-conversion raster (the growth-ring map).
        - Urban Sprawl Metrics: SDG 11.3.1 - the land-consumption-rate to population-growth-rate ratio (above 1 = the footprint outpaces the people) plus patch count, largest-patch share and edge density of the horizon fabric.
        - Engine: new pure-NumPy engine/growth.py (change_matrix, ca_simulate with default_rng tie-breaking, patch labelling, edge length, sprawl_metrics); cross-process determinism of the CA is a unit test; three new group-coloured tool icons.
    PlanX 3.4.0 - Environment Screening: road noise and green infrastructure, 46 algorithms total.
        - Road Noise Screening (Microclimate group): a screening-quality dB(A) grid - RLS-90-style emission (37.3 + 10 lg(M(1+0.082p))) from a traffic volume field (hourly factor for AADT) and heavy shares, roads sampled as line-calibrated point sources, energetic sum with 20 lg r spreading and a fixed insertion loss where buildings block the line of sight. Optional receiver points report their level and a population exposure table by 5 dB bands. Clearly documented as screening, not compliance mapping.
        - Green Space Access (new Green Infrastructure group): the park hierarchy standard (min_ha=max_dist ladder, e.g. 0.5=300, 2=800, 10=2000) tested on real street-network distances - per-demand distance and pass/fail per class, classes met, per-class covered-population summary and citywide m2 per capita.
        - Urban Green Connectivity: patches linked when the gap is crossable, components, the binary Probability-of-Connectivity index and per-patch dPC importance - which stepping stone holds the network together.
        - Engine: new pure-NumPy engine/noise.py (emission, line-calibrated sample power, energetic receiver sum, exposure bands - the infinite-line self-check is a unit test) and engine/green.py (hierarchy parser, components, PC index, dPC); three new group-coloured tool icons.
    PlanX 3.3.0 - Population & Housing: the demographic backbone of plan-making, 43 algorithms total.
        - Population Projection (Cohort-Component) (new Population and Housing group): a Leslie-matrix projection from a plain age-group table - per-step survival, fertility and optional net migration as fields, any number of steps; outputs step x age-group rows and per-step totals with growth. Single-sex screening form, rates constant over the horizon.
        - Housing Needs Assessment: the standard needs identity as a batchable tool - future households from the horizon population, a vacancy allowance, replacement losses and backlog; every intermediate lands in a metric/value table. Negative need = surplus.
        - Residential Capacity: per-parcel buildable floorspace from FAR minus existing floorspace, converted to whole dwelling units at your unit size and net-to-gross efficiency, with a district roll-up - the reality check against the housing need, and a target source for the Land-Use Allocation Optimizer.
        - Engine: new pure-NumPy engine/population.py (leslie_matrix, cohort_projection, housing_needs, residential_capacity) and report.svg_pyramid (age-structure comparison chart); three new group-coloured tool icons.
    PlanX 3.2.0 - Visibility: viewsheds, isovists and landmark exposure, 40 algorithms total.
        - Viewshed (DSM) (new Visibility group): line-of-sight sweep from observer points over a surface model - observer and target heights, view radius, direction count; outputs the visibility count raster (how many observers see each cell). Same radial-sweep idiom as the shadow tools, rays capped at the raster diagonal.
        - Isovist Field: samples a point grid between buildings and measures the 2-D isovist at every point (Benedikt): visible area and perimeter, min/max/mean sight line, circularity and occlusivity - the visibility-graph companion to the space syntax tools; style iso_area for the openness map.
        - Visual Exposure of Landmarks: the inverse viewshed - samples the landmark outline, sweeps a viewshed from each sample (plus an optional extra height for spires the DSM misses) and counts per cell how many outline points a person there would see; run before/after inserting a proposal into the DSM and difference the rasters.
        - Engine: new pure-NumPy engine/visibility.py (viewshed with running-horizon rays, isovist / isovist_field with shoelace areas and occlusivity); three new group-coloured tool icons.
    PlanX 3.1.0 - Transit: GTFS feeds become first-class citizens, 37 algorithms total.
        - GTFS Import and Service Stats (new Transit group): loads a GTFS zip into QGIS - stops as points with daily departures and route counts, plus a route summary table (mode, trips, service span). Validates the feed on the way in with clear errors; the service day defaults to the feed's first active day.
        - Transit Frequency Map: departures per stop within a time window of a service day - departures/hour, mean headway minutes and distinct routes per stop (style by per_hour for the frequent-network map), plus per-route trips in the window.
        - Transit Travel-Time Access: door-to-door times with public transport - walk to a stop on the street network, ride the timetable with up to N transfers (RAPTOR-style earliest arrival), walk to each destination; every destination reports walk-only vs transit minutes, the winning mode and the minutes saved.
        - Engine: new pure-stdlib+NumPy engine/transit.py (GTFS zip reader with named validation errors, past-midnight times as plain seconds, calendar/calendar_dates service resolution, stop frequencies, RAPTOR pattern compiler and earliest-arrival) and paths.multi_source_offset (egress Dijkstra whose sources start at their own arrival times); three new group-coloured tool icons.
    PlanX 3.0.0 - Scenarios & Walkability: the plan-evaluation loop closes and a tenth tool group opens, 34 algorithms total.
        - Scenario Snapshot (Reporting group): captures the plan score metrics of the current project into a snapshot JSON, auto-detecting the PlanX output layers by their field signatures (or pin layers explicitly). Model-designer friendly: run tools for alternative A, snapshot, rerun for B, snapshot, feed both to Scenario Compare.
        - NEW GROUP Walkability. Walkability Audit: scores every street segment 0-100 from intersection density, land-use mix entropy, destination counts, block length and slope - editable weights and breakpoints, sub-scores and raw ingredients on every segment.
        - Pedestrian Route Quality: routes over quality-weighted streets (length x quality penalty), reporting the detour ratio vs the plain shortest path, the length-weighted mean walk score along the route and the share on low-scoring segments. Nearest-destination or all-pairs.
        - Engine: new pure-NumPy engine/walkability.py (normalisation + weighted composite) and paths.shortest_path_tree / reconstruct_path (predecessor Dijkstra able to name the parallel edge taken); shared layer-collector planx/collect.py now feeds both the dashboard and the snapshot algorithm; three new group-coloured tool icons.
    PlanX 2.13.0 - Equity Cross-Tabs & Scenario Compare: who holds the low values, and which plan alternative wins, 31 algorithms total.
        - Demographic Equity Cross-Tabs (Equity group): cross-tabulates any per-unit value by population subgroup. Population-weighted quantile classes (or fixed breaks), a representation ratio per group x class cell (1 = proportional; over-representation in the lowest class flags a disadvantaged group), per-group mean/P10/median/P90/Gini/value share, and the Duncan dissimilarity index of each group against the rest. Optional second group field crosses two demographics; the input comes back annotated with its value class for mapping.
        - Scenario Compare A/B (Reporting group): the Plan Dashboard gains Save A / Save B scenario snapshots (score metrics to JSON next to the project) and an in-dock metric-by-metric comparison with direction-aware winners (higher access is good, more deficits are bad). Also headless: the planx:scenariocompare algorithm diffs two snapshot files into a comparison table and an optional one-file HTML report.
        - Engine: new pure-NumPy equity.crosstab and value_classes, new pure-stdlib engine/scenario.py (snapshot/compare/verdict) and report.compare_section/build_compare_html; two new group-coloured tool icons.
    PlanX 2.12.0 - Siting & Contiguity: Capacitated Facility Siting and Contiguous Land-Use Allocation, 29 algorithms total.
        - Capacitated Facility Siting (Optimization group): chooses where to build p facilities while respecting per-site capacities. Greedy construction followed by capacity-aware Teitz-Bart swap improvement. Returns selected sites, assignment, cost, loads, utilization, and marginal gains.
        - Contiguous Land-Use Allocation (Optimization group): optional Hard Contiguity mode on the Land-Use Allocation algorithm. Seed-based concurrent region-growing followed by boundary-swap local search preserving subgraph connectivity of affected uses.
        - Engine: new optimize.capacitated_siting, allocate.allocate_contiguous, and check_connectivity; new group-coloured tool icon.
        - Test suite grown to 225 unit checks and 174 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.11.0 - Inequality Curves: Lorenz / concentration curves and the Atkinson index, 28 algorithms total.
        - Inequality Curves (Lorenz & Atkinson) (Equity group): the distributional view of any per-unit good (access score, green space per capita, income...), with an exportable curve to chart and an inequality measure that lets you set how much you weight the worst-off.
        - Outputs the Lorenz curve as a table - cumulative population share vs cumulative value share, bowing below the 45-degree line of equality - plus the Gini coefficient (twice the area between them).
        - Reports the Atkinson index at low/medium/high inequality aversion (epsilon 0.5, 1, 2) and at your own epsilon: higher epsilon weights the lower tail more, so the index reads as the share of total value society would trade to equalise the distribution.
        - Give a rank field (deprivation, income...) for a concentration curve and index instead, revealing whether the value concentrates on the advantaged or disadvantaged end.
        - Engine: new pure-NumPy equity.atkinson_index, lorenz_points, gini_from_lorenz and concentration_index; new group-coloured tool icon.
        - Test suite grown to 216 unit checks and 166 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.10.0 - Land-Use Pareto Front: the suitability vs compactness trade-off, 27 algorithms total.
        - Land-Use Pareto Front (Optimization group): instead of one weighted run, maps the TRADE-OFF between per-parcel suitability and compact zoning. There is rarely a single best plan - clustering a use into compact zones usually costs some suitability, and vice versa.
        - Solves the Land-Use Allocation Optimizer across a sweep of compactness weights (auto-scaled to the data, or set an upper weight) and records two higher-is-better scores per result: area-weighted suitability and the shared boundary between adjacent same-use parcels (compactness).
        - Reports the non-dominated set (the Pareto front) and its knee - the best-balanced compromise. Outputs a front table (one row per weight: both scores raw and 0-1 normalised, on-front and knee flags) to plot, plus the parcel map of one chosen solution (the knee by default, or the maximum-suitability / maximum-compactness end).
        - Engine: new pure-NumPy allocate.pareto_front / pareto_mask / knee detection, reusing the existing multi-objective allocation core; new group-coloured tool icon.
        - Test suite grown to 202 unit checks and 158 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.9.0 - Annual Solar Potential: year-long clear-sky irradiation, 26 algorithms total.
        - Annual Solar Potential (DSM) (Microclimate group): clear-sky global solar irradiation summed over a whole year (kWh/m2/yr) - rooftop PV screening, annual solar access and year-round heat exposure, with no external solver or atmospheric dataset.
        - Rather than sweeping all 365 days, one representative average day per month (Klein 1977; Duffie & Beckman) is computed with the same shadow-aware beam + sky-view-weighted diffuse model as the single-day Solar Irradiation tool, scaled by the number of days in that month and summed - twelve day-sweeps stand in for the year, accurate for screening and far faster than a full daily run.
        - Outputs the annual irradiation raster; optionally a 12-band monthly raster (one named band per month) for seasonal analysis. The log reports the unobstructed flat-ground annual reference, scene statistics and the peak month.
        - Engine: new pure-NumPy solar.annual_irradiation (reuses the daily kernel) and a multi-band GeoTIFF writer; new group-coloured tool icon.
        - Test suite grown to 191 unit checks and 150 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.8.0 - Multi-objective land-use allocation: compactness and adjacency.
        - The Land-Use Allocation Optimizer is now MULTI-OBJECTIVE: beyond per-parcel suitability it can shape the spatial pattern of the plan.
        - Compactness weight (new): rewards same-use parcels that share a boundary, so each land use forms compact zones instead of scattering (reward per map unit of shared boundary; 0 = off, identical to the previous behaviour).
        - Adjacency rules (new): free text 'residential|industry=-2, residential|green=1' rewards (+) or penalises (-) specific use pairs being neighbours, per unit of shared boundary - keep incompatible uses apart and compatible ones together.
        - Suitability weight (advanced) balances suitability against the spatial terms. Parcel adjacency and shared-boundary lengths are computed with a spatial index; the run reports the spatial score and the share of shared boundary that is between same-use parcels (a compactness indicator). Pure-suitability runs are unchanged.
        - Engine: new engine/allocate.allocate_multi (suitability + a symmetric use-compatibility spatial term over the parcel adjacency graph; greedy + reassignment + capacity-respecting swaps on the full objective).
        - Test suite grown to 175 unit checks and 141 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.7.0 - Land-Use Allocation Optimizer: 25 algorithms total.
        - Land-Use Allocation Optimizer (Optimization group): assigns a land use to each parcel to MAXIMISE total suitability while meeting a target area for each use - the spatial allocation problem at the heart of plan-making, solved natively with no external solver. You give one suitability field per land use (0-1 or 0-100, e.g. straight from Suitability Lab) and a target area per use; each parcel is assigned in full to at most one use so the area given to a use stays within its target and the area-weighted suitability is as high as possible. Parcels not needed are left unassigned; a use that cannot be filled reports a shortfall. An optional lock field fixes already-zoned parcels. Method: greedy construction plus a local search of reassignments and capacity-respecting swaps (a fast heuristic, not a guaranteed global optimum). Outputs the parcels with their assigned use (style by 'alloc_use' for a land-use map) and a per-use summary of target vs allocated area, shortfall, parcel count and mean suitability.
        - New pure-NumPy engine/allocate.py; new group-coloured tool icon.
        - Test suite grown to 168 unit checks and 137 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.6.0 - Equity and Allocation: two new tools, 24 algorithms total.
        - Accessibility Equity (Gini / Theil) (new "Equity" group): measures how FAIRLY a value (an Access Score, a travel time, a distance to the nearest facility) is shared across the population - population-weighted Gini, Theil's T split into between-group and within-group inequality (the environmental-justice number when you supply a group field), P90/P10 ratio, coefficient of variation and an access-poverty share. Outputs the units with their percentile rank, deviation from the mean and a poverty flag, plus a summary table for the whole study area and per group.
        - Capacitated Allocation (Nearest with Capacity) (Optimization group): allocates demand to fixed facilities while RESPECTING capacity - each demand point goes in full to the nearest facility with room and spills to the next-nearest when its nearest is full; points that fit nowhere in reach are left uncovered. Outputs the demand (assigned facility, network cost, status Assigned/Spilled/Uncovered) and the facilities (load, remaining capacity, utilization, Full/Has space/Unused) - the realistic companion to Facility Adequacy.
        - New pure-NumPy engine/equity.py and engine/optimize.capacitated_assign; two new group-coloured tool icons.
        - Test suite grown to 156 unit checks and 126 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.5.0 - Microclimate II and per-tool icons: three new tools, 22 algorithms total.
        - Sun Hours (DSM): hours of direct sunlight per cell over one full day in a single run (replaces the old Batch workaround) - right-to-light checks, courtyard and playground sun audits.
        - Solar Irradiation (DSM): clear-sky daily global irradiation in kWh/m2 - ASHRAE-style beam blocked by cast shadows plus isotropic diffuse weighted by the sky view factor; quick roof-solar and heat-exposure screening.
        - Heat Island Risk Grid: vector UHI screening from the layers every plan already has (buildings, green, water) - fixed-scale 0-100 risk score and class per cell, comparable across scenarios and study areas.
        - Network Centrality now also computes eigenvector centrality (Bonacich power iteration).
        - Multi-Amenity Access Score: optional population field gives population-weighted audit numbers (weighted mean score, residents with full access, residents with none).
        - Every tool has its own meaningful icon - in the Processing toolbox and the PlanX Studio dock (22 distinct icons, colour-coded by group).
        - Engine fix: shadow casting no longer over-scans at very low sun altitudes; the sweep is capped at the raster diagonal.
        - Test suite grown to 131 unit checks and 109 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.4.0 - Optimization: facility location on the network, 19 algorithms total.
        - Facility Location Optimizer (new Optimization group): site new facilities among candidate locations - greedy maximal coverage (Church and ReVelle) or p-median with Teitz-Bart vertex substitution, on real network distances, no external solver.
        - Existing facilities are kept in the solution; every candidate gets a standalone screening score (demand within reach); outputs selected sites (rank, marginal gain) and demand allocation (facility, cost, covered).
        - New pure-NumPy engine/optimize.py; test suite grown to 111 unit checks and 90 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.3.0 - Performance Dashboard: live score cards and a one-click HTML report, 18 algorithms total.
        - Plan Dashboard dock: live score cards (Plan Performance Index, accessibility, standards compliance, covered population, density) over the PlanX output layers, auto-detected in the project by their field signatures.
        - Plan Performance Report (HTML): single-file stakeholder report with inline SVG charts - score histogram and red-to-green score map, provided-vs-required balance bars, facility utilization table, density summary. Also a Processing algorithm (new Reporting and Dashboard group) for headless and model-designer use.
        - New pure-stdlib engine/report.py; test suite grown to 98 unit checks and 80 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.2.0 - Plan Standards and QA: three new tools, 17 algorithms total.
        - Land-Use Balance: per-capita areas vs configurable standards (e.g. green=10, education=4), surplus/deficit and status per category.
        - Facility Adequacy: capacity and network distance checked together - facility utilization (Adequate/Overloaded/Unused) plus covered/uncovered demand and covered-population share.
        - Density Grid: distributes population/dwellings/GFA from polygons or points onto a grid by area share; density per hectare.
        - Test suite grown to 77 unit checks and 70 end-to-end assertions on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.1.0 - Microclimate (UMEP-lite): three new tools on the embedded engine, 14 algorithms total.
        - Shadow Casting (DSM): shadows for any date and local time; embedded NOAA solar-position model, UMEP-style DSM sweep; batch-friendly for shadow-duration maps.
        - Sky View Factor (DSM): visible-sky fraction per cell from multi-direction horizon scans; configurable directions and search radius.
        - Frontal Area Index: lambda-f and lambda-p wind-roughness grid (Grimmond and Oke), frontal areas distributed by footprint overlap.
        - Engine test suite grown to 69 unit checks and 56 end-to-end assertions, verified on QGIS 3.44 LTR and QGIS 4.0.2.
    PlanX 2.0.0 - Complete rewrite as the Urban Analytics Studio.
        - New embedded analytics engine (NumPy core, SciPy fast path with identical pure-Python fallback); zero external plugin/server/pip dependencies.
        - Space Syntax: segment angular analysis with metric radii - angular integration, choice, NACH and NAIN per radius.
        - Network Centrality: degree, closeness, straightness and Brandes betweenness (node and edge), radius-limited and sampled variants.
        - Network Analysis: Prepare Network, OD Cost Matrix with detour ratios and desire lines, Service Areas (isochrone bands as edges and polygons), Nearest Facility Allocation with facility load summary.
        - Urban Morphology: Building Form Metrics, Morphological Tessellation, Spacematrix Density (GSI/FSI/OSR/L plus class), Street Network Morphology (orientation entropy and order, meshedness, node typology).
        - Accessibility: Multi-Amenity Access Score (15-minute city) across any number of amenity layers.
        - PlanX Studio dock for browsing and launching the toolset; all tools also live in the Processing toolbox.
        - Removed the legacy mixed script collection (QNEAT/GRASS dependent tools and duplicates of other PlanX plugins).
    PlanX 1.0.9 - Legacy script suite (superseded).
