OSGeo / gdal

GDAL is an open source MIT licensed translator library for raster and vector geospatial data formats.
https://gdal.org
Other
4.77k stars 2.5k forks source link

[DXF] Retrieve the version of the DXF file #9495

Open lbartoletti opened 5 months ago

lbartoletti commented 5 months ago

Feature description

Unless I'm mistaken, it doesn't seem possible to obtain the version of a DXF file opened with GDAL. In my Python context, there's no function like GetVersion or GetVariables("ACADVER") available to retrieve the file version name.

I believe this variable is indeed read because it's among the first in the HEADER. However, it's not exposed.

In pure python, one could get this information with this dirty script:

# Mapping of AutoCAD versions to version names
# from https://help.autodesk.com/view/OARX/2024/ENU/?guid=GUID-A85E8E67-27CD-4C59-BE61-4DC9FADBE74A
autocad_versions = {
    "AC1006": "R10",
    #"AC1009": "R11 and R12",
    "AC1009": "R12",
    "AC1012": "R13",
    "AC1014": "R14",
    "AC1015": "AutoCAD 2000",
    "AC1018": "AutoCAD 2004",
    "AC1021": "AutoCAD 2007",
    "AC1024": "AutoCAD 2010",
    "AC1027": "AutoCAD 2013",
    "AC1032": "AutoCAD 2018"
}

def get_acadver_from_dxf(dxf_file):
    try:
        # Open the DXF file
        with open(dxf_file, 'r') as f:
            lines = f.readlines()

        # Search for the line with "$ACADVER"
        # $ACADVER is in the header section
        # Tipically a DXF file, will have this part:
        # $ACADVER
        #  1
        # ACXXX
        # Where $ACADVER is the variable
        #  1, the group code
        # and ACXXX the version id
        for i, line in enumerate(lines):
            if line.strip() == '$ACADVER':
                # Check if the next line exists
                if i + 2 < len(lines):
                    # Extract the version information from the next line
                    acadver = lines[i + 2].strip()
                    return acadver
                else:
                    raise ValueError("Version information not found after '$ACADVER' line.")

        # If '$ACADVER' line not found, raise an error
        raise ValueError("'$ACADVER' line not found in the DXF file.")

    except Exception as e:
        print("Error:", e)
        return None

# Example usage
dxf_file = "/path/to/you/autocad.dxf"
acadver = get_acadver_from_dxf(dxf_file)
if acadver:
    acadvername = autocad_versions.get(acadver, "Unknown")
    print("ACADVER:", acadver)
    print("ACADVER Name:", acadvername)
else:
    print("ACADVER not found or invalid in the DXF file.")

Would it be possible to have a method to retrieve the version of the DXF file?

Thanks,

Additional context

Related issue: https://github.com/Guts/DicoGIS/issues/228

rouault commented 5 months ago

Would it be possible to have a method to retrieve the version of the DXF file?

if you want to tackle this, the way to go would probably to expose that information in a dedicated "DXF" metadata domain, and you would fech it with dataset.GetMetadataItem("$ACADVER", "DXF"). (As the GDAL API is potentially usable for all drivers, we can't extend it just for the needs of a single driver)