Methodology · Austin Urban Heat
The data sources, satellite processing, spatial database work, and analysis behind the Austin urban heat story map.
This analysis measures summer land surface temperature across all 65 of Austin's neighborhood planning areas and tests its relationship to tree canopy, impervious surface, and median household income.
The pipeline spans four tools, each used where it is strongest:
Google Earth Engine satellite compositing & zonal stats PostGIS / PostgreSQL spatial join for census income R (tidycensus, sf) census data retrieval Leaflet + Chart.js the web story map
Earth Engine handles the satellite imagery and zonal statistics, PostGIS performs the tract-to-neighborhood income join, R retrieves the census data, and Leaflet with Chart.js renders the web map.
Boundaries are the City of Austin's Neighborhood Planning Areas, pulled from the municipal open-data portal. The raw layer contained 95 records, because several multi-part neighborhoods are stored as separate polygons.
These were dissolved by neighborhood name into 65 unique areas, so that each neighborhood is a single analytical unit. Central East Austin, for example, exists as two separate polygons in the source and was merged into one.
The source layer contained a self-intersecting edge that the spherical-geometry engine rejects, so geometries were repaired with st_make_valid() before dissolving.
Surface temperature comes from the thermal band of Landsat 8 and 9, Collection 2 Level-2, processed in Google Earth Engine. Land surface temperature (LST) is measured directly by the satellite's thermal sensor and reflects the temperature of the physical surface rather than the air.
Surface temperature varies considerably between individual scenes with weather conditions. The median across three summers of scenes reduces this scene-to-scene variation and represents typical summer conditions.
Both land-cover variables come from national products, sampled in Earth Engine:
Canopy and impervious cover change slowly relative to temperature, so values from the most recent available years represent the study window. They were not multi-summer composited in the way LST was.
With three raster surfaces (temperature, canopy, impervious) and 65 neighborhood polygons, the next step was zonal statistics: reducing each raster to one value per neighborhood. Earth Engine's reduceRegions did this in a single pass.
The result is a 65-row table of mean temperature, temperature standard deviation, mean canopy, and mean impervious cover per neighborhood.
Median household income is published by the U.S. Census at the tract level, which does not align with neighborhood boundaries. Aggregating tract income to neighborhoods requires a spatial join, performed in PostGIS.
Current income (ACS 2018–2022, table B19013) was pulled for all 290 Travis County tracts using R's tidycensus, with tract geometry attached, and written to the spatial database.
The census tracts were in NAD83 (EPSG:4269) and the neighborhoods in WGS84 (EPSG:4326). PostGIS does not permit spatial operations across mismatched coordinate systems, so the tracts were transformed before the join:
-- reproject tracts NAD83 -> WGS84 to match neighborhoods UPDATE income_tracts SET geometry = ST_Transform(geometry, 4326); SELECT UpdateGeometrySRID('income_tracts', 'geometry', 4326);
Each neighborhood overlaps several tracts partially. Each tract's income was weighted by the area of its overlap with the neighborhood, then averaged:
SELECT n.name, SUM(t.median_income * ST_Area(ST_Intersection(n.geometry, t.geometry))) / NULLIF(SUM(ST_Area(ST_Intersection(n.geometry, t.geometry))), 0) AS income_weighted FROM neighborhoods n JOIN income_tracts t ON ST_Intersects(n.geometry, t.geometry) WHERE t.median_income IS NOT NULL GROUP BY n.name;
In words: join each neighborhood to every tract it touches, compute the overlapping sliver of geometry, use that sliver's area as the weight, and take the area-weighted mean income. Tracts with no reported income are dropped so they cannot distort the average.
Pearson correlations were computed against surface temperature across all 65 neighborhoods:
| Relationship | r | Strength |
|---|---|---|
| Tree canopy ↔ heat | −0.87 | Strong negative |
| Impervious surface ↔ heat | +0.83 | Strong positive |
| Median income ↔ heat | −0.51 | Moderate negative |
The correlations are computed across all 65 neighborhoods. The six neighborhoods featured in the story map illustrate the pattern; the statistics describe the full set.
The pipeline runs from public data: City of Austin neighborhood boundaries, Landsat and NLCD collections in Earth Engine, and Census ACS data via the Census API. The Earth Engine scripts, R census retrieval, and PostGIS queries are in the project repository.