Conformance
terrio's results compared with GDAL's (and laspy's and PDAL's for point clouds) on real-world files: the files of scripts/fetch_test_data.sh (Natural Earth, USGS 3DEP, Sentinel-2, NASA ECOSTRESS and OPERA, OpenStreetMap and more, with copies GDAL derives in other formats), and synthetic rasters for the driver round trips. Each case is identical to the reference, within tolerance (the suite says which), or differs. Regenerate this page with:
cargo build --release
python scripts/conformance.py ../terrio-data --output docs/conformance.md
Generated on 2026-10-14 with terrio 0.1.1 (9e7f7f5), GDAL 3.12.2, PROJ 9.7.1, PDAL 2.9.3, laspy 2.7.0.
Summary
| Suite | Reference | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|---|
| Dataset summaries and pixels | GDAL (gdalinfo, ogrinfo, Python bindings) |
64 | 64 | 0 | 0 |
| Vector conversions | GDAL reading terrio's output | 23 | 23 | 0 | 0 |
| Raster drivers | GDAL writing what terrio reads, and reading what terrio writes | 487 | 487 | 0 | 0 |
| Windowed and overview reads | GDAL reading the same windows | 186 | 186 | 0 | 0 |
| Raster operations | gdal_translate, gdalwarp, gdalbuildvrt, gdal_merge.py |
49 | 42 | 7 | 0 |
| Terrain analysis and raster algebra | gdaldem, gdal_calc.py, gdal_proximity.py, gdal_sieve.py |
131 | 129 | 2 | 0 |
| Vector operations | ogr2ogr, gdal_rasterize, gdal_polygonize.py |
51 | 51 | 0 | 0 |
| Arrow and GeoArrow | GDAL's Arrow streams, pyarrow, GeoPandas | 180 | 171 | 9 | 0 |
| GeoPackage updates and spatial filters | ogr2ogr, GDAL's validate_gpkg.py |
12 | 12 | 0 | 0 |
| Point clouds | laspy (every value), PDAL (headers, PLY, E57 and EPT, COPC and EPT queries, filters, grids, reprojection) and gdal_grid (TIN and nearest-neighbour grids) | 615 | 609 | 6 | 0 |
| Coordinate transformations | GDAL 3.12 and PROJ (gdaltransform) |
19,003 | 18,919 | 72 | 12 |
| Datum shift grids, geoid models and coordinate epochs | GDAL 3.12 and PROJ, with the same grids | 19,253 | 19,123 | 110 | 20 |
| All | 40,054 | 39,816 | 206 | 32 |
Dataset summaries and pixels
Every raster and vector file of the test data: size, type, CRS, geotransform, nodata, band statistics, layers, fields, feature counts and extents as GDAL reports them (numbers within 1e-6 relative, statistics within 1e-4), and every raster pixel exactly.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| GTiff | 15 | 15 | 0 | 0 |
| GeoJSON | 7 | 7 | 0 | 0 |
| FlatGeobuf | 2 | 2 | 0 | 0 |
| GPKG | 4 | 4 | 0 | 0 |
| KML | 3 | 3 | 0 | 0 |
| GML | 1 | 1 | 0 | 0 |
| MapInfo File | 3 | 3 | 0 | 0 |
| Parquet | 2 | 2 | 0 | 0 |
| GPX | 3 | 3 | 0 | 0 |
| CSV | 1 | 1 | 0 | 0 |
| OSM | 2 | 2 | 0 | 0 |
| AAIGrid | 1 | 1 | 0 | 0 |
| ENVI | 1 | 1 | 0 | 0 |
| HFA | 1 | 1 | 0 | 0 |
| JP2 | 2 | 2 | 0 | 0 |
| Zarr | 3 | 3 | 0 | 0 |
| zip archives | 3 | 3 | 0 | 0 |
| KMZ | 1 | 1 | 0 | 0 |
| EHdr | 1 | 1 | 0 | 0 |
| ERS | 1 | 1 | 0 | 0 |
| GSBG | 1 | 1 | 0 | 0 |
| netCDF | 2 | 2 | 0 | 0 |
| RST | 1 | 1 | 0 | 0 |
| SAGA | 1 | 1 | 0 | 0 |
| TopoJSON | 2 | 2 | 0 | 0 |
Vector conversions
A file converted by terrio convert into each format, then read by GDAL: feature counts, fields, CRS, extent and a sample of geometries and attribute values must match what GDAL reads from the original, but for the differences GDAL's reading of ogr2ogr's own conversion into that format has too (KML naming the name field Name, shapefiles truncating field names, MapInfo rounding coordinates to its grid, CSV files without a CRS).
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| GeoJSON | 2 | 2 | 0 | 0 |
| FlatGeobuf | 3 | 3 | 0 | 0 |
| GPKG | 4 | 4 | 0 | 0 |
| ESRI Shapefile | 2 | 2 | 0 | 0 |
| Parquet | 2 | 2 | 0 | 0 |
| CSV | 2 | 2 | 0 | 0 |
| GML | 1 | 1 | 0 | 0 |
| KML | 3 | 3 | 0 | 0 |
| MapInfo File | 2 | 2 | 0 | 0 |
| TopoJSON | 1 | 1 | 0 | 0 |
| GPX | 1 | 1 | 0 | 0 |
Raster drivers
Synthetic rasters of every data type a format holds (several bands, NaN and finite nodata, geographic, projected and user-defined CRSs). Read: GDAL writes, terrio reads; write: terrio writes, GDAL reads. Pixels, type, CRS and nodata must match exactly, geotransforms within 1e-9.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| GTiff (read) | 14 | 14 | 0 | 0 |
| GTiff (write) | 70 | 70 | 0 | 0 |
| COG (read) | 14 | 14 | 0 | 0 |
| COG (write) | 56 | 56 | 0 | 0 |
| AAIGrid (read) | 5 | 5 | 0 | 0 |
| AAIGrid (write) | 5 | 5 | 0 | 0 |
| EHdr (read) | 10 | 10 | 0 | 0 |
| EHdr (write) | 10 | 10 | 0 | 0 |
| ENVI (read) | 12 | 12 | 0 | 0 |
| ENVI (write) | 12 | 12 | 0 | 0 |
| GSBG (read) | 1 | 1 | 0 | 0 |
| GSBG (write) | 1 | 1 | 0 | 0 |
| SAGA (read) | 7 | 7 | 0 | 0 |
| SAGA (write) | 7 | 7 | 0 | 0 |
| RST (read) | 4 | 4 | 0 | 0 |
| RST (write) | 4 | 4 | 0 | 0 |
| ERS (read) | 11 | 11 | 0 | 0 |
| ERS (write) | 11 | 11 | 0 | 0 |
| HFA (read) | 11 | 11 | 0 | 0 |
| PNG (read) | 3 | 3 | 0 | 0 |
| PNG (write) | 3 | 3 | 0 | 0 |
| JPEG (read) | 2 | 2 | 0 | 0 |
| JPEG (write) | 2 | 2 | 0 | 0 |
| JP2OpenJPEG (read) | 5 | 5 | 0 | 0 |
| JP2OpenJPEG (write) | 5 | 5 | 0 | 0 |
| XYZ (read) | 5 | 5 | 0 | 0 |
| XYZ (write) | 5 | 5 | 0 | 0 |
| Zarr (read) | 65 | 65 | 0 | 0 |
| Zarr (write) | 65 | 65 | 0 | 0 |
| netCDF (read) | 26 | 26 | 0 | 0 |
| netCDF (write) | 26 | 26 | 0 | 0 |
| GPKG (read) | 5 | 5 | 0 | 0 |
| GPKG (write) | 5 | 5 | 0 | 0 |
Windowed and overview reads
Windows of every GeoTIFF of the test data, at full resolution and from each overview, read in place by terrio convert --srcwin --overview: pixels identical, geotransforms within 1e-9. Remote: the same on public Cloud Optimized GeoTIFFs over HTTP.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| GTiff local, full resolution | 60 | 60 | 0 | 0 |
| GTiff local, overviews | 104 | 104 | 0 | 0 |
| GTiff remote, headers | 4 | 4 | 0 | 0 |
| GTiff remote, full resolution | 4 | 4 | 0 | 0 |
| GTiff remote, overviews | 14 | 14 | 0 | 0 |
Raster operations
The outputs of the same command lines on real files: size, type, CRS and geotransform must match, then pixels are compared. Identical: every pixel equal. Within tolerance: every pixel within the case's tolerance (1e-2 for interpolating resamplings).
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| translate | 14 | 14 | 0 | 0 |
| warp | 28 | 21 | 7 | 0 |
| mosaic | 5 | 5 | 0 | 0 |
| read | 2 | 2 | 0 | 0 |
Cases that are not identical:
| Format or operation | Case | Result | Details |
|---|---|---|---|
| warp | warp DEM NAD83->UTM bilinear | within tolerance | 5 pixels differ (3.957e-05 %), max difference 0.000244 |
| warp | warp DEM NAD83->UTM cubic | within tolerance | 4 pixels differ (3.166e-05 %), max difference 0.000244 |
| warp | warp DEM NAD83->UTM cubicspline | within tolerance | 4 pixels differ (3.166e-05 %), max difference 0.000244 |
| warp | warp DEM NAD83->UTM lanczos | within tolerance | 5 pixels differ (3.957e-05 %), max difference 0.000244 |
| warp | warp DEM NAD83->UTM average | within tolerance | 2 pixels differ (1.582e-05 %), max difference 0.000244 |
| warp | warp DEM NAD83->UTM rms | within tolerance | 7 pixels differ (5.538e-05 %), max difference 0.000244 |
| warp | warp DEM ->3857 tr 100 bilinear (-ovr NONE) | within tolerance | 1 pixels differ (6.187e-05 %), max difference 0.000122 |
Terrain analysis and raster algebra
The outputs of the same command lines on real DEMs and land cover: size, type, nodata and geotransform must match, then pixels are compared. Within tolerance: every pixel within the case's tolerance (float32 rounding of NumPy's SIMD functions, for example).
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| dem hillshade | 25 | 25 | 0 | 0 |
| dem slope | 14 | 14 | 0 | 0 |
| dem aspect | 10 | 10 | 0 | 0 |
| dem TRI | 7 | 7 | 0 | 0 |
| dem TPI | 6 | 6 | 0 | 0 |
| dem roughness | 6 | 6 | 0 | 0 |
| dem color-relief | 13 | 13 | 0 | 0 |
| calc landsat | 13 | 13 | 0 | 0 |
| calc usgs | 10 | 8 | 2 | 0 |
| calc srtm90 | 4 | 4 | 0 | 0 |
| calc dem | 2 | 2 | 0 | 0 |
| calc las_vegas | 1 | 1 | 0 | 0 |
| calc nlcd | 2 | 2 | 0 | 0 |
| calc mixed | 2 | 2 | 0 | 0 |
| calc extent | 2 | 2 | 0 | 0 |
| calc projwin | 1 | 1 | 0 | 0 |
| proximity nlcd | 2 | 2 | 0 | 0 |
| proximity usgs | 4 | 4 | 0 | 0 |
| proximity landsat | 1 | 1 | 0 | 0 |
| sieve nlcd | 3 | 3 | 0 | 0 |
| sieve usgs | 2 | 2 | 0 | 0 |
| sieve landsat | 1 | 1 | 0 | 0 |
Cases that are not identical:
| Format or operation | Case | Result | Details |
|---|---|---|---|
| calc usgs | calc usgs functions (NumPy SIMD float32) | within tolerance | 2797827 pixels differ (21.44 %), max difference 3.81e-06 |
| calc usgs | calc usgs arctan2 hypot (NumPy SIMD float32) | within tolerance | 2333 pixels differ (0.01788 %), max difference 0.000488 |
Vector operations
Conversions with ogr2ogr's options (where, spat, select, sql, nlt...) compared feature by feature; rasterized pixels compared exactly; polygons compared by count, holes and validity, and by rasterizing them back.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| convert (ogr2ogr options) | 28 | 28 | 0 | 0 |
| convert --append/--overwrite | 1 | 1 | 0 | 0 |
| rasterize | 18 | 18 | 0 | 0 |
| polygonize | 4 | 4 | 0 | 0 |
Arrow and GeoArrow
Every layer of the test data exported with Layer.to_arrow() (WKB and native GeoArrow) against GDAL's Arrow stream of the same layer, through pyarrow and GeoPandas, and imported back with terrio.from_arrow() (and by GDAL's WriteArrow): rows, geometries, attribute values and CRS. Within tolerance: geometries equal up to vertex order.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| export WKB vs GDAL | 16 | 15 | 1 | 0 |
| export CRS vs GDAL | 16 | 16 | 0 | 0 |
| export geoarrow.multipolygon (separated) vs GDAL | 6 | 5 | 1 | 0 |
| import geoarrow.multipolygon (separated) | 6 | 6 | 0 | 0 |
| export geoarrow.multipolygon (interleaved) vs GDAL | 6 | 5 | 1 | 0 |
| import geoarrow.multipolygon (interleaved) | 6 | 6 | 0 | 0 |
| GeoDataFrame.from_arrow vs GDAL | 12 | 11 | 1 | 0 |
| import GDAL stream (WKB) | 16 | 15 | 1 | 0 |
| import ogr.Layer | 16 | 15 | 1 | 0 |
| import GeoDataFrame.to_arrow(WKB) | 12 | 11 | 1 | 0 |
| import GeoDataFrame.to_arrow(geoarrow) | 12 | 11 | 1 | 0 |
| GDAL WriteArrow of terrio's table | 16 | 15 | 1 | 0 |
| export geoarrow.point (separated) vs GDAL | 5 | 5 | 0 | 0 |
| import geoarrow.point (separated) | 5 | 5 | 0 | 0 |
| export geoarrow.point (interleaved) vs GDAL | 5 | 5 | 0 | 0 |
| import geoarrow.point (interleaved) | 5 | 5 | 0 | 0 |
| export geoarrow.linestring (separated) vs GDAL | 3 | 3 | 0 | 0 |
| import geoarrow.linestring (separated) | 3 | 3 | 0 | 0 |
| export geoarrow.linestring (interleaved) vs GDAL | 3 | 3 | 0 | 0 |
| import geoarrow.linestring (interleaved) | 3 | 3 | 0 | 0 |
| export geoarrow.multilinestring (separated) vs GDAL | 2 | 2 | 0 | 0 |
| import geoarrow.multilinestring (separated) | 2 | 2 | 0 | 0 |
| export geoarrow.multilinestring (interleaved) vs GDAL | 2 | 2 | 0 | 0 |
| import geoarrow.multilinestring (interleaved) | 2 | 2 | 0 | 0 |
Cases that are not identical:
| Format or operation | Case | Result | Details |
|---|---|---|---|
| export WKB vs GDAL | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850 |
| export geoarrow.multipolygon (separated) vs GDAL | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850 |
| export geoarrow.multipolygon (interleaved) vs GDAL | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850 |
| GeoDataFrame.from_arrow vs GDAL | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850, crs same |
| import GDAL stream (WKB) | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850, crs same |
| import ogr.Layer | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850 |
| import GeoDataFrame.to_arrow(WKB) | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850, crs same |
| import GeoDataFrame.to_arrow(geoarrow) | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850, crs same |
| GDAL WriteArrow of terrio's table | liechtenstein.osm.pbf:multipolygons | within tolerance | rows 24314, geometries 24274/24314 (24314 equal up to vertex order), values 607850/607850 |
GeoPackage updates and spatial filters
--append, --overwrite and added layers compared with ogr2ogr (features, extents, counts, sequences, R-trees, integrity_check, the GeoPackage validator, rasters kept), and --spat through the R-tree compared with ogr2ogr -spat.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| append | 4 | 4 | 0 | 0 |
| add | 2 | 2 | 0 | 0 |
| --spat | 6 | 6 | 0 | 0 |
Point clouds
Every dimension of every point equal to laspy's; headers equal to laspy's and PDAL's; written files read back identically by laspy and PDAL; PLY, E57 and EPT points equal to PDAL's; COPC and EPT queries returning the same points as PDAL's; waveform samples equal to the file's packets; filters giving the same classes or points as PDAL's; grids equal to PDAL's writers.gdal. Reprojections are within 2e-7 degrees or 2 mm of PDAL's; TIN grids differ from gdal_grid's where points share an x and y.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| read vs laspy | 56 | 56 | 0 | 0 |
| header vs laspy | 56 | 56 | 0 | 0 |
| header vs PDAL | 56 | 56 | 0 | 0 |
| write and read back (laspy) | 159 | 159 | 0 | 0 |
| write and read back (PDAL) | 141 | 141 | 0 | 0 |
| COPC queries vs PDAL | 9 | 9 | 0 | 0 |
| grid vs PDAL writers.gdal | 8 | 8 | 0 | 0 |
| reproject vs PDAL | 3 | 0 | 3 | 0 |
| PLY, E57 and EPT vs PDAL | 24 | 24 | 0 | 0 |
| EPT queries vs PDAL | 4 | 4 | 0 | 0 |
| PLY, E57 and EPT written, read back | 8 | 8 | 0 | 0 |
| waveforms | 3 | 3 | 0 | 0 |
| filters vs PDAL | 84 | 84 | 0 | 0 |
| TIN and nearest grids vs gdal_grid | 4 | 1 | 3 | 0 |
Cases that are not identical:
| Format or operation | Case | Result | Details |
|---|---|---|---|
| reproject vs PDAL | reproject test_utm16.las to EPSG:4269 | within tolerance | max |dx| 9.41e-08, |dy| 6.91e-08 |
| reproject vs PDAL | reproject las_with_several_extra_byte_bloc.laz to EPSG:4326 | within tolerance | max |dx| 9.67e-08, |dy| 8.86e-08 |
| reproject vs PDAL | reproject format6.laz to EPSG:5070 | within tolerance | max |dx| 0.000784, |dy| 0.000838 |
| TIN and nearest grids vs gdal_grid | interp linear autzen_trim.las res 6.0 vs gdal_grid -a linear:radius=0 (197x94) | within tolerance | 16 of 18518 cells differ (99.914% identical) |
| TIN and nearest grids vs gdal_grid | interp linear autzen_trim.las res 6.0 vs gdal_grid -a linear (197x94) | within tolerance | 16 of 18518 cells differ (99.914% identical) |
| TIN and nearest grids vs gdal_grid | interp nearest autzen_trim.las res 6.0 vs gdal_grid -a nearest:radius1=8:radius2=8 (197x94) | within tolerance | 1 of 18518 cells differ (99.995% identical) |
Coordinate transformations
A reference point per EPSG geographic and projected CRS, transformed from WGS 84 (forward) and back (inverse), and between pairs of CRSs, compared with GDAL's results, neither using datum shift grids. Identical: within 1 mm. Within tolerance: within 1 cm (forward, inverse) or 1 m (CRS to CRS, where the datum transformations GDAL picks can differ by area of use).
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| forward (WGS 84 to CRS) | 6,354 | 6,353 | 1 | 0 |
| inverse (CRS to WGS 84) | 6,354 | 6,344 | 10 | 0 |
| CRS to CRS | 6,295 | 6,222 | 61 | 12 |
Cases that are not identical:
| Format or operation | Case | Result | Details |
|---|---|---|---|
| CRS to CRS | EPSG:4260 to EPSG:8859 | differs | 187.3931 m |
| CRS to CRS | EPSG:4809 to EPSG:4231 | differs | 129.3122 m |
| CRS to CRS | EPSG:6054 to EPSG:4287 | differs | 253.9519 m |
| CRS to CRS | EPSG:8043 to EPSG:5514 | differs | 115.2085 m |
| CRS to CRS | EPSG:10454 to EPSG:9054 | differs | 1.7425 m |
| CRS to CRS | EPSG:10459 to EPSG:10606 | differs | 1.8085 m |
| CRS to CRS | EPSG:23030 to EPSG:9053 | differs | 1.4924 m |
| CRS to CRS | EPSG:26393 to EPSG:23433 | differs | 122.2885 m |
| CRS to CRS | EPSG:26759 to EPSG:32417 | differs | 4.6988 m |
| CRS to CRS | EPSG:28357 to EPSG:9053 | differs | 1.2973 m |
| CRS to CRS | EPSG:29849 to EPSG:4740 | differs | 3.4770 m |
| CRS to CRS | EPSG:29850 to EPSG:9054 | differs | 1.9887 m |
| CRS to CRS | EPSG:2392 to EPSG:4124 | within tolerance | 0.2245 m |
| CRS to CRS | EPSG:3108 to EPSG:8998 | within tolerance | 0.3415 m |
| CRS to CRS | EPSG:3312 to EPSG:31171 | within tolerance | 0.0020 m |
| CRS to CRS | EPSG:3768 to EPSG:3908 | within tolerance | 0.5240 m |
| inverse (CRS to WGS 84) | EPSG:3973 | within tolerance | 0.0015 m |
| inverse (CRS to WGS 84) | EPSG:3975 | within tolerance | 0.0011 m |
| CRS to CRS | EPSG:5513 to EPSG:5224 | within tolerance | 0.5652 m |
| inverse (CRS to WGS 84) | EPSG:5633 | within tolerance | 0.0011 m |
| inverse (CRS to WGS 84) | EPSG:5635 | within tolerance | 0.0014 m |
| CRS to CRS | EPSG:5635 to EPSG:8989 | within tolerance | 0.0014 m |
| CRS to CRS | EPSG:6333 to EPSG:8993 | within tolerance | 0.0445 m |
| CRS to CRS | EPSG:6402 to EPSG:8990 | within tolerance | 0.0087 m |
| CRS to CRS | EPSG:6405 to EPSG:8991 | within tolerance | 0.0149 m |
| CRS to CRS | EPSG:6423 to EPSG:8992 | within tolerance | 0.0149 m |
| CRS to CRS | EPSG:6432 to EPSG:8994 | within tolerance | 0.0145 m |
| CRS to CRS | EPSG:6446 to EPSG:8993 | within tolerance | 0.0223 m |
| CRS to CRS | EPSG:6448 to EPSG:8988 | within tolerance | 0.0135 m |
| CRS to CRS | EPSG:6449 to EPSG:8996 | within tolerance | 0.0135 m |
| CRS to CRS | EPSG:6454 to EPSG:8990 | within tolerance | 0.0142 m |
| CRS to CRS | EPSG:6459 to EPSG:8989 | within tolerance | 0.0141 m |
| CRS to CRS | EPSG:6464 to EPSG:8992 | within tolerance | 0.0140 m |
| CRS to CRS | EPSG:6475 to EPSG:8994 | within tolerance | 0.0145 m |
| CRS to CRS | EPSG:6506 to EPSG:8998 | within tolerance | 0.0015 m |
| CRS to CRS | EPSG:6512 to EPSG:8992 | within tolerance | 0.0144 m |
| CRS to CRS | EPSG:6532 to EPSG:8989 | within tolerance | 0.0149 m |
| CRS to CRS | EPSG:6541 to EPSG:8998 | within tolerance | 0.0014 m |
| CRS to CRS | EPSG:6549 to EPSG:8994 | within tolerance | 0.0139 m |
| CRS to CRS | EPSG:6550 to EPSG:8990 | within tolerance | 0.0142 m |
| CRS to CRS | EPSG:6556 to EPSG:8988 | within tolerance | 0.0134 m |
| CRS to CRS | EPSG:6576 to EPSG:8998 | within tolerance | 0.0015 m |
| CRS to CRS | EPSG:6597 to EPSG:8992 | within tolerance | 0.0128 m |
| CRS to CRS | EPSG:6607 to EPSG:8988 | within tolerance | 0.0132 m |
| CRS to CRS | EPSG:6614 to EPSG:8989 | within tolerance | 0.0137 m |
| CRS to CRS | EPSG:6616 to EPSG:8998 | within tolerance | 0.0016 m |
| CRS to CRS | EPSG:6787 to EPSG:8996 | within tolerance | 0.0133 m |
| CRS to CRS | EPSG:6820 to EPSG:9000 | within tolerance | 0.0134 m |
| CRS to CRS | EPSG:6839 to EPSG:8992 | within tolerance | 0.0135 m |
| CRS to CRS | EPSG:6862 to EPSG:8990 | within tolerance | 0.0134 m |
| inverse (CRS to WGS 84) | EPSG:6931 | within tolerance | 0.0015 m |
| inverse (CRS to WGS 84) | EPSG:6933 | within tolerance | 0.0011 m |
| CRS to CRS | EPSG:7059 to EPSG:8988 | within tolerance | 0.0137 m |
| CRS to CRS | EPSG:7260 to EPSG:8995 | within tolerance | 0.0140 m |
| CRS to CRS | EPSG:7285 to EPSG:8994 | within tolerance | 0.0143 m |
| CRS to CRS | EPSG:7321 to EPSG:8990 | within tolerance | 0.0141 m |
| CRS to CRS | EPSG:7322 to EPSG:8990 | within tolerance | 0.0141 m |
| CRS to CRS | EPSG:7336 to EPSG:8991 | within tolerance | 0.0139 m |
| CRS to CRS | EPSG:7353 to EPSG:8990 | within tolerance | 0.0142 m |
| CRS to CRS | EPSG:7364 to EPSG:8991 | within tolerance | 0.0140 m |
| ... and 24 more |
Datum shift grids, geoid models and coordinate epochs
The EPSG reference points again, GDAL and terrio both using the grids of scripts/proj_grids.txt (crates/terrio/tests/epsg_accuracy_grids.rs); then random points through every horizontal shift grid (NTv2 and GeoTIFF, forward and inverse), geoid models (GeoTIFF and GTX), NADCON5 and geocentric translation grids, compound CRSs and time-dependent transformations with coordinate epochs (scripts/compare_crs_grids_with_gdal.py), with the largest difference of each case. Identical: within 1 mm. Within tolerance: within 1 cm, or 1 m from CRS to CRS.
| Format or operation | Cases | Identical | Within tolerance | Differs |
|---|---|---|---|---|
| forward (WGS 84 to CRS) with grids | 6,354 | 6,353 | 1 | 0 |
| inverse (CRS to WGS 84) with grids | 6,354 | 6,344 | 10 | 0 |
| CRS to CRS with grids | 6,295 | 6,176 | 99 | 20 |
| grids, geoids and epochs | 250 | 250 | 0 | 0 |
Cases that are not identical:
| Format or operation | Case | Result | Details |
|---|---|---|---|
| CRS to CRS with grids | EPSG:3080 to EPSG:8992 | differs | 39.8129 m |
| CRS to CRS with grids | EPSG:4260 to EPSG:8859 | differs | 187.3931 m |
| CRS to CRS with grids | EPSG:4809 to EPSG:4231 | differs | 129.3122 m |
| CRS to CRS with grids | EPSG:6054 to EPSG:4287 | differs | 253.9519 m |
| CRS to CRS with grids | EPSG:6202 to EPSG:9990 | differs | 4.8007 m |
| CRS to CRS with grids | EPSG:6738 to EPSG:8992 | differs | 1.1348 m |
| CRS to CRS with grids | EPSG:7991 to EPSG:3979 | differs | 2.4440 m |
| CRS to CRS with grids | EPSG:8043 to EPSG:5514 | differs | 115.2085 m |
| CRS to CRS with grids | EPSG:10454 to EPSG:9054 | differs | 1.7425 m |
| CRS to CRS with grids | EPSG:10459 to EPSG:10606 | differs | 1.8085 m |
| CRS to CRS with grids | EPSG:22645 to EPSG:3797 | differs | 53.9743 m |
| CRS to CRS with grids | EPSG:23030 to EPSG:9053 | differs | 1.4924 m |
| CRS to CRS with grids | EPSG:26393 to EPSG:23433 | differs | 122.2885 m |
| CRS to CRS with grids | EPSG:26787 to EPSG:32419 | differs | 9.8907 m |
| CRS to CRS with grids | EPSG:26801 to EPSG:9056 | differs | 3.8647 m |
| CRS to CRS with grids | EPSG:28357 to EPSG:9053 | differs | 1.2973 m |
| CRS to CRS with grids | EPSG:29849 to EPSG:4740 | differs | 3.4770 m |
| CRS to CRS with grids | EPSG:29850 to EPSG:9054 | differs | 1.9887 m |
| CRS to CRS with grids | EPSG:32086 to EPSG:22646 | differs | 46.3493 m |
| CRS to CRS with grids | EPSG:32218 to EPSG:2163 | differs | 5.9635 m |
| CRS to CRS with grids | EPSG:2392 to EPSG:4124 | within tolerance | 0.2245 m |
| CRS to CRS with grids | EPSG:2776 to EPSG:4759 | within tolerance | 0.0052 m |
| CRS to CRS with grids | EPSG:2793 to EPSG:3529 | within tolerance | 0.0031 m |
| CRS to CRS with grids | EPSG:2840 to EPSG:5072 | within tolerance | 0.0388 m |
| CRS to CRS with grids | EPSG:2843 to EPSG:3662 | within tolerance | 0.1508 m |
| CRS to CRS with grids | EPSG:2852 to EPSG:3614 | within tolerance | 0.0500 m |
| CRS to CRS with grids | EPSG:2871 to EPSG:3492 | within tolerance | 0.1760 m |
| CRS to CRS with grids | EPSG:2872 to EPSG:2227 | within tolerance | 0.0857 m |
| CRS to CRS with grids | EPSG:2918 to EPSG:3665 | within tolerance | 0.0222 m |
| CRS to CRS with grids | EPSG:2968 to EPSG:3529 | within tolerance | 0.0031 m |
| CRS to CRS with grids | EPSG:3087 to EPSG:26917 | within tolerance | 0.1727 m |
| CRS to CRS with grids | EPSG:3108 to EPSG:8998 | within tolerance | 0.3415 m |
| CRS to CRS with grids | EPSG:3309 to EPSG:8857 | within tolerance | 0.7493 m |
| CRS to CRS with grids | EPSG:3312 to EPSG:31171 | within tolerance | 0.0020 m |
| CRS to CRS with grids | EPSG:3363 to EPSG:3650 | within tolerance | 0.0115 m |
| CRS to CRS with grids | EPSG:3457 to EPSG:4759 | within tolerance | 0.0777 m |
| CRS to CRS with grids | EPSG:3485 to EPSG:2764 | within tolerance | 0.0137 m |
| CRS to CRS with grids | EPSG:3511 to EPSG:2778 | within tolerance | 0.0167 m |
| CRS to CRS with grids | EPSG:3542 to EPSG:3428 | within tolerance | 0.0095 m |
| CRS to CRS with grids | EPSG:3582 to EPSG:2893 | within tolerance | 0.0070 m |
| CRS to CRS with grids | EPSG:3618 to EPSG:3085 | within tolerance | 0.0174 m |
| CRS to CRS with grids | EPSG:3721 to EPSG:5071 | within tolerance | 0.0105 m |
| CRS to CRS with grids | EPSG:3732 to EPSG:2864 | within tolerance | 0.0318 m |
| CRS to CRS with grids | EPSG:3768 to EPSG:3908 | within tolerance | 0.5240 m |
| inverse (CRS to WGS 84) with grids | EPSG:3973 | within tolerance | 0.0015 m |
| inverse (CRS to WGS 84) with grids | EPSG:3975 | within tolerance | 0.0011 m |
| CRS to CRS with grids | EPSG:5513 to EPSG:5224 | within tolerance | 0.5152 m |
| inverse (CRS to WGS 84) with grids | EPSG:5633 | within tolerance | 0.0011 m |
| inverse (CRS to WGS 84) with grids | EPSG:5635 | within tolerance | 0.0014 m |
| CRS to CRS with grids | EPSG:5635 to EPSG:8989 | within tolerance | 0.0014 m |
| CRS to CRS with grids | EPSG:5651 to EPSG:9000 | within tolerance | 0.6038 m |
| CRS to CRS with grids | EPSG:6333 to EPSG:8993 | within tolerance | 0.0445 m |
| CRS to CRS with grids | EPSG:6402 to EPSG:8990 | within tolerance | 0.0087 m |
| CRS to CRS with grids | EPSG:6405 to EPSG:8991 | within tolerance | 0.0149 m |
| CRS to CRS with grids | EPSG:6423 to EPSG:8992 | within tolerance | 0.0149 m |
| CRS to CRS with grids | EPSG:6432 to EPSG:8994 | within tolerance | 0.0145 m |
| CRS to CRS with grids | EPSG:6446 to EPSG:8993 | within tolerance | 0.0223 m |
| CRS to CRS with grids | EPSG:6448 to EPSG:8988 | within tolerance | 0.0135 m |
| CRS to CRS with grids | EPSG:6449 to EPSG:8996 | within tolerance | 0.0135 m |
| CRS to CRS with grids | EPSG:6454 to EPSG:8990 | within tolerance | 0.0142 m |
| ... and 70 more |