Safe Software’s partial acquisition by a private equity firm in early 2024 triggered price increases that blindsided teams that had built their GIS infrastructure around FME. Users in the community forums reported annual maintenance increases ranging from substantial to a 400% jump for some license tiers. The reaction was predictable: teams that could absorb the cost renewed; teams that couldn’t started auditing what FME was actually doing for them.

What most found: the majority of their FME usage was format translation and straightforward transformation chains — work that GDAL, Python, and QGIS can handle without a license fee. The minority was complex branching pipelines and proprietary format readers that have no drop-in replacement.

This post maps FME use cases to realistic open-source alternatives, with the caveats about where the alternatives genuinely fall short.

What FME Actually Does — A Taxonomy

Before picking replacements, categorize your FME workspaces by what they do:

Format translation: Reading one spatial format and writing another. GeoJSON → Shapefile. GDB → GeoPackage. WFS → CSV. This is the most common FME use case and the easiest to replace.

Transformation pipelines: Reprojecting, filtering by attribute or geometry, cleaning topology, renaming fields, splitting/merging datasets. Often chained with format translation.

Visual workflow building: Non-technical teams building workflows in FME Workbench without writing code. The canvas model is FME’s genuine UX advantage.

Scheduling and automation: FME Server or FME Flow running workspaces on triggers (file drop, time schedule, webhook). Replace with OS-level scheduling + scripts.

Point cloud / LiDAR processing: Reading LAS/LAZ, ground classification, thinning, tiling, colorization, format conversion. FME’s point cloud transformers are widely used.

CAD format ingestion: Reading DWG, DGN, MicroStation, and writing them back. The hardest to replace.

Web service connectors: Reading from ArcGIS REST, WFS, WMS, Esri services. Replaceable but requires more code.


Replacement 1: GDAL/OGR — Format Translation and Transformation

Covers: Format translation (80%+ of typical FME use), reprojection, attribute filtering, basic geometry operations.

GDAL/OGR (ogr2ogr for vectors, gdal_translate/gdalwarp for rasters) reads and writes over 200 spatial formats. It is the underlying engine in QGIS, ArcGIS Pro, and most other desktop GIS tools. Using it directly bypasses the GUI overhead.

Basic format translation

# GeoJSON → Shapefile
ogr2ogr -f "ESRI Shapefile" output_dir/ input.geojson

# GeoPackage → PostGIS
ogr2ogr -f PostgreSQL PG:"dbname=gisdb" layers.gpkg

# WFS → GeoPackage (reads directly from web)
ogr2ogr -f GPKG output.gpkg "WFS:https://example.com/wfs?SERVICE=WFS&VERSION=2.0.0" LayerName

Reprojection and filtering

# Reproject to EPSG:4326 and filter by attribute
ogr2ogr -f "ESRI Shapefile" output.shp input.shp \
  -t_srs EPSG:4326 \
  -where "STATUS = 'active'"

# SQL-based transformation (more powerful than -where)
ogr2ogr -f GPKG output.gpkg input.gpkg \
  -sql "SELECT name, ST_Buffer(geometry, 100) AS geometry FROM buildings WHERE area > 500"

The -sql flag accepts OGR SQL or (with -dialect SQLite) SQLite/Spatialite syntax, which gives you access to geometry functions like ST_Buffer, ST_Intersects, and ST_Area directly in the ogr2ogr command.

PostGIS for complex transformations

For multi-step transformations on large datasets, loading into PostGIS and running SQL chains is faster and more auditable than a sequence of ogr2ogr calls:

-- Replace an FME workspace that clips features to a study area, 
-- reprojects, and dissolves by a category field
CREATE TABLE output AS
SELECT category, ST_Union(ST_Transform(geometry, 4326)) AS geometry
FROM input
WHERE ST_Intersects(geometry, ST_GeomFromText('POLYGON((...))'))
GROUP BY category;

