HERE Technologies and Wherobots announce partnership Learn More

What is Geospatial Analysis? Methods and Examples

Authors

Geospatial analysis, often called spatial analysis, examines where things are and how location shapes patterns in data. It answers questions such as "which homes are within a kilometer of a fire station?" and "where do shops cluster more than chance would explain?". Esri's GIS Dictionary defines spatial analysis as examining the locations, attributes, and relationships of features in spatial data to answer a question. Geospatial analysis applies those methods to geospatial data, data tied to places on Earth. This article's claim: four choices shape the answer as much as the method does. They are the coordinate system, the test for a match, the definition of neighbors, and the zones. A San Francisco walkthrough tests the claim by ranking places by census tract and by H3 hexagon.

Key takeaways

  • Spatial analysis and geospatial analysis name the same practice.
  • The core methods measure distance, match records by location, route on networks, estimate values between samples, summarize rasters by zone, and test for clusters.
  • Tobler's first law, that near things are more related than distant things, underlies the spatial statistics here.
  • The coordinate system, the test for a match, the neighbor definition, and the zones each change a result.

What is spatial analysis?

Spatial analysis treats location as a variable. Ordinary analysis groups sales by month. Spatial analysis groups them by neighborhood, measures how far each customer lives from a store, or tests whether high sales sit next to other high sales.

Geospatial analysis uses coordinates on the Earth. It must handle the planet's curvature and map projections, which flatten that surface onto a plane. In Advanced Placement (AP) Human Geography, spatial analysis means reading maps and data for patterns, for links between places, and for scale.

Why location changes the analysis

Waldo Tobler published A Computer Movie Simulating Urban Growth in the Detroit Region in Economic Geography in 1970. In it, he wrote that "everything is related to everything else, but near things are more related than distant things." Nearby observations resemble each other, a pattern called spatial autocorrelation. Tests that assume independent samples therefore overstate confidence on spatial data.

Core spatial analysis operations

Measurement, buffers, and proximity

Measurement returns distance, length, and area. A buffer is a zone at a fixed distance around a feature, such as 500 meters around a school. A spatial join then finds everything inside it. Nearest neighbor analysis finds the closest feature to each record, such as the closest hospital to every home. Wherobots runs this on large datasets as a k nearest neighbor (kNN) join, which finds the k closest features to each record. See Introducing kNN join for Wherobots and Apache Sedona.

Overlay and spatial joins

Overlay combines layers by location. A spatial join attaches the attributes of one dataset to another when their shapes pass a spatial predicate. A predicate is a true-or-false test of how two shapes relate, such as intersects, contains, or within. Point-in-polygon is a common case: which county, flood zone, or parcel contains each point? Max Egenhofer and Robert Franzosa defined these tests formally in Point-set topological spatial relations (1991). The Open Geospatial Consortium (OGC) Simple Feature Access standard encodes them as the dimensionally extended 9-intersection model (DE-9IM), which checks where two shapes' interiors, boundaries, and exteriors meet.

Network analysis

Network analysis measures travel along roads, rails, or pipes. Shortest-path routing comes from Edsger Dijkstra's A note on two problems in connexion with graphs (Numerische Mathematik, 1959). Service areas, closest-facility searches, and isochrones, the areas reachable within a set drive time, are built on it. Map matching places a vehicle's GPS points on the roads it drove. Wherobots Map Matching runs it on tables of trips.

Interpolation

Interpolation estimates values between measured points, such as rainfall between gauges. Inverse distance weighting gives closer samples more weight. Donald Shepard set it out in A two-dimensional interpolation function for irregularly-spaced data (1968). Kriging began with Danie Krige's 1951 work on gold grades in the Witwatersrand mines. Georges Matheron formalized it in Principles of geostatistics (Economic Geology, 1963). Kriging measures how similarity between samples falls with distance. It returns an error estimate with every prediction.

Raster analysis and zonal statistics

