The EU Deforestation Regulation applies from 30 December 2026. For operators placing timber, cocoa, coffee, palm oil, soy, cattle, and rubber on the EU market, compliance requires a Due Diligence Statement submitted through the TRACES NT system. That statement must include plot-level geolocation data — and the format specification is not flexible.

TRACES accepts GeoJSON in WGS84 (EPSG:4326) with coordinates expressed as decimal degrees to at least six decimal places. Plots over 4 hectares require a complete boundary polygon. Plots under 4 hectares may be represented by a single point.

The practical problem: most forestry and agricultural boundary data is captured in national coordinate reference systems, not WGS84. When the CRS conversion step is skipped or applied incorrectly, coordinates are submitted in the wrong projection. TRACES either rejects the submission outright or, worse, accepts it with coordinates that plot the forest in the wrong country on the EU’s satellite verification layer.

Why Boundary Data Arrives in the Wrong CRS

Field surveyors and forestry GIS teams work in the national CRS of their country for good reasons. National projections are optimized for local accuracy and match cadastral records, topographic maps, and national forest inventories.

Common CRS values in EUDR supply chains:

Country / RegionCRSEPSG
NetherlandsRD New / Amersfoort28992
GermanyETRS89 / UTM zone 32N25832
Germany (east, legacy)Gauss-Krüger zone 431468
UKBritish National Grid27700
FranceRGF93 / Lambert-932154
SwedenSWEREF99 TM3006
FinlandETRS89 / TM35FIN3067
IndonesiaWGS 84 / UTM zone 49S32749
BrazilSIRGAS 2000 / UTM zone 23S31983
MalaysiaTimbalai 1948 / RSO Borneo29873

Even when surveyors capture in WGS84 (GPS decimal degrees), the data often flows through GIS software that reprojects it into a local system for area calculations or map production, then exports without re-converting to WGS84.

The least visible problem: GeoJSON files with no CRS declaration. RFC 7946 specifies that GeoJSON without a CRS declaration is implicitly WGS84. Some GIS export tools strip the CRS from the file when exporting — if the data was in RD New at the time of export, the exported GeoJSON contains RD New coordinates but claims to be WGS84. TRACES has no way to detect this; it trusts the file’s implicit WGS84 declaration and accepts the submission. The polygon then appears in the middle of the North Sea during satellite verification.

How to Detect a Wrong CRS

Before reprojecting, confirm what CRS the data is actually in.

Coordinate range check. WGS84 coordinates are always: longitude between -180 and +180, latitude between -90 and +90. Coordinates in any projected CRS (UTM, national grids) will be in the hundreds of thousands to millions. Open your GeoJSON in a text editor and inspect the first few coordinates:

"coordinates": [[[150423.7, 463851.2], [150478.4, 463802.1]]]

These are not WGS84 decimal degrees. They’re in some projected system — likely a national grid. The values 150,000–160,000 and 460,000–470,000 are consistent with coordinates in the RD New system for central Netherlands, but similar ranges appear in many national grids.

WGS84 coordinates for a forest in the Netherlands should look like:

"coordinates": [[[5.291847, 52.143672], [5.292103, 52.143589]]]

ogrinfo CRS inspection. If the file has an embedded CRS declaration:

ogrinfo -al -so forest_boundary.geojson

The output includes the CRS in WKT format. Look for the AUTHORITY section at the end:

GEOGCS["WGS 84",
    DATUM["WGS_1984", ...],
    AUTHORITY["EPSG","4326"]]

If you see PROJCS (projected) instead of GEOGCS (geographic), the file is in a projected system and must be converted.

QGIS layer info. Right-click the layer → Properties → Information → CRS. This reads the embedded CRS metadata without any inspection commands.

The dangerous case. If coordinates look like they’re in the correct WGS84 range (small decimal values) but the geometry plots in the wrong location, the data was likely captured in a projected system with meters near the origin, or the CRS declaration is wrong. Verify by overlaying the imported polygon on a satellite basemap. If the polygon appears in the ocean or in another country, the CRS is incorrect.