PostgreSQL is free, auditable, version-controllable (schema migrations), and runs on the same Linux/Windows infrastructure as everything else.


Replacement 2: PDAL — Point Cloud and LiDAR Processing

Covers: FME’s point cloud readers/writers and transformers: LAS/LAZ format conversion, ground classification, thinning, tiling, merge by tile, colorization from raster, intensity normalization.

PDAL (Point Data Abstraction Library) is a C++ library with a JSON pipeline format and Python bindings. It was developed specifically for the types of workflows that FME’s point cloud transformers handle.

Running a PDAL pipeline

{
  "pipeline": [
    {
      "type": "readers.las",
      "filename": "input.las"
    },
    {
      "type": "filters.smrf",
      "scalar": 1.2,
      "slope": 0.15,
      "threshold": 0.45,
      "window": 18.0
    },
    {
      "type": "filters.range",
      "limits": "Classification[2:2]"
    },
    {
      "type": "writers.las",
      "filename": "ground_points.las",
      "compression": "laszip"
    }
  ]
}
pdal pipeline ground_classification.json

This pipeline reads a LAS file, runs SMRF (Simple Morphological Filter) ground classification, keeps only ground points (Classification 2), and writes compressed LAZ output — equivalent to an FME workspace with PointCloudReader → SMRFFilter → AttributeFilter → PointCloudWriter.

Python API

import pdal
import json

pipeline_json = json.dumps({
    "pipeline": [
        {"type": "readers.las", "filename": "input.las"},
        {"type": "filters.decimation", "step": 10},  # thin by factor 10
        {"type": "writers.las", "filename": "thinned.las"}
    ]
})

pipeline = pdal.Pipeline(pipeline_json)
pipeline.execute()
arrays = pipeline.arrays  # numpy arrays of point attributes

PDAL covers: LAS/LAZ, E57, PLY, PCD, COPC, EPT, BPF, text/CSV, and more. Formats that FME handles with its Point Cloud coercer but PDAL doesn’t: some vendor-specific terrestrial scanner formats (Leica XYZ, Trimble proprietary). For those, check pdal info --drivers.


Replacement 3: QGIS Graphical Modeler — Visual Workflow Building

Covers: FME Workbench workflows for non-technical users. Teams that built workspaces visually and ran them repeatedly, often without writing any code.

QGIS’s Processing Toolbox includes a Graphical Modeler (Processing menu → Graphical Modeler) that provides a drag-and-drop canvas for chaining QGIS Processing algorithms — reprojection, clipping, buffer, merge, attribute calculation, format export — without code.

Models saved from the Graphical Modeler can be:

  • Run from the QGIS GUI
  • Run headlessly via qgis_process:
    qgis_process run model:my_workflow -- INPUT=input.geojson OUTPUT=output.shp EPSG=4326
    
  • Exported as Python scripts for further modification

The QGIS Modeler handles linear transformation chains well. Where it falls short of FME Workbench: conditional branching (if/else routing based on feature attributes), error handling with fallback paths, and resuming from a failed step. FME’s control flow transformers (Tester, Router, Decelerator) have no direct QGIS equivalent in the visual environment.

See QGIS Model Builder to Python — an on-ramp for GIS scripting for how to graduate from visual models to Python when your workflows outgrow the canvas.


Replacement 4: Python (GeoPandas, Fiona, Rasterio, Shapely)

Covers: Complex transformation logic, custom geometry operations, batch processing with error handling, integration with non-GIS data systems.

The Python GIS stack:

LibraryWhat it replaces
FionaFME feature reading/writing, attribute access
ShapelyFME geometry transformers (buffer, intersection, validation)
GeoPandasFME attribute joining, filtering, spatial joins
RasterioFME raster readers/writers, resampling, reprojection
PyProjFME reprojector transformer

Example: spatial join with attribute filter (FME Workbench replacement)

import geopandas as gpd

# Read layers
parcels = gpd.read_file("parcels.geojson")
flood_zones = gpd.read_file("flood_zones.shp")