Raster analysis works on grids of cells. Dana Tomlin's Geographic Information Systems and Cartographic Modeling (1990) named its operations map algebra. Local operations combine cells at the same location, such as the Normalized Difference Vegetation Index (NDVI), computed from red and near-infrared bands. Focal operations compute each cell from a moving window of nearby cells. Zonal operations, or zonal statistics, return the mean, sum, or maximum of the cells inside each polygon, such as mean elevation per watershed from a digital elevation model.

Spatial autocorrelation

P. A. P. Moran introduced the statistic now called Moran's I in Notes on continuous stochastic phenomena (Biometrika, 1950). R. C. Geary followed with the contiguity ratio, Geary's C, in The contiguity ratio and statistical mapping (1954). Both need a spatial weights matrix, a table that records which observations count as neighbors. Neighbors can share a border, lie within a set distance, or be the k nearest. Moran's I runs from about -1 (neighbors differ) through 0 (random) to 1 (neighbors alike).

Hot spot and cluster analysis

Global statistics give one number per map. Local statistics give one per location. Arthur Getis and J. Keith Ord introduced the G statistics in The analysis of spatial association by use of distance statistics (Geographical Analysis, 1992). Ord and Getis gave Gi* its standardized form, a z-score, in Local spatial autocorrelation statistics (1995). A z-score counts standard deviations from the expected value. Gi* compares the sum of values around a location, the location included, with the sum expected if values were spread at random. A high z-score with a small p-value marks a cluster of high values. The p-value is the chance of a pattern this strong under random placement. Esri's guide to how hot spot analysis works explains the test. Luc Anselin's Local Indicators of Spatial Association (LISA, 1995) splits Moran's I into one value per location. That separates clusters of high values from a high value surrounded by low ones.

Density-Based Spatial Clustering of Applications with Noise (DBSCAN) builds clusters from points that have enough neighbors within a set distance. Ester, Kriegel, Sander, and Xu introduced it as a density-based algorithm for discovering clusters in large spatial databases with noise (KDD 1996). The local outlier factor of Breunig and colleagues (LOF, SIGMOD 2000) scores how isolated each point is relative to its neighbors. Wherobots added these methods in Introducing GeoStats for Wherobots and Apache Sedona.

Spatial regression

The relationship between two variables can change across a map, a pattern called spatial nonstationarity. Geographically weighted regression (GWR) fits a separate regression at every location and weights nearby observations more. Brunsdon, Fotheringham, and Charlton introduced it in Geographically Weighted Regression: A Method for Exploring Spatial Nonstationarity (1996). Multiscale GWR (Fotheringham, Yang, and Kang, 2017) lets the neighborhood size differ for each variable.

Change detection and AI on imagery

Change detection compares images of the same place over time. Satellite imagery analysis applies computer vision models to classify land cover, extract building footprints, and detect objects across large areas.

GIS vs spatial analysis

GISSpatial analysis
What it isSoftware for storing, editing, mapping, and analyzing geospatial dataMethods for answering questions with location
ExamplesQGIS, ArcGIS ProSpatial joins, buffers, zonal statistics, hot spots
Typical scaleA desktop and a project's layersFrom one map to billions of rows, depending on the engine
OutputMaps, layers, and reportsTables, scores, rasters, and maps
Where it runsGIS desktop or serverGIS, SQL databases, Python, distributed engines

Spatial analysis examples

Common pitfalls in spatial analysis

  • Measuring in degrees. A degree of longitude covers fewer meters as latitude rises. Transform to a projected system in meters, or use a geodesic function, which measures on the curved Earth.
  • The choice of zones. Counts per tract, ZIP code, and hexagon can differ for the same points. This is the modifiable areal unit problem.
  • Boundary cases. A point on a shared border can match two polygons with ST_Intersects. Check that joined rows equal distinct input records.
  • Edges of the study area. Features near the edge of a clipped dataset have fewer neighbors in the data than in reality. That biases density and hot spot results.

