[general]
name=PlanX
email=yusuf.eminoglu@deu.edu.tr
author=Yusuf Eminoglu
qgisMinimumVersion=3.28
description=Embedded urban analytics engine: space syntax (segment angular analysis), network centrality, urban morphology, OD matrices, OD shortest-path routes, service areas, nearest-facility allocation with real route geometries, link criticality (road-network robustness screening that ranks the street segments whose loss most raises travel cost or severs demand), 15-minute-city accessibility, green infrastructure (park hierarchy access, patch connectivity), cycling (Level of Traffic Stress classification and low-stress connectivity islands), GTFS public transport (feed import and validation, stop frequency maps, door-to-door walk+transit travel times with transfers), accessibility equity (Gini, Theil between/within groups, Atkinson index, Lorenz/concentration curves, demographic cross-tabs), microclimate (shadow casting, sun hours, clear-sky solar irradiation, annual solar potential, sky view factor, frontal area, heat island risk, road noise screening, road emissions and air quality dispersion screening), visibility (DSM viewsheds, isovist fields, landmark visual exposure), plan standards QA (per-capita land-use balance, facility adequacy, density grids), population and housing (cohort-component projection, housing needs, residential zoning capacity), walkability (street-segment walk scores from intersection density, land-use mix, destinations, block length and slope, plus quality-weighted pedestrian routing, slope comfort profiling with Tobler walking times, and street environment comfort from kernel densities of assets and barriers), location-allocation optimization (maximal coverage, p-median, capacity-respecting allocation, capacitated facility siting, multi-objective land-use allocation with compactness, adjacency, and contiguity, land-use Pareto front of suitability versus compactness), urban growth (land-cover change matrices, deterministic cellular-automaton growth simulation, SDG 11.3.1 sprawl metrics), hazard screening (priority-flood DEM filling, D8 flow accumulation, height-above-nearest-drainage inundation mapping, flood exposure of buildings and population), travel demand modeling (trip generation rates, doubly constrained gravity distribution with exponential or power deterrence over street network, multinomial logit mode split, and a parking demand-and-supply balance that estimates the spaces each zone demands from per-category rate tables with dwelling-unit, floor-area or seat bases and compares them against a counted inventory within a network or straight-line access radius, separating a real deficit from a coverage gap), land-use/transport interaction pipeline (CA growth simulation, largest-remainder population growth allocation to newly developed cells, access/walkability re-evaluation and scenario snapshotting), seismic risk screening (scenario ground motion from the Akkar-Sandikkaya-Bommer 2014 model, one of the four in the logic tree of Turkey's 2018 national seismic hazard map, giving every receiver peak ground acceleration, peak ground velocity and any spectral period you name from a magnitude, distance, fault-mechanism and Vs30 description, with rows outside the model's published applicability range flagged rather than silently extrapolated; Hazus equivalent-PGA fragility curves giving every building a full none-to-complete damage distribution from a joined peak-ground-acceleration field or, failing that, a scenario magnitude; damage-state-sampled debris spread with solid, bulked and tonnage volumes; network blockage, open evacuation corridors, and a navigable core narrowed to a minimum clear vehicle width; optional multi-seed runs with per-building collapse frequency; and Hazus Section 12 casualty and Section 13 shelter models that turn that damage distribution into expected injuries and deaths at four severities, unhoused households and the people who will seek public shelter, with the manual's occupancy-and-time-of-day population shares deciding who is in each building; and a Liquefaction Screening that asks the other ground-failure question, giving every map unit or every sampled feature the probability that saturated soil loses its strength during the shaking and the settlement to expect, from either the Zhu et al. 2015 logistic regression on shaking, topographic wetness and shear-wave velocity or the Hazus Section 4.2.2.1 susceptibility model on a classified map-unit layer, each with its own published tables and its own refusals; and a Coseismic Landslide Screening that asks the third ground-failure question - whether the hillside itself moves - giving every feature the Newmark sliding-block displacement of Jibson 2007 Equation 8 in centimetres, with the median and its 90th percentile, the critical acceleration from any of three routes (a field of your own, the Hazus 6.1 Section 4.2.2.2 geologic-group tables on dry or wet ground, or somebody else's susceptibility map), the slope read from a DEM in every route, the applicability envelope enforced and reported, and every row recording which route produced its number) and a plan dashboard/reporting workflow with batchable scenario snapshots, scenario A/B comparison and weighted multi-scenario ranking, a one-click HTML report and a Batch Plan Auditor that runs the whole battery in one call - all computed natively inside QGIS, no external plugins or services.
about=PlanX is the flagship of the PlanX ecosystem: a self-contained urban analytics studio for city planners and researchers. It embeds real implementations of the methods urban analysts usually need separate tools for - space syntax segment angular analysis (integration, choice, NACH/NAIN), the full centrality family (degree, closeness, straightness, eigenvector, betweenness), urban morphology (building form metrics, morphological tessellation, Spacematrix GSI/FSI/OSR, street orientation entropy), network accessibility (OD cost matrix, service-area isochrones, nearest-facility allocation, multi-amenity 15-minute-city scores with population-weighted summaries), public transport straight from a GTFS zip (feed import with clear validation errors and per-day stop/route service stats, stop frequency and headway maps for any time window, and 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 each destination, always compared against walking all the way), accessibility-equity analysis (population-weighted Gini, a Theil index split into between- and within-group inequality, P90/P10 ratio and access-poverty share, plus a Lorenz/concentration curve export and the Atkinson index at a chosen inequality-aversion, and demographic equity cross-tabs that cut any per-unit value into population-weighted classes and report each subgroup's representation ratio among the worst- and best-served together with Duncan dissimilarity - the spatial-justice view), microclimate screening (date-and-time shadow casting with an embedded NOAA solar-position model, whole-day sun-hours maps, clear-sky daily solar irradiation combining shadow-aware beam with SVF-weighted diffuse light, annual solar potential summing twelve representative average-day sweeps into a yearly kWh/m2 map with an optional 12-band monthly raster, sky view factor, frontal area index, and a vector heat-island risk grid built from buildings, green and water layers, plus a screening-quality road noise grid: RLS-90-style emission from traffic volumes and heavy shares, line-calibrated point sampling with geometric spreading and a fixed insertion loss behind buildings, with per-receiver levels and population exposure bands), green infrastructure (park-hierarchy access that tests minimum-size-within-maximum-distance standards on real network distances with per-class population coverage, and patch connectivity with the Probability-of-Connectivity index and each patch's dPC importance - the stepping-stone argument, quantified), cycling analysis (Level of Traffic Stress 1-4 from speed, lanes, AADT and infrastructure fields with editable thresholds, plus low-stress island connectivity and destination-reach population summaries), visibility analysis (DSM viewsheds from observer points with observer and target heights, an isovist field that samples Benedikt's 2-D visibility measures - area, radials, circularity, occlusivity - on a point grid between buildings, and landmark visual exposure that counts from where a landmark's outline can be seen, the skyline/heritage screening view), plan standards QA (land-use balance against configurable per-capita standards, facility adequacy combining capacity with network distance, dasymetric density grids), the demographic backbone of plan-making (a cohort-component population projection as a Leslie matrix - per-age-group survival, fertility and net migration, rates as table fields, no locale assumptions; a housing needs assessment turning the horizon population into dwellings to deliver with vacancy allowance, replacement losses and backlog; and residential capacity that converts each parcel's FAR minus existing floorspace into whole dwelling units with a district roll-up - projection feeds needs, capacity tests whether the zoning can deliver them), a walkability studio (a Walkability Audit that scores every street segment 0-100 from the classic walkability-index ingredients - intersection density, land-use mix entropy, destination counts, block length and slope, each normalised with editable breakpoints and weights - and Pedestrian Route Quality, which routes over quality-weighted streets and reports the detour ratio, the mean walk score along the route and the share spent on low-scoring segments), location-allocation optimization (greedy maximal coverage and Teitz-Bart p-median on network distances, with candidate-site screening and support for existing facilities, plus a capacity-respecting allocation that sends demand to the nearest facility with free capacity and spills to the next when it is full, capacitated facility siting with capacity-aware Teitz-Bart swap improvement, and a multi-objective land-use allocation optimizer that assigns parcels to land uses to maximise total suitability while meeting a target area for each use, with optional compactness, adjacency, and hard contiguity objectives that shape contiguous, compatible zones, and a land-use Pareto front that runs the allocation across a sweep of compactness weights and reports the non-dominated suitability-versus-compactness trade-off with its knee, instead of committing to one weighted run), urban growth analytics (a land-cover transition matrix with per-class gains, losses and persistence in hectares; a deterministic constrained cellular-automaton growth simulation in the SLEUTH tradition - suitability times a neighbourhood term, top scorers convert until the land demand is met, same seed same map in any process - writing a year-of-conversion raster; and urban sprawl metrics around the SDG 11.3.1 land-consumption-to-population-growth ratio with patch counts, largest-patch share and edge density), seismic risk screening in four chained tools (a Ground Motion Scenario that runs the Akkar-Sandikkaya-Bommer 2014 ground-motion model - one of the four in the logic tree of Turkey's 2018 national seismic hazard map - over any receiver layer, from a point source with a focal depth or an extended fault trace, reporting peak ground acceleration, peak ground velocity and any spectral periods you name at a chosen fault mechanism, distance metric, Vs30 site velocity and epsilon, with the Joyner-Boore, epicentral or hypocentral distance written to every row, receivers whose Vs30 field is empty flagged rather than quietly given rock, and every row outside the model's published magnitude, distance, depth or site range carrying an explicit caveat code instead of being silently extrapolated; and a Hazus equivalent-PGA fragility model that turns a joined peak-ground-acceleration field - or this tool's own output - into a full none-to-complete damage distribution per building, sampled damage states, solid, bulked and tonnage debris volumes, network blockage, open evacuation corridors and a navigable core narrowed to a minimum clear vehicle width; and a Seismic Human Impact tool that carries that same damage distribution into Hazus Section 12 and Section 13, giving every building the expected injured and killed at four severities, unhoused households and people needing public shelter, with the manual's occupancy and time-of-day population shares - a school empty at 2 a.m., a hotel a fifth full at 2 p.m. - and the demographic shelter modifiers present but neutral by default, so the shelter figure is reported as an upper bound rather than a forecast; and a Liquefaction Screening that answers the ground-failure question the other three never ask - whether the soil itself loses its strength - with two published models behind one interface: the Zhu, Daley, Baise, Thompson, Wald and Knudsen 2015 logistic regression on shaking, topographic wetness and shear-wave velocity, whose wetness index and slope come from one D8 pass on a DEM and whose Vs30 comes from the slope through the Allen and Wald 2007 USGS piecewise table, a field, a raster or a constant, with the tectonic setting deliberately having no default because the table's two columns differ by a factor of 1.96 in velocity at the same slope; and the Hazus 6.1 Section 4.2.2.1 susceptibility model, Equations 4-9 to 4-11 and Tables 4-10 to 4-13, which reads a map-unit layer somebody already classified Very High to None and gives each unit the probability and the expected settlement in inches, refusing to run without that layer and refusing a category it does not recognise rather than reading it as zero - both applied exactly as printed, both reported as UNCALIBRATED for Turkish soils, and both documented as screening for planning rather than a geotechnical investigation or a code check; and a Coseismic Landslide Screening that asks the third ground-failure question - whether the hillside itself moves - with the Newmark sliding-block displacement of Jibson 2007 Equation 8, a length in centimetres rather than a probability, whose critical acceleration comes from a field you already have, from the Hazus 6.1 Section 4.2.2.2 geologic-group and susceptibility-category tables transcribed from the manual, or from a map unit somebody else already classified, and whose slope is read from a DEM in every route: dry and wet ground are up to four susceptibility categories apart at one slope and group, so the groundwater state has no default; an unset route stops the run rather than choosing one; a zero critical acceleration is refused because the regression diverges there; a Hazus category of None reports an empty acceleration rather than a zero, because zero is the value the equation blows up on; and every row carries the route it took, the ratio the regression turns on, and the p90 beside the median), and a plan dashboard/reporting workflow with live score cards in PlanX Studio, a Plan Performance Index history sparkline, one-click access to the Batch Plan Auditor (give the plan's core layers once and it chains the access, walkability, balance, adequacy, green-access and equity tools into one scenario snapshot and report), batchable scenario snapshots (auto-detected PlanX output layers captured to JSON, model-designer friendly) compared metric by metric A/B (each metric knows which direction is better), plus a one-click single-file HTML Plan Dashboard & Performance Report (inline SVG charts, balance bars and score maps - shareable with stakeholders). Everything is computed inside the plugin with NumPy (SciPy used automatically when available, identical pure-Python fallback otherwise): no QNEAT3, no GRASS dependency, no UMEP, no servers, no pip installs. All tools are Processing algorithms - model-designer and batch friendly - and every tool carries its own icon in the toolbox and the PlanX Studio dock. Developed with feedback from educational workflows at Dokuz Eylul University, Department of City and Regional Planning. Online User Manual & Documentation: https://geophilo.com/planx/ | If you find this plugin helpful, please consider starring the repository on GitLab (https://gitlab.com/geophilo1/planx)!
version=4.18.0
tracker=https://gitlab.com/geophilo1/planx/-/issues
repository=https://gitlab.com/geophilo1/planx

category=Vector
tags=planx,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
homepage=https://geophilo.com/planx/
icon=icons/icon.png
experimental=False
deprecated=False
qgisMaximumVersion=4.99
hasProcessingProvider=yes
plugin_dependencies=
license=GPL-3
changelog=
    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 8, 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 8, 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 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 9 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 8 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 8 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).