Reprojection with ogr2ogr

ogr2ogr from the GDAL toolkit handles reprojection reliably and is the standard tool for this step.

Basic reprojection from a known source CRS:

ogr2ogr \
  -f GeoJSON \
  -s_srs EPSG:28992 \
  -t_srs EPSG:4326 \
  output_wgs84.geojson \
  input_rd_new.geojson

-s_srs declares the source CRS. -t_srs declares the target. If the source CRS is already declared in the file, you can omit -s_srs; ogr2ogr will read it from the file’s CRS metadata.

Reprojecting a Shapefile to GeoJSON in WGS84:

ogr2ogr \
  -f GeoJSON \
  -t_srs EPSG:4326 \
  output_wgs84.geojson \
  input_forest_parcels.shp

Shapefiles typically carry CRS information in the .prj file. If the .prj is missing or incorrect, specify -s_srs explicitly.

Overriding a wrong embedded CRS. If the file declares a wrong CRS — the GeoJSON says WGS84 but the coordinates are in RD New — you must override the source CRS:

ogr2ogr \
  -f GeoJSON \
  -s_srs EPSG:28992 \
  -t_srs EPSG:4326 \
  output_corrected.geojson \
  input_wrongly_declared.geojson

This ignores the file’s embedded CRS declaration and treats the coordinates as RD New.

Coordinate precision. EUDR requires at least 6 decimal places. ogr2ogr’s default GeoJSON output rounds to 7 significant figures, which is sufficient for 6 decimal places at most latitudes. To be explicit:

ogr2ogr \
  -f GeoJSON \
  -lco COORDINATE_PRECISION=7 \
  -t_srs EPSG:4326 \
  output_wgs84.geojson \
  input.shp

Reprojection in QGIS

For teams working in QGIS:

  1. Load the source layer
  2. Right-click → Export → Save Features As
  3. Format: GeoJSON
  4. CRS: click the globe icon and enter EPSG:4326
  5. Geometry: check Include Z-coordinates only if your data has elevation (most EUDR submissions do not need Z)
  6. Save

QGIS reads the source CRS from the layer’s metadata. If the CRS is undefined (no .prj, no embedded declaration), QGIS will prompt you to select the CRS manually before you can reproject.

Coordinate precision in QGIS export. QGIS 3.22+ allows setting decimal places in the export dialog. Set to 7 or higher. Older QGIS versions default to 15 significant digits, which is fine.

Python: Batch Reprojection with pyproj

For processing multiple plot files programmatically:

import json
from pyproj import Transformer

transformer = Transformer.from_crs("EPSG:28992", "EPSG:4326", always_xy=True)

def reproject_geometry(geom, transformer):
    """Reproject a GeoJSON geometry dict in-place (supports Point and Polygon)."""
    if geom["type"] == "Point":
        lon, lat = transformer.transform(geom["coordinates"][0], geom["coordinates"][1])
        geom["coordinates"] = [round(lon, 7), round(lat, 7)]
    elif geom["type"] == "Polygon":
        rings = []
        for ring in geom["coordinates"]:
            reprojected = []
            for x, y in ring:
                lon, lat = transformer.transform(x, y)
                reprojected.append([round(lon, 7), round(lat, 7)])
            rings.append(reprojected)
        geom["coordinates"] = rings
    return geom

with open("input_rd_new.geojson") as f:
    fc = json.load(f)

for feature in fc["features"]:
    feature["geometry"] = reproject_geometry(feature["geometry"], transformer)

# Remove any embedded CRS declaration; RFC 7946 GeoJSON is implicitly WGS84
fc.pop("crs", None)

with open("output_wgs84.geojson", "w") as f:
    json.dump(fc, f, indent=2)