Spatial analysis in Wherobots

Every query below ran in WherobotsDB, the Wherobots spatial SQL engine, on these four sources. The vector tables are Apache Iceberg tables in the Havasu catalog.

SourceFormatWhat the queries readRows or extent read
Overture placesIceberg table of pointsID, geometry, basic_category73,739 places in San Francisco, 53 tagged fire_station
Overture buildingsIceberg table of footprint polygonsfootprint centroid, bounding box162,818 buildings in San Francisco
US Census tractsIceberg table of TIGER/Line polygonsGEOID, land area ALAND, boundary242 San Francisco tracts with land
Copernicus digital elevation model (DEM) GLO-30Cloud Optimized GeoTIFF (COG) on S3elevation band 1one tile, under 241 tracts

WherobotsDB handles raster and vector data in one engine, so step 4 joins the elevation raster to tract polygons and place counts in one query. Most stacks handle one of the two.

1. Business density per tract with a spatial join

The header image above shows this point-in-polygon join between places and tracts:

SELECT t.GEOID AS tract,
       COUNT(p.id) AS places,
       ROUND(t.ALAND / 1e6, 2) AS land_sq_km,
       ROUND(COUNT(p.id) / (t.ALAND / 1e6)) AS places_per_sq_km
FROM wherobots_open_data.us_census.tiger_tract t
JOIN wherobots_open_data.overture_maps_foundation.places_place p
  ON ST_Intersects(t.geometry, p.geometry)
WHERE t.STATEFP = '06' AND t.COUNTYFP = '075' AND t.ALAND > 0
GROUP BY t.GEOID, t.ALAND
ORDER BY places_per_sq_km DESC
LIMIT 5
tractplacesland_sq_kmplaces_per_sq_km
060750117009,8770.5517,901
060750611011,8890.209,566
060750118005400.069,547
060750615013,2980.427,921
060750121007470.126,054

ST_Intersects matches each place to its tract. The group-by counts places per tract. ALAND is the tract's land area in square meters from the Census TIGER/Line files. Dividing by it turns counts into density, so small downtown tracts compare fairly with large residential ones. A check query over the same join returns 242 tracts and 73,739 joined rows for 73,739 distinct places. No place matched two tracts:

SELECT COUNT(DISTINCT t.GEOID) AS tracts, COUNT(*) AS joined_rows, COUNT(DISTINCT p.id) AS places
FROM wherobots_open_data.us_census.tiger_tract t
JOIN wherobots_open_data.overture_maps_foundation.places_place p
  ON ST_Intersects(t.geometry, p.geometry)
WHERE t.STATEFP = '06' AND t.COUNTYFP = '075' AND t.ALAND > 0

Census tracts hold between 1,200 and 8,000 people, according to the Census Bureau's geography glossary. Their areas vary widely, so the hot spot test below uses equal-area hexagons.

2. Buildings near a fire station with a buffer and spatial join

This query draws a 1 km buffer around every Overture place tagged fire_station inside San Francisco. The query joins building centroids, the center point of each footprint, to the buffers. It keeps each building's distance to its closest station:

