Dali Test Examples

June 29, 2026 · View on GitHub

The Dali tests exercise the /dali endpoint directly, bypassing the WMS/WMTS layers. Test inputs are .get files in test/input/ and expected outputs in test/output/. Product JSON configurations are under test/dali/customers/.

Each request URL is decomposed into a table showing every query parameter and its effect. Layer-specific URL overrides follow the pattern l.{qid}.{setting} and view overrides follow v{n}.{setting}.

Contents


Output Formats

Dali can produce SVG (default), PNG, PDF, GeoJSON, KML, GeoTIFF, MVT, and DataTile from the same product definition.

t2m_p — SVG (default)

Input: test/input/t2m_p.get

GET /dali?customer=test&product=t2m_p&time=200808050300 HTTP/1.0
ParameterValueDescription
customertestCustomer directory
productt2m_pProduct JSON: test/dali/customers/test/products/t2m_p.json
time200808050300Valid time: 2008-08-05 03:00 UTC

Renders Scandinavian temperature isobands and isolines from the kap producer in the data's native CRS (500×500 px). The product uses a defs block to define SVG symbols and CSS styles. Output is SVG (default when no type is specified).

Output:

t2m_p


png — PNG output

Input: test/input/png.get

GET /dali?customer=test&product=t2m_p&type=png&time=200808050300 HTTP/1.0
ParameterValueDescription
customertestCustomer directory
productt2m_pSame product as above
typepngForces 8-bit palette PNG raster output
time200808050300Valid time: 2008-08-05 03:00 UTC

Any product can be rasterised to PNG by supplying type=png. Output is 500×500 px, 8-bit colour-mapped PNG (default ≤256 colours).

Output:

png


png_truecolor — 24-bit PNG

Input: test/input/png_truecolor.get

GET /dali?customer=test&product=t2m_p&type=png&time=200808050300&png.truecolor=1 HTTP/1.0
ParameterValueDescription
typepngPNG output
png.truecolor1Forces 24-bit true-colour PNG instead of palette

Output:

png_truecolor


png_maxcolors_20 — Limited palette PNG

Input: test/input/png_maxcolors_20.get

GET /dali?customer=test&product=t2m_p&type=png&time=200808050300&png.maxcolors=20 HTTP/1.0
ParameterValueDescription
typepngPNG output
png.maxcolors20Caps the palette at 20 colours; reduces file size but introduces posterisation

Output:

png_maxcolors_20


pdf — PDF output

Input: test/input/pdf.get

GET /dali?customer=test&product=t2m_p&time=200808050300&type=pdf HTTP/1.0
ParameterValueDescription
typepdfProduces a vector PDF document

Output is a scalable PDF (no rasterisation).


t2m_p_geojson — GeoJSON output

Input: test/input/t2m_p_geojson.get

GET /dali?customer=test&product=t2m_p&time=200808050300&type=geojson HTTP/1.0
ParameterValueDescription
typegeojsonExports isoband/isoline geometries as GeoJSON

Polygon and line features are reprojected to WGS84 (EPSG:4326) in the output.


t2m_p_kml — KML output

Input: test/input/t2m_p_kml.get

GET /dali?customer=test&product=t2m_p&time=200808050300&type=kml HTTP/1.0
ParameterValueDescription
typekmlExports isoband/isoline geometries as KML (Google Earth)

Note: listed in .testignore — output precision can vary between RHEL 7 and RHEL 8 environments.


datatile_temperature — DataTile: single-band temperature

Input: test/input/datatile_temperature.get

GET /dali?customer=grid&type=datatile&product=datatile_temperature&time=200808050800 HTTP/1.0
ParameterValueDescription
customergridGrid data customer directory
typedatatileRGBA-encoded float data PNG (bypasses SVG pipeline)
productdatatile_temperatureProduct JSON: test/dali/customers/grid/products/datatile_temperature.json
time200808050800Valid time: 2008-08-05 08:00 UTC

Returns a 64x64 PNG tile where each pixel encodes a temperature value (parameter T-K) as a 16-bit quantised value in the R and G channels. The A channel is 255 for valid pixels, 0 for missing data. Scale and offset metadata are embedded in PNG tEXt chunks (datatile:min, datatile:max).

Output: test/output/datatile_temperature.get — PNG (binary, not a visual image)


datatile_wind — DataTile: dual-band wind direction + speed

Input: test/input/datatile_wind.get

GET /dali?customer=grid&type=datatile&product=datatile_wind&time=200808050800 HTTP/1.0
ParameterValueDescription
customergridGrid data customer directory
typedatatileRGBA-encoded float data PNG
productdatatile_windProduct JSON: test/dali/customers/grid/products/datatile_wind.json
time200808050800Valid time: 2008-08-05 08:00 UTC

Returns a 64x64 PNG tile with two bands encoded in the RGBA channels: wind direction (DD-D) in R+G and wind speed (FF-MS) in B+A. This is the dual-band encoding where valid values occupy [1, 65535] and 0 indicates missing data. Metadata chunks include datatile:min1/max1 (direction) and datatile:min2/max2 (speed).

Output: test/output/datatile_wind.get — PNG (binary)


datatile_precipitation — DataTile: single-band precipitation (RasterLayer)

Input: test/input/datatile_precipitation.get

GET /dali?customer=grid&type=datatile&product=datatile_precipitation&time=200808050800 HTTP/1.0
ParameterValueDescription
customergridGrid data customer directory
typedatatileRGBA-encoded float data PNG
productdatatile_precipitationProduct JSON: test/dali/customers/grid/products/datatile_precipitation.json
time200808050800Valid time: 2008-08-05 08:00 UTC

Returns a 64x64 PNG tile with 1-hour precipitation (PRECIP1H-KGM2) encoded as a single-band datatile via the raster layer type.

Output: test/output/datatile_precipitation.get — PNG (binary)


autoclass — Automatic CSS class names

Input: test/input/autoclass.get

GET /dali?customer=test&product=autoclass&time=200808050300&type=svg HTTP/1.0
ParameterValueDescription
productautoclassProduct JSON: test/dali/customers/test/products/autoclass.json
typesvgForces SVG output

The autoclass feature generates CSS class names automatically from isoband/isoline limit values using a template such as "Temperature_{}_{}"; the lower and upper limits substitute the placeholders (using None for open-ended bands). This eliminates the need to assign class names manually in every isoband specification.

Output:

autoclass


autoqid — Automatic query IDs

Input: test/input/autoqid.get

GET /dali?customer=test&product=autoqid&time=200808050300&format=svg HTTP/1.0
ParameterValueDescription
productautoqidProduct JSON: test/dali/customers/test/products/autoqid.json
formatsvgAlternative to type=svg for specifying SVG output

The autoqid feature auto-generates qid values for each isoband/isoline from the band limits using a template such as "temperature_{}_{}"; the resulting qid can then be referenced in URL parameter overrides. Unlike autoclass (which generates CSS class names), autoqid generates the query IDs used for URL-based overrides.

Output:

autoqid


disable_svg — Conditionally disabled layer

Input: test/input/disable_svg.get

GET /dali?customer=test&product=disable_svg&time=200808050300 HTTP/1.0
ParameterValueDescription
productdisable_svgProduct JSON: test/dali/customers/test/products/disable_svg.json

A layer carrying "disable": "svg" is skipped entirely when rendering to SVG but rendered for PNG/PDF. Useful for layers (e.g. pressure isolines) that are visually acceptable as vector but are too slow or heavy in SVG.

Output:

disable_svg


enable_png — Conditionally enabled layer

Input: test/input/enable_png.get

GET /dali?customer=test&product=enable_png&time=200808050300 HTTP/1.0
ParameterValueDescription
productenable_pngProduct JSON: test/dali/customers/test/products/enable_png.json

A layer carrying "enable": ["png","pdf"] is rendered only for those output formats and suppressed for SVG. The product adds pressure isolines only for raster/PDF output.

Output:

enable_png


Isoband and Isoline

feelslike — FeelsLike parameter

Input: test/input/feelslike.get

GET /dali?customer=test&product=feelslike&time=200808050300 HTTP/1.0
ParameterValueDescription
productfeelslikeProduct JSON: test/dali/customers/test/products/feelslike.json

Renders isobands and isolines of the FeelsLike apparent-temperature parameter from the pal_skandinavia producer, using the same colour scale as regular temperature.

Output:

feelslike


precipitation — Precipitation isobands

Input: test/input/precipitation.get

GET /dali?customer=test&product=precipitation&time=200808050300 HTTP/1.0
ParameterValueDescription
productprecipitationProduct JSON: test/dali/customers/test/products/precipitation.json

Renders precipitation isobands and isolines from pal_skandinavia in the data's native CRS.

Output:

precipitation


precipitation_warm — Precipitation warm season

Input: test/input/precipitation_warm.get

GET /dali?customer=test&product=precipitation_warm&time=200808050300 HTTP/1.0
ParameterValueDescription
productprecipitation_warmProduct JSON: test/dali/customers/test/products/precipitation_warm.json

Uses a warm-season precipitation colour scale with finer class resolution in the low-intensity range.

Output:

precipitation_warm


precipitation_minarea — Suppress small polygons (geographic area)

Input: test/input/precipitation_minarea.get

GET /dali?customer=test&product=precipitation&time=200808050300&l1.minarea=5000&l2.minarea=5000 HTTP/1.0
ParameterValueDescription
l1.minarea5000Drops isoband polygons smaller than 5000 m² for layer l1
l2.minarea5000Same for layer l2

The minarea setting removes noise from scattered small polygons. The default unit is m².

Output:

precipitation_minarea


precipitation_minarea_px — Suppress small polygons (pixel area)

Input: test/input/precipitation_minarea_px.get

GET /dali?customer=test&product=precipitation&time=200808050300&l1.minarea=1000&l2.minarea=1000&l1.areaunit=px^2&l2.areaunit=px^2 HTTP/1.0
ParameterValueDescription
l1.minarea1000Minimum polygon area threshold for layer l1
l1.areaunitpx^2Interprets the area threshold in pixels² (screen-space) instead of m²

Using areaunit=px^2 makes the filter resolution-independent: useful when the product may be rendered at different map scales.

Output:

precipitation_minarea_px


radar — Radar precipitation

Input: test/input/radar.get

GET /dali?customer=test&product=radar&time=20130910T1000 HTTP/1.0
ParameterValueDescription
productradarProduct JSON: test/dali/customers/test/products/radar.json
time20130910T1000Valid time: 2013-09-10 10:00 UTC

Renders radar-derived precipitation rate (PrecipitationRate) from the tutka_suomi_rr producer with a blue sea background and country-fill. Demonstrates isoband rendering on a 500×800 px product in the data's native CRS.

Output:

radar


radar_subdivide — Bilinear cell subdivision comparison (K = 0, 2, 4, 8)

Input: test/input/radar_subdivide.get

GET /dali?customer=test&product=radar_subdivide&time=20130910T1000 HTTP/1.0
ParameterValueDescription
productradar_subdivideProduct JSON: test/dali/customers/test/products/radar_subdivide.json
time20130910T1000Valid time: 2013-09-10 10:00 UTC