# Reproject to matching CRS
flood_zones = flood_zones.to_crs(parcels.crs)

# Spatial join: which parcels intersect flood zone A?
joined = gpd.sjoin(parcels, flood_zones[flood_zones["zone"] == "A"], 
                   how="inner", predicate="intersects")

# Write output
joined.to_file("flood_risk_parcels.shp")

This replaces an FME workspace with a SpatialFilter → Reprojector → FeatureJoiner → ShapefileWriter chain.

GeoPandas wraps Fiona (for I/O) and Shapely (for geometry), so installing it gets you the whole vector processing stack. For rasters, add Rasterio separately.


GeoJSON to Shapefile Without the Stack

For teams that just need to convert GeoJSON files to ESRI Shapefile format — which is one of the most common single-step FME workflows — you don’t need to install and configure GDAL locally.

GeoConvert handles GeoJSON → Shapefile conversion in the browser: uploads up to 100MB, validates geometry, preserves CRS, maps attributes following RFC 7946. No command-line setup, no GDAL path issues, no library conflicts. The output is a complete Shapefile package (.shp, .shx, .dbf, .prj) ready for ArcGIS, QGIS, or MapInfo.

This covers the conversion step but not transformation pipelines. For anything beyond pure format conversion, use GDAL/OGR or the Python stack above.

For the attribute-level gotchas in GeoJSON → Shapefile conversion — field name truncation, type coercion, encoding edge cases — see GeoJSON to Shapefile: The Field Truncation Problem Nobody Warns You About and 5 Ways GIS File Conversions Silently Fail.


What FME Still Does Better

Be honest about where the open-source alternatives genuinely cannot match FME:

DWG write support: GDAL’s DWG driver reads DWG but cannot write it. FME’s DWG writer is the only scriptable option for generating DWG output from spatial data. If your workflow produces DWG files (for civil engineers, architects, or AutoCAD-dependent clients), you either keep FME or use a commercial GDAL extension.

Complex branching pipelines with error routing: FME’s Tester, Router, Inspector, and Logger transformers let you build workflows with conditional paths, per-feature error handling, and mid-pipeline inspection. The Python stack can replicate this but requires writing explicit control flow code — the equivalent is more maintainable in code than in a visual canvas but requires a developer to own it.

Proprietary geodatabase formats: Esri PGDB, some vendor-specific raster products, MicroStation DGN v8 write support, Bentley i-model. GDAL coverage varies. FME’s broader format library remains its strongest differentiator.

Non-spatial data connectors: FME has transformers for reading Excel, databases, REST APIs, cloud storage, and joining them spatially in a single workspace. Replicating this requires combining multiple tools or writing custom Python.


Migration Approach

For teams auditing FME usage after the price increase:

  1. Inventory your workspaces. List every FME workspace by type: format translation only, transformation + translation, scheduling dependency, LiDAR, CAD read/write, other.

  2. Replace the easy 80% first. Pure format translation → ogr2ogr one-liners. Run them in a script triggered by Task Scheduler or cron. These are the lowest risk, highest volume replacements.

  3. Move transformation chains to Python. For workspaces with joins, filters, and geometry operations: GeoPandas + Shapely. Port them one at a time, validate outputs against FME output before switching.

  4. Convert visual models to QGIS Modeler or Python. For non-technical team members who maintain workspaces: QGIS Graphical Modeler if the logic is linear; Python with comments if it’s more complex.

  5. Keep FME for DWG write workflows and proprietary format readers. Don’t replace what can’t be replaced. Negotiate a lower-seat or department license for the workflows that genuinely need it.

For the long term: move toward open formats. GeoPackage vs Shapefile vs GeoParquet covers which formats survive tooling changes without conversion overhead. Free and open source GIS tools for format conversion goes broader across the GIS tool landscape.

The FME price increase is a forcing function to audit what your workflows actually need. Most teams find the audit reveals a much smaller FME dependency than expected.