The always_xy=True parameter tells pyproj to always interpret the first coordinate as the X axis (longitude for geographic CRS). Without it, EPSG:4326 uses latitude-first ordering by default, which inverts your coordinates.

Polygon Winding Order

RFC 7946 — the GeoJSON specification that TRACES validates against — requires a specific winding order:

  • Exterior ring: counter-clockwise (CCW)
  • Interior rings (holes): clockwise (CW)

Many GIS tools produce polygons in the opposite order, or produce CW exterior rings. TRACES may reject GeoJSON that violates RFC 7946 winding order even if the CRS and geometry are otherwise correct.

ogr2ogr enforces RFC 7946 winding order when exporting to GeoJSON since GDAL 2.5. If you’re using an older GDAL version or a different tool, check the exterior ring direction.

To detect and fix winding order violations in Python:

from shapely.geometry import shape, mapping
from shapely.ops import orient

for feature in fc["features"]:
    geom = shape(feature["geometry"])
    # orient() enforces RFC 7946: exterior CCW, holes CW
    feature["geometry"] = mapping(orient(geom, sign=1.0))

orient(geom, sign=1.0) sets positive signed area (CCW exterior ring). The shapely orient function is the reliable way to enforce this; don’t implement winding detection manually.

Validation Before Submission

Run these checks on the final GeoJSON before submitting to TRACES:

1. CRS is implicitly WGS84. The file must contain no "crs" key at the top level. A "crs" key with any value other than RFC 7946’s implicit WGS84 will cause TRACES to reject the submission. Remove any "crs" key from the output:

fc.pop("crs", None)

2. Coordinates are in WGS84 range. Longitude: -180 to 180. Latitude: -90 to 90.

3. Precision is sufficient. At least 6 decimal places. Six decimal places = roughly 0.11 meter resolution at the equator, which is adequate for plot-level forest boundary mapping.

4. Polygon is closed. The last coordinate pair of each ring must equal the first. ogr2ogr and shapely both enforce this; direct JSON editing can accidentally break closure.

5. Plot area is correctly represented. Plots under 4 hectares: a single Point feature is acceptable. Plots 4 hectares or larger: a Polygon or MultiPolygon. Representing a large plot as a single point will cause the submission to be marked incomplete during review.

6. Geometry is valid. Self-intersections, zero-area spikes, and degenerate rings cause validation failures. Check with:

ogrinfo -al -so output_wgs84.geojson

Look for any validation warnings in the output. Alternatively, load in QGIS and run Vector → Geometry Tools → Check Validity.

Where GeoConvert Fits

If you’re receiving boundary data from supply chain partners in Shapefile or CSV format, the first step is format conversion before any reprojection work. GeoConvert converts GeoJSON to Shapefile and back, with CRS preservation and automatic geometry validation — useful when partners deliver in one format and your GIS stack requires another before the reprojection step.

The reprojection itself must be done with ogr2ogr, QGIS, or pyproj once you have the source CRS confirmed. For the EUDR workflow specifically, the conversion and validation sequence is:

  1. Receive boundary data from supplier (Shapefile, KML, CSV, or GeoJSON in local CRS)
  2. Convert to a common working format if needed
  3. Confirm source CRS by inspecting coordinates and embedded metadata
  4. Reproject to EPSG:4326 with ogr2ogr or pyproj
  5. Strip "crs" key from output GeoJSON
  6. Validate winding order, coordinate precision, polygon closure, and area
  7. Submit to TRACES

For more on why GeoJSON-to-Shapefile conversions introduce silent errors at the format boundary, see why GeoJSON-to-Shapefile conversions silently corrupt your data. The field name truncation and type coercion problems documented there also apply in the reverse direction when receiving Shapefile data from suppliers and converting to GeoJSON for EUDR submission.

For teams working with large collections of plot boundaries across multiple countries, the GDAL OGR format conversion reference covers batch processing patterns with ogr2ogr that scale to thousands of plot files without manual intervention.