Drop a DXF file onto your GIS and the geometry lands in the middle of the ocean, rotated 90 degrees, scaled by 25.4. Or it lands in the right country but offset by a few hundred metres. Or it imports cleanly into QGIS but every feature ends up on a single layer called “0” with no attributes beyond the original AutoCAD entity type.
This is not a bug you can fix with a setting. The CAD-GIS format gap is structural. DWG and DXF were designed for engineering drawings, not for placing things on Earth. GIS formats were designed for the opposite. The two worlds have different answers to three fundamental questions: where are these objects, what do we know about them, and how do they relate to each other?
The Coordinate System Problem
A DXF file stores coordinates as floating-point X, Y, Z values. They might be 0.0, 0.0 to 3000.0, 2000.0 for a small panel, or 452301.5, 3812440.2 for a survey drawing using a local projected coordinate system. The file itself contains no metadata binding those numbers to a real-world coordinate reference system (CRS).
The standard DXF spec (the open AutoCAD exchange format) has no mandatory field for EPSG codes, WGS84 bounds, or projection parameters. AutoCAD Civil 3D adds CRS information via a proprietary DXF group code block that Civil 3D writes and reads, but this extension is invisible to software that reads standard DXF — including QGIS, GDAL, and most open-source tooling.
The result: when you tell QGIS “this DXF is in EPSG:32633 (UTM Zone 33N)”, QGIS does what you say. If you’re wrong — if the drawing was drafted in millimetres relative to a local origin with no relationship to UTM — the file lands somewhere in the Adriatic Sea.
What makes this worse in practice:
- Surveyors and civil engineers sometimes use Northing/Easting coordinates directly as X/Y in AutoCAD, which means the coordinates are in a real CRS but that information is nowhere in the file.
- Mechanical engineers never use real-world coordinates. Their drawings start at 0,0 because parts don’t have geographic locations.
- The same DXF file extension covers both cases. There is no way to tell which you have without either asking the originator or opening the file and checking whether the coordinate ranges make sense.
The World File Workaround
For DXF/DWG data from surveyors or civil engineers who used real-world coordinates, you can associate a CRS using a sidecar file. For ArcGIS, this is a .prj file with the same base name as the DXF containing the WKT projection definition. QGIS respects the same convention.
building_survey.dxf
building_survey.prj ← WKT definition of EPSG:27700 (British National Grid)
This works when the originator confirms which projected CRS the drawing was drafted in. For data from unknown sources, you’re guessing — and wrong guesses produce silently misaligned data.
Georeferencing from Scratch
When the DXF has no geographic relationship at all (local origin, arbitrary scale), you can georeference it interactively:
In QGIS:
- Use the Georeferencer plugin (Raster > Georeferencer for rasters; for vector DXF, the DXF must first be imported as a vector layer)
- Pick control points in the DXF that correspond to identifiable locations in a reference layer (satellite imagery, OS data, another GIS dataset)
- Apply an affine or polynomial transform to move, scale, and rotate the DXF geometry into real-world coordinates
For CAD drawings with known real-world coordinates embedded at a few survey control points, you need at least 3 control points for a reliable affine transform. Polynomial warping is rarely needed — CAD drawings are almost always Euclidean and just need translation, rotation, and uniform scale.
AutoCAD-to-QGIS with a world file: If the AutoCAD drawing was plotted at a known scale with tick marks at known coordinates, the surveyor can generate a .wld world file (six-parameter affine transform) to accompany the DXF. QGIS reads .wld files for raster data but not natively for vector DXF — you need to apply the transform via Processing Toolbox or a PyQGIS script.
The Attribute Schema Mismatch
GIS data is tabular. Every polygon, line, or point has a row in an attribute table with typed fields: parcel_id (integer), owner_name (text 100), area_sqm (float), acquisition_date (date). The schema defines what you know about each feature beyond its geometry.
DXF has none of this. What DXF has:
- Layer: a string name, typically used to categorise entity type (WALLS, DOORS, ELECTRICAL, etc.) or drawing phase (EXISTING, PROPOSED)
- Entity type: LINE, POLYLINE, CIRCLE, ARC, MTEXT, INSERT (block reference)
- Entity handle: a unique hex ID within the file
- Block attributes: if an entity is an INSERT (block reference), it may have user-defined attribute tags and values embedded in the block definition
GDAL’s DXF driver, which is what QGIS uses under the hood, translates DXF into a flat vector layer with a handful of standard fields: Layer, SubClasses, Linetype, EntityHandle, Text. That is the entire attribute schema GDAL extracts from a DXF.
If a Civil 3D drawing uses block attributes to store parcel IDs, owner names, or zone codes, those attributes are embedded in XDATA or block INSERT entities. GDAL reads the geometry of those inserts but does not automatically expose the attribute values as GIS fields. You get the shape with the layer name and entity type, nothing else.
The ogr2ogr DXF import:
ogr2ogr -f GPKG output.gpkg input.dxf
This produces a GeoPackage with layers named by entity type (entities, blocks). Each feature has the standard GDAL DXF fields. For a drawing with meaningful layer names and no block attributes, this is usable. For data with rich block attribute schemas, you need a custom extraction script or FME.
QGIS Import Layers from DWG/DXF (the right tool for most cases):
Project → Import/Export → Import Layers from DWG/DXF is the correct entry point in QGIS for CAD data. It reads all DXF entity types and groups them into point, line, polygon, and text layers, split by the DXF layer name. The output is a GeoPackage.
Use this instead of dragging the DXF directly into QGIS — direct drag-and-drop uses the GDAL driver and produces a less organised result. The Project menu import handles exploded polylines, closed polygons vs open polylines, and block geometry more reliably.
The Topology Gap
GIS formats encode topology. A shapefile or GeoPackage polygon is a closed ring — the software knows it’s an area, can calculate area and perimeter, can run spatial queries to find what’s inside it, and can enforce adjacency rules (no gaps between parcels, no overlaps).
DXF has no topology. A “closed” shape in DXF is typically a POLYLINE where the last point happens to coincide with the first point, or a LINE sequence where the endpoint of one line visually meets the startpoint of the next — but the file contains no assertion that these form a polygon. GDAL attempts to assemble closed polylines into polygons, but:
- Lines drawn as separate LINE entities that happen to form a closed shape will not be assembled into a polygon by GDAL
- Polylines with tiny gaps (a drafter snapped close but not exactly to the endpoint) will fail polygon assembly
- Text, dimensions, and annotation entities mixed in with linework on the same layer break the layer-as-layer assumption
This is the most common failure mode when someone sends you “a DXF of our site boundary” and you import it expecting polygons. What you get is a tangle of line segments with no filled areas.
Fixing Topology on Import
In QGIS, after importing DXF line geometry:
- Run Vector → Geometry Tools → Lines to Polygons on the closed line layer
- If lines don’t close cleanly, run Vector → Geometry Tools → Snap Geometries to Layer first with a tolerance matching the drawing’s unit precision
- For gaps, use the Topology Checker plugin to identify non-closed rings before attempting polygon conversion
If the originating drafter can give you POLYLINE entities (not LINE sequences) and guarantee closure, the import is cleaner. LWPOLYLINE with the Closed flag set is what GDAL reliably converts to polygon geometry.
Practical Workarounds by Use Case
Civil / survey data you’re receiving from a contractor
Ask for: native file format (Civil 3D, MicroStation), the CRS name as text (EPSG code preferred), and whether coordinates are in the project CRS or local origin.
If you’re stuck with DXF: get the .prj sidecar, use Project menu import in QGIS, verify the result against known landmarks in satellite imagery before doing any analysis.
Architectural drawings (floor plans, site plans)
These are almost always in local coordinates at 1:1 scale (real millimetres). Georeferencing from control points is the path. If you only need spatial context rather than GIS analysis, georeferencing as a raster (export to PDF or PNG, georeference the image) is often faster than fighting the vector import.
Utility data (pipes, cables, conduit runs)
Often stored in CAD with meaningful layer names and block attributes. The ogr2ogr import gives you the geometry but loses the attributes. For this use case, either use FME with a DXF reader configured to extract block attributes, or write a PyQGIS script using OGR’s Python bindings to walk the DXF entity tree and pull XDATA values.
When GeoConvert is the wrong tool
GeoConvert converts GIS formats to GIS formats — it converts GeoJSON to Shapefile, GeoPackage to GeoJSON, and similar. It does not convert CAD to GIS because that conversion requires geospatial intervention (CRS assignment, topology repair, schema mapping) that can’t be automated without knowing the context of the drawing.
The CAD-to-GIS path requires you — the person who knows where the drawing is and what it represents — to make the coordinate binding explicit. No automated tool can reliably infer that a drawing’s coordinates of 530000, 182000 are British National Grid rather than local millimetres.
Once you’ve done the coordinate binding and produced a clean GIS vector layer, GeoParquet vs GeoPackage vs Shapefile covers which format to land in for downstream analysis.
What Would Actually Fix This
The long-term fix is GeoPDF and IFC, not DXF.
GeoPDF (PDF/E with geospatial extension) embeds a full CRS definition and transforms geometry to real-world coordinates. Civil engineers can export from Civil 3D or MicroStation to GeoPDF, and GIS tools can read the embedded CRS. GDAL supports GeoPDF as a raster source with embedded vector layers.
IFC (Industry Foundation Classes) is the open standard for BIM data exchange. IFC models include building elements as typed objects with attributes, linked to a site coordinate system. IFC doesn’t solve the local-origin problem entirely, but it carries attribute schemas and element semantics that DXF strips.
Neither has replaced DXF/DWG as the de facto CAD exchange format, but for new projects where you control the pipeline, requiring GeoPDF or IFC output from the CAD side eliminates most of the import friction.
Until then, the workarounds above are the path. The gap is real, it’s structural, and it requires intervention each time you cross it.