WITH sf AS (
  SELECT GEOID, geometry FROM wherobots_open_data.us_census.tiger_tract
  WHERE STATEFP = '06' AND COUNTYFP = '075' AND ALAND > 0
),
st AS (            -- Overture places tagged fire_station inside San Francisco
  SELECT p.id, p.geometry
  FROM wherobots_open_data.overture_maps_foundation.places_place p
  JOIN sf ON ST_Intersects(sf.geometry, p.geometry)
  WHERE p.basic_category = 'fire_station'
),
b AS (             -- building centroids inside San Francisco
  SELECT b.id, ST_Centroid(b.geometry) AS c
  FROM wherobots_open_data.overture_maps_foundation.buildings_building b
  JOIN sf ON ST_Intersects(sf.geometry, ST_Centroid(b.geometry))
  WHERE b.bbox.xmin > -123.1 AND b.bbox.xmax < -122.3 AND b.bbox.ymin > 37.6 AND b.bbox.ymax < 37.9
),
near AS (          -- 1 km geodesic buffer around each station, joined to buildings
  SELECT /*+ BROADCAST(st) */ b.id, MIN(ST_DistanceSpheroid(b.c, st.geometry)) AS d
  FROM b JOIN st ON ST_Intersects(ST_Buffer(st.geometry, 1000, true), b.c)
  GROUP BY b.id
)
SELECT (SELECT COUNT(*) FROM st) AS stations,
       (SELECT COUNT(*) FROM b)  AS buildings,
       SUM(CASE WHEN d <= 500 THEN 1 ELSE 0 END) AS within_500m,
       COUNT(*) AS within_1km
FROM near
stationsbuildingswithin_500mwithin_1km
53162,81849,062134,003

The query ran in 35 seconds. Of 162,818 buildings, 134,003 lie within 1 km of one of the 53 station records and 49,062 within 500 m. The true argument to ST_Buffer draws the buffer in meters on the spheroid of WGS 84, the World Geodetic System 1984 that GPS uses. A spheroid is a model of the Earth's shape. No projection step is needed.

Map of San Francisco with 500 meter and 1 kilometer buffers drawn around 53 Overture places tagged fire_station. The 1 km zones cover most of the city, with gaps along the ocean shore, in the Presidio, and at the southeastern shoreline
Buffers around the 53 fire_station records in Overture places: 134,003 of San Francisco’s 162,818 Overture buildings lie within 1 km and 49,062 within 500 m.

3. Hot spots and spatial autocorrelation on H3 cells

This query counts places per resolution 8 cell of H3, a global grid of hexagons. Every cell with a building is kept, so cells with buildings and no places count as zeros. ST_BinaryDistanceBandColumn builds the spatial weights. A cell's neighbors are the cells with centroids within 1 km. On this grid, that is the cell itself and the ring of six around it. ST_GLocal computes Gi* for every cell. The same neighbor lists give global Moran's I:

WITH sf AS (
  SELECT geometry FROM wherobots_open_data.us_census.tiger_tract
  WHERE STATEFP = '06' AND COUNTYFP = '075' AND ALAND > 0
),
bld AS (           -- H3 resolution 8 cells that hold at least one building
  SELECT ST_H3CellIDs(ST_Centroid(b.geometry), 8, false)[0] AS h
  FROM wherobots_open_data.overture_maps_foundation.buildings_building b
  JOIN sf ON ST_Intersects(sf.geometry, ST_Centroid(b.geometry))
  WHERE b.bbox.xmin > -123.1 AND b.bbox.xmax < -122.3 AND b.bbox.ymin > 37.6 AND b.bbox.ymax < 37.9
  GROUP BY 1
),
pl AS (            -- places per cell
  SELECT ST_H3CellIDs(p.geometry, 8, false)[0] AS h, COUNT(*) AS places
  FROM wherobots_open_data.overture_maps_foundation.places_place p
  JOIN sf ON ST_Intersects(sf.geometry, p.geometry)
  GROUP BY 1
),
cells AS (
  SELECT bld.h, CAST(COALESCE(pl.places, 0) AS DOUBLE) AS places,
         ST_Centroid(ST_H3ToGeom(array(bld.h))[0]) AS geometry
  FROM bld LEFT JOIN pl ON bld.h = pl.h
),
w AS (             -- binary weights: every cell centroid within 1 km, including itself
  SELECT h, places,
         ST_BinaryDistanceBandColumn(geometry, 1000.0, true, true, true, struct(h, places, geometry)) AS weights
  FROM cells
),
gi AS (            -- Getis-Ord Gi* per cell, plus the neighbour lag for Moran's I
  SELECT h, places,
         ST_GLocal(places, weights, true).Z AS z,
         AVG(places) OVER () AS mean,
         filter(weights, x -> x.neighbor.h <> h) AS nbrs
  FROM w
),
lag AS (
  SELECT h, places, z, mean, size(nbrs) AS k,
         aggregate(nbrs, 0D, (acc, x) -> acc + x.neighbor.places - mean) AS lag_dev
  FROM gi
)
SELECT COUNT(*)                                        AS cells,
       SUM(places)                                     AS places,
       SUM(CASE WHEN z > 1.96 THEN 1 ELSE 0 END)       AS hot_cells_95,
       SUM(CASE WHEN z < -1.96 THEN 1 ELSE 0 END)      AS cold_cells_95,
       SUM(CASE WHEN z > 1.96 THEN places ELSE 0 END)  AS places_in_hot_cells,
       lower(hex(max_by(h, z)))                        AS top_cell,
       ROUND(MAX(z), 2)                                AS top_z,
       SUM(k)                                          AS neighbour_links,
       ROUND(COUNT(*) / SUM(k) * SUM((places - mean) * lag_dev)
             / SUM(POW(places - mean, 2)), 3)          AS morans_i