Four-panel comparison over the SW Finland / Åland archipelago zoom at the same radar timestamp, each panel using a different value of the isoband layer's subdivide key. The top-left panel (K = 0) is the classic linear marching-squares output — note the sharp diamond-shaped lone-pixel polygons. With increasing K every interior level-curve segment is split into K shorter chords on the true bilinear level curve between the cell-edge intersections, turning the diamonds into progressively rounded four-lobed blobs. The cell-edge intersections themselves are identical across all four panels, which is what lets adjacent cells keep stitching together cleanly regardless of the K value. K = 8 is close to the analytical bilinear shape; K = 10 is the hard cap and produces only a sub-1 % further change.

See the subdivide row in the isoband layer reference and the Bilinear cell subdivision section of the trax docs for the underlying math and limitations.

Output:

radar_subdivide


tmax_smooth — Smoothed maximum temperature

Input: test/input/tmax_smooth.get

GET /dali?customer=test&product=tmax_smooth&time=200101011200 HTTP/1.0
ParameterValueDescription
producttmax_smoothProduct JSON: test/dali/customers/test/products/tmax_smooth.json

Applies a contouring smoother ("smoother": {"degree": 1, "size": 1}) to maximum temperature before rendering isobands; reduces jagged edges in coarse-resolution data.

Output:

tmax_smooth


t2m_p_smooth — Smoothed temperature

Input: test/input/t2m_p_smooth.get

GET /dali?customer=test&product=t2m_p_smooth&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_p_smoothProduct JSON: test/dali/customers/test/products/t2m_p_smooth.json

Same as t2m_p but with a stronger smoother applied to the temperature field, producing fewer and smoother contours.

Output:

t2m_p_smooth


Pressure smoothing comparison

The same European pressure field is rendered with several smoothing pipelines so the visual effect of each can be compared side by side.

Each test is a /dali?customer=test&product=pressure_europe[_variant]&time=200808050300 request. All variants share the same product structure — only the filter block on the isoband/isoline layers changes.

TestFilterProduct JSONOutput
pressure_europe.getNone — raw isobands and isolinespressure_europe.jsonpe
pressure_europe_bezier.getBezier curve fitting on the contour polylines, accuracy 5.0 px (no pre-smoothing of the field)pressure_europe_bezier.jsonpe_b
pressure_europe_bezier_compare.getSide-by-side comparison: no Bezier vs accuracy 2/3/5 pxpressure_europe_bezier_compare.jsonpe_bc
pressure_europe_gaussian.getGaussian filter applied to the field before contouringpressure_europe_gaussian.jsonpe_g
pressure_europe_gaussian_bezier.getGaussian filter on the field + Bezier fitting on the contourspressure_europe_gaussian_bezier.jsonpe_gb
pressure_europe_tukey.getTukey biweight filter (robust to outliers) on the fieldpressure_europe_tukey.jsonpe_t

The Bezier accuracy parameter is the maximum allowed deviation (in pixels) of the fitted cubic curve from the source polyline. The minimum allowed value is 2 px — below that the moment-matching fitter starts producing extreme control points that project far outside the view. Higher accuracy values give smoother, more compact paths at the cost of (mostly imperceptible) visual fidelity. The _compare test renders the same field at four accuracy settings in a 2×2 grid for direct visual comparison.

To eliminate gaps between adjacent isobands' shared edges, the bezier code keeps a per-request cache of fitted cubics keyed by canonical-direction polyline. The cache works for whole rings (rotation- and direction-invariant via canonical-form lookup) and for sub-segments split at counter-flagged corners and at view-boundary vertices. Isolines drawn over isobands hit the same cache. Sub-pixel residual differences may remain where contour ghostlines diverge between rings, but they fall well below the chosen accuracy threshold.

The fitting algorithm is a C++ port of Raph Levien's moment-matching cubic Bezier fitter from the Rust kurbo library, which itself implements ideas from his 2009 UC Berkeley PhD thesis From Spiral to Spline: Optimal Techniques in Interactive Curve Design. The algorithm computes the signed area and first moment of the source curve segment and solves a quartic polynomial for cubic control points whose moments match. The original Rust implementation is dual-licensed Apache-2.0 / MIT.


Grid smoother comparison

Input: test/input/smoother_compare.get

GET /dali?customer=test&product=smoother_compare&time=200808050300 HTTP/1.0
ParameterValueDescription
productsmoother_compareProduct JSON: test/dali/customers/test/products/smoother_compare.json
time200808050300Valid time: 2008-08-05 03:00 UTC

Five panels over the same pal_skandinavia temperature field: the unsmoothed original followed by the four grid smoothers applied at a matched scale so the comparison is about each filter's character rather than how hard it happens to be pushed. The Savitzky-Golay size 3 (7×7) window sets the reference scale; box, median and morphology are tuned to remove the same spatial scale (box radius 1, passes 3; median radius 2; morphology radius 2) — note that at equal radius the rank/morphological filters would remove far more than the polynomial fit, which is what made the earlier per-method gallery misleading.

At this matched scale the differences are qualitative: Savitzky-Golay keeps the most fine detail and the strongest extrema (and costs the most); box removes the same scale of structure but, as a linear low-pass, attenuates the cold pockets the most; median gives sharp, overshoot-free edges (every output value existed in the input) and holds features broader than its window; morphology (openclose) keeps the magnitude of the broad extrema but leaves visibly blocky, axis-aligned boundaries. See the Smoother structure section of the reference for the full parameter list and the Trax grid smoother docs for the algorithms.

Output:

smoother_compare


Grid smoother comparison — low cost

Input: test/input/smoother_compare_small.get

GET /dali?customer=test&product=smoother_compare_small&time=200808050300 HTTP/1.0
ParameterValueDescription
productsmoother_compare_smallProduct JSON: test/dali/customers/test/products/smoother_compare_small.json
time200808050300Valid time: 2008-08-05 03:00 UTC

The companion to the comparison above, but with every method at its minimal setting (Savitzky-Golay reduced to a 5×5 window; box, median and morphology to a single 3×3-class pass). The previous example is tuned to equal smoothing quality, which makes Savitzky-Golay look like the obvious choice — but it is the slowest filter, whereas box and morphology cost O(N) per pass independent of radius and median grows with radius. This panel answers the practical question on a loaded server: which is the cheapest filter that smooths well enough? A single cheap box r1 p1 pass already removes the grid speckle nearly as well as the much more expensive Savitzky-Golay fit. Prefer box for plain smoothing, median/morphology for their edge/speckle behaviour, and reserve Savitzky-Golay for when exact extremum-height preservation is genuinely required. See the Smoother structure section of the reference for the per-method cost notes.

Output:

smoother_compare_small


TFP — Thermal-Front Parameter diagnostics

The TFP (Thermal-Front Parameter) diagnostic highlights baroclinic zones — boundaries where temperature/humidity changes sharply. These three tests apply TFP isobands to different upper-level fields to reveal jet-stream edges, moisture boundaries, and frontal surfaces. Each test is a /dali?customer=test&product=tfp_*&type=png&time=200809101200 request. See the TFP metaparameter section in the reference for the underlying scalar field options.

TestField / LevelProduct JSONOutput
tfp_humidity.getHumidity at 850 hPa (moisture boundaries)tfp_humidity.jsontfp_h
tfp_theta.getPotential temperature at 850 hPa (frontal surface marker)tfp_theta.jsontfp_t
tfp_wind.getWind speed at 300 hPa (jet-stream edges)tfp_wind.jsontfp_w

All three use the ecmwf_skandinavia_painepinta pressure-level producer, render to PNG (700×500 px) over Northern Europe in Web Mercator.


crs_bbox — CRS bounding box handling

Input: test/input/crs_bbox.get

GET /dali?customer=test&product=crs_bbox&time=200808050300 HTTP/1.0
ParameterValueDescription
productcrs_bboxProduct JSON: test/dali/customers/test/products/crs_bbox.json

Tests that the bounding box specified in the product is interpreted correctly in the product's CRS. The product uses "crs": "data" with a smoother applied.

Output:

crs_bbox


t2m_p_noqid — Layers without qid

Input: test/input/t2m_p_noqid.get

GET /dali?customer=test&product=t2m_p_noqid&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_p_noqidProduct JSON: test/dali/customers/test/products/t2m_p_noqid.json

Like t2m_p but the layers omit qid fields. Without a qid, layers cannot be overridden via URL parameters but the product still renders correctly.

Output:

t2m_p_noqid


Isoband Labels

Labels can be placed directly in the isoband definition with the t2m_isoband_labels test, or as a separate IsolabelLayer — see the Isolabel examples section below.

t2m_isoband_labels — Labels embedded in isoband layer

Input: test/input/t2m_isoband_labels.get

GET /dali?customer=test&product=t2m_isoband_labels&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_isoband_labelsProduct JSON: test/dali/customers/test/products/t2m_isoband_labels.json

Demonstrates value labels embedded directly in the isoband layer specification. Labels are drawn along the contour lines at a configured spacing.

Output:

t2m_isoband_labels


Isolabel examples

Labels along isolines using the dedicated IsolabelLayer. The placement algorithm — multi-angle local-extremum scan, divisibility-weighted MST selection, data-probed orientation — is documented in isolabel_algorithms.md. The tests below exercise each tunable in turn (angle handling, cut-through style, multi-style, wide labels, concentric/dense/crossing isolines).

isolabel — Basic isolabels

Input: test/input/isolabel.get

GET /dali?customer=test&product=isolabel&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabelProduct JSON: test/dali/customers/test/products/isolabel.json

Uses the dedicated isolabel layer type to draw contour labels at a fixed spacing along isoline paths.

Output:

isolabel


isolabel_angles — Angle-following labels

Input: test/input/isolabel_angles.get

GET /dali?customer=test&product=isolabel_angles&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_anglesProduct JSON: test/dali/customers/test/products/isolabel_angles.json

Labels are rotated to follow the tangent direction of the isoline.

Output:

isolabel_angles


isolabel_horizontal — Horizontal labels only

Input: test/input/isolabel_horizontal.get

GET /dali?customer=test&product=isolabel_horizontal&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_horizontalProduct JSON: test/dali/customers/test/products/isolabel_horizontal.json

All labels are rendered horizontally regardless of isoline orientation; suitable when readability is prioritised over alignment with the contour.

Output:

isolabel_horizontal


isolabel_cut — Cut-through labels

Input: test/input/isolabel_cut.get

GET /dali?customer=test&product=isolabel_cut&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_cutProduct JSON: test/dali/customers/test/products/isolabel_cut.json

The isoline is cut at each label position so the label appears embedded in the line rather than on top of it.

Output:

isolabel_cut


isolabel_styles — Multiple label styles

Input: test/input/isolabel_styles.get

GET /dali?customer=test&product=isolabel_styles&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_stylesProduct JSON: test/dali/customers/test/products/isolabel_styles.json

Demonstrates per-isoline label styling: each contour level can have its own font size, colour, and background.

Output:

isolabel_styles


isolabel_wide — Wide formatted labels

Input: test/input/isolabel_wide.get

GET /dali?customer=test&product=isolabel_wide&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_wideProduct JSON: test/dali/customers/test/products/isolabel_wide.json

Sets label.precision: 1 and label.suffix: " hPa" so labels render as 1015.0 hPa. Each candidate's collision box is sized from the actual rendered text, so wider labels reserve more space and the MST drops nearby competitors that would have fit at the default width.

Output:

isolabel_wide


isolabel_concentric — Concentric closed contours

Input: test/input/isolabel_concentric.get

GET /dali?customer=test&product=isolabel_concentric&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_concentricProduct JSON: test/dali/customers/test/products/isolabel_concentric.json

