UPDATE 26 December 2023

The DXF file was created via the Export Project to DXF function in QGIS 3.34. Although the exported DXF was set to EPSG 3395, that designation is not set in the dxf.coordinate_type. The answer by mozman and the previously displayed code have been combined as the following:

import ezdxf
from ezdxf import transform
from ezdxf.math import Matrix44

CRS_TO_WCS = True

doc = ezdxf.readfile("tester.dxf")
msp = doc.modelspace()
geo_data = msp.get_geodata()


def wcs_to_crs(entities, m):
    transform.inplace(entities, m)

def crs_to_wcs(entities, m):
    m = m.copy()
    m.inverse()
    transform.inplace(entities, m)

if geo_data:
    # Get the transformation matrix and epsg code:
    m, epsg = geo_data.get_crs_transformation()
else:
    # Identity matrix for DXF files without a geo location reference:
    m = Matrix44()
    epsg = 3395

if geo_data:
    m, epsg = geo_data.get_crs_transformation()
    if CRS_TO_WCS:
        crs_to_wcs(msp)
    else:
        wcs_to_crs(msp)
else:
    print("No geo reference data available.")

The result is "No geo reference data available."

I will ask a separate question (ezdxf - DXF - set CRS for DXF file internally or via python) to set the CRS value.


All entities in the tester DXF are either TEXT or LWPOLYLINE.

My goal is to transform all LWPOLYLINE and TEXT entities in all layers in the DXF recursively from EPSG 3395 (latitude longitude in decimal degrees) to WCS coordinates, and then save that revised DXF file as a new file.

In order to do so, should I use crs_to_wcs or globe_to_map? Is there a good example that shows the steps?

Below is the python code modified from the ezdxf documentation:

import ezdxf
from ezdxf.math import Matrix44
from ezdxf.addons import geo

doc = ezdxf.readfile("tester.dxf")

msp = doc.modelspace()

# Get the geo location information from the DXF file:
geo_data = msp.get_geodata()
if geo_data:
    # Get transformation matrix and epsg code:
    m, epsg = geo_data.get_crs_transformation()
else:
    # Identity matrix for DXF files without geo reference data:
    m = Matrix44()
    epsg = 3395
1

There are 1 best solutions below

0
mozman On

The geo add-on implements the __geo_interface__ and is not required here.

import ezdxf
from ezdxf import transform

CRS_TO_WCS = True

doc = ezdxf.readfile("tester.dxf")
msp = doc.modelspace()
geo_data = msp.get_geodata()


def wcs_to_crs(entities, m):
    transform.inplace(entities, m)

def crs_to_wcs(entities, m):
    m = m.copy()
    m.inverse()
    transform.inplace(entities, m)

if geo_data:
    m, epsg = geo_data.get_crs_transformation()
    if CRS_TO_WCS:
        crs_to_wcs(msp)
    else:
        wcs_to_crs(msp)
else:
   print("No geo reference data available.")

Please read the docs for the GEODATA entity to understand the limitations.

  • works only for local grid (linear) transformation
  • works only for known CRS configurations
  • GEODATA version 1 is not really supported (no docs)