Skip to content

Why GeoDMS

Jip Claassens edited this page Jul 6, 2026 · 1 revision

Considering whether to build your next spatial model in GeoDMS or as a collection of Python scripts? This page explains where GeoDMS earns its keep, and how it combines with Python rather than competing with it.

Models outgrow scripts

A spatial model that matters rarely stays small. It starts as a script that reads a few files and writes a map, and then it grows: more inputs, more indicators, more scenario variants, finer resolutions. At some point the script hits three walls:

  1. Time: every run recalculates everything, so iteration slows from seconds to hours. You start saving intermediate files by hand, and from that moment on you are never quite sure which of them are stale.
  2. Memory: national grids at fine resolution no longer fit in RAM, so you introduce chunking or a framework like dask, and the code becomes harder to read, change and debug.
  3. Trust: a reviewer, auditor or colleague asks how exactly a number on a map was calculated, and the honest answer is a guided tour through scripts, notebooks and an undocumented run order.

GeoDMS was designed, from the late 1990s on, for precisely this class of models. It removes the three walls not with more code, but with a different structure.

A model is a specification, not a script

In GeoDMS you declare what every result is: each map, table or indicator is a data item with an expression over source data and other data items, anchored to explicit domain and values units. You never specify how or in which order things are computed; the engine derives that from the dependencies. This has far-reaching consequences:

  • There is no run order to maintain, document or get wrong. The dependency tree is the model.
  • Calculation management is lazy: only results that are actually requested are calculated, and only invalidated results are ever recalculated.
  • Within a session, calculated results are kept and reused; nothing is computed twice. Stable intermediates can be decoupled: written once to storages declared in the configuration and read back in later runs, by every variant and every colleague (see Strategic decoupling). Because the decoupling is part of the model text rather than save-calls scattered through scripts, it stays visible, reviewable and versioned.
  • Data items are immutable: results are never modified in place, so there is no hidden state and the same configuration always yields the same outcome.

Performance and scale

GeoDMS is a multi-threaded C++ engine with a columnar data model and carefully chosen algorithmic techniques. Grids are processed in segments through automatic tiling, which means models routinely work with far more data than fits in memory: the Netherlands at 10 meter resolution, Europe at 100 meter (the LUISA territorial modelling platform of the JRC), or world-wide network models. All of this runs interactively on an ordinary Windows machine, without a cluster.

Quality control built in

Modelling errors are usually not crashes; they are plausible-looking numbers that are wrong. GeoDMS is designed to catch these early:

  • Every data item has a values unit with a metric, and unit consistency is checked when expressions are parsed: meters cannot be added to seconds, and euro/m2 multiplied by m2 yields euro. See dimensional analysis.
  • Every data item lives on a domain. Attributes of different domains (say, municipalities and grid cells) cannot be combined accidentally; they must be related explicitly through a relation, with functions like lookup and rjoin.
  • Value types are explicit, so precision and memory footprint are deliberate choices instead of accidents.
  • Every result can be inspected in the GUI as a map or table, together with its expression, its units and its suppliers. Reviewing a model does not require reading code and adding print statements; it is browsing a tree.

Reproducible and open

A GeoDMS configuration is a set of plain text files. It can be versioned in git, diffed line by line, reviewed in a pull request and published alongside a study. Combined with the immutability of data items, this makes model results reproducible by construction: the configuration plus the source data determine the outcome, and the full calculation lineage of every number is inspectable. For models that feed policy decisions, this transparency is not a luxury; it is the requirement that keeps them credible.

Where Python is the better tool

GeoDMS is a domain-specific language for spatial model calculation. It is not a general-purpose programming environment, and it does not try to be. For machine learning, bespoke statistics, plotting and reporting, web services or one-off data wrangling, Python and its ecosystem are the better tool.

The dividing line is simple: the core of the model belongs in GeoDMS, Python belongs at the edges. Every external script in the middle of a calculation chain is a black box to the engine: its inputs and outputs must be wired up by hand, its correctness cannot be checked against units and domains, and traceability stops at its doorstep, for that step and for everything calculated from it. Used at the edges, estimating parameters before the model runs and presenting results after, Python costs none of that.

The good news is that this is not an either-or choice. GeoDMS through Python describes three proven architectures to combine them: Python driving the GeoDMS engine as a separate process, a GeoDMS model running Python scripts on demand (exchanging typed data through parquet files), and the Python bindings that embed the engine in the Python process. A typical division of labour keeps the heavy, recurring spatial calculations in GeoDMS, where they are fast, cached and traceable, and uses Python around it for estimation, analysis and presentation.

What you avoid by not rebuilding the calculation core in Python: dependency tracking, chunking for larger-than-memory grids, unit discipline by convention, and a viewer round-trip for every intermediate result. That infrastructure already exists, tested by 25 years of production use.

For pandas and numpy users

The concepts of GeoDMS map naturally onto what you already know (see also Relational model versus Semantic arrays):

pandas / numpy GeoDMS
the index of a DataFrame, an entity set a domain unit
a column an attribute
vectorised arithmetic on columns an expression; all operations are vectorised
df.merge(other, on=key) rjoin, or a relation with lookup
df.groupby('region')['x'].sum() sum(x, region_rel), see aggregation functions
chunking large rasters by hand, or dask automatic [[tiling
ad-hoc caching: pickles and parquet dumps scattered through code [[strategic decoupling
units tracked in your head or in comments [[units

A groupby-sum in pandas:

value_per_region = houses.groupby('region_id')['value'].sum()

and in GeoDMS:

attribute<euro> value_per_region (Region) := sum(House/value, House/Region_rel);

The GeoDMS version states its units (euro) and its domain (Region), both of which the engine verifies. The GeoDMS Academy offers hands-on tutorials to get productive quickly.

Track record

GeoDMS has powered land-use, accessibility, energy and population models for national and European institutions since the late 1990s, including PBL Netherlands Environmental Assessment Agency, the Joint Research Centre of the European Commission, Deltares, TNO and the German BBR. See the Home page for an overview of users and applications, and Projects for more background.

Clone this wiki locally