Tightens the spacing thresholds (min_distance_self: 80, min_distance_same: 30, min_distance_other: 15) so closely nested closed pressure rings can each carry a label. The MST keeps the ladder placement readable instead of collapsing labels into clusters.

Output:

isolabel_concentric


isolabel_crossing — Two parameters labelled together

Input: test/input/isolabel_crossing.get

GET /dali?customer=test&product=isolabel_crossing&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_crossingProduct JSON: test/dali/customers/test/products/isolabel_crossing.json

Labels two parameters at once — pressure plus temperature. The SAT-based overlap test catches places where the two label sets cross at large angles; without SAT a corner-to-corner-only test would miss those collisions.

Output:

isolabel_crossing


isolabel_dense — Dense isovalue grid

Input: test/input/isolabel_dense.get

GET /dali?customer=test&product=isolabel_dense&time=200808050300 HTTP/1.0
ParameterValueDescription
productisolabel_denseProduct JSON: test/dali/customers/test/products/isolabel_dense.json

Generates pressure isolines at every 1 hPa via isovalues: { start: 990, stop: 1010, step: 1 }. Every divisibility class — multiples of 10, 5, 2, and others — competes for placement; the divisibility weighting keeps the round numbers visible while the rest fill in only where there is room.

Output:

isolabel_dense


Location Label Placement

The LocationLayer places labels next to city markers using one of several algorithms. The full algorithm reference is in docs/labeling_algorithms.md; the tests below exercise each placement strategy and the cross-cutting options (free-space bias, population bucketing, pan invariance).

location_labels_fixed — Fixed NE position

Input: test/input/location_labels_fixed.get

GET /dali?customer=test&product=location_labels_fixed&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_fixedProduct JSON: test/dali/customers/test/products/location_labels_fixed.json

Every label is placed at the NE corner with no conflict avoidance. Labels that would cover a higher-priority marker are dropped (and so is their own marker), but labels are allowed to overlap each other.

Output:

location_labels_fixed


location_labels_greedy — Greedy placement

Input: test/input/location_labels_greedy.get

GET /dali?customer=test&product=location_labels_greedy&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_greedyProduct JSON: test/dali/customers/test/products/location_labels_greedy.json

For each candidate (in geonames priority order) the algorithm tries the eight Imhof positions in priority order and keeps the first one that fits without overlapping a previously placed label or another candidate's marker. Recommended default for most weather maps.

Output:

location_labels_greedy


location_labels_priority_greedy — Population-sorted greedy

Input: test/input/location_labels_priority_greedy.get

GET /dali?customer=test&product=location_labels_priority_greedy&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_priority_greedyProduct JSON: test/dali/customers/test/products/location_labels_priority_greedy.json

Same as greedy, but candidates are pre-sorted by population descending before placement. Use this when geonames autocomplete order does not already match the population ranking you want.

Output:

location_labels_priority_greedy


location_labels_priority_greedy_bucketed — Population buckets + shorter-name tiebreak

Input: test/input/location_labels_priority_greedy_bucketed.get

GET /dali?customer=test&product=location_labels_priority_greedy_bucketed&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_priority_greedy_bucketedProduct JSON: test/dali/customers/test/products/location_labels_priority_greedy_bucketed.json

Adds priority_bucket_ratio: 2.0 so cities with similar populations land in the same log-bucket and the shorter label wins ties. On dense maps this typically places more labels overall — short names slot into prime NE positions and free up room for neighbours.

Output:

location_labels_priority_greedy_bucketed


location_labels_sa — Simulated annealing

Input: test/input/location_labels_sa.get

GET /dali?customer=test&product=location_labels_sa&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_saProduct JSON: test/dali/customers/test/products/location_labels_sa.json

Uses Christensen-Marks-Shieber simulated annealing to minimise total label-overlap energy. Converges toward a near-global optimum that pure greedy can miss in dense urban areas where several labels need to coordinate to fit. The random seed is fixed so results are deterministic.

Output:

location_labels_sa


location_labels_freespace — Greedy with free-space bias

Input: test/input/location_labels_freespace.get

GET /dali?customer=test&product=location_labels_freespace&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_freespaceProduct JSON: test/dali/customers/test/products/location_labels_freespace.json

Adds free_space_weight: 1.5, free_space_radius: 120 to the greedy run. Each candidate scores positions by alignment with the direction away from neighbouring markers and labels, so coastal cities push their labels out into the empty water without needing a sea mask.

Output:

location_labels_freespace


location_labels_sa_freespace — Simulated annealing with free-space bias

Input: test/input/location_labels_sa_freespace.get

GET /dali?customer=test&product=location_labels_sa_freespace&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_sa_freespaceProduct JSON: test/dali/customers/test/products/location_labels_sa_freespace.json

The same free-space bias on top of SA's overlap optimisation: the bias term is added to the position penalty and recomputed on every move so the bias reflects the current assignment.

Output:

location_labels_sa_freespace


location_labels_pan_invariant — Pan-invariant greedy

Input: test/input/location_labels_pan_invariant.get

GET /dali?customer=test&product=location_labels_pan_invariant&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_pan_invariantProduct JSON: test/dali/customers/test/products/location_labels_pan_invariant.json

Sets pan_invariant: true and centres on Jyväskylä. Candidates are filtered to a margin-buffered bbox so cities just beyond the visible edge still influence the placement of visible cities; anchors outside the original bbox are skipped at render time.

Output:

location_labels_pan_invariant


location_labels_pan_invariant_shifted — Same view, panned 0.5° east

Input: test/input/location_labels_pan_invariant_shifted.get

GET /dali?customer=test&product=location_labels_pan_invariant_shifted&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_pan_invariant_shiftedProduct JSON: test/dali/customers/test/products/location_labels_pan_invariant_shifted.json

Same projection as location_labels_pan_invariant but with cx shifted by +0.5°. Cities visible in both panned views land at identical offsets from their markers — pan invariance verified per-city by the test harness.

Output:

location_labels_pan_invariant_shifted


location_labels_country_off / _on — Country constraint

This pair demonstrates the country_constraint option, zoomed to the Finland–Russia border around Lappeenranta / Imatra (Finland) and Viipuri / Vyborg (Russia). Finland is tinted blue and Russia red so it is obvious which side of the border each label lands on. The keyword ajax_fi_all is a worldwide place set, so non-Finnish names (e.g. Viipuri) appear alongside the Finnish towns. Both products are identical except for the single "country_constraint": true flag.

Input: test/input/location_labels_country_off.get · test/input/location_labels_country_on.get

GET /dali?customer=test&product=location_labels_country_off&type=svg HTTP/1.0
GET /dali?customer=test&product=location_labels_country_on&type=svg HTTP/1.0
ParameterValueDescription
productlocation_labels_country_offProduct JSON: test/dali/customers/test/products/location_labels_country_off.json — greedy placement, no constraint
productlocation_labels_country_onProduct JSON: test/dali/customers/test/products/location_labels_country_on.json — same, with "country_constraint": true

Watch the border-hugging towns Nuijamaa, Vainikkala, Hiivaniemi and Ahola. Without the constraint their labels lean east, across the border into Russia (red). With the constraint enabled every label is forced to stay within its own country's polygon, so those labels flip west into Finland (blue). Towns far from the border — Viipuri (RU), Lappeenranta and Imatra (FI) — are unaffected: the constraint only intervenes where a label would otherwise cross a border.

Output — without country_constraint (left) vs with it (right):

country_constraint: off
country_constraint: on

SVG Customisation

t2m_p_shadow — SVG drop shadow

Input: test/input/t2m_p_shadow.get

GET /dali?customer=test&product=t2m_p_shadow&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_p_shadowProduct JSON: test/dali/customers/test/products/t2m_p_shadow.json

Adds an SVG <filter> drop-shadow (feDropShadow) to the product's root element via the top-level "attributes": {"filter": "url(#shadow)"} setting.

Output:

t2m_p_shadow


t2m_p_display_none — Hidden layer with optimizesize

Input: test/input/t2m_p_display_none.get

GET /dali?customer=test&product=t2m_p&time=200808050300&l3.attributes.display=none&optimizesize=1 HTTP/1.0
ParameterValueDescription
l3.attributes.displaynoneSets display=none on layer l3 via URL override, making it invisible
optimizesize1When set, layers with display=none are omitted from the output entirely (reducing file size)

The optimizesize flag strips out hidden layers rather than leaving them as invisible elements in the SVG.

Output:

t2m_p_display_none


t2m_pattern — SVG pattern fill

Input: test/input/t2m_pattern.get

GET /dali?customer=test&product=t2m_pattern&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_patternProduct JSON: test/dali/customers/test/products/t2m_pattern.json

Uses SVG <pattern> elements defined in the defs section to fill isoband polygons with a hatching or repeat pattern rather than a solid colour.

Output:

t2m_pattern


defs_circle — SVG defs with reusable shapes

Input: test/input/defs_circle.get

GET /dali?customer=test&product=defs_circle&time=200808050300 HTTP/1.0
ParameterValueDescription
productdefs_circleProduct JSON: test/dali/customers/test/products/defs_circle.json

Shows how defs.layers can define reusable SVG elements (filters, named circles, clip paths, text nodes) that are referenced later via xlink:href.

Output:

defs_circle


clip — Explicit clipPath layer

Input: test/input/clip.get

GET /dali?customer=test&product=clip&time=200808050300 HTTP/1.0
ParameterValueDescription
productclipProduct JSON: test/dali/customers/test/products/clip.json