FROM lag
cellsplaceshot_cells_95cold_cells_95places_in_hot_cellstop_celltop_zneighbour_linksmorans_i
20173,73016038,21688283082a3fffff9.281,0400.485

A Moran's I of 0.485 means busy cells sit next to busy cells far more often than chance would produce. In the Gi* results, 16 of 201 cells are hot spots at the 95% level (z above 1.96). Those 16 cells hold 38,216 of the 73,730 places. The strongest, cell 88283082a3fffff with a z-score of 9.28, is centered on Montgomery Street in the Financial District. No cell qualifies as a cold spot. The counts are so skewed toward downtown that a quiet residential cell sits close to the citywide average. Low and ordinary cells therefore get similar z-scores.

Hexagon map of San Francisco at H3 resolution 8 colored by Getis-Ord Gi* z-score. A cluster of 16 outlined hot spot cells covers the northeast of the city around the Financial District, peaking at z equals 9.28. The rest of the city stays near zero
Getis-Ord Gi* on places per H3 cell, computed with ST_GLocal in Wherobots: 16 of 201 cells are hot spots holding 38,216 of 73,730 places, and Moran’s I is 0.485.

The tract ranking and the hex test agree on downtown and differ in detail. Tract 06075011800 ranks third on density with 540 places because its land area is 0.06 km². In the hex grid, those places merge into a larger cell.

4. Elevation per tract with raster zonal statistics

This query reads one Copernicus GLO-30 elevation tile in place on AWS with RS_FromPath. RS_ZonalStatsAll summarizes the elevation pixels inside every tract. The query joins those results to the place counts from step 1 and groups tracts by mean elevation:

