Planetary-scale answers, unlocked.
A Hands-On Guide for Working with Large-Scale Spatial Data. Learn more.
Raster vs. vector data is the choice between the two ways a geographic information system (GIS) stores geographic data. Raster data is a grid of cells, or pixels. Each cell holds one value: the color of a satellite image, the height of the ground, the class of land cover. Vector data is a set of features drawn as points, lines, and polygons. Each feature has a row of attributes: a building footprint with its height, a road with its speed limit. A raster covers every location in its extent. A vector layer covers each feature. Converting one into the other changes the measurement. Joining the two in one query avoids that conversion.
Raster data divides an area into rows and columns of equal cells. Esri describes a raster as a matrix in which each cell holds a value representing information such as temperature. Georeferencing places the grid on Earth. It has three parts: the coordinates of one corner, the cell size, and a coordinate reference system (CRS).
Cell size sets the resolution. A Sentinel-2 image at 10 m resolution covers 100 square meters with each pixel. USDA NAIP aerial imagery goes down to 30 cm. NAIP is the National Agriculture Imagery Program of the U.S. Department of Agriculture (USDA). A raster can hold several bands, one grid per measurement. Sentinel-2 records 13 spectral bands, and a digital elevation model (DEM) has one band of heights.
Rasters come from satellites such as Sentinel-2 and Landsat, the main source of Earth observation data, and from aerial and drone cameras. Elevation models built from radar or lidar data are rasters too, as are model outputs of land cover, temperature, or flood depth.
Vector data stores each feature as geometry plus attributes. The geometry is a list of coordinates. The Open Geospatial Consortium (OGC) Simple Features standard defines the common geometry model. It has a base Geometry class with subclasses for points, curves such as line strings, surfaces such as polygons, and geometry collections, which hold multi-part features.
Each feature carries a row of attributes. An Overture buildings record has a footprint polygon with height and floor count where available.
A raster is an array plus a transform. The array is the cell values, stored row by row. The transform is six numbers that map a row and column to coordinates. They are the corner position, the cell width and height, and two rotation terms that are zero for a north-up grid. The CRS gives those numbers their units. A grid in a projected CRS such as Universal Transverse Mercator (UTM) has cells of equal area in meters. A grid in longitude and latitude has cells of equal angle. Their ground width shrinks toward the poles. ESA WorldCover, the European Space Agency's 10 m land cover map used below, is a longitude-latitude grid. Its "10 m" cells cover less ground in Wisconsin than at the equator.
A vector feature is coordinates plus topology rules. A polygon is a closed ring of vertices with optional holes. Its area comes from the coordinates. Spatial relationships between features, such as touches, contains, and overlaps, follow from the geometry. Egenhofer and Franzosa formalized them in the point-set topological spatial relations (1991) that SQL predicates such as ST_Intersects implement.
GeoTIFF and Cloud Optimized GeoTIFF (raster). GeoTIFF is a TIFF (Tagged Image File Format) image with georeferencing tags, published as an OGC standard. A Cloud Optimized GeoTIFF (COG) arranges pixels in internal tiles with overviews, so a client reads only the byte ranges it needs over HTTP. OGC adopted the Cloud Optimized GeoTIFF standard in 2023. GDAL, the open-source raster library, writes the format with its GDAL COG driver. The public archive of Sentinel-2 Level-2A images on AWS is stored as COGs.
Shapefile (vector). Esri's shapefile splits one layer across several files: .shp for geometry, .shx for the index, and .dbf for attributes. Each component file has a 2 GB size limit, and field names have a 10-character limit.
GeoJSON (vector). GeoJSON encodes features as JSON text. Its specification, RFC 7946 from the Internet Engineering Task Force, fixes the coordinates to World Geodetic System 1984 (WGS84) longitude and latitude.
GeoParquet (vector). GeoParquet adds geometry columns to Apache Parquet, a columnar file format. Query engines read only the columns and row groups a query touches. The Overture Maps Foundation distributes its data as GeoParquet.
Raster. A grid represents continuous surfaces with no boundaries to draw. Overlay is cell-by-cell arithmetic, which runs fast. Detail smaller than a cell disappears. Halving the cell size quadruples the cell count. A single building or road has no identity in a grid until someone extracts it.
Vector. Geometry stays precise at any scale. Each feature carries attributes and a stable ID. Networks, adjacency, and containment are direct to compute. A temperature gradient has no natural vector form. Polygons with millions of vertices slow joins and overlays.
Use raster for measurements that vary across space: imagery, elevation, slope, temperature, vegetation index, flood depth. Use raster for change detection between dates and for computer vision on imagery.
Use vector for things with identity and edges: buildings, roads, parcels, pipelines, administrative areas, customer locations. Use vector when the answer is a count, a list of features, or a route.
Many use cases need both. A flood risk analyst reads flood depth from a raster and reports results per building or parcel from a vector layer.
Well-known raster datasets:
Well-known vector datasets:
Rasterizing turns vector into raster. It burns geometries into a grid. GDAL's gdal_rasterize writes vector points, lines, and polygons into raster bands. Lines become a chain of cells, the problem Jack Bresenham solved for pen plotters in his line algorithm (IBM Systems Journal, 1965). Polygons fill the cells whose centers fall inside them, or every cell they touch under an all-touched rule. Features smaller than one cell can vanish.
Polygonizing turns raster into vector. Also called vectorizing, it traces connected cells with the same value into polygons. It rests on connected component labeling, which Rosenfeld and Pfaltz described in Sequential operations in digital picture processing (Journal of the ACM, 1966). GDAL's gdal_polygonize creates a polygon for each connected region of pixels sharing a value. A water mask becomes flood extent polygons. A model's building predictions become footprints. Edges follow the cell grid, so outputs often need smoothing or simplification.
Zonal statistics, point sampling, and clipping each read a raster through vector features:
Mismatched coordinate systems, resolutions, and formats make these operations hard. So does scale: thousands of image tiles against millions of polygons.
One Wherobots analysis studied the Eaton fire burn scar. Its raster-vector join of elevation to building footprints and roads found that "15,233 of the 83,930 footprints sit below that point, 223 m (732 ft)," the burn scar's lowest point. In another, WherobotsDB read 719 Sentinel-2 scenes, 151 GB in total, then joined vessel detections against Overture Maps land polygons to remove rocks and coastline.
WherobotsDB runs raster and vector in one engine; most stacks pick one. RS_ZonalStats summarizes a raster under each polygon. RS_Value reads it under a point. RS_PixelAsPolygons and RS_Polygonize turn cells into polygons, and RS_AsRaster burns polygons into a grid. With the out-of-database raster architecture, the raster stays in its file, and each query below reads only the COG tiles inside its box.
The walkthrough uses one 11.31 km² box on the Madison, Wisconsin, isthmus, between Lake Mendota and Lake Monona: 89.41 to 89.36° W and 43.065 to 43.09° N. Three WherobotsDB queries read two sources:
The first query counts WorldCover pixels per class inside the box. It measures each class two ways. The first is pixel count times the nominal 100 m². The second is the summed area of the cell polygons that RS_PixelAsPolygons returns. ST_AreaSpheroid measures them on the WGS84 ellipsoid, the mathematical model of Earth's shape. RS_TileExplode splits the 3 by 3 degree file into 512-pixel tiles. Only the four tiles that overlap the box are read. It ran in 23.7 seconds.
WITH aoi AS ( SELECT ST_PolygonFromEnvelope(-89.41, 43.065, -89.36, 43.09) AS g ), wc AS ( SELECT RS_TileExplode(RS_FromPath('s3://esa-worldcover/v200/2021/map/ESA_WorldCover_10m_2021_v200_N42W090_Map.tif'), 512, 512) AS (x, y, rast) ), c AS ( -- keep tiles that overlap the box by area, then RS_Clip(raster, band, geometry, allTouched, noDataValue, crop) SELECT /*+ BROADCAST(aoi) */ RS_Clip(wc.rast, 1, aoi.g, false, 0, true) AS c FROM wc CROSS JOIN aoi WHERE RS_Intersects(wc.rast, aoi.g) AND ST_Area(ST_Intersection(RS_Envelope(wc.rast), aoi.g)) > 0 ), px AS ( SELECT p.value AS v, p.geom AS cell FROM (SELECT explode(RS_PixelAsPolygons(c, 1)) AS p FROM c) WHERE p.value > 0 ) SELECT CAST(v AS INT) AS worldcover_class, COUNT(*) AS pixels, COUNT(*) * 100 / 1e6 AS area_km2_at_100m2_per_pixel, ROUND(SUM(ST_AreaSpheroid(cell)) / 1e6, 4) AS area_km2_from_cell_polygons, ROUND(AVG(ST_AreaSpheroid(cell)), 2) AS mean_cell_m2 FROM px GROUP BY CAST(v AS INT) ORDER BY pixels DESC
The cells average 62.83 m². WorldCover cells are 1/12,000 of a degree on each side. A degree of longitude narrows away from the equator. At this latitude, a pixel count times 100 m² overstates each class by 59%. The 180,000 cells add up to 18.00 km² at 100 m² each, against 11.31 km² for the box itself.
Vectorizing the same grid with RS_Polygonize and dissolving each class across tile seams returns the same areas to the fourth decimal, because the polygons follow the cell edges. The shape of the data changes. Tree cover becomes 482 separate patches with 9,022 vertices. Built-up land becomes 131 patches with 10,093 vertices. Simplifying those polygons with a 0.0001° tolerance cuts tree cover vertices by 58%, from 9,022 to 3,763. It shrinks tree cover area by 1.6%, from 1.0745 to 1.0571 km². Grassland, in small scattered patches, loses 6.8% of its area.
-- Keep the WITH clause above through the clipped tiles (c), add a comma after c, then append: polys AS ( -- vectorize: one polygon per connected run of equal cells, per tile SELECT p.value AS v, p.geom AS geom FROM (SELECT explode(RS_Polygonize(c, 1)) AS p FROM c) WHERE p.value > 0 ), merged AS ( -- dissolve across tile seams, one multipolygon per class SELECT CAST(v AS INT) AS worldcover_class, ST_Union_Aggr(geom) AS geom FROM polys GROUP BY CAST(v AS INT) ) SELECT worldcover_class, ST_NumGeometries(geom) AS patches, ST_NPoints(geom) AS vertices, ROUND(ST_AreaSpheroid(geom) / 1e6, 4) AS area_km2_polygonized, ROUND(ST_AreaSpheroid(ST_SimplifyPreserveTopology(geom, 0.0001)) / 1e6, 4) AS area_km2_simplified_0001deg, ST_NPoints(ST_SimplifyPreserveTopology(geom, 0.0001)) AS vertices_simplified FROM merged ORDER BY area_km2_polygonized DESC
The second measurement runs the other direction. It burns the 4,182 Overture footprints in the box into WorldCover's own grid. The query turns each cell into a polygon once. It then applies the two standard rasterization rules as spatial joins. The cell-center rule, GDAL's default, burns a cell when its center falls inside a footprint. The all-touched rule burns every cell a footprint touches. RS_AsRaster applies the same two rules when the output should stay a raster. It ran in 32.3 seconds.
WITH aoi AS (SELECT ST_PolygonFromEnvelope(-89.41, 43.065, -89.36, 43.09) AS g), wc AS ( SELECT RS_TileExplode(RS_FromPath('s3://esa-worldcover/v200/2021/map/ESA_WorldCover_10m_2021_v200_N42W090_Map.tif'), 512, 512) AS (x, y, rast) ), c AS ( -- the WorldCover grid inside the box, clipped once SELECT /*+ BROADCAST(aoi) */ RS_Clip(wc.rast, 1, aoi.g, false, 0, true) AS c FROM wc CROSS JOIN aoi WHERE RS_Intersects(wc.rast, aoi.g) AND ST_Area(ST_Intersection(RS_Envelope(wc.rast), aoi.g)) > 0 ), cells AS ( -- every cell as a polygon, with its center and its area on the ellipsoid SELECT p.geom AS cell, ST_Centroid(p.geom) AS center, ST_AreaSpheroid(p.geom) AS cell_m2, ST_GeoHash(ST_Centroid(p.geom), 12) AS cell_id FROM (SELECT explode(RS_PixelAsPolygons(c, 1)) AS p FROM c) ), b AS ( -- Overture footprints, clipped to the box SELECT /*+ BROADCAST(aoi) */ b.id, ST_Intersection(b.geometry, aoi.g) AS geom FROM wherobots_open_data.overture_maps_foundation.buildings_building b CROSS JOIN aoi WHERE b.bbox.xmin < -89.36 AND b.bbox.xmax > -89.41 AND b.bbox.ymin < 43.09 AND b.bbox.ymax > 43.065 AND ST_Intersects(b.geometry, aoi.g) ), center_rule AS ( -- a cell is burned when its center falls inside a footprint SELECT b.id, ST_AreaSpheroid(b.geom) AS footprint_m2, COUNT(k.cell_id) AS cells, COALESCE(SUM(k.cell_m2), 0) AS burned_m2 FROM b LEFT JOIN cells k ON ST_Contains(b.geom, k.center) GROUP BY b.id, b.geom ), touched AS ( -- all-touched rule: every cell a footprint touches, counted once SELECT DISTINCT k.cell_id, k.cell_m2 FROM cells k JOIN b ON ST_Intersects(k.cell, b.geom) ) SELECT COUNT(*) AS buildings, ROUND(SUM(footprint_m2) / 1e6, 4) AS footprint_km2, ROUND(SUM(burned_m2) / 1e6, 4) AS raster_km2_cell_center, (SELECT ROUND(SUM(cell_m2) / 1e6, 4) FROM touched) AS raster_km2_all_touched, SUM(CASE WHEN cells = 0 THEN 1 ELSE 0 END) AS buildings_with_no_cell, ROUND(SUM(CASE WHEN cells = 0 THEN footprint_m2 ELSE 0 END)) AS lost_footprint_m2 FROM center_rule
The cell-center total lands within 0.2% of the footprint area, because cells gained along one edge offset cells lost along another. 246 footprints, 9,124 m² in all, cover no cell center and disappear from the raster. The all-touched rule keeps every building and inflates the total by 73.5%.
WorldCover's built-up class covers 2.7 times the footprint area, because it labels whole cells of developed land.
A raster-vector join attaches a raster value to every feature. This query clips the WorldCover tiles once and turns the cells into polygons. It then gives each building the class of the cell under a point inside its footprint. It ran in 23.8 seconds.
WITH aoi AS (SELECT ST_PolygonFromEnvelope(-89.41, 43.065, -89.36, 43.09) AS g), wc AS ( -- ESA WorldCover 2021: 512-pixel tiles of one 3 x 3 degree COG, read on demand SELECT RS_TileExplode(RS_FromPath('s3://esa-worldcover/v200/2021/map/ESA_WorldCover_10m_2021_v200_N42W090_Map.tif'), 512, 512) AS (x, y, rast) ), c AS ( -- clip the tiles that overlap the box, once SELECT /*+ BROADCAST(aoi) */ RS_Clip(wc.rast, 1, aoi.g, false, 0, true) AS c FROM wc CROSS JOIN aoi WHERE RS_Intersects(wc.rast, aoi.g) AND ST_Area(ST_Intersection(RS_Envelope(wc.rast), aoi.g)) > 0 ), cells AS ( -- each cell as a polygon with its land cover class SELECT CAST(p.value AS INT) AS worldcover_class, p.geom AS cell FROM (SELECT explode(RS_PixelAsPolygons(c, 1)) AS p FROM c) ), b AS ( -- Overture footprints clipped to the box, with one point inside each SELECT /*+ BROADCAST(aoi) */ b.id, b.height, ST_AreaSpheroid(ST_Intersection(b.geometry, aoi.g)) AS footprint_m2, ST_PointOnSurface(ST_Intersection(b.geometry, aoi.g)) AS pt FROM wherobots_open_data.overture_maps_foundation.buildings_building b CROSS JOIN aoi WHERE b.bbox.xmin < -89.36 AND b.bbox.xmax > -89.41 AND b.bbox.ymin < 43.09 AND b.bbox.ymax > 43.065 AND ST_Intersects(b.geometry, aoi.g) ), one AS ( -- the class of the cell under each building; a point on a cell edge keeps one match SELECT b.id, MIN(b.height) AS height, MIN(b.footprint_m2) AS footprint_m2, MIN(k.worldcover_class) AS worldcover_class FROM b JOIN cells k ON ST_Intersects(k.cell, b.pt) GROUP BY b.id ) SELECT worldcover_class, COUNT(*) AS buildings, ROUND(SUM(footprint_m2) / 1e6, 4) AS footprint_km2, COUNT(height) AS with_height, ROUND(percentile_approx(height, 0.5), 1) AS median_height_m FROM one GROUP BY worldcover_class ORDER BY buildings DESC
1,186 of the 4,182 buildings, 28%, sit on cells that WorldCover labels tree cover. They hold 0.13 km² of footprint, about 110 m² each. They are most likely houses under street trees, in cells where canopy covers the most ground. The other 2,988 sit on built-up cells and hold 92% of the footprint area. The 4 buildings on water cells are most likely boathouses or shoreline structures in cells that are mostly lake.
The Model Context Protocol (MCP) is a protocol that lets AI agents call data tools. An agent connected through the Wherobots MCP Server can write these queries from a plain-language request such as "how much of the Madison isthmus is tree cover". The models people use every day were trained on text, documents, databases, and the internet. Joining pixels to polygons in SQL is a core task in geospatial AI and physical AI.
Donna Peuquet's A conceptual framework and comparison of spatial data models (Cartographica, 1984) compared three families of data structure. They are tessellations (grids of cells), vector structures, and hierarchical forms, judged on storage, retrieval, and the operations each supports. Dana Tomlin's GIS and Cartographic Modeling (1990) defined map algebra, a set of operations on grids. Its local, focal, and zonal operations still name raster functions today.
In 1992 the argument moved from data structures to how people conceive of space. Helen Couclelis wrote People manipulate objects (but cultivate fields): beyond the raster-vector debate in GIS. She argued that the choice reflects two views of geography: discrete objects with identity, and continuous fields with a value everywhere. Michael Goodchild's Geographical data modeling (Computers & Geosciences, 1992) defined data modeling as discretizing spatial variation: breaking a surface into a finite set of pieces. He compared the ways a database can discretize a field, from grids of cells to triangulated networks and polygons. A raster is one encoding of a field, and a vector layer can encode either view.
Later work joined the two. Karen Kemp proposed fields as a framework for integrating GIS and environmental process models (Transactions in GIS, 1996). Cova and Goodchild's Extending geographical representation to include fields of spatial objects (IJGIS, 2002) mapped every location in a field to an object. An example is the viewshed: the area visible from each point. Goodchild, Yuan, and Cova's Towards a general theory of geographic representation in GIS (IJGIS, 2007) built both views from one primitive, the geo-atom: a location, a property, and a value.
Bregt and colleagues measured rasterizing error on the soil map of the Netherlands (1991). They related it to cell size and to map complexity, measured as boundary length. On complex sheets the error reached 20%. Russell Congalton's Exploring and evaluating the consequences of vector-to-raster and raster-to-vector conversion (PE&RS, 1997) traced squares, triangles, circles, and a polygon with a hole through conversion and back. The 246 Madison buildings that vanish at 10 m are the same effect.
Woodcock and Strahler's The factor of scale in remote sensing (1987) related image resolution to the size of the objects on the ground. Peter Fisher's The pixel: a snare and a delusion (1997) argued that a pixel's value seldom describes a square of uniform ground. A WorldCover cell labeled built-up can hold a house, a driveway, and a tree.
Samriddhi Singla, Ahmed Eldawy, and colleagues built Raptor (PVLDB, 2019) to process raster and vector data together without converting one into the other. Their Experimental study of big raster and vector database systems (ICDE, 2021) benchmarked the systems available for that work.
Jia Yu, Jinxuan Wu, and Mohamed Sarwat introduced distributed spatial processing on Apache Spark with GeoSpark (ACM SIGSPATIAL, 2015). Yu, Zhang, and Sarwat described its partitioning, indexing, and spatial join design in Spatial data management in Apache Spark: the GeoSpark perspective and beyond (GeoInformatica, 2019). GeoSpark became Apache Sedona. Sedona 1.5 made it one engine for raster and vector data, with RS_AsRaster, map algebra, and zonal statistics among its raster functions.
On the Madison isthmus, raster and vector data gave different areas for the same land and buildings, so choosing between them changes the result.
Join raster and vector data in one query with a Wherobots free trial at cloud.wherobots.com.
Raster data divides space into a grid of cells, and each cell holds one value, such as a reflectance, an elevation, or a land cover class. Vector data represents features as points, lines, and polygons defined by coordinates, with a row of attributes for each feature. Raster suits continuous surfaces such as imagery and terrain. Vector suits discrete features such as roads, buildings, and parcels.
A shapefile is vector. It holds points, lines, or polygons in a .shp file, an index in a .shx file, and attributes in a .dbf table. Esri created the format, and most GIS software reads it.
Check the file format and zoom in. GeoTIFF, COG, JPEG 2000, and NetCDF files are raster, and zooming in shows square pixels. Shapefile, GeoJSON, GeoPackage vector layers, and GeoParquet files are vector, and zooming in keeps edges sharp because the geometry is stored as coordinates.
Use raster when the value changes across every location: elevation, temperature, rainfall, or the reflectance a satellite measures. A grid holds those surfaces cell by cell. Map algebra, arithmetic applied cell by cell across grids, runs fast. In vector data, every feature needs a boundary, and continuous surfaces have none.
A GeoTIFF is raster. It is a TIFF image with tags that tie each pixel to a location on Earth. A Cloud Optimized GeoTIFF (COG) arranges the same pixels in internal tiles so a program can read one area over HTTP without downloading the whole file.
A JPEG is a raster image. Scanned maps and drone photos often arrive as JPEGs. A world file or embedded georeferencing ties the pixels to coordinates so GIS software can place the image on a map.
Yes. Polygonizing, also called vectorizing, traces connected cells with the same value into polygons, for example a flood mask into flood extent polygons. The reverse, rasterizing, burns points, lines, or polygons into a grid. Both steps change the data: rasterizing loses detail smaller than a cell, and polygonizing produces stair-stepped edges.
Raster examples include satellite imagery from Sentinel-2 and Landsat, aerial photos, digital elevation models, land cover maps, and weather grids. Vector examples include building footprints, road networks, property parcels, administrative boundaries, and GPS points.
Satellite imagery is raster. A sensor records reflected light as a grid of pixels, one grid per spectral band. Each pixel covers a fixed patch of ground: 10 m for the Sentinel-2 visible and near-infrared bands, 30 m for most Landsat bands. Features such as buildings, fields, and roads become vector data only after someone digitizes or extracts them from the image.
The raster-vector debate was the argument in early GIS over which data structure a GIS should be built on. Donna Peuquet compared the two in 1984. In 1992 Helen Couclelis and Michael Goodchild reframed the question as two views of geography: continuous fields and discrete objects. Modern systems store and join both.
A pixel count gives the wrong area when each pixel is assumed to cover its nominal size. ESA WorldCover is a 10 m map with cells of 1/12,000 of a degree on each side. At the latitude of Madison, Wisconsin, each cell covers 62.83 square meters. Counting each one as 100 square meters overstates area by 59%. Measure the cell polygons on the ellipsoid, or reproject to an equal-area grid, before converting counts to area.
What is a Kelvin Wave? Speed, El Niño and 2026 Data
A Kelvin wave is a long, low ocean wave that carries warm water east along the equator in an El Niño. In the 30 days to 10 November 2026, the sea at San Diego stood a record 41.2 cm above NOAA's tide prediction.
What Is an ETL Pipeline? Steps, Examples and Spatial ETL
An ETL (extract, transform, load) pipeline moves data from sources into storage. Learn the steps with examples. Then see a spatial mistake that passed the usual checks: rounding coordinates emptied 27% of Denver's building outlines.
What is an MCP Server? Spatial Context for AI Agents
An MCP server gives AI agents tools to call. With no tools, Claude Code gave no count of San Francisco's buildings. Via Wherobots MCP, it counted 162,538.
share this article
Awesome that you’d like to share our articles. Where would you like to share it to: