pretrip_source_digitraffic
One call that fetches the nearest measured road-visibility (metres) from
Finland's Fintraffic Digitraffic road-weather network — never estimated; null
when no fresh sensor is in range. Pure Dart, no Flutter.
dart pub add pretrip_source_digitraffic
(Pulls its only runtime peer, pretrip_decision_advisor, automatically.)
Quick start
import 'package:pretrip_source_digitraffic/pretrip_source_digitraffic.dart';
Future<void> main() async {
final provider = DigitrafficVisibilityProvider();
// Nearest measured road visibility to Helsinki (60.17 N, 24.93 E), now.
final obs = await provider.fetchNearestVisibility(latitude: 60.17, longitude: 24.93);
provider.close();
if (obs == null) {
// No fresh sensor in range — visibility is NEVER estimated; the call stays the driver's.
print('No fresh measured visibility in range — not estimated.');
return;
}
print('Measured ${obs.meters} m visibility at ${obs.stationName} '
'(${obs.distanceKm.toStringAsFixed(1)} km away), at ${obs.measuredAt.toIso8601String()}.');
print(kDigitrafficVisibilityAttributionString); // CC BY 4.0 attribution — required at your UI.
}
You get back a VisibilityObservation with .meters, .stationName,
.distanceKm, and .measuredAt — a real value measured now at the nearest
road-weather station — or null when none is fresh in range. Run it
(dart run example/quickstart.dart) and it prints a live reading, e.g.:
Measured 20000.0 m visibility at kt51_Hki_Lapinlahti (1.8 km away), at 2026-06-26T22:02:25.000.
Source: Fintraffic / digitraffic.fi, license CC 4.0 BY.
To put the measurement onto a forecast for a pre-trip briefing, see
example/main.dart (merges it onto the departure-hour slot
with mergeObservedVisibility).
Background & provenance
Fintraffic Digitraffic measured road-visibility source for the
pretrip_decision_advisor
pre-trip briefing. Fetches the nearest fresh measured visibility
(NÄKYVYYS_M, metres) on the Finnish road-weather network and emits a
source-neutral VisibilityObservation you merge onto the departure-hour slot
of a WeatherForecast with mergeObservedVisibility.
Pure Dart. Only http and pretrip_decision_advisor runtime dependencies. No
Flutter.
⚠️ SAFETY — honesty rules (binding, verbatim)
This is a safety-class source for a driving-decision surface. These rules are binding on every consumer and are reproduced verbatim from the contract this package serves. Do not relax them in your UI/XI:
- visibility NEVER estimated
- a warning NEVER produces a number
- an observation valid for the departure hour only
- null = the driver's own judgment, never a fabricated hazard
What this means concretely for this source:
- A
VisibilityObservationis a NOW measurement at a real road-weather station up tomaxDistanceKmfrom the requested point. The caller applies it to the current (departure) hour only — never projects it forward into later forecast hours.mergeObservedVisibilityenforces this: it sets the value on the single covering departure-hour slot and leaves every later hour untouched. - No station in range / no fresh visibility sensor / a stale reading / any
fetch failure →
null. Visibility is never estimated from sky symbols, precipitation, or anything else.nullis not a hazard and not a zero — it hands the call back to the driver. - This package emits a measurement (a number, in metres). It does not emit a warning. The "a warning NEVER produces a number" rule lives with the warning side (see the sibling below): a human-facing warning must not invent a precise figure it did not measure. Here the figure exists only because a sensor reported it.
Mission
These sources feed the published pretrip_decision_advisor 0.2.0 so an edge
developer can build their own UI/XI that warns HER (Nagoya) and HER
mother (Akita, a heavy-snow prefecture) before she drives into the
whiteout. Success is an edge developer who runs and sees a briefing that
helped a real driver — never a package count. Adoption is 0; that is named,
and it ranks nothing.
Service trace (driver in unexpected snow; ≤4 hops)
Fintraffic Digitraffic road-weather network (real NÄKYVYYS_M sensors)
→ DigitrafficVisibilityProvider (this package)
→ mergeObservedVisibility onto the departure-hour forecast slot
(pretrip_decision_advisor)
→ an edge developer's pre-trip briefing warns the driver before she
leaves, in compound-failure winter conditions
Sibling: measurement vs. warning (which to pub add)
This package has a sibling built on the same upstream provider (Fintraffic Digitraffic). They emit different things — depend on the one that matches your need (you may use both):
| Package | Emits | Type | pub add when you want… |
|---|---|---|---|
pretrip_source_digitraffic (this) |
a MEASUREMENT | VisibilityObservation (metres, a number measured at a station) |
to put a real, measured visibility figure onto the departure-hour of a pre-trip forecast/briefing |
condition_aggregator_digitraffic |
a WARNING | Advisory (CAP-class severity/certainty/urgency from traffic announcements) |
to surface live road advisories/warnings near a point through the condition_aggregator interface |
Rule of thumb: a number you measured → this package; a human-facing warning → the sibling. Per the honesty rules, never let a warning invent a number — keep the two paths distinct.
Sibling sources — same contract, pick by region
The pretrip_source_* family all feed the same
pretrip_decision_advisor
and emit the SAME typed inputs, so you can swap region without changing your UI
code:
| Region / network | pub add |
Emits |
|---|---|---|
| Japan — JMA / AMeDAS | pretrip_source_jma |
measured VisibilityObservation (metres) |
| Finland — Fintraffic Digitraffic | pretrip_source_digitraffic (this package) |
measured VisibilityObservation (metres) |
| Global — MET Norway locationforecast | pretrip_source_met_norway |
hourly WeatherForecast |
Full reference integration (Flutter)
A standalone, edge-developer-shaped Flutter app that assembles and RENDERS a
pre-trip briefing from pretrip_decision_advisor + pretrip_source_jma — no
SNGNav app widgets — lives at
examples/edge_dev_akita_briefing/.
The contract this serves condition-general
This source is not snow-specific. It emits visibility in metres for the departure hour — which serves any weather turmoil that drops visibility (fog, heavy rain, dust, smoke), not only snow. The snow framing is the driving mission, not a regression on the contract; the data path stays general.
Endpoint
Road-weather station network base: https://tie.digitraffic.fi/api/weather/v1
GET /stations— GeoJSON station metadata (~20 KB gzip); the nearestGATHERINGstation to the requested point withinmaxDistanceKmis chosen.GET /stations/{id}/data— theNÄKYVYYS_Msensor (orNÄKYVYYS_KM× 1000), accepted only whenmeasuredTimeis withinmaxObservationAge(30 min default).
No authentication required. Requests carry an identifying User-Agent, as
Digitraffic asks integrations to identify themselves. Measured 2026-06-12: 453
of 526 stations (86%) report a live visibility sensor.
Merge onto a forecast (departure-hour only)
import 'package:pretrip_decision_advisor/pretrip_decision_advisor.dart';
import 'package:pretrip_source_digitraffic/pretrip_source_digitraffic.dart';
Future<void> main() async {
final provider = DigitrafficVisibilityProvider();
try {
final departure = DateTime.now();
final observation = await provider.fetchNearestVisibility(
latitude: 60.17,
longitude: 24.93,
now: departure,
);
if (observation == null) {
// No fresh sensor in range — nothing is estimated. The call stays
// with the driver.
return;
}
// Valid for the departure hour ONLY — mergeObservedVisibility never
// projects it forward into later hours. (`forecast` is your own
// WeatherForecast for the trip; see example/main.dart for a full one.)
final merged = mergeObservedVisibility(forecast, observation, departure);
// ... hand `merged` to pretrip_decision_advisor's brief().
} finally {
provider.close();
}
}
See example/main.dart for a complete runnable program.
License + attribution (binding)
This package code is licensed under BSD 3-Clause.
Digitraffic data is licensed CC BY 4.0 per Fintraffic Terms of Service
(https://www.digitraffic.fi/en/terms-of-service/): "Fintraffic's open data is
licensed under the Creative Commons 4.0 By license." Attribution is REQUIRED
at the consumer-facing surface, not optional. Surface this line, verbatim, where
the visibility is rendered (per-reading detail, credits screen, about panel —
any "reasonable manner" satisfying CC BY 4.0 §3(a)(2)):
Source: Fintraffic / digitraffic.fi, license CC 4.0 BY.
It is also exported as the constant kDigitrafficVisibilityAttributionString
for direct integrator use.
License
BSD 3-Clause License. See LICENSE.
Libraries
- pretrip_source_digitraffic
- pretrip_source_digitraffic — Fintraffic Digitraffic measured-visibility
source for the
pretrip_decision_advisorbriefing.