WITH t AS (       -- San Francisco tracts, spread over 8 tasks for the raster reads
  SELECT /*+ REPARTITION(8) */ GEOID, ALAND, geometry FROM wherobots_open_data.us_census.tiger_tract
  WHERE STATEFP = '06' AND COUNTYFP = '075' AND ALAND > 0 AND GEOID <> '06075980401'   -- Farallon Islands
),
dem AS (           -- Copernicus DEM GLO-30 tile, read in place on AWS
  SELECT RS_FromPath('s3://copernicus-dem-30m/Copernicus_DSM_COG_10_N37_00_W123_00_DEM/Copernicus_DSM_COG_10_N37_00_W123_00_DEM.tif') AS rast
),
z AS (             -- zonal statistics of the DEM inside each tract
  SELECT /*+ BROADCAST(dem) */ t.GEOID, t.ALAND,
         RS_ZonalStatsAll(dem.rast, t.geometry, 1, false, true) AS s
  FROM t JOIN dem ON RS_Intersects(dem.rast, t.geometry)
),
pc AS (            -- places per tract, the spatial join from step 1
  SELECT t.GEOID, COUNT(p.id) AS places
  FROM t JOIN wherobots_open_data.overture_maps_foundation.places_place p
    ON ST_Intersects(t.geometry, p.geometry)
  GROUP BY t.GEOID
),
j AS (
  SELECT z.GEOID, z.s.count AS px, z.s.mean AS m, z.s.max AS mx,
         COALESCE(pc.places, 0) AS places, COALESCE(pc.places, 0) / (z.ALAND / 1e6) AS density
  FROM z LEFT JOIN pc ON z.GEOID = pc.GEOID
)
SELECT CASE WHEN m < 25 THEN '0 to 25 m' WHEN m < 50 THEN '25 to 50 m'
            WHEN m < 100 THEN '50 to 100 m' ELSE '100 m and up' END AS tract_mean_elevation,
       COUNT(*)                                  AS tracts,
       CAST(SUM(px) AS BIGINT)                   AS pixels,
       SUM(places)                               AS places,
       ROUND(percentile_approx(density, 0.5))    AS median_places_per_sq_km,
       ROUND(MAX(m), 1)                          AS highest_tract_mean_m,
       ROUND(MAX(mx), 1)                         AS highest_pixel_m
FROM j
GROUP BY 1
ORDER BY MIN(m)
tract_mean_elevationtractspixelsplacesmedian_places_per_sq_kmhighest_tract_mean_mhighest_pixel_m
0 to 25 m64110,10641,59998025.0143.6
25 to 50 m6328,94813,07967749.6125.1
50 to 100 m8850,24515,95336697.6185.1
100 m and up2623,5983,105129195.8280.0

The query ran in 23 seconds. Most places sit low. The 64 tracts with a mean elevation below 25 m hold 41,599 places, at a median of 980 per km². The 26 hilltop tracts have a median of 129. GLO-30 is a surface model, so it measures the tops of roofs and trees. TIGER tract polygons also include some shoreline water, which pulls coastal means down. The query plan has no Cartesian product, a join that pairs every row with every other row. REPARTITION(8) spreads the 241 zonal reads over eight parallel tasks. Each task fetches only the COG tiles under its tracts, the design of the out-of-database raster architecture.

Map of San Francisco census tracts shaded by mean elevation from the Copernicus DEM in four bands. The central hills sit above 100 meters and the bayside and oceanside tracts below 25 meters. A bar chart beside the map shows median places per square kilometer falling from 980 in the lowest band to 129 in the highest
Zonal statistics of the Copernicus GLO-30 DEM per tract, joined to Overture places. Median density falls from 980 places per km² in the 64 tracts below 25 m to 129 in the 26 tracts at 100 m and up.

Running it with AI

Language models were trained on text, documents, databases, and the internet, and cannot compute a spatial join or a Gi* test alone. With the Wherobots Model Context Protocol (MCP) server, an AI coding tool can find the tables, write the joins, and run the queries in Wherobots from a plain-language request.

Spatial analysis research and what changes at scale

From the quantitative revolution to GIScience

The quantitative revolution, geography's turn to statistics in the 1950s and 1960s, produced Moran's and Geary's statistics, Matheron's geostatistics, and Tobler's law. Stan Openshaw and colleagues' Geographical Analysis Machine (1987) tested circles of many sizes for disease clusters, an early brute-force method. Michael Goodchild's Geographical information science (1992) argued that the questions behind GIS deserved their own science. The field took that name.

Local statistics and neighbor definitions

Every global and local statistic depends on the weights matrix. A 1 km band on H3 cells, as in the walkthrough, gives most cells seven neighbors including themselves. A wider band averages over more cells and spreads the hot spot. These weights and statistics became an open source Python library called PySAL (Rey and Anselin, 2007), and libpysal still builds them. Brian Ripley's K function, from Modelling spatial patterns (1977), tests raw points for clustering at many distances at once.

The modifiable areal unit problem

C. E. Gehlke and Katherine Biehl noticed in 1934 that correlation coefficients computed from census tracts grew as tracts were merged into larger units. W. S. Robinson's Ecological correlations and the behavior of individuals (1950) named the ecological fallacy, a correlation across areas that differs from the one across the people in them. Stan Openshaw named the general case in his 1984 monograph The Modifiable Areal Unit Problem (CATMOG 38). He split it into a scale effect (how large the zones are) and a zoning effect (where their boundaries fall). Fotheringham and Wong showed in 1991 that regression results on census data shift with both. Mei-Po Kwan's uncertain geographic context problem (2012) adds that the neighborhood a person experiences rarely matches the tract of their address. Equal-area grids such as H3 remove unequal zone sizes and leave the scale choice in place.

What changes at scale

A naive neighbor search compares every pair. The 201 hexagons form about 20,000 pairs, and the 162,818 buildings about 13 billion. Spatial partitioning splits the data into regions, and a spatial index finds the pairs that can match inside each one. Jia Yu, Jinxuan Wu, and Mohamed Sarwat introduced GeoSpark (ACM SIGSPATIAL 2015) to run spatial queries on Apache Spark. Yu, Zongsi Zhang, and Sarwat described its partitioning, indexing, and join algorithms in Spatial data management in Apache Spark (GeoInformatica, 2019). GeoSpark became Apache Sedona. Yu and Sarwat founded Wherobots, and WherobotsDB builds on that engine, as the Wherobots spatial join optimizer documentation describes. The walkthrough's distance band weights and Gi* test run on the same partitioning.

Running one Gi* test per location multiplies the chance of false hot spots. Caldas de Castro and Singer adapted false discovery rate control (2006) to local statistics for that reason. The method caps the expected share of false hot spots among those found. Permutation tests, which reshuffle values across locations, are the other common check. Edge effects shrink as a share of the study area. Data quality, such as duplicate or missing points of interest, becomes the main source of error.

Open problems

  • Choosing neighbors and scale. No cited source gives a rule for choosing the distance band or the k of a weights matrix. Results depend on that choice.
  • Zones. The cited literature offers mitigations for both zone problems, such as testing several zonings, and no general solution.
  • Machine learning on spatial data. A random train and test split puts test points beside similar training points, which inflates measured accuracy. Roberts and colleagues recommend blocked cross-validation (Ecography, 2017), which holds out whole blocks of space for testing.

Conclusions

The San Francisco runs support the claim. Zones, neighbors, join checks, and input data shape a spatial analysis answer as much as the method does.

  1. Spatial analysis ranks zones fairly only after normalizing. Tract 06075011800 ranks third on density because it covers 0.06 km². Divide counts by area or population before comparing zones.
  2. A spatial join needs a count check. The tract join returned 73,739 rows for 73,739 distinct places, so no point matched two tracts.
  3. Changing the zones changes a spatial analysis result. Tracts were ranked by density and H3 cells by Gi* on counts, and the point counts differ (73,739 and 73,730). To isolate the zoning effect, run one statistic on one point set in both zonings. Use an equal-area grid for statistics and administrative zones for reporting, and state the scale.
  4. Hot spot analysis on skewed counts can find hot spots and no cold spots. Gi* gave 16 hot cells holding 38,216 of 73,730 places and zero cold cells. Test a rate or a log transform beside the raw count, and correct for false discoveries.
  5. Raster and vector spatial analysis can run in one query. Zonal statistics for 241 tracts, joined to place counts, took 23 seconds. Check the plan for a Cartesian product before any raster join at scale.
  6. A spatial analysis is limited by its input points. The 53 fire_station records can include duplicates or omissions. A coverage study starts from the agency's own station list.

Read more from Wherobots

