ASCII Grid — ESRI's text elevation format: universal DEM exchange
ASCII Grid (.asc or .grd extension) is a text format for storing regular raster data, primarily elevation, developed by ESRI in the 1990s for ARC/INFO. The file consists of six header lines and a grid of space-separated numbers — opens in any text editor, readable by a human, parsable by a regular expression. Over three decades ASCII Grid became the universal exchange format between ArcGIS, QGIS, GRASS, GDAL, R, Python, and dozens of academic GIS tools. When you need to send a colleague an elevation grid of a region without explaining how to open a binary — export to ASCII Grid and attach to email.
History: from ARC/INFO to a universal exchange standard
ESRI ASCII Grid emerged in the 1990s as part of ARC/INFO Workstation — Esri's flagship GIS of that era. The format was designed with exactly one goal: enable grid import/export between heterogeneous tools without binary converters. Six-line header + grid of numbers — a structure understandable by a human and easily parsable by a bash script.
By 2000 the format became a de-facto standard for DEM exchange in academic GIS communities. Journals like Computers & Geosciences began requiring ASCII Grid as a mandatory format for supplementary materials — guaranteeing reproducibility without buying commercial software. NASA Earth Observatory, USGS, NOAA Coastal Services Center published their DEMs precisely as .asc.
In 2003 GDAL added the AAIGrid driver, cementing the format as universal. Today it's read and written by GRASS, QGIS, R raster package, Python rasterio, MATLAB, IDL, ENVI, ERDAS Imagine, GlobalMapper, MicroDEM. A .asc file even opens in Excel — slowly for large files.
A 1990s alternative to ASCII Grid is Surfer Grid from Golden Software, .grd. Similar text structure, slightly different header syntax. Still used in oil-and-gas geology.
What's inside an ASCII Grid file
A .asc file consists of two parts: header (6 lines) + data (NROWS rows, NCOLS numbers per row).
Header looks like:
NCOLS 1201
NROWS 1201
XLLCORNER 39.0
YLLCORNER 43.0
CELLSIZE 0.000833333333
NODATA_VALUE -9999
NCOLS, NROWS — grid dimensions in pixels. XLLCORNER, YLLCORNER — coordinates of the lower-left corner of the lower-left cell (in CRS units defined by an external .prj file). CELLSIZE — cell size in the same units. NODATA_VALUE — value indicating missing data (typically -9999 or -32768).
Alternative — specifying the center of the lower-left cell instead of its corner: XLLCENTER instead of XLLCORNER. Difference of 0.5 cells. On large grids this is visually invisible, but on overlay with vectors can shift everything half a meter. Always check which variant is used.
After the header comes data: NROWS rows, each with NCOLS numbers separated by spaces or tabs. The first row corresponds to the northernmost row of the grid. Numbers can be integer, floating point, or scientific notation. Example:
NCOLS 5
NROWS 3
XLLCORNER 0
YLLCORNER 0
CELLSIZE 1
NODATA_VALUE -9999
105 110 115 120 125
108 112 117 122 127
110 115 120 125 130
The CRS is not stored inside the .asc file — it's specified in an external .prj file in WKT format with the same base name. For example, terrain.asc ships alongside terrain.prj.
Who needs ASCII Grid: five roles
Geophysicist with academic publication. Geomorphology journals (Geomorphology, Earth Surface Processes), climatology (Climate Dynamics), hydrology (Hydrological Processes) require all DEM data in supplementary materials to be in a reproducible format. ASCII Grid reads in any open-source tool — guaranteeing any reviewer can replicate the analysis.
GIS course instructor. In seminars students learn to process DEMs. Binary HGT/GeoTIFF is a black box: unclear what's inside, parser closed. ASCII Grid lets a student open the file in Notepad++, see numbers, touch them. Many curricula (TU Delft, ETH Zurich, MIT 1.012 Hydrology) start with .asc.
Hydrologist modeling water flow. TauDEM, GRASS r.watershed, ArcGIS Hydrology toolbox — all accept ASCII Grid as input for flow direction, accumulation, watershed delineation calculations. Text format is convenient for debugging: you can manually verify output values match expectations on small test grids.
Meteorologist. Numerical weather models (WRF, COSMO, ICON) produce and consume grids of temperature, pressure, humidity on regular meshes. ASCII Grid is the standard export/import format for these fields in research. For operational work more compact NetCDF / GRIB is used; for debugging and exchange with colleagues — .asc.
Archaeologist and historian. Reconstruction of ancient landscapes (paleogeography, virtual maps of Ancient Rome, modeling pre-industrial coastlines) often uses ASCII Grid for small custom grids. Small data volume (1–10 MB typical grid), text nature — simplifies archiving and submission to Zenodo / Dryad data repositories.
Software for ASCII Grid: seven programs
Text editor. Notepad, VSCode, Sublime open .asc instantly. Not suitable for large files (>100 MB), but ideal for header debugging.
GDAL/OGR. Universal bridge. gdalinfo terrain.asc shows metadata, gdal_translate terrain.asc terrain.tif converts to GeoTIFF, gdaldem hillshade creates shading. Free. gdal.org/drivers/raster/aaigrid
QGIS. Drag-and-drop .asc into QGIS — auto-recognized via GDAL backend. Full arsenal available: hillshade, contour, slope, aspect, viewshed. Free. qgis.org
GRASS GIS. Open-source GIS with deep academic roots. Module r.in.ascii imports ASCII Grid into a project, r.out.ascii exports back. Good for script automation. grass.osgeo.org
Python: rasterio. rasterio.open('terrain.asc') reads with AAIGrid driver auto-detect. After reading, work with it as a regular numpy array. rasterio.readthedocs.io
R: raster package. library(raster); r <- raster('terrain.asc') — standard R import path. For academic publication entire analysis often runs in R. cran.r-project.org/package=raster
ArcGIS Pro. Paid, Esri. Import via ArcToolbox → Conversion Tools → To Raster → ASCII to Raster. Used in government and major commercial projects. esri.com/arcgis-pro
Pitfalls and tips
File size grows fast. One pixel in ASCII Grid is 4–8 bytes of text (number with space and newline). A 1201×1201 grid (standard SRTM3 tile) takes 6–10 MB as .asc — 4× larger than 2.7 MB HGT. A 10000×10000 grid is already 400+ MB of text. For production pipelines use binary formats (GeoTIFF, COG), for exchange/archive — .asc.
Slow I/O. ASCII parsing into numpy goes through numpy.loadtxt or pandas.read_csv — CPU-expensive. For a large grid (10K×10K) reading can take minutes vs milliseconds for GeoTIFF. Don't use .asc in performance-critical code.
CRS in separate .prj file. Lose the .prj — and you'll have to recover the CRS manually, often impossible without knowing the file's origin. When archiving always bundle .asc + .prj in ZIP or TAR.
NODATA_VALUE may be a string. Sometimes real files contain NODATA_VALUE NA or NODATA_VALUE NaN — non-standard, but R writes this by default. GDAL understands both, but homemade regex parsers may break. Check via gdalinfo before bulk processing.
Locale-dependent decimal separator. A float printer on a German-locale system may write 0,5 instead of 0.5 (comma instead of period). This breaks most parsers. Always set LANG=C in .asc generation scripts or use numeric formatters with explicit %.6f.
Newline conventions. Linux: \n, Windows: \r\n, old Mac: \r. ArcGIS Workstation on Windows wrote \r\n, which is fine, but GDAL and rasterio read everything. If you write .asc manually in Python — open with newline='' to avoid \r\r\n on Windows.
CELLSIZE and units. CELLSIZE is in CRS units. For geographic WGS84 — degrees (0.000833 ≈ 90 m at equator). For UTM — meters (90). Many parsers assume one or the other — check .prj.
Dialect: XLLCORNER vs XLLCENTER. Difference of 0.5 cells. On large grids invisible, but overlays with vectors get a half-pixel shift. ArcGIS writes CORNER, GRASS sometimes CENTER. If you see strange shift — first suspect is XLLCORNER vs XLLCENTER.
How to use ASCII Grid with an OSM export from osm2cdr.ru
ASCII Grid is a raster format, and osm2cdr.ru does export it: .asc delivers your area as a numeric grid, bundled as .asc + .prj in a ZIP so the CRS is not lost. Just be clear on what the cells hold: a rasterised OSM map — roads, buildings, water burned into the grid — not elevation. There is no terrain in that file. If what you need is an elevation grid, start with HGT and convert it to .asc with a single GDAL command, as in step 1 below. The combination is in demand for academic GIS projects and hydrology.
Step 1. Get the region's terrain as ASCII Grid. Take an HGT tile — order the elevation for your own area or download the original SRTM tile — and convert:
gdal_translate -of AAIGrid N56E043.hgt nizhny.asc
This creates nizhny.asc (text grid) + nizhny.prj (CRS) + nizhny.prj.aux.xml (optional). Georeferencing of a file ordered from the site is nominal — GDAL treats .hgt as a full-degree tile; if the grid must land exactly in place, take the original SRTM tile.
Step 2. On osm2cdr.ru export the region to SHP, GeoJSON, or WKT — vector formats understood by GRASS, GDAL, R.
Step 3. Open both in QGIS or R. Example R workflow for hydrology:
library(raster)
library(sf)
dem <- raster('nizhny.asc')
crs(dem) <- '+proj=longlat +datum=WGS84'
# Import OSM vectors
roads <- st_read('osm_roads.geojson')
# Hillshade
slope <- terrain(dem, opt='slope')
aspect <- terrain(dem, opt='aspect')
hillshade <- hillShade(slope, aspect, angle=45, direction=315)
# Visualize
plot(hillshade, col=grey(0:100/100))
plot(roads, add=TRUE, col='red')
Step 4. You get a topographic chart of Nizhny Novgorod with OSM roads over SRTM terrain.
For batch processing of multiple cities, Python + rasterio + geopandas is faster than R + raster + sf:
import rasterio
import geopandas as gpd
dem = rasterio.open('nizhny.asc')
roads = gpd.read_file('osm_roads.geojson')
# Then any numpy/scipy analysis
Related formats and resources
- HGT — native NASA SRTM tiles
- Terrain RGB — elevation for WebGL maps
- GeoTIFF — binary standard for georeferenced rasters
- CSV — text tabular format
- WKT — text representation of geometry
- SHP landing page on osm2cdr.ru
Sources
- GDAL AAIGrid driver — gdal.org/drivers/raster/aaigrid.html
- ESRI ArcGIS, ASCII to Raster reference — pro.arcgis.com/en/pro-app/tool-reference/conversion/ascii-to-raster.htm
- GRASS GIS, r.in.ascii manual — grass.osgeo.org/grass-stable/manuals/r.in.ascii.html
- TauDEM, ASCII Grid I/O — hydrology.usu.edu/taudem
- R raster package, ASCII read/write — rdrr.io/cran/raster
- Wikipedia, Esri grid — en.wikipedia.org/wiki/Esri_grid