Proj.jl icon indicating copy to clipboard operation
Proj.jl copied to clipboard

Proj.Transformation should error if it cannot create a transformation

Open tiemvanderdeure opened this issue 1 week ago • 4 comments

This issue came up in Rasters where Proj segfaults when attempting to create a CRS transformation: https://github.com/rafaqz/Rasters.jl/issues/895

MWE:

using Proj, GeoFormatTypes
crs_string = "LOCAL_CS[\"unnamed\",UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]],AXIS[\"Easting\",EAST],AXIS[\"Northing\",NORTH]]"
crs = WellKnownText(GeoFormatTypes.CRS(), crs_string)
transform = Proj.Transformation(crs, EPSG(4326)) # works, but show errors
transform.pj === C_NULL # true
Proj.Transformation(crs, EPSG(4326); always_xy = true) # segfaults!!

This is a CRS that is valid but cannot be transformed (according to @evetion), Proj.Transformation returns a null pointer, and if always_xy is set to true, normalize_axis_order! is called on it, which causes the segfault.

Probably Proj should just error instead of returning a null string, similar to ArchGDAL:

using ArchGDAL
gdalcrs = ArchGDAL.importCRS(crs)
target = ArchGDAL.importEPSG(4326)
ArchGDAL.createcoordtrans(gdalcrs, target) do transform end
ERROR: GDALError (CE_Failure, code 6):
        Cannot find coordinate operations from `{
  "$schema": "https://proj.org/schemas/v0.7/projjson.schema.json",
  "type": "EngineeringCRS",
  "name": "unnamed",
  "datum": {
    "name": "Unknown engineering datum"
  },
  "coordinate_system": {
    "subtype": "Cartesian",
    "axis": [
      {
        "name": "Easting",
        "abbreviation": "",
        "direction": "east",
        "unit": "metre"
      },
      {
        "name": "Northing",
        "abbreviation": "",
        "direction": "north",
        "unit": "metre"
      }
    ]
  }
}' to `EPSG:4326'

Stacktrace:
 [1] maybe_throw()
   @ GDAL C:\Users\tsh371\.julia\packages\GDAL\8oAvY\src\error.jl:42
 [2] aftercare
   @ C:\Users\tsh371\.julia\packages\GDAL\8oAvY\src\error.jl:59 [inlined]
 [3] octnewcoordinatetransformation
   @ C:\Users\tsh371\.julia\packages\GDAL\8oAvY\src\libgdal.jl:38029 [inlined]
 [4] unsafe_createcoordtrans(source::ArchGDAL.ISpatialRef, target::ArchGDAL.ISpatialRef)
   @ ArchGDAL C:\Users\tsh371\.julia\packages\ArchGDAL\ujstt\src\spatialref.jl:812
 [5] createcoordtrans(::var"#11#12", ::ArchGDAL.ISpatialRef, ::Vararg{ArchGDAL.ISpatialRef}; kwargs::@Kwargs{})
   @ ArchGDAL C:\Users\tsh371\.julia\packages\ArchGDAL\ujstt\src\context.jl:266
 [6] createcoordtrans(::Function, ::ArchGDAL.ISpatialRef, ::Vararg{ArchGDAL.ISpatialRef})
   @ ArchGDAL C:\Users\tsh371\.julia\packages\ArchGDAL\ujstt\src\context.jl:265
 [7] top-level scope

tiemvanderdeure avatar Feb 15 '25 13:02 tiemvanderdeure