Run spatial joins, hot spot statistics, zonal statistics, and nearest neighbor analysis with a Wherobots free trial at cloud.wherobots.com.

Frequently asked questions

What is meant by spatial analysis?

Spatial analysis is the process of examining the locations, attributes, and relationships of features in geospatial data to answer a question. It uses location as part of the calculation: distances, overlaps, containment, neighbors, and patterns across space.

What is the difference between spatial analysis and geospatial analysis?

The terms are used interchangeably. Spatial analysis can apply to any space, including a microscope slide or a building floor plan. Geospatial analysis applies the same methods to data referenced to the Earth, such as satellite imagery, roads, parcels, and GPS tracks.

What is the difference between GIS and spatial analysis?

A geographic information system (GIS) is software for storing, editing, mapping, and analyzing geospatial data. Spatial analysis is the set of methods applied to that data. GIS is one place to run spatial analysis. SQL engines, Python libraries, and distributed platforms such as Wherobots run the same methods on larger datasets.

Can you give me an example of geospatial analysis?

Counting the businesses in each census tract is a geospatial analysis. A spatial join matches each business location to the tract polygon that contains it. A group-by then counts the businesses in each tract, and dividing by land area gives a density to compare across a city. Other examples include John Snow’s 1854 map of cholera deaths around a London water pump, scoring buildings for flood risk, and finding the nearest hospital to every home.

What are the main types of spatial analysis?

Common types measure distance and proximity, combine layers by location with overlay and spatial joins, and route trips along networks. Others estimate values between sample points (interpolation), summarize a raster inside zones (zonal statistics), and test whether similar values cluster (spatial autocorrelation and hot spot analysis). Spatial regression and change detection on imagery over time complete the list.

Is spatial analysis hard to learn?

The core ideas, such as distance, containment, and overlap, are intuitive. The harder parts are coordinate reference systems, choosing the right spatial test (such as intersects or contains), deciding which locations count as neighbors, and running analysis on large datasets. Analysts who know SQL can start with spatial functions such as ST_Intersects and ST_Distance and add more methods as needed.

What tools are used for geospatial analysis?

Desktop GIS such as QGIS and ArcGIS Pro, databases such as PostGIS, Python libraries such as GeoPandas and PySAL, and distributed engines such as Apache Sedona and WherobotsDB. The choice depends on data size. Desktop and single-node tools suit city-scale work. Distributed engines handle state, national, and global datasets.

What is spatial analysis in AP Human Geography?

In AP Human Geography, spatial analysis means reading maps and data for spatial patterns and for relationships between places, at local, national, and global scales. The course’s first unit, Thinking Geographically, covers map types, how geographers collect data, spatial concepts such as distance decay, and scales of analysis. GIS and spatial SQL compute the same ideas with software.

What is spatial autocorrelation?

Spatial autocorrelation is the tendency of nearby locations to have similar values, the pattern described by Tobler’s first law of geography. Moran’s I (1950) and Geary’s C (1954) measure it. Both use a spatial weights matrix, a table that lists which locations are neighbors. Positive values of Moran’s I mean similar values cluster. In San Francisco, places counted per H3 cell have a Moran’s I of 0.485.

What is hot spot analysis?

Hot spot analysis finds locations where high values cluster more than chance would explain. The Getis-Ord Gi* statistic (1992) compares the sum of values in each location’s neighborhood with the expected sum. It returns a z-score: values above 1.96 mark a hot spot at the 95% confidence level. In WherobotsDB, ST_GLocal computes Gi* in SQL.

What is the modifiable areal unit problem?

The modifiable areal unit problem (MAUP) is the change in statistical results that comes from changing the zones data are aggregated into. Stan Openshaw named it in 1984 and split it into a scale effect, how large the zones are, and a zoning effect, where their boundaries fall. Testing more than one zoning, such as census tracts and equal-area hexagons, shows how sensitive a result is.