Uses a tag: "clipPath" layer containing a tag: "circle" to create an SVG <clipPath> element inline. A tag: "g" wrapper layer with clip-path: url(#mycircle) then applies it to the isoband layers, while the product-level filter: url(#shadow) adds a drop shadow.

Output:

clip


circle — Circular clip with isobands

Input: test/input/circle.get

GET /dali?customer=test&product=circle&time=200808050300 HTTP/1.0
ParameterValueDescription
productcircleProduct JSON: test/dali/customers/test/products/circle.json
time200808050300Valid time: 2008-08-05 03:00 UTC

Projects Scandinavian temperature data using the data's own native CRS, renders temperature isobands and isolines, and clips the output with an SVG <circle> element centred at (250, 250) with radius 250.

Output:

circle


Clipping to Geographic Boundaries

t2m_inside_finland — Clip to country polygon

Input: test/input/t2m_inside_finland.get

GET /dali?customer=test&product=t2m_inside_finland&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_inside_finlandProduct JSON: test/dali/customers/test/products/t2m_inside_finland.json

Uses "inside" on the isoband layer referencing a PostGIS query for the Finland border (iso_a2='FI') to clip the rendered isobands to inside Finland.

Output:

t2m_inside_finland


t2m_inside_simplified_finland — Clip to simplified country polygon

Input: test/input/t2m_inside_simplified_finland.get

GET /dali?customer=test&product=t2m_inside_simplified_finland&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_inside_simplified_finlandProduct JSON: test/dali/customers/test/products/t2m_inside_simplified_finland.json

Same as above but uses a mindistance tolerance to simplify the clip polygon, producing a smoother (less precise) boundary and faster rendering.

Output:

t2m_inside_simplified_finland


t2m_outside_finland — Clip to outside country

Input: test/input/t2m_outside_finland.get

GET /dali?customer=test&product=t2m_outside_finland&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_outside_finlandProduct JSON: test/dali/customers/test/products/t2m_outside_finland.json

Uses "outside" to clip isobands to the area outside Finland — the inverse of t2m_inside_finland.

Output:

t2m_outside_finland


t2m_inside_rain — Clip isobands to rain area

Input: test/input/t2m_inside_rain.get

GET /dali?customer=test&product=t2m_inside_rain&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_inside_rainProduct JSON: test/dali/customers/test/products/t2m_inside_rain.json

Clips temperature isobands to areas where precipitation exceeds 0 mm/h (the rain area). The inside polygon is derived dynamically from another data layer rather than from a static geographic boundary.

Output:

t2m_inside_rain


t2m_lines_inside_rain — Isolines clipped to rain area

Input: test/input/t2m_lines_inside_rain.get

GET /dali?customer=test&product=t2m_lines_inside_rain&time=200808050300 HTTP/1.0
ParameterValueDescription
productt2m_lines_inside_rainProduct JSON: test/dali/customers/test/products/t2m_lines_inside_rain.json

Temperature isolines (not isobands) are clipped to the rain area. Shows that the inside clipping mechanism works equally for line layers.

Output:

t2m_lines_inside_rain


frost_inside_simplified_finland — Frost probability inside Finland

Input: test/input/frost_inside_simplified_finland.get

GET /dali?customer=test&product=frost_inside_simplified_finland&time=201604140000 HTTP/1.0
ParameterValueDescription
productfrost_inside_simplified_finlandProduct JSON: test/dali/customers/test/products/frost_inside_simplified_finland.json
time201604140000Valid time: 2016-04-14 00:00 UTC

Renders FrostProbability isobands from the ground producer at 1200×1200 px in EPSG:4326. Uses "inside": "ref:refs.finland" where the refs.finland entry queries the Natural Earth countries table with iso_a2 IN ('FI','AX') and a mindistance simplification tolerance.

Output:

frost_inside_simplified_finland


Pressure Level and Elevation Selection

t2m_level_* — Named pressure levels

Input files: test/input/t2m_level_1000.get, test/input/t2m_level_850.get, test/input/t2m_level_300.get

GET /dali?customer=test&product=t2m_pressurelevel&time=20080909T1200&level=1000 HTTP/1.0
GET /dali?customer=test&product=t2m_pressurelevel&time=20080909T1200&level=850  HTTP/1.0
GET /dali?customer=test&product=t2m_pressurelevel&time=20080909T1200&level=300  HTTP/1.0
ParameterValueDescription
productt2m_pressurelevelProduct JSON: test/dali/customers/test/products/t2m_pressurelevel.json
time20080909T1200Valid time: 2008-09-09 12:00 UTC
level1000 / 850 / 300Selects the pressure level in hPa from the ecmwf_skandinavia_painepinta producer

The level parameter selects a pressure level slice; the producer must have data for that level.

LevelOutput
1000 hPat2m_level_1000
850 hPat2m_level_850
300 hPat2m_level_300

t2m_elevation_* — Elevation in metres

Input files: test/input/t2m_elevation_1000.get, test/input/t2m_elevation_850.get, test/input/t2m_elevation_300.get

GET /dali?customer=test&product=t2m_pressurelevel&time=20080909T1200&elevation=1000 HTTP/1.0
GET /dali?customer=test&product=t2m_pressurelevel&time=20080909T1200&elevation=850  HTTP/1.0
GET /dali?customer=test&product=t2m_pressurelevel&time=20080909T1200&elevation=300  HTTP/1.0
ParameterValueDescription
elevation1000 / 850 / 300Selects the level using the elevation parameter (in metres or hPa depending on data convention)

The elevation parameter is an alternative to level; which one is applicable depends on the data source's level type convention.

ElevationOutput
1000 mt2m_elevation_1000
850 mt2m_elevation_850
300 mt2m_elevation_300

high_resolution — High resolution rendering

Input: test/input/high_resolution.get

GET /dali?customer=test&product=high_resolution&time=202006051200 HTTP/1.0
ParameterValueDescription
producthigh_resolutionProduct JSON: test/dali/customers/test/products/high_resolution.json
time202006051200Valid time: 2020-06-05 12:00 UTC

Tests rendering of a high-resolution model grid (e.g. HARMONIE/AROME). Listed in .testignore as a debugging test case with non-deterministic output in CI.

No reference output image available.


Multiple Views and Side-by-Side Products

t2m_twice — Two views side by side

Input: test/input/t2m_twice.get

GET /dali?customer=test&product=t2m_twice&time=200808050300&v2.time_offset=1440 HTTP/1.0
ParameterValueDescription
productt2m_twiceProduct JSON: test/dali/customers/test/products/t2m_twice.json
v2.time_offset`1440$\text{Advances} \text{the} \text{valid} \text{time} \text{of} \text{view} 2 \text{by} 1440 \text{minutes} (24 \text{hours})

\text{The} \text{product} \text{defines} \text{two} 500 \times 500 \text{px} \text{views} ($v1, v2) side by side in a 1030×520 canvas. Each view includes temperature isobands, isolines, and a time label. The URL overrides v2.time_offset` to show T+24 h in the second panel.

Output:

t2m_twice


t2m_twice_altered — Transformed second view

Input: test/input/t2m_twice_altered.get

GET /dali?customer=test&product=t2m_twice&time=200808050300
    &v2.time_offset=1440
    &v2.attributes.transform=translate%28500,1%29+rotate%2830%29+scale%280.75%29
    &v1.attributes.filter=url%28#shadow%29
    &v2.attributes.filter=url%28#shadow%29 HTTP/1.0
ParameterValueDescription
v2.attributes.transformtranslate(500,1) rotate(30) scale(0.75)Applies an SVG transform to view 2: shifted, rotated 30°, scaled 75%
v1.attributes.filterurl(#shadow)Adds a drop-shadow filter to view 1
v2.attributes.filterurl(#shadow)Adds a drop-shadow filter to view 2

Demonstrates that SVG attributes (including transform and filter) can be set on any view via URL overrides. The URL-encoded values %28 = (, %29 = ).

Output:

t2m_twice_altered


t2m_twice_margins — Views with margins (unclipped)

Input: test/input/t2m_twice_margins.get

GET /dali?customer=test&product=t2m_twice&time=200808050300
    &v2.time_offset=1440
    &v1.clip=0&v2.clip=0
    &v1.margin=5&v2.margin=10
    &projection.place=Helsinki&projection.resolution=1 HTTP/1.0
ParameterValueDescription
v1.clip0Disables clipping for view 1 (data may extend beyond the view boundary)
v2.clip0Disables clipping for view 2
v1.margin5Adds a 5-pixel margin around view 1's data extent
v2.margin10Adds a 10-pixel margin around view 2's data extent
projection.placeHelsinkiCentres the projection on Helsinki
projection.resolution1Sets projection resolution to 1 km/px

Output:

t2m_twice_margins


t2m_twice_margins_clipped — Views with margins (clipped)

Input: test/input/t2m_twice_margins_clipped.get

GET /dali?customer=test&product=t2m_twice&time=200808050300
    &v2.time_offset=1440
    &v1.clip=1&v2.clip=1
    &v1.margin=5&v2.margin=10
    &projection.place=Helsinki&projection.resolution=1 HTTP/1.0
ParameterValueDescription
v1.clip1Enables clipping for view 1
v2.clip1Enables clipping for view 2

Same as t2m_twice_margins but clipping is re-enabled. Layers are clipped to the view boundary even though a margin is specified.

Output:

t2m_twice_margins_clipped


resolution — View-level projection resolution

Input: test/input/resolution.get

GET /dali?customer=test&product=resolution&time=200808050300 HTTP/1.0
ParameterValueDescription
productresolutionProduct JSON: test/dali/customers/test/products/resolution.json

Two 500×500 views centred on Finland are placed side by side, each with a different resolution setting in their projection block (2.5 and 1.5 km/px). Map layers use minresolution and maxresolution to select detail levels: coarse data is shown in black for coarse resolutions, fine data in red for fine resolutions.

Output:

resolution


ely_overlay — Multi-customer overlay

Input: test/input/ely_overlay.get

GET /dali?customer=ely&product=temperatureoverlay&time=200808080000&type=svg HTTP/1.1
ParameterValueDescription
customerelySelects the ely customer directory (separate from test)
producttemperatureoverlayProduct JSON: test/dali/customers/ely/products/temperatureoverlay.json
typesvgSVG output

A second customer (ely) demonstrating that multiple customer configurations can coexist. This overlay product uses a number layer with a masked legend background.

Output:

ely_overlay


Time Layer and Timezone

timelayer — Time annotation

Input: test/input/timelayer.get

GET /dali?customer=test&product=timelayer&time=200808051200 HTTP/1.0
ParameterValueDescription
producttimelayerProduct JSON: test/dali/customers/test/products/timelayer.json
time200808051200Valid time: 2008-08-05 12:00 UTC

The time layer renders the product's valid time as formatted text (e.g. "%Y-%m-%d %H:%M") at a specified position in the SVG. The product uses "timestamp": "validtime" and "timezone": "UTC".

Output:

timelayer


timezone — Time in local timezone

Input: test/input/timezone.get

GET /dali?customer=test&product=timelayer&time=200808051500&tz=Europe/Helsinki HTTP/1.0
ParameterValueDescription
time200808051500Valid time: 2008-08-05 15:00 UTC
tzEurope/HelsinkiOverrides the display timezone for the time layer; 15:00 UTC → 18:00 EEST

The tz URL parameter overrides the product's timezone for all time layer annotations in the response.

Output:

timezone


Observation Numbers

temperature_fmisid — Station temperatures by FMI ID

Input: test/input/temperature_fmisid.get

GET /dali?customer=test&product=temperature_fmisid&time=200808050300 HTTP/1.0
ParameterValueDescription
producttemperature_fmisidProduct JSON: test/dali/customers/test/products/temperature_fmisid.json
time200808050300Valid time: 2008-08-05 03:00 UTC

Plots temperature observations at a hand-picked list of FMI station IDs (fmisid). Individual stations may override the default label offset (dx, dy). Background: white fill + Natural Earth country borders.

Output:

temperature_fmisid


opendata_temperature_fmisid — Opendata station temperatures

Input: test/input/opendata_temperature_fmisid.get

GET /dali?customer=test&product=opendata_temperature_fmisid&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_temperature_fmisidProduct JSON: test/dali/customers/test/products/opendata_temperature_fmisid.json
time20130805T1500Valid time: 2013-08-05 15:00 UTC (ISO 8601 compact format)

Same concept as temperature_fmisid but using the opendata producer from the Finnish Meteorological Institute.

Output:

opendata_temperature_fmisid


opendata_temperature_fmisid_shift — Station numbers with label offset

Input: test/input/opendata_temperature_fmisid_shift.get

GET /dali?customer=test&product=opendata_temperature_fmisid_shift&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_temperature_fmisid_shiftProduct JSON: test/dali/customers/test/products/opendata_temperature_fmisid_shift.json

Station labels are systematically shifted (dx, dy) to reduce overlap with symbols.

Output:

opendata_temperature_fmisid_shift


opendata_temperature_grid — Grid-spaced observation numbers

Input: test/input/opendata_temperature_grid.get

GET /dali?customer=test&product=opendata_temperature_grid&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_temperature_gridProduct JSON: test/dali/customers/test/products/opendata_temperature_grid.json

Uses "positions": {"layout": "grid", "dx": 30, "dy": 30} to place observation values at regular pixel intervals, thinning dense station networks.

Output:

opendata_temperature_grid


opendata_temperature_keyword — Keyword-selected stations

Input: test/input/opendata_temperature_keyword.get

GET /dali?customer=test&product=opendata_temperature_keyword&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_temperature_keywordProduct JSON: test/dali/customers/test/products/opendata_temperature_keyword.json

Selects stations by keyword (administrative classification such as county or municipality) rather than by explicit FMI station IDs.

Output:

opendata_temperature_keyword


ecmwf_data_numbers — ECMWF grid point values

Input: test/input/ecmwf_data_numbers.get

GET /dali?customer=test&product=ecmwf_data_numbers&time=201503131200 HTTP/1.0
ParameterValueDescription
productecmwf_data_numbersProduct JSON: test/dali/customers/test/products/ecmwf_data_numbers.json
time201503131200Valid time: 2015-03-13 12:00 UTC

Plots temperature values at regular grid intervals from the ECMWF surface analysis (ecmwf_maailma_pinta) over Europe.

Output:

ecmwf_data_numbers


ecmwfpoint_data_numbers — ECMWF point values

Input: test/input/ecmwfpoint_data_numbers.get

GET /dali?customer=test&product=ecmwfpoint_data_numbers&time=200808051200 HTTP/1.0
ParameterValueDescription
productecmwfpoint_data_numbersProduct JSON: test/dali/customers/test/products/ecmwfpoint_data_numbers.json
time200808051200Valid time: 2008-08-05 12:00 UTC

Plots ECMWF model values at specific geographic point locations rather than a regular grid.

Output:

ecmwfpoint_data_numbers


ecmwf_world_numbers — ECMWF global grid values

Input: test/input/ecmwf_world_numbers.get

GET /dali?customer=test&product=ecmwf_world_numbers&time=201503131200 HTTP/1.0
ParameterValueDescription
productecmwf_world_numbersProduct JSON: test/dali/customers/test/products/ecmwf_world_numbers.json

Plots ECMWF global surface temperature values at grid intervals on a world map.

Output:

ecmwf_world_numbers


aviation_numbers — Aviation temperature numbers

Input: test/input/aviation_numbers.get

GET /dali?customer=test&product=aviation_numbers&time=201503131200 HTTP/1.0
ParameterValueDescription
productaviation_numbersProduct JSON: test/dali/customers/test/products/aviation_numbers.json
time201503131200Valid time: 2015-03-13 12:00 UTC

Renders ECMWF temperature isobands over the North Atlantic aviation area (EPSG:4326, 62.5–75°N, 15°W–37.5°E) and overlays integer temperature values at a 20×20 px grid with alternating 10-pixel row offsets (ddx).

Output:

aviation_numbers


aviation_numbers_multiple5 — Rounded-to-5 numbers

Input: test/input/aviation_numbers_multiple5.get

GET /dali?customer=test&product=aviation_numbers_multiple5&time=201503131200 HTTP/1.0
ParameterValueDescription
productaviation_numbers_multiple5Product JSON: test/dali/customers/test/products/aviation_numbers_multiple5.json

Like aviation_numbers but values are rounded to the nearest 5 (ICAO convention: temperatures reported in multiples of 5°C on SIGWX charts).

Output:

aviation_numbers_multiple5


synop_numbers — SYNOP observation values

Input: test/input/synop_numbers.get

GET /dali?customer=test&product=synop_numbers&time=20081201T1200 HTTP/1.0
ParameterValueDescription
productsynop_numbersProduct JSON: test/dali/customers/test/products/synop_numbers.json
time20081201T1200Valid time: 2008-12-01 12:00 UTC

Plots SYNOP observation values from the pal_skandinavia producer at station locations.

Output:

synop_numbers


monitoring — Health monitoring text

Input: test/input/monitoring.get

GET /dali?customer=test&product=monitoring HTTP/1.0
ParameterValueDescription
productmonitoringProduct JSON: test/dali/customers/test/products/monitoring.json

A minimal product that outputs a plain-text "OK" health-check response without requiring any weather data. Used for liveness/readiness probes.

Output:

monitoring


Observation Positions and Keyword Selection

latlon_positions — Lat/lon coordinate list

Input: test/input/latlon_positions.get

GET /dali?customer=test&product=latlon_positions&time=201503131200 HTTP/1.0
ParameterValueDescription
productlatlon_positionsProduct JSON: test/dali/customers/test/products/latlon_positions.json

Plots observation values at positions specified as explicit latitude/longitude coordinate pairs in the product JSON.

Output:

latlon_positions


latlon_positions_shifted — Positions with per-station label offset

Input: test/input/latlon_positions_shifted.get

GET /dali?customer=test&product=latlon_positions_shifted&time=201503131200 HTTP/1.0
ParameterValueDescription
productlatlon_positions_shiftedProduct JSON: test/dali/customers/test/products/latlon_positions_shifted.json

Each coordinate entry includes an individual dx/dy offset for its label, allowing crowded stations to be legible without overlapping.

Output:

latlon_positions_shifted


keyword — Keyword-based station selection

Input: test/input/keyword.get

GET /dali?customer=test&product=keyword&time=201503131200 HTTP/1.0
ParameterValueDescription
productkeywordProduct JSON: test/dali/customers/test/products/keyword.json

Selects stations using a keyword field (e.g. a municipality or region name) instead of numeric IDs. The server resolves the keyword to matching stations.

Output:

keyword


keyword_shifted — Keyword stations with shifted labels

Input: test/input/keyword_shifted.get

GET /dali?customer=test&product=keyword_shifted&time=201503131200 HTTP/1.0
ParameterValueDescription
productkeyword_shiftedProduct JSON: test/dali/customers/test/products/keyword_shifted.json

Same as keyword but with per-station label offsets (dx, dy) defined for each keyword entry.

Output:

keyword_shifted


Weather Symbols

opendata_temperature_symbols — SmartMet symbols

Input: test/input/opendata_temperature_symbols.get

GET /dali?customer=test&product=opendata_temperature_symbols&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_temperature_symbolsProduct JSON: test/dali/customers/test/products/opendata_temperature_symbols.json
time20130805T1500Valid time: 2013-08-05 15:00 UTC

Plots SmartMet weather symbols at station locations combined with temperature numbers.

Output:

opendata_temperature_symbols


opendata_temperature_symbols_oddmitime — Odd-minute valid time

Input: test/input/opendata_temperature_symbols_oddmitime.get

GET /dali?customer=test&product=opendata_temperature_symbols&time=20130805T1502 HTTP/1.0
ParameterValueDescription
time20130805T1502Valid time: 15:02 UTC — not on the hour; tests nearest-time matching

Tests that the system correctly snaps to the nearest available observation when the requested time is between observation steps.

Output:

opendata_temperature_symbols_oddmitime


opendata_temperature_symbols_oddmitime_interval_back — Time interval backward

Input: test/input/opendata_temperature_symbols_oddmitime_interval_back.get

GET /dali?customer=test&product=opendata_temperature_symbols&time=20130805T1502&interval_start=2 HTTP/1.0
ParameterValueDescription
time20130805T1502Non-round valid time
interval_start2Accept data up to 2 minutes before the requested time

The interval_start parameter widens the time-matching window backward, useful for observations that arrive with a slight delay.

Output:

opendata_temperature_symbols_oddmitime_interval_back


opendata_temperature_symbols_oddmitime_interval_forward — Time interval forward

Input: test/input/opendata_temperature_symbols_oddmitime_interval_forward.get

GET /dali?customer=test&product=opendata_temperature_symbols&time=20130805T1455&interval_end=5 HTTP/1.0
ParameterValueDescription
time20130805T1455Non-round valid time: 5 minutes before 15:00
interval_end5Accept data up to 5 minutes after the requested time

The interval_end parameter widens the window forward, allowing a request before the hour to still display the on-the-hour data.

Output:

opendata_temperature_symbols_oddmitime_interval_forward


smartsymbol — SmartMet numeric symbol codes

Input: test/input/smartsymbol.get

GET /dali?customer=test&product=smartsymbol&time=200808050300 HTTP/1.0
ParameterValueDescription
productsmartsymbolProduct JSON: test/dali/customers/test/products/smartsymbol.json

Renders the SmartSymbol parameter (integer code) as SVG symbol graphics at station locations. Each code maps to an SVG symbol ID loaded from the symbol set.

Output:

smartsymbol


smartsymbolnumber — Symbol codes as numbers

Input: test/input/smartsymbolnumber.get

GET /dali?customer=test&product=smartsymbolnumber&time=200808050300 HTTP/1.0
ParameterValueDescription
productsmartsymbolnumberProduct JSON: test/dali/customers/test/products/smartsymbolnumber.json

Plots the numeric SmartSymbol code as a text label (for debugging).

Output:

smartsymbolnumber


weather — Standard weather symbols

Input: test/input/weather.get

GET /dali?customer=test&product=weather&time=200808050300 HTTP/1.0
ParameterValueDescription
productweatherProduct JSON: test/dali/customers/test/products/weather.json

Renders a set of weather symbols loaded from SVG symbol files. The product combines a map background with symbol layer.

Output:

weather


weather-cssdef — Inline CSS override via URL

Input: test/input/weather-cssdef.get

GET /dali?customer=test&product=weather&time=200808050300
    &defs.css.test%2Fsymbols%2Fdot=data:,.Dot%20%7B%20fill%3A%20yellow%3B%20stroke%3A%20none%20%7D%0A HTTP/1.0
ParameterValue (URL-decoded)Description
defs.css.test/symbols/dotdata:,.Dot { fill: yellow; stroke: none }Inlines a CSS rule for the dot symbol class via a data-URL; overrides the file-based CSS

The defs.css.{name}=data:,... pattern allows injecting arbitrary CSS rules through the URL without modifying product files.

Output:

weather-cssdef


weather-symbol-dataurl-get — Inline SVG symbol override

Input: test/input/weather-symbol-dataurl-get.get

GET /dali?customer=test&product=weather-base64-symbol&time=200808050300
    &defs.symbols.weather%2F1_II%2F1="data:;base64,PHN5bWJvbC..." HTTP/1.0
ParameterValue (URL-decoded)Description
defs.symbols.weather/1_II/1data:;base64,<base64-SVG>Replaces the SVG symbol weather/1_II/1 with an inline base64-encoded SVG symbol (an orange circle)

Allows runtime replacement of individual symbols through the URL, e.g. for A/B testing or custom client-specific iconography.

Output:

weather-symbol-dataurl-get


weather-base64json-symbol — Base64 symbol from JSON

Input: test/input/weather-base64json-symbol.get

GET /dali?customer=test&product=weather-base64-symbol&time=200808050300 HTTP/1.0
ParameterValueDescription
productweather-base64-symbolProduct JSON: test/dali/customers/test/products/weather-base64-symbol.json

The product JSON itself specifies symbols using data:;base64,… data URLs (base64-encoded SVG), bypassing the filesystem symbol store. Tests that the server can decode and embed inline symbols from the product definition.

Output:

weather-base64json-symbol


symbols_coloured — Weather symbols in multiple projections

The same symbols_coloured product is rendered in four different projections using the projection.crs URL override:

Inputs:

ParameterValueDescription
productsymbols_colouredProduct JSON: test/dali/customers/test/products/symbols_coloured.json
projection.crs(varies)Overrides the product's CRS on-the-fly

Demonstrates that projection.crs can reproject any product at request time without modifying the JSON.

ProjectionOutput
Native CRSsymbols_coloured_native
EPSG:3067 (ETRS-TM35FIN)symbols_coloured_fin
EPSG:3857 (WebMercator)symbols_coloured_webmercator
WGS84symbols_coloured_wgs84

Flash and Lightning Symbols

flash_symbols — Combined flash symbols

Input: test/input/flash_symbols.get

GET /dali?customer=test&product=flash_symbols&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productflash_symbolsProduct JSON: test/dali/customers/test/products/flash_symbols.json
time20130805T1500Valid time: 2013-08-05 15:00 UTC

Plots all flash (lightning) strike locations (cloud-to-ground and cloud-to-cloud) as symbols from the flash producer.

Output:

flash_symbols


flash_cloud_symbols — Cloud flash only

Input: test/input/flash_cloud_symbols.get

GET /dali?customer=test&product=flash_cloud_symbols&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productflash_cloud_symbolsProduct JSON: test/dali/customers/test/products/flash_cloud_symbols.json

Plots only intra-cloud (IC) lightning flashes, filtering out cloud-to-ground (CG) strikes.

Output:

flash_cloud_symbols


flash_ground_symbols — Ground flash only

Input: test/input/flash_ground_symbols.get

GET /dali?customer=test&product=flash_ground_symbols&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productflash_ground_symbolsProduct JSON: test/dali/customers/test/products/flash_ground_symbols.json

Plots only cloud-to-ground (CG) lightning strikes.

Output:

flash_ground_symbols


flash_cloud_and_ground_symbols — Separate symbol types

Input: test/input/flash_cloud_and_ground_symbols.get

GET /dali?customer=test&product=flash_cloud_and_ground_symbols&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productflash_cloud_and_ground_symbolsProduct JSON: test/dali/customers/test/products/flash_cloud_and_ground_symbols.json

Uses two symbol layers (one for IC, one for CG) with distinct symbol shapes and colours in a single product.

Output:

flash_cloud_and_ground_symbols


Wind Arrows

wind — Basic wind arrows

Input: test/input/wind.get

GET /dali?customer=test&product=wind&time=200808050300 HTTP/1.0
ParameterValueDescription
productwindProduct JSON: test/dali/customers/test/products/wind.json

Renders wind direction arrows from pal_skandinavia using "direction" and "speed" parameters. Arrow length scales with wind speed.

Output:

wind


wind_margin — Wind arrows with map margin

Input: test/input/wind_margin.get

GET /dali?customer=test&product=wind_margin&time=200808050300 HTTP/1.0
ParameterValueDescription
productwind_marginProduct JSON: test/dali/customers/test/products/wind_margin.json

Same wind arrows but with a map area margin setting that extends the data area outside the nominal bounding box.

Output:

wind_margin


wind_minrotationspeed — Arrow rotation threshold

Input: test/input/wind_minrotationspeed.get

GET /dali?customer=test&product=wind&time=200808050300&l3.minrotationspeed=10 HTTP/1.0
ParameterValueDescription
l3.minrotationspeed10Arrows for layer l3 are only rotated (to point in the wind direction) when wind speed exceeds 10 m/s; calmer arrows remain pointing north

The minrotationspeed threshold prevents cluttered arrow directions at very low wind speeds.

Output:

wind_minrotationspeed


wind_scaled — Scaled wind arrows

Input: test/input/wind_scaled.get

GET /dali?customer=test&product=wind_scaled&time=200808050300 HTTP/1.0
ParameterValueDescription
productwind_scaledProduct JSON: test/dali/customers/test/products/wind_scaled.json

Uses an explicit "scale" factor to map wind speed to arrow length.

Output:

wind_scaled


wind_without_speed — Direction-only arrows

Input: test/input/wind_without_speed.get

GET /dali?customer=test&product=wind_without_speed&time=200808050300 HTTP/1.0
ParameterValueDescription
productwind_without_speedProduct JSON: test/dali/customers/test/products/wind_without_speed.json

Arrows show direction only; all arrows are rendered at the same fixed length since no speed parameter is provided.

Output:

wind_without_speed


hirlam_wind — HIRLAM wind (direction + speed)

Input: test/input/hirlam_wind.get

GET /dali?customer=test&product=hirlam_wind&time=201804060600 HTTP/1.0
ParameterValueDescription
producthirlam_windProduct JSON: test/dali/customers/test/products/hirlam_wind.json
time201804060600Valid time: 2018-04-06 06:00 UTC

Arrow layer using meteorological "direction": "WindDirection" and "speed": "WindSpeedMS" parameters from the HIRLAM NWP model.

Output:

hirlam_wind


hirlam_uv — HIRLAM wind (U/V components)

Input: test/input/hirlam_uv.get

GET /dali?customer=test&product=hirlam_uv&time=201804060600 HTTP/1.0
ParameterValueDescription
producthirlam_uvProduct JSON: test/dali/customers/test/products/hirlam_uv.json

Arrow layer using Cartesian wind components "u": "WindUMS" and "v": "WindVMS" instead of direction/speed. The server converts U/V to direction and magnitude internally.

Output:

hirlam_uv


Wind Barbs and Wind Roses

windbarb — Classic wind barbs

Input: test/input/windbarb.get

GET /dali?customer=test&product=windbarb&time=200808050300 HTTP/1.0
ParameterValueDescription
productwindbarbProduct JSON: test/dali/customers/test/products/windbarb.json

Renders standard meteorological wind barbs (staff + barbs/pennants encoding speed in knots).

Output:

windbarb


windrose — Wind roses at stations

Input: test/input/windrose.get

GET /dali?customer=test&product=windrose&time=2013-08-05 HTTP/1.0
ParameterValueDescription
productwindroseProduct JSON: test/dali/customers/test/products/windrose.json
time2013-08-05Valid date: 2013-08-05 (ISO 8601 date-only format)

Renders wind roses at named coastal stations showing frequency distribution of wind direction and speed classes. Each rose uses starttimeoffset/endtimeoffset to aggregate over a 24-hour window. Station titles and connectors are customisable via CSS classes.

Output:

windrose


WAFS Aviation Charts

WAFS (World Area Forecast System) products use ICAO aviation weather data at pressure levels.

wafs_temperature — Upper-level temperature

Input: test/input/wafs_temperature.get

GET /dali?customer=test&product=wafs_temperature&time=201601191800 HTTP/1.0
ParameterValueDescription
productwafs_temperatureProduct JSON: test/dali/customers/test/products/wafs_temperature.json
time201601191800Valid time: 2016-01-19 18:00 UTC

Temperature isobands at a WAFS pressure level (flight level) over the North Atlantic aviation area.

Output:

wafs_temperature


wafs_wind — Upper-level wind arrows

Input: test/input/wafs_wind.get

GET /dali?customer=test&product=wafs_wind&time=201601191800 HTTP/1.0
ParameterValueDescription
productwafs_windProduct JSON: test/dali/customers/test/products/wafs_wind.json

Wind arrows at WAFS pressure level overlaid on a base map.

Output:

wafs_wind


wafs_leveldata — Level data display

Input: test/input/wafs_leveldata.get

GET /dali?customer=test&product=wafs_leveldata&time=201601191800 HTTP/1.0
ParameterValueDescription
productwafs_leveldataProduct JSON: test/dali/customers/test/products/wafs_leveldata.json

Displays numeric values at grid points for WAFS level data.

Output:

wafs_leveldata


wafs_windbarb — WAFS wind barbs

Input: test/input/wafs_windbarb.get

GET /dali?customer=test&product=wafs_windbarb&time=201601191800 HTTP/1.0
ParameterValueDescription
productwafs_windbarbProduct JSON: test/dali/customers/test/products/wafs_windbarb.json

Standard wind barbs at a WAFS flight level.

Output:

wafs_windbarb


wafs_windbarb_shifted — Wind barbs with label offset

Input: test/input/wafs_windbarb_shifted.get

GET /dali?customer=test&product=wafs_windbarb_shifted&time=201601191800 HTTP/1.0
ParameterValueDescription
productwafs_windbarb_shiftedProduct JSON: test/dali/customers/test/products/wafs_windbarb_shifted.json

WAFS wind barbs with a global label offset (dx, dy) applied to all barb positions.

Output:

wafs_windbarb_shifted


wafs_windbarb_graticulefill — Wind barbs with graticule fill

Input: test/input/wafs_windbarb_graticulefill.get

GET /dali?customer=test&product=wafs_windbarb_graticulefill&time=201601191800 HTTP/1.0
ParameterValueDescription
productwafs_windbarb_graticulefillProduct JSON: test/dali/customers/test/products/wafs_windbarb_graticulefill.json

Adds temperature-coloured filled rectangles in the graticule grid cells behind the wind barbs — a compact SIGWX-style layout.

Output:

wafs_windbarb_graticulefill


Observations with Wind and Temperature

opendata_meteorological_wind_keyword — Wind by keyword

Input: test/input/opendata_meteorological_wind_keyword.get

GET /dali?customer=test&product=opendata_meteorological_wind_keyword&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_meteorological_wind_keywordProduct JSON: test/dali/customers/test/products/opendata_meteorological_wind_keyword.json

Wind arrows at keyword-selected stations from the opendata producer.

Output:

opendata_meteorological_wind_keyword


opendata_meteorological_wind_keyword_plustemperatures — Wind + temperature

Input: test/input/opendata_meteorological_wind_keyword_plustemperatures.get

GET /dali?customer=test&product=opendata_meteorological_wind_keyword_plustemperatures&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_meteorological_wind_keyword_plustemperaturesProduct JSON: test/dali/customers/test/products/opendata_meteorological_wind_keyword_plustemperatures.json

Combines wind arrows and temperature numbers at keyword-selected stations.

Output:

opendata_meteorological_wind_keyword_plustemperatures


opendata_meteorological_wind_grid — Wind on grid

Input: test/input/opendata_meteorological_wind_grid.get

GET /dali?customer=test&product=opendata_meteorological_wind_grid&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_meteorological_wind_gridProduct JSON: test/dali/customers/test/products/opendata_meteorological_wind_grid.json

Wind arrows placed at regular pixel-grid intervals (layout: "grid"), thinning the station network for legibility.

Output:

opendata_meteorological_wind_grid


opendata_meteorological_wind_data_plustemperatures — Wind + temperature data

Input: test/input/opendata_meteorological_wind_data_plustemperatures.get

GET /dali?customer=test&product=opendata_meteorological_wind_data_plustemperatures&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_meteorological_wind_data_plustemperaturesProduct JSON: test/dali/customers/test/products/opendata_meteorological_wind_data_plustemperatures.json

Combines wind arrows and temperature numbers sourced from the same OpenData observation query.

Output:

opendata_meteorological_wind_data_plustemperatures


opendata_meteorological_wind_data_plustemperatures_aggregate_max — Time-aggregated max wind

Input: test/input/opendata_meteorological_wind_data_plustemperatures_aggregate_max.get

GET /dali?customer=test&product=opendata_meteorological_wind_data_plustemperatures_aggregate_max&time=20130805T1500 HTTP/1.0
ParameterValueDescription
productopendata_meteorological_wind_data_plustemperatures_aggregate_maxProduct JSON: test/dali/customers/test/products/opendata_meteorological_wind_data_plustemperatures_aggregate_max.json

Uses SmartMet time-aggregation function syntax to compute maximum wind speed over a trailing 12-hour window: "speed": "nanmax_t(WindSpeedMS:12h:0h)". The nanmax_t function aggregates over the time range ignoring NaN values.

Output:

opendata_meteorological_wind_data_plustemperatures_aggregate_max


Heatmap

heatmap — Kernel-density heatmap

Input: test/input/heatmap.get

GET /dali?customer=test&product=heatmap&time=20130805T1500&l.heatmap.kernel=exp&l.heatmap.radius=40&l.heatmap.deviation=4 HTTP/1.0
ParameterValueDescription
productheatmapProduct JSON: test/dali/customers/test/products/heatmap.json
time20130805T1500Valid time: 2013-08-05 15:00 UTC
l.heatmap.kernelexpKernel function for density estimation (exp = exponential decay)
l.heatmap.radius40Override: kernel radius in pixels (product default is 20)
l.heatmap.deviation4Override: kernel deviation parameter (product default is 10.0)

The heatmap is generated by an isoband layer with a "heatmap" sub-block specifying resolution, radius, kernel, and deviation. A kernel-density surface is computed from the observation point locations and then rendered as isobands.

Output:

heatmap


Hovmoeller Diagrams

Hovmoeller diagrams show a meteorological parameter plotted over two axes, one of which is time.

hovmoeller_geoph500 — Geopotential: time × longitude

Input: test/input/hovmoeller_geoph500.get

GET /dali?customer=test&product=hovmoeller_geoph500 HTTP/1.0
ParameterValueDescription
producthovmoeller_geoph500Product JSON: test/dali/customers/test/products/hovmoeller_geoph500.json

"direction": "time_lon" — time on Y-axis, longitude on X-axis at fixed "latitude": 60.0. Plots 500 hPa geopotential height isobands over lon_min/lon_max = 5°–35°E.

Output:

hovmoeller_geoph500


hovmoeller_geoph500_time_lat — Geopotential: time × latitude

Input: test/input/hovmoeller_geoph500_time_lat.get

GET /dali?customer=test&product=hovmoeller_geoph500_time_lat HTTP/1.0
ParameterValueDescription
producthovmoeller_geoph500_time_latProduct JSON: test/dali/customers/test/products/hovmoeller_geoph500_time_lat.json

"direction": "time_lat" — time on Y-axis, latitude on X-axis at fixed "longitude": 20.0.

Output:

hovmoeller_geoph500_time_lat


hovmoeller_temperature_time_level — Temperature: time × pressure level

Input: test/input/hovmoeller_temperature_time_level.get

GET /dali?customer=test&product=hovmoeller_temperature_time_level HTTP/1.0
ParameterValueDescription
producthovmoeller_temperature_time_levelProduct JSON: test/dali/customers/test/products/hovmoeller_temperature_time_level.json

"direction": "time_level" — time on X-axis, pressure level on Y-axis at a fixed geographic point. Shows the vertical temperature structure over time (a time-height cross-section).

Output:

hovmoeller_temperature_time_level


Graticule

graticule — Basic lat/lon grid

Input: test/input/graticule.get

GET /dali?customer=test&product=graticule HTTP/1.0
ParameterValueDescription
productgraticuleProduct JSON: test/dali/customers/test/products/graticule.json

Two overlapping grids: a fine 1° grid (light, 0.2 px) skipping 10° multiples, and a coarse 10° grid (dark, 0.5 px). Projection is inferred from the kap producer's native CRS.

Output:

graticule


graticule_goode — Graticule in Goode projection

Input: test/input/graticule_goode.get

GET /dali?customer=test&product=graticule_goode HTTP/1.0
ParameterValueDescription
productgraticule_goodeProduct JSON: test/dali/customers/test/products/graticule_goode.json

A 10° graticule in the Goode Interrupted Homolosine projection (+proj=igh). Tests correct handling across the projection's interior discontinuities.

Output:

graticule_goode


graticule_num_center — Centred labels

Input: test/input/graticule_num_center.get

GET /dali?customer=test&product=graticule_num_center HTTP/1.0
ParameterValueDescription
productgraticule_num_centerProduct JSON: test/dali/customers/test/products/graticule_num_center.json

Graticule with "labels": {"layout": "center"} — degree values placed at the centres of grid lines with a rectangle background.

Output:

graticule_num_center


graticule_num_center_edge — Edge-centred labels

Input: test/input/graticule_num_center_edge.get

GET /dali?customer=test&product=graticule_num_edge_center HTTP/1.0
ParameterValueDescription
productgraticule_num_edge_centerProduct JSON: test/dali/customers/test/products/graticule_num_edge_center.json

Graticule with "layout": "edge_center" — labels placed at the mid-point of each grid line where it intersects the map edge (frame), with a bordered rectangle background.

Output:

graticule_num_center_edge


graticule_num_cross — Crossing-point labels

Input: test/input/graticule_num_cross.get

GET /dali?customer=test&product=graticule_num_cross HTTP/1.0
ParameterValueDescription
productgraticule_num_crossProduct JSON: test/dali/customers/test/products/graticule_num_cross.json

Graticule with "layout": "cross" — labels placed at every intersection of latitude and longitude grid lines.

Output:

graticule_num_cross


graticule_ticks — Tick marks at frame

Input: test/input/graticule_ticks.get

GET /dali?customer=test&product=graticule_ticks HTTP/1.0
ParameterValueDescription
productgraticule_ticksProduct JSON: test/dali/customers/test/products/graticule_ticks.json

Uses "layout": "ticks" to draw only short tick marks at the map border where grid lines intersect, without drawing the full grid lines across the map.

Output:

graticule_ticks


Circles Layer

The circle layer type draws SVG circles at named geographic locations.

circles — Concentric circles at cities

Input: test/input/circles.get

GET /dali?customer=test&product=circles&time=201503131200 HTTP/1.0
ParameterValueDescription
productcirclesProduct JSON: test/dali/customers/test/products/circles.json
time201503131200Valid time: 2015-03-13 12:00 UTC

Draws concentric rings around named cities (Helsinki, Tampere, Turku) over a Natural Earth map in EPSG:3035 (ETRS-LAEA). Each circle layer entry specifies a name (resolved to coordinates via a geocoder) and a radius.

Output:

circles


circles_labels_sw — Circle labels (SW anchor)

Input: test/input/circles_labels_sw.get

GET /dali?customer=test&product=circles_labels_sw&time=201503131200 HTTP/1.0
ParameterValueDescription
productcircles_labels_swProduct JSON: test/dali/customers/test/products/circles_labels_sw.json

Adds city name labels to the circles, anchored at the south-west corner of each station.

Output:

circles_labels_sw


circles_labels_tr — Circle labels (TR anchor)

Input: test/input/circles_labels_tr.get

GET /dali?customer=test&product=circles_labels_tr&time=201503131200 HTTP/1.0
ParameterValueDescription
productcircles_labels_trProduct JSON: test/dali/customers/test/products/circles_labels_tr.json

Same as circles_labels_sw but labels are anchored at the top-right corner.

Output:

circles_labels_tr


Fronts

fronts — Weather fronts

Input: test/input/fronts.get

GET /dali?customer=test&product=fronts&type=png&time=201503131200 HTTP/1.0
ParameterValueDescription
productfrontsProduct JSON: test/dali/customers/test/products/fronts.json
typepngRasterised PNG output (700×500 px, 8-bit palette)

Renders weather fronts (cold, warm, occluded, stationary) in EPSG:3857 over a background map. Uses the fronts layer type with CSS styling.

Output:

fronts


PostGIS Layer

ice — Ice chart from PostGIS

Input: test/input/ice.get

GET /dali?customer=test&product=ice HTTP/1.0
ParameterValueDescription
producticeProduct JSON: test/dali/customers/test/products/ice.json

Renders Baltic Sea ice chart polygons from the icemap PostGIS database using "layer_type": "postgis". The PostGIS layer can read any geometry type (Polygon, MultiPolygon, LineString) and apply CSS fill/stroke styling.

Output:

ice


WKT Layer

wkt — Well-Known Text geometry

Input: test/input/wkt.get

GET /dali?customer=test&product=wkt&time=201503131200 HTTP/1.0
ParameterValueDescription
productwktProduct JSON: test/dali/customers/test/products/wkt.json
time201503131200Valid time: 2015-03-13 12:00 UTC

The wkt layer type renders arbitrary WKT (Well-Known Text) geometry strings (e.g. polygons, lines) stored in the product definition. Geometries are projected to the map CRS and styled with CSS.

Output:

wkt


METAR Layer

metar_basic — Aviation METAR observations

Input: test/input/metar_basic.get

GET /dali?customer=test&product=metar_basic&time=201511170020&format=svg HTTP/1.0
ParameterValueDescription
productmetar_basicProduct JSON: test/dali/customers/test/products/metar_basic.json
time201511170020Valid time: 2015-11-17 00:20 UTC
formatsvgSVG output format

Uses "layer_type": "metar" with "message_type": "METAR" and "message_format": "TAC" to decode raw METAR reports stored as TAC (Traditional Alphanumeric Code) weather tokens. Controls which elements to display: show_station, show_wind, show_visibility, show_present_weather, show_sky_condition, show_temperature.

No reference output image available (no test output file generated in CI).


Fire Weather

forestfire — Forest Fire Index isobands

Input: test/input/forestfire.get

GET /dali?product=forestfire&time=20190207T0600 HTTP/1.0
ParameterValueDescription
productforestfireNo customer specified — uses the default customer directory
time20190207T0600Valid time: 2019-02-07 06:00 UTC

Renders ForestFireIndex isobands using "extrapolation": 2 to fill in missing data near the domain boundaries. The product uses the forestfire producer (separate from general synoptic producers).

Output:

forestfire


grassfire — Grassfire risk by named region

Input: test/input/grassfire.get

GET /dali?product=grassfire&time=20181212T0600 HTTP/1.0
ParameterValueDescription
productgrassfireUses default customer
time20181212T0600Valid time: 2018-12-12 06:00 UTC

Renders grassfire risk levels using the grassfire layer type. Regions are matched by named feature attributes (e.g. "value": "Uusimaa" matches the Uusimaa administrative area).

Output:

grassfire


grassfire_automatic — Grassfire risk by attribute range

Input: test/input/grassfire_automatic.get

GET /dali?product=grassfire_automatic&time=20181212T0600 HTTP/1.0
ParameterValueDescription
productgrassfire_automaticUses default customer

Like grassfire but regions are matched by numeric attribute ranges instead of named values — more flexible for data with numeric risk-class codes.

No reference output image available.


Text Layer

text — SVG text layer

Input: test/input/text.get

GET /dali?customer=test&product=text&time=200808050300 HTTP/1.0
ParameterValueDescription
producttextProduct JSON: test/dali/customers/test/products/text.json

The text layer type renders static or parameterised text strings as SVG <text> elements. The product also demonstrates how tag: "clipPath" and tag: "g" layers are used to create inline clip regions.

Output:

text


Map simplification

The MapLayer honours four optional settings that thin the polygons returned by PostGIS before they are clipped, projected and rendered:

  • an amalgamator that merges nearby polygons via constrained Delaunay triangulation,
  • a Visvalingam-Whyatt simplifier with a pixel-based tolerance (Douglas-Peucker is no longer supported — see the Map structure documentation for why),
  • the legacy minarea (km²) and mindistance (km) filters.

The GIS engine applies them in the order amalgamator → minareamindistance → simplifier, so that minarea and the new simplifier operate on the merged outline. See the Map structure documentation for the algorithmic background and a "Choosing an algorithm" comparison.

The seven examples below all render the same Northern-Baltic view (lon 18°–27°, lat 59°–65°, 900×600 px) using the gshhg.gshhs_h_l1 table (the GSHHG high-resolution L1 land polygons, ≈ 200 m vertex spacing). A bbox prefilter (the_geom && ST_MakeEnvelope(17, 58, 28, 66, 4326)) is added to every test so that the engine reads only the ~14 000 polygons in the area instead of all 144 000 globally — without that filter the amalgamator would attempt a Delaunay triangulation of every island in the world. They are directly comparable so that the visual effect of each option is easy to read.

The four amalgamation examples (map_amalgamate, map_amalgamate_wide, map_amalgamate_extreme, map_amalgamate_pathological) form a deliberate calibration sequence at amalgamation_length 0.01 → 0.02 → 0.05 → 0.1, so that the visual cost of pushing the gap distance past a sensible value for the rendering pixel scale is easy to read off the gallery PNGs. The pathological case is included to show that the algorithm degrades gracefully — it produces valid topology even at clearly absurd distances.

Apart from the baseline (which keeps every vertex), every other example applies minarea=2 (km²) after simplification / amalgamation. This is the standard "drop islands that are below ~2 px² at the rendered scale" filter; the point of running the amalgamator first is that nearby small islands first merge into one larger landmass and only then face the area filter, so an archipelago survives as a chunky shape instead of being thrown away entirely.

Units. amalgamation_length is in CRS coordinate units — at this latitude (≈ 60° N), 1° lat ≈ 111 km and 1° lon ≈ 56 km, so amalgamation_length=0.01 ≈ 0.6 km. The simplifier's tolerance is in pixels at the active projection. minarea is in km².

map_baseline — No simplification (reference image)

Input: test/input/map_baseline.get

GET /dali?customer=test&product=map_baseline HTTP/1.0
ParameterValueDescription
productmap_baselinetest/dali/customers/test/products/map_baseline.json

The unfiltered source data from gshhg.gshhs_h_l1: every coastline vertex from the high-resolution GSHHG product is kept (≈ 45 000 vertices in the rendered output). The Stockholm archipelago, Finland's southwestern archipelago and Åland are visible as dense clusters of individual skerries — exactly the kind of data the simplifier and amalgamator are designed to thin. This image is the reference against which the simplification settings below should be compared.

Output:

map_baseline


map_simplifier_vw — Visvalingam-Whyatt simplification

Input: test/input/map_simplifier_vw.get

GET /dali?customer=test&product=map_simplifier_vw HTTP/1.0
ParameterValueDescription
productmap_simplifier_vwtest/dali/customers/test/products/map_simplifier_vw.json

Same data as the baseline with simplifier="visvalingam_whyatt", tolerance=5.0 pixels, and minarea=2 (km²). About 89 % of the source vertices are removed (≈ 5 200 vertices remain). VW iteratively removes the vertex whose triangle with its neighbours has the smallest area, which preserves the overall shape character — bays and peninsulas remain recognisable, and the silhouette is blockier rather than ragged. Note that without amalgamation, minarea deletes every individual island that is below the threshold; large stretches of the archipelago that would survive amalgamation are lost.

Output:

map_simplifier_vw


map_amalgamate — Polygon amalgamation

Input: test/input/map_amalgamate.get

GET /dali?customer=test&product=map_amalgamate HTTP/1.0
ParameterValueDescription
productmap_amalgamatetest/dali/customers/test/products/map_amalgamate.json

Same data as the baseline with amalgamation_length=0.01 (≈ 0.6 km gap-bridging), amalgamation_mainland_area=1000 km² with amalgamation_mainland_amalgamate=true, and minarea=2 (km²). The amalgamator triangulates the gaps between polygons via constrained Delaunay; gap triangles whose edges are all shorter than amalgamation_length are accepted as part of the merged outline. Mainland polygons (Finnish, Estonian, Latvian coasts in this view) are above the 1000 km² threshold and would otherwise dominate the CDT input vertex count, so they are routed to a per-polygon CDT pass instead — far cheaper than including them in the global cluster CDT, but it still closes their own bays/inlets below the gap-triangle threshold. The visible result is a coastline that reads as solid rather than fingered.

Compared to the simplifier-only examples above, far more of the archipelago survives: nearby skerries that are individually smaller than 2 km² merge into a single landmass that exceeds the threshold and is therefore kept. This is a topology change that GEOS' SimplifyPreserveTopology cannot perform — that simplifier would leave each tiny island as its own (simplified) polygon.

Output:

map_amalgamate


map_amalgamate_wide — Doubled gap distance

Input: test/input/map_amalgamate_wide.get

GET /dali?customer=test&product=map_amalgamate_wide HTTP/1.0
ParameterValueDescription
productmap_amalgamate_widetest/dali/customers/test/products/map_amalgamate_wide.json

Same as map_amalgamate with amalgamation_length doubled from 0.01 to 0.02 (≈ 1.2 km gap-bridging at 60° N). Useful for calibrating how aggressive the gap distance should be at a given rendering pixel scale: at this view the silhouette still reads cleanly along the Finnish coast, but the Stockholm and Åland archipelagos dissolve further into solid blobs and clusters of small skerries in the southern bbox start to merge into single landmasses. Pushing the distance further would eventually produce a coastline that no longer looks like the source dataset — at twice the default the result is still recognisable but visibly more abstract than map_amalgamate.

Output:

map_amalgamate_wide


map_amalgamate_extreme — Excessive gap distance (do not exceed)

Input: test/input/map_amalgamate_extreme.get

GET /dali?customer=test&product=map_amalgamate_extreme HTTP/1.0
ParameterValueDescription
productmap_amalgamate_extremetest/dali/customers/test/products/map_amalgamate_extreme.json

Same as map_amalgamate with amalgamation_length raised to 0.05 (≈ 3 km gap-bridging at 60° N) — five times the recommended default. Included as a deliberate "do not exceed" reference: the Stockholm archipelago has dissolved into the Swedish mainland, Åland has become a single solid blob no longer recognisable as an archipelago, the Estonian and Latvian coasts have lost most of their detail, and shallow Finnish bays have filled in. The output is faster to render than the default (less geometry to draw) but is no longer a faithful representation of the source dataset. Useful for calibrating an upper limit when picking amalgamation_length for a new view or zoom level.

Output:

map_amalgamate_extreme


Input: test/input/map_amalgamate_pathological.get

GET /dali?customer=test&product=map_amalgamate_pathological HTTP/1.0
ParameterValueDescription
productmap_amalgamate_pathologicaltest/dali/customers/test/products/map_amalgamate_pathological.json

amalgamation_length=0.1 (≈ 6 km gap-bridging at 60° N), 10 × the recommended default and well past the source data's natural island spacing. Mainland coastlines reduce to cartoonish silhouettes, the Stockholm archipelago is fully fused with the Swedish mainland, and the gap-triangle pass starts producing scattered "ghost" white spots in the Bothnian Sea and Gulf of Finland — narrow interior holes inside the merged region that survive the boundary walk. The algorithm is degrading gracefully (it still produces valid topology, just nonsensical output) rather than failing. Included to make the upper edge of the calibration sequence visible.

Output:

map_amalgamate_pathological


map_amalgamate_simplified — Amalgamation followed by Visvalingam-Whyatt

Input: test/input/map_amalgamate_simplified.get

GET /dali?customer=test&product=map_amalgamate_simplified HTTP/1.0
ParameterValueDescription
productmap_amalgamate_simplifiedtest/dali/customers/test/products/map_amalgamate_simplified.json

Same amalgamation, mainland-amalgamate flag and minarea as map_amalgamate with simplifier="visvalingam_whyatt" and tolerance=1.5 pixels chained on. This combination is the recommended pipeline for archipelago and dense-coastline datasets: amalgamation gets the silhouette right by merging nearby islands and closing mainland bays, minarea drops the merged blobs that are still too small to render meaningfully, and the simplifier then thins out the redundant vertices on what's left.

Output:

map_amalgamate_simplified


World Map Products

These products render global-scale model data in various projections. Each family (ECMWF, GFS) covers a standard set of projections; Pacific-centred views are available for equidistant cylindrical and WGS84 projections.

ECMWF global temperature

All EC world products use the `ecmwf_maailma_pinta$ \text{producer} \text{and} \text{a} 1440 \times 720 \text{px} \text{canvas}:

\text{Test}\text{Projection}\text{CRS}\text{Input}
$ec_world_eqc`Equidistant Cylindrical (Atlantic)EPSG:4087ec_world_eqc.get
ec_world_eqc_pacificEquidistant Cylindrical (Pacific, lon₀=180°)+init=epsg:4087 +lon_0=180ec_world_eqc_pacific.get
ec_world_webmercatorWeb MercatorEPSG:3857ec_world_webmercator.get
ec_world_wgs84_atlanticGeographic WGS84 (Atlantic)+init=epsg:4326ec_world_wgs84_atlantic.get
ec_world_wgs84_pacificGeographic WGS84 (Pacific, lon_wrap=180)+init=epsg:4326 +lon_wrap=180ec_world_wgs84_pacific.get

The +lon_wrap=180 modifier shifts the longitude seam to the antimeridian so that the Pacific Ocean is unbroken.

ProjectionOutput
EQC Atlanticec_world_eqc
EQC Pacificec_world_eqc_pacific
Web Mercatorec_world_webmercator
WGS84 Atlanticec_world_wgs84_atlantic
WGS84 Pacificec_world_wgs84_pacific

GFS global temperature

All GFS world products use the gfs producer. In addition to the five standard projections, GFS also includes polar, Goode, Natural Earth, and Near-side Perspective views:

TestProjectionCRS
gfs_world_eqcEQC Atlantic+init=epsg:4087
gfs_world_eqc_pacificEQC Pacific (lon₀=180°)+init=epsg:4087 +lon_0=180
gfs_world_webmercatorWeb Mercator (Atlantic)EPSG:3857
gfs_world_webmercator_pacificWeb Mercator (Pacific bbox)EPSG:3857
gfs_world_wgs84_atlanticGeographic WGS84 Atlantic+init=epsg:4326
gfs_world_wgs84_pacificGeographic WGS84 Pacific+init=epsg:4326 +lon_wrap=180
gfs_world_arcticPolar Stereographic (N)+proj=stere +lat_0=90
gfs_world_antarcticPolar Stereographic (S)+proj=stere +lat_0=-90
gfs_world_goodeGoode Homolosine+proj=igh +lon_0=0
gfs_world_natural_earthNatural Earth+proj=natearth
gfs_world_perspectiveNear-side Perspective (h=3000 km)+proj=nsper +h=3000000 +lat_0=60 +lon_0=25
gfs_world_stereographicPolar Stereographic (Europe)+proj=stere +lat_0=90 +lat_ts=60 +lon_0=20
ProjectionOutput
EQC Atlanticgfs_world_eqc
EQC Pacificgfs_world_eqc_pacific
Web Mercatorgfs_world_webmercator
Web Mercator Pacificgfs_world_webmercator_pacific
WGS84 Atlanticgfs_world_wgs84_atlantic
WGS84 Pacificgfs_world_wgs84_pacific
Arcticgfs_world_arctic
Antarcticgfs_world_antarctic
Goode Homolosinegfs_world_goode
Natural Earthgfs_world_natural_earth
Perspective (h=3000 km)gfs_world_perspective
Stereographic (Europe)gfs_world_stereographic