Writing map templates¶
mapbuilder generates map files for the EuroScope plugins Ground Radar (GRP) and TopSky from
templates. A template is a .jinja file in your maps/ directory. It mixes plain map statements
(MAP:, COLOR:, …) with Jinja expressions that draw
geometries from your data sources.
This section describes the Feature API (v2.1): a set of Jinja filters that work on features (a geometry plus its properties) and turn them into map statements.
A first template¶
MAP:Taxilanes
AIRPORT:EDDM
FOLDER:Airport Layout
COLOR:taxilane-yellow
{% set taxilanes = data.eddm.group('GuidanceLine', 'designator') %}
{{ taxilanes['C1'] | feat_join | feat_simplify(0.000005) | render_line('C1') }}
{{ taxilanes['C2'] | feat_join | feat_simplify(0.000005) | render_line('C2') }}
Line by line:
- The map header is copied unchanged into the output.
data.eddmis a data source defined inmapbuilder.toml.group(...)collects all guidance lines by their designator.- Each
{{ … }}expression is a pipeline: it takes the guidance lines of a taxilane, joins them into one line, simplifies it and renders it as GRPLINEstatements.
The output looks like this:
// C1
LINE:48.3501234:11.7712345:48.3502345:11.7723456
LINE:48.3502345:11.7723456:48.3503456:11.7734567
How pipelines work¶
Every pipeline has the same shape:
graph LR
D[Data source] --> S["Select<br/>feat_where, feat_exclude, …"]
S --> T["Transform<br/>feat_simplify, feat_join, …"]
T --> R["Render<br/>render_grp, render_ts, …"]
R --> O[Map statements]
- Selecting and transforming filters start with
feat_. They take features and always return features, so you can chain them in any order and the properties stay available until the end. See Selecting and transforming. - Rendering filters start with
render_. They end the pipeline and produce the text that goes into the map file. See Rendering.
Features in, features out
You never have to think about whether you are holding a feature or a bare geometry. Filters
accept a single feature, a list of features, a dict of features (as returned by group(...) or a
KML folder) and even bare geometries, and they flatten nested lists and dicts for you.
Rendering for GRP or TopSky¶
The quickest way to draw something is render_grp or render_ts. They render every geometry by its
type, so a folder that mixes areas, lines and points needs only one call:
Use the specific renderers (render_area, render_line, render_coordpoly, …) when you need a
particular statement type. The rendering reference lists all of them.
Jinja tips¶
{{- … }}and{%- … %}strip the whitespace before the tag; mapbuilder also removes leading indentation and collapses blank lines in the final file, so you can indent templates freely.- Keep repeated values in variables:
{% set default = 0.000005 %}and thenfeat_simplify(default). -
Loops work as usual:
-
If you mistype a key, for example
taxilanes['C 1'], mapbuilder logs a warning such asFeature filter got an undefined value: 'dict object' has no attribute 'C 1'and renders nothing for that expression.
Next steps¶
- Data and features: which data sources produce features and how to access them.
- Selecting and transforming: reference for all
feat_filters. - Rendering: reference for all
render_filters and output settings. - Migrating templates: moving existing templates to the Feature API.